bzr revid: christophe@tinyerp.com-20080819131400-s14sq8un0rzlucg0
This commit is contained in:
Christophe Simonis 2008-08-19 15:14:00 +02:00
commit 64f20c2234
12 changed files with 180 additions and 56 deletions

View File

@ -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')")

View File

@ -1369,6 +1369,7 @@
<field name="code">COP</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>
<record id="CZK" model="res.currency">
@ -1376,6 +1377,7 @@
<field name="code">CZK</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>
<record id="DKK" model="res.currency">
@ -1396,6 +1398,7 @@
<field name="code">HUF</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>
<record id="IDR" model="res.currency">
@ -1403,6 +1406,7 @@
<field name="code">IDR</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>
<record id="LVL" model="res.currency">
@ -1449,6 +1453,7 @@
<field name="code">PLN</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>
<record id="SEK" model="res.currency">
@ -1456,6 +1461,7 @@
<field name="code">SEK</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>
<record id="GBP" model="res.currency">
@ -1475,6 +1481,7 @@
<field name="code">ARS</field>
<field name="rounding">0.01</field>
<field name="accuracy">4</field>
<field eval="False" name="active"/>
</record>

55
bin/addons/base/ir/ir.xml Normal file → Executable file
View File

@ -1039,23 +1039,34 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Server Action">
<field name="name" select="1"/>
<field name="name" select="1"/>
<field name="state" select="1"/>
<field name="model_id" select="1"/>
<field name="sequence" select="2"/>
<separator colspan="4" string="Python code"/>
<field name="code" colspan="4" attrs="{'readonly':[('state','!=','python')]}"/>
<separator colspan="4" string="Trigger Configuration"/>
<field name="trigger_obj_id" select="2" colspan="4" attrs="{'readonly':[('state','!=','trigger')]}"/>
<field name="trigger_name" select="2" attrs="{'readonly':[('state','!=','trigger')]}"/>
<!-- <field name="trigger_object_id" attrs="{'readonly':[('state','!=','trigger')]}"/>-->
<separator colspan="4" string="Email Configuration"/>
<field name="address" select="2" attrs="{'readonly':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','object_create'), ('state','=','object_write'), ('state','=','client_action'), ('state','=','other')]}"/>
<field name="message" select="2" colspan="4" attrs="{'readonly':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','object_create'), ('state','=','object_write'), ('state','=','client_action'), ('state','=','other')]}"/>
<separator colspan="4" string="Other Actions Configuration"/>
<field name="child_ids" colspan="4" attrs="{'readonly':[('state','!=','other')]}"/>
<notebook colspan="4">
<page string="Python Code" attrs="{'invisible':[('state','!=','python')]}">
<separator colspan="4" string="Python code"/>
<field name="code" colspan="4" nolabel="1" />
</page>
<page string="Trigger" attrs="{'invisible':[('state','!=','trigger')]}">
<separator colspan="4" string="Trigger Configuration"/>
<field name="trigger_obj_id" select="2" colspan="4"/>
<field name="trigger_name" select="2"/>
</page>
<page string="Email" attrs="{'invisible':[('state','=','python'),('state','=','dummy'),('state','=','trigger'), ('state','=','object_create'), ('state','=','object_write'), ('state','=','client_action'), ('state','=','other')]}">
<separator colspan="4" string="Email Configuration"/>
<field name="address" domain="[('model_id','=',model_id)]"/>
<field name="message" select="2" colspan="4"/>
</page>
<page string="Other Actions" attrs="{'invisible':[('state','!=','other')]}">
<separator colspan="4" string="Other Actions Configuration"/>
<field name="child_ids" nolabel="1" colspan="4" />
</page>
</notebook>
<field name="usage"/>
<field name="type"/>
</form>
@ -1080,8 +1091,22 @@
<field name="res_model">ir.actions.server</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_server_action_tree"/>
<field name="context">{'key':'myval'}</field>
</record>
<menuitem action="action_server_action" id="menu_server_action" parent="base.next_id_6"/>
<record id="view_model_fields_tree" model="ir.ui.view">
<field name="name">ir.model.fields.tree</field>
<field name="model">ir.model.fields</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Fields">
<field name="complete_name"/>
<field name="model_id"/>
<field name="name"/>
<field name="field_description"/>
</tree>
</field>
</record>
</data>
</terp>

View File

@ -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()

View File

@ -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,

View File

@ -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)

View File

@ -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'),

View File

@ -6,6 +6,7 @@
<rng:optional><rng:attribute name="col"/></rng:optional>
<rng:optional><rng:attribute name="editable"/></rng:optional>
<rng:optional><rng:attribute name="type"/></rng:optional>
<rng:optional><rng:attribute name="position"/></rng:optional>
<rng:zeroOrMore>
<rng:choice>
<rng:ref name="notebook"/>
@ -16,6 +17,7 @@
<rng:ref name="label" />
<rng:ref name="separator"/>
<rng:ref name="image"/>
<rng:ref name="form"/>
<rng:element name="newline"><rng:empty/></rng:element>
<rng:element name="properties"><rng:empty/></rng:element>
</rng:choice>
@ -30,10 +32,13 @@
<rng:optional><rng:attribute name="color"/></rng:optional>
<rng:optional><rng:attribute name="editable"/></rng:optional>
<rng:optional><rng:attribute name="toolbar"/></rng:optional>
<rng:optional><rng:attribute name="position"/></rng:optional>
<rng:zeroOrMore>
<rng:choice>
<rng:ref name="field"/>
<rng:ref name="separator"/>
<rng:ref name="tree"/>
<rng:ref name="group"/>
<rng:element name="newline"><rng:empty/></rng:element>
</rng:choice>
</rng:zeroOrMore>
@ -186,6 +191,7 @@
<rng:ref name="separator"/>
<rng:ref name="xpath"/>
<rng:ref name="button"/>
<rng:ref name="group"/>
<rng:element name="newline"><rng:empty/></rng:element>
</rng:choice>
</rng:zeroOrMore>

View File

@ -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 !

View File

@ -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))

View File

@ -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)

View File

@ -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