book/line: felder für quantity, etc.

This commit is contained in:
Frederik Jaeckel 2022-12-22 00:32:26 +01:00
parent 510b85f99f
commit 70416dbc12
15 changed files with 583 additions and 0 deletions

3
.hgignore Normal file
View file

@ -0,0 +1,3 @@
syntax: glob
__pycache__/*
locale/convert_de2en.py

View file

@ -4,7 +4,13 @@
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.pool import Pool from trytond.pool import Pool
from .types import Type
from .book import Book
from .line import Line
def register(): def register():
Pool.register( Pool.register(
Type,
Book,
Line,
module='cashbook_investment', type_='model') module='cashbook_investment', type_='model')

77
book.py Normal file
View file

@ -0,0 +1,77 @@
# -*- 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
from trytond.exceptions import UserError
from trytond.pool import PoolMeta
from trytond.pyson import Eval, Or, Len
from trytond.modules.cashbook.book import STATES2, DEPENDS2
class Book(metaclass=PoolMeta):
__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'])
@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
@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

15
book.xml Normal file
View 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="book_view_form">
<field name="model">cashbook.book</field>
<field name="inherit" ref="cashbook.book_view_form"/>
<field name="name">book_form</field>
</record>
</data>
</tryton>

69
line.py Normal file
View file

@ -0,0 +1,69 @@
# -*- 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 decimal import Decimal
from trytond.model import fields
from trytond.pool import PoolMeta
from trytond.pyson import Eval, Or, If
from trytond.modules.cashbook.line import STATES, DEPENDS
class Line(metaclass=PoolMeta):
__name__ = 'cashbook.line'
quantity = fields.Numeric(string='Quantity',
digits=(16, Eval('quantity_digits', 4)),
states={
'required': Eval('feature', '') == 'asset',
'invisible': Eval('feature', '') != 'asset',
'readonly': Or(
STATES['readonly'],
Eval('bookingtype', '').in_(['spin', 'spout']),
),
}, depends=DEPENDS+['feature', 'quantity_digits', 'bookingtype'])
quantity_digits = fields.Function(fields.Integer(string='Digits',
readonly=True, states={'invisible': True}),
'on_change_with_quantity_digits')
quantity_uom = fields.Function(fields.Many2One(string='Symbol',
readonly=True, model_name='product.uom'),
'on_change_with_quantity_symbol')
asset_rate = fields.Function(fields.Numeric(string='Rate',
readonly=True,
digits=(16, If(
Eval('currency_digits', 2) > Eval('quantity_digits', 2),
Eval('currency_digits', 2), Eval('quantity_digits', 2)))),
'on_change_with_asset_rate')
#asset_ratesymbol = fields.
@fields.depends('quantity', 'amount', 'currency_digits', 'quantity_digits')
def on_change_with_asset_rate(self, name=None):
""" get rate
"""
if (self.quantity is None) or (self.amount is None):
return
digit = max(
self.currency_digits if self.currency_digits is not None else 2,
self.quantity_digits if self.quantity_digits is not None else 4)
if self.quantity != Decimal('0.0'):
return (
self.amount / self.quantity
).quantize(Decimal(str(1/10**digit)))
@fields.depends('cashbook', '_parent_cashbook.quantity_uom')
def on_change_with_quantity_symbol(self, name=None):
""" get quantity-symbol of asset
"""
if self.cashbook:
return self.cashbook.quantity_uom.id
@fields.depends('cashbook', '_parent_cashbook.quantity_digits')
def on_change_with_quantity_digits(self, name=None):
""" get digits from cashbook
"""
if self.cashbook:
return self.cashbook.quantity_digits
return 4
# end LineContext

15
line.xml Normal file
View 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="line_view_form">
<field name="model">cashbook.line</field>
<field name="inherit" ref="cashbook.line_view_form"/>
<field name="name">line_form</field>
</record>
</data>
</tryton>

59
locale/de.po Normal file
View file

@ -0,0 +1,59 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
##############
# ir.message #
##############
msgctxt "model:ir.message,text:msg_btype_asset"
msgid "Asset"
msgstr "Vermögenswert"
#################
# cashbook.book #
#################
msgctxt "view:cashbook.book:"
msgid "Asset"
msgstr "Vermögenswert"
msgctxt "field:cashbook.book,asset:"
msgid "Asset"
msgstr "Vermögenswert"
msgctxt "field:cashbook.book,quantity_digits:"
msgid "Digits"
msgstr "Dezimalstellen"
msgctxt "help:cashbook.book,quantity_digits:"
msgid "Quantity Digits"
msgstr "Dezimalstellen für Anzahl"
msgctxt "help:cashbook.book,asset_uomcat:"
msgid "UOM Category"
msgstr "Einheitenkategorie"
msgctxt "help:cashbook.book,quantity_uom:"
msgid "UOM"
msgstr "Einheit"
#################
# cashbook.line #
#################
msgctxt "field:cashbook.line,quantity_digits:"
msgid "Digits"
msgstr "Dezimalstellen"
msgctxt "field:cashbook.line,quantity:"
msgid "Quantity"
msgstr "Anzahl"
msgctxt "field:cashbook.line,quantity_symbol:"
msgid "Symbol"
msgstr "Symbol"
msgctxt "field:cashbook.line,asset_rate:"
msgid "Rate"
msgstr "Kurs"

44
locale/en.po Normal file
View file

@ -0,0 +1,44 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "model:ir.message,text:msg_btype_asset"
msgid "Asset"
msgstr "Asset"
msgctxt "view:cashbook.book:"
msgid "Asset"
msgstr "Asset"
msgctxt "field:cashbook.book,asset:"
msgid "Asset"
msgstr "Asset"
msgctxt "field:cashbook.book,quantity_digits:"
msgid "Digits"
msgstr "Digits"
msgctxt "help:cashbook.book,quantity_digits:"
msgid "Quantity Digits"
msgstr "Quantity Digits"
msgctxt "help:cashbook.book,asset_uomcat:"
msgid "UOM Category"
msgstr "UOM Category"
msgctxt "help:cashbook.book,quantity_uom:"
msgid "UOM"
msgstr "UOM"
msgctxt "field:cashbook.line,quantity_digits:"
msgid "Digits"
msgstr "Digits"
msgctxt "field:cashbook.line,quantity:"
msgid "Quantity"
msgstr "Quantity"
msgctxt "field:cashbook.line,quantity_symbol:"
msgid "Symbol"
msgstr "Symbol"

13
message.xml Normal file
View file

@ -0,0 +1,13 @@
<?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.message" id="msg_btype_asset">
<field name="text">Asset</field>
</record>
</data>
</tryton>

24
tests/__init__.py Normal file
View file

@ -0,0 +1,24 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import trytond.tests.test_tryton
import unittest
from trytond.modules.cashbook_investment.tests.test_book import CbInvTestCase
__all__ = ['suite']
class CashbookInvestmentTestCase(\
CbInvTestCase,\
):
'Test cashbook-investment module'
module = 'cashbook_investment'
# end CashbookInvestmentTestCase
def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CashbookInvestmentTestCase))
return suite

191
tests/test_book.py Normal file
View file

@ -0,0 +1,191 @@
# -*- 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.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.exceptions import UserError
from trytond.modules.cashbook.tests import CashbookTestCase
from trytond.modules.investment.tests import InvestmentTestCase
from datetime import date
from decimal import Decimal
class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
'Test cashbook-investment module'
module = 'cashbook_investment'
@with_transaction()
def test_assetbook_create(self):
""" create cashbook, set 'btype' to asset
"""
pool = Pool()
Book = pool.get('cashbook.book')
BType = pool.get('cashbook.type')
types = self.prep_type()
company = self.prep_company()
book, = Book.create([{
'name': 'Book 1',
'btype': types.id,
'company': company.id,
'currency': company.currency.id,
'number_sequ': self.prep_sequence().id,
}])
BType.write(*[
[types],
{
'feature': 'asset',
}])
self.assertEqual(book.name, 'Book 1')
self.assertEqual(book.rec_name, 'Book 1 | 0.00 usd | Open')
self.assertEqual(book.btype.rec_name, 'CAS - Cash')
self.assertEqual(book.state, 'open')
self.assertEqual(book.state_string, 'Open')
self.assertEqual(book.feature, 'asset')
self.assertEqual(book.quantity_digits, 4)
@with_transaction()
def test_assetbook_create_line(self):
""" create cashbook, add line
"""
pool = Pool()
Book = pool.get('cashbook.book')
BType = pool.get('cashbook.type')
types = self.prep_type()
BType.write(*[
[types],
{
'feature': 'asset',
}])
category = 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([{
'start_date': date(2022, 4, 1),
'name': 'Book 1',
'btype': types.id,
'company': company.id,
'currency': company.currency.id,
'number_sequ': self.prep_sequence().id,
'asset': asset.id,
'quantity_uom': asset.uom.id,
'quantity_digits': 3,
'lines': [('create', [{
'date': date(2022, 5, 1),
'description': 'Text 1',
'category': category.id,
'bookingtype': 'in',
'amount': Decimal('2.5'),
'party': party.id,
'quantity': Decimal('1.453'),
}],
)],
}])
self.assertEqual(book.name, 'Book 1')
self.assertEqual(book.rec_name, 'Book 1 | 2.50 usd | Open')
self.assertEqual(book.state, 'open')
self.assertEqual(book.feature, 'asset')
self.assertEqual(book.quantity_digits, 3)
self.assertEqual(book.balance_all, Decimal('2.5'))
self.assertEqual(len(book.lines), 1)
self.assertEqual(book.lines[0].amount, Decimal('2.5'))
self.assertEqual(book.lines[0].quantity, Decimal('1.453'))
self.assertEqual(book.lines[0].quantity_digits, 3)
self.assertEqual(book.lines[0].quantity_symbol, 'u')
@with_transaction()
def test_assetbook_book_uom(self):
""" check default auf uom
"""
pool = Pool()
Book = pool.get('cashbook.book')
BType = pool.get('cashbook.type')
company = self.prep_company()
types = self.prep_type()
BType.write(*[
[types],
{
'feature': 'asset',
'name': 'Asset',
'short': 'A',
}])
asset = self.prep_asset_item(
company=company,
product = self.prep_asset_product(name='Product 1'))
self.assertEqual(asset.symbol, 'usd/u')
book = Book(
asset = asset,
quantity_uom = None,
)
self.assertEqual(book.quantity_uom, None)
book.on_change_asset()
self.assertEqual(book.quantity_uom.rec_name, 'Unit')
@with_transaction()
def test_assetbook_book_with_asset(self):
""" create cashbook, set 'btype' to asset
"""
pool = Pool()
Book = pool.get('cashbook.book')
BType = pool.get('cashbook.type')
company = self.prep_company()
types = self.prep_type()
BType.write(*[
[types],
{
'feature': 'asset',
'name': 'Asset',
'short': 'A',
}])
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': 'Book 1',
'btype': types.id,
'company': company.id,
'currency': company.currency.id,
'number_sequ': self.prep_sequence().id,
'asset': asset.id,
'quantity_uom': asset.uom.id,
}])
self.assertEqual(book.name, 'Book 1')
self.assertEqual(book.rec_name, 'Book 1 | 0.00 usd | Open')
self.assertEqual(book.btype.rec_name, 'A - Asset')
self.assertEqual(book.state, 'open')
self.assertEqual(book.feature, 'asset')
self.assertEqual(book.asset.rec_name, 'Product 1 | - usd/u | -')
self.assertEqual(book.quantity_uom.rec_name, 'Unit')
self.assertRaisesRegex(UserError,
'A value is required for field "Asset" in "Cashbook".',
Book.write,
*[
[book],
{
'asset': None,
}
])
# end CbInvTestCase

View file

@ -2,4 +2,8 @@
version=6.0.0 version=6.0.0
depends: depends:
cashbook cashbook
investment
xml: xml:
message.xml
book.xml
line.xml

21
types.py Normal file
View file

@ -0,0 +1,21 @@
# -*- 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.i18n import gettext
from trytond.pool import PoolMeta
class Type(metaclass=PoolMeta):
__name__ = 'cashbook.type'
@classmethod
def get_sel_feature(cls):
""" get feature-modes
"""
l1 = super(Type, cls).get_sel_feature()
l1.append(('asset', gettext('cashbook_investment.msg_btype_asset')))
return l1
# end Type

20
view/book_form.xml Normal file
View file

@ -0,0 +1,20 @@
<?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/notebook/page[@id='pggeneral']" position="after">
<page name="asset" string="Asset">
<label name="asset"/>
<field name="asset"/>
<label name="quantity_uom"/>
<field name="quantity_uom"/>
<label name="quantity_digits"/>
<field name="quantity_digits"/>
<field name="asset_uomcat"/>
</page>
</xpath>
</data>

22
view/line_form.xml Normal file
View file

@ -0,0 +1,22 @@
<?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='reference']" position="after">
<label name="quantity" />
<field name="quantity" symbol="quantity_uom"/>
<label name="asset_rate"/>
<!--<field name="asset_rate"/>-->
<group id="asset_rate" col="2">
<field name="asset_rate" xexpand="0"/>
<field name="number" xalign="0.0" xexpand="0"/>
</group>
<field name="quantity_digits"/>
<newline/>
</xpath>
</data>