Add country organizations

issue11689
review417911003
This commit is contained in:
Cédric Krier committed 2022-09-15 21:45:37 +02:00
1 parent b346b77e55
commit 5ed7f4e1d1
15 files changed
+724 -4

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Add country organizations
* Add UN M49 regions
* Add flag symbol for country and subdivision
+2
View File
@@ -8,6 +8,8 @@ def register():
# Prevent to import backend when importing scripts
from . import country
Pool.register(
country.Organization,
country.OrganizationMember,
country.Region,
country.Country,
country.Subdivision,
+120 -1
View File
@@ -1,13 +1,109 @@
# 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 datetime as dt
from sql import Literal
from sql.conditionals import Coalesce
from trytond import backend
from trytond.model import DeactivableMixin, ModelSQL, ModelView, fields, tree
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.pyson import Eval, If
from trytond.tools import lstrip_wildcard
from trytond.transaction import Transaction
class Organization(ModelSQL, ModelView):
"Organization"
__name__ = 'country.organization'
name = fields.Char("Name", required=True, translate=True)
code = fields.Char("Code")
members = fields.One2Many(
'country.organization.member', 'organization', "Members",
filter=[
('active', 'in', [True, False]),
])
countries = fields.Many2Many(
'country.organization.member', 'organization', 'country', "Countries",
readonly=True)
class OrganizationMember(ModelSQL, ModelView):
"Organization Member"
__name__ = 'country.organization.member'
organization = fields.Many2One(
'country.organization', "Organization", required=True)
country = fields.Many2One(
'country.country', "Country", required=True)
from_date = fields.Date(
"From Date",
domain=[
If(Eval('from_date') & Eval('to_date'),
('from_date', '<=', Eval('to_date')),
()),
])
to_date = fields.Date(
"To Date",
domain=[
If(Eval('from_date') & Eval('to_date'),
('to_date', '>=', Eval('from_date')),
()),
])
active = fields.Function(fields.Boolean("Active"), 'on_change_with_active')
@classmethod
def __setup__(cls):
super().__setup__()
cls._order.insert(0, ('country', None))
cls._order.insert(1, ('from_date', 'ASC NULLS FIRST'))
cls.__access__.add('organization')
@classmethod
def default_active(cls):
return True
@fields.depends('from_date', 'to_date')
def on_change_with_active(self, name=None):
pool = Pool()
Date = pool.get('ir.date')
context = Transaction().context
date = context.get('date', Date.today())
from_date = self.from_date or dt.date.min
to_date = self.to_date or dt.date.max
return from_date <= date <= to_date
@classmethod
def domain_active(cls, domain, tables):
pool = Pool()
Date = pool.get('ir.date')
context = Transaction().context
table, _ = tables[None]
_, operator, operand = domain
date = context.get('date', Date.today())
from_date = Coalesce(table.from_date, dt.date.min)
to_date = Coalesce(table.to_date, dt.date.max)
expression = (from_date <= date) & (to_date >= date)
if operator in {'=', '!='}:
if (operator == '=') != operand:
expression = ~expression
elif operator in {'in', 'not in'}:
if True in operand and False not in operand:
pass
elif False in operand and True not in operand:
expression = ~expression
else:
expression = Literal(True)
else:
expression = Literal(True)
return expression
class Region(tree(), ModelSQL, ModelView):
"Region"
__name__ = 'country.region'
@@ -60,6 +156,14 @@ class Country(DeactivableMixin, ModelSQL, ModelView):
'country.region', "Region", ondelete='SET NULL')
subdivisions = fields.One2Many('country.subdivision',
'country', 'Subdivisions')
members = fields.One2Many(
'country.organization.member', 'country', "Members",
filter=[
('active', 'in', [True, False]),
])
organizations = fields.Many2Many(
'country.organization.member', 'country', 'organization',
"Organizations", readonly=True)
@classmethod
def __setup__(cls):
@@ -115,6 +219,21 @@ class Country(DeactivableMixin, ModelSQL, ModelView):
('code_numeric', clause[1], code_value) + tuple(clause[3:]),
]
def is_member(self, organization, date=None):
"""Return if the country is in the organization at the date
organization can be an XML id"""
pool = Pool()
Date = pool.get('ir.date')
ModelData = pool.get('ir.model.data')
Organization = pool.get('country.organization')
if date is None:
date = Date.today()
if isinstance(organization, str):
organization = ModelData.get_id(organization)
with Transaction().set_context(date=date):
organization = Organization(organization)
return self in organization.countries
@classmethod
def create(cls, vlist):
vlist = [x.copy() for x in vlist]
+60
View File
@@ -20,6 +20,66 @@ this repository contains the full copyright notices and license terms. -->
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.ui.view" id="organization_view_form">
<field name="model">country.organization</field>
<field name="type">form</field>
<field name="name">organization_form</field>
</record>
<record model="ir.ui.view" id="organization_view_list">
<field name="model">country.organization</field>
<field name="type">tree</field>
<field name="name">organization_list</field>
</record>
<record model="ir.action.act_window" id="act_organization_form">
<field name="name">Organizations</field>
<field name="res_model">country.organization</field>
</record>
<record model="ir.action.act_window.view" id="act_organization_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="organization_view_list"/>
<field name="act_window" ref="act_organization_form"/>
</record>
<record model="ir.action.act_window.view" id="act_organization_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="organization_view_form"/>
<field name="act_window" ref="act_organization_form"/>
</record>
<menuitem
parent="menu_country"
action="act_organization_form"
sequence="20"
id="menu_organization_form"/>
<record model="ir.model.access" id="access_organization">
<field name="model" search="[('model', '=', 'country.organization')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_organization_admin">
<field name="model" search="[('model', '=', 'country.organization')]"/>
<field name="group" ref="res.group_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="organization_member_view_form">
<field name="model">country.organization.member</field>
<field name="type">form</field>
<field name="name">organization_member_form</field>
</record>
<record model="ir.ui.view" id="organization_member_view_list">
<field name="model">country.organization.member</field>
<field name="type">tree</field>
<field name="name">organization_member_list</field>
</record>
<record model="ir.ui.view" id="region_view_form">
<field name="model">country.region</field>
<field name="type">form</field>
+18
View File
@@ -4,6 +4,24 @@ Design
The *Country Module* introduces the following concepts:
.. _model-country.organization:
Organization
============
The *Organization* represents an international organization of `Countries
<model-country.country>`.
.. seealso::
Organizations can be found under the main menu entry:
|Administration --> Countries --> Organizations|__
.. |Administration --> Countries --> Organizations| replace:: :menuselection:`Administration --> Countries --> Organizations`
__ https://demo.tryton.org/model/country.organization
.. _model-country.region:
Region
+101
View File
@@ -0,0 +1,101 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data grouped="1">
<record model="country.organization" id="organization_eu">
<field name="name">European Union</field>
<field name="code">EU</field>
</record>
<record model="country.organization" id="organization_benelux">
<field name="name">Benelux Union</field>
<field name="code">Benelux</field>
</record>
<record model="country.organization" id="organization_nafta">
<field name="name">North American Free Trade Agreement</field>
<field name="code">NAFTA</field>
</record>
<record model="country.organization" id="organization_mercosur">
<field name="name">Southern Common Market</field>
<field name="code">Mercosur</field>
</record>
<record model="country.organization" id="organization_can">
<field name="name">Andean Community</field>
<field name="code">CAN</field>
</record>
<record model="country.organization" id="organization_caricom">
<field name="name">Caribbean Community</field>
<field name="code">CARICOM</field>
</record>
<record model="country.organization" id="organization_apec">
<field name="name">Asia-Pacific Economic Cooperation</field>
<field name="code">APEC</field>
</record>
<record model="country.organization" id="organization_asean">
<field name="name">Association of Southeast Asian Nations</field>
<field name="code">ASEAN</field>
</record>
<record model="country.organization" id="organization_safta">
<field name="name">South Asian Free Trade Area</field>
<field name="code">SAFTA</field>
</record>
<record model="country.organization" id="organization_gcc">
<field name="name">Cooperation Council for the Arab States of the Gulf</field>
<field name="code">GCC</field>
</record>
<record model="country.organization" id="organization_cemac">
<field name="name">Economic and Monetary Community of Central Africa</field>
<field name="code">CEMAC</field>
</record>
<record model="country.organization" id="organization_eccas">
<field name="name">Economic Community of Central African States</field>
<field name="code">ECCAS</field>
</record>
<record model="country.organization" id="organization_ecowas">
<field name="name">Economic Community of West African States</field>
<field name="code">ECOWAS</field>
</record>
<record model="country.organization" id="organization_cen-sad">
<field name="name">Community of Sahel–Saharan States</field>
<field name="code">CEN-SAD</field>
</record>
<record model="country.organization" id="organization_comesa">
<field name="name">Common Market for Eastern and Southern Africa</field>
<field name="code">COMESA</field>
</record>
<record model="country.organization" id="organization_eac">
<field name="name">East African Community</field>
<field name="code">EAC</field>
</record>
<record model="country.organization" id="organization_igad">
<field name="name">Intergovernmental Authority on Development</field>
<field name="code">IGAD</field>
</record>
<record model="country.organization" id="organization_sadc">
<field name="name">Southern African Development Community</field>
<field name="code">SADC</field>
</record>
<record model="country.organization" id="organization_amu">
<field name="name">Arab Maghreb Union</field>
<field name="code">AMU</field>
</record>
</data>
</tryton>
+306 -1
View File
@@ -2,6 +2,8 @@
# PYTHON_ARGCOMPLETE_OK
# 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 datetime as dt
import gettext
import os
import sys
@@ -25,6 +27,286 @@ except ImportError:
prog = os.path.basename(sys.argv[0])
sys.exit("proteus must be installed to use %s" % prog)
ORGANIZATIONS = {
# Founding members has no from date
'EU': {
'AT': [(dt.date(1995, 1, 1), None)],
'BE': [(None, None)],
'BG': [(dt.date(2007, 1, 1), None)],
'CY': [(dt.date(2004, 5, 1), None)],
'CZ': [(dt.date(2004, 5, 1), None)],
'DE': [(None, None)],
'DK': [(dt.date(1973, 1, 1), None)],
'EE': [(dt.date(2004, 5, 1), None)],
'ES': [(dt.date(1986, 1, 1), None)],
'FI': [(dt.date(1995, 1, 1), None)],
'FR': [(None, None)],
'GB': [(dt.date(1973, 1, 1), dt.date(2020, 1, 31))],
'GR': [(dt.date(1981, 1, 1), None)],
'HR': [(dt.date(2013, 7, 1), None)],
'HU': [(dt.date(2004, 5, 1), None)],
'IE': [(dt.date(1973, 1, 1), None)],
'IT': [(None, None)],
'LT': [(dt.date(2004, 5, 1), None)],
'LU': [(None, None)],
'LV': [(dt.date(2004, 5, 1), None)],
'MT': [(dt.date(2004, 5, 1), None)],
'NL': [(None, None)],
'PL': [(dt.date(2004, 5, 1), None)],
'PT': [(dt.date(1986, 1, 1), None)],
'RO': [(dt.date(2007, 1, 1), None)],
'SE': [(dt.date(1995, 1, 1), None)],
'SI': [(dt.date(2004, 5, 1), None)],
'SK': [(dt.date(2004, 5, 1), None)],
},
'Benelux': {
'BE': [(None, None)],
'LU': [(None, None)],
'NL': [(None, None)],
},
'NAFTA': {
'CA': [(None, None)],
'MX': [(None, None)],
'US': [(None, None)],
},
'Mercosur': {
'AR': [(None, None)],
'BR': [(None, None)],
'PY': [(None, None)],
'UY': [(None, None)],
'VE': [(dt.date(2012, 7, 31), dt.date(2016, 12, 2))],
},
'CAN': {
# days and months are default to covert the full year
'BO': [(None, None)],
'CL': [(dt.date(1969, 1, 1), dt.date(1976, 12, 31))],
'CO': [(None, None)],
'EC': [(None, None)],
'PE': [(None, None)],
'VE': [(dt.date(1973, 1, 1), dt.date(2006, 12, 31))],
},
'CARICOM': {
'AG': [(dt.date(1974, 7, 4), None)],
'BB': [(None, None)],
'BS': [(dt.date(1983, 7, 4), None)],
'BZ': [(dt.date(1974, 5, 1), None)],
'DM': [(dt.date(1974, 5, 1), None)],
'GD': [(dt.date(1974, 5, 1), None)],
'GY': [(None, None)],
'HT': [(dt.date(2002, 7, 2), None)],
'JM': [(None, None)],
'KN': [(dt.date(1974, 7, 26), None)],
'LC': [(dt.date(1974, 5, 1), None)],
'MS': [(dt.date(1974, 5, 1), None)],
'SR': [(dt.date(1995, 7, 4), None)],
'TT': [(None, None)],
'VC': [(dt.date(1974, 5, 1), None)],
},
'APEC': {
# days are default to covert the full month
'AU': [(None, None)],
'BN': [(None, None)],
'CA': [(None, None)],
'CL': [(dt.date(1994, 11, 1), None)],
'CN': [(dt.date(1991, 11, 1), None)],
'HK': [(dt.date(1991, 11, 1), None)],
'ID': [(None, None)],
'JP': [(None, None)],
'KR': [(None, None)],
'MX': [(dt.date(1993, 11, 1), None)],
'MY': [(None, None)],
'NZ': [(None, None)],
'PE': [(dt.date(1998, 11, 1), None)],
'PG': [(dt.date(1993, 11, 1), None)],
'PH': [(None, None)],
'RU': [(dt.date(1998, 11, 1), None)],
'SG': [(None, None)],
'TH': [(None, None)],
'TW': [(dt.date(1991, 11, 1), None)],
'US': [(None, None)],
'VN': [(dt.date(1998, 11, 1), None)],
},
'ASEAN': {
'BN': [(dt.date(1984, 1, 7), None)],
'ID': [(None, None)],
'KH': [(dt.date(1999, 4, 30), None)],
'LA': [(dt.date(1997, 7, 23), None)],
'MM': [(dt.date(1997, 7, 23), None)],
'MY': [(None, None)],
'PH': [(None, None)],
'SG': [(None, None)],
'TH': [(None, None)],
'VN': [(dt.date(1995, 7, 28), None)],
},
'SAFTA': {
'AF': [(None, None)],
'BD': [(None, None)],
'BT': [(None, None)],
'IN': [(None, None)],
'LK': [(None, None)],
'MV': [(None, None)],
'NP': [(None, None)],
'PK': [(None, None)],
},
'GCC': {
'AE': [(None, None)],
'BH': [(None, None)],
'KW': [(None, None)],
'OM': [(None, None)],
'QA': [(None, None)],
'SA': [(None, None)],
},
'CEMAC': {
'CF': [(None, None)],
'CG': [(None, None)],
'CM': [(None, None)],
'GA': [(None, None)],
'GQ': [(dt.date(1983, 12, 19), None)],
'TD': [(None, None)],
},
'ECCAS': {
'AO': [(None, None)],
'BI': [(None, None)],
'CM': [(None, None)],
'CF': [(None, None)],
'TD': [(None, None)],
'CD': [(None, None)],
'GQ': [(None, None)],
'GA': [(None, None)],
'CG': [(None, None)],
'RW': [(None, dt.date(2007, 12, 31)), (dt.date(2016, 8, 17), None)],
'ST': [(None, None)],
},
'ECOWAS': {
'BF': [(None, dt.date(2022, 1, 28))],
'BJ': [(None, None)],
'CI': [(None, None)],
'CV': [(dt.date(1977, 1, 1), None)],
'GH': [(None, None)],
'GM': [(None, None)],
'GN': [(None, dt.date(2021, 9, 8))],
'GW': [(None, None)],
'LR': [(None, None)],
'ML': [(None, dt.date(2021, 5, 30))],
'MR': [(None, dt.date(2000, 12, 1))],
'NE': [(None, None)],
'NG': [(None, None)],
'SL': [(None, None)],
'SN': [(None, None)],
'TG': [(None, None)],
},
'CEN-SAD': {
# days and months are default to covert the full year
'BF': [(None, None)],
'BJ': [(dt.date(2002, 1, 1), None)],
'CF': [(dt.date(1999, 1, 1), None)],
'CI': [(dt.date(2004, 1, 1), None)],
'CV': [(dt.date(2009, 1, 1), None)],
'DJ': [(dt.date(2000, 1, 1), None)],
'EG': [(dt.date(2001, 1, 1), None)],
'ER': [(dt.date(1999, 1, 1), None)],
'FN': [(dt.date(2007, 1, 1), None)],
'GH': [(dt.date(2005, 1, 1), None)],
'GM': [(dt.date(2000, 1, 1), None)],
'GW': [(dt.date(2004, 1, 1), None)],
'KE': [(dt.date(2007, 1, 1), None)],
'KM': [(dt.date(2007, 1, 1), None)],
'LR': [(dt.date(2004, 1, 1), None)],
'LY': [(None, None)],
'MA': [(dt.date(2001, 1, 1), None)],
'ML': [(None, None)],
'MR': [(dt.date(2007, 1, 1), None)],
'NE': [(None, None)],
'NG': [(dt.date(2001, 1, 1), None)],
'SD': [(None, None)],
'SL': [(dt.date(2005, 1, 1), None)],
'SN': [(dt.date(2000, 1, 1), None)],
'SO': [(dt.date(2001, 1, 1), None)],
'ST': [(dt.date(2007, 1, 1), None)],
'TD': [(None, None)],
'TG': [(dt.date(2002, 1, 1), None)],
'TN': [(dt.date(2001, 1, 1), None)],
},
'COMESA': {
# days and months are default to covert the full year
'AO': [(None, dt.date(2007, 1, 1))],
'BI': [(dt.date(1981, 12, 21), None)],
'CD': [(dt.date(1981, 12, 21), None)],
'DJ': [(dt.date(1981, 12, 21), None)],
'EG': [(dt.date(1999, 1, 6), None)],
'ER': [(dt.date(1994, 1, 1), None)],
'ET': [(dt.date(1981, 12, 21), None)],
'KE': [(None, None)],
'KM': [(dt.date(1981, 12, 21), None)],
'LS': [(None, dt.date(1997, 1, 1))],
'LY': [(dt.date(2005, 6, 3), None)],
'MG': [(None, None)],
'MU': [(None, None)],
'MW': [(None, None)],
'MZ': [(None, dt.date(1997, 1, 1))],
'NA': [(None, dt.date(2004, 5, 2))],
'RW': [(None, None)],
'SC': [(dt.date(2001, 1, 1), None)],
'SD': [(dt.date(1981, 12, 21), None)],
'SO': [(dt.date(2018, 7, 19), None)],
'SZ': [(dt.date(1981, 12, 21), None)],
'TN': [(dt.date(2018, 7, 18), None)],
'TZ': [(None, dt.date(2000, 9, 2))],
'UG': [(None, None)],
'ZM': [(None, None)],
'ZW': [(None, None)],
},
'EAC': {
# days and months are default to covert the full year
'BI': [(dt.date(2007, 1, 1), None)],
'CD': [(dt.date(2022, 1, 1), None)],
'KE': [(None, None)],
'RW': [(dt.date(2007, 1, 1), None)],
'SS': [(dt.date(2012, 1, 1), None)],
'TZ': [(None, None)],
'UG': [(None, None)],
},
'IGAD': {
# days and months are default to covert the full year
'DJ': [(None, None)],
'ER': [(dt.date(1993, 1, 1), dt.date(2007, 12, 31)),
(dt.date(2011, 1, 1), None)],
'ET': [(None, None)],
'KE': [(None, None)],
'SD': [(None, None)],
'SO': [(None, None)],
'SS': [(dt.date(2011, 1, 1), dt.date(2021, 12, 1))],
'UG': [(None, None)],
},
'SADC': {
'AO': [(None, None)],
'BW': [(None, None)],
'CD': [(dt.date(1997, 9, 8), None)],
'KM': [(dt.date(2017, 1, 1), None)],
'LS': [(None, None)],
'MG': [(dt.date(2005, 8, 18), dt.date(2009, 1, 26)),
(dt.date(2014, 1, 30), None)],
'MU': [(dt.date(1995, 8, 28), None)],
'MW': [(None, None)],
'MZ': [(None, None)],
'NA': [(dt.date(1990, 3, 21), None)],
'SC': [(dt.date(1997, 9, 8), dt.date(2004, 7, 1)),
(dt.date(2008, 1, 1), None)],
'SZ': [(None, None)],
'TZ': [(None, None)],
'ZA': [(dt.date(1994, 8, 30), None)],
'ZM': [(None, None)],
'ZW': [(None, None)],
},
'AMU': {
'DZ': [(None, None)],
'LY': [(None, None)],
'MA': [(None, None)],
'MR': [(None, None)],
'TN': [(None, None)],
},
}
SUBREGIONS = {
'001': ['002', '009', '010', '019', '142', '150'],
'002': ['015', '202'],
@@ -109,10 +391,18 @@ def get_countries():
return {c.code: c for c in Country.find([])}
def get_organizations():
Organization = Model.get('country.organization')
return {o.code: o for o in Organization.find([])}
def update_countries(countries):
print("Update countries", file=sys.stderr)
Region = Model.get('country.region')
Country = Model.get('country.country')
Member = Model.get('country.organization.member')
organizations = get_organizations()
code2region = {a.code_numeric: a for a in Region.find([])}
@@ -122,11 +412,26 @@ def update_countries(countries):
if code in countries:
record = countries[code]
else:
record = Country(code=code)
record = Country(code=code, members=[])
record.name = _remove_forbidden_chars(country.name)
record.code3 = country.alpha_3
record.code_numeric = country.numeric
record.region = code2region.get(REGION2PARENT.get(country.numeric))
for organization_code, members in ORGANIZATIONS.items():
if organization_code in organizations and code in members:
organization = organizations[organization_code]
dates = members[code].copy()
for member in list(record.members):
if member.organization == organization:
if dates:
member.from_date, member.to_date = dates.pop()
else:
record.members.remove(member)
for from_date, to_date in dates:
record.members.append(Member(
organization=organization,
from_date=from_date,
to_date=to_date))
records.append(record)
Country.save(records)
+1 -1
View File
@@ -61,7 +61,7 @@ else:
if local_version:
version += '+' + '.'.join(local_version)
requires = []
requires = ['python-sql']
for dep in info.get('depends', []):
if not re.match(r'(ir|res)(\W|$)', dep):
requires.append(get_require_version('trytond_%s' % dep))
+71 -1
View File
@@ -1,12 +1,82 @@
# This file is part of 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
import datetime as dt
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
class CountryTestCase(ModuleTestCase):
'Test Country module'
module = 'country'
def create_membership(self, from_date=None, to_date=None):
pool = Pool()
Country = pool.get('country.country')
Organization = pool.get('country.organization')
OrganizationMember = pool.get('country.organization.member')
organization = Organization(name="Organization")
organization.save()
country = Country(name="Country")
country.save()
member = OrganizationMember(
organization=organization, country=country,
from_date=from_date, to_date=to_date)
member.save()
return organization, country
@with_transaction()
def test_is_member_no_date(self):
"Test is member without date"
organization, country = self.create_membership()
self.assertTrue(country.is_member(organization))
self.assertTrue(country.is_member(organization, dt.date.min))
self.assertTrue(country.is_member(organization, dt.date.max))
@with_transaction()
def test_is_member_with_from_date(self):
"Test is member with from date"
today = dt.date.today()
yesterday = today - dt.timedelta(days=1)
tomorrow = today + dt.timedelta(days=1)
organization, country = self.create_membership(from_date=today)
self.assertTrue(country.is_member(organization, today))
self.assertFalse(country.is_member(organization, yesterday))
self.assertTrue(country.is_member(organization, tomorrow))
self.assertFalse(country.is_member(organization, dt.date.min))
self.assertTrue(country.is_member(organization, dt.date.max))
@with_transaction()
def test_is_member_with_to_date(self):
"Test is member with to date"
today = dt.date.today()
yesterday = today - dt.timedelta(days=1)
tomorrow = today + dt.timedelta(days=1)
organization, country = self.create_membership(to_date=today)
self.assertTrue(country.is_member(organization, today))
self.assertTrue(country.is_member(organization, yesterday))
self.assertFalse(country.is_member(organization, tomorrow))
self.assertTrue(country.is_member(organization, dt.date.min))
self.assertFalse(country.is_member(organization, dt.date.max))
@with_transaction()
def test_is_member_with_dates(self):
"Test is member with dates"
today = dt.date.today()
yesterday = today - dt.timedelta(days=1)
tomorrow = today + dt.timedelta(days=1)
organization, country = self.create_membership(
from_date=yesterday, to_date=tomorrow)
self.assertTrue(country.is_member(organization, today))
self.assertTrue(country.is_member(organization, yesterday))
self.assertFalse(country.is_member(organization, dt.date.min))
self.assertFalse(country.is_member(organization, dt.date.max))
del ModuleTestCase
+1
View File
@@ -5,4 +5,5 @@ depends:
res
xml:
country.xml
organization.xml
region.xml
+2
View File
@@ -16,4 +16,6 @@ this repository contains the full copyright notices and license terms. -->
<label name="code_numeric"/>
<field name="code_numeric"/>
<field name="subdivisions" colspan="6"/>
<field name="members" colspan="6"/>
</form>
+11
View File
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form>
<label name="name"/>
<field name="name"/>
<label name="code"/>
<field name="code"/>
<field name="members" colspan="4"/>
</form>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="name" expand="2"/>
<field name="code" optional="0"/>
</tree>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form>
<label name="country"/>
<field name="country"/>
<label name="organization"/>
<field name="organization"/>
<label name="from_date"/>
<field name="from_date"/>
<label name="to_date"/>
<field name="to_date"/>
</form>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="country" expand="2"/>
<field name="organization" expand="2"/>
<field name="from_date" optional="0"/>
<field name="to_date" optional="0"/>
</tree>