changes PurchaseSuggested seach by categories
This commit is contained in:
parent
27de630b23
commit
7c3acbfc24
156
purchase.py
156
purchase.py
|
@ -82,7 +82,7 @@ class CreatePurchaseSuggested(Wizard):
|
|||
('effective_date', '<=', today),
|
||||
('state', '=', 'done'),
|
||||
('product', 'in', products_ids),
|
||||
('to_location.type', 'in', ['customer','production']),
|
||||
('to_location.type', 'in', ['customer', 'production']),
|
||||
]
|
||||
location_id = None
|
||||
if self.start.location:
|
||||
|
@ -339,6 +339,8 @@ class PurchaseSuggestedReportStart(ModelView):
|
|||
])
|
||||
historical_time = fields.Integer('Historical Time', required=True,
|
||||
help='In days')
|
||||
categories = fields.Many2Many(
|
||||
'product.category', None, None, 'Categories')
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
|
@ -378,7 +380,8 @@ class PrintPurchaseSuggestedReport(Wizard):
|
|||
'location': location_id,
|
||||
'location_name': location_name,
|
||||
'time_stock': self.start.time_stock,
|
||||
'historical_time': self.start.historical_time
|
||||
'historical_time': self.start.historical_time,
|
||||
'categories': [category.id for category in self.start.categories]
|
||||
}
|
||||
return action, data
|
||||
|
||||
|
@ -404,6 +407,7 @@ class PurchaseSuggestedReport(Report):
|
|||
)
|
||||
products_supplier = ProductSupplier.search(domain)
|
||||
suppliers_dict = {}
|
||||
supplier_list = []
|
||||
for ps in products_supplier:
|
||||
products_ids = [p.id for p in ps.template.products]
|
||||
try:
|
||||
|
@ -413,7 +417,8 @@ class PurchaseSuggestedReport(Report):
|
|||
'name': ps.party.name,
|
||||
'products': products_ids
|
||||
}
|
||||
return suppliers_dict
|
||||
supplier_list = [{key: value} for key, value in suppliers_dict.items()]
|
||||
return supplier_list
|
||||
|
||||
@classmethod
|
||||
def get_last_purchase(cls, product_id):
|
||||
|
@ -468,6 +473,11 @@ class PurchaseSuggestedReport(Report):
|
|||
moves = StockMove.search(dom_stock)
|
||||
return sum([l.quantity for l in moves])
|
||||
|
||||
@classmethod
|
||||
def check_parameters(cls, supplier, categories):
|
||||
if not supplier and not categories:
|
||||
raise UserError('You must set a supplier or category.')
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
|
@ -478,7 +488,8 @@ class PurchaseSuggestedReport(Report):
|
|||
Location = pool.get('stock.location')
|
||||
today = date.today()
|
||||
start_date = today - timedelta(data['historical_time'])
|
||||
suppliers_dict = cls.get_supplier_products(data['supplier'])
|
||||
cls.check_parameters(data['supplier'], data['categories'])
|
||||
suppliers_list = cls.get_supplier_products(data['supplier'])
|
||||
historical_time = data['historical_time']
|
||||
time_stock = data['time_stock']
|
||||
dom_stock = [
|
||||
|
@ -489,6 +500,8 @@ class PurchaseSuggestedReport(Report):
|
|||
]
|
||||
records = []
|
||||
location_id = None
|
||||
if data['categories']:
|
||||
dom_stock.append(('product.categories', 'in', data['categories']))
|
||||
if data['location']:
|
||||
location_id = data['location']
|
||||
location_ids = [location_id]
|
||||
|
@ -499,73 +512,76 @@ class PurchaseSuggestedReport(Report):
|
|||
('type', '=', 'warehouse')
|
||||
])
|
||||
location_ids = [l.storage_location.id for l in locations]
|
||||
for supplier in suppliers_dict.values():
|
||||
dom_stock.append(('product', 'in', supplier['products']))
|
||||
supplier['products'] = []
|
||||
moves = StockMove.search(dom_stock, order=[('effective_date', 'ASC')])
|
||||
target_products = {}
|
||||
supplier_cost = []
|
||||
supplier_daily_sale = []
|
||||
historical_products = {}
|
||||
for move in moves:
|
||||
if move.product not in target_products.keys():
|
||||
# setattr(move.product, 'historical_time', move.effective_date)
|
||||
target_products[move.product] = [move.quantity]
|
||||
historical_products[move.product.id] = move.effective_date
|
||||
else:
|
||||
target_products[move.product].append(move.quantity)
|
||||
for sl in suppliers_list:
|
||||
for supplier in sl.values():
|
||||
dom_stock.append(('product', 'in', supplier['products']))
|
||||
supplier['products'] = []
|
||||
print(dom_stock, supplier['name'])
|
||||
moves = StockMove.search(dom_stock, order=[('effective_date', 'ASC')])
|
||||
target_products = {}
|
||||
supplier_cost = []
|
||||
supplier_daily_sale = []
|
||||
historical_products = {}
|
||||
for move in moves:
|
||||
if move.product not in target_products.keys():
|
||||
# setattr(move.product, 'historical_time', move.effective_date)
|
||||
target_products[move.product] = [move.quantity]
|
||||
historical_products[move.product.id] = move.effective_date
|
||||
else:
|
||||
target_products[move.product].append(move.quantity)
|
||||
# print(target_products)
|
||||
for product, quantities in target_products.items():
|
||||
""" stock necesario para n dias - existencia"""
|
||||
current_stock = cls.get_product_stock(product.id, location_ids)
|
||||
""" search the real historical time, not the default (90) """
|
||||
real_historical_time = historical_time
|
||||
pdt_historical_time = historical_products[product.id]
|
||||
if pdt_historical_time > start_date:
|
||||
real_historical_time = historical_time - (pdt_historical_time - start_date).days
|
||||
|
||||
for product, quantities in target_products.items():
|
||||
""" stock necesario para n dias - existencia"""
|
||||
current_stock = cls.get_product_stock(product.id, location_ids)
|
||||
""" search the real historical time, not the default (90) """
|
||||
real_historical_time = historical_time
|
||||
pdt_historical_time = historical_products[product.id]
|
||||
if pdt_historical_time > start_date:
|
||||
real_historical_time = historical_time - (pdt_historical_time - start_date).days
|
||||
|
||||
if real_historical_time == 0:
|
||||
suggest_qty = 0
|
||||
daily_rotation = 0
|
||||
stock_duration = 0
|
||||
else:
|
||||
suggest_qty = int(time_stock * sum(quantities) / real_historical_time - current_stock)
|
||||
daily_rotation = Decimal(sum(quantities) / real_historical_time)
|
||||
stock_duration = int(Decimal(current_stock) / daily_rotation)
|
||||
# suggest_qty = int(time_stock * sum(quantities) / real_historical_time - current_stock)
|
||||
sales_30 = cls.get_last_out_moves(product.id, data['location'], today, 30)
|
||||
sales_60 = cls.get_last_out_moves(product.id, data['location'], today-timedelta(30), 30)
|
||||
last_purchase_date, last_quantity, last_cost_price = cls.get_last_purchase(product.id)
|
||||
if last_cost_price > 0:
|
||||
last_cost_price += (product.extra_tax or 0)
|
||||
else: #assigns cost price when there aren't purchases (production)
|
||||
last_cost_price = product.cost_price + (product.extra_tax or 0)
|
||||
list_price = Decimal(product.list_price + (product.extra_tax or 0))
|
||||
cost_price = int(Decimal(current_stock) * last_cost_price)
|
||||
daily_sale = int(daily_rotation * list_price)
|
||||
supplier_cost.append(cost_price)
|
||||
supplier_daily_sale.append(daily_sale)
|
||||
supplier['products'].append({
|
||||
'product_id': product.id,
|
||||
'code': product.code,
|
||||
'name': product.template.name,
|
||||
'current_stock': current_stock,
|
||||
'uom': product.template.default_uom.name,
|
||||
'stock_duration': stock_duration,
|
||||
'pending_purchase': cls.get_pending_purchase(product.id),
|
||||
'30': sales_30,
|
||||
'60': sales_60,
|
||||
'daily_rotation': daily_rotation,
|
||||
'daily_sale': daily_sale,
|
||||
'suggest_qty': suggest_qty,
|
||||
'last_purchase': last_purchase_date,
|
||||
'last_quantity': last_quantity,
|
||||
'last_cost_price': last_cost_price,
|
||||
'amount_stock': cost_price
|
||||
})
|
||||
supplier['total_cost_price'] = sum(supplier_cost)
|
||||
supplier['total_daily_sale'] = sum(supplier_daily_sale)
|
||||
records.append(supplier)
|
||||
if real_historical_time == 0:
|
||||
suggest_qty = 0
|
||||
daily_rotation = 0
|
||||
stock_duration = 0
|
||||
else:
|
||||
suggest_qty = int(time_stock * sum(quantities) / real_historical_time - current_stock)
|
||||
daily_rotation = Decimal(sum(quantities) / real_historical_time)
|
||||
stock_duration = int(Decimal(current_stock) / daily_rotation)
|
||||
# suggest_qty = int(time_stock * sum(quantities) / real_historical_time - current_stock)
|
||||
sales_30 = cls.get_last_out_moves(product.id, data['location'], today, 30)
|
||||
sales_60 = cls.get_last_out_moves(product.id, data['location'], today-timedelta(30), 30)
|
||||
last_purchase_date, last_quantity, last_cost_price = cls.get_last_purchase(product.id)
|
||||
if last_cost_price > 0:
|
||||
last_cost_price += (product.extra_tax or 0)
|
||||
else: #assigns cost price when there aren't purchases (production)
|
||||
last_cost_price = product.cost_price + (product.extra_tax or 0)
|
||||
list_price = Decimal(product.list_price + (product.extra_tax or 0))
|
||||
cost_price = int(Decimal(current_stock) * last_cost_price)
|
||||
daily_sale = int(daily_rotation * list_price)
|
||||
supplier_cost.append(cost_price)
|
||||
supplier_daily_sale.append(daily_sale)
|
||||
supplier['products'].append({
|
||||
'product_id': product.id,
|
||||
'code': product.code,
|
||||
'name': product.template.name,
|
||||
'current_stock': current_stock,
|
||||
'uom': product.template.default_uom.name,
|
||||
'stock_duration': stock_duration,
|
||||
'pending_purchase': cls.get_pending_purchase(product.id),
|
||||
'30': sales_30,
|
||||
'60': sales_60,
|
||||
'daily_rotation': daily_rotation,
|
||||
'daily_sale': daily_sale,
|
||||
'suggest_qty': suggest_qty,
|
||||
'last_purchase': last_purchase_date,
|
||||
'last_quantity': last_quantity,
|
||||
'last_cost_price': last_cost_price,
|
||||
'amount_stock': cost_price
|
||||
})
|
||||
supplier['total_cost_price'] = sum(supplier_cost)
|
||||
supplier['total_daily_sale'] = sum(supplier_daily_sale)
|
||||
dom_stock.pop()
|
||||
records.append(supplier) if supplier['products'] else None
|
||||
report_context['records'] = records
|
||||
report_context['today'] = date.today()
|
||||
report_context['company'] = company.party.name
|
||||
|
|
|
@ -12,4 +12,6 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="historical_time"/>
|
||||
<label name="location"/>
|
||||
<field name="location" widget="selection"/>
|
||||
<newline/>
|
||||
<field name="categories" colspan='4'/>
|
||||
</form>
|
||||
|
|
Loading…
Reference in New Issue