formatting

This commit is contained in:
Frederik Jaeckel 2023-12-03 17:31:42 +01:00
parent a7dda40f43
commit cce59eb8bf
5 changed files with 150 additions and 224 deletions

140
book.py
View file

@ -49,23 +49,20 @@ class Book(SymbolMixin, metaclass=PoolMeta):
'invisible': Eval('feature', '') != 'asset', 'invisible': Eval('feature', '') != 'asset',
'readonly': Or( 'readonly': Or(
STATES2['readonly'], STATES2['readonly'],
Len(Eval('lines')) > 0, Len(Eval('lines')) > 0)},
), depends=DEPENDS2+['feature', 'lines'])
}, depends=DEPENDS2+['feature', 'lines'])
quantity_digits = fields.Integer( quantity_digits = fields.Integer(
string='Digits', help='Quantity Digits', string='Digits', help='Quantity Digits',
domain=[ domain=[
('quantity_digits', '>=', 0), ('quantity_digits', '>=', 0),
('quantity_digits', '<=', 6), ('quantity_digits', '<=', 6)],
],
states={ states={
'required': Eval('feature', '') == 'asset', 'required': Eval('feature', '') == 'asset',
'invisible': Eval('feature', '') != 'asset', 'invisible': Eval('feature', '') != 'asset',
'readonly': Or( 'readonly': Or(
STATES2['readonly'], STATES2['readonly'],
Len(Eval('lines')) > 0, Len(Eval('lines')) > 0)},
), depends=DEPENDS2+['feature', 'lines'])
}, depends=DEPENDS2+['feature', 'lines'])
asset_uomcat = fields.Function(fields.Many2One( asset_uomcat = fields.Function(fields.Many2One(
string='UOM Category', readonly=True, string='UOM Category', readonly=True,
model_name='product.uom.category', model_name='product.uom.category',
@ -73,17 +70,14 @@ class Book(SymbolMixin, metaclass=PoolMeta):
quantity_uom = fields.Many2One( quantity_uom = fields.Many2One(
string='UOM', select=True, string='UOM', select=True,
model_name='product.uom', ondelete='RESTRICT', model_name='product.uom', ondelete='RESTRICT',
domain=[ domain=[('category.id', '=', Eval('asset_uomcat', -1))],
('category.id', '=', Eval('asset_uomcat', -1)),
],
states={ states={
'required': Eval('feature', '') == 'asset', 'required': Eval('feature', '') == 'asset',
'invisible': Eval('feature', '') != 'asset', 'invisible': Eval('feature', '') != 'asset',
'readonly': Or( 'readonly': Or(
STATES2['readonly'], STATES2['readonly'],
Len(Eval('lines')) > 0, Len(Eval('lines')) > 0)},
), depends=DEPENDS2+['feature', 'lines', 'asset_uomcat'])
}, depends=DEPENDS2+['feature', 'lines', 'asset_uomcat'])
symbol = fields.Function(fields.Char( symbol = fields.Function(fields.Char(
string='Symbol', readonly=True), 'on_change_with_symbol') string='Symbol', readonly=True), 'on_change_with_symbol')
asset_symbol = fields.Function(fields.Many2One( asset_symbol = fields.Function(fields.Many2One(
@ -92,25 +86,20 @@ class Book(SymbolMixin, metaclass=PoolMeta):
quantity = fields.Function(fields.Numeric( quantity = fields.Function(fields.Numeric(
string='Quantity', help='Quantity of assets until to date', string='Quantity', help='Quantity of assets until to date',
readonly=True, digits=(16, Eval('quantity_digits', 4)), readonly=True, digits=(16, Eval('quantity_digits', 4)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['quantity_digits', 'feature']), 'get_asset_quantity')
}, depends=['quantity_digits', 'feature']),
'get_asset_quantity')
quantity_all = fields.Function(fields.Numeric( quantity_all = fields.Function(fields.Numeric(
string='Total Quantity', help='Total quantity of all assets', string='Total Quantity', help='Total quantity of all assets',
readonly=True, digits=(16, Eval('quantity_digits', 4)), readonly=True, digits=(16, Eval('quantity_digits', 4)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['quantity_digits', 'feature']), 'get_asset_quantity')
}, depends=['quantity_digits', 'feature']),
'get_asset_quantity')
current_value = fields.Function(fields.Numeric( current_value = fields.Function(fields.Numeric(
string='Value', string='Value',
help='Valuation of the investment based on the current ' + help='Valuation of the investment based on the current ' +
'stock market price.', 'stock market price.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': ~Eval('show_performance', False)},
'invisible': Eval('show_performance', False) == False, depends=['currency_digits', 'show_performance']),
}, depends=['currency_digits', 'show_performance']),
'get_asset_quantity') 'get_asset_quantity')
current_value_ref = fields.Function(fields.Numeric( current_value_ref = fields.Function(fields.Numeric(
string='Value (Ref.)', string='Value (Ref.)',
@ -119,10 +108,9 @@ class Book(SymbolMixin, metaclass=PoolMeta):
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={
'invisible': Or( 'invisible': Or(
Eval('show_performance', False) == False, ~Eval('show_performance', False),
~Bool(Eval('company_currency', -1)), ~Bool(Eval('company_currency', -1)))},
), depends=['currency_digits', 'show_performance', 'company_currency']),
}, depends=['currency_digits', 'show_performance', 'company_currency']),
'get_asset_quantity') 'get_asset_quantity')
# performance # performance
@ -130,92 +118,78 @@ class Book(SymbolMixin, metaclass=PoolMeta):
string='Difference', string='Difference',
help='Difference between acquisition value and current value', help='Difference between acquisition value and current value',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': ~Eval('show_performance', False)},
'invisible': Eval('show_performance', False) == False, depends=['currency_digits', 'show_performance']),
}, depends=['currency_digits', 'show_performance']),
'get_asset_quantity') 'get_asset_quantity')
diff_percent = fields.Function(fields.Numeric( diff_percent = fields.Function(fields.Numeric(
string='Percent', string='Percent',
help='percentage performance since acquisition', help='percentage performance since acquisition',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': ~Eval('show_performance', False)},
'invisible': Eval('show_performance', False) == False, depends=['currency_digits', 'show_performance']),
}, depends=['currency_digits', 'show_performance']),
'get_asset_quantity') 'get_asset_quantity')
show_performance = fields.Function(fields.Boolean( show_performance = fields.Function(fields.Boolean(
string='Performance', readonly=True), string='Performance', readonly=True), 'on_change_with_show_performance')
'on_change_with_show_performance')
current_rate = fields.Function(fields.Numeric( current_rate = fields.Function(fields.Numeric(
string='Rate', string='Rate',
help='Rate per unit of investment based on current stock ' + help='Rate per unit of investment based on current stock ' +
'exchange price.', 'exchange price.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_asset_quantity')
}, depends=['currency_digits', 'feature']), 'get_asset_quantity')
purchase_amount = fields.Function(fields.Numeric( purchase_amount = fields.Function(fields.Numeric(
string='Purchase Amount', string='Purchase Amount',
help='Total purchase amount, from shares and fees.', help='Total purchase amount, from shares and fees.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_asset_quantity')
}, depends=['currency_digits', 'feature']),
'get_asset_quantity')
# yield # yield
yield_dividend_total = fields.Function(fields.Numeric( yield_dividend_total = fields.Function(fields.Numeric(
string='Dividend', help='Total dividends received', string='Dividend', help='Total dividends received',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_yield_data')
}, depends=['currency_digits', 'feature']), 'get_yield_data')
yield_dividend_12m = fields.Function(fields.Numeric( yield_dividend_12m = fields.Function(fields.Numeric(
string='Dividend 1y', string='Dividend 1y',
help='Dividends received in the last twelve months', help='Dividends received in the last twelve months',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_yield_data')
}, depends=['currency_digits', 'feature']), 'get_yield_data')
yield_fee_total = fields.Function(fields.Numeric( yield_fee_total = fields.Function(fields.Numeric(
string='Trade Fee', help='Total trade fees payed', string='Trade Fee', help='Total trade fees payed',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_yield_data')
}, depends=['currency_digits', 'feature']), 'get_yield_data')
yield_fee_12m = fields.Function(fields.Numeric( yield_fee_12m = fields.Function(fields.Numeric(
string='Trade Fee 1y', string='Trade Fee 1y',
help='Trade fees payed in the last twelve month', help='Trade fees payed in the last twelve month',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_yield_data')
}, depends=['currency_digits', 'feature']), 'get_yield_data')
yield_sales = fields.Function(fields.Numeric( yield_sales = fields.Function(fields.Numeric(
string='Sales', help='Total profit or loss on sale of shares.', string='Sales', help='Total profit or loss on sale of shares.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_yield_data')
}, depends=['currency_digits', 'feature']), 'get_yield_data')
yield_sales_12m = fields.Function(fields.Numeric( yield_sales_12m = fields.Function(fields.Numeric(
string='Sales 1y', string='Sales 1y',
help='Total profit or loss on sale of shares in the last twelve month.', help='Total profit or loss on sale of shares in the last twelve month.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'get_yield_data')
}, depends=['currency_digits', 'feature']), 'get_yield_data')
yield_balance = fields.Function(fields.Numeric( yield_balance = fields.Function(fields.Numeric(
string='Total Yield', string='Total Yield',
help='Total income: price gain + dividends + sales gains - fees', help='Total income: price gain + dividends + sales gains - fees',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'on_change_with_yield_balance')
}, depends=['currency_digits', 'feature']),
'on_change_with_yield_balance')
@classmethod @classmethod
def view_attributes(cls): def view_attributes(cls):
return super(Book, cls).view_attributes() + [ return super(Book, cls).view_attributes() + [
('/tree', 'visual', ('/tree', 'visual',
If(Eval('show_performance', False) == True, If(Eval('show_performance', False),
If(Eval('diff_percent', 0) < 0, 'danger', If(Eval('diff_percent', 0) < 0, 'danger',
If(Eval('diff_percent', 0) > 0, If(Eval('diff_percent', 0) > 0,
'success', '')), '')), 'success', '')), '')),
@ -295,8 +269,7 @@ class Book(SymbolMixin, metaclass=PoolMeta):
Sum(tab_line_gainloss.gainloss).as_('gainloss'), Sum(tab_line_gainloss.gainloss).as_('gainloss'),
tab_cur.digits.as_('currency_digits'), tab_cur.digits.as_('currency_digits'),
group_by=[tab_book.id, tab_cur.digits], group_by=[tab_book.id, tab_cur.digits],
where=where where=where)
)
return (tab_book, query) return (tab_book, query)
@classmethod @classmethod
@ -457,8 +430,7 @@ class Book(SymbolMixin, metaclass=PoolMeta):
tab_book.currency, tab_cur.digits, tab_asset.uom, tab_book.currency, tab_cur.digits, tab_asset.uom,
tab_book.quantity_uom, tab_asset.currency, tab_book.quantity_uom, tab_asset.currency,
tab_balance.balance], tab_balance.balance],
where=(tab_type.feature == 'asset'), where=(tab_type.feature == 'asset'))
)
return (query, tab_book) return (query, tab_book)
@classmethod @classmethod
@ -529,14 +501,12 @@ class Book(SymbolMixin, metaclass=PoolMeta):
uom_factor = Decimal( uom_factor = Decimal(
Uom.compute_qty( Uom.compute_qty(
Uom(rdata[6]), 1.0, Uom(rdata[6]), 1.0,
Uom(rdata[7]), round=False) Uom(rdata[7]), round=False))
)
current_value = Currency.compute( current_value = Currency.compute(
rdata[8], rdata[8],
rdata[3] * rdata[1] / uom_factor, rdata[3] * rdata[1] / uom_factor,
rdata[4] rdata[4])
)
return (record[0], { return (record[0], {
'quantity': rdata[1], 'quantity': rdata[1],
'quantity_all': rdata[2], 'quantity_all': rdata[2],
@ -545,8 +515,7 @@ class Book(SymbolMixin, metaclass=PoolMeta):
rdata[8], rdata[8],
rdata[3] * rdata[1] / uom_factor, rdata[3] * rdata[1] / uom_factor,
company_currency company_currency
if company_currency is not None else rdata[8], if company_currency is not None else rdata[8]),
),
'diff_amount': current_value - rdata[9], 'diff_amount': current_value - rdata[9],
'diff_percent': ( 'diff_percent': (
Decimal('100.0') * current_value / Decimal('100.0') * current_value /
@ -563,8 +532,7 @@ class Book(SymbolMixin, metaclass=PoolMeta):
rdata[4], rdata[4],
record[9], record[9],
company_currency company_currency
if company_currency is not None else rdata[4], if company_currency is not None else rdata[4]),
),
}) })
ids_assetbooks = [x.id for x in cashbooks if x.btype is not None] ids_assetbooks = [x.id for x in cashbooks if x.btype is not None]
@ -617,8 +585,7 @@ class Book(SymbolMixin, metaclass=PoolMeta):
tab_book.id, tab_quantity.rate, tab_book.id, tab_quantity.rate,
tab_quantity.currency, tab_quantity.currency_digits, tab_quantity.currency, tab_quantity.currency_digits,
tab_quantity.uom, tab_quantity.quantity_uom, tab_quantity.uom, tab_quantity.quantity_uom,
tab_quantity.asset_currency, tab_book.currency], tab_quantity.asset_currency, tab_book.currency])
)
cursor.execute(*query) cursor.execute(*query)
records = cursor.fetchall() records = cursor.fetchall()
@ -637,16 +604,14 @@ class Book(SymbolMixin, metaclass=PoolMeta):
company_currency company_currency
if company_currency is not None else record[4], if company_currency is not None else record[4],
values['current_value_ref'], values['current_value_ref'],
record[10], record[10])
)
elif name == 'diff_amount': elif name == 'diff_amount':
value = Currency.compute( value = Currency.compute(
company_currency company_currency
if company_currency is not None else record[4], if company_currency is not None else record[4],
values['current_value_ref'] - values['current_value_ref'] -
values['purchase_amount_ref'], values['purchase_amount_ref'],
record[10], record[10])
)
elif name in ['current_value_ref', 'purchase_amount_ref']: elif name in ['current_value_ref', 'purchase_amount_ref']:
value = values[name] value = values[name]
result['digits'][book_id] = record[5] result['digits'][book_id] = record[5]
@ -697,8 +662,7 @@ class Book(SymbolMixin, metaclass=PoolMeta):
""" """
return '%(currency)s/%(unit)s' % { return '%(currency)s/%(unit)s' % {
'currency': getattr(self.currency, 'symbol', '-'), 'currency': getattr(self.currency, 'symbol', '-'),
'unit': getattr(self.quantity_uom, 'symbol', '-'), 'unit': getattr(self.quantity_uom, 'symbol', '-')}
}
@fields.depends('asset', '_parent_asset.uom') @fields.depends('asset', '_parent_asset.uom')
def on_change_with_asset_uomcat(self, name=None): def on_change_with_asset_uomcat(self, name=None):

