Browse Source

Apr 03: [FIX] Bug Fixed 'inventory_forecast_analysis_report'

pull/278/merge
RisvanaCybro 1 year ago
parent
commit
58a652eb53
  1. 2
      inventory_forecast_analysis_report/__manifest__.py
  2. 6
      inventory_forecast_analysis_report/doc/RELEASE_NOTES.md
  3. 14
      inventory_forecast_analysis_report/models/product_template.py
  4. 131
      inventory_forecast_analysis_report/wizards/forecast_analysis_report.py

2
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 "

6
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

14
inventory_forecast_analysis_report/models/product_template.py

@ -18,7 +18,7 @@
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
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]

131
inventory_forecast_analysis_report/wizards/forecast_analysis_report.py

@ -18,9 +18,8 @@
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
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,

Loading…
Cancel
Save