diff --git a/inventory_forecast_analysis_report/__manifest__.py b/inventory_forecast_analysis_report/__manifest__.py
index 90c4352ee..5e98cdaa6 100644
--- a/inventory_forecast_analysis_report/__manifest__.py
+++ b/inventory_forecast_analysis_report/__manifest__.py
@@ -20,7 +20,7 @@
#############################################################################
{
"name": "Inventory Forecast Analysis Report",
- "version": "16.0.1.0.0",
+ "version": "16.0.1.0.1",
"category": "Warehouse",
"summary": "Helps to find all the stock quantities",
"description": "This module allows the user to find all the "
diff --git a/inventory_forecast_analysis_report/doc/RELEASE_NOTES.md b/inventory_forecast_analysis_report/doc/RELEASE_NOTES.md
index 5112e1c41..1e5197954 100644
--- a/inventory_forecast_analysis_report/doc/RELEASE_NOTES.md
+++ b/inventory_forecast_analysis_report/doc/RELEASE_NOTES.md
@@ -3,5 +3,9 @@
#### 28.02.2024
#### Version 16.0.1.0.0
#### ADD
-
- Initial Commit for Inventory Forecast Analysis Report
+
+#### 02.04.2024
+#### Version 16.0.1.0.1
+##### UPDT
+- Bug Fix-Resolved corrected the issue in action_print_report method
diff --git a/inventory_forecast_analysis_report/models/product_template.py b/inventory_forecast_analysis_report/models/product_template.py
index 5577c6a90..4fa99dab0 100644
--- a/inventory_forecast_analysis_report/models/product_template.py
+++ b/inventory_forecast_analysis_report/models/product_template.py
@@ -18,7 +18,7 @@
# If not, see .
#
#############################################################################
-from odoo import api, fields, models
+from odoo import fields, models
class ProductTemplate(models.Model):
@@ -26,16 +26,4 @@ class ProductTemplate(models.Model):
product_brand_id = fields.Many2one('product.brand', string="Product Brand",
help="Brand of the Product.")
- supplier_id = fields.Many2one(
- 'product.supplierinfo', string="Supplier",
- compute="_compute_suppliers",
- store=True, help="Supplier of the Product.")
- @api.depends('seller_ids.partner_id')
- def _compute_suppliers(self):
- """This function is used to compute the main supplier
- of the product."""
- for rec in self:
- rec.supplier_id = False
- if rec.seller_ids:
- rec.supplier_id = rec.seller_ids[0]
diff --git a/inventory_forecast_analysis_report/wizards/forecast_analysis_report.py b/inventory_forecast_analysis_report/wizards/forecast_analysis_report.py
index cf8074737..14f29f0e9 100644
--- a/inventory_forecast_analysis_report/wizards/forecast_analysis_report.py
+++ b/inventory_forecast_analysis_report/wizards/forecast_analysis_report.py
@@ -18,9 +18,8 @@
# If not, see .
#
#############################################################################
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
-from odoo import api, fields, models
+from odoo import api, fields, models, _
+from odoo.exceptions import ValidationError
class ForecastAnalysisReportWizard(models.TransientModel):
@@ -33,9 +32,6 @@ class ForecastAnalysisReportWizard(models.TransientModel):
parent_category_id = fields.Many2one(
'product.category', string="Parent Category",
help="Parent category of product")
- supplier_id = fields.Many2one(
- 'product.supplierinfo', string="Supplier",
- help="Supplier/Vendor of the Product.")
product_brand_id = fields.Many2one('product.brand', string="Product Brand",
help="Brand of the Product.")
period = fields.Selection([('1week', 'Last 1 week'),
@@ -72,30 +68,30 @@ class ForecastAnalysisReportWizard(models.TransientModel):
return {'domain': {
'product_category_id': ()}}
- def _compute_date(self):
+ def get_start_date(self, today):
"""This function will calculate the start_date with respect to the
period and returns the result"""
- res = datetime.today() + relativedelta(months=-3)
+ res = fields.Date.subtract(today, months=3)
if self.period == '1week':
- res = datetime.today() + relativedelta(weeks=-1)
+ res = fields.Date.subtract(today, weeks=1)
elif self.period == '2week':
- res = datetime.today() + relativedelta(weeks=-2)
+ res = fields.Date.subtract(today, weeks=2)
elif self.period == '3week':
- res = datetime.today() + relativedelta(weeks=-3)
+ res = fields.Date.subtract(today, weeks=3)
elif self.period == '1month':
- res = datetime.today() + relativedelta(months=-1)
+ res = fields.Date.subtract(today, months=1)
elif self.period == '6months':
- res = datetime.today() + relativedelta(months=-6)
+ res = fields.Date.subtract(today, months=6)
elif self.period == '12months':
- res = datetime.today() + relativedelta(months=-12)
+ res = fields.Date.subtract(today, months=12)
elif self.period == '24months':
- res = datetime.today() + relativedelta(months=-24)
+ res = fields.Date.subtract(today, months=24)
elif self.period == '36months':
- res = datetime.today() + relativedelta(months=-36)
+ res = fields.Date.subtract(today, months=36)
elif self.period == '2months':
- res = datetime.today() + relativedelta(months=-2)
+ res = fields.Date.subtract(today, months=2)
elif self.period == '5months':
- res = datetime.today() + relativedelta(months=-5)
+ res = fields.Date.subtract(today, months=5)
return res
def action_print_report(self):
@@ -103,88 +99,81 @@ class ForecastAnalysisReportWizard(models.TransientModel):
on the report wizard and returns the report."""
previous_report = self.env['forecast.report'].search([])
previous_report.unlink() if previous_report else False
- suppliers = self.env['product.supplierinfo'].search(
- [('partner_id', '=', self.partner_id.id)])
- category_ids = []
- if self.parent_category_id:
- # if there is a parent category, the report will be generated based
- # on the product category as the sub-sub categories
- category_ids = self.env['product.category'].search(
- [('parent_id', '=', self.parent_category_id.id)])
- categ_list = category_ids.ids if category_ids else []
- if categ_list:
- for rec in categ_list:
- sub_category = self.env['product.category'].search(
- [('parent_id', '=', rec)])
- for category in sub_category.ids:
- if category not in categ_list:
- categ_list.append(category)
- category_ids = self.env['product.category'].browse(categ_list)
+ if (not self.product_category_id and not self.parent_category_id and
+ not self.partner_id and not self.product_brand_id and
+ not self.location_ids):
+ raise ValidationError(_("Data missing"))
domain = []
- # if both categories are present, it will generate the
- # report based on the product category only
- if self.parent_category_id and self.product_category_id:
- domain += [('categ_id', '=', self.product_category_id.id)]
- elif self.product_category_id and not self.parent_category_id:
+ if self.product_category_id:
domain += [('categ_id', '=', self.product_category_id.id)]
elif not self.product_category_id and self.parent_category_id:
domain += [('categ_id', '=', self.parent_category_id.id)]
if self.partner_id:
- domain += [('supplier_id', 'in', suppliers.ids)]
+ suppliers = self.env['product.supplierinfo'].search(
+ [('partner_id', '=', self.partner_id.id)])
+ domain += [('seller_ids', 'in', suppliers.ids)]
if self.product_brand_id:
domain += [('product_brand_id', '=', self.product_brand_id.id)]
products = self.env['product.product'].search(domain)
product_ids = tuple([product.id for product in products])
- start_date = self._compute_date()
- current_date = datetime.today()
+ current_date = fields.date.today()
+ start_date = self.get_start_date(current_date)
query = """
- SELECT sum(sl.product_uom_qty) AS product_uom_qty,
- sl.product_id, sum(sl.qty_invoiced) AS qty_invoiced
- FROM sale_order_line AS sl
- JOIN sale_order AS so ON sl.order_id = so.id
- WHERE so.state IN ('sale','done')
- AND so.date_order::date >= %s
- AND so.date_order::date <= %s
- AND sl.product_id in %s
- group by sl.product_id"""
- params = start_date.date(), current_date.date(), \
+ SELECT sum(sl.product_uom_qty) AS product_uom_qty,
+ sl.product_id, sum(sl.qty_invoiced) AS qty_invoiced
+ FROM sale_order_line AS sl
+ JOIN sale_order AS so ON sl.order_id = so.id
+ WHERE so.state IN ('sale','done')
+ AND so.date_order::date >= %s
+ AND so.date_order::date <= %s
+ AND sl.product_id in %s
+ group by sl.product_id"""
+ params = start_date, current_date, \
product_ids if product_ids else (0, 0, 0, 0)
self._cr.execute(query, params)
result = self._cr.dictfetchall()
- locations = self.location_ids
- if not locations:
- locations = self.env['stock.location'].search([
- ('name', '=', 'Stock')])
for product in products:
- for location in locations:
- warehouse = location.warehouse_id.id
+ internal_locations = self.env['stock.location'].search(
+ [('usage', '=', 'internal')])
+ locations = self.env['stock.quant'].search([
+ ('product_id', '=', product.id),
+ ('location_id', 'in', internal_locations.ids)]).location_id
+ for location in self.location_ids if self.location_ids else locations:
+ stock_quant = self.env['stock.quant'].search([
+ ('location_id', '=', location.id),
+ ('product_id', '=', product.id),
+ ('write_date', '>=', start_date),
+ ('write_date', '<=', current_date)])
+ available_qty = sum(
+ [quant.quantity for quant in stock_quant])
sold = 0
for sol_product in result:
if sol_product['product_id'] == product.id:
sold = sol_product['qty_invoiced']
- available_qty = product.with_context(
- {'from_date': start_date, 'to_date': current_date,
- 'warehouse': warehouse}).qty_available
forecasted_qty = product.with_context(
- {'warehouse': warehouse}).virtual_available
+ {'warehouse': location.warehouse_id.id}).virtual_available
reorder_qty = self.env['stock.warehouse.orderpoint'].search(
[('product_id', '=', product.id),
- ('location_id', '=', product.id)])
+ ('location_id', '=', location.id)])
reorder_min = sum(
- [q.product_min_qty for q in reorder_qty])
- minimum_qty = 0
- if available_qty < reorder_min:
- minimum_qty = reorder_min
+ [qty.product_min_qty for qty in reorder_qty])
+ minimum_qty = reorder_min if available_qty < reorder_min else 0
pending = product.with_context(
{'from_date': start_date, 'to_date': current_date,
- 'location': location.id}).incoming_qty
+ 'location_id': location.id}).incoming_qty
suggested = sold - (forecasted_qty + pending + minimum_qty)
+ if self.partner_id:
+ supplier = product.seller_ids.filtered(
+ lambda seller: seller.partner_id == self.partner_id).id
+ elif not self.partner_id and product.seller_ids:
+ supplier = product.seller_ids.ids[0]
+ else:
+ supplier = False
vals = {
'sold': sold,
'product_id': product.id,
'product_category_id': product.categ_id.id,
- 'supplier_id': product.seller_ids.ids[
- 0] if product.seller_ids else False,
+ 'supplier_id': supplier,
'product_brand_id': product.product_brand_id.id,
'on_hand': available_qty,
'pending': pending,