diff --git a/__init__.py b/__init__.py
index 461ecbc..e4eea0f 100644
--- a/__init__.py
+++ b/__init__.py
@@ -5,8 +5,10 @@
from trytond.pool import Pool
from .asset import Asset
+from .identifier import Identifier
def register():
Pool.register(
Asset,
+ Identifier,
module='investment', type_='model')
diff --git a/asset.py b/asset.py
index 9503311..c7d3c4c 100644
--- a/asset.py
+++ b/asset.py
@@ -4,8 +4,6 @@
# full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields
-from trytond.exceptions import UserError
-from trytond.i18n import gettext
from trytond.transaction import Transaction
from trytond.pool import Pool
from trytond.pyson import Eval, Bool
@@ -46,6 +44,16 @@ class Asset(ModelSQL, ModelView):
currency_digits = fields.Integer(string='Currency Digits',
required=True)
+ wkn = fields.Function(fields.Char(string='NSIN', readonly=True,
+ help='National Securities Identifying Number'),
+ 'get_identifiers', searcher='search_identifier')
+ isin = fields.Function(fields.Char(string='ISIN', readonly=True,
+ help='International Securities Identification Number'),
+ 'get_identifiers', searcher='search_identifier')
+ secsymb = fields.Function(fields.Char(string='Symbol', readonly=True,
+ help='Stock market symbol'),
+ 'get_identifiers', searcher='search_identifier')
+
@classmethod
def default_currency(cls):
""" currency of company
@@ -84,6 +92,87 @@ class Asset(ModelSQL, ModelView):
if self.currency:
self.currency_digits = self.currency.digits
+ @classmethod
+ def get_identifier_sql(cls, tab_asset):
+ """ sql-query for identifiers
+ """
+ pool = Pool()
+ Product = pool.get('product.product')
+ Identifier = pool.get('product.identifier')
+ tab_prod = Product.__table__()
+ tab_wkn = Identifier.__table__()
+ tab_secsymb = Identifier.__table__()
+ tab_isin = Identifier.__table__()
+
+ query = tab_asset.join(tab_prod,
+ condition=tab_asset.product==tab_prod.id,
+ ).join(tab_wkn,
+ condition=(tab_prod.id==tab_wkn.product) & \
+ (tab_wkn.type == 'wkn'),
+ type_ = 'LEFT OUTER',
+ ).join(tab_secsymb,
+ condition=(tab_prod.id==tab_secsymb.product) & \
+ (tab_secsymb.type == 'secsymb'),
+ type_ = 'LEFT OUTER',
+ ).join(tab_isin,
+ condition=(tab_prod.id==tab_isin.product) & \
+ (tab_isin.type == 'isin'),
+ type_ = 'LEFT OUTER',
+ ).select(
+ tab_asset.id,
+ tab_wkn.code.as_('wkn'),
+ tab_secsymb.code.as_('secsymb'),
+ tab_isin.code.as_('isin'),
+ )
+ return query
+
+ @classmethod
+ def search_identifier(cls, names, clause):
+ """ search in identifier
+ """
+ pool = Pool()
+ Asset = pool.get('investment.asset')
+ tab_asset = Asset.__table__()
+ Operator = fields.SQL_OPERATORS[clause[1]]
+ tab_ids = cls.get_identifier_sql(tab_asset)
+
+ field_qu = getattr(tab_ids, names)
+ query = tab_ids.join(tab_asset,
+ condition=tab_ids.id==tab_asset.id,
+ ).select(
+ tab_asset.id,
+ where=Operator(field_qu, clause[2]) & \
+ (field_qu != None),
+ )
+
+ return [('id', 'in', query)]
+
+ @classmethod
+ def get_identifiers(cls, assets, names):
+ """ get identifiers of assets
+ """
+ pool = Pool()
+ Asset = pool.get('investment.asset')
+ tab_asset = Asset.__table__()
+ cursor = Transaction().connection.cursor()
+
+ result = {x:{y.id: None for y in assets} for x in names}
+
+ query = cls.get_identifier_sql(tab_asset)
+ query.where = tab_asset.id.in_([x.id for x in assets])
+
+ cursor.execute(*query)
+ l1 = cursor.fetchall()
+
+ for x in l1:
+ (id1, wkn, secsymb, isin) = x
+ r1 = {'wkn': wkn, 'secsymb': secsymb, 'isin': isin}
+
+ for n in names:
+ result[n][id1] = r1[n]
+
+ return result
+
@fields.depends('product')
def on_change_with_product_uom(self, name=None):
""" get category of product-uom
diff --git a/identifier.py b/identifier.py
new file mode 100644
index 0000000..ca5692d
--- /dev/null
+++ b/identifier.py
@@ -0,0 +1,21 @@
+# -*- 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 fields
+from trytond.pool import PoolMeta
+
+
+class Identifier(metaclass=PoolMeta):
+ __name__ = 'product.identifier'
+
+ @classmethod
+ def __setup__(cls):
+ super(Identifier, cls).__setup__()
+ cls.type.selection.extend([
+ ('wkn', 'National Securities Identifying Number (NSIN)'),
+ ('secsymb', 'Stock market symbol'),
+ ])
+
+# end Identifier
diff --git a/locale/de.po b/locale/de.po
index 5ecd515..6af7f3c 100644
--- a/locale/de.po
+++ b/locale/de.po
@@ -46,6 +46,10 @@ msgctxt "view:investment.asset:"
msgid "Currency and Units"
msgstr "Währung und Einheiten"
+msgctxt "view:investment.asset:"
+msgid "Identifiers"
+msgstr "Bezeichner"
+
msgctxt "field:investment.asset,company:"
msgid "Company"
msgstr "Unternehmen"
@@ -82,3 +86,38 @@ msgctxt "field:investment.asset,uom:"
msgid "UOM"
msgstr "Einheit"
+msgctxt "field:investment.asset,wkn:"
+msgid "NSIN"
+msgstr "WKN"
+
+msgctxt "help:investment.asset,wkn:"
+msgid "National Securities Identifying Number"
+msgstr "Wertpapierkennnummer"
+
+msgctxt "field:investment.asset,isin:"
+msgid "ISIN"
+msgstr "ISIN"
+
+msgctxt "help:investment.asset,isin:"
+msgid "International Securities Identification Number"
+msgstr "Internationale Wertpapierkennnummer"
+
+msgctxt "field:investment.asset,secsymb:"
+msgid "Symbol"
+msgstr "Symbol"
+
+msgctxt "help:investment.asset,secsymb:"
+msgid "Stock market symbol"
+msgstr "Börsensymbol"
+
+
+######################
+# product.identifier #
+######################
+msgctxt "selection:product.identifier,type:"
+msgid "National Securities Identifying Number (NSIN)"
+msgstr "Wertpapierkennnummer (WKN)"
+
+msgctxt "selection:product.identifier,type:"
+msgid "Stock market symbol"
+msgstr "Börsensymbol"
diff --git a/locale/en.po b/locale/en.po
index 66fc058..36c4ac5 100644
--- a/locale/en.po
+++ b/locale/en.po
@@ -30,6 +30,10 @@ msgctxt "view:investment.asset:"
msgid "Currency and Units"
msgstr "Currency and Units"
+msgctxt "view:investment.asset:"
+msgid "Identifiers"
+msgstr "Identifiers"
+
msgctxt "field:investment.asset,company:"
msgid "Company"
msgstr "Company"
@@ -66,3 +70,31 @@ msgctxt "field:investment.asset,uom:"
msgid "UOM"
msgstr "UOM"
+msgctxt "field:investment.asset,wkn:"
+msgid "NSIN"
+msgstr "NSIN"
+
+msgctxt "help:investment.asset,wkn:"
+msgid "National Securities Identifying Number"
+msgstr "National Securities Identifying Number"
+
+msgctxt "field:investment.asset,isin:"
+msgid "ISIN"
+msgstr "ISIN"
+
+msgctxt "help:investment.asset,isin:"
+msgid "International Securities Identification Number"
+msgstr "International Securities Identification Number"
+
+msgctxt "field:investment.asset,secsymb:"
+msgid "Symbol"
+msgstr "Symbol"
+
+msgctxt "help:investment.asset,secsymb:"
+msgid "Stock market symbol"
+msgstr "Stock market symbol"
+
+msgctxt "selection:product.identifier,type:"
+msgid "National Securities Identifying Number (NSIN)"
+msgstr "National Securities Identifying Number (NSIN)"
+
diff --git a/tests/test_asset.py b/tests/test_asset.py
index fd46058..e64ea88 100644
--- a/tests/test_asset.py
+++ b/tests/test_asset.py
@@ -6,7 +6,6 @@
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.company.tests import create_company
from datetime import date
from decimal import Decimal
@@ -82,6 +81,75 @@ class AssetTestCase(ModuleTestCase):
company=company,
product = product)
+ @with_transaction()
+ def test_asset_indentifiers(self):
+ """ create asset, add identifiers
+ """
+ pool = Pool()
+ Product = pool.get('product.product')
+ Asset = pool.get('investment.asset')
+
+ company = self.prep_asset_company()
+ product1 = self.prep_asset_product(
+ name='Product unit', unit='u')
+ product2 = self.prep_asset_product(
+ name='Product gram', unit='g')
+
+ asset1 = self.prep_asset_item(
+ company=company,
+ product = product1)
+ asset2 = self.prep_asset_item(
+ company=company,
+ product = product2)
+
+ Product.write(*[
+ [product1],
+ {
+ 'identifiers': [('create', [{
+ 'type': 'wkn',
+ 'code': '965515',
+ }, {
+ 'type': 'secsymb',
+ 'code': '1472977',
+ }, {
+ 'type': 'isin',
+ 'code': 'XC0009655157',
+ }, ])],
+ },
+ [product2],
+ {
+ 'identifiers': [('create', [{
+ 'type': 'wkn',
+ 'code': '965310',
+ }, {
+ 'type': 'secsymb',
+ 'code': '1431157',
+ }, {
+ 'type': 'isin',
+ 'code': 'XC0009653103',
+ }, ])],
+ },
+ ])
+
+ self.assertEqual(asset1.wkn, '965515')
+ self.assertEqual(asset1.isin, 'XC0009655157')
+ self.assertEqual(asset1.secsymb, '1472977')
+
+ self.assertEqual(Asset.search_count([('wkn', '=', '965515')]), 1)
+ self.assertEqual(Asset.search_count([('isin', '=', 'XC0009655157')]), 1)
+ self.assertEqual(Asset.search_count([('secsymb', '=', '1472977')]), 1)
+
+ self.assertEqual(Asset.search_count([
+ ('wkn', 'ilike', '9655%'),
+ ]), 1)
+ self.assertEqual(Asset.search_count([
+ ('wkn', 'ilike', '965%'),
+ ]), 2)
+
+ self.assertEqual(asset2.wkn, '965310')
+ self.assertEqual(asset2.isin, 'XC0009653103')
+ self.assertEqual(asset2.secsymb, '1431157')
+
@with_transaction()
def test_asset_check_product_update(self):
""" create asset
diff --git a/view/asset_form.xml b/view/asset_form.xml
index d53566b..7d279db 100644
--- a/view/asset_form.xml
+++ b/view/asset_form.xml
@@ -18,4 +18,14 @@ full copyright notices and license terms. -->
+
+
+
+
+
+
+
+
+
+
diff --git a/view/asset_list.xml b/view/asset_list.xml
index 31283db..23b5f74 100644
--- a/view/asset_list.xml
+++ b/view/asset_list.xml
@@ -4,6 +4,9 @@ The COPYRIGHT file at the top level of this repository contains the
full copyright notices and license terms. -->
+
+
+