184
line.py
View file

@ -14,21 +14,19 @@ from trytond.i18n import gettext
from trytond.report import Report from trytond.report import Report
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.modules.cashbook.line import STATES, DEPENDS from trytond.modules.cashbook.line import STATES, DEPENDS
from trytond.modules.cashbook.const import DEF_NONE
from .mixin import SecondUomMixin from .mixin import SecondUomMixin
STATESQ1 = { STATESQ1 = {
'invisible': And( 'invisible': And(
Eval('feature', '') != 'asset', Eval('feature', '') != 'asset',
Eval('booktransf_feature', '') != 'asset', Eval('booktransf_feature', '') != 'asset'),
),
'required': Or( 'required': Or(
Eval('feature', '') == 'asset', Eval('feature', '') == 'asset',
Eval('booktransf_feature', '') == 'asset', Eval('booktransf_feature', '') == 'asset'),
),
'readonly': Or( 'readonly': Or(
STATES['readonly'], STATES['readonly'],
Eval('bookingtype', '').in_(['spin', 'spout']), Eval('bookingtype', '').in_(['spin', 'spout'])),
),
} }
DEPENDSQ1 = ['feature', 'booktransf_feature', 'quantity_digits', 'bookingtype'] DEPENDSQ1 = ['feature', 'booktransf_feature', 'quantity_digits', 'bookingtype']
DEPENDSQ1.extend(DEPENDS) DEPENDSQ1.extend(DEPENDS)
@ -38,14 +36,12 @@ STATESQ1B.update(STATESQ1)
STATESQ1B['invisible'] = And( STATESQ1B['invisible'] = And(
Eval('feature', '') != 'asset', Eval('feature', '') != 'asset',
Eval('booktransf_feature', '') != 'asset', Eval('booktransf_feature', '') != 'asset',
Eval('splitline_has_quantity', False) == False, ~Eval('splitline_has_quantity', False))
)
STATESQ2 = { STATESQ2 = {
'invisible': Eval('feature', '') != 'asset', 'invisible': Eval('feature', '') != 'asset',
'required': Eval('feature', '') == 'asset', 'required': Eval('feature', '') == 'asset'}
}
DEPENDSQ2 = ['feature', 'quantity_digits', 'bookingtype'] DEPENDSQ2 = ['feature', 'quantity_digits', 'bookingtype']
@ -66,30 +62,26 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
states=STATESQ2, depends=DEPENDSQ2) states=STATESQ2, depends=DEPENDSQ2)
quantity_digits = fields.Function(fields.Integer( quantity_digits = fields.Function(fields.Integer(
string='Digits', string='Digits', readonly=True, states={'invisible': True}),
readonly=True, states={'invisible': True}),
'on_change_with_quantity_digits') 'on_change_with_quantity_digits')
quantity_uom = fields.Function(fields.Many2One( quantity_uom = fields.Function(fields.Many2One(
string='Symbol', string='Symbol', readonly=True, model_name='product.uom'),
readonly=True, model_name='product.uom'),
'on_change_with_quantity_uom') 'on_change_with_quantity_uom')
asset_rate = fields.Function(fields.Numeric( asset_rate = fields.Function(fields.Numeric(
string='Rate', readonly=True, string='Rate', readonly=True,
digits=(16, If( digits=(16, If(
Eval('currency_digits', 2) > Eval('quantity_digits', 2), Eval('currency_digits', 2) > Eval('quantity_digits', 2),
Eval('currency_digits', 2), Eval('quantity_digits', 2))), Eval('currency_digits', 2), Eval('quantity_digits', 2))),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'quantity_digits', 'feature']),
}, depends=['currency_digits', 'quantity_digits', 'feature']),
'on_change_with_asset_rate') 'on_change_with_asset_rate')
quantity_balance = fields.Function(fields.Numeric( quantity_balance = fields.Function(fields.Numeric(
string='Quantity', string='Quantity',
digits=(16, Eval('quantity_digits', 4)), readonly=True, digits=(16, Eval('quantity_digits', 4)), readonly=True,
help='Number of shares in the cashbook up to the current ' + help='Number of shares in the cashbook up to the current ' +
'row if the default sort applies.', 'row if the default sort applies.',
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['quantity_digits', 'feature']),
}, depends=['quantity_digits', 'feature']),
'on_change_with_quantity_balance') 'on_change_with_quantity_balance')
splitline_has_quantity = fields.Function(fields.Boolean( splitline_has_quantity = fields.Function(fields.Boolean(
string='has quantity', readonly=True, states={'invisible': True}), string='has quantity', readonly=True, states={'invisible': True}),
@ -101,50 +93,42 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
help='Valuation of the investment based on the current ' + help='Valuation of the investment based on the current ' +
'stock market price.', 'stock market price.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']),
}, depends=['currency_digits', 'feature']),
'on_change_with_current_value') 'on_change_with_current_value')
diff_amount = fields.Function(fields.Numeric( diff_amount = fields.Function(fields.Numeric(
string='Difference', string='Difference',
help='Difference between acquisition value and current value', help='Difference between acquisition value and current value',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'on_change_with_diff_amount')
}, depends=['currency_digits', 'feature']),
'on_change_with_diff_amount')
diff_percent = fields.Function(fields.Numeric( diff_percent = fields.Function(fields.Numeric(
string='Percent', string='Percent',
help='percentage performance since acquisition', help='percentage performance since acquisition',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']), 'on_change_with_diff_percent')
}, depends=['currency_digits', 'feature']),
'on_change_with_diff_percent')
trade_fee = fields.Function(fields.Numeric( trade_fee = fields.Function(fields.Numeric(
string='Fee', string='Fee',
help='Trading fee for the current booking line.', help='Trading fee for the current booking line.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']),
}, depends=['currency_digits', 'feature']),
'get_yield_data', searcher='search_trade_fee') 'get_yield_data', searcher='search_trade_fee')
asset_dividend = fields.Function(fields.Numeric( asset_dividend = fields.Function(fields.Numeric(
string='Dividend', string='Dividend',
help='Dividend received at the current booking line.', help='Dividend received at the current booking line.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']),
}, depends=['currency_digits', 'feature']),
'get_yield_data', searcher='search_asset_dividend') 'get_yield_data', searcher='search_asset_dividend')
asset_gainloss = fields.Function(fields.Numeric( asset_gainloss = fields.Function(fields.Numeric(
string='Profit/Loss', string='Profit/Loss',
help='Profit or loss on sale on the current booking line.', help='Profit or loss on sale on the current booking line.',
readonly=True, digits=(16, Eval('currency_digits', 2)), readonly=True, digits=(16, Eval('currency_digits', 2)),
states={ states={'invisible': Eval('feature', '') != 'asset'},
'invisible': Eval('feature', '') != 'asset', depends=['currency_digits', 'feature']),
}, depends=['currency_digits', 'feature']),
'get_yield_data', searcher='search_asset_gainloss') 'get_yield_data', searcher='search_asset_gainloss')
@classmethod @classmethod
@ -176,7 +160,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
tab_mvsp_counterpart, tab_mvsp_counterpart,
# [MV-SP] transfer booking, # [MV-SP] transfer booking,
# select counterpart [1] - a split-booking # select counterpart [1] - a split-booking
condition=tab_line.bookingtype.in_(['mvin', 'mvout']) & \ condition=tab_line.bookingtype.in_(['mvin', 'mvout']) &
((tab_line.reference == tab_mvsp_counterpart.id) | ((tab_line.reference == tab_mvsp_counterpart.id) |
(tab_line.id == tab_mvsp_counterpart.reference)) & (tab_line.id == tab_mvsp_counterpart.reference)) &
(tab_mvsp_counterpart.bookingtype.in_(['spin', 'spout'])), (tab_mvsp_counterpart.bookingtype.in_(['spin', 'spout'])),
@ -185,9 +169,9 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
tab_mv_spline, tab_mv_spline,
# [MV-SP] line is linked to split-booking-line # [MV-SP] line is linked to split-booking-line
# of counterpart [1] # of counterpart [1]
condition=(tab_mv_spline.line == tab_mvsp_counterpart.id) & \ condition=(tab_mv_spline.line == tab_mvsp_counterpart.id) &
(tab_mv_spline.splittype == 'tr') & \ (tab_mv_spline.splittype == 'tr') &
(tab_mv_spline.booktransf != None) & \ (tab_mv_spline.booktransf != DEF_NONE) &
(tab_mv_spline.booktransf == gainloss_book), (tab_mv_spline.booktransf == gainloss_book),
type_='LEFT OUTER', type_='LEFT OUTER',
@ -195,20 +179,20 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
tab_spmv_counterpart, tab_spmv_counterpart,
# [SP-MV] split booking, select counterpart [1] # [SP-MV] split booking, select counterpart [1]
# - a transfer-booking # - a transfer-booking
condition=tab_line.bookingtype.in_(['spin', 'spout']) & \ condition=tab_line.bookingtype.in_(['spin', 'spout']) &
((tab_line.reference == tab_spmv_counterpart.id) | \ ((tab_line.reference == tab_spmv_counterpart.id) |
(tab_line.id == tab_spmv_counterpart.reference)) & \ (tab_line.id == tab_spmv_counterpart.reference)) &
tab_spmv_counterpart.bookingtype.in_(['mvin', 'mvout']) & \ tab_spmv_counterpart.bookingtype.in_(['mvin', 'mvout']) &
(tab_spmv_counterpart.cashbook == gainloss_book), (tab_spmv_counterpart.cashbook == gainloss_book),
type_='LEFT OUTER', type_='LEFT OUTER',
).join( ).join(
tab_mvmv_counterpart, tab_mvmv_counterpart,
# [MV-MV] transfer booking # [MV-MV] transfer booking
condition=tab_line.bookingtype.in_(['mvin', 'mvout']) & \ condition=tab_line.bookingtype.in_(['mvin', 'mvout']) &
((tab_mvmv_counterpart.reference == tab_line.id) | \ ((tab_mvmv_counterpart.reference == tab_line.id) |
(tab_mvmv_counterpart.id == tab_line.reference)) & \ (tab_mvmv_counterpart.id == tab_line.reference)) &
tab_mvmv_counterpart.bookingtype.in_(['mvin', 'mvout']) & \ tab_mvmv_counterpart.bookingtype.in_(['mvin', 'mvout']) &
(tab_mvmv_counterpart.cashbook == gainloss_book), (tab_mvmv_counterpart.cashbook == gainloss_book),
type_='LEFT OUTER', type_='LEFT OUTER',
).select( ).select(
@ -218,17 +202,14 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
Case( Case(
(tab_line.bookingtype == 'mvin', tab_mv_spline.amount), (tab_line.bookingtype == 'mvin', tab_mv_spline.amount),
(tab_line.bookingtype == 'mvout', (tab_line.bookingtype == 'mvout',
tab_mv_spline.amount * Decimal('-1.0')), tab_mv_spline.amount * Decimal('-1.0'))),
),
Case( Case(
(tab_mvsp_counterpart.cashbook == gainloss_book, (tab_mvsp_counterpart.cashbook == gainloss_book,
tab_line.debit - tab_line.credit), tab_line.debit - tab_line.credit)),
),
tab_spmv_counterpart.credit - tab_spmv_counterpart.debit, tab_spmv_counterpart.credit - tab_spmv_counterpart.debit,
Decimal('0.0'), Decimal('0.0'),
) * Decimal('-1.0')).as_('gainloss'), ) * Decimal('-1.0')).as_('gainloss'),
tab_line.cashbook, tab_line.cashbook)
)
return (tab_line, query) return (tab_line, query)
@classmethod @classmethod
@ -262,17 +243,17 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
).join( ).join(
tab_inout_fee, tab_inout_fee,
# [INOUT] fee, local booked # [INOUT] fee, local booked
condition=(tab_inout_fee.id == tab_line.id) & \ condition=(tab_inout_fee.id == tab_line.id) &
tab_inout_fee.bookingtype.in_(['in', 'out']) & \ tab_inout_fee.bookingtype.in_(['in', 'out']) &
(tab_inout_fee.category != None) & \ (tab_inout_fee.category != DEF_NONE) &
(tab_inout_fee.category == fee_category), (tab_inout_fee.category == fee_category),
type_='LEFT OUTER', type_='LEFT OUTER',
).join( ).join(
tab_inout_divi, tab_inout_divi,
# [INOUT] dividend, local booked # [INOUT] dividend, local booked
condition=(tab_inout_divi.id == tab_line.id) & \ condition=(tab_inout_divi.id == tab_line.id) &
tab_inout_divi.bookingtype.in_(['in', 'out']) & \ tab_inout_divi.bookingtype.in_(['in', 'out']) &
(tab_inout_divi.category != None) & \ (tab_inout_divi.category != DEF_NONE) &
(tab_inout_divi.category == dividend_category), (tab_inout_divi.category == dividend_category),
type_='LEFT OUTER', type_='LEFT OUTER',
@ -280,46 +261,46 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
tab_mv_counterpart, tab_mv_counterpart,
# [MV] transfer booking, select counterpart [1] # [MV] transfer booking, select counterpart [1]
# - a split-booking # - a split-booking
condition=tab_line.bookingtype.in_(['mvin', 'mvout']) & \ condition=tab_line.bookingtype.in_(['mvin', 'mvout']) &
((tab_line.reference == tab_mv_counterpart.id) | \ ((tab_line.reference == tab_mv_counterpart.id) |
(tab_line.id == tab_mv_counterpart.reference)) & \ (tab_line.id == tab_mv_counterpart.reference)) &
(tab_mv_counterpart.bookingtype.in_(['spin', 'spout'])), (tab_mv_counterpart.bookingtype.in_(['spin', 'spout'])),
type_='LEFT OUTER', type_='LEFT OUTER',
).join( ).join(
tab_mv_spline_fee, tab_mv_spline_fee,
# [MV] fee-line is linked to split-booking-line # [MV] fee-line is linked to split-booking-line
# of counterpart [1] # of counterpart [1]
condition=(tab_mv_spline_fee.line == tab_mv_counterpart.id) & \ condition=(tab_mv_spline_fee.line == tab_mv_counterpart.id) &
(tab_mv_spline_fee.splittype == 'cat') & \ (tab_mv_spline_fee.splittype == 'cat') &
(tab_mv_spline_fee.category != None) & \ (tab_mv_spline_fee.category != DEF_NONE) &
(tab_mv_spline_fee.category == fee_category), (tab_mv_spline_fee.category == fee_category),
type_='LEFT OUTER', type_='LEFT OUTER',
).join( ).join(
tab_mv_spline_divi, tab_mv_spline_divi,
# [MV] dividend-line is linked to split-booking-line # [MV] dividend-line is linked to split-booking-line
# of counterpart [1] # of counterpart [1]
condition=(tab_mv_spline_divi.line == tab_mv_counterpart.id) & \ condition=(tab_mv_spline_divi.line == tab_mv_counterpart.id) &
(tab_mv_spline_divi.splittype == 'cat') & \ (tab_mv_spline_divi.splittype == 'cat') &
(tab_mv_spline_divi.category != None) & \ (tab_mv_spline_divi.category != DEF_NONE) &
(tab_mv_spline_divi.category == dividend_category), (tab_mv_spline_divi.category == dividend_category),
type_='LEFT OUTER', type_='LEFT OUTER',
).join( ).join(
tab_spline_fee, tab_spline_fee,
# [SP] fee, split booking # [SP] fee, split booking
condition=(tab_spline_fee.line == tab_line.id) & \ condition=(tab_spline_fee.line == tab_line.id) &
tab_line.bookingtype.in_(['spin', 'spout']) & \ tab_line.bookingtype.in_(['spin', 'spout']) &
(tab_spline_fee.splittype == 'cat') & \ (tab_spline_fee.splittype == 'cat') &
(tab_spline_fee.category != None) & \ (tab_spline_fee.category != DEF_NONE) &
(tab_spline_fee.category == fee_category), (tab_spline_fee.category == fee_category),
type_='LEFT OUTER', type_='LEFT OUTER',
).join( ).join(
tab_spline_divi, tab_spline_divi,
# [SP] dividend, split booking # [SP] dividend, split booking
condition=(tab_spline_divi.line == tab_line.id) & \ condition=(tab_spline_divi.line == tab_line.id) &
tab_line.bookingtype.in_(['spin', 'spout']) & \ tab_line.bookingtype.in_(['spin', 'spout']) &
(tab_spline_divi.splittype == 'cat') & \ (tab_spline_divi.splittype == 'cat') &
(tab_spline_divi.category != None) & \ (tab_spline_divi.category != DEF_NONE) &
(tab_spline_divi.category == dividend_category), (tab_spline_divi.category == dividend_category),
type_='LEFT OUTER', type_='LEFT OUTER',
).select( ).select(
@ -350,8 +331,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
Decimal('0.0'), Decimal('0.0'),
)).as_('dividend'), )).as_('dividend'),
tab_line.cashbook, tab_line.cashbook,
group_by=[tab_line.id, tab_line.cashbook], group_by=[tab_line.id, tab_line.cashbook])
)
return (tab_line, query) return (tab_line, query)
@classmethod @classmethod
@ -363,8 +343,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
query = tab_query.select( query = tab_query.select(
tab_query.id, tab_query.id,
where=Operator(tab_query.fee, clause[2]), where=Operator(tab_query.fee, clause[2]))
)
return [('id', 'in', query)] return [('id', 'in', query)]
@classmethod @classmethod
@ -376,8 +355,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
query = tab_query.select( query = tab_query.select(
tab_query.id, tab_query.id,
where=Operator(tab_query.dividend, clause[2]), where=Operator(tab_query.dividend, clause[2]))
)
return [('id', 'in', query)] return [('id', 'in', query)]
@classmethod @classmethod
@ -389,8 +367,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
query = tab_query.select( query = tab_query.select(
tab_query.id, tab_query.id,
where=Operator(tab_query.gainloss, clause[2]), where=Operator(tab_query.gainloss, clause[2]))
)
return [('id', 'in', query)] return [('id', 'in', query)]
@classmethod @classmethod
@ -421,8 +398,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
line = Line2(record[0]) line = Line2(record[0])
values = { values = {
'trade_fee': quantize_val(record[1], line), 'trade_fee': quantize_val(record[1], line),
'asset_dividend': quantize_val(record[2], line), 'asset_dividend': quantize_val(record[2], line)}
}
for name in list(name_set): for name in list(name_set):
result[name][record[0]] = values[name] result[name][record[0]] = values[name]
@ -452,8 +428,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
'quantity': Report.format_number( 'quantity': Report.format_number(
credit - debit, credit - debit,
lang=None, digits=self.quantity_digits), lang=None, digits=self.quantity_digits),
'uom_symbol': getattr(self.quantity_uom, 'symbol', '-'), 'uom_symbol': getattr(self.quantity_uom, 'symbol', '-')}
}
return recname return recname
@classmethod @classmethod
@ -516,8 +491,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
result = super(Line, cls).get_counterpart_values( result = super(Line, cls).get_counterpart_values(
line, line,
splitline=splitline, splitline=splitline,
values=values values=values)
)
line_uom = getattr(line.quantity_uom, 'id', None) line_uom = getattr(line.quantity_uom, 'id', None)
booktransf_uom = getattr(getattr( booktransf_uom = getattr(getattr(
@ -543,27 +517,23 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
if (asset_books == 2) and (diff_uom is True) if (asset_books == 2) and (diff_uom is True)
else splitline.quantity, else splitline.quantity,
'quantity_2nd_uom': splitline.quantity 'quantity_2nd_uom': splitline.quantity
if (asset_books == 2) and (diff_uom is True) else None, if (asset_books == 2) and (diff_uom is True) else None})
})
elif sum([1 if booktransf_uom is not None else 0, elif sum([1 if booktransf_uom is not None else 0,
1 if line_uom is not None else 0]) == 1: 1 if line_uom is not None else 0]) == 1:
# one of the related cashbooks only is asset-type # one of the related cashbooks only is asset-type
result.update({ result.update({
'quantity': line.quantity, 'quantity': line.quantity,
'quantity_2nd_uom': None, 'quantity_2nd_uom': None})
})
elif sum([1 if booktransf_uom is not None else 0, elif sum([1 if booktransf_uom is not None else 0,
1 if line_uom is not None else 0]) == 2: 1 if line_uom is not None else 0]) == 2:
if line_uom == booktransf_uom: if line_uom == booktransf_uom:
result.update({ result.update({
'quantity': line.quantity, 'quantity': line.quantity,
'quantity_2nd_uom': None, 'quantity_2nd_uom': None})
})
else: else:
result.update({ result.update({
'quantity': line.quantity_2nd_uom, 'quantity': line.quantity_2nd_uom,
'quantity_2nd_uom': line.quantity, 'quantity_2nd_uom': line.quantity})
})
return result return result
@fields.depends('amount', 'splitlines', 'quantity') @fields.depends('amount', 'splitlines', 'quantity')
@ -728,8 +698,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
(line.quantity_debit is None): (line.quantity_debit is None):
raise UserError(gettext( raise UserError(gettext(
'cashbook_investment.msg_line_quantity_not_set', 'cashbook_investment.msg_line_quantity_not_set',
linetxt=line.rec_name, linetxt=line.rec_name))
))
# quantity and amount must with same sign # quantity and amount must with same sign
if (line.amount != Decimal('0.0')) and \ if (line.amount != Decimal('0.0')) and \
@ -739,8 +708,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
if amount_sign != quantity_sign: if amount_sign != quantity_sign:
raise UserError(gettext( raise UserError(gettext(
'cashbook_investment.msg_line_sign_mismatch', 'cashbook_investment.msg_line_sign_mismatch',
linetxt=line.rec_name, linetxt=line.rec_name))
))
@classmethod @classmethod
def update_values_by_splitlines(cls, lines): def update_values_by_splitlines(cls, lines):
@ -753,7 +721,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
quantity = sum([ quantity = sum([
x.quantity or Decimal('0.0') for x in line.splitlines]) x.quantity or Decimal('0.0') for x in line.splitlines])
if (cnt1 > 0) and (quantity != line.quantity): if (cnt1 > 0) and (quantity != line.quantity):
to_write.extend([[line], {'quantity': quantity, }]) to_write.extend([[line], {'quantity': quantity}])
return to_write return to_write
@classmethod @classmethod

