Active Record
This commit is contained in:
1 parent
7d37313c72
commit
4d84501fef
7 files changed
+292
-321
No files matched your search
+17
@@ -1,8 +1,25 @@
|
||||
#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.pool import Pool
|
||||
from .category import *
|
||||
from .party import *
|
||||
from .address import *
|
||||
from .contact_mechanism import *
|
||||
from .configuration import *
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
Category,
|
||||
Party,
|
||||
PartyCategory,
|
||||
CheckVIESResult,
|
||||
CheckVIESNoResult,
|
||||
Address,
|
||||
ContactMechanism,
|
||||
Configuration,
|
||||
module='party', type_='model')
|
||||
Pool.register(
|
||||
CheckVIES,
|
||||
module='party', type_='wizard')
|
||||
+69
-81
@@ -3,10 +3,11 @@
|
||||
'Address'
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.pyson import Eval, If
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.backend import TableHandler
|
||||
|
||||
__all__ = ['Address']
|
||||
|
||||
STATES = {
|
||||
'readonly': ~Eval('active'),
|
||||
}
|
||||
@@ -15,10 +16,9 @@ DEPENDS = ['active']
|
||||
|
||||
class Address(ModelSQL, ModelView):
|
||||
"Address"
|
||||
_name = 'party.address'
|
||||
_description = __doc__
|
||||
__name__ = 'party.address'
|
||||
party = fields.Many2One('party.party', 'Party', required=True,
|
||||
ondelete='CASCADE', select=True, states={
|
||||
ondelete='CASCADE', select=True, states={
|
||||
'readonly': If(~Eval('active'), True, Eval('id', 0) > 0),
|
||||
},
|
||||
depends=['active', 'id'])
|
||||
@@ -39,98 +39,86 @@ class Address(ModelSQL, ModelView):
|
||||
full_address = fields.Function(fields.Text('Full Address'),
|
||||
'get_full_address')
|
||||
|
||||
def __init__(self):
|
||||
super(Address, self).__init__()
|
||||
self._order.insert(0, ('party', 'ASC'))
|
||||
self._order.insert(1, ('sequence', 'ASC'))
|
||||
self._error_messages.update({
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Address, cls).__setup__()
|
||||
cls._order.insert(0, ('party', 'ASC'))
|
||||
cls._order.insert(1, ('sequence', 'ASC'))
|
||||
cls._error_messages.update({
|
||||
'write_party': 'You can not modify the party of an address!',
|
||||
})
|
||||
|
||||
def init(self, module_name):
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
cursor = Transaction().cursor
|
||||
table = TableHandler(cursor, self, module_name)
|
||||
table = TableHandler(cursor, cls, module_name)
|
||||
|
||||
super(Address, self).init(module_name)
|
||||
super(Address, cls).__register__(module_name)
|
||||
|
||||
# Migration from 2.4: drop required on sequence
|
||||
table.not_null_action('sequence', action='remove')
|
||||
|
||||
def default_active(self):
|
||||
@staticmethod
|
||||
def default_active():
|
||||
return True
|
||||
|
||||
def get_full_address(self, ids, name):
|
||||
if not ids:
|
||||
return {}
|
||||
res = {}
|
||||
for address in self.browse(ids):
|
||||
res[address.id] = ''
|
||||
if address.name:
|
||||
res[address.id] += address.name
|
||||
if address.street:
|
||||
if res[address.id]:
|
||||
res[address.id] += '\n'
|
||||
res[address.id] += address.street
|
||||
if address.streetbis:
|
||||
if res[address.id]:
|
||||
res[address.id] += '\n'
|
||||
res[address.id] += address.streetbis
|
||||
if address.zip or address.city:
|
||||
if res[address.id]:
|
||||
res[address.id] += '\n'
|
||||
if address.zip:
|
||||
res[address.id] += address.zip
|
||||
if address.city:
|
||||
if res[address.id][-1:] != '\n':
|
||||
res[address.id] += ' '
|
||||
res[address.id] += address.city
|
||||
if address.country or address.subdivision:
|
||||
if res[address.id]:
|
||||
res[address.id] += '\n'
|
||||
if address.subdivision:
|
||||
res[address.id] += address.subdivision.name
|
||||
if address.country:
|
||||
if res[address.id][-1:] != '\n':
|
||||
res[address.id] += ' '
|
||||
res[address.id] += address.country.name
|
||||
return res
|
||||
def get_full_address(self, name):
|
||||
full_address = ''
|
||||
if self.name:
|
||||
full_address = self.name
|
||||
if self.street:
|
||||
if full_address:
|
||||
full_address += '\n'
|
||||
full_address += self.street
|
||||
if self.streetbis:
|
||||
if full_address:
|
||||
full_address += '\n'
|
||||
full_address += self.streetbis
|
||||
if self.zip or self.city:
|
||||
if full_address:
|
||||
full_address += '\n'
|
||||
if self.zip:
|
||||
full_address += self.zip
|
||||
if self.city:
|
||||
if full_address[-1:] != '\n':
|
||||
full_address += ' '
|
||||
full_address += self.city
|
||||
if self.country or self.subdivision:
|
||||
if full_address:
|
||||
full_address += '\n'
|
||||
if self.subdivision:
|
||||
full_address += self.subdivision.name
|
||||
if self.country:
|
||||
if full_address[-1:] != '\n':
|
||||
full_address += ' '
|
||||
full_address += self.country.name
|
||||
return full_address
|
||||
|
||||
def get_rec_name(self, ids, name):
|
||||
if not ids:
|
||||
return {}
|
||||
res = {}
|
||||
for address in self.browse(ids):
|
||||
res[address.id] = ", ".join(x for x in [address.name,
|
||||
address.party.rec_name, address.zip, address.city] if x)
|
||||
return res
|
||||
def get_rec_name(self, name):
|
||||
return ", ".join(x for x in [self.name,
|
||||
self.party.rec_name, self.zip, self.city] if x)
|
||||
|
||||
def search_rec_name(self, name, clause):
|
||||
ids = self.search(['OR',
|
||||
('zip',) + clause[1:],
|
||||
('city',) + clause[1:],
|
||||
('name',) + clause[1:],
|
||||
], order=[])
|
||||
if ids:
|
||||
return [('id', 'in', ids)]
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
addresses = cls.search(['OR',
|
||||
('zip',) + clause[1:],
|
||||
('city',) + clause[1:],
|
||||
('name',) + clause[1:],
|
||||
], order=[])
|
||||
if addresses:
|
||||
return [('id', 'in', [address.id for address in addresses])]
|
||||
return [('party',) + clause[1:]]
|
||||
|
||||
def write(self, ids, vals):
|
||||
@classmethod
|
||||
def write(cls, addresses, vals):
|
||||
if 'party' in vals:
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for address in self.browse(ids):
|
||||
for address in addresses:
|
||||
if address.party.id != vals['party']:
|
||||
self.raise_user_error('write_party')
|
||||
return super(Address, self).write(ids, vals)
|
||||
cls.raise_user_error('write_party')
|
||||
super(Address, cls).write(addresses, vals)
|
||||
|
||||
def on_change_country(self, vals):
|
||||
subdivision_obj = Pool().get('country.subdivision')
|
||||
result = dict((k, vals.get(k))
|
||||
for k in ('country', 'subdivision'))
|
||||
if vals['subdivision']:
|
||||
subdivision = subdivision_obj.browse(vals['subdivision'])
|
||||
if subdivision.country.id != vals['country']:
|
||||
result['subdivision'] = None
|
||||
return result
|
||||
|
||||
Address()
|
||||
def on_change_country(self):
|
||||
if (self.subdivision
|
||||
and self.subdivision.country != self.country):
|
||||
return {'subdivision': None}
|
||||
return {}
|
||||
+23
-33
@@ -3,6 +3,8 @@
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.pyson import Eval
|
||||
|
||||
__all__ = ['Category']
|
||||
|
||||
STATES = {
|
||||
'readonly': ~Eval('active'),
|
||||
}
|
||||
@@ -13,8 +15,7 @@ SEPARATOR = ' / '
|
||||
|
||||
class Category(ModelSQL, ModelView):
|
||||
"Category"
|
||||
_name = "party.category"
|
||||
_description = __doc__
|
||||
__name__ = 'party.category'
|
||||
name = fields.Char('Name', required=True, states=STATES, translate=True,
|
||||
depends=DEPENDS)
|
||||
parent = fields.Many2One('party.category', 'Parent',
|
||||
@@ -23,48 +24,39 @@ class Category(ModelSQL, ModelView):
|
||||
'Children', states=STATES, depends=DEPENDS)
|
||||
active = fields.Boolean('Active')
|
||||
|
||||
def __init__(self):
|
||||
super(Category, self).__init__()
|
||||
self._sql_constraints = [
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Category, cls).__setup__()
|
||||
cls._sql_constraints = [
|
||||
('name_parent_uniq', 'UNIQUE(name, parent)',
|
||||
'The name of a party category must be unique by parent!'),
|
||||
]
|
||||
self._constraints += [
|
||||
cls._constraints += [
|
||||
('check_recursion', 'recursive_categories'),
|
||||
('check_name', 'wrong_name'),
|
||||
]
|
||||
self._error_messages.update({
|
||||
cls._error_messages.update({
|
||||
'recursive_categories': 'You can not create recursive categories!',
|
||||
'wrong_name': 'You can not use "%s" in name field!' % SEPARATOR,
|
||||
})
|
||||
self._order.insert(1, ('name', 'ASC'))
|
||||
cls._order.insert(1, ('name', 'ASC'))
|
||||
|
||||
def default_active(self):
|
||||
@staticmethod
|
||||
def default_active():
|
||||
return True
|
||||
|
||||
def check_name(self, ids):
|
||||
for category in self.browse(ids):
|
||||
if SEPARATOR in category.name:
|
||||
return False
|
||||
def check_name(self):
|
||||
if SEPARATOR in self.name:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_rec_name(self, ids, name):
|
||||
if not ids:
|
||||
return {}
|
||||
res = {}
|
||||
def get_rec_name(self, name):
|
||||
if self.parent:
|
||||
return self.parent.get_rec_name(name) + SEPARATOR + self.name
|
||||
return self.name
|
||||
|
||||
def _name(category):
|
||||
if category.id in res:
|
||||
return res[category.id]
|
||||
elif category.parent:
|
||||
return _name(category.parent) + SEPARATOR + category.name
|
||||
else:
|
||||
return category.name
|
||||
for category in self.browse(ids):
|
||||
res[category.id] = _name(category)
|
||||
return res
|
||||
|
||||
def search_rec_name(self, name, clause):
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
if isinstance(clause[2], basestring):
|
||||
values = clause[2].split(SEPARATOR)
|
||||
values.reverse()
|
||||
@@ -73,9 +65,7 @@ class Category(ModelSQL, ModelView):
|
||||
for name in values:
|
||||
domain.append((field, clause[1], name))
|
||||
field = 'parent.' + field
|
||||
ids = self.search(domain, order=[])
|
||||
return [('id', 'in', ids)]
|
||||
categories = cls.search(domain, order=[])
|
||||
return [('id', 'in', [category.id for category in categories])]
|
||||
#TODO Handle list
|
||||
return [('name',) + tuple(clause[1:])]
|
||||
|
||||
Category()
|
||||
+3
-4
@@ -2,11 +2,12 @@
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from trytond.model import ModelView, ModelSQL, ModelSingleton, fields
|
||||
|
||||
__all__ = ['Configuration']
|
||||
|
||||
|
||||
class Configuration(ModelSingleton, ModelSQL, ModelView):
|
||||
'Party Configuration'
|
||||
_name = 'party.configuration'
|
||||
_description = __doc__
|
||||
__name__ = 'party.configuration'
|
||||
|
||||
party_sequence = fields.Property(fields.Many2One('ir.sequence',
|
||||
'Party Sequence', domain=[
|
||||
@@ -15,5 +16,3 @@ class Configuration(ModelSingleton, ModelSQL, ModelView):
|
||||
party_lang = fields.Property(fields.Many2One("ir.lang", 'Party Language',
|
||||
help=('The value set on this field will preset the language on new '
|
||||
'parties')))
|
||||
|
||||
Configuration()
|
||||
+42
-43
@@ -5,6 +5,8 @@ from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.backend import TableHandler
|
||||
|
||||
__all__ = ['ContactMechanism']
|
||||
|
||||
STATES = {
|
||||
'readonly': ~Eval('active'),
|
||||
}
|
||||
@@ -26,8 +28,7 @@ _TYPES = [
|
||||
|
||||
class ContactMechanism(ModelSQL, ModelView):
|
||||
"Contact Mechanism"
|
||||
_name = "party.contact_mechanism"
|
||||
_description = __doc__
|
||||
__name__ = 'party.contact_mechanism'
|
||||
_rec_name = 'value'
|
||||
|
||||
type = fields.Selection(_TYPES, 'Type', required=True, states=STATES,
|
||||
@@ -72,41 +73,42 @@ class ContactMechanism(ModelSQL, ModelView):
|
||||
}, on_change=['other_value'], depends=['value', 'type', 'active']),
|
||||
'get_value', setter='set_value')
|
||||
|
||||
def __init__(self):
|
||||
super(ContactMechanism, self).__init__()
|
||||
self._order.insert(0, ('party', 'ASC'))
|
||||
self._order.insert(1, ('sequence', 'ASC'))
|
||||
self._error_messages.update({
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(ContactMechanism, cls).__setup__()
|
||||
cls._order.insert(0, ('party', 'ASC'))
|
||||
cls._order.insert(1, ('sequence', 'ASC'))
|
||||
cls._error_messages.update({
|
||||
'write_party': 'You can not modify the party of ' \
|
||||
'a contact mechanism!',
|
||||
})
|
||||
|
||||
def init(self, module_name):
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
cursor = Transaction().cursor
|
||||
table = TableHandler(cursor, self, module_name)
|
||||
table = TableHandler(cursor, cls, module_name)
|
||||
|
||||
super(ContactMechanism, self).init(module_name)
|
||||
super(ContactMechanism, cls).__register__(module_name)
|
||||
|
||||
# Migration from 2.4: drop required on sequence
|
||||
table.not_null_action('sequence', action='remove')
|
||||
|
||||
def default_type(self):
|
||||
@staticmethod
|
||||
def default_type():
|
||||
return 'phone'
|
||||
|
||||
def default_active(self):
|
||||
@staticmethod
|
||||
def default_active():
|
||||
return True
|
||||
|
||||
def get_value(self, ids, names):
|
||||
res = {}
|
||||
for name in names:
|
||||
res[name] = {}
|
||||
for mechanism in self.browse(ids):
|
||||
for name in names:
|
||||
res[name][mechanism.id] = mechanism.value
|
||||
return res
|
||||
@classmethod
|
||||
def get_value(cls, mechanisms, names):
|
||||
return dict((name, dict((m.id, m.value) for m in mechanisms))
|
||||
for name in names)
|
||||
|
||||
def set_value(self, ids, name, value):
|
||||
self.write(ids, {
|
||||
@classmethod
|
||||
def set_value(cls, mechanisms, name, value):
|
||||
cls.write(mechanisms, {
|
||||
'value': value,
|
||||
})
|
||||
|
||||
@@ -118,33 +120,30 @@ class ContactMechanism(ModelSQL, ModelView):
|
||||
'skype': value,
|
||||
'sip': value,
|
||||
'other_value': value,
|
||||
}
|
||||
}
|
||||
|
||||
def on_change_value(self, vals):
|
||||
return self._change_value(vals.get('value'))
|
||||
def on_change_value(self):
|
||||
return self._change_value(self.value)
|
||||
|
||||
def on_change_website(self, vals):
|
||||
return self._change_value(vals.get('website'))
|
||||
def on_change_website(self):
|
||||
return self._change_value(self.website)
|
||||
|
||||
def on_change_email(self, vals):
|
||||
return self._change_value(vals.get('email'))
|
||||
def on_change_email(self):
|
||||
return self._change_value(self.email)
|
||||
|
||||
def on_change_skype(self, vals):
|
||||
return self._change_value(vals.get('skype'))
|
||||
def on_change_skype(self):
|
||||
return self._change_value(self.skype)
|
||||
|
||||
def on_change_sip(self, vals):
|
||||
return self._change_value(vals.get('sip'))
|
||||
def on_change_sip(self):
|
||||
return self._change_value(self.sip)
|
||||
|
||||
def on_change_other_value(self, vals):
|
||||
return self._change_value(vals.get('other_value'))
|
||||
def on_change_other_value(self):
|
||||
return self._change_value(self.other_value)
|
||||
|
||||
def write(self, ids, vals):
|
||||
@classmethod
|
||||
def write(cls, mechanisms, vals):
|
||||
if 'party' in vals:
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for mechanism in self.browse(ids):
|
||||
for mechanism in mechanisms:
|
||||
if mechanism.party.id != vals['party']:
|
||||
self.raise_user_error('write_party')
|
||||
return super(ContactMechanism, self).write(ids, vals)
|
||||
|
||||
ContactMechanism()
|
||||
cls.raise_user_error('write_party')
|
||||
super(ContactMechanism, cls).write(mechanisms, vals)
|
||||
@@ -7,6 +7,9 @@ from trytond.pyson import Bool, Eval
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.pool import Pool
|
||||
|
||||
__all__ = ['Party', 'PartyCategory', 'CheckVIESNoResult', 'CheckVIESResult',
|
||||
'CheckVIES']
|
||||
|
||||
HAS_VATNUMBER = False
|
||||
VAT_COUNTRIES = [('', '')]
|
||||
try:
|
||||
@@ -26,8 +29,7 @@ DEPENDS = ['active']
|
||||
|
||||
class Party(ModelSQL, ModelView):
|
||||
"Party"
|
||||
_description = __doc__
|
||||
_name = "party.party"
|
||||
__name__ = 'party.party'
|
||||
|
||||
name = fields.Char('Name', required=True, select=True,
|
||||
states=STATES, depends=DEPENDS)
|
||||
@@ -70,62 +72,64 @@ class Party(ModelSQL, ModelView):
|
||||
email = fields.Function(fields.Char('E-Mail'), 'get_mechanism')
|
||||
website = fields.Function(fields.Char('Website'), 'get_mechanism')
|
||||
|
||||
def __init__(self):
|
||||
super(Party, self).__init__()
|
||||
self._sql_constraints = [
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Party, cls).__setup__()
|
||||
cls._sql_constraints = [
|
||||
('code_uniq', 'UNIQUE(code)',
|
||||
'The code of the party must be unique!')
|
||||
]
|
||||
self._constraints += [
|
||||
cls._constraints += [
|
||||
('check_vat', 'invalid_vat'),
|
||||
]
|
||||
self._error_messages.update({
|
||||
cls._error_messages.update({
|
||||
'invalid_vat': 'Invalid VAT number!',
|
||||
})
|
||||
self._order.insert(0, ('name', 'ASC'))
|
||||
cls._order.insert(0, ('name', 'ASC'))
|
||||
|
||||
def default_active(self):
|
||||
@staticmethod
|
||||
def default_active():
|
||||
return True
|
||||
|
||||
def default_categories(self):
|
||||
@staticmethod
|
||||
def default_categories():
|
||||
return Transaction().context.get('categories', [])
|
||||
|
||||
def default_addresses(self):
|
||||
@staticmethod
|
||||
def default_addresses():
|
||||
if Transaction().user == 0:
|
||||
return []
|
||||
address_obj = Pool().get('party.address')
|
||||
fields_names = list(x for x in set(address_obj._columns.keys()
|
||||
+ address_obj._inherit_fields.keys())
|
||||
Address = Pool().get('party.address')
|
||||
fields_names = list(x for x in set(Address._fields.keys()
|
||||
+ Address._inherit_fields.keys())
|
||||
if x not in ['id', 'create_uid', 'create_date',
|
||||
'write_uid', 'write_date'])
|
||||
return [address_obj.default_get(fields_names)]
|
||||
return [Address.default_get(fields_names)]
|
||||
|
||||
def default_lang(self):
|
||||
config_obj = Pool().get('party.configuration')
|
||||
config = config_obj.browse(1)
|
||||
return config.party_lang.id
|
||||
@staticmethod
|
||||
def default_lang():
|
||||
Configuration = Pool().get('party.configuration')
|
||||
config = Configuration(1)
|
||||
if config.party_lang:
|
||||
return config.party_lang.id
|
||||
|
||||
def default_code_readonly(self):
|
||||
config_obj = Pool().get('party.configuration')
|
||||
config = config_obj.browse(1)
|
||||
@staticmethod
|
||||
def default_code_readonly():
|
||||
Configuration = Pool().get('party.configuration')
|
||||
config = Configuration(1)
|
||||
return bool(config.party_sequence)
|
||||
|
||||
def get_code_readonly(self, ids, name):
|
||||
return dict((x, True) for x in ids)
|
||||
def get_code_readonly(self, name):
|
||||
return True
|
||||
|
||||
def on_change_with_vat_code(self, vals):
|
||||
return (vals.get('vat_country') or '') + (vals.get('vat_number') or '')
|
||||
def on_change_with_vat_code(self):
|
||||
return (self.vat_country or '') + (self.vat_number or '')
|
||||
|
||||
def get_vat_code(self, ids, name):
|
||||
if not ids:
|
||||
return []
|
||||
res = {}
|
||||
for party in self.browse(ids):
|
||||
res[party.id] = ((party.vat_country or '')
|
||||
+ (party.vat_number or ''))
|
||||
return res
|
||||
def get_vat_code(self, name):
|
||||
return (self.vat_country or '') + (self.vat_number or '')
|
||||
|
||||
def search_vat_code(self, name, clause):
|
||||
@classmethod
|
||||
def search_vat_code(cls, name, clause):
|
||||
res = []
|
||||
value = clause[2]
|
||||
for country, _ in VAT_COUNTRIES:
|
||||
@@ -138,150 +142,127 @@ class Party(ModelSQL, ModelView):
|
||||
res.append(('vat_number', clause[1], value))
|
||||
return res
|
||||
|
||||
def get_full_name(self, ids, name):
|
||||
if not ids:
|
||||
return []
|
||||
res = {}
|
||||
for party in self.browse(ids):
|
||||
res[party.id] = party.name
|
||||
return res
|
||||
def get_full_name(self, name):
|
||||
return self.name
|
||||
|
||||
def get_mechanism(self, ids, name):
|
||||
if not ids:
|
||||
return []
|
||||
res = {}
|
||||
for party in self.browse(ids):
|
||||
res[party.id] = ''
|
||||
for mechanism in party.contact_mechanisms:
|
||||
if mechanism.type == name:
|
||||
res[party.id] = mechanism.value
|
||||
break
|
||||
return res
|
||||
def get_mechanism(self, name):
|
||||
for mechanism in self.contact_mechanisms:
|
||||
if mechanism.type == name:
|
||||
return mechanism.value
|
||||
return ''
|
||||
|
||||
def create(self, values):
|
||||
sequence_obj = Pool().get('ir.sequence')
|
||||
config_obj = Pool().get('party.configuration')
|
||||
@classmethod
|
||||
def create(cls, values):
|
||||
Sequence = Pool().get('ir.sequence')
|
||||
Configuration = Pool().get('party.configuration')
|
||||
|
||||
values = values.copy()
|
||||
if not values.get('code'):
|
||||
config = config_obj.browse(1)
|
||||
values['code'] = sequence_obj.get_id(config.party_sequence.id)
|
||||
config = Configuration(1)
|
||||
values['code'] = Sequence.get_id(config.party_sequence.id)
|
||||
|
||||
values['code_length'] = len(values['code'])
|
||||
return super(Party, self).create(values)
|
||||
return super(Party, cls).create(values)
|
||||
|
||||
def write(self, ids, vals):
|
||||
@classmethod
|
||||
def write(cls, parties, vals):
|
||||
if vals.get('code'):
|
||||
vals = vals.copy()
|
||||
vals['code_length'] = len(vals['code'])
|
||||
return super(Party, self).write(ids, vals)
|
||||
super(Party, cls).write(parties, vals)
|
||||
|
||||
def copy(self, ids, default=None):
|
||||
address_obj = Pool().get('party.address')
|
||||
|
||||
int_id = False
|
||||
if isinstance(ids, (int, long)):
|
||||
int_id = True
|
||||
ids = [ids]
|
||||
@classmethod
|
||||
def copy(cls, parties, default=None):
|
||||
Address = Pool().get('party.address')
|
||||
|
||||
if default is None:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['code'] = None
|
||||
default['addresses'] = None
|
||||
new_ids = []
|
||||
for party in self.browse(ids):
|
||||
new_id = super(Party, self).copy(party.id, default=default)
|
||||
address_obj.copy([x.id for x in party.addresses],
|
||||
new_parties = []
|
||||
for party in parties:
|
||||
new_party = super(Party, cls).copy(party, default=default)
|
||||
Address.copy([x.id for x in new_party.addresses],
|
||||
default={
|
||||
'party': new_id,
|
||||
'party': new_party.id,
|
||||
})
|
||||
new_ids.append(new_id)
|
||||
new_parties.append(new_party)
|
||||
|
||||
if int_id:
|
||||
return new_ids[0]
|
||||
return new_ids
|
||||
return new_parties
|
||||
|
||||
def search_rec_name(self, name, clause):
|
||||
ids = self.search([('code',) + tuple(clause[1:])], order=[])
|
||||
if ids:
|
||||
ids += self.search([('name',) + tuple(clause[1:])], order=[])
|
||||
return [('id', 'in', ids)]
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
parties = cls.search([('code',) + tuple(clause[1:])], order=[])
|
||||
if parties:
|
||||
parties += cls.search([('name',) + tuple(clause[1:])], order=[])
|
||||
|
||||
return [('id', 'in', [party.id for party in parties])]
|
||||
return [('name',) + clause[1:]]
|
||||
|
||||
def address_get(self, party_id, type=None):
|
||||
def address_get(self, type=None):
|
||||
"""
|
||||
Try to find an address for the given type, if no type match
|
||||
the first address is return.
|
||||
Try to find an address for the given type, if no type matches
|
||||
the first address is returned.
|
||||
"""
|
||||
address_obj = Pool().get("party.address")
|
||||
address_ids = address_obj.search(
|
||||
[("party", "=", party_id), ("active", "=", True)],
|
||||
Address = Pool().get("party.address")
|
||||
addresses = Address.search(
|
||||
[("party", "=", self.id), ("active", "=", True)],
|
||||
order=[('sequence', 'ASC'), ('id', 'ASC')])
|
||||
if not address_ids:
|
||||
if not addresses:
|
||||
return None
|
||||
default_address = address_ids[0]
|
||||
default_address = addresses[0]
|
||||
if not type:
|
||||
return default_address
|
||||
for address in address_obj.browse(address_ids):
|
||||
if address[type]:
|
||||
return address.id
|
||||
for address in addresses:
|
||||
if getattr(address, type):
|
||||
return address
|
||||
return default_address
|
||||
|
||||
def check_vat(self, ids):
|
||||
def check_vat(self):
|
||||
'''
|
||||
Check the VAT number depending of the country.
|
||||
http://sima-pc.com/nif.php
|
||||
'''
|
||||
if not HAS_VATNUMBER:
|
||||
return True
|
||||
for party in self.browse(ids):
|
||||
vat_number = party.vat_number
|
||||
vat_number = self.vat_number
|
||||
|
||||
if not party.vat_country:
|
||||
continue
|
||||
if not self.vat_country:
|
||||
return True
|
||||
|
||||
if not getattr(vatnumber, 'check_vat_' + \
|
||||
party.vat_country.lower())(vat_number):
|
||||
if not getattr(vatnumber, 'check_vat_' + \
|
||||
self.vat_country.lower())(vat_number):
|
||||
|
||||
#Check if user doesn't have put country code in number
|
||||
if vat_number.startswith(party.vat_country):
|
||||
vat_number = vat_number[len(party.vat_country):]
|
||||
self.write(party.id, {
|
||||
'vat_number': vat_number,
|
||||
})
|
||||
else:
|
||||
return False
|
||||
#Check if user doesn't have put country code in number
|
||||
if vat_number.startswith(self.vat_country):
|
||||
vat_number = vat_number[len(self.vat_country):]
|
||||
Party.write([self], {
|
||||
'vat_number': vat_number,
|
||||
})
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
Party()
|
||||
|
||||
|
||||
class PartyCategory(ModelSQL):
|
||||
'Party - Category'
|
||||
_name = 'party.party-party.category'
|
||||
__name__ = 'party.party-party.category'
|
||||
_table = 'party_category_rel'
|
||||
_description = __doc__
|
||||
party = fields.Many2One('party.party', 'Party', ondelete='CASCADE',
|
||||
required=True, select=True)
|
||||
category = fields.Many2One('party.category', 'Category',
|
||||
ondelete='CASCADE', required=True, select=True)
|
||||
|
||||
PartyCategory()
|
||||
|
||||
|
||||
class CheckVIESNoResult(ModelView):
|
||||
'Check VIES'
|
||||
_name = 'party.check_vies.no_result'
|
||||
_description = __doc__
|
||||
|
||||
CheckVIESNoResult()
|
||||
__name__ = 'party.check_vies.no_result'
|
||||
|
||||
|
||||
class CheckVIESResult(ModelView):
|
||||
'Check VIES'
|
||||
_name = 'party.check_vies.result'
|
||||
_description = __doc__
|
||||
__name__ = 'party.check_vies.result'
|
||||
parties_succeed = fields.Many2Many('party.party', None, None,
|
||||
'Parties Succeed', readonly=True, states={
|
||||
'invisible': ~Eval('parties_succeed'),
|
||||
@@ -291,12 +272,10 @@ class CheckVIESResult(ModelView):
|
||||
'invisible': ~Eval('parties_failed'),
|
||||
})
|
||||
|
||||
CheckVIESResult()
|
||||
|
||||
|
||||
class CheckVIES(Wizard):
|
||||
'Check VIES'
|
||||
_name = 'party.check_vies'
|
||||
__name__ = 'party.check_vies'
|
||||
start_state = 'check'
|
||||
|
||||
check = StateTransition()
|
||||
@@ -309,22 +288,23 @@ class CheckVIES(Wizard):
|
||||
Button('Ok', 'end', 'tryton-ok', True),
|
||||
])
|
||||
|
||||
def __init__(self):
|
||||
super(CheckVIES, self).__init__()
|
||||
self._error_messages.update({
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(CheckVIES, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'vies_unavailable': 'The VIES service is unavailable, ' \
|
||||
'try again later.',
|
||||
})
|
||||
|
||||
def transition_check(self, session):
|
||||
party_obj = Pool().get('party.party')
|
||||
def transition_check(self):
|
||||
Party = Pool().get('party.party')
|
||||
|
||||
if not HAS_VATNUMBER or not hasattr(vatnumber, 'check_vies'):
|
||||
return 'no_result'
|
||||
|
||||
parties_succeed = []
|
||||
parties_failed = []
|
||||
parties = party_obj.browse(Transaction().context.get('active_ids'))
|
||||
parties = Party.browse(Transaction().context.get('active_ids'))
|
||||
for party in parties:
|
||||
if not party.vat_code:
|
||||
continue
|
||||
@@ -345,14 +325,12 @@ class CheckVIES(Wizard):
|
||||
or e.faultstring.find('SERVER_BUSY'):
|
||||
self.raise_user_error('vies_unavailable')
|
||||
raise
|
||||
session.result.parties_succeed = parties_succeed
|
||||
session.result.parties_failed = parties_failed
|
||||
self.result.parties_succeed = parties_succeed
|
||||
self.result.parties_failed = parties_failed
|
||||
return 'result'
|
||||
|
||||
def default_result(self, session, fields):
|
||||
def default_result(self, fields):
|
||||
return {
|
||||
'parties_succeed': [p.id for p in session.result.parties_succeed],
|
||||
'parties_failed': [p.id for p in session.result.parties_failed],
|
||||
'parties_succeed': [p.id for p in self.result.parties_succeed],
|
||||
'parties_failed': [p.id for p in self.result.parties_failed],
|
||||
}
|
||||
|
||||
CheckVIES()
|
||||
+24
-24
@@ -44,10 +44,10 @@ class PartyTestCase(unittest.TestCase):
|
||||
'''
|
||||
with Transaction().start(DB_NAME, USER,
|
||||
context=CONTEXT) as transaction:
|
||||
category1_id = self.category.create({
|
||||
category1 = self.category.create({
|
||||
'name': 'Category 1',
|
||||
})
|
||||
self.assert_(category1_id)
|
||||
self.assert_(category1.id)
|
||||
transaction.cursor.commit()
|
||||
|
||||
def test0020category_recursion(self):
|
||||
@@ -55,20 +55,20 @@ class PartyTestCase(unittest.TestCase):
|
||||
Test category recursion.
|
||||
'''
|
||||
with Transaction().start(DB_NAME, USER, context=CONTEXT):
|
||||
category1_id = self.category.search([
|
||||
category1, = self.category.search([
|
||||
('name', '=', 'Category 1'),
|
||||
], limit=1)[0]
|
||||
], limit=1)
|
||||
|
||||
category2_id = self.category.create({
|
||||
category2 = self.category.create({
|
||||
'name': 'Category 2',
|
||||
'parent': category1_id,
|
||||
'parent': category1.id,
|
||||
})
|
||||
self.assert_(category2_id)
|
||||
self.assert_(category2.id)
|
||||
|
||||
self.failUnlessRaises(Exception, self.category.write,
|
||||
category1_id, {
|
||||
'parent': category2_id,
|
||||
})
|
||||
self.assertRaises(Exception, self.category.write,
|
||||
[category1], {
|
||||
'parent': category2.id,
|
||||
})
|
||||
|
||||
def test0030party(self):
|
||||
'''
|
||||
@@ -76,10 +76,10 @@ class PartyTestCase(unittest.TestCase):
|
||||
'''
|
||||
with Transaction().start(DB_NAME, USER,
|
||||
context=CONTEXT) as transaction:
|
||||
party1_id = self.party.create({
|
||||
party1 = self.party.create({
|
||||
'name': 'Party 1',
|
||||
})
|
||||
self.assert_(party1_id)
|
||||
self.assert_(party1.id)
|
||||
transaction.cursor.commit()
|
||||
|
||||
def test0040party_code(self):
|
||||
@@ -87,32 +87,32 @@ class PartyTestCase(unittest.TestCase):
|
||||
Test party code constraint.
|
||||
'''
|
||||
with Transaction().start(DB_NAME, USER, context=CONTEXT):
|
||||
party1_id = self.party.search([], limit=1)[0]
|
||||
party1, = self.party.search([], limit=1)
|
||||
|
||||
code = self.party.read(party1_id, ['code'])['code']
|
||||
code = party1.code
|
||||
|
||||
party2_id = self.party.create({
|
||||
party2 = self.party.create({
|
||||
'name': 'Party 2',
|
||||
})
|
||||
|
||||
self.failUnlessRaises(Exception, self.party.write,
|
||||
party2_id, {
|
||||
'code': code,
|
||||
})
|
||||
self.assertRaises(Exception, self.party.write,
|
||||
[party2], {
|
||||
'code': code,
|
||||
})
|
||||
|
||||
def test0050address(self):
|
||||
'''
|
||||
Create address.
|
||||
'''
|
||||
with Transaction().start(DB_NAME, USER, context=CONTEXT):
|
||||
party1_id = self.party.search([], limit=1)[0]
|
||||
party1, = self.party.search([], limit=1)
|
||||
|
||||
self.address.create({
|
||||
'party': party1_id,
|
||||
address = self.address.create({
|
||||
'party': party1.id,
|
||||
'street': 'St sample, 15',
|
||||
'city': 'City',
|
||||
})
|
||||
self.assert_(party1_id)
|
||||
self.assert_(address.id)
|
||||
|
||||
|
||||
def suite():
|
||||
|
||||
Reference in new issue
Block a user