cashbook_investment/book.py

258 lines
10 KiB
Python
Raw Normal View History

2022-12-21 23:32:26 +00:00
# -*- coding: utf-8 -*-
# This file is part of the cashbook-module from m-ds for Tryton.
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
from trytond.model import fields, SymbolMixin
2022-12-22 23:34:45 +00:00
from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval, Or, Len, Bool, If
2022-12-21 23:32:26 +00:00
from trytond.modules.cashbook.book import STATES2, DEPENDS2
2022-12-22 23:34:45 +00:00
from trytond.transaction import Transaction
from decimal import Decimal
from sql.functions import CurrentDate
from sql.aggregate import Sum
from sql.conditionals import Case, Coalesce
2022-12-21 23:32:26 +00:00
class Book(SymbolMixin, metaclass=PoolMeta):
2022-12-21 23:32:26 +00:00
__name__ = 'cashbook.book'
asset = fields.Many2One(string='Asset',
model_name='investment.asset', ondelete='RESTRICT',
states={
'required': Eval('feature', '') == 'asset',
'invisible': Eval('feature', '') != 'asset',
'readonly': Or(
STATES2['readonly'],
Len(Eval('lines')) > 0,
),
}, depends=DEPENDS2+['feature', 'lines'])
quantity_digits = fields.Integer(string='Digits',
help='Quantity Digits',
domain=[
('quantity_digits', '>=', 0),
('quantity_digits', '<=', 6),
],
states={
'required': Eval('feature', '') == 'asset',
'invisible': Eval('feature', '') != 'asset',
'readonly': Or(
STATES2['readonly'],
Len(Eval('lines')) > 0,
),
}, depends=DEPENDS2+['feature', 'lines'])
asset_uomcat = fields.Function(fields.Many2One(string='UOM Category',
readonly=True, model_name='product.uom.category',
states={'invisible': True}), 'on_change_with_asset_uomcat')
quantity_uom = fields.Many2One(string='UOM',
model_name='product.uom', ondelete='RESTRICT',
domain=[
('category.id', '=', Eval('asset_uomcat', -1)),
],
states={
'required': Eval('feature', '') == 'asset',
'invisible': Eval('feature', '') != 'asset',
'readonly': Or(
STATES2['readonly'],
Len(Eval('lines')) > 0,
),
}, depends=DEPENDS2+['feature', 'lines', 'asset_uomcat'])
symbol = fields.Function(fields.Char(string='Symbol', readonly=True),
'on_change_with_symbol')
2022-12-22 23:34:45 +00:00
quantity = fields.Function(fields.Numeric(string='Quantity',
help='Quantity of assets until to date', readonly=True,
digits=(16, Eval('quantity_digits', 4)),
states={
'invisible': Eval('feature', '') != 'asset',
}, depends=['quantity_digits', 'feature']),
'get_asset_quantity')
quantity_all = fields.Function(fields.Numeric(string='Total Quantity',
help='Total quantity of all assets', readonly=True,
digits=(16, Eval('quantity_digits', 4)),
states={
'invisible': Eval('feature', '') != 'asset',
}, depends=['quantity_digits', 'feature']),
'get_asset_quantity')
current_value = fields.Function(fields.Numeric(string='Value',
help='Valuation of the investment based on the current stock market price.',
2022-12-22 23:34:45 +00:00
readonly=True, digits=(16, Eval('currency_digits', 2)),
states={
'invisible': Eval('feature', '') != 'asset',
}, depends=['currency_digits', 'feature']),
'get_asset_quantity')
current_value_ref = fields.Function(fields.Numeric(string='Value (Ref.)',
help='Valuation of the investment based on the current stock exchange price, converted into the company currency.',
2022-12-22 23:34:45 +00:00
readonly=True, digits=(16, Eval('currency_digits', 2)),
states={
'invisible': Or(
Eval('feature', '') != 'asset',
~Bool(Eval('company_currency', -1)),
),
}, depends=['currency_digits', 'feature', 'company_currency']),
2022-12-22 23:34:45 +00:00
'get_asset_quantity')
2022-12-21 23:32:26 +00:00
# performance
diff_amount = fields.Function(fields.Numeric(string='Difference',
help='Difference between acquisition value and current value',
readonly=True, digits=(16, Eval('currency_digits', 2)),
2022-12-24 12:14:51 +00:00
states={
'invisible': Eval('feature', '') != 'asset',
}, depends=['currency_digits', 'feature']), 'get_asset_quantity')
diff_percent = fields.Function(fields.Numeric(string='Percent',
help='percentage performance since acquisition',
readonly=True, digits=(16, Eval('currency_digits', 2)),
2022-12-24 12:14:51 +00:00
states={
'invisible': Eval('feature', '') != 'asset',
}, depends=['currency_digits', 'feature']), 'get_asset_quantity')
current_rate = fields.Function(fields.Numeric(string='Rate',
help='Rate per unit of investment based on current stock exchange price.',
readonly=True, digits=(16, Eval('currency_digits', 2)),
states={
'invisible': Eval('feature', '') != 'asset',
}, depends=['currency_digits', 'feature']), 'get_asset_quantity')
@classmethod
def view_attributes(cls):
return super(Book, cls).view_attributes() + [
('/tree', 'visual',
If(Eval('feature', '') == 'asset',
If(Eval('diff_percent', 0) < 0, 'danger',
If(Eval('diff_percent', 0) > 0, 'success', '')
), '')
),
]
2022-12-21 23:32:26 +00:00
@fields.depends('asset', 'quantity_uom')
def on_change_asset(self):
""" get uom from asset
"""
if self.asset:
self.quantity_uom = self.asset.uom.id
@classmethod
def default_quantity_digits(cls):
""" default: 4
"""
return 4
2022-12-22 23:34:45 +00:00
@classmethod
def get_asset_quantity(cls, cashbooks, names):
""" get quantities
"""
pool = Pool()
CBook = pool.get('cashbook.book')
2022-12-24 12:14:51 +00:00
BookType = pool.get('cashbook.type')
2022-12-22 23:34:45 +00:00
Line = pool.get('cashbook.line')
Asset = pool.get('investment.asset')
Currency = pool.get('currency.currency')
Uom = pool.get('product.uom')
tab_book = CBook.__table__()
2022-12-24 12:14:51 +00:00
tab_type = BookType.__table__()
2022-12-22 23:34:45 +00:00
tab_line = Line.__table__()
tab_cur = Currency.__table__()
tab_asset = Asset.__table__()
(tab_rate, tab2) = Asset.get_rate_data_sql()
(tab_balance, tab2) = CBook.get_balance_of_cashbook_sql()
2022-12-22 23:34:45 +00:00
cursor = Transaction().connection.cursor()
context = Transaction().context
result = {x:{y.id: None for y in cashbooks} for x in names}
query_date = context.get('qdate', CurrentDate())
company_currency = CBook.default_currency()
query = tab_book.join(tab_line,
condition=(tab_book.id==tab_line.cashbook),
2022-12-24 12:14:51 +00:00
).join(tab_type,
condition=tab_book.btype==tab_type.id,
2022-12-22 23:34:45 +00:00
).join(tab_cur,
condition=tab_book.currency==tab_cur.id,
).join(tab_asset,
condition=tab_book.asset==tab_asset.id,
).join(tab_balance,
condition=tab_book.id==tab_balance.cashbook,
type_ = 'LEFT OUTER',
2022-12-22 23:34:45 +00:00
).join(tab_rate,
condition=tab_book.asset==tab_rate.id,
type_ = 'LEFT OUTER',
).select(
tab_book.id, # 0
Coalesce(Sum(Case(
(tab_line.date <= query_date, tab_line.quantity),
else_ = Decimal('0.0'),
)), Decimal('0.0')).as_('quantity'), # 1
Sum(tab_line.quantity).as_('quantity_all'), # 2
Coalesce(tab_rate.rate, Decimal('0.0')).as_('rate'), # 3
tab_book.currency, # 4
tab_cur.digits.as_('currency_digits'), # 5
tab_asset.uom, # 6
tab_book.quantity_uom, # 7
tab_asset.currency.as_('asset_currency'), #8
Coalesce(tab_balance.balance, Decimal('0.0')).as_('balance'), #9
2022-12-22 23:34:45 +00:00
group_by=[tab_book.id, tab_rate.rate,
tab_book.currency, tab_cur.digits, tab_asset.uom,
tab_book.quantity_uom, tab_asset.currency,
tab_balance.balance],
2022-12-24 12:14:51 +00:00
where=tab_book.id.in_([x.id for x in cashbooks]) & \
(tab_type.feature == 'asset'),
2022-12-22 23:34:45 +00:00
)
cursor.execute(*query)
records = cursor.fetchall()
for record in records:
# uom-factor
if record[6] == record[7]:
uom_factor = Decimal('1.0')
else :
uom_factor = Decimal(
Uom.compute_qty(Uom(record[6]), 1.0, Uom(record[7]), round=False)
)
current_value = Currency.compute(
record[8],
record[3] * record[1] / uom_factor,
record[4]
)
2022-12-22 23:34:45 +00:00
values = {
'quantity': record[1],
'quantity_all': record[2],
'current_value': current_value,
2022-12-22 23:34:45 +00:00
'current_value_ref': Currency.compute(
record[8],
record[3] * record[1] / uom_factor,
company_currency if company_currency is not None else record[8],
),
'diff_amount': current_value - record[9],
'diff_percent': (
Decimal('100.0') * current_value / \
record[9] - Decimal('100.0')
).quantize(Decimal(str(1/10**record[5]))) \
if record[9] != Decimal('0.0') else None,
2022-12-24 12:14:51 +00:00
'current_rate': (
current_value / record[1]
).quantize(Decimal(str(1/10**record[5]))) \
if record[1] != Decimal('0.0') else None,
2022-12-22 23:34:45 +00:00
}
for name in names:
result[name][record[0]] = values[name]
return result
@fields.depends('quantity_uom', 'currency')
def on_change_with_symbol(self, name=None):
""" get symbol for asset
"""
return '%(currency)s/%(unit)s' % {
'currency': getattr(self.currency, 'symbol', '-'),
'unit': getattr(self.quantity_uom, 'symbol', '-'),
}
2022-12-21 23:32:26 +00:00
@fields.depends('asset', '_parent_asset.uom')
def on_change_with_asset_uomcat(self, name=None):
""" get uom-category of asset
"""
if self.asset:
return self.asset.uom.category.id
# end Book