diff --git a/.hgignore b/.hgignore
index 05eeec70d0..2e6331fd7e 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,4 +1,6 @@
syntax: glob
.hgignore
*.pyc
-*~
\ No newline at end of file
+*~
+addons/*
+trytond.conf
diff --git a/trytond/config.py b/trytond/config.py
index eff831c265..e468671caf 100644
--- a/trytond/config.py
+++ b/trytond/config.py
@@ -50,7 +50,7 @@ class ConfigManager(object):
parser.add_option("-c", "--config", dest="config",
help="specify alternate config file")
parser.add_option("-s", "--save", action="store_true", dest="save",
- default=False, help="save configuration to ~/.terp_serverrc")
+ default=False, help="save configuration to ~/.trytondrc")
parser.add_option("-v", "--verbose", action="store_true",
dest="verbose", default=False, help="enable debugging")
parser.add_option("--pidfile", dest="pidfile",
@@ -125,12 +125,12 @@ class ConfigManager(object):
# or even to start the server...
if os.name == 'nt':
rcfilepath = os.path.join(os.path.abspath(
- os.path.dirname(sys.argv[0])), 'tinyerp-server.conf')
+ os.path.dirname(sys.argv[0])), 'tryton-server.conf')
else:
- rcfilepath = os.path.expanduser('~/.terp_serverrc')
+ rcfilepath = os.path.expanduser('~/.trytondrc')
self.rcfile = fname or opt.config \
- or os.environ.get('TERP_SERVER') or rcfilepath
+ or os.environ.get('TRYTOND') or rcfilepath
self.load()
# Verify that we want to log or not, if not the output will go to stdout
diff --git a/trytond/init.sql b/trytond/init.sql
index e6b3fb4866..fa62e6df2d 100644
--- a/trytond/init.sql
+++ b/trytond/init.sql
@@ -41,7 +41,7 @@ CREATE TABLE ir_model (
CREATE TABLE ir_model_fields (
id serial,
model varchar(64) DEFAULT ''::varchar NOT NULL,
- model_id int references ir_model,
+ model_id int references ir_model on delete cascade,
name varchar(64) DEFAULT ''::varchar NOT NULL,
relation varchar(64),
field_description varchar(256),
@@ -172,7 +172,7 @@ create table wkf_transition
create table wkf_instance
(
id serial,
- wkf_id int references wkf on delete set null,
+ wkf_id int references wkf on delete restrict,
uid int default null,
res_id int not null,
res_type varchar(64) not null,
diff --git a/trytond/ir/__terp__.py b/trytond/ir/__tryton__.py
similarity index 100%
rename from trytond/ir/__terp__.py
rename to trytond/ir/__tryton__.py
diff --git a/trytond/ir/actions.xml b/trytond/ir/actions.xml
index 62ff273969..54df963dcf 100644
--- a/trytond/ir/actions.xml
+++ b/trytond/ir/actions.xml
@@ -1,5 +1,5 @@
-
+
@@ -245,4 +245,4 @@
-
+
diff --git a/trytond/ir/attachment.xml b/trytond/ir/attachment.xml
index 05e7482258..97bb07810e 100644
--- a/trytond/ir/attachment.xml
+++ b/trytond/ir/attachment.xml
@@ -1,5 +1,5 @@
-
+
ir.attachment
@@ -53,4 +53,4 @@
-
+
diff --git a/trytond/ir/cron.xml b/trytond/ir/cron.xml
index d5eec554fe..eeb437a02f 100644
--- a/trytond/ir/cron.xml
+++ b/trytond/ir/cron.xml
@@ -1,5 +1,5 @@
-
+
ir.cron
@@ -63,4 +63,4 @@
-
+
diff --git a/trytond/ir/exports.xml b/trytond/ir/exports.xml
index c5cbf1108e..6815936e65 100644
--- a/trytond/ir/exports.xml
+++ b/trytond/ir/exports.xml
@@ -1,5 +1,5 @@
-
+
ir.exports
@@ -47,4 +47,4 @@
-
+
diff --git a/trytond/ir/ir.xml b/trytond/ir/ir.xml
index 057da56bf9..8fce1df812 100644
--- a/trytond/ir/ir.xml
+++ b/trytond/ir/ir.xml
@@ -1,7 +1,7 @@
-
+
-
+
diff --git a/trytond/ir/model.py b/trytond/ir/model.py
index 3b2b7dce13..d00a922f33 100644
--- a/trytond/ir/model.py
+++ b/trytond/ir/model.py
@@ -32,7 +32,7 @@ class ModelFields(OSV):
'model': fields.char('Model Name', size=64, required=True),
'relation': fields.char('Model Relation', size=64),
'model_id': fields.many2one('ir.model', 'Model id', required=True,
- select=True),
+ select=True, ondelete='cascade'),
'field_description': fields.char('Field Description', size=256),
'ttype': fields.char('Field Type', size=64),
'relate': fields.boolean('Click and Relate'),
diff --git a/trytond/ir/model.xml b/trytond/ir/model.xml
index c678beea70..755d869100 100644
--- a/trytond/ir/model.xml
+++ b/trytond/ir/model.xml
@@ -1,5 +1,5 @@
-
+
ir.model
@@ -153,4 +153,4 @@
action="act_model_access_form" id="menu_model_access_form"/>
-
+
diff --git a/trytond/ir/module/category.xml b/trytond/ir/module/category.xml
index 4c09f7f3c5..6629353189 100644
--- a/trytond/ir/module/category.xml
+++ b/trytond/ir/module/category.xml
@@ -1,5 +1,5 @@
-
+
ir.module.category
@@ -41,4 +41,4 @@
-
+
diff --git a/trytond/ir/module/module.py b/trytond/ir/module/module.py
index e4376fbb8f..2493ce998b 100644
--- a/trytond/ir/module/module.py
+++ b/trytond/ir/module/module.py
@@ -128,10 +128,10 @@ class Module(OSV):
@staticmethod
def get_module_info(name):
- "Return the content of the __terp__.py"
+ "Return the content of the __tryton__.py"
try:
file_p = tools.file_open(os.path.join(ADDONS_PATH, name,
- '__terp__.py'))
+ '__tryton__.py'))
data = file_p.read()
info = eval(data)
file_p.close()
@@ -320,36 +320,36 @@ class Module(OSV):
if ids:
module_id = ids[0]
mod = self.browse(cursor, user, module_id)
- terp = Module.get_module_info(mod_name)
- if terp.get('installable', True) \
+ tryton = Module.get_module_info(mod_name)
+ if tryton.get('installable', True) \
and mod.state == 'uninstallable':
self.write(cursor, user, module_id, {
'state': 'uninstalled'}, context=context)
- if vercmp(terp.get('version', ''),
+ if vercmp(tryton.get('version', ''),
mod.latest_version or '0') > 0:
self.write(cursor, user, module_id, {
- 'latest_version': terp.get('version'),
+ 'latest_version': tryton.get('version'),
'url': '',
}, context=context)
res[0] += 1
self.write(cursor, user, module_id, {
- 'description': terp.get('description', ''),
- 'shortdesc': terp.get('name', ''),
- 'author': terp.get('author', ''),
- 'website': terp.get('website', ''),
- 'license': terp.get('license', 'GPL-2'),
+ 'description': tryton.get('description', ''),
+ 'shortdesc': tryton.get('name', ''),
+ 'author': tryton.get('author', ''),
+ 'website': tryton.get('website', ''),
+ 'license': tryton.get('license', 'GPL-2'),
})
self._update_dependencies(cursor, user, module_id,
- terp.get('depends', []))
+ tryton.get('depends', []))
self._update_category(cursor, user, module_id,
- terp.get('category', 'None'))
+ tryton.get('category', 'None'))
continue
mod_path = os.path.join(ADDONS_PATH, name)
if os.path.isdir(mod_path) \
or os.path.islink(mod_path) \
or zipfile.is_zipfile(mod_path):
- terp = Module.get_module_info(mod_name)
- if not terp or not terp.get('installable', True):
+ tryton = Module.get_module_info(mod_name)
+ if not tryton or not tryton.get('installable', True):
continue
if not os.path.isfile(
os.path.join(ADDONS_PATH, mod_name+'.zip')):
@@ -364,18 +364,18 @@ class Module(OSV):
new_id = self.create(cursor, user, {
'name': mod_name,
'state': 'uninstalled',
- 'description': terp.get('description', ''),
- 'shortdesc': terp.get('name', ''),
- 'author': terp.get('author', 'Unknown'),
- 'website': terp.get('website', ''),
- 'latest_version': terp.get('version', ''),
- 'license': terp.get('license', 'GPL-2'),
+ 'description': tryton.get('description', ''),
+ 'shortdesc': tryton.get('name', ''),
+ 'author': tryton.get('author', 'Unknown'),
+ 'website': tryton.get('website', ''),
+ 'latest_version': tryton.get('version', ''),
+ 'license': tryton.get('license', 'GPL-2'),
})
res[1] += 1
self._update_dependencies(cursor, user, new_id,
- terp.get('depends', []))
+ tryton.get('depends', []))
self._update_category(cursor, user, new_id,
- terp.get('category', 'None'))
+ tryton.get('category', 'None'))
import socket
socket.setdefaulttimeout(10)
@@ -448,17 +448,17 @@ class Module(OSV):
except IOError:
raise ExceptORM('Error', 'Can not create the module file: %s'
% (fname,))
- terp = Module.get_module_info(mod.name)
+ tryton = Module.get_module_info(mod.name)
self.write(cursor, user, mod.id, {
- 'description': terp.get('description', ''),
- 'shortdesc': terp.get('name', ''),
- 'author': terp.get('author', 'Unknown'),
- 'website': terp.get('website', ''),
- 'license': terp.get('license', 'GPL-2'),
+ 'description': tryton.get('description', ''),
+ 'shortdesc': tryton.get('name', ''),
+ 'author': tryton.get('author', 'Unknown'),
+ 'website': tryton.get('website', ''),
+ 'license': tryton.get('license', 'GPL-2'),
})
- self._update_dependencies(cursor, user, mod.id, terp.get('depends',
+ self._update_dependencies(cursor, user, mod.id, tryton.get('depends',
[]))
- self._update_category(cursor, user, mod.id, terp.get('category',
+ self._update_category(cursor, user, mod.id, tryton.get('category',
'Uncategorized'))
return res
@@ -524,7 +524,7 @@ class ModuleDependency(OSV):
_columns = {
'name': fields.char('Name', size=128),
- 'module_id': fields.many2one('ir.module.module', 'Module', select=1),
+ 'module_id': fields.many2one('ir.module.module', 'Module', select=1, ondelete='cascade'),
'state': fields.function(_state, method=True, type='selection',
selection=[
('uninstallable','Uninstallable'),
diff --git a/trytond/ir/module/module.xml b/trytond/ir/module/module.xml
index dd87930c05..74499be1d4 100644
--- a/trytond/ir/module/module.xml
+++ b/trytond/ir/module/module.xml
@@ -1,5 +1,5 @@
-
+
@@ -187,4 +187,4 @@
type="wizard"
id="menu_module_install_upgrade"/>
-
+
diff --git a/trytond/ir/module/repository.xml b/trytond/ir/module/repository.xml
index 193a87ce73..72e9219218 100644
--- a/trytond/ir/module/repository.xml
+++ b/trytond/ir/module/repository.xml
@@ -1,5 +1,5 @@
-
+
ir.module.repository
@@ -51,4 +51,4 @@
-
+
diff --git a/trytond/ir/property.xml b/trytond/ir/property.xml
index 6909026848..ae4c0c7672 100644
--- a/trytond/ir/property.xml
+++ b/trytond/ir/property.xml
@@ -1,5 +1,5 @@
-
+
ir.property
@@ -72,4 +72,4 @@
-
+
diff --git a/trytond/ir/rule.xml b/trytond/ir/rule.xml
index 46ec065e93..1bd3153c71 100644
--- a/trytond/ir/rule.xml
+++ b/trytond/ir/rule.xml
@@ -1,5 +1,5 @@
-
+
ir.rule.group
@@ -82,4 +82,4 @@
-
+
diff --git a/trytond/ir/sequence.xml b/trytond/ir/sequence.xml
index 116a7e5e27..f8be96f28b 100644
--- a/trytond/ir/sequence.xml
+++ b/trytond/ir/sequence.xml
@@ -1,5 +1,5 @@
-
+
@@ -106,4 +106,4 @@
-
+
diff --git a/trytond/ir/translation.xml b/trytond/ir/translation.xml
index ed26bbb89f..915fb7a047 100644
--- a/trytond/ir/translation.xml
+++ b/trytond/ir/translation.xml
@@ -1,5 +1,5 @@
-
+
ir.translation
@@ -52,4 +52,4 @@
-
+
diff --git a/trytond/ir/ui/menu.xml b/trytond/ir/ui/menu.xml
index 4b51c6d78e..58692cc19e 100644
--- a/trytond/ir/ui/menu.xml
+++ b/trytond/ir/ui/menu.xml
@@ -1,5 +1,5 @@
-
+
-
+
diff --git a/trytond/ir/ui/ui.xml b/trytond/ir/ui/ui.xml
index 1e9bf9d053..18aae7c6cd 100644
--- a/trytond/ir/ui/ui.xml
+++ b/trytond/ir/ui/ui.xml
@@ -1,6 +1,6 @@
-
+
-
+
diff --git a/trytond/ir/ui/view.xml b/trytond/ir/ui/view.xml
index b1e9f3a124..ea22bf5c7c 100644
--- a/trytond/ir/ui/view.xml
+++ b/trytond/ir/ui/view.xml
@@ -1,5 +1,5 @@
-
+
ir.ui.view
@@ -95,4 +95,4 @@
-
+
diff --git a/trytond/ir/values.xml b/trytond/ir/values.xml
index 9efc3ab89f..1c259be65e 100644
--- a/trytond/ir/values.xml
+++ b/trytond/ir/values.xml
@@ -1,5 +1,5 @@
-
+
ir.values
@@ -56,4 +56,4 @@
-
+
diff --git a/trytond/module.py b/trytond/module.py
index 95c2cc0624..edb1d542c7 100644
--- a/trytond/module.py
+++ b/trytond/module.py
@@ -106,18 +106,18 @@ def create_graph(module_list, force=None):
for module in module_list:
if module[-4:] == '.zip':
module = module[:-4]
- terp_file = OPJ(ADDONS_PATH, module, '__terp__.py')
+ tryton_file = OPJ(ADDONS_PATH, module, '__tryton__.py')
mod_path = OPJ(ADDONS_PATH, module)
if module in ('ir', 'workflow', 'res'):
root_path = os.path.dirname(__file__)
- terp_file = OPJ(root_path, module, '__terp__.py')
+ tryton_file = OPJ(root_path, module, '__tryton__.py')
mod_path = OPJ(root_path, module)
- if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path+'.zip'):
+ if os.path.isfile(tryton_file) or zipfile.is_zipfile(mod_path+'.zip'):
try:
- info = eval(tools.file_open(terp_file).read())
+ info = eval(tools.file_open(tryton_file).read())
except:
Logger().notify_channel('init', LOG_ERROR,
- 'addon:%s:eval file %s' % (module, terp_file))
+ 'addon:%s:eval file %s' % (module, tryton_file))
raise
if info.get('installable', True):
packages.append((module, info.get('depends', []), info))
diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py
index dde2b92e46..6f0f24edc2 100644
--- a/trytond/osv/orm.py
+++ b/trytond/osv/orm.py
@@ -584,6 +584,55 @@ class ORM(object):
cursor.execute("DROP INDEX \"%s_%s_index\"" % \
(self._table, k))
cursor.commit()
+ if isinstance(field, fields.many2one):
+ ref_obj = self.pool.get(field._obj)
+ if ref_obj:
+ ref = ref_obj._table
+ else:
+ ref = field._obj.replace('.', '_')
+ if ref != 'ir_actions':
+ cursor.execute('SELECT confdeltype, conname ' \
+ 'FROM pg_constraint as con, ' \
+ 'pg_class as cl1, pg_class as cl2, ' \
+ 'pg_attribute as att1, pg_attribute as att2 ' \
+ 'WHERE con.conrelid = cl1.oid ' \
+ 'AND cl1.relname = %s ' \
+ 'AND con.confrelid = cl2.oid ' \
+ 'AND cl2.relname = %s ' \
+ 'AND array_lower(con.conkey, 1) = 1 ' \
+ 'AND con.conkey[1] = att1.attnum ' \
+ 'AND att1.attrelid = cl1.oid ' \
+ 'AND att1.attname = %s ' \
+ 'AND array_lower(con.confkey, 1) = 1 ' \
+ 'AND con.confkey[1] = att2.attnum ' \
+ 'AND att2.attrelid = cl2.oid ' \
+ 'AND att2.attname = %s ' \
+ 'AND con.contype = \'f\'',
+ (self._table, ref, k, 'id'))
+ res = cursor.dictfetchall()
+ if res:
+ confdeltype = {
+ 'RESTRICT': 'r',
+ 'NO ACTION': 'a',
+ 'CASCADE': 'c',
+ 'SET NULL': 'n',
+ 'SET DEFAULT': 'd',
+ }
+ if res[0]['confdeltype'] != \
+ confdeltype.get(
+ field.ondelete.upper(),
+ 'a'):
+ cursor.execute('ALTER TABLE "' + \
+ self._table + '" ' \
+ 'DROP CONSTRAINT "' + \
+ res[0]['conname'] + '"')
+ cursor.execute('ALTER TABLE "' + \
+ self._table + '" ' \
+ 'ADD FOREIGN KEY ' \
+ '("' + k + '") ' \
+ 'REFERENCES "' + ref + \
+ '" ON DELETE ' + field.ondelete)
+ cursor.commit()
else:
# TODO add error message
logger.notify_channel('init', LOG_ERROR, '')
@@ -1562,7 +1611,7 @@ class ORM(object):
result = self.view_header_get(cursor, user, False, node.localName,
context)
if result:
- node.setAttribute('string', result)
+ node.setAttribute('string', result.decode('utf8'))
if node.nodeType == node.ELEMENT_NODE:
# translate view
@@ -1594,13 +1643,13 @@ class ORM(object):
for fname, gname in cursor.fetchall():
if oldgroup != gname:
child = doc.createElement('separator')
- child.setAttribute('string', gname)
+ child.setAttribute('string', gname.decode('utf8'))
child.setAttribute('colspan', "4")
oldgroup = gname
parent.insertBefore(child, node)
child = doc.createElement('field')
- child.setAttribute('name', fname)
+ child.setAttribute('name', fname.decode('utf8'))
parent.insertBefore(child, node)
parent.removeChild(node)
diff --git a/trytond/res/__terp__.py b/trytond/res/__tryton__.py
similarity index 100%
rename from trytond/res/__terp__.py
rename to trytond/res/__tryton__.py
diff --git a/trytond/res/lang.xml b/trytond/res/lang.xml
index d50454b4e9..04385ec260 100644
--- a/trytond/res/lang.xml
+++ b/trytond/res/lang.xml
@@ -1,5 +1,5 @@
-
+
en_US
@@ -35,4 +35,4 @@
-
+
diff --git a/trytond/res/report/user.odt b/trytond/res/report/user.odt
new file mode 100644
index 0000000000..7b1b0e7446
Binary files /dev/null and b/trytond/res/report/user.odt differ
diff --git a/trytond/res/request.xml b/trytond/res/request.xml
index 20e439c31c..8da2872e9a 100644
--- a/trytond/res/request.xml
+++ b/trytond/res/request.xml
@@ -1,5 +1,5 @@
-
+
res.request
@@ -136,4 +136,4 @@
-
+
diff --git a/trytond/res/res.xml b/trytond/res/res.xml
index 34c4dfd13c..7600ca808d 100644
--- a/trytond/res/res.xml
+++ b/trytond/res/res.xml
@@ -1,6 +1,6 @@
-
+
-
+
diff --git a/trytond/res/users.xml b/trytond/res/users.xml
index e5e0510c4a..c08abefd33 100644
--- a/trytond/res/users.xml
+++ b/trytond/res/users.xml
@@ -1,5 +1,5 @@
-
+
admin
@@ -186,4 +186,4 @@
-
+
diff --git a/trytond/sql_db.py b/trytond/sql_db.py
index e72e709d04..ecdc0641d6 100644
--- a/trytond/sql_db.py
+++ b/trytond/sql_db.py
@@ -116,20 +116,20 @@ def init_db(cursor):
addons_path = os.path.join(os.path.dirname(__file__), 'addons')
for i in (os.listdir(addons_path) + ['ir', 'workflow', 'res']):
- terp_file = opj(addons_path, i, '__terp__.py')
+ tryton_file = opj(addons_path, i, '__tryton__.py')
mod_path = opj(addons_path, i)
if i in ('ir', 'workflow', 'res'):
root_path = os.path.dirname(__file__)
- terp_file = opj(root_path, i, '__terp__.py')
+ tryton_file = opj(root_path, i, '__tryton__.py')
mod_path = opj(root_path, i)
info = {}
- if os.path.isfile(terp_file) \
+ if os.path.isfile(tryton_file) \
and not os.path.isfile(opj(addons_path, i + '.zip')):
- info = eval(file(terp_file).read())
+ info = eval(file(tryton_file).read())
elif zipfile.is_zipfile(mod_path):
zfile = zipfile.ZipFile(mod_path)
i = os.path.splitext(i)[0]
- info = eval(zfile.read(opj(i, '__terp__.py')))
+ info = eval(zfile.read(opj(i, '__tryton__.py')))
if info:
categs = info.get('category', 'Uncategorized').split('/')
p_id = None
diff --git a/trytond/tools/convert.py b/trytond/tools/convert.py
index 34c3848021..c38a183334 100644
--- a/trytond/tools/convert.py
+++ b/trytond/tools/convert.py
@@ -274,7 +274,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
self.taghandler = None
# Managed tags are handled by the current class
- self.managedtags= ["data", "terp"]
+ self.managedtags= ["data", "tryton"]
self.idlist = []
@@ -301,7 +301,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler):
elif name == "data":
self.noupdate = attributes.get("noupdate", False)
- elif name == "terp":
+ elif name == "tryton":
pass
else:
diff --git a/trytond/workflow/__terp__.py b/trytond/workflow/__tryton__.py
similarity index 100%
rename from trytond/workflow/__terp__.py
rename to trytond/workflow/__tryton__.py
diff --git a/trytond/workflow/workflow.py b/trytond/workflow/workflow.py
index 01733fec21..62a5b1b0cf 100644
--- a/trytond/workflow/workflow.py
+++ b/trytond/workflow/workflow.py
@@ -44,7 +44,7 @@ class WorkflowActivity(OSV):
_columns = {
'name': fields.char('Name', size=64, required=True),
'wkf_id': fields.many2one('workflow', 'Workflow', required=True,
- select=1),
+ select=1, ondelete='cascade'),
'split_mode': fields.selection([
('XOR', 'Xor'),
('OR', 'Or'),
@@ -93,9 +93,9 @@ class WorkflowTransition(OSV):
'role_id': fields.many2one('res.role', 'Role Required'),
'condition': fields.char('Condition', required=True, size=128),
'act_from': fields.many2one('workflow.activity', 'Source Activity',
- required=True, select=1),
+ required=True, select=1, ondelete='cascade'),
'act_to': fields.many2one('workflow.activity', 'Destination Activity',
- required=True, select=1),
+ required=True, select=1, ondelete='cascade'),
}
_defaults = {
'condition': lambda *a: 'True',
@@ -112,7 +112,7 @@ class WorkflowInstance(OSV):
_log_access = False
_description = __doc__
_columns = {
- 'wkf_id': fields.many2one('workflow', 'Workflow', ondelete="cascade"),
+ 'wkf_id': fields.many2one('workflow', 'Workflow', ondelete="restrict"),
'uid': fields.integer('User ID'),
'res_id': fields.integer('Resource ID'),
'res_type': fields.char('Resource Model', size=64),
diff --git a/trytond/workflow/workflow.xml b/trytond/workflow/workflow.xml
index 14d1d75e74..23e01e4d6e 100644
--- a/trytond/workflow/workflow.xml
+++ b/trytond/workflow/workflow.xml
@@ -1,5 +1,5 @@
-
+
@@ -271,4 +271,4 @@
-
+