Files
2026-03-14 09:42:12 +00:00

233 lines
7.9 KiB
Python

# 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.model import fields
from trytond.modules.account_product.product import (
account_used, template_property)
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.transaction import Transaction
account_names = [
'account_stock', 'account_stock_in', 'account_stock_out']
class Category(metaclass=PoolMeta):
__name__ = 'product.category'
account_stock = fields.MultiValue(fields.Many2One(
'account.account', "Account Stock",
domain=[
('closed', '!=', True),
('type.stock', '=', True),
('type.statement', '=', 'balance'),
('company', '=', Eval('context', {}).get('company', -1)),
],
states={
'invisible': (~Eval('context', {}).get('company')
| Eval('account_parent')
| ~Eval('accounting', False)),
}))
account_stock_in = fields.MultiValue(fields.Many2One(
'account.account', "Account Stock IN",
domain=[
('closed', '!=', True),
('type.stock', '=', True),
('company', '=', Eval('context', {}).get('company', -1)),
],
states={
'invisible': (~Eval('context', {}).get('company')
| Eval('account_parent')
| ~Eval('accounting', False)),
}))
account_stock_out = fields.MultiValue(fields.Many2One(
'account.account', "Account Stock OUT",
domain=[
('closed', '!=', True),
('type.stock', '=', True),
('company', '=', Eval('context', {}).get('company', -1)),
],
states={
'invisible': (~Eval('context', {}).get('company')
| Eval('account_parent')
| ~Eval('accounting', False)),
}))
@classmethod
def __setup__(cls):
pool = Pool()
CategoryAccount = pool.get('product.category.account')
super().__setup__()
for account in [cls.account_stock_in, cls.account_stock_out]:
account.domain = [
account.domain,
('type.statement', 'in',
CategoryAccount.get_account_stock_type_statements()),
]
@classmethod
def multivalue_model(cls, field):
pool = Pool()
if field in account_names:
return pool.get('product.category.account')
return super().multivalue_model(field)
@property
@account_used('account_stock')
def account_stock_used(self):
pass
@property
@account_used('account_stock_in')
def account_stock_in_used(self):
pass
@property
@account_used('account_stock_out')
def account_stock_out_used(self):
pass
@fields.depends(
'accounting', 'account_stock', 'account_stock_in', 'account_stock_out')
def on_change_accounting(self):
super().on_change_accounting()
if not self.accounting:
self.account_stock = None
self.account_stock_in = None
self.account_stock_out = None
class CategoryAccount(metaclass=PoolMeta):
__name__ = 'product.category.account'
account_stock = fields.Many2One(
'account.account', "Account Stock",
domain=[
('closed', '!=', True),
('type.stock', '=', True),
('type.statement', '=', 'balance'),
('company', '=', Eval('company', -1)),
])
account_stock_in = fields.Many2One(
'account.account', "Account Stock IN",
domain=[
('closed', '!=', True),
('type.stock', '=', True),
('company', '=', Eval('company', -1)),
])
account_stock_out = fields.Many2One(
'account.account', "Account Stock OUT",
domain=[
('closed', '!=', True),
('type.stock', '=', True),
('company', '=', Eval('company', -1)),
])
@classmethod
def __setup__(cls):
super().__setup__()
for account in [cls.account_stock_in, cls.account_stock_out]:
account.domain = [
account.domain,
('type.statement', 'in',
cls.get_account_stock_type_statements()),
]
@classmethod
def get_account_stock_type_statements(cls):
return ['income']
class Template(metaclass=PoolMeta):
__name__ = 'product.template'
@classmethod
def __setup__(cls):
super().__setup__()
cls._modify_no_move.append(
('cost_price',
'account_stock_continental.msg_product_change_cost_price'))
@property
@account_used('account_stock', 'account_category')
def account_stock_used(self):
pass
@property
@account_used('account_stock_in', 'account_category')
def account_stock_in_used(self):
pass
@property
@account_used('account_stock_out', 'account_category')
def account_stock_out_used(self):
pass
class Product(metaclass=PoolMeta):
__name__ = 'product.product'
account_stock_used = template_property('account_stock_used')
account_stock_in_used = template_property('account_stock_in_used')
account_stock_out_used = template_property('account_stock_out_used')
@classmethod
def update_cost_price(cls, costs):
pool = Pool()
Date = pool.get('ir.date')
Stock = pool.get('stock.location')
Company = pool.get('company.company')
Move = pool.get('account.move')
Period = pool.get('account.period')
context = Transaction().context
locations = Stock.search([('type', '=', 'storage')])
company = Company(context['company'])
with Transaction().set_context(company=company.id):
stock_date_end = Date.today()
period = Period.find(company, date=stock_date_end)
if period.fiscalyear.account_stock_method:
moves = []
with Transaction().set_context(locations=[l.id for l in locations],
stock_date_end=stock_date_end):
for cost, products in costs.items():
products = cls.browse(products)
for product in products:
difference = cost - product.cost_price
quantity = product.quantity
amount = company.currency.round(
Decimal(str(quantity)) * difference)
if amount:
moves.append(product._update_cost_price_move(
amount, company, period, stock_date_end))
Move.save(moves)
Move.post(moves)
super().update_cost_price(costs)
def _update_cost_price_move(self, amount, company, period, date):
pool = Pool()
AccountConfiguration = pool.get('account.configuration')
Move = pool.get('account.move')
Line = pool.get('account.move.line')
config = AccountConfiguration(1)
if amount > 0:
account = self.account_stock_in_used
else:
account = self.account_stock_out_used
return Move(
period=period,
journal=config.stock_journal,
date=date,
origin=self,
lines=[Line(
debit=amount if amount > 0 else 0,
credit=-amount if amount < 0 else 0,
account=self.account_stock_used,
),
Line(
debit=-amount if amount < 0 else 0,
credit=amount if amount > 0 else 0,
account=account,
),
],
)