Add compute unit cost for BOM

This commit is contained in:
oscar alvarez 2023-04-19 12:50:00 -05:00
parent 81c84a8683
commit bfcee95d57
11 changed files with 53 additions and 46 deletions

View File

@ -1,4 +1,4 @@
Copyright (C) 2019 Oscar Alvarez
Copyright (C) 2019-2023 Oscar Alvarez
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -4,7 +4,7 @@ Installing trytond_production_accounting
Prerequisites
-------------
* Python 3.6 or later (http://www.python.org/)
* Python 3.7 or later (http://www.python.org/)
* trytond (http://www.tryton.org/)
* trytond_company (http://www.tryton.org/)
* trytond_party (http://www.tryton.org/)

View File

@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: trytond_production_accounting
Version: 5.0.0
Version: 6.0.0
Summary: Tryton module creates account moves for production stock moves.
Home-page: http://www.tryton.org/
Author: Oscar Alvarez

View File

@ -1,11 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval
from trytond.model import fields
from trytond.wizard import Wizard, StateTransition
from trytond.pool import PoolMeta
class Move(metaclass=PoolMeta):

33
bom.py
View File

@ -1,4 +1,4 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from datetime import datetime, date
@ -15,13 +15,15 @@ class BOM(metaclass=PoolMeta):
@classmethod
def calc_cost_ldm(cls):
# This method is temporal for CRON sync for a specific customer
ProductLdm = Pool().get('production.bom')
ProductLdmOut = Pool().get('production.bom.output')
Product = Pool().get('product.product')
Uom = Pool().get('product.uom')
current_date = datetime.combine(date.today(), datetime.min.time())
products_ldm = [p['product'] for p in ProductLdmOut.search_read([], fields_names=['id', 'product'])]
ldm_outs = ProductLdmOut.search_read([], fields_names=['id', 'product'])
products_ldm = [p['product'] for p in ldm_outs]
products = Product.search([
('active', '=', True),
('template.producible', '=', True),
@ -38,22 +40,31 @@ class BOM(metaclass=PoolMeta):
output = ldm.outputs[0]
if not ldm.outputs or not ldm.inputs:
continue
cost = cls.get_cost_ldm(ldm, uom_compute_qty)
cost = ldm.get_cost_ldm(uom_compute_qty)
if cost > 0:
cost = round(cost / Decimal(output.quantity), 4)
Product.write([output.product], {'cost_price': cost})
@classmethod
def get_cost_ldm(cls, ldm, uom_compute_qty):
def compute_unit_cost(self):
Product = Pool().get('product.product')
total_cost = self.get_cost_ldm()
for output in self.outputs:
if output.quantity > 0:
cost = round(total_cost / Decimal(output.quantity), 4)
Product.write([output.product], {'cost_price': cost})
cost = Decimal(0)
for input_ in ldm.inputs:
quantity = uom_compute_qty(input_.uom, input_.quantity,
input_.product.default_uom)
def get_cost_ldm(self):
Uom = Pool().get('product.uom')
compute_qty = Uom.compute_qty
res = []
for input_ in self.inputs:
quantity = compute_qty(
input_.uom, input_.quantity,
input_.product.default_uom)
cost_price = input_.product.cost_price
cost += (Decimal(str(quantity)) * cost_price)
res.append(Decimal(str(quantity)) * cost_price)
return round_price(cost)
return round_price(sum(res))
class BOMDirectCost(ModelSQL, ModelView):

View File

@ -1,4 +1,4 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta
from trytond.model import fields

3
ir.py
View File

@ -1,3 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta

View File

@ -113,7 +113,7 @@ class Production(metaclass=PoolMeta):
if not total_cost and self.cost:
total_cost = self.cost
ouput = self.outputs[0]
# ouput = self.outputs[0]
new_cost_price = round_dec(total_cost / Decimal(self.quantity))
return new_cost_price
@ -152,15 +152,15 @@ class Production(metaclass=PoolMeta):
for input in rec.inputs:
account_id = input.product.account_expense_used.id
amount = input.product.cost_price * Decimal(input.quantity)
_line = {
line = {
'description': input.product.rec_name,
'account': account_id,
'debit': 0,
'credit': amount,
}
cost_production.append(amount)
cls.set_analytic_lines(_line, date_, rec.analytic_account_materials)
lines.append(_line)
cls.set_analytic_lines(line, date_, rec.analytic_account_materials)
lines.append(line)
account_id = None
for cost in rec.costs:
@ -188,7 +188,6 @@ class Production(metaclass=PoolMeta):
def get_consumption_lines(cls, inputs, factor, date_, args=None):
""" Get Consumption Account Move Lines """
lines = []
# balance = []
costs_lines = {}
for _in in inputs:
product = _in.product
@ -210,7 +209,6 @@ class Production(metaclass=PoolMeta):
'credit': credit
}
lines.append(_line)
# balance.append(credit)
account_expense_id = category.account_expense.id
try:
costs_lines[account_expense_id].append(credit)
@ -340,7 +338,8 @@ class Production(metaclass=PoolMeta):
res.append(Decimal(quantity) * cost_price)
self.material_costs = sum(res)
@fields.depends('costs', 'indirect_costs', 'services_costs', 'labour_costs')
@fields.depends(
'costs', 'indirect_costs', 'services_costs', 'labour_costs')
def on_change_costs(self, name=None):
indirect_costs = []
services_costs = []
@ -440,7 +439,8 @@ class ProcessProductionAsyncStart(ModelView):
class ProcessProductionAsync(Wizard):
'Process Production Async'
__name__ = 'production.process_production_async'
start = StateView('production.process_production_async.start',
start = StateView(
'production.process_production_async.start',
'production_accounting.process_production_async_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Ok', 'accept', 'tryton-ok', default=True),
@ -456,11 +456,17 @@ class ProcessProductionAsync(Wizard):
'state': 'draft',
'lines': [('create', lines)],
'description': '',
# 'origin': ,
}])
Move.post([move])
print('Asiento creado No ', move.number)
def update_product_cost(self, producibles):
print('Actualizando update product cost')
for product, value in producibles.items():
cost = value['bom'].compute_unit_cost(value['quantity'])
product.average_cost = cost
product.save()
def create_stock_moves(self, producibles):
Move = Pool().get('stock.move')
date_ = self.start.date
@ -589,7 +595,6 @@ class ProcessProductionAsync(Wizard):
def transition_accept(self):
pool = Pool()
SaleLine = pool.get('sale.line')
# Shop = pool.get('sale.shop')
Period = pool.get('account.period')
Journal = pool.get('account.journal')
Configuration = pool.get('production.configuration')
@ -617,7 +622,6 @@ class ProcessProductionAsync(Wizard):
if not lines:
return 'end'
# shop = Shop(self.start.shop.id)
producibles = {}
for line in lines:
@ -637,6 +641,8 @@ class ProcessProductionAsync(Wizard):
}
if configuration.production_accounting:
self.create_production_moves(producibles, journal, period_id)
self.update_product_cost(producibles)
self.create_stock_moves(producibles)
SaleLine.write(lines, {'produced': True})
return 'end'
@ -668,7 +674,8 @@ class ProductionDetailedStart(ModelView):
class ProductionDetailed(Wizard):
'Production Detailed'
__name__ = 'production.detailed'
start = StateView('production.detailed.start',
start = StateView(
'production.detailed.start',
'production_accounting.production_detailed_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-ok', default=True),

13
sale.py
View File

@ -1,17 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from datetime import timedelta, date
from itertools import chain
from sql import Table
from decimal import Decimal
from trytond.model import fields, ModelSQL, ModelView
from trytond.model import fields
from trytond.pool import PoolMeta
# from trytond.pyson import Eval
# from trytond.transaction import Transaction
# from trytond.exceptions import UserError
# from trytond.report import Report
# from trytond.wizard import Wizard, StateView, Button, StateTransition, StateReport
class SaleLine(metaclass=PoolMeta):

View File

@ -1,4 +1,4 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta

View File

@ -1,5 +1,5 @@
[tryton]
version=6.0.6
version=6.0.7
depends:
party
company