diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py
index 74ecc9a6f04..ec45981081b 100644
--- a/bin/addons/__init__.py
+++ b/bin/addons/__init__.py
@@ -327,6 +327,9 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
if force_demo:
force.append('demo')
if update_module:
+ for module in tools.config['init']:
+ cr.execute('update ir_module_module set state=%s where state=%s and name=%s', ('to install', 'uninstalled', module))
+ cr.commit()
cr.execute("select name from ir_module_module where state in ('installed', 'to install', 'to upgrade','to remove')")
else:
cr.execute("select name from ir_module_module where state in ('installed', 'to upgrade', 'to remove')")
diff --git a/bin/addons/base/base_data.xml b/bin/addons/base/base_data.xml
index 88464eb97c4..a087ad4d620 100644
--- a/bin/addons/base/base_data.xml
+++ b/bin/addons/base/base_data.xml
@@ -1369,6 +1369,7 @@
COP
0.01
4
+
@@ -1376,6 +1377,7 @@
CZK
0.01
4
+
@@ -1396,6 +1398,7 @@
HUF
0.01
4
+
@@ -1403,6 +1406,7 @@
IDR
0.01
4
+
@@ -1449,6 +1453,7 @@
PLN
0.01
4
+
@@ -1456,6 +1461,7 @@
SEK
0.01
4
+
@@ -1475,6 +1481,7 @@
ARS
0.01
4
+
diff --git a/bin/addons/base/ir/ir.xml b/bin/addons/base/ir/ir.xml
old mode 100644
new mode 100755
index d68c126bf60..83372789a86
--- a/bin/addons/base/ir/ir.xml
+++ b/bin/addons/base/ir/ir.xml
@@ -1039,23 +1039,34 @@
form
@@ -1080,8 +1091,22 @@
ir.actions.server
form
+ {'key':'myval'}
-
+
+
+ ir.model.fields.tree
+ ir.model.fields
+ tree
+
+
+
+
+
+
+
+
+
diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py
index 159707cdd1d..9ed4565169a 100755
--- a/bin/addons/base/ir/ir_actions.py
+++ b/bin/addons/base/ir/ir_actions.py
@@ -255,10 +255,6 @@ class act_url(osv.osv):
}
act_url()
-def _get_fields(self, cr, uid, context={}):
-
- return [('key','Email Value')]
-
def model_get(self, cr, uid, context={}):
wkf_pool = self.pool.get('workflow')
ids = wkf_pool.search(cr, uid, [])
@@ -273,8 +269,60 @@ def model_get(self, cr, uid, context={}):
res.append((model, name))
return res
-
+
+#class ir_model_fields(osv.osv):
+# _inherit = 'ir.model.fields'
+# _rec_name = 'complete_name'
+# _columns = {
+# 'complete_name': fields.char('Complete Name', required=True, size=64, select=1),
+# }
#
+# def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=80):
+# def get_fields(cr, uid, field, rel):
+# result = []
+# mobj = self.pool.get('ir.model')
+# id = mobj.search(cr, uid, [('model','=',rel)])
+#
+# obj = self.pool.get('ir.model.fields')
+# ids = obj.search(cr, uid, [('model_id','in',id)])
+# records = obj.read(cr, uid, ids)
+# for record in records:
+# id = record['id']
+# fld = field + '/' + record['name']
+#
+# result.append((id, fld))
+# return result
+#
+# if not args:
+# args=[]
+# if not context:
+# context={}
+# return super(ir_model_fields, self).name_search(cr, uid, name, args, operator, context, limit)
+#
+# result = []
+# obj = self.pool.get('ir.model.fields')
+# ids = obj.search(cr, uid, args)
+# records = obj.read(cr, uid, ids)
+# for record in records:
+# id = record['id']
+# field = record['name']
+#
+# if record['ttype'] == 'many2one':
+# rel = record['relation']
+# res = get_fields(cr, uid, field, record['relation'])
+# for rs in res:
+# result.append(rs)
+#
+# result.append((id, field))
+#
+# for rs in result:
+# obj.write(cr, uid, [rs[0]], {'complete_name':rs[1]})
+#
+# #result = super(ir_model_fields, self).name_search(cr, uid, name, [['complete_name','ilike',name]], operator, context, limit)
+# return result
+#
+#ir_model_fields()
+##
# Actions that are run on the server side
#
class actions_server(osv.osv):
@@ -302,7 +350,8 @@ class actions_server(osv.osv):
#'trigger_object': fields.char('Trigger Object', size=128),
#'trigger_object_id': fields.char('Trigger Object ID', size=128),
'message': fields.text('Message', translate=True),
- 'address': fields.selection(_get_fields ,'Email / SMS', size=128),
+ 'address': fields.many2one('ir.model.fields', 'Email From / SMS'),
+ #selection(_get_fields ,'Email / SMS', size=128),
'child_ids': fields.one2many('ir.actions.actions', 'parent_id', 'Others Actions'),
'usage': fields.char('Action Usage', size=32),
'type': fields.char('Report Type', size=32, required=True),
@@ -322,6 +371,11 @@ class actions_server(osv.osv):
"""
}
+# def on_change_model(self, cr, uid, ids, model_id):
+# print '**************** : method called'
+# res = {'value' : {'address': [('key1','Email Value One')]} }
+# return res
+
#
# Context should contains:
# ids : original ids
@@ -344,9 +398,14 @@ class actions_server(osv.osv):
exec action.code in localdict
if 'action' in localdict:
return localdict['action']
+
if action.state == 'email':
user = config['email_from']
subject = action.name
+
+ #TODO : Apply Mail merge in to the Content of the Email
+ print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ',context
+
body = action.message
if tools.email_send_attach(user, action.address, subject, body, debug=False) == True:
logger.notifyChannel('email', netsvc.LOG_INFO, 'Email successfully send to : %s' % (action.address))
@@ -361,10 +420,12 @@ class actions_server(osv.osv):
wf_service.trg_validate(uid, model, int(id), action.trigger_name, cr)
if action.state == 'sms':
+ #TODO: Apply mearge with the field
if tools.sms_send(user, password, api_id, text, to) == True:
logger.notifyChannel('sms', netsvc.LOG_INFO, 'SMS successfully send to : %s' % (action.address))
else:
logger.notifyChannel('sms', netsvc.LOG_ERROR, 'Failed to send SMS to : %s' % (action.address))
+
if action.state == 'other':
localdict = {
'self': self.pool.get(action.model_id.model),
@@ -376,15 +437,10 @@ class actions_server(osv.osv):
}
for act in action.child_ids:
- code = """
- action = {
- 'res_model': %s,
- 'type': %s,
- 'name': %s,
- 'usage': %s,
- }
- """ % (action.model_id.model, act.type, act.name, act.usage)
- exec action.code in localdict
+ code = """action = {'model':'%s','type':'%s', %s}""" % (action.model_id.model, act.type, act.usage)
+ exec code in localdict
+ if 'action' in localdict:
+ return localdict['action']
return False
actions_server()
diff --git a/bin/addons/base/ir/ir_model.py b/bin/addons/base/ir/ir_model.py
index 499a9a4354b..e811c25ef7d 100644
--- a/bin/addons/base/ir/ir_model.py
+++ b/bin/addons/base/ir/ir_model.py
@@ -122,6 +122,7 @@ class ir_model_fields(osv.osv):
'groups': fields.many2many('res.groups', 'ir_model_fields_group_rel', 'field_id', 'group_id', 'Groups'),
'group_name': fields.char('Group Name', size=128),
'view_load': fields.boolean('View Auto-Load'),
+ 'complete_name': fields.char('Complete Name', required=True, size=64, select=1),
}
_defaults = {
'relate': lambda *a: 0,
diff --git a/bin/addons/base/module/wizard/wizard_module_upgrade.py b/bin/addons/base/module/wizard/wizard_module_upgrade.py
index c9cf6042108..55432bd44f9 100644
--- a/bin/addons/base/module/wizard/wizard_module_upgrade.py
+++ b/bin/addons/base/module/wizard/wizard_module_upgrade.py
@@ -89,6 +89,15 @@ class wizard_info_get(wizard.interface):
mod_obj = pool.get('ir.module.module')
ids = mod_obj.search(cr, uid, [
('state', 'in', ['to upgrade', 'to remove', 'to install'])])
+ unmet_packages=[]
+ mod_dep_obj = pool.get('ir.module.module.dependency')
+ for mod in mod_obj.browse(cr,uid,ids):
+ depends_mod_ids=mod_dep_obj.search(cr,uid,[('module_id','=',mod.id)])
+ for dep_mod in mod_dep_obj.browse(cr,uid,depends_mod_ids):
+ if dep_mod.state in ('unknown','uninstalled'):
+ unmet_packages.append(dep_mod.name)
+ if len(unmet_packages):
+ raise wizard.except_wizard('Unmet dependency !','Following modules are uninstalled or unknown. \n\n'+'\n'.join(unmet_packages))
mod_obj.download(cr, uid, ids, context=context)
cr.commit()
db, pool = pooler.restart_pool(cr.dbname, update_module=True)
diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py
index 3cac309de11..0d3ff0bf3d9 100644
--- a/bin/addons/base/res/partner/partner.py
+++ b/bin/addons/base/res/partner/partner.py
@@ -142,6 +142,7 @@ class res_partner(osv.osv):
'user_id': fields.many2one('res.users', 'Dedicated Salesman', help='The internal user that is in charge of communicating with this partner if any.'),
'responsible': fields.many2one('res.users', 'Users'),
'vat': fields.char('VAT',size=32 ,help="Value Added Tax number"),
+ 'vat_subject': fields.boolean('Subjected to the VAT'),
'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
'website': fields.char('Website',size=64),
'comment': fields.text('Notes'),
diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng
index 0f4b87f021e..666ab76194b 100644
--- a/bin/addons/base/rng/view.rng
+++ b/bin/addons/base/rng/view.rng
@@ -6,6 +6,7 @@
+
@@ -16,6 +17,7 @@
+
@@ -30,10 +32,13 @@
+
+
+
@@ -186,6 +191,7 @@
+
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 5c312503c4f..198a3a17407 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -593,28 +593,28 @@ class orm_template(object):
while len(datas):
res = {}
- try:
- (res, other, warning, translate, data_id) = \
- process_liness(self, datas, [], fields_def)
- if warning:
- cr.rollback()
- return (-1, res, warning, '')
- id = self.pool.get('ir.model.data')._update(cr, uid, self._name,
- current_module, res, xml_id=data_id, mode=mode,
- noupdate=noupdate)
- for lang in translate:
- context2 = context.copy()
- context2['lang'] = lang
- self.write(cr, uid, [id], translate[lang], context2)
- if config.get('commit_mode', False):
- cr.commit()
- except Exception, e:
- logger.notifyChannel("import", netsvc.LOG_ERROR, e)
+ #try:
+ (res, other, warning, translate, data_id) = \
+ process_liness(self, datas, [], fields_def)
+ if warning:
cr.rollback()
- try:
- return (-1, res, e[0], warning)
- except:
- return (-1, res, e[0], '')
+ return (-1, res, warning, '')
+ id = self.pool.get('ir.model.data')._update(cr, uid, self._name,
+ current_module, res, xml_id=data_id, mode=mode,
+ noupdate=noupdate)
+ for lang in translate:
+ context2 = context.copy()
+ context2['lang'] = lang
+ self.write(cr, uid, [id], translate[lang], context2)
+ if config.get('import_partial', False):
+ cr.commit()
+ #except Exception, e:
+ # logger.notifyChannel("import", netsvc.LOG_ERROR, e)
+ # cr.rollback()
+ # try:
+ # return (-1, res, e[0], warning)
+ # except:
+ # return (-1, res, e[0], '')
done += 1
#
# TODO: Send a request with the result and multi-thread !
diff --git a/bin/osv/osv.py b/bin/osv/osv.py
index 8e2944eed76..611ba504955 100644
--- a/bin/osv/osv.py
+++ b/bin/osv/osv.py
@@ -236,7 +236,10 @@ class osv(orm.orm):
parent_name = hasattr(cls, '_inherit') and cls._inherit
if parent_name:
parent_class = pool.get(parent_name).__class__
- assert parent_class, "parent class %s does not exist !" % parent_name
+
+ print cls
+ print cls._name
+ assert pool.get(parent_name), "parent class %s does not exist in module %s !" % (parent_name, module)
nattr = {}
for s in ('_columns', '_defaults', '_inherits', '_constraints', '_sql_constraints'):
new = copy.copy(getattr(pool.get(parent_name), s))
diff --git a/bin/tools/config.py b/bin/tools/config.py
index 49993b2a534..2083e6fff70 100644
--- a/bin/tools/config.py
+++ b/bin/tools/config.py
@@ -58,7 +58,7 @@ class configmanager(object):
'addons_path': None,
'root_path': None,
'debug_mode': False,
- 'commit_mode': False,
+ 'import_partial': "",
'pidfile': None,
'logfile': None,
'secure': False,
@@ -114,7 +114,7 @@ class configmanager(object):
group.add_option("--db_host", dest="db_host", help="specify the database host")
group.add_option("--db_port", dest="db_port", help="specify the database port")
group.add_option("--db_maxconn", dest="db_maxconn", default='64', help="specify the the maximum number of physical connections to posgresql")
- group.add_option("-C", "--commit-mode", dest="commit_mode", action="store_true", help="Several commit during one file importation. Use this for big data importation.", default=False)
+ group.add_option("-C", "--commit-mode", dest="import_partial", help="Several commit during one file importation. Use this for big data importation. Provide a filename to store intermediate state.", default=False)
parser.add_option_group(group)
group = optparse.OptionGroup(parser, "Internationalisation options",
@@ -156,7 +156,7 @@ class configmanager(object):
self.options['pidfile'] = False
for arg in ('interface', 'port', 'db_name', 'db_user', 'db_password', 'db_host',
- 'db_port', 'logfile', 'pidfile', 'secure', 'smtp_ssl', 'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy', 'netinterface', 'netport', 'db_maxconn', 'commit_mode', 'addons_path'):
+ 'db_port', 'logfile', 'pidfile', 'secure', 'smtp_ssl', 'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy', 'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path'):
if getattr(opt, arg):
self.options[arg] = getattr(opt, arg)
diff --git a/bin/tools/convert.py b/bin/tools/convert.py
index bca44cb349f..626052c060d 100644
--- a/bin/tools/convert.py
+++ b/bin/tools/convert.py
@@ -657,7 +657,7 @@ form: module.record_id""" % (xml_id,)
id = self.pool.get('ir.model.data')._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode )
if rec_id:
self.idref[rec_id] = int(id)
- if config.get('commit_mode', False):
+ if config.get('import_partial', False):
cr.commit()
return rec_model, id
@@ -724,6 +724,15 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
pool = pooler.get_pool(cr.dbname)
+ import pickle
+ if config.get('import_partial'):
+ if not os.path.isfile(config.get('import_partial')):
+ pickle.dump({}, file(config.get('import_partial'),'w+'))
+ data = pickle.load(file(config.get('import_partial')))
+ if fname in data:
+ if not data[fname]:
+ return
+
input = StringIO.StringIO(csvcontent)
reader = csv.reader(input, quotechar='"', delimiter=',')
fields = reader.next()
@@ -738,6 +747,10 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
continue
datas.append( map(lambda x:x.decode('utf8').encode('utf8'), line))
pool.get(model).import_data(cr, uid, fields, datas,mode, module,noupdate)
+ if config.get('import_partial'):
+ data = pickle.load(file(config.get('import_partial')))
+ data[fname] = 0
+ pickle.dump(data, file(config.get('import_partial'),'wb'))
#
# xml import/export