line: quantity_balance, validate,
reconciliation: start/end-quantity todo: tests
This commit is contained in:
parent
e94a869166
commit
f86db6dea3
11 changed files with 484 additions and 140 deletions
|
@ -7,10 +7,12 @@ from trytond.pool import Pool
|
||||||
from .types import Type
|
from .types import Type
|
||||||
from .book import Book
|
from .book import Book
|
||||||
from .line import Line
|
from .line import Line
|
||||||
|
from .reconciliation import Reconciliation
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
Pool.register(
|
Pool.register(
|
||||||
Type,
|
Type,
|
||||||
Book,
|
Book,
|
||||||
Line,
|
Line,
|
||||||
|
Reconciliation,
|
||||||
module='cashbook_investment', type_='model')
|
module='cashbook_investment', type_='model')
|
||||||
|
|
70
line.py
70
line.py
|
@ -7,6 +7,8 @@ from decimal import Decimal
|
||||||
from trytond.model import fields
|
from trytond.model import fields
|
||||||
from trytond.pool import PoolMeta
|
from trytond.pool import PoolMeta
|
||||||
from trytond.pyson import Eval, Or, If
|
from trytond.pyson import Eval, Or, If
|
||||||
|
from trytond.exceptions import UserError
|
||||||
|
from trytond.i18n import gettext
|
||||||
from trytond.modules.cashbook.line import STATES, DEPENDS
|
from trytond.modules.cashbook.line import STATES, DEPENDS
|
||||||
|
|
||||||
STATESQ = {
|
STATESQ = {
|
||||||
|
@ -34,11 +36,17 @@ class Line(metaclass=PoolMeta):
|
||||||
digits=(16, Eval('quantity_digits', 4)),
|
digits=(16, Eval('quantity_digits', 4)),
|
||||||
states=STATESQ, depends=DEPENDSQ)
|
states=STATESQ, depends=DEPENDSQ)
|
||||||
quantity_credit = fields.Numeric(string='Quantity Credit',
|
quantity_credit = fields.Numeric(string='Quantity Credit',
|
||||||
digits=(16, Eval('quantity_digits', 4)),
|
digits=(16, Eval('quantity_digits', 4)), readonly=True,
|
||||||
states=STATESQ, depends=DEPENDSQ)
|
states={
|
||||||
|
'invisible': STATESQ['invisible'],
|
||||||
|
'required': STATESQ['required'],
|
||||||
|
}, depends=DEPENDSQ)
|
||||||
quantity_debit = fields.Numeric(string='Quantity Debit',
|
quantity_debit = fields.Numeric(string='Quantity Debit',
|
||||||
digits=(16, Eval('quantity_digits', 4)),
|
digits=(16, Eval('quantity_digits', 4)), readonly=True,
|
||||||
states=STATESQ, depends=DEPENDSQ)
|
states={
|
||||||
|
'invisible': STATESQ['invisible'],
|
||||||
|
'required': STATESQ['required'],
|
||||||
|
}, depends=DEPENDSQ)
|
||||||
|
|
||||||
quantity_digits = fields.Function(fields.Integer(string='Digits',
|
quantity_digits = fields.Function(fields.Integer(string='Digits',
|
||||||
readonly=True, states={'invisible': True}),
|
readonly=True, states={'invisible': True}),
|
||||||
|
@ -55,6 +63,11 @@ class Line(metaclass=PoolMeta):
|
||||||
'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(string='Quantity',
|
||||||
|
digits=(16, Eval('quantity_digits', 4)),
|
||||||
|
help='Number of shares in the cashbook up to the current row if the default sort applies.',
|
||||||
|
readonly=True, depends=['quantity_digits']),
|
||||||
|
'on_change_with_quantity_balance')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_debit_credit(cls, values):
|
def get_debit_credit(cls, values):
|
||||||
|
@ -123,4 +136,53 @@ class Line(metaclass=PoolMeta):
|
||||||
return self.cashbook.quantity_digits
|
return self.cashbook.quantity_digits
|
||||||
return 4
|
return 4
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate(cls, lines):
|
||||||
|
""" deny pos/neg mismatch
|
||||||
|
"""
|
||||||
|
super(Line, cls).validate(lines)
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
# ignore non-asset-lines
|
||||||
|
if line.cashbook.feature != 'asset':
|
||||||
|
continue
|
||||||
|
|
||||||
|
# quantity must be set
|
||||||
|
if (line.quantity is None) or \
|
||||||
|
(line.quantity_credit is None) or \
|
||||||
|
(line.quantity_debit is None):
|
||||||
|
raise UserError(gettext(
|
||||||
|
'cashbook_investment.msg_line_quantity_not_set',
|
||||||
|
linetxt = line.rec_name,
|
||||||
|
))
|
||||||
|
|
||||||
|
# quantity and amount must with same sign
|
||||||
|
(amount_sign, a_dig, a_exp) = line.amount.as_tuple()
|
||||||
|
(quantity_sign, q_dig, q_exp) = line.quantity.as_tuple()
|
||||||
|
if amount_sign != quantity_sign:
|
||||||
|
raise UserError(gettext(
|
||||||
|
'cashbook_investment.msg_line_sign_mismatch',
|
||||||
|
linetxt = line.rec_name,
|
||||||
|
))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def write(cls, *args):
|
||||||
|
""" add or update quanity_debit/credit
|
||||||
|
"""
|
||||||
|
actions = iter(args)
|
||||||
|
to_write = []
|
||||||
|
for lines, values in zip(actions, actions):
|
||||||
|
# update debit / credit
|
||||||
|
if len(set(values.keys()).intersection(set({'quantity', 'bookingtype'}))) > 0:
|
||||||
|
for line in lines:
|
||||||
|
values2 = {}
|
||||||
|
values2.update(values)
|
||||||
|
values2.update(cls.get_debit_credit({
|
||||||
|
x:values.get(x, getattr(line, x)) for x in ['quantity', 'bookingtype']
|
||||||
|
}))
|
||||||
|
to_write.extend([lines, values2])
|
||||||
|
else :
|
||||||
|
to_write.extend([lines, values])
|
||||||
|
super(Line, cls).write(*to_write)
|
||||||
|
|
||||||
# end LineContext
|
# end LineContext
|
||||||
|
|
40
locale/de.po
40
locale/de.po
|
@ -10,6 +10,14 @@ msgctxt "model:ir.message,text:msg_btype_asset"
|
||||||
msgid "Asset"
|
msgid "Asset"
|
||||||
msgstr "Vermögenswert"
|
msgstr "Vermögenswert"
|
||||||
|
|
||||||
|
msgctxt "model:ir.message,text:msg_line_quantity_not_set"
|
||||||
|
msgid "Quantity must be set for line '%(linetxt)s'."
|
||||||
|
msgstr "Menge für die Zeile '%(linetxt)s' muß gesetzt werden."
|
||||||
|
|
||||||
|
msgctxt "model:ir.message,text:msg_line_sign_mismatch"
|
||||||
|
msgid "Quantity and Amount must with same sign for line %(linetxt)s."
|
||||||
|
msgstr "Menge und Betrag müssen für Zeile %(linetxt)s mit demselben Vorzeichen versehen werden."
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# cashbook.book #
|
# cashbook.book #
|
||||||
|
@ -124,11 +132,11 @@ msgstr "Anzahl"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_credit:"
|
msgctxt "field:cashbook.line,quantity_credit:"
|
||||||
msgid "Quantity Credit"
|
msgid "Quantity Credit"
|
||||||
msgstr "Anzahlgutschrift"
|
msgstr "Anzahl Haben"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_debit:"
|
msgctxt "field:cashbook.line,quantity_debit:"
|
||||||
msgid "Quantity Debit"
|
msgid "Quantity Debit"
|
||||||
msgstr "Anzahllastschrift"
|
msgstr "Anzahl Soll"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_symbol:"
|
msgctxt "field:cashbook.line,quantity_symbol:"
|
||||||
msgid "Symbol"
|
msgid "Symbol"
|
||||||
|
@ -137,3 +145,31 @@ msgstr "Symbol"
|
||||||
msgctxt "field:cashbook.line,asset_rate:"
|
msgctxt "field:cashbook.line,asset_rate:"
|
||||||
msgid "Rate"
|
msgid "Rate"
|
||||||
msgstr "Kurs"
|
msgstr "Kurs"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.line,quantity_balance:"
|
||||||
|
msgid "Quantity"
|
||||||
|
msgstr "Anzahl"
|
||||||
|
|
||||||
|
msgctxt "help:cashbook.line,quantity_balance:"
|
||||||
|
msgid "Number of shares in the cashbook up to the current row if the default sort applies."
|
||||||
|
msgstr "Anzahl Anteile im Kassenbuch bis zur aktuellen Zeile, wenn die Standardsortierung zutrifft."
|
||||||
|
|
||||||
|
|
||||||
|
##################
|
||||||
|
# cashbook.recon #
|
||||||
|
##################
|
||||||
|
msgctxt "field:cashbook.recon,start_quantity:"
|
||||||
|
msgid "Start Quantity"
|
||||||
|
msgstr "Anfangsmenge"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.recon,end_quantity:"
|
||||||
|
msgid "End Quantity"
|
||||||
|
msgstr "Endmenge"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.recon,quantity_digits:"
|
||||||
|
msgid "Quantity Digits"
|
||||||
|
msgstr "Anzahl-Dezimalstellen"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.recon,quantity_uom:"
|
||||||
|
msgid "Symbol"
|
||||||
|
msgstr "Symbol"
|
||||||
|
|
280
locale/en.po
280
locale/en.po
|
@ -1,124 +1,156 @@
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr "Content-Type: text/plain; charset=utf-8\n"
|
msgstr "Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
|
||||||
msgctxt "model:ir.message,text:msg_btype_asset"
|
msgctxt "model:ir.message,text:msg_btype_asset"
|
||||||
msgid "Asset"
|
msgid "Asset"
|
||||||
msgstr "Asset"
|
msgstr "Asset"
|
||||||
|
|
||||||
msgctxt "view:cashbook.book:"
|
msgctxt "model:ir.message,text:msg_line_quantity_not_set"
|
||||||
msgid "Asset"
|
msgid "Quantity must be set for line '%(linetxt)s'."
|
||||||
msgstr "Asset"
|
msgstr "Quantity must be set for line '%(linetxt)s'."
|
||||||
|
|
||||||
msgctxt "view:cashbook.book:"
|
msgctxt "model:ir.message,text:msg_line_sign_mismatch"
|
||||||
msgid "Quantity"
|
msgid "Quantity and Amount must with same sign for line %(linetxt)s."
|
||||||
msgstr "Quantity"
|
msgstr "Quantity and Amount must with same sign for line %(linetxt)s."
|
||||||
|
|
||||||
msgctxt "view:cashbook.book:"
|
msgctxt "view:cashbook.book:"
|
||||||
msgid "Current valuation of the investment"
|
msgid "Asset"
|
||||||
msgstr "Current valuation of the investment"
|
msgstr "Asset"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,asset:"
|
msgctxt "view:cashbook.book:"
|
||||||
msgid "Asset"
|
msgid "Quantity"
|
||||||
msgstr "Asset"
|
msgstr "Quantity"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,quantity_digits:"
|
msgctxt "view:cashbook.book:"
|
||||||
msgid "Digits"
|
msgid "Current valuation of the investment"
|
||||||
msgstr "Digits"
|
msgstr "Current valuation of the investment"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,quantity_digits:"
|
msgctxt "field:cashbook.book,asset:"
|
||||||
msgid "Quantity Digits"
|
msgid "Asset"
|
||||||
msgstr "Quantity Digits"
|
msgstr "Asset"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,asset_uomcat:"
|
msgctxt "field:cashbook.book,quantity_digits:"
|
||||||
msgid "UOM Category"
|
msgid "Digits"
|
||||||
msgstr "UOM Category"
|
msgstr "Digits"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,quantity_uom:"
|
msgctxt "help:cashbook.book,quantity_digits:"
|
||||||
msgid "UOM"
|
msgid "Quantity Digits"
|
||||||
msgstr "UOM"
|
msgstr "Quantity Digits"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,symbol:"
|
msgctxt "help:cashbook.book,asset_uomcat:"
|
||||||
msgid "Symbol"
|
msgid "UOM Category"
|
||||||
msgstr "Symbol"
|
msgstr "UOM Category"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,asset_symbol:"
|
msgctxt "field:cashbook.book,quantity_uom:"
|
||||||
msgid "Symbol"
|
msgid "UOM"
|
||||||
msgstr "Symbol"
|
msgstr "UOM"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,quantity:"
|
msgctxt "field:cashbook.book,symbol:"
|
||||||
msgid "Quantity"
|
msgid "Symbol"
|
||||||
msgstr "Quantity"
|
msgstr "Symbol"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,quantity:"
|
msgctxt "field:cashbook.book,asset_symbol:"
|
||||||
msgid "Quantity of assets until to date"
|
msgid "Symbol"
|
||||||
msgstr "Quantity of assets until to date"
|
msgstr "Symbol"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,quantity_all:"
|
msgctxt "field:cashbook.book,quantity:"
|
||||||
msgid "Total Quantity"
|
msgid "Quantity"
|
||||||
msgstr "Total Quantity"
|
msgstr "Quantity"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,quantity_all:"
|
msgctxt "help:cashbook.book,quantity:"
|
||||||
msgid "Total quantity of all assets"
|
msgid "Quantity of assets until to date"
|
||||||
msgstr "Total quantity of all assets"
|
msgstr "Quantity of assets until to date"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,current_value:"
|
msgctxt "field:cashbook.book,quantity_all:"
|
||||||
msgid "Value"
|
msgid "Total Quantity"
|
||||||
msgstr "Value"
|
msgstr "Total Quantity"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,current_value:"
|
msgctxt "help:cashbook.book,quantity_all:"
|
||||||
msgid "Valuation of the investment based on the current stock market price."
|
msgid "Total quantity of all assets"
|
||||||
msgstr "Valuation of the investment based on the current stock market price."
|
msgstr "Total quantity of all assets"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,current_value_ref:"
|
msgctxt "field:cashbook.book,current_value:"
|
||||||
msgid "Value (Ref.)"
|
msgid "Value"
|
||||||
msgstr "Value (Ref.)"
|
msgstr "Value"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,current_value_ref:"
|
msgctxt "help:cashbook.book,current_value:"
|
||||||
msgid "Valuation of the investment based on the current stock exchange price, converted into the company currency."
|
msgid "Valuation of the investment based on the current stock market price."
|
||||||
msgstr "Valuation of the investment based on the current stock exchange price, converted into the company currency."
|
msgstr "Valuation of the investment based on the current stock market price."
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,diff_amount:"
|
msgctxt "field:cashbook.book,current_value_ref:"
|
||||||
msgid "Difference"
|
msgid "Value (Ref.)"
|
||||||
msgstr "Difference"
|
msgstr "Value (Ref.)"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,diff_amount:"
|
msgctxt "help:cashbook.book,current_value_ref:"
|
||||||
msgid "Difference between acquisition value and current value"
|
msgid "Valuation of the investment based on the current stock exchange price, converted into the company currency."
|
||||||
msgstr "Difference between acquisition value and current value"
|
msgstr "Valuation of the investment based on the current stock exchange price, converted into the company currency."
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,diff_percent:"
|
msgctxt "field:cashbook.book,diff_amount:"
|
||||||
msgid "Percent"
|
msgid "Difference"
|
||||||
msgstr "Percent"
|
msgstr "Difference"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,diff_percent:"
|
msgctxt "help:cashbook.book,diff_amount:"
|
||||||
msgid "percentage performance since acquisition"
|
msgid "Difference between acquisition value and current value"
|
||||||
msgstr "percentage performance since acquisition"
|
msgstr "Difference between acquisition value and current value"
|
||||||
|
|
||||||
msgctxt "field:cashbook.book,current_rate:"
|
msgctxt "field:cashbook.book,diff_percent:"
|
||||||
msgid "Rate"
|
msgid "Percent"
|
||||||
msgstr "Rate"
|
msgstr "Percent"
|
||||||
|
|
||||||
msgctxt "help:cashbook.book,current_rate:"
|
msgctxt "help:cashbook.book,diff_percent:"
|
||||||
msgid "Rate per unit of investment based on current stock exchange price."
|
msgid "percentage performance since acquisition"
|
||||||
msgstr "Rate per unit of investment based on current stock exchange price."
|
msgstr "percentage performance since acquisition"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_digits:"
|
msgctxt "field:cashbook.book,current_rate:"
|
||||||
msgid "Digits"
|
msgid "Rate"
|
||||||
msgstr "Digits"
|
msgstr "Rate"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity:"
|
msgctxt "help:cashbook.book,current_rate:"
|
||||||
msgid "Quantity"
|
msgid "Rate per unit of investment based on current stock exchange price."
|
||||||
msgstr "Quantity"
|
msgstr "Rate per unit of investment based on current stock exchange price."
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_credit:"
|
msgctxt "field:cashbook.line,quantity_digits:"
|
||||||
msgid "Quantity Credit"
|
msgid "Digits"
|
||||||
msgstr "Quantity Credit"
|
msgstr "Digits"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_debit:"
|
msgctxt "field:cashbook.line,quantity:"
|
||||||
msgid "Quantity Debit"
|
msgid "Quantity"
|
||||||
msgstr "Quantity Debit"
|
msgstr "Quantity"
|
||||||
|
|
||||||
msgctxt "field:cashbook.line,quantity_symbol:"
|
msgctxt "field:cashbook.line,quantity_credit:"
|
||||||
msgid "Symbol"
|
msgid "Quantity Credit"
|
||||||
msgstr "Symbol"
|
msgstr "Quantity Credit"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.line,quantity_debit:"
|
||||||
|
msgid "Quantity Debit"
|
||||||
|
msgstr "Quantity Debit"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.line,quantity_symbol:"
|
||||||
|
msgid "Symbol"
|
||||||
|
msgstr "Symbol"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.line,asset_rate:"
|
||||||
|
msgid "Rate"
|
||||||
|
msgstr "Rate"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.line,quantity_balance:"
|
||||||
|
msgid "Quantity"
|
||||||
|
msgstr "Quantity"
|
||||||
|
|
||||||
|
msgctxt "help:cashbook.line,quantity_balance:"
|
||||||
|
msgid "Number of shares in the cashbook up to the current row if the default sort applies."
|
||||||
|
msgstr "Number of shares in the cashbook up to the current row if the default sort applies."
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.recon,start_quantity:"
|
||||||
|
msgid "Start Quantity"
|
||||||
|
msgstr "Start Quantity"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.recon,end_quantity:"
|
||||||
|
msgid "End Quantity"
|
||||||
|
msgstr "End Quantity"
|
||||||
|
|
||||||
|
msgctxt "field:cashbook.recon,quantity_digits:"
|
||||||
|
msgid "Quantity Digits"
|
||||||
|
msgstr "Quantity Digits"
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,12 @@ full copyright notices and license terms. -->
|
||||||
<record model="ir.message" id="msg_btype_asset">
|
<record model="ir.message" id="msg_btype_asset">
|
||||||
<field name="text">Asset</field>
|
<field name="text">Asset</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record model="ir.message" id="msg_line_quantity_not_set">
|
||||||
|
<field name="text">Quantity must be set for line '%(linetxt)s'.</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.message" id="msg_line_sign_mismatch">
|
||||||
|
<field name="text">Quantity and Amount must with same sign for line %(linetxt)s.</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|
100
reconciliation.py
Normal file
100
reconciliation.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# -*- 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.pool import PoolMeta
|
||||||
|
from trytond.model import fields
|
||||||
|
from trytond.pyson import Eval
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
|
||||||
|
class Reconciliation(metaclass=PoolMeta):
|
||||||
|
__name__ = 'cashbook.recon'
|
||||||
|
|
||||||
|
start_quantity = fields.Numeric(string='Start Quantity',
|
||||||
|
readonly=True, digits=(16, Eval('quantity_digits', 4)),
|
||||||
|
states={
|
||||||
|
'required': Eval('feature', '') == 'asset',
|
||||||
|
'invisible': Eval('feature', '') != 'asset',
|
||||||
|
}, depends=['quantity_digits', 'feature'])
|
||||||
|
end_quantity = fields.Numeric(string='End Quantity',
|
||||||
|
readonly=True, digits=(16, Eval('quantity_digits', 4)),
|
||||||
|
states={
|
||||||
|
'required': Eval('feature', '') == 'asset',
|
||||||
|
'invisible': Eval('feature', '') != 'asset',
|
||||||
|
}, depends=['quantity_digits', 'feature'])
|
||||||
|
quantity_digits = fields.Function(fields.Integer(string='Quantity Digits'),
|
||||||
|
'on_change_with_quantity_digits')
|
||||||
|
quantity_uom = fields.Function(fields.Many2One(string='Symbol',
|
||||||
|
readonly=True, model_name='product.uom'),
|
||||||
|
'on_change_with_quantity_uom')
|
||||||
|
|
||||||
|
@fields.depends('cashbook', '_parent_cashbook.quantity_uom')
|
||||||
|
def on_change_with_quantity_uom(self, name=None):
|
||||||
|
""" get quantity-unit of asset
|
||||||
|
"""
|
||||||
|
if self.cashbook:
|
||||||
|
if self.cashbook.quantity_uom:
|
||||||
|
return self.cashbook.quantity_uom.id
|
||||||
|
|
||||||
|
@fields.depends('cashbook', '_parent_cashbook.quantity_digits')
|
||||||
|
def on_change_with_quantity_digits(self, name=None):
|
||||||
|
""" quantity_digits of cashbook
|
||||||
|
"""
|
||||||
|
if self.cashbook:
|
||||||
|
return self.cashbook.currency.digits
|
||||||
|
else:
|
||||||
|
return 4
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def default_start_quantity(cls):
|
||||||
|
return Decimal('0.0')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def default_end_quantity(cls):
|
||||||
|
return Decimal('0.0')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_values_wfedit(cls, reconciliation):
|
||||||
|
""" get values for 'to_write' in wf-edit
|
||||||
|
"""
|
||||||
|
values = super(Reconciliation, cls).get_values_wfedit(reconciliation)
|
||||||
|
values.update({
|
||||||
|
'start_quantity': Decimal('0.0'),
|
||||||
|
'end_quantity': Decimal('0.0'),
|
||||||
|
})
|
||||||
|
return values
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_values_wfcheck(cls, reconciliation):
|
||||||
|
""" get values for 'to_write' in wf-check
|
||||||
|
"""
|
||||||
|
values = super(Reconciliation, cls).get_values_wfcheck(reconciliation)
|
||||||
|
|
||||||
|
if reconciliation.predecessor:
|
||||||
|
values['start_quantity'] = reconciliation.predecessor.end_quantity
|
||||||
|
else :
|
||||||
|
values['start_quantity'] = Decimal('0.0')
|
||||||
|
values['end_quantity'] = values['start_quantity']
|
||||||
|
|
||||||
|
# add quantities of new lines
|
||||||
|
if 'lines' in values.keys():
|
||||||
|
if len(values['lines']) != 1:
|
||||||
|
raise ValueError('invalid number of values')
|
||||||
|
|
||||||
|
values['end_quantity'] += sum([
|
||||||
|
x.quantity_credit - x.quantity_debit
|
||||||
|
for x in values['lines'][0][1]
|
||||||
|
])
|
||||||
|
|
||||||
|
# add quantities of already linked lines
|
||||||
|
values['end_quantity'] += sum([
|
||||||
|
x.quantity_credit - x.quantity_debit
|
||||||
|
for x in reconciliation.lines
|
||||||
|
])
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
# end Reconciliation
|
15
reconciliation.xml
Normal file
15
reconciliation.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- 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. -->
|
||||||
|
<tryton>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="recon_view_form">
|
||||||
|
<field name="model">cashbook.recon</field>
|
||||||
|
<field name="inherit" ref="cashbook.recon_view_form"/>
|
||||||
|
<field name="name">recon_form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</tryton>
|
|
@ -531,10 +531,22 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
|
||||||
self.assertEqual(book.rec_name, 'Book 1 | -1.00 usd | Open')
|
self.assertEqual(book.rec_name, 'Book 1 | -1.00 usd | Open')
|
||||||
self.assertEqual(len(book.lines), 1)
|
self.assertEqual(len(book.lines), 1)
|
||||||
self.assertEqual(book.lines[0].quantity, Decimal('1.5'))
|
self.assertEqual(book.lines[0].quantity, Decimal('1.5'))
|
||||||
|
self.assertEqual(book.lines[0].quantity_credit, Decimal('0.0'))
|
||||||
|
self.assertEqual(book.lines[0].quantity_debit, Decimal('1.5'))
|
||||||
self.assertEqual(len(book2.lines), 0)
|
self.assertEqual(len(book2.lines), 0)
|
||||||
self.assertEqual(book.lines[0].rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 0.00 usd | Open]')
|
self.assertEqual(book.lines[0].rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 0.00 usd | Open]')
|
||||||
self.assertEqual(len(book.lines[0].references), 0)
|
self.assertEqual(len(book.lines[0].references), 0)
|
||||||
|
|
||||||
|
# update quantity
|
||||||
|
Book.write(*[
|
||||||
|
[book],
|
||||||
|
{
|
||||||
|
'lines': [('write', [book.lines[0]], {'quantity': Decimal('2.5')})],
|
||||||
|
}])
|
||||||
|
self.assertEqual(book.lines[0].quantity, Decimal('2.5'))
|
||||||
|
self.assertEqual(book.lines[0].quantity_credit, Decimal('0.0'))
|
||||||
|
self.assertEqual(book.lines[0].quantity_debit, Decimal('2.5'))
|
||||||
|
|
||||||
# check counterpart
|
# check counterpart
|
||||||
self.assertEqual(book.lines[0].booktransf.rec_name, 'Asset-Book | 0.00 usd | Open')
|
self.assertEqual(book.lines[0].booktransf.rec_name, 'Asset-Book | 0.00 usd | Open')
|
||||||
self.assertEqual(book.lines[0].booktransf.btype.feature, 'asset')
|
self.assertEqual(book.lines[0].booktransf.btype.feature, 'asset')
|
||||||
|
@ -547,9 +559,9 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
|
||||||
self.assertEqual(book.lines[0].rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]')
|
self.assertEqual(book.lines[0].rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]')
|
||||||
self.assertEqual(book.lines[0].state, 'check')
|
self.assertEqual(book.lines[0].state, 'check')
|
||||||
self.assertEqual(book.lines[0].bookingtype, 'mvout')
|
self.assertEqual(book.lines[0].bookingtype, 'mvout')
|
||||||
self.assertEqual(book.lines[0].quantity, Decimal('1.5'))
|
self.assertEqual(book.lines[0].quantity, Decimal('2.5'))
|
||||||
self.assertEqual(book.lines[0].quantity_credit, Decimal('0.0'))
|
self.assertEqual(book.lines[0].quantity_credit, Decimal('0.0'))
|
||||||
self.assertEqual(book.lines[0].quantity_debit, Decimal('1.5'))
|
self.assertEqual(book.lines[0].quantity_debit, Decimal('2.5'))
|
||||||
self.assertEqual(len(book.lines[0].references), 1)
|
self.assertEqual(len(book.lines[0].references), 1)
|
||||||
self.assertEqual(book.lines[0].reference, None)
|
self.assertEqual(book.lines[0].reference, None)
|
||||||
self.assertEqual(book.lines[0].references[0].id, book2.lines[0].id)
|
self.assertEqual(book.lines[0].references[0].id, book2.lines[0].id)
|
||||||
|
@ -557,12 +569,78 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
|
||||||
self.assertEqual(len(book2.lines), 1)
|
self.assertEqual(len(book2.lines), 1)
|
||||||
self.assertEqual(book2.lines[0].rec_name, '05/01/2022|from|1.00 usd|Transfer Out [Book 1 | -1.00 usd | Open]')
|
self.assertEqual(book2.lines[0].rec_name, '05/01/2022|from|1.00 usd|Transfer Out [Book 1 | -1.00 usd | Open]')
|
||||||
self.assertEqual(book2.lines[0].state, 'check')
|
self.assertEqual(book2.lines[0].state, 'check')
|
||||||
self.assertEqual(book2.lines[0].quantity, Decimal('1.5'))
|
self.assertEqual(book2.lines[0].quantity, Decimal('2.5'))
|
||||||
self.assertEqual(book2.lines[0].quantity_credit, Decimal('1.5'))
|
self.assertEqual(book2.lines[0].quantity_credit, Decimal('2.5'))
|
||||||
self.assertEqual(book2.lines[0].quantity_debit, Decimal('0.0'))
|
self.assertEqual(book2.lines[0].quantity_debit, Decimal('0.0'))
|
||||||
self.assertEqual(book2.lines[0].bookingtype, 'mvin')
|
self.assertEqual(book2.lines[0].bookingtype, 'mvin')
|
||||||
self.assertEqual(book2.lines[0].asset_rate, Decimal('0.6667'))
|
self.assertEqual(book2.lines[0].asset_rate, Decimal('0.4'))
|
||||||
self.assertEqual(book2.lines[0].reference.rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]')
|
self.assertEqual(book2.lines[0].reference.rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]')
|
||||||
self.assertEqual(len(book2.lines[0].references), 0)
|
self.assertEqual(len(book2.lines[0].references), 0)
|
||||||
|
|
||||||
|
@with_transaction()
|
||||||
|
def test_assetbook_check_sign_mismatch(self):
|
||||||
|
""" create cashbook + line, bookingtype 'in',
|
||||||
|
check detection of sign mismatch between quantity and amount
|
||||||
|
"""
|
||||||
|
pool = Pool()
|
||||||
|
Book = pool.get('cashbook.book')
|
||||||
|
Line = pool.get('cashbook.line')
|
||||||
|
Category = pool.get('cashbook.category')
|
||||||
|
BType = pool.get('cashbook.type')
|
||||||
|
|
||||||
|
type_depot = self.prep_type('Depot', 'D')
|
||||||
|
BType.write(*[
|
||||||
|
[type_depot],
|
||||||
|
{
|
||||||
|
'feature': 'asset',
|
||||||
|
}])
|
||||||
|
|
||||||
|
category_in = self.prep_category(cattype='in')
|
||||||
|
company = self.prep_company()
|
||||||
|
party = self.prep_party()
|
||||||
|
|
||||||
|
asset = self.prep_asset_item(
|
||||||
|
company=company,
|
||||||
|
product = self.prep_asset_product(name='Product 1'))
|
||||||
|
self.assertEqual(asset.symbol, 'usd/u')
|
||||||
|
|
||||||
|
book, = Book.create([{
|
||||||
|
'name': 'Asset-Book',
|
||||||
|
'btype': type_depot.id,
|
||||||
|
'asset': asset.id,
|
||||||
|
'quantity_uom': asset.uom.id,
|
||||||
|
'company': company.id,
|
||||||
|
'currency': company.currency.id,
|
||||||
|
'number_sequ': self.prep_sequence().id,
|
||||||
|
'start_date': date(2022, 5, 1),
|
||||||
|
'lines': [('create', [{
|
||||||
|
'date': date(2022, 5, 1),
|
||||||
|
'description': 'buy some',
|
||||||
|
'category': category_in.id,
|
||||||
|
'bookingtype': 'in',
|
||||||
|
'amount': Decimal('1.0'),
|
||||||
|
'quantity': Decimal('1.5'),
|
||||||
|
}])],
|
||||||
|
}])
|
||||||
|
|
||||||
|
self.assertEqual(book.rec_name, 'Asset-Book | 1.00 usd | Open')
|
||||||
|
self.assertEqual(len(book.lines), 1)
|
||||||
|
self.assertEqual(book.lines[0].amount, Decimal('1.0'))
|
||||||
|
self.assertEqual(book.lines[0].credit, Decimal('1.0'))
|
||||||
|
self.assertEqual(book.lines[0].debit, Decimal('0.0'))
|
||||||
|
self.assertEqual(book.lines[0].quantity, Decimal('1.5'))
|
||||||
|
self.assertEqual(book.lines[0].quantity_credit, Decimal('1.5'))
|
||||||
|
self.assertEqual(book.lines[0].quantity_debit, Decimal('0.0'))
|
||||||
|
|
||||||
|
self.assertRaisesRegex(UserError,
|
||||||
|
"Quantity and Amount must with same sign for line 05/01/2022|Rev|1.00 usd|buy some [Cat1].",
|
||||||
|
Book.write,
|
||||||
|
*[
|
||||||
|
[book],
|
||||||
|
{
|
||||||
|
'lines': [('write', [book.lines[0]], {
|
||||||
|
'quantity': Decimal('-1.5'),
|
||||||
|
})],
|
||||||
|
}])
|
||||||
|
|
||||||
# end CbInvTestCase
|
# end CbInvTestCase
|
||||||
|
|
|
@ -7,3 +7,4 @@ xml:
|
||||||
message.xml
|
message.xml
|
||||||
book.xml
|
book.xml
|
||||||
line.xml
|
line.xml
|
||||||
|
reconciliation.xml
|
||||||
|
|
|
@ -9,11 +9,7 @@ full copyright notices and license terms. -->
|
||||||
<field name="quantity" symbol="quantity_uom"/>
|
<field name="quantity" symbol="quantity_uom"/>
|
||||||
<label name="asset_rate"/>
|
<label name="asset_rate"/>
|
||||||
<field name="asset_rate" symbol="cashbook"/>
|
<field name="asset_rate" symbol="cashbook"/>
|
||||||
|
<newline/>
|
||||||
<label name="quantity_credit" />
|
|
||||||
<field name="quantity_credit" symbol="quantity_uom"/>
|
|
||||||
<label name="quantity_debit"/>
|
|
||||||
<field name="quantity_debit" symbol="quantity_uom"/>
|
|
||||||
|
|
||||||
<field name="quantity_digits"/>
|
<field name="quantity_digits"/>
|
||||||
<newline/>
|
<newline/>
|
||||||
|
|
16
view/recon_form.xml
Normal file
16
view/recon_form.xml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- 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. -->
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<xpath expr="/form/field[@name='end_amount']" position="after">
|
||||||
|
<newline/>
|
||||||
|
<label name="start_quantity" />
|
||||||
|
<field name="start_quantity" symbol="quantity_uom"/>
|
||||||
|
<label name="end_quantity"/>
|
||||||
|
<field name="end_quantity" symbol="quantity_uom"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
</data>
|
Loading…
Reference in a new issue