diff --git a/__init__.py b/__init__.py
index e4eea0f..0c48da5 100644
--- a/__init__.py
+++ b/__init__.py
@@ -5,10 +5,12 @@
from trytond.pool import Pool
from .asset import Asset
+from .rate import Rate
from .identifier import Identifier
def register():
Pool.register(
Asset,
+ Rate,
Identifier,
module='investment', type_='model')
diff --git a/asset.py b/asset.py
index c7d3c4c..53cc0ce 100644
--- a/asset.py
+++ b/asset.py
@@ -30,6 +30,8 @@ class Asset(ModelSQL, ModelView):
domain=[
('category', '=', Eval('product_uom')),
], depends=['product_uom', 'product'])
+ rates = fields.One2Many(string='Rates', field='asset',
+ model_name='investment.rate')
company_currency = fields.Function(fields.Many2One(readonly=True,
string='Company Currency', states={'invisible': True},
@@ -72,9 +74,9 @@ class Asset(ModelSQL, ModelView):
@classmethod
def default_currency_digits(cls):
- """ default: 2
+ """ default: 4
"""
- return 2
+ return 4
@fields.depends('product', 'uom')
def on_change_product(self):
diff --git a/locale/de.po b/locale/de.po
index 6af7f3c..12870d3 100644
--- a/locale/de.po
+++ b/locale/de.po
@@ -15,6 +15,18 @@ msgid "Investment Administrator"
msgstr "Investition Administrator"
+##############
+# ir.message #
+##############
+msgctxt "model:ir.message,text:msg_currency_unique_rate_date"
+msgid "A asset can only have one rate by date."
+msgstr "Es darf nur einen Kurs pro Datum für einen Vermögenswert geben."
+
+msgctxt "model:ir.message,text:msg_currency_rate_positive"
+msgid "A asset rate must be positive."
+msgstr "Der Kurs des Vermögenswertes muss positiv sein."
+
+
##############
# ir.ui.menu #
##############
@@ -50,6 +62,10 @@ msgctxt "view:investment.asset:"
msgid "Identifiers"
msgstr "Bezeichner"
+msgctxt "view:investment.asset:"
+msgid "Rates"
+msgstr "Kurse"
+
msgctxt "field:investment.asset,company:"
msgid "Company"
msgstr "Unternehmen"
@@ -110,6 +126,38 @@ msgctxt "help:investment.asset,secsymb:"
msgid "Stock market symbol"
msgstr "Börsensymbol"
+msgctxt "field:investment.asset,rates:"
+msgid "Rates"
+msgstr "Kurse"
+
+
+###################
+# investment.rate #
+###################
+msgctxt "model:investment.rate,name:"
+msgid "Rate"
+msgstr "Kurs"
+
+msgctxt "view:investment.rate:"
+msgid "per"
+msgstr "pro"
+
+msgctxt "field:investment.rate,asset:"
+msgid "Asset"
+msgstr "Vermögenswert"
+
+msgctxt "field:investment.rate,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:investment.rate,rate:"
+msgid "Rate"
+msgstr "Kurs"
+
+msgctxt "field:investment.rate,digits:"
+msgid "Digits"
+msgstr "Nachkommastellen"
+
######################
# product.identifier #
diff --git a/locale/en.po b/locale/en.po
index 36c4ac5..0625d2b 100644
--- a/locale/en.po
+++ b/locale/en.po
@@ -10,6 +10,14 @@ msgctxt "model:res.group,name:group_investment_admin"
msgid "Investment Administrator"
msgstr "Investment Administrator"
+msgctxt "model:ir.message,text:msg_currency_unique_rate_date"
+msgid "A asset can only have one rate by date."
+msgstr "A asset can only have one rate by date."
+
+msgctxt "model:ir.message,text:msg_currency_rate_positive"
+msgid "A asset rate must be positive."
+msgstr "A asset rate must be positive."
+
msgctxt "model:ir.ui.menu,name:menu_investment"
msgid "Investment"
msgstr "Investment"
@@ -94,6 +102,26 @@ msgctxt "help:investment.asset,secsymb:"
msgid "Stock market symbol"
msgstr "Stock market symbol"
+msgctxt "model:investment.rate,name:"
+msgid "Rate"
+msgstr "Rate"
+
+msgctxt "field:investment.rate,asset:"
+msgid "Asset"
+msgstr "Asset"
+
+msgctxt "field:investment.rate,date:"
+msgid "Date"
+msgstr "Date"
+
+msgctxt "field:investment.rate,rate:"
+msgid "Rate"
+msgstr "Rate"
+
+msgctxt "field:investment.rate,digits:"
+msgid "Digits"
+msgstr "Digits"
+
msgctxt "selection:product.identifier,type:"
msgid "National Securities Identifying Number (NSIN)"
msgstr "National Securities Identifying Number (NSIN)"
diff --git a/message.xml b/message.xml
new file mode 100644
index 0000000..7954767
--- /dev/null
+++ b/message.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ A asset can only have one rate by date.
+
+
+ A asset rate must be positive.
+
+
+
+
diff --git a/rate.py b/rate.py
new file mode 100644
index 0000000..f37194b
--- /dev/null
+++ b/rate.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+# This file is part of the investment-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 ModelView, ModelSQL, fields, Unique, Check
+from trytond.transaction import Transaction
+from trytond.pool import Pool
+from trytond.pyson import Eval, Bool
+
+
+class Rate(ModelSQL, ModelView):
+ 'Rate'
+ __name__ = 'investment.rate'
+
+ asset = fields.Many2One(string='Asset', required=True,
+ select=True, ondelete='CASCADE',
+ model_name='investment.asset')
+ date = fields.Date(string='Date', required=True, select=True)
+ rate = fields.Numeric(string='Rate', required=True,
+ digits=(16, Eval('asset_digits', 4)),
+ depends=['asset_digits'])
+
+ asset_digits = fields.Function(fields.Integer(string='Digits',
+ readonly=True), 'on_change_with_asset_digits')
+ currency = fields.Function(fields.Many2One(string='Currency',
+ readonly=True, model_name='currency.currency'),
+ 'on_change_with_currency')
+ uom = fields.Function(fields.Many2One(string='Uom',
+ readonly=True, model_name='product.uom'),
+ 'on_change_with_uom')
+
+ @classmethod
+ def __setup__(cls):
+ super(Rate, cls).__setup__()
+ t = cls.__table__()
+ cls._sql_constraints = [
+ ('date_asset_uniq',
+ Unique(t, t.date, t.asset),
+ 'investment.msg_unique_rate_date'),
+ ('check_rate',
+ Check(t, t.rate >= 0),
+ 'currency.msg_rate_positive'),
+ ]
+ cls._order.insert(0, ('date', 'DESC'))
+
+ @classmethod
+ def default_date(cls):
+ """ today
+ """
+ IrDate = Pool().get('ir.date')
+ return IrDate.today()
+
+ @fields.depends('asset', '_parent_asset.uom')
+ def on_change_with_uom(self, name=None):
+ """ get unit of asset
+ """
+ if self.asset:
+ return self.asset.uom.id
+
+ @fields.depends('asset', '_parent_asset.currency')
+ def on_change_with_currency(self, name=None):
+ """ get currency
+ """
+ if self.asset:
+ return self.asset.currency.id
+
+ @fields.depends('asset', '_parent_asset.currency_digits')
+ def on_change_with_asset_digits(self, name=None):
+ """ get digits for asset
+ """
+ if self.asset:
+ return self.asset.currency_digits
+ return 4
+
+# Rate
diff --git a/rate.xml b/rate.xml
new file mode 100644
index 0000000..dacff3d
--- /dev/null
+++ b/rate.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+ investment.rate
+ graph
+
+ rate_graph
+
+
+ investment.rate
+ tree
+
+ rate_list
+
+
+ investment.rate
+ form
+
+ rate_form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/__init__.py b/tests/__init__.py
index 04676f1..72793e9 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -5,12 +5,14 @@ import trytond.tests.test_tryton
import unittest
from trytond.modules.investment.tests.test_asset import AssetTestCase
+from trytond.modules.investment.tests.test_rate import RateTestCase
__all__ = ['suite']
class InvestmentTestCase(\
+ RateTestCase,\
AssetTestCase,\
):
'Test investment module'
diff --git a/tests/test_asset.py b/tests/test_asset.py
index e64ea88..6ea561e 100644
--- a/tests/test_asset.py
+++ b/tests/test_asset.py
@@ -5,9 +5,7 @@
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.pool import Pool
-from trytond.transaction import Transaction
from trytond.modules.company.tests import create_company
-from datetime import date
from decimal import Decimal
diff --git a/tests/test_rate.py b/tests/test_rate.py
new file mode 100644
index 0000000..647f221
--- /dev/null
+++ b/tests/test_rate.py
@@ -0,0 +1,50 @@
+# -*- 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.modules.company.tests import create_company
+from decimal import Decimal
+from datetime import date
+
+
+class RateTestCase(ModuleTestCase):
+ 'Test rate module'
+ module = 'investment'
+
+ @with_transaction()
+ def test_rate_create(self):
+ """ create rate
+ """
+ Asset = Pool().get('investment.asset')
+
+ company = self.prep_asset_company()
+ product = self.prep_asset_product(
+ name='Product 1',
+ description='some asset')
+
+ asset = self.prep_asset_item(
+ company=company,
+ product = product)
+
+ Asset.write(*[
+ [asset],
+ {
+ 'rates': [('create', [{
+ 'date': date(2022, 5, 1),
+ 'rate': Decimal('2.5'),
+ }, {
+ 'date': date(2022, 5, 2),
+ 'rate': Decimal('2.8'),
+ }])],
+ }])
+ self.assertEqual(len(asset.rates), 2)
+ self.assertEqual(asset.rates[0].date, date(2022, 5, 2))
+ self.assertEqual(asset.rates[0].rate, Decimal('2.8'))
+ self.assertEqual(asset.rates[0].uom.rec_name, 'Unit')
+ self.assertEqual(asset.rates[0].asset_digits, 4)
+ self.assertEqual(asset.rates[0].currency.rec_name, 'usd')
+
+# end RateTestCase
diff --git a/tryton.cfg b/tryton.cfg
index 3a75410..06d33ec 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -7,6 +7,8 @@ depends:
product
xml:
icon.xml
+ message.xml
group.xml
asset.xml
+ rate.xml
menu.xml
diff --git a/view/asset_form.xml b/view/asset_form.xml
index 7d279db..f3407bf 100644
--- a/view/asset_form.xml
+++ b/view/asset_form.xml
@@ -18,14 +18,19 @@ full copyright notices and license terms. -->
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
diff --git a/view/rate_form.xml b/view/rate_form.xml
new file mode 100644
index 0000000..82ae70d
--- /dev/null
+++ b/view/rate_form.xml
@@ -0,0 +1,17 @@
+
+
+
diff --git a/view/rate_graph.xml b/view/rate_graph.xml
new file mode 100644
index 0000000..a8a405b
--- /dev/null
+++ b/view/rate_graph.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/view/rate_list.xml b/view/rate_list.xml
new file mode 100644
index 0000000..2a41201
--- /dev/null
+++ b/view/rate_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+