View file

@ -28,12 +28,11 @@ class SecondUomMixin(object):
digits=(16, Eval('quantity2nd_digits', 4)), digits=(16, Eval('quantity2nd_digits', 4)),
states={ states={
'readonly': Or( 'readonly': Or(
STATESQ['readonly'], STATESQ['readonly'],
~Bool(Eval('quantity2nd')) ~Bool(Eval('quantity2nd'))),
),
'required': Bool(Eval('quantity2nd')), 'required': Bool(Eval('quantity2nd')),
'invisible': ~Bool(Eval('quantity2nd')), 'invisible': ~Bool(Eval('quantity2nd'))},
}, depends=DEPENDSQ+['quantity2nd_digits', 'quantity2nd']) depends=DEPENDSQ+['quantity2nd_digits', 'quantity2nd'])
factor_2nd_uom = fields.Function(fields.Numeric( factor_2nd_uom = fields.Function(fields.Numeric(
string='Conversion factor', string='Conversion factor',
help='Conversion factor between the units of the ' + help='Conversion factor between the units of the ' +
@ -41,12 +40,11 @@ class SecondUomMixin(object):
digits=uom_conversion_digits, digits=uom_conversion_digits,
states={ states={
'readonly': Or( 'readonly': Or(
STATESQ['readonly'], STATESQ['readonly'],
~Bool(Eval('quantity2nd')) ~Bool(Eval('quantity2nd'))),
),
'required': Bool(Eval('quantity2nd')), 'required': Bool(Eval('quantity2nd')),
'invisible': ~Bool(Eval('quantity2nd')), 'invisible': ~Bool(Eval('quantity2nd'))},
}, depends=DEPENDSQ+['quantity2nd_digits', 'quantity2nd']), depends=DEPENDSQ+['quantity2nd_digits', 'quantity2nd']),
'on_change_with_factor_2nd_uom', setter='set_factor_2nd_uom') 'on_change_with_factor_2nd_uom', setter='set_factor_2nd_uom')
quantity2nd = fields.Function(fields.Many2One( quantity2nd = fields.Function(fields.Many2One(
@ -86,8 +84,7 @@ class SecondUomMixin(object):
raise UserError(gettext( raise UserError(gettext(
'cashbook_investment.msg_uomcat_mismatch', 'cashbook_investment.msg_uomcat_mismatch',
cat1=from_uom.category.rec_name, cat1=from_uom.category.rec_name,
cat2=booktransf.quantity_uom.category.rec_name, cat2=booktransf.quantity_uom.category.rec_name))
))
values['quantity_2nd_uom'] = Decimal(UOM.compute_qty( values['quantity_2nd_uom'] = Decimal(UOM.compute_qty(
from_uom, from_uom,
@ -96,8 +93,7 @@ class SecondUomMixin(object):
round=False, round=False,
)).quantize(Decimal( )).quantize(Decimal(
Decimal(1) / Decimal(1) /
10 ** booktransf.quantity_digits) 10 ** booktransf.quantity_digits))
)
return values return values
@classmethod @classmethod
@ -175,8 +171,7 @@ class SecondUomMixin(object):
self.quantity_uom, self.quantity_uom,
float(self.quantity), float(self.quantity),
self.booktransf.quantity_uom, self.booktransf.quantity_uom,
round=False, round=False))
))
if self.quantity != Decimal('0.0'): if self.quantity != Decimal('0.0'):
self.factor_2nd_uom = ( self.factor_2nd_uom = (
self.quantity_2nd_uom / self.quantity self.quantity_2nd_uom / self.quantity

View file

@ -39,15 +39,18 @@ class Reconciliation(metaclass=PoolMeta):
""" """
recname = super(Reconciliation, self).get_rec_name(name) recname = super(Reconciliation, self).get_rec_name(name)
if self.cashbook.feature == 'asset': if self.cashbook.feature == 'asset':
recname += ' | %(start_quantity)s %(uom_symbol)s - %(end_quantity)s %(uom_symbol)s' % { recname += ' '.join([
'start_quantity': Report.format_number( ' |',
Report.format_number(
self.start_quantity or 0.0, None, self.start_quantity or 0.0, None,
digits=self.quantity_digits), digits=self.quantity_digits),
'end_quantity': Report.format_number( getattr(self.quantity_uom, 'symbol', '-'),
'-',
Report.format_number(
self.end_quantity or 0.0, None, self.end_quantity or 0.0, None,
digits=self.quantity_digits), digits=self.quantity_digits),
'uom_symbol': getattr(self.quantity_uom, 'symbol', '-'), getattr(self.quantity_uom, 'symbol', '-')
} ])
return recname return recname
@fields.depends('cashbook', '_parent_cashbook.quantity_uom') @fields.depends('cashbook', '_parent_cashbook.quantity_uom')
@ -82,8 +85,7 @@ class Reconciliation(metaclass=PoolMeta):
values = super(Reconciliation, cls).get_values_wfedit(reconciliation) values = super(Reconciliation, cls).get_values_wfedit(reconciliation)
values.update({ values.update({
'start_quantity': Decimal('0.0'), 'start_quantity': Decimal('0.0'),
'end_quantity': Decimal('0.0'), 'end_quantity': Decimal('0.0')})
})
return values return values
@classmethod @classmethod
@ -116,8 +118,7 @@ class Reconciliation(metaclass=PoolMeta):
# add quantities of already linked lines # add quantities of already linked lines
values['end_quantity'] += sum([ values['end_quantity'] += sum([
x.quantity_credit - x.quantity_debit x.quantity_credit - x.quantity_debit
for x in reconciliation.lines for x in reconciliation.lines])
])
return values return values

View file

@ -45,8 +45,7 @@ class SplitLine(SecondUomMixin, metaclass=PoolMeta):
'quantity': Report.format_number( 'quantity': Report.format_number(
self.quantity or 0.0, None, self.quantity or 0.0, None,
digits=self.quantity_digits), digits=self.quantity_digits),
'uom_symbol': self.quantity_uom.symbol, 'uom_symbol': self.quantity_uom.symbol}
}
return recname return recname
@fields.depends( @fields.depends(
@ -76,7 +75,6 @@ class SplitLine(SecondUomMixin, metaclass=PoolMeta):
if self.booktransf: if self.booktransf:
if self.booktransf.feature == 'asset': if self.booktransf.feature == 'asset':
return self.booktransf.quantity_digits return self.booktransf.quantity_digits
return 4 return 4
@classmethod @classmethod