From 7ef45906cfa7b8c6bcefb6280f3ab76e82256080 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Mon, 1 Feb 2010 15:23:55 +0530 Subject: [PATCH 01/38] [IMP]: initial work of diagram view. bzr revid: apa@tinyerp.com-20100201095355-gohn3f6z4eb98d87 --- bin/addons/base/ir/ir_ui_view.py | 1 + bin/addons/base/ir/workflow/workflow_view.xml | 17 +++++++++ bin/addons/base/rng/view.rng | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index b66d7eedcf6..2391737c425 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -59,6 +59,7 @@ class view(osv.osv): ('mdx','mdx'), ('graph', 'Graph'), ('calendar', 'Calendar'), + ('diagram','Diagram'), ('gantt', 'Gantt'), ('search','Search')), 'View Type', required=True), 'arch': fields.text('View Architecture', required=True), diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index a0bfb7fdc03..6d3ddf9f5cc 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -23,6 +23,22 @@ + + + workflow.diagram + workflow + diagram + + + + + + + + + + + workflow.tree workflow @@ -41,6 +57,7 @@ workflow form + tree,form,diagram diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng index 3a9c8f92369..82112a834c7 100644 --- a/bin/addons/base/rng/view.rng +++ b/bin/addons/base/rng/view.rng @@ -30,6 +30,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -332,6 +368,7 @@ + @@ -507,6 +544,7 @@ + From 487b9ea3dd501f48cb0a4e93cf9fa94047c12461 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Tue, 2 Feb 2010 17:24:22 +0530 Subject: [PATCH 02/38] [IMP]:Make get_graph method as generic.(REF.APA,YSA) bzr revid: apa@tinyerp.com-20100202115422-0mg6annejy8f09nd --- bin/addons/base/ir/ir_ui_view.py | 89 +++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 2391737c425..6c932eb312e 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -15,12 +15,13 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## from osv import fields,osv from lxml import etree +from tools import graph import tools import netsvc import os @@ -130,6 +131,90 @@ class view(osv.osv): return result return super(view, self).write(cr, uid, ids, vals, context) + + def graph_get(self, cr, uid, id, scale, context={}): + + _Node={} + _Arrow={} + _Ids = self.search(cr, uid, [('type','=','diagram')], context=context) + _Models = self.browse(cr, uid, _Ids, context) + + for _Model in _Models: + + from lxml import etree + import StringIO,xml.dom.minidom + + d = xml.dom.minidom.parseString(str(_Model.arch)) + de = d.documentElement + + def node_attributes(node): + result = {} + attrs = node.attributes + if attrs is None: + return {} + for i in range(attrs.length): + result[attrs.item(i).localName] = str(attrs.item(i).nodeValue) + if attrs.item(i).localName == "digits" and isinstance(attrs.item(i).nodeValue, (str, unicode)): + result[attrs.item(i).localName] = eval(attrs.item(i).nodeValue) + return result + + for n in [i for i in de.childNodes]: + if n.nodeName=='node': + _Node.update(node_attributes(n)) + elif n.nodeName=='arrow': + _Arrow.update(node_attributes(n)) + + _Model_Obj = self.pool.get(str(_Model.model)) + + for _Field,_Value in _Model_Obj._columns.items(): + if _Value._type == 'one2many': + if _Value._obj==_Node['object']: + _Node_Obj = self.pool.get(_Value._obj) + _Node_Field = _Field + _Flag=False + for _Field_1,_Value_1 in _Node_Obj._columns.items(): + if _Value_1._type == 'one2many': + if _Value_1._obj==_Arrow['object']: + _Arrow_Obj = self.pool.get(_Value_1._obj) + for _Key,_Val in _Arrow_Obj._columns.items(): + if _Arrow['source'] == _Key: + if _Flag: + _Source_Field = _Field_1 + if _Arrow['destination'] == _Key: + if not _Flag: + _Destination_Field = _Field_1 + _Flag = True + nodes= [] + nodes_name = [] + transitions = [] + start = [] + tres = {} + no_ancester = [] + workflow = _Model_Obj.read(cr, uid, id, [],context) + for a in _Node_Obj.read(cr,uid, workflow[_Node_Field],[]): + nodes_name.append((a['id'],a['name'])) + nodes.append(a['id']) + if a['flow_start']: + start.append(a['id']) + else: + if not a[_Source_Field]: + no_ancester.append(a['id']) + + for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): + transitions.append((a['id'], t[_Arrow['destination']][0])) + tres[t['id']] = (a['id'], t[_Arrow['destination']][0]) + + g = graph(nodes, transitions, no_ancester) + g.process(start) + g.scale(*scale) + result = g.result_get() + results = {} + + for node in nodes_name: + results[str(node[0])] = result[node[0]] + results[str(node[0])]['name'] = node[1] + + return {'nodes': results, 'transitions': tres} view() class view_sc(osv.osv): From d6c5fa26d32cbdc55f280b781dd042d778f87429 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Fri, 5 Feb 2010 18:28:52 +0530 Subject: [PATCH 03/38] [IMP]:improved the graph_get method for generic. bzr revid: apa@tinyerp.com-20100205125852-ykgf5ti2vuhswfle --- bin/addons/base/ir/ir_ui_view.py | 125 +++++++++++-------------------- 1 file changed, 45 insertions(+), 80 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 6c932eb312e..af4445e0b32 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -132,89 +132,54 @@ class view(osv.osv): return super(view, self).write(cr, uid, ids, vals, context) - def graph_get(self, cr, uid, id, scale, context={}): + def graph_get(self, cr, uid, id, model, node_obj, conn_obj, src_node, des_node, scale,context={}): + nodes= [] + nodes_name = [] + transitions = [] + start = [] + tres = {} + no_ancester = [] - _Node={} - _Arrow={} - _Ids = self.search(cr, uid, [('type','=','diagram')], context=context) - _Models = self.browse(cr, uid, _Ids, context) + _Model_Obj = self.pool.get(model) + _Node_Obj = self.pool.get(node_obj) + _Arrow_Obj = self.pool.get(conn_obj) - for _Model in _Models: + for model_key,model_value in _Model_Obj._columns.items(): + if model_value._type == 'one2many': + if model_value._obj==node_obj: + _Node_Field=model_key + flag=False + for node_key,node_value in _Node_Obj._columns.items(): + if node_value._type=='one2many': + if src_node in _Arrow_Obj._columns: + if flag: + _Source_Field = node_key + if des_node in _Arrow_Obj._columns: + if not flag: + _Destination_Field = node_key + flag = True - from lxml import etree - import StringIO,xml.dom.minidom - - d = xml.dom.minidom.parseString(str(_Model.arch)) - de = d.documentElement - - def node_attributes(node): - result = {} - attrs = node.attributes - if attrs is None: - return {} - for i in range(attrs.length): - result[attrs.item(i).localName] = str(attrs.item(i).nodeValue) - if attrs.item(i).localName == "digits" and isinstance(attrs.item(i).nodeValue, (str, unicode)): - result[attrs.item(i).localName] = eval(attrs.item(i).nodeValue) - return result - - for n in [i for i in de.childNodes]: - if n.nodeName=='node': - _Node.update(node_attributes(n)) - elif n.nodeName=='arrow': - _Arrow.update(node_attributes(n)) - - _Model_Obj = self.pool.get(str(_Model.model)) - - for _Field,_Value in _Model_Obj._columns.items(): - if _Value._type == 'one2many': - if _Value._obj==_Node['object']: - _Node_Obj = self.pool.get(_Value._obj) - _Node_Field = _Field - _Flag=False - for _Field_1,_Value_1 in _Node_Obj._columns.items(): - if _Value_1._type == 'one2many': - if _Value_1._obj==_Arrow['object']: - _Arrow_Obj = self.pool.get(_Value_1._obj) - for _Key,_Val in _Arrow_Obj._columns.items(): - if _Arrow['source'] == _Key: - if _Flag: - _Source_Field = _Field_1 - if _Arrow['destination'] == _Key: - if not _Flag: - _Destination_Field = _Field_1 - _Flag = True - nodes= [] - nodes_name = [] - transitions = [] - start = [] - tres = {} - no_ancester = [] - workflow = _Model_Obj.read(cr, uid, id, [],context) - for a in _Node_Obj.read(cr,uid, workflow[_Node_Field],[]): - nodes_name.append((a['id'],a['name'])) - nodes.append(a['id']) - if a['flow_start']: - start.append(a['id']) - else: - if not a[_Source_Field]: - no_ancester.append(a['id']) - - for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): - transitions.append((a['id'], t[_Arrow['destination']][0])) - tres[t['id']] = (a['id'], t[_Arrow['destination']][0]) - - g = graph(nodes, transitions, no_ancester) - g.process(start) - g.scale(*scale) - result = g.result_get() - results = {} - - for node in nodes_name: - results[str(node[0])] = result[node[0]] - results[str(node[0])]['name'] = node[1] - - return {'nodes': results, 'transitions': tres} + datas = _Model_Obj.read(cr, uid, id, [],context) + for a in _Node_Obj.read(cr,uid,datas[_Node_Field],[]): + nodes_name.append((a['id'],a['name'])) + nodes.append(a['id']) + if a['flow_start']: + start.append(a['id']) + else: + if not a[_Source_Field]: + no_ancester.append(a['id']) + for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): + transitions.append((a['id'], t[des_node][0])) + tres[t['id']] = (a['id'], t[des_node][0]) + g = graph(nodes, transitions, no_ancester) + g.process(start) + g.scale(*scale) + result = g.result_get() + results = {} + for node in nodes_name: + results[str(node[0])] = result[node[0]] + results[str(node[0])]['name'] = node[1] + return {'nodes': results, 'transitions': tres} view() class view_sc(osv.osv): From e3bac5fec496f84f7f08314453fdf6737819c3bb Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Fri, 5 Feb 2010 20:08:13 +0530 Subject: [PATCH 04/38] [IMP]:improve code bzr revid: apa@tinyerp.com-20100205143813-s9nt379rgqdjx6pw --- bin/addons/base/ir/ir_ui_view.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index af4445e0b32..10d2b694ad2 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -145,19 +145,17 @@ class view(osv.osv): _Arrow_Obj = self.pool.get(conn_obj) for model_key,model_value in _Model_Obj._columns.items(): - if model_value._type == 'one2many': + if model_value._type=='one2many' and model_value._obj==node_obj: if model_value._obj==node_obj: _Node_Field=model_key flag=False for node_key,node_value in _Node_Obj._columns.items(): if node_value._type=='one2many': - if src_node in _Arrow_Obj._columns: - if flag: - _Source_Field = node_key - if des_node in _Arrow_Obj._columns: - if not flag: - _Destination_Field = node_key - flag = True + if src_node in _Arrow_Obj._columns and flag: + _Source_Field=node_key + if des_node in _Arrow_Obj._columns and not flag: + _Destination_Field=node_key + flag = True datas = _Model_Obj.read(cr, uid, id, [],context) for a in _Node_Obj.read(cr,uid,datas[_Node_Field],[]): From 01e68a6a56ad961d575f26c3e11b22b3587e84a4 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Fri, 5 Feb 2010 20:09:02 +0530 Subject: [PATCH 05/38] [IMP]:improve code bzr revid: apa@tinyerp.com-20100205143902-ih121kafmupku6pz --- bin/addons/base/ir/ir_ui_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 10d2b694ad2..59d0e431f3a 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -145,7 +145,7 @@ class view(osv.osv): _Arrow_Obj = self.pool.get(conn_obj) for model_key,model_value in _Model_Obj._columns.items(): - if model_value._type=='one2many' and model_value._obj==node_obj: + if model_value._type=='one2many': if model_value._obj==node_obj: _Node_Field=model_key flag=False From 7308ba4ca4796a01b73059841fc414f889dbbcb0 Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Tue, 9 Feb 2010 13:11:27 +0530 Subject: [PATCH 06/38] [IMP] add shape and bgcolor attribute add in diagram node bzr revid: ysa@tinyerp.co.in-20100209074127-okyugub65gmj56yo --- bin/addons/base/ir/workflow/workflow_view.xml | 2 +- bin/addons/base/rng/view.rng | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index 6d3ddf9f5cc..435d0f3d61f 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -30,7 +30,7 @@ diagram - + diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng index 82112a834c7..90ca81251bc 100644 --- a/bin/addons/base/rng/view.rng +++ b/bin/addons/base/rng/view.rng @@ -44,7 +44,9 @@ - + + + From cc4bf70f1baa7920a278832ea4ab6b47d4e6737d Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Tue, 9 Feb 2010 15:41:32 +0530 Subject: [PATCH 07/38] [IMP] workflow get_graph method keep in comment bzr revid: ysa@tinyerp.co.in-20100209101132-kem10xbj4at56l0f --- bin/addons/base/ir/workflow/workflow.py | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/bin/addons/base/ir/workflow/workflow.py b/bin/addons/base/ir/workflow/workflow.py index 89e18a08fb4..bc51ee1f8e4 100644 --- a/bin/addons/base/ir/workflow/workflow.py +++ b/bin/addons/base/ir/workflow/workflow.py @@ -49,40 +49,40 @@ class workflow(osv.osv): # - def graph_get(self, cr, uid, id, scale, context={}): - - nodes= [] - nodes_name = [] - transitions = [] - start = [] - tres = {} - no_ancester = [] - workflow = self.browse(cr, uid, id, context) - for a in workflow.activities: - nodes_name.append((a.id,a.name)) - nodes.append(a.id) - if a.flow_start: - start.append(a.id) - else: - if not a.in_transitions: - no_ancester.append(a.id) - - for t in a.out_transitions: - transitions.append((a.id, t.act_to.id)) - tres[t.id] = (a.id, t.act_to.id) - - - g = graph(nodes, transitions, no_ancester) - g.process(start) - g.scale(*scale) - result = g.result_get() - results = {} - - for node in nodes_name: - results[str(node[0])] = result[node[0]] - results[str(node[0])]['name'] = node[1] - - return {'nodes': results, 'transitions': tres} +# def graph_get(self, cr, uid, id, scale, context={}): +# +# nodes= [] +# nodes_name = [] +# transitions = [] +# start = [] +# tres = {} +# no_ancester = [] +# workflow = self.browse(cr, uid, id, context) +# for a in workflow.activities: +# nodes_name.append((a.id,a.name)) +# nodes.append(a.id) +# if a.flow_start: +# start.append(a.id) +# else: +# if not a.in_transitions: +# no_ancester.append(a.id) +# +# for t in a.out_transitions: +# transitions.append((a.id, t.act_to.id)) +# tres[t.id] = (a.id, t.act_to.id) +# +# +# g = graph(nodes, transitions, no_ancester) +# g.process(start) +# g.scale(*scale) +# result = g.result_get() +# results = {} +# +# for node in nodes_name: +# results[str(node[0])] = result[node[0]] +# results[str(node[0])]['name'] = node[1] +# +# return {'nodes': results, 'transitions': tres} def create(self, cr, user, vals, context=None): From 03f896fed992c0a62ef5d38bb80e29a9fa753ead Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Wed, 10 Feb 2010 14:28:03 +0530 Subject: [PATCH 08/38] [IMP] make optional node attribute in diagram view bzr revid: ysa@tinyerp.co.in-20100210085803-gp59xfor6zvv0taw --- bin/addons/base/rng/view.rng | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng index 54cae3f5688..3b9d63ec989 100644 --- a/bin/addons/base/rng/view.rng +++ b/bin/addons/base/rng/view.rng @@ -45,8 +45,8 @@ - - + + From dfb5786fe03ab88a76e320f5fbb39d79b51a433c Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Wed, 10 Feb 2010 16:14:16 +0530 Subject: [PATCH 09/38] [IMP]:Improved the generic method for diagram view. bzr revid: apa@tinyerp.com-20100210104416-u5esh24kpb9j9ljq --- bin/addons/base/ir/ir_ui_view.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 59d0e431f3a..036ab1c582b 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -144,6 +144,7 @@ class view(osv.osv): _Node_Obj = self.pool.get(node_obj) _Arrow_Obj = self.pool.get(conn_obj) + print model, node_obj, conn_obj, src_node, des_node for model_key,model_value in _Model_Obj._columns.items(): if model_value._type=='one2many': if model_value._obj==node_obj: @@ -151,17 +152,19 @@ class view(osv.osv): flag=False for node_key,node_value in _Node_Obj._columns.items(): if node_value._type=='one2many': - if src_node in _Arrow_Obj._columns and flag: - _Source_Field=node_key - if des_node in _Arrow_Obj._columns and not flag: - _Destination_Field=node_key - flag = True + if node_value._obj==conn_obj: + if src_node in _Arrow_Obj._columns and flag: + _Source_Field=node_key + if des_node in _Arrow_Obj._columns and not flag: + _Destination_Field=node_key + flag = True datas = _Model_Obj.read(cr, uid, id, [],context) + print ":::::::::::::::::",_Node_Field,_Source_Field,_Destination_Field for a in _Node_Obj.read(cr,uid,datas[_Node_Field],[]): nodes_name.append((a['id'],a['name'])) nodes.append(a['id']) - if a['flow_start']: + if a.has_key('flow_start') and a['flow_start']: start.append(a['id']) else: if not a[_Source_Field]: @@ -169,7 +172,10 @@ class view(osv.osv): for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): transitions.append((a['id'], t[des_node][0])) tres[t['id']] = (a['id'], t[des_node][0]) + + print nodes, transitions, no_ancester g = graph(nodes, transitions, no_ancester) +# print start g.process(start) g.scale(*scale) result = g.result_get() @@ -177,6 +183,7 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] +# print {'nodes': results, 'transitions': tres} return {'nodes': results, 'transitions': tres} view() From c3b91a0a9d04bbc6897caeb96ec35b5d6db777a5 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Wed, 10 Feb 2010 17:15:18 +0530 Subject: [PATCH 10/38] [IMP]:improved code bzr revid: apa@tinyerp.com-20100210114518-ck2on1npoatsan1n --- bin/addons/base/ir/ir_ui_view.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 036ab1c582b..58fd6255399 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -144,11 +144,11 @@ class view(osv.osv): _Node_Obj = self.pool.get(node_obj) _Arrow_Obj = self.pool.get(conn_obj) - print model, node_obj, conn_obj, src_node, des_node for model_key,model_value in _Model_Obj._columns.items(): if model_value._type=='one2many': if model_value._obj==node_obj: _Node_Field=model_key + _Model_Field=model_value._fields_id flag=False for node_key,node_value in _Node_Obj._columns.items(): if node_value._type=='one2many': @@ -160,7 +160,6 @@ class view(osv.osv): flag = True datas = _Model_Obj.read(cr, uid, id, [],context) - print ":::::::::::::::::",_Node_Field,_Source_Field,_Destination_Field for a in _Node_Obj.read(cr,uid,datas[_Node_Field],[]): nodes_name.append((a['id'],a['name'])) nodes.append(a['id']) @@ -173,9 +172,7 @@ class view(osv.osv): transitions.append((a['id'], t[des_node][0])) tres[t['id']] = (a['id'], t[des_node][0]) - print nodes, transitions, no_ancester g = graph(nodes, transitions, no_ancester) -# print start g.process(start) g.scale(*scale) result = g.result_get() @@ -183,7 +180,6 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] -# print {'nodes': results, 'transitions': tres} return {'nodes': results, 'transitions': tres} view() From bff06b021a86ed6a8b9a74391826ed8486403fee Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Thu, 18 Feb 2010 12:08:58 +0530 Subject: [PATCH 11/38] Improve graph_get method. bzr revid: ysa@tinyerp.co.in-20100218063858-by8e5t1ycoei9snc --- bin/addons/base/ir/ir_ui_view.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 58fd6255399..4241d79178e 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -138,6 +138,7 @@ class view(osv.osv): transitions = [] start = [] tres = {} + signal = {} no_ancester = [] _Model_Obj = self.pool.get(model) @@ -170,8 +171,12 @@ class view(osv.osv): no_ancester.append(a['id']) for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): transitions.append((a['id'], t[des_node][0])) - tres[t['id']] = (a['id'], t[des_node][0]) - + tres[str(t['id'])] = (a['id'],t[des_node][0]) + if t['signal']: + signal[str(t['id'])] = t['signal'] + else: + signal[str(t['id'])] = t['condition'] + g = graph(nodes, transitions, no_ancester) g.process(start) g.scale(*scale) @@ -180,7 +185,7 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] - return {'nodes': results, 'transitions': tres} + return {'nodes': results, 'transitions': tres, 'signal' : signal} view() class view_sc(osv.osv): From cc6685b7612580e28124101e4166b7d65ce2454a Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Thu, 18 Feb 2010 14:48:04 +0530 Subject: [PATCH 12/38] [IMP]:code comment bzr revid: apa@tinyerp.com-20100218091804-0hcpceryiib2pmfh --- bin/addons/base/ir/ir_ui_view.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 4241d79178e..b59ddbf720f 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -172,11 +172,10 @@ class view(osv.osv): for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): transitions.append((a['id'], t[des_node][0])) tres[str(t['id'])] = (a['id'],t[des_node][0]) - if t['signal']: - signal[str(t['id'])] = t['signal'] - else: - signal[str(t['id'])] = t['condition'] - +# if t['signal']: +# signal[str(t['id'])] = t['signal'] +# else: +# signal[str(t['id'])] = t['condition'] g = graph(nodes, transitions, no_ancester) g.process(start) g.scale(*scale) @@ -185,7 +184,8 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] - return {'nodes': results, 'transitions': tres, 'signal' : signal} + return {'nodes': results, 'transitions': tres} +# return {'nodes': results, 'transitions': tres, 'signal' : signal} view() class view_sc(osv.osv): From 7b96c8e03a7c586f99d3d1bd7e28b6f475383bb6 Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Thu, 18 Feb 2010 16:59:35 +0530 Subject: [PATCH 13/38] Improve code bzr revid: ysa@tinyerp.co.in-20100218112935-mqfj2gum9l0z977f --- bin/addons/base/ir/ir_ui_view.py | 11 +++++------ bin/addons/base/ir/workflow/workflow_view.xml | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index b59ddbf720f..a092f2b2f45 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -172,10 +172,10 @@ class view(osv.osv): for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): transitions.append((a['id'], t[des_node][0])) tres[str(t['id'])] = (a['id'],t[des_node][0]) -# if t['signal']: -# signal[str(t['id'])] = t['signal'] -# else: -# signal[str(t['id'])] = t['condition'] + if t['signal']: + signal[str(t['id'])] = t['signal'] + else: + signal[str(t['id'])] = t['condition'] g = graph(nodes, transitions, no_ancester) g.process(start) g.scale(*scale) @@ -184,8 +184,7 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] - return {'nodes': results, 'transitions': tres} -# return {'nodes': results, 'transitions': tres, 'signal' : signal} + return {'nodes': results, 'transitions': tres, 'signal' : signal} view() class view_sc(osv.osv): diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index 435d0f3d61f..5cc8933c698 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -33,7 +33,7 @@ - + From 34d8f3faa0ede721bb13ebe68be8c887fd422dc6 Mon Sep 17 00:00:00 2001 From: "ksh (Axelor)" Date: Thu, 18 Feb 2010 17:10:34 +0530 Subject: [PATCH 14/38] [IMP] get active activities for the workflow for the record bzr revid: ksh@openerp.co.in-20100218114034-8gcx0yxege2taaid --- bin/addons/base/ir/workflow/workflow.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bin/addons/base/ir/workflow/workflow.py b/bin/addons/base/ir/workflow/workflow.py index bc51ee1f8e4..2a551e9549f 100644 --- a/bin/addons/base/ir/workflow/workflow.py +++ b/bin/addons/base/ir/workflow/workflow.py @@ -44,6 +44,25 @@ class workflow(osv.osv): wf_service.clear_cache(cr, user) return super(workflow, self).write(cr, user, ids, vals, context=context) + def get_active_workitems(self, cr, uid, res, res_id, context={}): + + cr.execute('select * from wkf where osv=%s limit 1',(res,)) + wkfinfo = cr.dictfetchone() + workitems = [] + + if wkfinfo: + cr.execute('SELECT id FROM wkf_instance \ + WHERE res_id=%s AND wkf_id=%s \ + ORDER BY state LIMIT 1', + (res_id, wkfinfo['id'])) + inst_id = cr.fetchone() + + cr.execute('select act_id,count(*) from wkf_workitem where inst_id=%s group by act_id', (inst_id,)) + workitems = dict(cr.fetchall()) + + return {'wkf': wkfinfo, 'workitems': workitems} + + # # scale = (vertical-distance, horizontal-distance, min-node-width(optional), min-node-height(optional), margin(default=20)) # From 6eadc92bee06569e984cf9bcb034c90b1e0d76f8 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Mon, 22 Feb 2010 15:48:23 +0530 Subject: [PATCH 15/38] [IMP]:improved diagram code with signal in graph. bzr revid: apa@tinyerp.com-20100222101823-ksphjjdecxjn6cnp --- bin/addons/base/ir/ir_ui_view.py | 31 +++++++++++++++---------------- bin/addons/base/rng/view.rng | 15 ++++++++------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index a092f2b2f45..e7be5117828 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -132,18 +132,18 @@ class view(osv.osv): return super(view, self).write(cr, uid, ids, vals, context) - def graph_get(self, cr, uid, id, model, node_obj, conn_obj, src_node, des_node, scale,context={}): - nodes= [] - nodes_name = [] - transitions = [] - start = [] - tres = {} - signal = {} - no_ancester = [] + def graph_get(self, cr, uid, id, model, node_obj, conn_obj, src_node, des_node,signal,scale,context={}): + nodes=[] + nodes_name=[] + transitions=[] + start=[] + tres={} + sig={} + no_ancester=[] - _Model_Obj = self.pool.get(model) - _Node_Obj = self.pool.get(node_obj) - _Arrow_Obj = self.pool.get(conn_obj) + _Model_Obj=self.pool.get(model) + _Node_Obj=self.pool.get(node_obj) + _Arrow_Obj=self.pool.get(conn_obj) for model_key,model_value in _Model_Obj._columns.items(): if model_value._type=='one2many': @@ -172,10 +172,9 @@ class view(osv.osv): for t in _Arrow_Obj.read(cr,uid, a[_Destination_Field],[]): transitions.append((a['id'], t[des_node][0])) tres[str(t['id'])] = (a['id'],t[des_node][0]) - if t['signal']: - signal[str(t['id'])] = t['signal'] - else: - signal[str(t['id'])] = t['condition'] + if t.has_key(str(signal)) and str(t[signal])=='False': + t[signal]=' ' + sig[str(t['id'])] = (a['id'],t.get(signal,' ')) g = graph(nodes, transitions, no_ancester) g.process(start) g.scale(*scale) @@ -184,7 +183,7 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] - return {'nodes': results, 'transitions': tres, 'signal' : signal} + return {'nodes': results, 'transitions': tres, 'signal' : sig} view() class view_sc(osv.osv): diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng index 3b9d63ec989..a69f06d9c39 100644 --- a/bin/addons/base/rng/view.rng +++ b/bin/addons/base/rng/view.rng @@ -32,7 +32,7 @@ - + @@ -41,7 +41,7 @@ - + @@ -49,25 +49,26 @@ - + - + - + + - + - + From 7da66c83aef25ac247f5ace6a1bfb0763fe1be44 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Mon, 22 Feb 2010 16:34:19 +0530 Subject: [PATCH 16/38] smallchanges bzr revid: apa@tinyerp.com-20100222110419-0k51dftd64uycz02 --- bin/addons/base/ir/workflow/workflow_view.xml | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index 5cc8933c698..db42935b36f 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -2,13 +2,13 @@ - + - + workflow.form workflow @@ -23,20 +23,20 @@ - + workflow.diagram workflow diagram - + - + @@ -51,7 +51,7 @@ - + Workflows workflow @@ -126,7 +126,7 @@ - + Activities workflow.activity @@ -134,14 +134,14 @@ - - + + - + workflow.transition.form workflow.transition @@ -174,8 +174,8 @@ - - + + Transitions workflow.transition @@ -183,13 +183,13 @@ - + - + workflow.instance.form workflow.instance @@ -218,7 +218,7 @@ - + Instances workflow.instance @@ -226,13 +226,13 @@ - + - + workflow.workitem.form workflow.workitem @@ -259,7 +259,7 @@ - + Workitems workflow.workitem @@ -267,6 +267,6 @@ - + From c9763d3200c4c518fa8e462293b6f2b63d53a972 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Wed, 24 Feb 2010 17:18:06 +0530 Subject: [PATCH 17/38] [IMP]:improve orm for diagram view. bzr revid: apa@tinyerp.com-20100224114806-s10137rwshuflw3c --- bin/osv/orm.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 63235e158d4..38d6dd0c473 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -247,7 +247,7 @@ class browse_record(object): new_data[n] = self._list_class([browse_record(self._cr, self._uid, id, self._table.pool.get(f._obj), self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) for id in data[n]], self._context) else: new_data[n] = data[n] - self._data[data['id']].update(new_data) + self._data[data['id']].update(new_data) if not name in self._data[self._id]: #how did this happen? self.logger.notifyChannel("browse_record", netsvc.LOG_ERROR, @@ -1100,7 +1100,7 @@ class orm_template(object): if column._domain and not isinstance(column._domain, (str, unicode)): dom = column._domain dom += eval(node.get('domain','[]'), {'uid':user, 'time':time}) - context.update(eval(node.get('context','{}'))) + context.update(eval(node.get('context','{}'))) attrs['selection'] = self.pool.get(relation).name_search(cr, user, '', dom, context=context) if (node.get('required') and not int(node.get('required'))) or not column.required: attrs['selection'].append((False,'')) @@ -1186,7 +1186,21 @@ class orm_template(object): button.set('readonly', str(int(not can_click))) arch = etree.tostring(node, encoding="utf-8").replace('\t', '') - fields = self.fields_get(cr, user, fields_def.keys(), context) + + #code for diagram view. + fields={} + if node.tag=='diagram': + if node.getchildren()[0].tag=='node': + node_fields=self.pool.get(node.getchildren()[0].get('object')).fields_get(cr, user, fields_def.keys(), context) + if node.getchildren()[1].tag=='arrow': + arrow_fields = self.pool.get(node.getchildren()[1].get('object')).fields_get(cr, user, fields_def.keys(), context) + for key,value in node_fields.items(): + fields[key]=value + for key,value in arrow_fields.items(): + fields[key]=value + else: + fields = self.fields_get(cr, user, fields_def.keys(), context) + for field in fields_def: if field == 'id': # sometime, the view may containt the (invisible) field 'id' needed for a domain (when 2 objects have cross references) @@ -1202,7 +1216,6 @@ class orm_template(object): msg += "\n\nEither you wrongly customised this view, or some modules bringing those views are not compatible with your current data model" netsvc.Logger().notifyChannel('orm', netsvc.LOG_ERROR, msg) raise except_orm('View error', msg) - return arch, fields def __get_default_calendar_view(self): @@ -1855,7 +1868,7 @@ class orm(orm_template): float_int_fields = filter(lambda x: fget[x]['type'] in ('float','integer'), fields) sum = {} - group_by = groupby + group_by = groupby if fget.get(groupby,False) and fget[groupby]['type'] in ('date','datetime'): flist = "to_char(%s,'yyyy-mm') as %s "%(groupby,groupby) groupby = "to_char(%s,'yyyy-mm')"%(groupby) @@ -2032,12 +2045,12 @@ class orm(orm_template): if isinstance(f, fields.one2many): cr.execute("SELECT relname FROM pg_class WHERE relkind='r' AND relname=%s", (f._obj,)) - + if self.pool.get(f._obj): if f._fields_id not in self.pool.get(f._obj)._columns.keys(): if not self.pool.get(f._obj)._inherits or (f._fields_id not in self.pool.get(f._obj)._inherit_fields.keys()): raise except_orm('Programming Error', ("There is no reference field '%s' found for '%s'") % (f._fields_id,f._obj,)) - + if cr.fetchone(): cr.execute("SELECT count(1) as c FROM pg_class c,pg_attribute a WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid", (f._obj, f._fields_id)) res = cr.fetchone()[0] From 0dbd853c36fdb735f499c0c4f08fa4c4612bb5ba Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Thu, 25 Feb 2010 12:51:04 +0530 Subject: [PATCH 18/38] [IMP] add field in diagram view bzr revid: ysa@tinyerp.co.in-20100225072104-6jnnoc30xepzt1cs --- bin/addons/base/ir/workflow/workflow_view.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index db42935b36f..9e9bc47c300 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -34,7 +34,9 @@ - + + + From 6cf08db5e37879878659da8f2b134cf66e6e24fe Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Fri, 26 Feb 2010 14:00:41 +0530 Subject: [PATCH 19/38] [IMP]:improved code for diagram view bzr revid: apa@tinyerp.com-20100226083041-qzsttqezrzuuwniz --- bin/addons/base/ir/ir_ui_view.py | 5 +- bin/tools/graph.py | 495 ++++++++++++++++--------------- 2 files changed, 251 insertions(+), 249 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index e7be5117828..52631a06990 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -162,8 +162,9 @@ class view(osv.osv): datas = _Model_Obj.read(cr, uid, id, [],context) for a in _Node_Obj.read(cr,uid,datas[_Node_Field],[]): - nodes_name.append((a['id'],a['name'])) - nodes.append(a['id']) + if a[_Source_Field] or a[_Destination_Field]: + nodes_name.append((a['id'],a['name'])) + nodes.append(a['id']) if a.has_key('flow_start') and a['flow_start']: start.append(a['id']) else: diff --git a/bin/tools/graph.py b/bin/tools/graph.py index 7b0375504f2..c0d2194f0ce 100644 --- a/bin/tools/graph.py +++ b/bin/tools/graph.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -16,7 +16,7 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## @@ -26,80 +26,80 @@ import math class graph(object): def __init__(self, nodes, transitions, no_ancester=None): """Initailize graph's object - + @param nodes: list of ids of nodes in the graph @param transitions: list of edges in the graph in the form (source_node, destination_node) - @param no_ancester: list of nodes with no incoming edges + @param no_ancester: list of nodes with no incoming edges """ - + self.nodes = nodes or [] self.edges = transitions or [] self.no_ancester = no_ancester or {} trans = {} - + for t in transitions: trans.setdefault(t[0], []) trans[t[0]].append(t[1]) self.transitions = trans self.result = {} - - + + def init_rank(self): """Computes rank of the nodes of the graph by finding initial feasible tree """ self.edge_wt = {} for link in self.links: self.edge_wt[link] = self.result[link[1]]['x'] - self.result[link[0]]['x'] - + tot_node = self.partial_order.__len__() - #do until all the nodes in the component are searched + #do until all the nodes in the component are searched while self.tight_tree()self.edge_wt[edge]-1): slack = self.edge_wt[edge]-1 new_edge = edge - + if new_edge[0] not in self.reachable_nodes: delta = -(self.edge_wt[new_edge]-1) else: delta = self.edge_wt[new_edge]-1 - + for node in self.result: if node in self.reachable_nodes: self.result[node]['x'] += delta - + for edge in self.edge_wt: - self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] - - self.init_cutvalues() - - + self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] + + self.init_cutvalues() + + def tight_tree(self): self.reachable_nodes = [] self.tree_edges = [] - self.reachable_node(self.start) + self.reachable_node(self.start) return self.reachable_nodes.__len__() - - + + def reachable_node(self, node): - """Find the nodes of the graph which are only 1 rank apart from each other + """Find the nodes of the graph which are only 1 rank apart from each other """ - + if node not in self.reachable_nodes: self.reachable_nodes.append(node) for edge in self.edge_wt: @@ -109,27 +109,27 @@ class graph(object): if edge[1] not in self.reachable_nodes: self.reachable_nodes.append(edge[1]) self.reachable_node(edge[1]) - - + + def init_cutvalues(self): """Initailize cut values of edges of the feasible tree. - Edges with negative cut-values are removed from the tree to optimize rank assignment + Edges with negative cut-values are removed from the tree to optimize rank assignment """ self.cut_edges = {} self.head_nodes = [] i=0; - + for edge in self.tree_edges: self.head_nodes = [] rest_edges = [] rest_edges += self.tree_edges rest_edges.__delitem__(i) - self.head_component(self.start, rest_edges) + self.head_component(self.start, rest_edges) i+=1 positive = 0 negative = 0 for source_node in self.transitions: - if source_node in self.head_nodes: + if source_node in self.head_nodes: for dest_node in self.transitions[source_node]: if dest_node not in self.head_nodes: negative+=1 @@ -140,62 +140,62 @@ class graph(object): self.cut_edges[edge] = positive - negative - + def head_component(self, node, rest_edges): """Find nodes which are reachable from the starting node, after removing an edge """ if node not in self.head_nodes: self.head_nodes.append(node) - + for edge in rest_edges: - if edge[0]==node: + if edge[0]==node: self.head_component(edge[1],rest_edges) - + def process_ranking(self, node, level=0): """Computes initial feasible ranking after making graph acyclic with depth-first search """ - + if node not in self.result: self.result[node] = {'y': None, 'x':level, 'mark':0} else: if level > self.result[node]['x']: self.result[node]['x'] = level - + if self.result[node]['mark']==0: self.result[node]['mark'] = 1 for sec_end in self.transitions.get(node, []): self.process_ranking(sec_end, level+1) - - + + def make_acyclic(self, parent, node, level, tree): """Computes Partial-order of the nodes with depth-first search """ - + if node not in self.partial_order: self.partial_order[node] = {'level':level, 'mark':0} if parent: tree.append((parent, node)) - + if self.partial_order[node]['mark']==0: self.partial_order[node]['mark'] = 1 for sec_end in self.transitions.get(node, []): self.links.append((node, sec_end)) self.make_acyclic(node, sec_end, level+1, tree) - return tree + return tree + - def rev_edges(self, tree): - """reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order - to make the graph acyclic + """reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order + to make the graph acyclic """ Is_Cyclic = False - i=0 + i=0 for link in self.links: src = link[0] des = link[1] - edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level'] + edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level'] if edge_len < 0: self.links.__delitem__(i) self.links.insert(i, (des, src)) @@ -205,9 +205,9 @@ class graph(object): elif math.fabs(edge_len) > 1: Is_Cyclic = True i += 1 - + return Is_Cyclic - + def exchange(self, e, f): """Exchange edges to make feasible-tree optimized @param edge: edge with negative cut-value @@ -216,144 +216,144 @@ class graph(object): self.tree_edges.__delitem__(self.tree_edges.index(e)) self.tree_edges.append(f) self.init_cutvalues() - - + + def enter_edge(self, edge): - """Finds a new_edge with minimum slack value to replace an edge with negative cut-value - - @param edge: edge with negative cut-value + """Finds a new_edge with minimum slack value to replace an edge with negative cut-value + + @param edge: edge with negative cut-value """ - + self.head_nodes = [] rest_edges = [] rest_edges += self.tree_edges rest_edges.__delitem__(rest_edges.index(edge)) self.head_component(self.start, rest_edges) - + if self.head_nodes.__contains__(edge[1]): l = [] for node in self.result: if not self.head_nodes.__contains__(node): - l.append(node) + l.append(node) self.head_nodes = l - + slack = 100 new_edge = edge for source_node in self.transitions: - if source_node in self.head_nodes: + if source_node in self.head_nodes: for dest_node in self.transitions[source_node]: if dest_node not in self.head_nodes: if(slack>(self.edge_wt[edge]-1)): slack = self.edge_wt[edge]-1 new_edge = (source_node, dest_node) - - return new_edge - + + return new_edge + def leave_edge(self): - """Returns the edge with negative cut_value(if exists) + """Returns the edge with negative cut_value(if exists) """ if self.critical_edges: for edge in self.critical_edges: self.cut_edges[edge] = 0 - + for edge in self.cut_edges: if self.cut_edges[edge]<0: return edge - - return None - - + + return None + + def finalize_rank(self, node, level): self.result[node]['x'] = level for destination in self.optimal_edges.get(node, []): self.finalize_rank(destination, level+1) - - + + def normalize(self): """The ranks are normalized by setting the least rank to zero. """ - + least_rank = min(map(lambda x: x['x'], self.result.values())) - + if(least_rank!=0): for node in self.result: - self.result[node]['x']-=least_rank - - - def make_chain(self): - """Edges between nodes more than one rank apart are replaced by chains of unit + self.result[node]['x']-=least_rank + + + def make_chain(self): + """Edges between nodes more than one rank apart are replaced by chains of unit length edges between temporary nodes. """ - + for edge in self.edge_wt: if self.edge_wt[edge]>1: self.transitions[edge[0]].remove(edge[1]) start = self.result[edge[0]]['x'] end = self.result[edge[1]]['x'] - - for rank in range(start+1, end): - if not self.result.get((rank, 'temp'), False): + + for rank in range(start+1, end): + if not self.result.get((rank, 'temp'), False): self.result[(rank, 'temp')] = {'y': None, 'x': rank, 'mark': 0} - + for rank in range(start, end): - if start==rank: + if start==rank: self.transitions[edge[0]].append((rank+1, 'temp')) elif rank==end-1: self.transitions.setdefault((rank, 'temp'), []).append(edge[1]) else: - self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp')) - - + self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp')) + + def init_order(self, node, level): """Initialize orders the nodes in each rank with depth-first search - """ - if not self.result[node]['y']: + """ + if not self.result[node]['y']: self.result[node]['y'] = self.order[level] - self.order[level] = self.order[level]+1 - + self.order[level] = self.order[level]+1 + for sec_end in self.transitions.get(node, []): self.init_order(sec_end, self.result[sec_end]['x']) - - + + def order_heuristic(self): for i in range(12): self.wmedian() - - + + def wmedian(self): """Applies median heuristic to find optimzed order of the nodes with in their ranks """ - for level in self.levels: - + for level in self.levels: + node_median = [] - nodes = self.levels[level] - for node in nodes: + nodes = self.levels[level] + for node in nodes: node_median.append((node, self.median_value(node, level-1))) sort_list = sorted(node_median, key=operator.itemgetter(1)) new_list = [tuple[0] for tuple in sort_list] - + self.levels[level] = new_list order = 0 for node in nodes: self.result[node]['y'] = order - order +=1 + order +=1 def median_value(self, node, adj_rank): - """Returns median value of a vertex , defined as the median position of the adjacent vertices - - @param node: node to process - @param adj_rank: rank 1 less than the node's rank + """Returns median value of a vertex , defined as the median position of the adjacent vertices + + @param node: node to process + @param adj_rank: rank 1 less than the node's rank """ adj_nodes = self.adj_position(node, adj_rank) l = len(adj_nodes) m = l/2 - + if l==0: - return -1.0 + return -1.0 elif l%2 == 1: return adj_nodes[m]#median of the middle element elif l==2: @@ -361,106 +361,106 @@ class graph(object): else: left = adj_nodes[m-1] - adj_nodes[0] right = adj_nodes[l-1] - adj_nodes[m] - return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right) - - + return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right) + + def adj_position(self, node, adj_rank): """Returns list of the present positions of the nodes adjacent to node in the given adjacent rank. - - @param node: node to process - @param adj_rank: rank 1 less than the node's rank + + @param node: node to process + @param adj_rank: rank 1 less than the node's rank """ - - pre_level_nodes = self.levels.get(adj_rank, []) + + pre_level_nodes = self.levels.get(adj_rank, []) adj_nodes = [] - + if pre_level_nodes: for src in pre_level_nodes: if (self.transitions.get(src) and self.transitions[src].__contains__(node)): adj_nodes.append(self.result[src]['y']) - - return adj_nodes - - + + return adj_nodes + + def preprocess_order(self): levels = {} - + for r in self.partial_order: l = self.result[r]['x'] levels.setdefault(l,[]) levels[l].append(r) - + self.levels = levels - - - def graph_order(self): - """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component + + + def graph_order(self): + """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component """ - mid_pos = None + mid_pos = 0.0 max_level = max(map(lambda x: len(x), self.levels.values())) - + for level in self.levels: if level: no = len(self.levels[level]) - factor = (max_level - no) * 0.10 - list = self.levels[level] + factor = (max_level - no) * 0.10 + list = self.levels[level] list.reverse() - + if no%2==0: first_half = list[no/2:] - factor = -factor + factor = -factor else: first_half = list[no/2+1:] if max_level==1:#for the case when horizontal graph is there self.result[list[no/2]]['y'] = mid_pos + (self.result[list[no/2]]['x']%2 * 0.5) else: self.result[list[no/2]]['y'] = mid_pos + factor - - last_half = list[:no/2] - + + last_half = list[:no/2] + i=1 for node in first_half: self.result[node]['y'] = mid_pos - (i + factor) i += 1 - + i=1 for node in last_half: self.result[node]['y'] = mid_pos + (i + factor) i += 1 - else: + else: self.max_order += max_level+1 - mid_pos = self.result[self.start]['y'] - + mid_pos = self.result[self.start]['y'] + def tree_order(self, node, last=0): mid_pos = self.result[node]['y'] l = self.transitions.get(node, []) l.reverse() no = len(l) - + if no%2==0: - first_half = l[no/2:] - factor = 1 + first_half = l[no/2:] + factor = 1 else: first_half = l[no/2+1:] factor = 0 - - last_half = l[:no/2] - + + last_half = l[:no/2] + i=1 for child in first_half: self.result[child]['y'] = mid_pos - (i - (factor * 0.5)) i += 1 - + if self.transitions.get(child, False): if last: self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 last = self.tree_order(child, last) - + if no%2: mid_node = l[no/2] - self.result[mid_node]['y'] = mid_pos - + self.result[mid_node]['y'] = mid_pos + if self.transitions.get((mid_node), False): if last: self.result[mid_node]['y'] = last + len(self.transitions[mid_node])/2 + 1 @@ -469,51 +469,51 @@ class graph(object): if last: self.result[mid_node]['y'] = last + 1 self.result[node]['y'] = self.result[mid_node]['y'] - mid_pos = self.result[node]['y'] - - i=1 + mid_pos = self.result[node]['y'] + + i=1 last_child = None - for child in last_half: + for child in last_half: self.result[child]['y'] = mid_pos + (i - (factor * 0.5)) - last_child = child + last_child = child i += 1 if self.transitions.get(child, False): if last: - self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 + self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 last = self.tree_order(child, last) - + if last_child: last = self.result[last_child]['y'] - - return last - - - def process_order(self): - """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component + + return last + + + def process_order(self): + """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component """ - + if self.Is_Cyclic: max_level = max(map(lambda x: len(x), self.levels.values())) - + if max_level%2: self.result[self.start]['y'] = (max_level+1)/2 + self.max_order + (self.max_order and 1) else: self.result[self.start]['y'] = (max_level)/2 + self.max_order + (self.max_order and 1) - + self.graph_order() - - else: - self.result[self.start]['y'] = 0 + + else: + self.result[self.start]['y'] = 0 self.tree_order(self.start, 0) min_order = math.fabs(min(map(lambda x: x['y'], self.result.values()))) - - index = self.start_nodes.index(self.start) + + index = self.start_nodes.index(self.start) same = False - + roots = [] - if index>0: + if index>0: for start in self.start_nodes[:index]: - same = True + same = True for edge in self.tree_list[start][1:]: if self.tree_list[self.start].__contains__(edge): continue @@ -522,46 +522,48 @@ class graph(object): break if same: roots.append(start) - - if roots: - min_order += self.max_order + + if roots: + min_order += self.max_order else: min_order += self.max_order + 1 - + for level in self.levels: for node in self.levels[level]: self.result[node]['y'] += min_order - + if roots: roots.append(self.start) + print "self.start==>",self.start + print "self.tree_list==>",self.tree_list one_level_el = self.tree_list[self.start][0][1] base = self.result[one_level_el]['y']# * 2 / (index + 2) - - + + no = len(roots) first_half = roots[:no/2] - + if no%2==0: last_half = roots[no/2:] else: last_half = roots[no/2+1:] - + factor = -math.floor(no/2) for start in first_half: - self.result[start]['y'] = base + factor + self.result[start]['y'] = base + factor factor += 1 - + if no%2: self.result[roots[no/2]]['y'] = base + factor factor +=1 - + for start in last_half: - self.result[start]['y'] = base + factor + self.result[start]['y'] = base + factor factor += 1 - + self.max_order = max(map(lambda x: x['y'], self.result.values())) - - def find_starts(self): + + def find_starts(self): """Finds other start nodes of the graph in the case when graph is disconneted """ rem_nodes = [] @@ -577,7 +579,7 @@ class graph(object): count = 0 new_start = rem_nodes[0] largest_tree = [] - + for node in rem_nodes: self.partial_order = {} tree = self.make_acyclic(None, node, 0, []) @@ -589,120 +591,119 @@ class graph(object): if not largest_tree: new_start = rem_nodes[0] rem_nodes.remove(new_start) - + self.start_nodes.append(new_start) - - + + for edge in largest_tree: if rem_nodes.__contains__(edge[0]): rem_nodes.remove(edge[0]) if rem_nodes.__contains__(edge[1]): rem_nodes.remove(edge[1]) - + if not rem_nodes: break - + def rank(self): """Finds the optimized rank of the nodes using Network-simplex algorithm - + @param start: starting node of the component """ - self.levels = {} + self.levels = {} self.critical_edges = [] self.partial_order = {} self.links = [] self.Is_Cyclic = False - + self.tree_list[self.start] = self.make_acyclic(None, self.start, 0, []) - self.Is_Cyclic = self.rev_edges(self.tree_list[self.start]) + self.Is_Cyclic = self.rev_edges(self.tree_list[self.start]) self.process_ranking(self.start) self.init_rank() - + #make cut values of all tree edges to 0 to optimize feasible tree - e = self.leave_edge() - + e = self.leave_edge() + while e : f = self.enter_edge(e) if e==f: self.critical_edges.append(e) else: - self.exchange(e,f) + self.exchange(e,f) e = self.leave_edge() - + #finalize rank using optimum feasible tree # self.optimal_edges = {} # for edge in self.tree_edges: # source = self.optimal_edges.setdefault(edge[0], []) # source.append(edge[1]) - + # self.finalize_rank(self.start, 0) - + #normalization - self.normalize() + self.normalize() for edge in self.edge_wt: self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] - + def order_in_rank(self): """Finds optimized order of the nodes within their ranks using median heuristic - - @param start: starting node of the component + + @param start: starting node of the component """ - + self.make_chain() self.preprocess_order() self.order = {} max_rank = max(map(lambda x: x, self.levels.keys())) - + for i in range(max_rank+1): self.order[i] = 0 - + self.init_order(self.start, self.result[self.start]['x']) - + for level in self.levels: self.levels[level].sort(lambda x, y: cmp(self.result[x]['y'], self.result[y]['y'])) - - self.order_heuristic() + + self.order_heuristic() self.process_order() - + def process(self, starting_node): """Process the graph to find ranks and order of the nodes - - @param starting_node: node from where to start the graph search + + @param starting_node: node from where to start the graph search """ - + self.start_nodes = starting_node or [] - self.partial_order = {} - self.links = [] - self.tree_list = {} - + self.partial_order = {} + self.links = [] + self.tree_list = {} + if self.nodes: if self.start_nodes: #add dummy edges to the nodes which does not have any incoming edges tree = self.make_acyclic(None, self.start_nodes[0], 0, []) - for node in self.no_ancester: for sec_node in self.transitions.get(node, []): if sec_node in self.partial_order.keys(): self.transitions[self.start_nodes[0]].append(node) break - + self.partial_order = {} tree = self.make_acyclic(None, self.start_nodes[0], 0, []) - - - # if graph is disconnected or no start-node is given - #than to find starting_node for each component of the node + + + # if graph is disconnected or no start-node is given + #than to find starting_node for each component of the node if len(self.nodes) > len(self.partial_order): - self.find_starts() - - self.max_order = 0 + self.find_starts() + + self.max_order = 0 #for each component of the graph find ranks and order of the nodes - for s in self.start_nodes: + for s in self.start_nodes: self.start = s self.rank() # First step:Netwoek simplex algorithm - self.order_in_rank() #Second step: ordering nodes within ranks - + self.order_in_rank() #Second step: ordering nodes within ranks + def __str__(self): result = '' @@ -716,21 +717,21 @@ class graph(object): def scale(self, maxx, maxy, nwidth=0, nheight=0, margin=20): """Computes actual co-ordiantes of the nodes """ - + #for flat edges ie. source an destination nodes are on the same rank for src in self.transitions: for des in self.transitions[src]: - if (self.result[des]['x'] - self.result[src]['x'] == 0): + if (self.result[des]['x'] - self.result[src]['x'] == 0): self.result[src]['x'] += 0.08 self.result[des]['x'] -= 0.08 - + factorX = maxx + nheight - factorY = maxy + nwidth - + factorY = maxy + nwidth + for node in self.result: self.result[node]['y'] = (self.result[node]['y']) * factorX + margin self.result[node]['x'] = (self.result[node]['x']) * factorY + margin - + def result_get(self): return self.result @@ -763,14 +764,14 @@ if __name__=='__main__': import ImageDraw img = Image.new("RGB", (800, 600), "#ffffff") draw = ImageDraw.Draw(img) - + result = g.result_get() node_res = {} for node in nodes: node_res[node] = result[node] - + for name,node in node_res.items(): - + draw.arc( (int(node['y']-radius), int(node['x']-radius),int(node['y']+radius), int(node['x']+radius) ), 0, 360, (128,128,128)) draw.text( (int(node['y']), int(node['x'])), name, (128,128,128)) From 878ef36359d3b5281e3626cdf8ba534df9da858b Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Fri, 26 Feb 2010 14:16:15 +0530 Subject: [PATCH 20/38] Remove print statement bzr revid: ysa@tinyerp.co.in-20100226084615-9ehu6ybx7m7w4rfb --- bin/tools/graph.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bin/tools/graph.py b/bin/tools/graph.py index c0d2194f0ce..e25d1c710e0 100644 --- a/bin/tools/graph.py +++ b/bin/tools/graph.py @@ -534,8 +534,6 @@ class graph(object): if roots: roots.append(self.start) - print "self.start==>",self.start - print "self.tree_list==>",self.tree_list one_level_el = self.tree_list[self.start][0][1] base = self.result[one_level_el]['y']# * 2 / (index + 2) From c77153ce30deab2f70dde5c984ffe349b8dfc694 Mon Sep 17 00:00:00 2001 From: "Ysa (Open ERP)" Date: Fri, 26 Feb 2010 15:23:21 +0530 Subject: [PATCH 21/38] [IMP] diagram:- blank node pass client side bzr revid: ysa@tinyerp.co.in-20100226095321-1p7wtfq4cm03g56v --- bin/addons/base/ir/ir_ui_view.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/addons/base/ir/ir_ui_view.py b/bin/addons/base/ir/ir_ui_view.py index 52631a06990..95ce993c8b1 100644 --- a/bin/addons/base/ir/ir_ui_view.py +++ b/bin/addons/base/ir/ir_ui_view.py @@ -140,6 +140,7 @@ class view(osv.osv): tres={} sig={} no_ancester=[] + blank_nodes = [] _Model_Obj=self.pool.get(model) _Node_Obj=self.pool.get(node_obj) @@ -165,6 +166,9 @@ class view(osv.osv): if a[_Source_Field] or a[_Destination_Field]: nodes_name.append((a['id'],a['name'])) nodes.append(a['id']) + else: + blank_nodes.append({'id': a['id'],'name':a['name']}) + if a.has_key('flow_start') and a['flow_start']: start.append(a['id']) else: @@ -184,7 +188,7 @@ class view(osv.osv): for node in nodes_name: results[str(node[0])] = result[node[0]] results[str(node[0])]['name'] = node[1] - return {'nodes': results, 'transitions': tres, 'signal' : sig} + return {'nodes': results, 'transitions': tres, 'signal' : sig, 'blank_nodes': blank_nodes} view() class view_sc(osv.osv): From f22c3eb50f2335db7dfb5ab745881694791f5b38 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Fri, 26 Feb 2010 18:19:38 +0530 Subject: [PATCH 22/38] [IMP]:improved view bzr revid: apa@tinyerp.com-20100226124938-h38kbfnyoy4m9ho8 --- bin/addons/base/ir/workflow/workflow_view.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/addons/base/ir/workflow/workflow_view.xml b/bin/addons/base/ir/workflow/workflow_view.xml index 9e9bc47c300..04457f21338 100644 --- a/bin/addons/base/ir/workflow/workflow_view.xml +++ b/bin/addons/base/ir/workflow/workflow_view.xml @@ -32,8 +32,9 @@ + - + From 2aba47bbcfb561ff9c4681193772efcc1492200e Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Tue, 2 Mar 2010 11:06:17 +0530 Subject: [PATCH 23/38] reverted graph.py bzr revid: apa@tinyerp.com-20100302053617-jdpc1ww462jhwffg --- bin/tools/graph.py | 493 +++++++++++++++++++++++---------------------- 1 file changed, 247 insertions(+), 246 deletions(-) diff --git a/bin/tools/graph.py b/bin/tools/graph.py index e25d1c710e0..7b0375504f2 100644 --- a/bin/tools/graph.py +++ b/bin/tools/graph.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -16,7 +16,7 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## @@ -26,80 +26,80 @@ import math class graph(object): def __init__(self, nodes, transitions, no_ancester=None): """Initailize graph's object - + @param nodes: list of ids of nodes in the graph @param transitions: list of edges in the graph in the form (source_node, destination_node) - @param no_ancester: list of nodes with no incoming edges + @param no_ancester: list of nodes with no incoming edges """ - + self.nodes = nodes or [] self.edges = transitions or [] self.no_ancester = no_ancester or {} trans = {} - + for t in transitions: trans.setdefault(t[0], []) trans[t[0]].append(t[1]) self.transitions = trans self.result = {} - - + + def init_rank(self): """Computes rank of the nodes of the graph by finding initial feasible tree """ self.edge_wt = {} for link in self.links: self.edge_wt[link] = self.result[link[1]]['x'] - self.result[link[0]]['x'] - + tot_node = self.partial_order.__len__() - #do until all the nodes in the component are searched + #do until all the nodes in the component are searched while self.tight_tree()self.edge_wt[edge]-1): slack = self.edge_wt[edge]-1 new_edge = edge - + if new_edge[0] not in self.reachable_nodes: delta = -(self.edge_wt[new_edge]-1) else: delta = self.edge_wt[new_edge]-1 - + for node in self.result: if node in self.reachable_nodes: self.result[node]['x'] += delta - + for edge in self.edge_wt: - self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] - - self.init_cutvalues() - - + self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] + + self.init_cutvalues() + + def tight_tree(self): self.reachable_nodes = [] self.tree_edges = [] - self.reachable_node(self.start) + self.reachable_node(self.start) return self.reachable_nodes.__len__() - - + + def reachable_node(self, node): - """Find the nodes of the graph which are only 1 rank apart from each other + """Find the nodes of the graph which are only 1 rank apart from each other """ - + if node not in self.reachable_nodes: self.reachable_nodes.append(node) for edge in self.edge_wt: @@ -109,27 +109,27 @@ class graph(object): if edge[1] not in self.reachable_nodes: self.reachable_nodes.append(edge[1]) self.reachable_node(edge[1]) - - + + def init_cutvalues(self): """Initailize cut values of edges of the feasible tree. - Edges with negative cut-values are removed from the tree to optimize rank assignment + Edges with negative cut-values are removed from the tree to optimize rank assignment """ self.cut_edges = {} self.head_nodes = [] i=0; - + for edge in self.tree_edges: self.head_nodes = [] rest_edges = [] rest_edges += self.tree_edges rest_edges.__delitem__(i) - self.head_component(self.start, rest_edges) + self.head_component(self.start, rest_edges) i+=1 positive = 0 negative = 0 for source_node in self.transitions: - if source_node in self.head_nodes: + if source_node in self.head_nodes: for dest_node in self.transitions[source_node]: if dest_node not in self.head_nodes: negative+=1 @@ -140,62 +140,62 @@ class graph(object): self.cut_edges[edge] = positive - negative - + def head_component(self, node, rest_edges): """Find nodes which are reachable from the starting node, after removing an edge """ if node not in self.head_nodes: self.head_nodes.append(node) - + for edge in rest_edges: - if edge[0]==node: + if edge[0]==node: self.head_component(edge[1],rest_edges) - + def process_ranking(self, node, level=0): """Computes initial feasible ranking after making graph acyclic with depth-first search """ - + if node not in self.result: self.result[node] = {'y': None, 'x':level, 'mark':0} else: if level > self.result[node]['x']: self.result[node]['x'] = level - + if self.result[node]['mark']==0: self.result[node]['mark'] = 1 for sec_end in self.transitions.get(node, []): self.process_ranking(sec_end, level+1) - - + + def make_acyclic(self, parent, node, level, tree): """Computes Partial-order of the nodes with depth-first search """ - + if node not in self.partial_order: self.partial_order[node] = {'level':level, 'mark':0} if parent: tree.append((parent, node)) - + if self.partial_order[node]['mark']==0: self.partial_order[node]['mark'] = 1 for sec_end in self.transitions.get(node, []): self.links.append((node, sec_end)) self.make_acyclic(node, sec_end, level+1, tree) - return tree - + return tree + def rev_edges(self, tree): - """reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order - to make the graph acyclic + """reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order + to make the graph acyclic """ Is_Cyclic = False - i=0 + i=0 for link in self.links: src = link[0] des = link[1] - edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level'] + edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level'] if edge_len < 0: self.links.__delitem__(i) self.links.insert(i, (des, src)) @@ -205,9 +205,9 @@ class graph(object): elif math.fabs(edge_len) > 1: Is_Cyclic = True i += 1 - + return Is_Cyclic - + def exchange(self, e, f): """Exchange edges to make feasible-tree optimized @param edge: edge with negative cut-value @@ -216,144 +216,144 @@ class graph(object): self.tree_edges.__delitem__(self.tree_edges.index(e)) self.tree_edges.append(f) self.init_cutvalues() - - + + def enter_edge(self, edge): - """Finds a new_edge with minimum slack value to replace an edge with negative cut-value - - @param edge: edge with negative cut-value + """Finds a new_edge with minimum slack value to replace an edge with negative cut-value + + @param edge: edge with negative cut-value """ - + self.head_nodes = [] rest_edges = [] rest_edges += self.tree_edges rest_edges.__delitem__(rest_edges.index(edge)) self.head_component(self.start, rest_edges) - + if self.head_nodes.__contains__(edge[1]): l = [] for node in self.result: if not self.head_nodes.__contains__(node): - l.append(node) + l.append(node) self.head_nodes = l - + slack = 100 new_edge = edge for source_node in self.transitions: - if source_node in self.head_nodes: + if source_node in self.head_nodes: for dest_node in self.transitions[source_node]: if dest_node not in self.head_nodes: if(slack>(self.edge_wt[edge]-1)): slack = self.edge_wt[edge]-1 new_edge = (source_node, dest_node) - - return new_edge - + + return new_edge + def leave_edge(self): - """Returns the edge with negative cut_value(if exists) + """Returns the edge with negative cut_value(if exists) """ if self.critical_edges: for edge in self.critical_edges: self.cut_edges[edge] = 0 - + for edge in self.cut_edges: if self.cut_edges[edge]<0: return edge - - return None - - + + return None + + def finalize_rank(self, node, level): self.result[node]['x'] = level for destination in self.optimal_edges.get(node, []): self.finalize_rank(destination, level+1) - - + + def normalize(self): """The ranks are normalized by setting the least rank to zero. """ - + least_rank = min(map(lambda x: x['x'], self.result.values())) - + if(least_rank!=0): for node in self.result: - self.result[node]['x']-=least_rank - - - def make_chain(self): - """Edges between nodes more than one rank apart are replaced by chains of unit + self.result[node]['x']-=least_rank + + + def make_chain(self): + """Edges between nodes more than one rank apart are replaced by chains of unit length edges between temporary nodes. """ - + for edge in self.edge_wt: if self.edge_wt[edge]>1: self.transitions[edge[0]].remove(edge[1]) start = self.result[edge[0]]['x'] end = self.result[edge[1]]['x'] - - for rank in range(start+1, end): - if not self.result.get((rank, 'temp'), False): + + for rank in range(start+1, end): + if not self.result.get((rank, 'temp'), False): self.result[(rank, 'temp')] = {'y': None, 'x': rank, 'mark': 0} - + for rank in range(start, end): - if start==rank: + if start==rank: self.transitions[edge[0]].append((rank+1, 'temp')) elif rank==end-1: self.transitions.setdefault((rank, 'temp'), []).append(edge[1]) else: - self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp')) - - + self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp')) + + def init_order(self, node, level): """Initialize orders the nodes in each rank with depth-first search - """ - if not self.result[node]['y']: + """ + if not self.result[node]['y']: self.result[node]['y'] = self.order[level] - self.order[level] = self.order[level]+1 - + self.order[level] = self.order[level]+1 + for sec_end in self.transitions.get(node, []): self.init_order(sec_end, self.result[sec_end]['x']) - - + + def order_heuristic(self): for i in range(12): self.wmedian() - - + + def wmedian(self): """Applies median heuristic to find optimzed order of the nodes with in their ranks """ - for level in self.levels: - + for level in self.levels: + node_median = [] - nodes = self.levels[level] - for node in nodes: + nodes = self.levels[level] + for node in nodes: node_median.append((node, self.median_value(node, level-1))) sort_list = sorted(node_median, key=operator.itemgetter(1)) new_list = [tuple[0] for tuple in sort_list] - + self.levels[level] = new_list order = 0 for node in nodes: self.result[node]['y'] = order - order +=1 + order +=1 def median_value(self, node, adj_rank): - """Returns median value of a vertex , defined as the median position of the adjacent vertices - - @param node: node to process - @param adj_rank: rank 1 less than the node's rank + """Returns median value of a vertex , defined as the median position of the adjacent vertices + + @param node: node to process + @param adj_rank: rank 1 less than the node's rank """ adj_nodes = self.adj_position(node, adj_rank) l = len(adj_nodes) m = l/2 - + if l==0: - return -1.0 + return -1.0 elif l%2 == 1: return adj_nodes[m]#median of the middle element elif l==2: @@ -361,106 +361,106 @@ class graph(object): else: left = adj_nodes[m-1] - adj_nodes[0] right = adj_nodes[l-1] - adj_nodes[m] - return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right) - - + return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right) + + def adj_position(self, node, adj_rank): """Returns list of the present positions of the nodes adjacent to node in the given adjacent rank. - - @param node: node to process - @param adj_rank: rank 1 less than the node's rank + + @param node: node to process + @param adj_rank: rank 1 less than the node's rank """ - - pre_level_nodes = self.levels.get(adj_rank, []) + + pre_level_nodes = self.levels.get(adj_rank, []) adj_nodes = [] - + if pre_level_nodes: for src in pre_level_nodes: if (self.transitions.get(src) and self.transitions[src].__contains__(node)): adj_nodes.append(self.result[src]['y']) - - return adj_nodes - - + + return adj_nodes + + def preprocess_order(self): levels = {} - + for r in self.partial_order: l = self.result[r]['x'] levels.setdefault(l,[]) levels[l].append(r) - + self.levels = levels - - - def graph_order(self): - """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component + + + def graph_order(self): + """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component """ - mid_pos = 0.0 + mid_pos = None max_level = max(map(lambda x: len(x), self.levels.values())) - + for level in self.levels: if level: no = len(self.levels[level]) - factor = (max_level - no) * 0.10 - list = self.levels[level] + factor = (max_level - no) * 0.10 + list = self.levels[level] list.reverse() - + if no%2==0: first_half = list[no/2:] - factor = -factor + factor = -factor else: first_half = list[no/2+1:] if max_level==1:#for the case when horizontal graph is there self.result[list[no/2]]['y'] = mid_pos + (self.result[list[no/2]]['x']%2 * 0.5) else: self.result[list[no/2]]['y'] = mid_pos + factor - - last_half = list[:no/2] - + + last_half = list[:no/2] + i=1 for node in first_half: self.result[node]['y'] = mid_pos - (i + factor) i += 1 - + i=1 for node in last_half: self.result[node]['y'] = mid_pos + (i + factor) i += 1 - else: + else: self.max_order += max_level+1 - mid_pos = self.result[self.start]['y'] - + mid_pos = self.result[self.start]['y'] + def tree_order(self, node, last=0): mid_pos = self.result[node]['y'] l = self.transitions.get(node, []) l.reverse() no = len(l) - + if no%2==0: - first_half = l[no/2:] - factor = 1 + first_half = l[no/2:] + factor = 1 else: first_half = l[no/2+1:] factor = 0 - - last_half = l[:no/2] - + + last_half = l[:no/2] + i=1 for child in first_half: self.result[child]['y'] = mid_pos - (i - (factor * 0.5)) i += 1 - + if self.transitions.get(child, False): if last: self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 last = self.tree_order(child, last) - + if no%2: mid_node = l[no/2] - self.result[mid_node]['y'] = mid_pos - + self.result[mid_node]['y'] = mid_pos + if self.transitions.get((mid_node), False): if last: self.result[mid_node]['y'] = last + len(self.transitions[mid_node])/2 + 1 @@ -469,51 +469,51 @@ class graph(object): if last: self.result[mid_node]['y'] = last + 1 self.result[node]['y'] = self.result[mid_node]['y'] - mid_pos = self.result[node]['y'] - - i=1 + mid_pos = self.result[node]['y'] + + i=1 last_child = None - for child in last_half: + for child in last_half: self.result[child]['y'] = mid_pos + (i - (factor * 0.5)) - last_child = child + last_child = child i += 1 if self.transitions.get(child, False): if last: - self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 + self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 last = self.tree_order(child, last) - + if last_child: last = self.result[last_child]['y'] - - return last - - - def process_order(self): - """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component + + return last + + + def process_order(self): + """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component """ - + if self.Is_Cyclic: max_level = max(map(lambda x: len(x), self.levels.values())) - + if max_level%2: self.result[self.start]['y'] = (max_level+1)/2 + self.max_order + (self.max_order and 1) else: self.result[self.start]['y'] = (max_level)/2 + self.max_order + (self.max_order and 1) - + self.graph_order() - - else: - self.result[self.start]['y'] = 0 + + else: + self.result[self.start]['y'] = 0 self.tree_order(self.start, 0) min_order = math.fabs(min(map(lambda x: x['y'], self.result.values()))) - - index = self.start_nodes.index(self.start) + + index = self.start_nodes.index(self.start) same = False - + roots = [] - if index>0: + if index>0: for start in self.start_nodes[:index]: - same = True + same = True for edge in self.tree_list[start][1:]: if self.tree_list[self.start].__contains__(edge): continue @@ -522,46 +522,46 @@ class graph(object): break if same: roots.append(start) - - if roots: - min_order += self.max_order + + if roots: + min_order += self.max_order else: min_order += self.max_order + 1 - + for level in self.levels: for node in self.levels[level]: self.result[node]['y'] += min_order - + if roots: roots.append(self.start) one_level_el = self.tree_list[self.start][0][1] base = self.result[one_level_el]['y']# * 2 / (index + 2) - - + + no = len(roots) first_half = roots[:no/2] - + if no%2==0: last_half = roots[no/2:] else: last_half = roots[no/2+1:] - + factor = -math.floor(no/2) for start in first_half: - self.result[start]['y'] = base + factor + self.result[start]['y'] = base + factor factor += 1 - + if no%2: self.result[roots[no/2]]['y'] = base + factor factor +=1 - + for start in last_half: - self.result[start]['y'] = base + factor + self.result[start]['y'] = base + factor factor += 1 - + self.max_order = max(map(lambda x: x['y'], self.result.values())) - - def find_starts(self): + + def find_starts(self): """Finds other start nodes of the graph in the case when graph is disconneted """ rem_nodes = [] @@ -577,7 +577,7 @@ class graph(object): count = 0 new_start = rem_nodes[0] largest_tree = [] - + for node in rem_nodes: self.partial_order = {} tree = self.make_acyclic(None, node, 0, []) @@ -589,119 +589,120 @@ class graph(object): if not largest_tree: new_start = rem_nodes[0] rem_nodes.remove(new_start) - + self.start_nodes.append(new_start) - - + + for edge in largest_tree: if rem_nodes.__contains__(edge[0]): rem_nodes.remove(edge[0]) if rem_nodes.__contains__(edge[1]): rem_nodes.remove(edge[1]) - + if not rem_nodes: break - + def rank(self): """Finds the optimized rank of the nodes using Network-simplex algorithm - + @param start: starting node of the component """ - self.levels = {} + self.levels = {} self.critical_edges = [] self.partial_order = {} self.links = [] self.Is_Cyclic = False - + self.tree_list[self.start] = self.make_acyclic(None, self.start, 0, []) - self.Is_Cyclic = self.rev_edges(self.tree_list[self.start]) + self.Is_Cyclic = self.rev_edges(self.tree_list[self.start]) self.process_ranking(self.start) self.init_rank() - + #make cut values of all tree edges to 0 to optimize feasible tree - e = self.leave_edge() - + e = self.leave_edge() + while e : f = self.enter_edge(e) if e==f: self.critical_edges.append(e) else: - self.exchange(e,f) + self.exchange(e,f) e = self.leave_edge() - + #finalize rank using optimum feasible tree # self.optimal_edges = {} # for edge in self.tree_edges: # source = self.optimal_edges.setdefault(edge[0], []) # source.append(edge[1]) - + # self.finalize_rank(self.start, 0) - + #normalization - self.normalize() + self.normalize() for edge in self.edge_wt: self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] - + def order_in_rank(self): """Finds optimized order of the nodes within their ranks using median heuristic - - @param start: starting node of the component + + @param start: starting node of the component """ - + self.make_chain() self.preprocess_order() self.order = {} max_rank = max(map(lambda x: x, self.levels.keys())) - + for i in range(max_rank+1): self.order[i] = 0 - + self.init_order(self.start, self.result[self.start]['x']) - + for level in self.levels: self.levels[level].sort(lambda x, y: cmp(self.result[x]['y'], self.result[y]['y'])) - - self.order_heuristic() + + self.order_heuristic() self.process_order() - + def process(self, starting_node): """Process the graph to find ranks and order of the nodes - - @param starting_node: node from where to start the graph search + + @param starting_node: node from where to start the graph search """ - + self.start_nodes = starting_node or [] - self.partial_order = {} - self.links = [] - self.tree_list = {} - + self.partial_order = {} + self.links = [] + self.tree_list = {} + if self.nodes: if self.start_nodes: #add dummy edges to the nodes which does not have any incoming edges tree = self.make_acyclic(None, self.start_nodes[0], 0, []) + for node in self.no_ancester: for sec_node in self.transitions.get(node, []): if sec_node in self.partial_order.keys(): self.transitions[self.start_nodes[0]].append(node) break - + self.partial_order = {} tree = self.make_acyclic(None, self.start_nodes[0], 0, []) - - - # if graph is disconnected or no start-node is given - #than to find starting_node for each component of the node + + + # if graph is disconnected or no start-node is given + #than to find starting_node for each component of the node if len(self.nodes) > len(self.partial_order): - self.find_starts() - - self.max_order = 0 + self.find_starts() + + self.max_order = 0 #for each component of the graph find ranks and order of the nodes - for s in self.start_nodes: + for s in self.start_nodes: self.start = s self.rank() # First step:Netwoek simplex algorithm - self.order_in_rank() #Second step: ordering nodes within ranks - + self.order_in_rank() #Second step: ordering nodes within ranks + def __str__(self): result = '' @@ -715,21 +716,21 @@ class graph(object): def scale(self, maxx, maxy, nwidth=0, nheight=0, margin=20): """Computes actual co-ordiantes of the nodes """ - + #for flat edges ie. source an destination nodes are on the same rank for src in self.transitions: for des in self.transitions[src]: - if (self.result[des]['x'] - self.result[src]['x'] == 0): + if (self.result[des]['x'] - self.result[src]['x'] == 0): self.result[src]['x'] += 0.08 self.result[des]['x'] -= 0.08 - + factorX = maxx + nheight - factorY = maxy + nwidth - + factorY = maxy + nwidth + for node in self.result: self.result[node]['y'] = (self.result[node]['y']) * factorX + margin self.result[node]['x'] = (self.result[node]['x']) * factorY + margin - + def result_get(self): return self.result @@ -762,14 +763,14 @@ if __name__=='__main__': import ImageDraw img = Image.new("RGB", (800, 600), "#ffffff") draw = ImageDraw.Draw(img) - + result = g.result_get() node_res = {} for node in nodes: node_res[node] = result[node] - + for name,node in node_res.items(): - + draw.arc( (int(node['y']-radius), int(node['x']-radius),int(node['y']+radius), int(node['x']+radius) ), 0, 360, (128,128,128)) draw.text( (int(node['y']), int(node['x'])), name, (128,128,128)) From abfe6add89abad9fd202e8aa034b96ad88ae3be2 Mon Sep 17 00:00:00 2001 From: apa-tiny Date: Tue, 2 Mar 2010 11:08:53 +0530 Subject: [PATCH 24/38] improved bzr revid: apa@tinyerp.com-20100302053853-laq7143efs4q4tbu --- bin/tools/graph.py | 494 ++++++++++++++++++++++----------------------- 1 file changed, 247 insertions(+), 247 deletions(-) diff --git a/bin/tools/graph.py b/bin/tools/graph.py index 7b0375504f2..05a1b8302f0 100644 --- a/bin/tools/graph.py +++ b/bin/tools/graph.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). # @@ -16,7 +16,7 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## @@ -26,80 +26,80 @@ import math class graph(object): def __init__(self, nodes, transitions, no_ancester=None): """Initailize graph's object - + @param nodes: list of ids of nodes in the graph @param transitions: list of edges in the graph in the form (source_node, destination_node) - @param no_ancester: list of nodes with no incoming edges + @param no_ancester: list of nodes with no incoming edges """ - + self.nodes = nodes or [] self.edges = transitions or [] self.no_ancester = no_ancester or {} trans = {} - + for t in transitions: trans.setdefault(t[0], []) trans[t[0]].append(t[1]) self.transitions = trans self.result = {} - - + + def init_rank(self): """Computes rank of the nodes of the graph by finding initial feasible tree """ self.edge_wt = {} for link in self.links: self.edge_wt[link] = self.result[link[1]]['x'] - self.result[link[0]]['x'] - + tot_node = self.partial_order.__len__() - #do until all the nodes in the component are searched + #do until all the nodes in the component are searched while self.tight_tree()self.edge_wt[edge]-1): slack = self.edge_wt[edge]-1 new_edge = edge - + if new_edge[0] not in self.reachable_nodes: delta = -(self.edge_wt[new_edge]-1) else: delta = self.edge_wt[new_edge]-1 - + for node in self.result: if node in self.reachable_nodes: self.result[node]['x'] += delta - + for edge in self.edge_wt: - self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] - - self.init_cutvalues() - - + self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] + + self.init_cutvalues() + + def tight_tree(self): self.reachable_nodes = [] self.tree_edges = [] - self.reachable_node(self.start) + self.reachable_node(self.start) return self.reachable_nodes.__len__() - - + + def reachable_node(self, node): - """Find the nodes of the graph which are only 1 rank apart from each other + """Find the nodes of the graph which are only 1 rank apart from each other """ - + if node not in self.reachable_nodes: self.reachable_nodes.append(node) for edge in self.edge_wt: @@ -109,27 +109,27 @@ class graph(object): if edge[1] not in self.reachable_nodes: self.reachable_nodes.append(edge[1]) self.reachable_node(edge[1]) - - + + def init_cutvalues(self): """Initailize cut values of edges of the feasible tree. - Edges with negative cut-values are removed from the tree to optimize rank assignment + Edges with negative cut-values are removed from the tree to optimize rank assignment """ self.cut_edges = {} self.head_nodes = [] i=0; - + for edge in self.tree_edges: self.head_nodes = [] rest_edges = [] rest_edges += self.tree_edges rest_edges.__delitem__(i) - self.head_component(self.start, rest_edges) + self.head_component(self.start, rest_edges) i+=1 positive = 0 negative = 0 for source_node in self.transitions: - if source_node in self.head_nodes: + if source_node in self.head_nodes: for dest_node in self.transitions[source_node]: if dest_node not in self.head_nodes: negative+=1 @@ -140,62 +140,62 @@ class graph(object): self.cut_edges[edge] = positive - negative - + def head_component(self, node, rest_edges): """Find nodes which are reachable from the starting node, after removing an edge """ if node not in self.head_nodes: self.head_nodes.append(node) - + for edge in rest_edges: - if edge[0]==node: + if edge[0]==node: self.head_component(edge[1],rest_edges) - + def process_ranking(self, node, level=0): """Computes initial feasible ranking after making graph acyclic with depth-first search """ - + if node not in self.result: self.result[node] = {'y': None, 'x':level, 'mark':0} else: if level > self.result[node]['x']: self.result[node]['x'] = level - + if self.result[node]['mark']==0: self.result[node]['mark'] = 1 for sec_end in self.transitions.get(node, []): self.process_ranking(sec_end, level+1) - - + + def make_acyclic(self, parent, node, level, tree): """Computes Partial-order of the nodes with depth-first search """ - + if node not in self.partial_order: self.partial_order[node] = {'level':level, 'mark':0} if parent: tree.append((parent, node)) - + if self.partial_order[node]['mark']==0: self.partial_order[node]['mark'] = 1 for sec_end in self.transitions.get(node, []): self.links.append((node, sec_end)) self.make_acyclic(node, sec_end, level+1, tree) - return tree + return tree + - def rev_edges(self, tree): - """reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order - to make the graph acyclic + """reverse the direction of the edges whose source-node-partail_order> destination-node-partail_order + to make the graph acyclic """ Is_Cyclic = False - i=0 + i=0 for link in self.links: src = link[0] des = link[1] - edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level'] + edge_len = self.partial_order[des]['level'] - self.partial_order[src]['level'] if edge_len < 0: self.links.__delitem__(i) self.links.insert(i, (des, src)) @@ -205,9 +205,9 @@ class graph(object): elif math.fabs(edge_len) > 1: Is_Cyclic = True i += 1 - + return Is_Cyclic - + def exchange(self, e, f): """Exchange edges to make feasible-tree optimized @param edge: edge with negative cut-value @@ -216,144 +216,144 @@ class graph(object): self.tree_edges.__delitem__(self.tree_edges.index(e)) self.tree_edges.append(f) self.init_cutvalues() - - + + def enter_edge(self, edge): - """Finds a new_edge with minimum slack value to replace an edge with negative cut-value - - @param edge: edge with negative cut-value + """Finds a new_edge with minimum slack value to replace an edge with negative cut-value + + @param edge: edge with negative cut-value """ - + self.head_nodes = [] rest_edges = [] rest_edges += self.tree_edges rest_edges.__delitem__(rest_edges.index(edge)) self.head_component(self.start, rest_edges) - + if self.head_nodes.__contains__(edge[1]): l = [] for node in self.result: if not self.head_nodes.__contains__(node): - l.append(node) + l.append(node) self.head_nodes = l - + slack = 100 new_edge = edge for source_node in self.transitions: - if source_node in self.head_nodes: + if source_node in self.head_nodes: for dest_node in self.transitions[source_node]: if dest_node not in self.head_nodes: if(slack>(self.edge_wt[edge]-1)): slack = self.edge_wt[edge]-1 new_edge = (source_node, dest_node) - - return new_edge - + + return new_edge + def leave_edge(self): - """Returns the edge with negative cut_value(if exists) + """Returns the edge with negative cut_value(if exists) """ if self.critical_edges: for edge in self.critical_edges: self.cut_edges[edge] = 0 - + for edge in self.cut_edges: if self.cut_edges[edge]<0: return edge - - return None - - + + return None + + def finalize_rank(self, node, level): self.result[node]['x'] = level for destination in self.optimal_edges.get(node, []): self.finalize_rank(destination, level+1) - - + + def normalize(self): """The ranks are normalized by setting the least rank to zero. """ - + least_rank = min(map(lambda x: x['x'], self.result.values())) - + if(least_rank!=0): for node in self.result: - self.result[node]['x']-=least_rank - - - def make_chain(self): - """Edges between nodes more than one rank apart are replaced by chains of unit + self.result[node]['x']-=least_rank + + + def make_chain(self): + """Edges between nodes more than one rank apart are replaced by chains of unit length edges between temporary nodes. """ - + for edge in self.edge_wt: if self.edge_wt[edge]>1: self.transitions[edge[0]].remove(edge[1]) start = self.result[edge[0]]['x'] end = self.result[edge[1]]['x'] - - for rank in range(start+1, end): - if not self.result.get((rank, 'temp'), False): + + for rank in range(start+1, end): + if not self.result.get((rank, 'temp'), False): self.result[(rank, 'temp')] = {'y': None, 'x': rank, 'mark': 0} - + for rank in range(start, end): - if start==rank: + if start==rank: self.transitions[edge[0]].append((rank+1, 'temp')) elif rank==end-1: self.transitions.setdefault((rank, 'temp'), []).append(edge[1]) else: - self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp')) - - + self.transitions.setdefault((rank, 'temp'), []).append((rank+1, 'temp')) + + def init_order(self, node, level): """Initialize orders the nodes in each rank with depth-first search - """ - if not self.result[node]['y']: + """ + if not self.result[node]['y']: self.result[node]['y'] = self.order[level] - self.order[level] = self.order[level]+1 - + self.order[level] = self.order[level]+1 + for sec_end in self.transitions.get(node, []): self.init_order(sec_end, self.result[sec_end]['x']) - - + + def order_heuristic(self): for i in range(12): self.wmedian() - - + + def wmedian(self): """Applies median heuristic to find optimzed order of the nodes with in their ranks """ - for level in self.levels: - + for level in self.levels: + node_median = [] - nodes = self.levels[level] - for node in nodes: + nodes = self.levels[level] + for node in nodes: node_median.append((node, self.median_value(node, level-1))) sort_list = sorted(node_median, key=operator.itemgetter(1)) new_list = [tuple[0] for tuple in sort_list] - + self.levels[level] = new_list order = 0 for node in nodes: self.result[node]['y'] = order - order +=1 + order +=1 def median_value(self, node, adj_rank): - """Returns median value of a vertex , defined as the median position of the adjacent vertices - - @param node: node to process - @param adj_rank: rank 1 less than the node's rank + """Returns median value of a vertex , defined as the median position of the adjacent vertices + + @param node: node to process + @param adj_rank: rank 1 less than the node's rank """ adj_nodes = self.adj_position(node, adj_rank) l = len(adj_nodes) m = l/2 - + if l==0: - return -1.0 + return -1.0 elif l%2 == 1: return adj_nodes[m]#median of the middle element elif l==2: @@ -361,106 +361,106 @@ class graph(object): else: left = adj_nodes[m-1] - adj_nodes[0] right = adj_nodes[l-1] - adj_nodes[m] - return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right) - - + return ((adj_nodes[m-1]*right) + (adj_nodes[m]*left))/(left+right) + + def adj_position(self, node, adj_rank): """Returns list of the present positions of the nodes adjacent to node in the given adjacent rank. - - @param node: node to process - @param adj_rank: rank 1 less than the node's rank + + @param node: node to process + @param adj_rank: rank 1 less than the node's rank """ - - pre_level_nodes = self.levels.get(adj_rank, []) + + pre_level_nodes = self.levels.get(adj_rank, []) adj_nodes = [] - + if pre_level_nodes: for src in pre_level_nodes: if (self.transitions.get(src) and self.transitions[src].__contains__(node)): adj_nodes.append(self.result[src]['y']) - - return adj_nodes - - + + return adj_nodes + + def preprocess_order(self): levels = {} - + for r in self.partial_order: l = self.result[r]['x'] levels.setdefault(l,[]) levels[l].append(r) - + self.levels = levels - - - def graph_order(self): - """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component + + + def graph_order(self): + """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component """ - mid_pos = None + mid_pos = 0.0 max_level = max(map(lambda x: len(x), self.levels.values())) - + for level in self.levels: if level: no = len(self.levels[level]) - factor = (max_level - no) * 0.10 - list = self.levels[level] + factor = (max_level - no) * 0.10 + list = self.levels[level] list.reverse() - + if no%2==0: first_half = list[no/2:] - factor = -factor + factor = -factor else: first_half = list[no/2+1:] if max_level==1:#for the case when horizontal graph is there self.result[list[no/2]]['y'] = mid_pos + (self.result[list[no/2]]['x']%2 * 0.5) else: self.result[list[no/2]]['y'] = mid_pos + factor - - last_half = list[:no/2] - + + last_half = list[:no/2] + i=1 for node in first_half: self.result[node]['y'] = mid_pos - (i + factor) i += 1 - + i=1 for node in last_half: self.result[node]['y'] = mid_pos + (i + factor) i += 1 - else: + else: self.max_order += max_level+1 - mid_pos = self.result[self.start]['y'] - + mid_pos = self.result[self.start]['y'] + def tree_order(self, node, last=0): mid_pos = self.result[node]['y'] l = self.transitions.get(node, []) l.reverse() no = len(l) - + if no%2==0: - first_half = l[no/2:] - factor = 1 + first_half = l[no/2:] + factor = 1 else: first_half = l[no/2+1:] factor = 0 - - last_half = l[:no/2] - + + last_half = l[:no/2] + i=1 for child in first_half: self.result[child]['y'] = mid_pos - (i - (factor * 0.5)) i += 1 - + if self.transitions.get(child, False): if last: self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 last = self.tree_order(child, last) - + if no%2: mid_node = l[no/2] - self.result[mid_node]['y'] = mid_pos - + self.result[mid_node]['y'] = mid_pos + if self.transitions.get((mid_node), False): if last: self.result[mid_node]['y'] = last + len(self.transitions[mid_node])/2 + 1 @@ -469,51 +469,51 @@ class graph(object): if last: self.result[mid_node]['y'] = last + 1 self.result[node]['y'] = self.result[mid_node]['y'] - mid_pos = self.result[node]['y'] - - i=1 + mid_pos = self.result[node]['y'] + + i=1 last_child = None - for child in last_half: + for child in last_half: self.result[child]['y'] = mid_pos + (i - (factor * 0.5)) - last_child = child + last_child = child i += 1 if self.transitions.get(child, False): if last: - self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 + self.result[child]['y'] = last + len(self.transitions[child])/2 + 1 last = self.tree_order(child, last) - + if last_child: last = self.result[last_child]['y'] - - return last - - - def process_order(self): - """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component + + return last + + + def process_order(self): + """Finds actual-order of the nodes with respect to maximum number of nodes in a rank in component """ - + if self.Is_Cyclic: max_level = max(map(lambda x: len(x), self.levels.values())) - + if max_level%2: self.result[self.start]['y'] = (max_level+1)/2 + self.max_order + (self.max_order and 1) else: self.result[self.start]['y'] = (max_level)/2 + self.max_order + (self.max_order and 1) - + self.graph_order() - - else: - self.result[self.start]['y'] = 0 + + else: + self.result[self.start]['y'] = 0 self.tree_order(self.start, 0) min_order = math.fabs(min(map(lambda x: x['y'], self.result.values()))) - - index = self.start_nodes.index(self.start) + + index = self.start_nodes.index(self.start) same = False - + roots = [] - if index>0: + if index>0: for start in self.start_nodes[:index]: - same = True + same = True for edge in self.tree_list[start][1:]: if self.tree_list[self.start].__contains__(edge): continue @@ -522,46 +522,46 @@ class graph(object): break if same: roots.append(start) - - if roots: - min_order += self.max_order + + if roots: + min_order += self.max_order else: min_order += self.max_order + 1 - + for level in self.levels: for node in self.levels[level]: self.result[node]['y'] += min_order - + if roots: roots.append(self.start) one_level_el = self.tree_list[self.start][0][1] base = self.result[one_level_el]['y']# * 2 / (index + 2) - - + + no = len(roots) first_half = roots[:no/2] - + if no%2==0: last_half = roots[no/2:] else: last_half = roots[no/2+1:] - + factor = -math.floor(no/2) for start in first_half: - self.result[start]['y'] = base + factor + self.result[start]['y'] = base + factor factor += 1 - + if no%2: self.result[roots[no/2]]['y'] = base + factor factor +=1 - + for start in last_half: - self.result[start]['y'] = base + factor + self.result[start]['y'] = base + factor factor += 1 - + self.max_order = max(map(lambda x: x['y'], self.result.values())) - - def find_starts(self): + + def find_starts(self): """Finds other start nodes of the graph in the case when graph is disconneted """ rem_nodes = [] @@ -577,7 +577,7 @@ class graph(object): count = 0 new_start = rem_nodes[0] largest_tree = [] - + for node in rem_nodes: self.partial_order = {} tree = self.make_acyclic(None, node, 0, []) @@ -589,120 +589,120 @@ class graph(object): if not largest_tree: new_start = rem_nodes[0] rem_nodes.remove(new_start) - + self.start_nodes.append(new_start) - - + + for edge in largest_tree: if rem_nodes.__contains__(edge[0]): rem_nodes.remove(edge[0]) if rem_nodes.__contains__(edge[1]): rem_nodes.remove(edge[1]) - + if not rem_nodes: break - + def rank(self): """Finds the optimized rank of the nodes using Network-simplex algorithm - + @param start: starting node of the component """ - self.levels = {} + self.levels = {} self.critical_edges = [] self.partial_order = {} self.links = [] self.Is_Cyclic = False - + self.tree_list[self.start] = self.make_acyclic(None, self.start, 0, []) - self.Is_Cyclic = self.rev_edges(self.tree_list[self.start]) + self.Is_Cyclic = self.rev_edges(self.tree_list[self.start]) self.process_ranking(self.start) self.init_rank() - + #make cut values of all tree edges to 0 to optimize feasible tree - e = self.leave_edge() - + e = self.leave_edge() + while e : f = self.enter_edge(e) if e==f: self.critical_edges.append(e) else: - self.exchange(e,f) + self.exchange(e,f) e = self.leave_edge() - + #finalize rank using optimum feasible tree # self.optimal_edges = {} # for edge in self.tree_edges: # source = self.optimal_edges.setdefault(edge[0], []) # source.append(edge[1]) - + # self.finalize_rank(self.start, 0) - + #normalization - self.normalize() + self.normalize() for edge in self.edge_wt: self.edge_wt[edge] = self.result[edge[1]]['x'] - self.result[edge[0]]['x'] - + def order_in_rank(self): """Finds optimized order of the nodes within their ranks using median heuristic - - @param start: starting node of the component + + @param start: starting node of the component """ - + self.make_chain() self.preprocess_order() self.order = {} max_rank = max(map(lambda x: x, self.levels.keys())) - + for i in range(max_rank+1): self.order[i] = 0 - + self.init_order(self.start, self.result[self.start]['x']) - + for level in self.levels: self.levels[level].sort(lambda x, y: cmp(self.result[x]['y'], self.result[y]['y'])) - - self.order_heuristic() + + self.order_heuristic() self.process_order() - + def process(self, starting_node): """Process the graph to find ranks and order of the nodes - - @param starting_node: node from where to start the graph search + + @param starting_node: node from where to start the graph search """ - + self.start_nodes = starting_node or [] - self.partial_order = {} - self.links = [] - self.tree_list = {} - + self.partial_order = {} + self.links = [] + self.tree_list = {} + if self.nodes: if self.start_nodes: #add dummy edges to the nodes which does not have any incoming edges tree = self.make_acyclic(None, self.start_nodes[0], 0, []) - + for node in self.no_ancester: for sec_node in self.transitions.get(node, []): if sec_node in self.partial_order.keys(): self.transitions[self.start_nodes[0]].append(node) break - + self.partial_order = {} tree = self.make_acyclic(None, self.start_nodes[0], 0, []) - - - # if graph is disconnected or no start-node is given - #than to find starting_node for each component of the node + + + # if graph is disconnected or no start-node is given + #than to find starting_node for each component of the node if len(self.nodes) > len(self.partial_order): - self.find_starts() - - self.max_order = 0 + self.find_starts() + + self.max_order = 0 #for each component of the graph find ranks and order of the nodes - for s in self.start_nodes: + for s in self.start_nodes: self.start = s self.rank() # First step:Netwoek simplex algorithm - self.order_in_rank() #Second step: ordering nodes within ranks - + self.order_in_rank() #Second step: ordering nodes within ranks + def __str__(self): result = '' @@ -716,21 +716,21 @@ class graph(object): def scale(self, maxx, maxy, nwidth=0, nheight=0, margin=20): """Computes actual co-ordiantes of the nodes """ - + #for flat edges ie. source an destination nodes are on the same rank for src in self.transitions: for des in self.transitions[src]: - if (self.result[des]['x'] - self.result[src]['x'] == 0): + if (self.result[des]['x'] - self.result[src]['x'] == 0): self.result[src]['x'] += 0.08 self.result[des]['x'] -= 0.08 - + factorX = maxx + nheight - factorY = maxy + nwidth - + factorY = maxy + nwidth + for node in self.result: self.result[node]['y'] = (self.result[node]['y']) * factorX + margin self.result[node]['x'] = (self.result[node]['x']) * factorY + margin - + def result_get(self): return self.result @@ -763,14 +763,14 @@ if __name__=='__main__': import ImageDraw img = Image.new("RGB", (800, 600), "#ffffff") draw = ImageDraw.Draw(img) - + result = g.result_get() node_res = {} for node in nodes: node_res[node] = result[node] - + for name,node in node_res.items(): - + draw.arc( (int(node['y']-radius), int(node['x']-radius),int(node['y']+radius), int(node['x']+radius) ), 0, 360, (128,128,128)) draw.text( (int(node['y']), int(node['x'])), name, (128,128,128)) From b528a80036cc13b539af76e5ff23f195a4086213 Mon Sep 17 00:00:00 2001 From: "HDA (OpenERP)" Date: Fri, 12 Mar 2010 15:45:34 +0530 Subject: [PATCH 25/38] Fixed for directory not having __openerp__ or __terp__ files bzr revid: hda@tinyerp.com-20100312101534-gmpph29sc47wweo6 --- bin/addons/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index c5e73e7c709..13ff5133b31 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -32,6 +32,7 @@ import pooler import netsvc from osv import fields +import addons import zipfile import release @@ -302,8 +303,8 @@ def load_information_from_description_file(module): description_file = addons.get_module_resource(module, filename) if os.path.isfile(description_file): return eval(tools.file_open(description_file).read()) - - raise Exception('The module %s does not contain a description file: __openerp__.py or __terp__.py (deprecated)') + return +# raise Exception('The module %s does not contain a description file: __openerp__.py or __terp__.py (deprecated)') def get_modules_with_version(): modules = get_modules() From bb091a77b0c08964356629df19547de2c9203bd7 Mon Sep 17 00:00:00 2001 From: "Rga (Open ERP)" Date: Fri, 12 Mar 2010 17:22:58 +0530 Subject: [PATCH 26/38] [IMP]set default_focus attribute on buttons and fields bzr revid: rga@tinyerp.co.in-20100312115258-2txw1jm58nlog9gw --- bin/addons/base/rng/view.rng | 12 +++++++----- bin/osv/orm.py | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng index 4f99a03a8c1..69a4cc466d6 100644 --- a/bin/addons/base/rng/view.rng +++ b/bin/addons/base/rng/view.rng @@ -89,7 +89,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -357,6 +357,7 @@ + @@ -429,7 +430,7 @@ - + @@ -442,9 +443,9 @@ - + - + @@ -469,6 +470,7 @@ + diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 7f412be0a7a..44f0bff3a14 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1501,6 +1501,10 @@ class orm_template(object): 'action': resaction, 'relate': resrelate } + if result['type']=='form' and result['arch'].count("default_focus")>1: + msg = "Form View contain more than one default_focus attribute" + netsvc.Logger().notifyChannel('orm', netsvc.LOG_ERROR, msg) + raise except_orm('View Error !',msg) return result _view_look_dom_arch = __view_look_dom_arch From c0935c2513e3150d9cdbe3a07563db670562ffcb Mon Sep 17 00:00:00 2001 From: "nch@tinyerp.com" <> Date: Tue, 16 Mar 2010 10:56:09 +0530 Subject: [PATCH 27/38] [IMP]:added parent_field in attrs of O2M field and set limit=20 for O2M field bzr revid: nch@tinyerp.com-20100316052609-mp5q3o4859xej9a0 --- bin/osv/fields.py | 4 +++- bin/osv/orm.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/osv/fields.py b/bin/osv/fields.py index ce02de20a27..19735857680 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -81,6 +81,7 @@ class _column(object): self.select = select self.selectable = True self.group_operator = args.get('group_operator', False) + self.parent_field = args.get('parent_field', False) for a in args: if args[a]: setattr(self, a, args[a]) @@ -365,7 +366,8 @@ class one2many(_column): _prefetch = False _type = 'one2many' - def __init__(self, obj, fields_id, string='unknown', limit=None, **args): + def __init__(self, obj, fields_id, string='unknown', limit=20, **args): + args.update({'parent_field':fields_id}) _column.__init__(self, string=string, **args) self._obj = obj self._fields_id = fields_id diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 2bf846d631d..83934f8b1a2 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1008,7 +1008,7 @@ class orm_template(object): continue res[f] = {'type': self._columns[f]._type} for arg in ('string', 'readonly', 'states', 'size', 'required', 'group_operator', - 'change_default', 'translate', 'help', 'select', 'selectable'): + 'change_default', 'translate', 'help', 'select', 'selectable','parent_field'): if getattr(self._columns[f], arg): res[f][arg] = getattr(self._columns[f], arg) if not read_access: From bf77cfe0059775dcbf8d073845ae5172ddddc093 Mon Sep 17 00:00:00 2001 From: "Rvo (Open ERP)" Date: Tue, 16 Mar 2010 12:18:12 +0530 Subject: [PATCH 28/38] command line server management with -i and -u options bzr revid: rvo@tinyerp.co.in-20100316064812-5uurt3vhids9o57u --- bin/addons/base/module/module.py | 2 ++ bin/osv/orm.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index e11b4964471..01ea8cc0745 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -237,6 +237,8 @@ class module(osv.osv): def button_upgrade(self, cr, uid, ids, context=None): depobj = self.pool.get('ir.module.module.dependency') todo = self.browse(cr, uid, ids, context=context) + self.update_list(cr, uid) + i = 0 while i Date: Tue, 16 Mar 2010 18:35:17 +0530 Subject: [PATCH 29/38] [IMP]:allowed default_get method to throw exception for osv_memory wizards bzr revid: rvo@tinyerp.co.in-20100316130517-z5ojbxincq62mkle --- bin/osv/orm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 7d7afccf2b2..a7f6056c4c9 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -370,6 +370,10 @@ class orm_template(object): CONCURRENCY_CHECK_FIELD = '__last_update' + def view_init(self, cr , uid , fields_list, context=None): + """Override this method to do specific things when a view on the object is opened.""" + pass + def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None): raise _('The read_group method is not implemented on this object !') @@ -1697,6 +1701,7 @@ class orm_memory(orm_template): return id_new def default_get(self, cr, uid, fields_list, context=None): + self.view_init(cr, uid, fields_list, context) if not context: context = {} value = {} From 122901dc7a068b1ca154b611fd45df45d9caefcc Mon Sep 17 00:00:00 2001 From: "Rga (Open ERP)" Date: Tue, 16 Mar 2010 19:44:08 +0530 Subject: [PATCH 30/38] [IMP] browse() on reference fields bzr revid: rga@tinyerp.co.in-20100316141408-7u2hg1nmgplpu0n5 --- bin/osv/orm.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index a7f6056c4c9..4871658b833 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -247,6 +247,15 @@ class browse_record(object): new_data[n] = browse_null() elif f._type in ('one2many', 'many2many') and len(data[n]): new_data[n] = self._list_class([browse_record(self._cr, self._uid, id, self._table.pool.get(f._obj), self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) for id in data[n]], self._context) + elif f._type in ('reference'): + if data[n]: + ref_obj, ref_id = data[n].split(',') + ref_id = long(ref_id) + obj = self._table.pool.get(ref_obj) + compids = False + new_data[n] = browse_record(self._cr, self._uid, ref_id, obj, self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) + else: + new_data[n] = browse_null() else: new_data[n] = data[n] self._data[data['id']].update(new_data) @@ -1481,7 +1490,7 @@ class orm_template(object): if context and context.get('active_id',False): data_menu = self.pool.get('ir.ui.menu').browse(cr, user, context['active_id'], context).action if data_menu: - act_id = int(data_menu.split(',')[1]) + act_id = data_menu.id if act_id: data_action = self.pool.get('ir.actions.act_window').browse(cr, user, [act_id], context)[0] result['submenu'] = getattr(data_action,'menus', False) From 397b5a36d837f44b7e12765cb2dfc1e1b608d72e Mon Sep 17 00:00:00 2001 From: "RGA(OpenERP)" <> Date: Wed, 17 Mar 2010 19:41:30 +0530 Subject: [PATCH 31/38] Improved related changes for browse support in reference field bzr revid: hda@tinyerp.com-20100317141130-08v21img7a8tu9qx --- addons/base_calendar/base_calendar.py | 22 +++++----------------- addons/crm/crm_meeting.py | 7 ++----- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 4d0f85376f3..62ffc7c39d8 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -325,26 +325,17 @@ class calendar_attendee(osv.osv): result[id][name] = ', '.join(fromdata) if name == 'event_date': if attdata.ref: - model, res_id = tuple(attdata.ref.split(',')) - model_obj = self.pool.get(model) - obj = model_obj.read(cr, uid, res_id, ['date'])[0] - result[id][name] = obj.get('date') + result[id][name] = attdata.ref.date else: result[id][name] = False if name == 'event_end_date': if attdata.ref: - model, res_id = tuple(attdata.ref.split(',')) - model_obj = self.pool.get(model) - obj = model_obj.read(cr, uid, res_id, ['date_deadline'])[0] - result[id][name] = obj.get('date_deadline') + result[id][name] = attdata.ref.date_deadline else: result[id][name] = False if name == 'sent_by_uid': if attdata.ref: - model, res_id = tuple(attdata.ref.split(',')) - model_obj = self.pool.get(model) - obj = model_obj.read(cr, uid, res_id, ['user_id'])[0] - result[id][name] = obj.get('user_id') + result[id][name] = (attdata.ref.user_id.id,attdata.ref.user_id.name) else: result[id][name] = uid if name == 'language': @@ -441,8 +432,7 @@ request was delegated to"), for att in self.browse(cr, uid, ids, context=context): sign = att.sent_by_uid and att.sent_by_uid.signature or '' sign = '
'.join(sign and sign.split('\n') or []) - model, res_id = tuple(att.ref.split(',')) - res_obj = self.pool.get(model).browse(cr, uid, res_id) + res_obj = att.ref if res_obj and len(res_obj): res_obj = res_obj[0] sub = '[%s Invitation][%d] %s' % (company, att.id, res_obj.name) @@ -490,9 +480,7 @@ request was delegated to"), if user: ref = vals.get('ref', None) if ref: - model, event = ref.split(',') - model_obj = self.pool.get(model) - event_ref = model_obj.browse(cr, uid, event, context=context)[0] + event_ref = ref if event_ref.user_id.id != user[0]: defaults = {'user_id': user[0]} new_event = model_obj.copy(cr, uid, event, default=defaults, context=context) diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py index ce818fa0189..de0f1f01c33 100644 --- a/addons/crm/crm_meeting.py +++ b/addons/crm/crm_meeting.py @@ -74,17 +74,14 @@ class calendar_attendee(osv.osv): result[id] = {} if name == 'categ_id': if attdata.ref: - model, res_id = tuple(attdata.ref.split(',')) - model_obj = self.pool.get(model) - obj = model_obj.read(cr, uid, res_id, ['categ_id'])[0] - result[id][name] = obj.get('categ_id') + result[id][name] = (attdata.ref.categ_id.id,attdata.ref.categ_id.name,) else: result[id][name] = False return result _columns = { 'categ_id': fields.function(_compute_data, method=True, \ string='Event Type', type="many2one", \ - relation="crm.case.categ", multi='categ_id'), + relation="crm.case.categ", multi='categ_id'), } calendar_attendee() From 38b78087090aaf735ebc139fc4f79588d3bd68b7 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Wed, 17 Mar 2010 15:24:01 +0100 Subject: [PATCH 32/38] [IMP] base_calendar: Change the layout of the alarm [IMP] crm: Change the layout [IMP] product: Change the layout [IMP] sale: Change the layout bzr revid: stephane@openerp.com-20100317142401-pobas1gc9qypd50x --- addons/base_calendar/base_calendar_view.xml | 2 +- addons/crm/crm_claims_view.xml | 2 +- addons/crm/crm_fund_view.xml | 26 ++++++++++----------- addons/crm/crm_helpdesk_view.xml | 3 ++- addons/crm/crm_opportunity_view.xml | 14 +++++------ addons/crm/crm_view.xml | 2 +- addons/product/pricelist_view.xml | 1 + addons/product/product_view.xml | 4 ++-- addons/sale/report/sale_report_view.xml | 4 ++-- addons/sale/sale_view.xml | 19 ++++++++------- 10 files changed, 40 insertions(+), 37 deletions(-) diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml index d6430ca98a2..f1e59583cc1 100644 --- a/addons/base_calendar/base_calendar_view.xml +++ b/addons/base_calendar/base_calendar_view.xml @@ -159,8 +159,8 @@ - + diff --git a/addons/crm/crm_claims_view.xml b/addons/crm/crm_claims_view.xml index 5a4c6a3f6ad..f51f6890d0c 100644 --- a/addons/crm/crm_claims_view.xml +++ b/addons/crm/crm_claims_view.xml @@ -45,7 +45,7 @@ crm.claim tree - + diff --git a/addons/crm/crm_fund_view.xml b/addons/crm/crm_fund_view.xml index 75aae19a4af..a78d5e3eeb6 100644 --- a/addons/crm/crm_fund_view.xml +++ b/addons/crm/crm_fund_view.xml @@ -202,24 +202,24 @@ - - - - - + default="1" domain="[('user_id','=',uid)]" + separator="1" + help="Funds Related to Current User" + /> + + + + + - + - - + + /> diff --git a/addons/crm/crm_helpdesk_view.xml b/addons/crm/crm_helpdesk_view.xml index 68a47fef9f8..ec662885a04 100644 --- a/addons/crm/crm_helpdesk_view.xml +++ b/addons/crm/crm_helpdesk_view.xml @@ -122,7 +122,8 @@ crm.helpdesk tree - + diff --git a/addons/crm/crm_opportunity_view.xml b/addons/crm/crm_opportunity_view.xml index 4bf7a0b858d..4ce8c647c13 100644 --- a/addons/crm/crm_opportunity_view.xml +++ b/addons/crm/crm_opportunity_view.xml @@ -215,24 +215,24 @@ /> + - - - - + + + diff --git a/addons/crm/crm_view.xml b/addons/crm/crm_view.xml index fddd3bf2598..908cdd6fa91 100644 --- a/addons/crm/crm_view.xml +++ b/addons/crm/crm_view.xml @@ -634,7 +634,7 @@ - + diff --git a/addons/product/pricelist_view.xml b/addons/product/pricelist_view.xml index 8045cc6cf22..1dbf110cd64 100644 --- a/addons/product/pricelist_view.xml +++ b/addons/product/pricelist_view.xml @@ -104,6 +104,7 @@ + diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index e6c5588f4f7..ab0d2118bd7 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -344,8 +344,8 @@ form
- - + + diff --git a/addons/sale/report/sale_report_view.xml b/addons/sale/report/sale_report_view.xml index 3592cda4662..2e36b7d9923 100644 --- a/addons/sale/report/sale_report_view.xml +++ b/addons/sale/report/sale_report_view.xml @@ -62,13 +62,13 @@ default="1" domain="[('state','<>','draft'),('state','<>','cancel')]"/> - + diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index b3cec7496e4..4b9e5df8f8c 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -30,9 +30,9 @@ + - @@ -80,6 +80,7 @@ + @@ -428,15 +429,15 @@ search - - - - + + + + From 062fc996a4c54f4bef3f3bb3d2fbf1e3652bbcfc Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Wed, 17 Mar 2010 15:29:51 +0100 Subject: [PATCH 33/38] [FIX] Add some missing views and change the layouts of some views bzr revid: stephane@openerp.com-20100317142951-8olx5ehlhibgl34c --- bin/addons/base/res/partner/crm_view.xml | 11 +++++++++++ bin/addons/base/res/partner/partner_view.xml | 14 +++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/bin/addons/base/res/partner/crm_view.xml b/bin/addons/base/res/partner/crm_view.xml index da4e08c7644..3a0e25b8898 100644 --- a/bin/addons/base/res/partner/crm_view.xml +++ b/bin/addons/base/res/partner/crm_view.xml @@ -2,6 +2,17 @@ + + res.partner.canal.tree + res.partner.canal + tree + + + + + + + res.partner.canal.form res.partner.canal diff --git a/bin/addons/base/res/partner/partner_view.xml b/bin/addons/base/res/partner/partner_view.xml index 938ffc83d12..b638742fd41 100644 --- a/bin/addons/base/res/partner/partner_view.xml +++ b/bin/addons/base/res/partner/partner_view.xml @@ -182,6 +182,17 @@ Partner Titles ======================= --> + + res.partner.title.tree + res.partner.title + tree + + + + + + + res.partner.title.form res.partner.title @@ -340,8 +351,8 @@ default="context.get('default_supplier',False)"/> - + @@ -555,6 +566,7 @@ + From e328055359259bb9ea676dec3d7e0c2155ebe061 Mon Sep 17 00:00:00 2001 From: "qdp-launchpad@tinyerp.com" <> Date: Wed, 17 Mar 2010 18:09:26 +0100 Subject: [PATCH 34/38] [IMP] hr_holidays: improvements bzr revid: qdp-launchpad@tinyerp.com-20100317170926-zyw5frdscx3kpi1p --- addons/hr_holidays/__terp__.py | 3 +- addons/hr_holidays/hr.py | 131 ++++++------------ addons/hr_holidays/hr_holidays_report.xml | 71 ++++++++++ addons/hr_holidays/hr_holidays_wizard.xml | 7 +- addons/hr_holidays/hr_view.xml | 99 +++++-------- addons/hr_holidays/report/__init__.py | 6 +- .../hr_holidays/report/available_holidays.py | 33 +++++ .../report/holidays_summary_report.py | 1 - .../hr_holidays/security/ir.model.access.csv | 8 +- 9 files changed, 187 insertions(+), 172 deletions(-) create mode 100644 addons/hr_holidays/report/available_holidays.py diff --git a/addons/hr_holidays/__terp__.py b/addons/hr_holidays/__terp__.py index f44fe590015..26dc78675cc 100644 --- a/addons/hr_holidays/__terp__.py +++ b/addons/hr_holidays/__terp__.py @@ -53,9 +53,8 @@ 'security/ir.model.access.csv', 'hr_workflow.xml', 'hr_view.xml', - 'hr_holidays_report.xml', 'hr_holidays_wizard.xml', - 'report/hr_holidays_report_view.xml', + 'hr_holidays_report.xml', #'process/hr_holidays_process.xml' ], 'demo_xml': [], diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py index b6c0313e13f..12cb02f659f 100755 --- a/addons/hr_holidays/hr.py +++ b/addons/hr_holidays/hr.py @@ -37,17 +37,13 @@ class hr_holidays_status(osv.osv): for record in self.browse(cr, uid, ids, context): res[record.id] = {} max_leaves = leaves_taken = 0 - obj_ids = self.pool.get('hr.holidays.per.user').search(cr, uid, [('user_id','=',uid),('employee_id','=',employee_id),('holiday_status','=',record.id)]) - if obj_ids: - br_ob=self.pool.get('hr.holidays.per.user').browse(cr, uid, obj_ids)[0] - max_leaves=br_ob.max_leaves if not return_false: cr.execute("""SELECT type, sum(number_of_days) FROM hr_holidays WHERE employee_id = %s AND state='validate' AND holiday_status_id = %s GROUP BY type""", (str(employee_id), str(record.id))) for line in cr.fetchall(): if line[0] =='remove': - leaves_taken = -line[1] + leaves_taken = -line[1] if line[0] =='add': - max_leaves = line[1] + max_leaves = line[1] res[record.id]['max_leaves'] = max_leaves res[record.id]['leaves_taken'] = leaves_taken res[record.id]['remaining_leaves'] = max_leaves - leaves_taken @@ -66,18 +62,19 @@ class hr_holidays_status(osv.osv): employee_id = employee_ids[0] else: return_false = True - res = self.get_days(cr, uid, ids, employee_id, return_false, context=context) + if employee_id: + res = self.get_days(cr, uid, ids, employee_id, return_false, context=context) return res _columns = { 'name' : fields.char('Name', size=64, required=True, translate=True), - 'section_id': fields.many2one('crm.case.section', 'CRM Section', help='If you link this type of leave with a section in the CRM, it will synchronize each leave asked with a case in this section, to display it in the company shared calendar for example.'), + 'categ_id': fields.many2one('crm.case.categ', 'Meeting Category', domain="[('object_id.model', '=', 'crm.meeting')]", help='If you link this type of leave with a category in the CRM, it will synchronize each leave asked with a case in this category, to display it in the company shared calendar for example.'), 'color_name' : fields.selection([('red', 'Red'), ('lightgreen', 'Light Green'), ('lightblue','Light Blue'), ('lightyellow', 'Light Yellow'), ('magenta', 'Magenta'),('lightcyan', 'Light Cyan'),('black', 'Black'),('lightpink', 'Light Pink'),('brown', 'Brown'),('violet', 'Violet'),('lightcoral', 'Light Coral'),('lightsalmon', 'Light Salmon'),('lavender', 'Lavender'),('wheat', 'Wheat'),('ivory', 'Ivory')],'Color of the status', required=True, help='This color will be used in the leaves summary located in Reporting\Print Summary of Leaves'), 'limit' : fields.boolean('Allow to override Limit', help='If you thick this checkbox, the system will allow, for this section, the employees to take more leaves than the available ones.'), - 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the leave type without removing it."), + 'active' : fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the leave type without removing it."), 'max_leaves' : fields.function(_user_left_days, method=True, string='Maximum Leaves Allowed', help='This value is given by the sum of all holidays requests with a positive value.', multi='user_left_days'), 'leaves_taken' : fields.function(_user_left_days, method=True, string='Leaves Already Taken', help='This value is given by the sum of all holidays requests with a negative value.', multi='user_left_days'), - 'remaining_leaves' : fields.function(_user_left_days, method=True, string='Remaining Leaves', multi='user_left_days'), + 'remaining_leaves' : fields.function(_user_left_days, method=True, string='Remaining Leaves', help='Maximum Leaves Allowed - Leaves Already Taken', multi='user_left_days'), } _defaults = { @@ -86,48 +83,6 @@ class hr_holidays_status(osv.osv): } hr_holidays_status() -class hr_holidays_per_user(osv.osv): - _name = "hr.holidays.per.user" - _description = "Holidays Per User" - _rec_name = "user_id" - - def _get_remaining_leaves(self, cr, uid, ids, field_name, arg=None, context={}): - obj_holiday = self.pool.get('hr.holidays') - result = {} - for holiday_user in self.browse(cr, uid, ids): - days = 0.0 - ids_request = obj_holiday.search(cr, uid, [('employee_id', '=', holiday_user.employee_id.id),('state', '=', 'validate'),('holiday_status_id', '=', holiday_user.holiday_status.id)]) - if ids_request: - holidays = obj_holiday.browse(cr, uid, ids_request) - for holiday in holidays: - days -= holiday.number_of_days - days = holiday_user.max_leaves - days - result[holiday_user.id] = days - return result - - _columns = { - 'employee_id': fields.many2one('hr.employee', "Employee's Name",required=True), - 'user_id' : fields.many2one('res.users','User'), - 'holiday_status' : fields.many2one("hr.holidays.status", "Holiday's Status", required=True), - 'max_leaves' : fields.float('Maximum Leaves Allowed',required=True), - 'leaves_taken' : fields.float('Leaves Already Taken',readonly=True), - 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the holidays per user without removing it."), - 'notes' : fields.text('Notes'), - 'remaining_leaves': fields.function(_get_remaining_leaves, method=True, string='Remaining Leaves', type='float'), - 'holiday_ids': fields.one2many('hr.holidays', 'holiday_user_id', 'Holidays') - } - _defaults = { - 'active' : lambda *a: True, - } - - def create(self, cr, uid, vals, *args, **kwargs): - if vals['employee_id']: - obj_emp=self.pool.get('hr.employee').browse(cr,uid,vals['employee_id']) - vals.update({'user_id': obj_emp.user_id.id}) - return super(osv.osv,self).create(cr, uid, vals, *args, **kwargs) - -hr_holidays_per_user() - class hr_holidays(osv.osv): _name = "hr.holidays" _description = "Holidays" @@ -152,13 +107,12 @@ class hr_holidays(osv.osv): 'notes' : fields.text('Notes',readonly=True, states={'draft':[('readonly',False)]}), 'number_of_days': fields.float('Number of Days', readonly=True, states={'draft':[('readonly',False)]}), 'number_of_days_temp': fields.float('Number of Days', readonly=True, states={'draft':[('readonly',False)]}), - 'case_id': fields.many2one('crm.case', 'Case'), + 'case_id': fields.many2one('crm.meeting', 'Case'), 'type': fields.selection([('remove','Leave Request'),('add','Allocation Request')], 'Request Type', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="Choose 'Leave Request' if someone wants to take an off-day. \nChoose 'Allocation Request' if you want to increase the number of leaves available for someone"), 'allocation_type': fields.selection([('employee','Employee Request'),('company','Company Allocation')], 'Allocation Type', required=True, readonly=True, states={'draft':[('readonly',False)]}, help='This field is only for informative purposes, to depict if the leave request/allocation comes from an employee or from the company'), 'parent_id': fields.many2one('hr.holidays', 'Parent'), 'linked_request_ids': fields.one2many('hr.holidays', 'parent_id', 'Linked Requests',), - 'holiday_user_id' : fields.many2one('hr.holidays.per.user', 'User'), - 'department_id':fields.many2one('hr.department','Department'), + 'department_id':fields.many2one('hr.department','Department', readonly=True, states={'draft':[('readonly',False)]} ), } _defaults = { @@ -170,6 +124,14 @@ class hr_holidays(osv.osv): } _order = 'date_from desc' + def create(self, cr, uid, vals, context={}): + if context: + if context.has_key('type'): + vals['type'] = context['type'] + if context.has_key('allocation_type'): + vals['allocation_type'] = context['allocation_type'] + return super(osv.osv,self).create(cr, uid, vals, context) + def onchange_date_from(self, cr, uid, ids, date_to, date_from): result = {} if date_to and date_from: @@ -188,16 +150,14 @@ class hr_holidays(osv.osv): def _update_user_holidays(self, cr, uid, ids): for record in self.browse(cr, uid, ids): if record.state=='validate': - holiday_id=self.pool.get('hr.holidays.per.user').search(cr, uid, [('employee_id','=', record.employee_id.id),('holiday_status','=',record.holiday_status_id.id)]) - if holiday_id: - obj_holidays_per_user=self.pool.get('hr.holidays.per.user').browse(cr, uid,holiday_id[0]) - self.pool.get('hr.holidays.per.user').write(cr,uid,obj_holidays_per_user.id,{'leaves_taken':obj_holidays_per_user.leaves_taken - record.number_of_days}) if record.case_id: - if record.case_id.state <> 'draft': - raise osv.except_osv(_('Warning !'), - _('You can not cancel this holiday request. first You have to make its case in draft state.')) - else: - self.pool.get('crm.case').unlink(cr,uid,[record.case_id.id]) + self.pool.get('crm.meeting').unlink(cr,uid,[record.case_id.id]) + if record.linked_request_ids: + list_ids = [] + for id in record.linked_request_ids: + list_ids.append(id.id) + self.holidays_cancel(cr,uid,list_ids) + self.unlink(cr,uid,list_ids) def _check_date(self, cr, uid, ids): if ids: @@ -209,26 +169,11 @@ class hr_holidays(osv.osv): _constraints = [(_check_date, 'Start date should not be larger than end date! ', ['number_of_days'])] - def create(self, cr, uid, vals, *args, **kwargs): - id_holiday = super(hr_holidays, self).create(cr, uid, vals, *args, **kwargs) - self._create_holiday(cr, uid, [id_holiday]) - return id_holiday def unlink(self, cr, uid, ids, context={}): self._update_user_holidays(cr, uid, ids) return super(hr_holidays, self).unlink(cr, uid, ids, context) - def _create_holiday(self, cr, uid, ids): - holidays_user_obj = self.pool.get('hr.holidays.per.user') - holidays_data = self.browse(cr, uid, ids[0]) - list_holiday = [] - ids_user_hdays = holidays_user_obj.search(cr, uid, [('employee_id', '=', holidays_data.employee_id.id),('holiday_status', '=', holidays_data.holiday_status_id.id)]) - for hdays in holidays_user_obj.browse(cr, uid, ids_user_hdays): - for req in hdays.holiday_ids: - list_holiday.append(req.id) - list_holiday.append(ids[0]) - holidays_user_obj.write(cr, uid, ids_user_hdays, {'holiday_ids': [(6, 0, list_holiday)]}) - return True def onchange_date_to(self, cr, uid, ids, date_from, date_to): result = {} @@ -249,7 +194,7 @@ class hr_holidays(osv.osv): warning = {} if status: brows_obj = self.pool.get('hr.holidays.status').browse(cr, uid, [status])[0] - if brows_obj.section_id and not brows_obj.section_id.allow_unlink: + if brows_obj.categ_id and brows_obj.categ_id.section_id and not brows_obj.categ_id.section_id.allow_unlink: warning = { 'title': "Warning for ", 'message': "You won\'t be able to cancel this leave request because the CRM Section of the leave type disallows." @@ -283,6 +228,7 @@ class hr_holidays(osv.osv): def holidays_confirm(self, cr, uid, ids, *args): for record in self.browse(cr, uid, ids): + user_id = False leave_asked = record.number_of_days_temp if record.type == 'remove': if record.employee_id and not record.holiday_status_id.limit: @@ -300,14 +246,14 @@ class hr_holidays(osv.osv): 'number_of_days': nb, 'user_id': user_id }) - vals= { - 'name':record.name, - 'date_from':record.date_from, - 'date_to':record.date_to, - 'calendar_id':record.employee_id.calendar_id.id, - 'company_id':record.employee_id.company_id.id, - 'resource_id':record.employee_id.resource_id.id - } + #vals= { + # 'name':record.name, + # 'date_from':record.date_from, + # 'date_to':record.date_to, + # 'calendar_id':record.employee_id.calendar_id.id, + # 'company_id':record.employee_id.company_id.id, + # 'resource_id':record.employee_id.resource_id.id + # } #self.pool.get('resource.calendar.leaves').create(cr,uid,vals) return True @@ -365,14 +311,17 @@ class hr_holidays(osv.osv): employee_ids = self.pool.get('hr.employee').search(cr, uid, []) for employee in employee_ids: vals['employee_id'] = employee + user_id = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)]) + if user_id: + vals['user_id'] = user_id[0] holiday_ids.append(self.create(cr, uid, vals, context={})) self.holidays_confirm(cr, uid, holiday_ids) self.holidays_validate(cr, uid, holiday_ids) - if record.holiday_status_id.section_id and record.date_from and record.date_to and record.employee_id: + if record.holiday_status_id.categ_id and record.date_from and record.date_to and record.employee_id: vals={} vals['name']=record.name - vals['section_id']=record.holiday_status_id.section_id.id + vals['categ_id']=record.holiday_status_id.categ_id.id epoch_c = time.mktime(time.strptime(record.date_to,'%Y-%m-%d %H:%M:%S')) epoch_d = time.mktime(time.strptime(record.date_from,'%Y-%m-%d %H:%M:%S')) diff_day = (epoch_c - epoch_d)/(3600*24) @@ -380,7 +329,7 @@ class hr_holidays(osv.osv): vals['note'] = record.notes vals['user_id'] = record.user_id.id vals['date'] = record.date_from - case_id = self.pool.get('crm.case').create(cr,uid,vals) + case_id = self.pool.get('crm.meeting').create(cr,uid,vals) self.write(cr, uid, ids, {'case_id':case_id}) return True hr_holidays() diff --git a/addons/hr_holidays/hr_holidays_report.xml b/addons/hr_holidays/hr_holidays_report.xml index 23d1e1a75bf..66669bd2f51 100644 --- a/addons/hr_holidays/hr_holidays_report.xml +++ b/addons/hr_holidays/hr_holidays_report.xml @@ -9,6 +9,77 @@ auto="False" menu="False"/> + + + + + + + hr.holidays.report.tree + hr.holidays.report + tree + + + + + + + + + + + hr.holidays.report.form + hr.holidays.report + form + + + + + + + + + + hr.holiday.report.graph + hr.holidays.report + graph + + + + + + + + + + + Available Holidays + hr.holidays.report + form + tree,graph + + + + + + + tree + + + + + + + + graph + + + + + + + + diff --git a/addons/hr_holidays/hr_holidays_wizard.xml b/addons/hr_holidays/hr_holidays_wizard.xml index fb505d65497..fc433a181e7 100644 --- a/addons/hr_holidays/hr_holidays_wizard.xml +++ b/addons/hr_holidays/hr_holidays_wizard.xml @@ -11,10 +11,11 @@ name="Holidays" parent="hr.menu_hr_reporting" sequence="3" /> - - @@ -24,7 +25,7 @@ - diff --git a/addons/hr_holidays/hr_view.xml b/addons/hr_holidays/hr_view.xml index 146e06d25a3..d46898bd6bb 100644 --- a/addons/hr_holidays/hr_view.xml +++ b/addons/hr_holidays/hr_view.xml @@ -1,13 +1,6 @@ - - - hr.holidays.filter hr.holidays @@ -38,7 +31,6 @@ - Leave Request hr.holidays @@ -73,7 +65,6 @@ - Allocation Request hr.holidays @@ -104,18 +95,17 @@ - - + - Company Allocation + Leaves Management hr.holidays form -
+ - + @@ -153,13 +143,13 @@ - + - + - + + Leave Request(s) hr.holidays @@ -226,13 +195,8 @@ - @@ -256,16 +220,32 @@ form - + - + action="open_allocation_holidays"/> + + + hr.holidays + form + tree,form + + {'allocation_type':'company'} + + + @@ -276,7 +256,7 @@ - + @@ -303,10 +283,6 @@ - - - Holiday Per User - hr.holidays.per.user - form - tree,form - - - - - diff --git a/addons/hr_holidays/report/__init__.py b/addons/hr_holidays/report/__init__.py index bb1f6229bc0..00783721fe3 100644 --- a/addons/hr_holidays/report/__init__.py +++ b/addons/hr_holidays/report/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2010 Tiny SPRL (). # @@ -15,11 +15,11 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## import holidays_summary_report -import hr_holidays_report +import available_holidays # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_holidays/report/available_holidays.py b/addons/hr_holidays/report/available_holidays.py new file mode 100644 index 00000000000..259aea0dec9 --- /dev/null +++ b/addons/hr_holidays/report/available_holidays.py @@ -0,0 +1,33 @@ +from osv import fields,osv +import tools + +class hr_holidays_report(osv.osv): + _name = "hr.holidays.report" + _auto = False + _columns = { + 'employee_id': fields.many2one ('hr.employee', 'Employee', readonly=True), + 'holiday_status_id': fields.many2one('hr.holidays.status', 'Leave Type', readonly=True), + # 'max_leave': fields.float('Allocated Leaves', readonly=True), +# 'taken_leaves': fields.float('Taken Leaves', readonly=True), + 'remaining_leave': fields.float('Remaining Leaves',readonly=True), + } + def init(self, cr): + tools.drop_view_if_exists(cr, 'hr_holidays_report') + cr.execute(""" + create or replace view hr_holidays_report as ( + select + min(h.id) as id, + h.employee_id as employee_id, + h.holiday_status_id as holiday_status_id, + sum(number_of_days) as remaining_leave + from + hr_holidays h + left join hr_holidays_status s on (s.id = h.holiday_status_id) + where h.state = 'validate' + and h.employee_id is not null + and s.active <> 'f' + group by h.holiday_status_id, h.employee_id + )""") +hr_holidays_report() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py index e0cb697b3b9..c61e8f733b4 100644 --- a/addons/hr_holidays/report/holidays_summary_report.py +++ b/addons/hr_holidays/report/holidays_summary_report.py @@ -44,7 +44,6 @@ def strToDate(dt): def emp_create_xml(self,cr,uid,dept,holiday_type,row_id,empid,name,som,eom): display={} - if dept==0: count=0 p_id=pooler.get_pool(cr.dbname).get('hr.holidays').search(cr,uid,[('employee_id','in',[empid,False]), ('type', '=', 'remove')]) diff --git a/addons/hr_holidays/security/ir.model.access.csv b/addons/hr_holidays/security/ir.model.access.csv index 236b6a8fb89..a7426724594 100644 --- a/addons/hr_holidays/security/ir.model.access.csv +++ b/addons/hr_holidays/security/ir.model.access.csv @@ -1,5 +1,5 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" -"access_hr_holydays_status_user","hr.holidays.status user","model_hr_holidays_status","hr.group_hr_user",1,1,1,1 -"access_hr_holidays_user","hr holidays user","model_hr_holidays","hr.group_hr_user",1,1,1,1 -"access_hr_holidays_per_user","hr.holidays.per.user","model_hr_holidays_per_user","hr.group_hr_user",1,1,1,1 -"access_hr_holidays_report","hr.holidays.report","model_hr_holidays_report","hr.group_hr_user",1,1,1,1 +"access_hr_holydays_status_user","hr.holidays.status user","model_hr_holidays_status","hr.group_hr_user",1,0,0,0 +"access_hr_holidays_user","hr holidays user","model_hr_holidays","hr.group_hr_user",1,1,1,0 +"access_hr_holydays_status_manager","hr.holidays.status manager","model_hr_holidays_status","hr.group_hr_manager",1,1,1,1 +"access_hr_holidays_manager","hr holidays manager","model_hr_holidays","hr.group_hr_manager",1,1,1,1 From 939f4652d70c33f742c0d69172c1902a5b36ef5c Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 18 Mar 2010 01:22:17 +0100 Subject: [PATCH 35/38] multicompany fix default res_partner_address.company_id bzr revid: al@openerp.com-20100318002217-1w71naain7tegsm3 --- bin/addons/base/res/partner/partner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py index d2024294059..a5f76b80390 100644 --- a/bin/addons/base/res/partner/partner.py +++ b/bin/addons/base/res/partner/partner.py @@ -309,6 +309,7 @@ class res_partner_address(osv.osv): } _defaults = { 'active': lambda *a: 1, + 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c), } def name_get(self, cr, user, ids, context={}): From d53d5a8d259c14185ad34202564c528792f36e55 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 18 Mar 2010 03:04:46 +0100 Subject: [PATCH 36/38] browse now handles reference update ir_ui_menu accordingly bzr revid: al@openerp.com-20100318020446-ae811kivbamg8shd --- bin/addons/base/ir/ir_ui_menu.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/addons/base/ir/ir_ui_menu.py b/bin/addons/base/ir/ir_ui_menu.py index 78c86a8569e..cb2e91e7671 100644 --- a/bin/addons/base/ir/ir_ui_menu.py +++ b/bin/addons/base/ir/ir_ui_menu.py @@ -100,8 +100,10 @@ class ir_ui_menu(osv.osv): if menu.action: # we check if the user has access to the action of the menu - m, oid = menu.action.split(',', 1) - data = self.pool.get(m).browse(cr, 1, int(oid)) + #m, oid = menu.action.split(',', 1) + #data = self.pool.get(m).browse(cr, 1, int(oid)) + data = menu.action + m = data._name if data: model_field = { 'ir.actions.act_window': 'res_model', From c1dbb155edc903461dc376ff7b71f85013435651 Mon Sep 17 00:00:00 2001 From: Launchpad Code Hosting Date: Thu, 18 Mar 2010 04:34:35 +0000 Subject: [PATCH 37/38] Launchpad automatic translations update. bzr revid: codehost@crowberry-20100318043435-zdw3mpmw0lvtjh7e --- bin/addons/base/i18n/hr.po | 4 ++-- bin/addons/base/i18n/ja.po | 4 ++-- bin/addons/base/i18n/ro.po | 4 ++-- bin/addons/base/i18n/sv.po | 4 ++-- bin/addons/base/i18n/uk.po | 4 ++-- bin/addons/base/i18n/zh_CN.po | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bin/addons/base/i18n/hr.po b/bin/addons/base/i18n/hr.po index 897cc4ed51c..96d5ca04a71 100644 --- a/bin/addons/base/i18n/hr.po +++ b/bin/addons/base/i18n/hr.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-16 05:10+0000\n" +"PO-Revision-Date: 2010-03-17 05:13+0000\n" "Last-Translator: goranc \n" "Language-Team: openerp-translators\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-17 04:39+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Language: hr\n" diff --git a/bin/addons/base/i18n/ja.po b/bin/addons/base/i18n/ja.po index 8721b79b2c4..22fb11fc66a 100644 --- a/bin/addons/base/i18n/ja.po +++ b/bin/addons/base/i18n/ja.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-16 05:09+0000\n" +"PO-Revision-Date: 2010-03-17 05:14+0000\n" "Last-Translator: Harry (Open ERP) \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-17 04:39+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:33+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/ro.po b/bin/addons/base/i18n/ro.po index f2d25122948..12bd218dcb8 100644 --- a/bin/addons/base/i18n/ro.po +++ b/bin/addons/base/i18n/ro.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-16 16:14+0000\n" +"PO-Revision-Date: 2010-03-17 05:16+0000\n" "Last-Translator: Valentin Caragea \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-17 04:39+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/sv.po b/bin/addons/base/i18n/sv.po index d2b3d972b83..ffafa36c6b0 100644 --- a/bin/addons/base/i18n/sv.po +++ b/bin/addons/base/i18n/sv.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-16 05:11+0000\n" +"PO-Revision-Date: 2010-03-17 05:09+0000\n" "Last-Translator: Anders Wallenquist \n" "Language-Team: <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-17 04:39+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/uk.po b/bin/addons/base/i18n/uk.po index 10a8a3edf9f..55cbba030fc 100644 --- a/bin/addons/base/i18n/uk.po +++ b/bin/addons/base/i18n/uk.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-16 05:11+0000\n" +"PO-Revision-Date: 2010-03-17 05:13+0000\n" "Last-Translator: Fabien (Open ERP) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-17 04:39+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/zh_CN.po b/bin/addons/base/i18n/zh_CN.po index 8e6c890c2d9..147fb54dc58 100644 --- a/bin/addons/base/i18n/zh_CN.po +++ b/bin/addons/base/i18n/zh_CN.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-16 05:12+0000\n" +"PO-Revision-Date: 2010-03-17 05:11+0000\n" "Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-17 04:39+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base From 07272579b5f971aecd9e9ceca89f7c4699d3d7dd Mon Sep 17 00:00:00 2001 From: Launchpad Code Hosting Date: Thu, 18 Mar 2010 04:35:07 +0000 Subject: [PATCH 38/38] Launchpad automatic translations update. bzr revid: codehost@crowberry-20100318043507-w84bqsim7u0bs25a --- addons/account/i18n/cs.po | 16 +- addons/account/i18n/fi.po | 750 +++++++++++------------ addons/account_anglo_saxon/i18n/hi.po | 64 ++ addons/account_balance/i18n/pt_BR.po | 58 +- addons/account_tax_include/i18n/fi.po | 53 ++ addons/base_module_quality/i18n/zh_CN.po | 10 +- addons/base_report_creator/i18n/hr.po | 14 +- addons/board_account/i18n/sv.po | 8 +- addons/event_project/i18n/hi.po | 8 +- addons/idea/i18n/ro.po | 8 +- addons/mrp_subproduct/i18n/fi.po | 89 +++ addons/multi_company/i18n/fi.po | 192 ++++++ addons/report_document/i18n/it.po | 16 +- 13 files changed, 832 insertions(+), 454 deletions(-) create mode 100644 addons/account_anglo_saxon/i18n/hi.po create mode 100644 addons/account_tax_include/i18n/fi.po create mode 100644 addons/mrp_subproduct/i18n/fi.po create mode 100644 addons/multi_company/i18n/fi.po diff --git a/addons/account/i18n/cs.po b/addons/account/i18n/cs.po index b1394d47d19..932d4e3cf3d 100644 --- a/addons/account/i18n/cs.po +++ b/addons/account/i18n/cs.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2010-01-13 11:48+0000\n" -"Last-Translator: Kuvaly [LCT] \n" +"PO-Revision-Date: 2010-03-17 20:55+0000\n" +"Last-Translator: mitev.dmitry \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 04:49+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: account @@ -154,7 +154,7 @@ msgstr "Položky" #. module: account #: selection:account.move.line,centralisation:0 msgid "Debit Centralisation" -msgstr "" +msgstr "Debetní Centralizace" #. module: account #: model:ir.actions.wizard,name:account.wizard_invoice_state_confirm @@ -257,7 +257,7 @@ msgstr "Celkový dluh" #. module: account #: rml:account.tax.code.entries:0 msgid "Accounting Entries-" -msgstr "" +msgstr "Účetní zápisy" #. module: account #: help:account.journal,view_id:0 @@ -299,7 +299,7 @@ msgstr "Zpožděné platby" #: wizard_view:account.analytic.account.quantity_cost_ledger.report,init:0 #: wizard_view:account.vat.declaration,init:0 msgid "Select period" -msgstr "" +msgstr "Vyberte období" #. module: account #: field:account.invoice,origin:0 @@ -384,7 +384,7 @@ msgstr "Celkové částky" #: field:account.fiscal.position.account,account_src_id:0 #: field:account.fiscal.position.account.template,account_src_id:0 msgid "Account Source" -msgstr "" +msgstr "Zdroj účtu" #. module: account #: field:account.journal,update_posted:0 @@ -420,7 +420,7 @@ msgstr "" #. module: account #: rml:account.partner.balance:0 msgid "(Account/Partner) Name" -msgstr "" +msgstr "(Účet / Partner) Název" #. module: account #: selection:account.move,type:0 diff --git a/addons/account/i18n/fi.po b/addons/account/i18n/fi.po index f2364683845..26a51ff5469 100644 --- a/addons/account/i18n/fi.po +++ b/addons/account/i18n/fi.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2010-03-02 11:01+0000\n" -"Last-Translator: smii \n" +"PO-Revision-Date: 2010-03-16 13:30+0000\n" +"Last-Translator: Henri Kovalainen \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 04:50+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: account @@ -97,7 +97,7 @@ msgstr "Suorittamattomat tapahtumat" #: field:account.tax,base_code_id:0 #: field:account.tax.template,base_code_id:0 msgid "Base Code" -msgstr "Perustekoodi" +msgstr "Peruskoodi" #. module: account #: view:account.account:0 @@ -131,7 +131,7 @@ msgstr "Jäännös" #: field:account.tax.template,base_sign:0 #: field:account.tax.template,ref_base_sign:0 msgid "Base Code Sign" -msgstr "Perustekoodin merkki" +msgstr "Peruskoodin merkki" #. module: account #: model:ir.actions.wizard,name:account.wizard_unreconcile_select @@ -183,7 +183,7 @@ msgstr "Summa kredit" #. module: account #: field:account.config.wizard,charts:0 msgid "Charts of Account" -msgstr "Tilikartta" +msgstr "Tilikartat" #. module: account #: model:ir.actions.wizard,name:account.wizard_move_line_select @@ -334,7 +334,7 @@ msgstr "Viite" #. module: account #: wizard_view:account.subscription.generate,init:0 msgid "Subscription Compute" -msgstr "Ennakkomaksun arvio" +msgstr "Laske ennakkomaksut" #. module: account #: rml:account.central.journal:0 @@ -500,8 +500,8 @@ msgid "" "Set if the amount of tax must be included in the base amount before " "computing the next taxes." msgstr "" -"Aseta jos veromäärä täytyy sisältyä perusmäärään ennen seuraavien verojen " -"laskemista" +"Aseta jos veron määrä täytyy sisällyttää perusmäärään ennen seuraavien " +"verojen laskemista." #. module: account #: model:ir.ui.menu,name:account.menu_finance_periodical_processing @@ -517,7 +517,7 @@ msgstr "Analyyttisten merkintöjen tilastot" #: model:ir.actions.act_window,name:account.action_account_tax_code_template_form #: model:ir.ui.menu,name:account.menu_action_account_tax_code_template_form msgid "Tax Code Templates" -msgstr "Verokoodipohjat" +msgstr "Verokoodimallit" #. module: account #: view:account.invoice:0 @@ -528,7 +528,7 @@ msgstr "Toimittajan lasku" #: model:process.transition,name:account.process_transition_reconcilepaid0 #: model:process.transition,name:account.process_transition_supplierreconcilepaid0 msgid "Reconcile Paid" -msgstr "Kirjaa maksetut tapahtumat" +msgstr "Suorita maksetut" #. module: account #: wizard_field:account.chart,init,target_move:0 @@ -539,12 +539,12 @@ msgstr "Kohteen liikkeet" #: model:ir.actions.act_window,name:account.action_account_tax_template_form #: model:ir.ui.menu,name:account.menu_action_account_tax_template_form msgid "Tax Templates" -msgstr "Veropohjat" +msgstr "Veromallit" #. module: account #: field:account.invoice,reconciled:0 msgid "Paid/Reconciled" -msgstr "Maksettu/kirjattu" +msgstr "Maksettu/Suoritettu" #. module: account #: field:account.account.type,close_method:0 @@ -554,7 +554,7 @@ msgstr "Jaksotusmenetelmä" #. module: account #: field:account.tax.template,include_base_amount:0 msgid "Include in Base Amount" -msgstr "Sisällytä pohjamäärään" +msgstr "Sisällytä perusmäärään" #. module: account #: field:account.tax,ref_base_code_id:0 @@ -601,7 +601,7 @@ msgstr "Tulostuspäivämäärä" #. module: account #: rml:account.general.ledger:0 msgid "Mvt" -msgstr "" +msgstr "Mvt" #. module: account #: model:ir.actions.wizard,name:account.wizard_aged_trial_balance @@ -632,7 +632,7 @@ msgstr "Jätä tyhjäksi avataksesi nykyisen tilanteen" #. module: account #: model:ir.model,name:account.model_account_fiscal_position_account msgid "Fiscal Position Accounts Mapping" -msgstr "Verotuksen sijainti tilikartoituksessa" +msgstr "Talouskannan tilien kartoitus" #. module: account #: field:account.analytic.account,contact_id:0 @@ -648,7 +648,7 @@ msgstr "Kumppani maksutermi" #. module: account #: view:account.move.reconcile:0 msgid "Account Entry Reconcile" -msgstr "Tilin merkintä sovittelu" +msgstr "Tilimerkintöjen suoritus" #. module: account #: wizard_button:account.move.bank.reconcile,init,open:0 @@ -664,12 +664,12 @@ msgstr "Alennus (%)" #: wizard_field:account.move.line.reconcile,init_full,writeoff:0 #: wizard_field:account.move.line.reconcile,init_partial,writeoff:0 msgid "Write-Off amount" -msgstr "Poiston määrä" +msgstr "Arvonalennuksen määrä" #. module: account #: help:account.fiscalyear,company_id:0 msgid "Keep empty if the fiscal year belongs to several companies." -msgstr "Jätä tyhjäksi jos verovuosi kuuluu useammalle yritykselle." +msgstr "Jätä tyhjäksi jos tilikausi kuuluu useammalle yritykselle." #. module: account #: model:ir.ui.menu,name:account.menu_analytic_accounting @@ -751,7 +751,7 @@ msgstr "Kentän nimi" #: field:account.tax.code,sign:0 #: field:account.tax.code.template,sign:0 msgid "Sign for parent" -msgstr "Kirjaudu tämänhetkiseen" +msgstr "Etumerkki ylemmälle" #. module: account #: field:account.fiscalyear,end_journal_period_id:0 @@ -762,7 +762,7 @@ msgstr "Päätösmerkintöjen päiväkirja" #: view:product.product:0 #: view:product.template:0 msgid "Purchase Properties" -msgstr "Osto tarpeisto" +msgstr "Ostojen ominaisuudet" #. module: account #: model:process.node,note:account.process_node_paymententries0 @@ -819,7 +819,7 @@ msgstr "Maksu tilikirja" #: wizard_view:account.partner.balance.report,init:0 #: wizard_view:account.third_party_ledger.report,init:0 msgid "(Keep empty for all open fiscal years)" -msgstr "(Jätä tyhjäksi kaikille avoimille verovuosille)" +msgstr "(Jätä tyhjäksi käyttääksesi kaikkia avoimia tilikausia)" #. module: account #: field:account.invoice,move_lines:0 @@ -859,7 +859,7 @@ msgstr "Pankki sovinto" #. module: account #: model:ir.model,name:account.model_account_account_template msgid "Templates for Accounts" -msgstr "Tilipohjat" +msgstr "Tilimallit" #. module: account #: model:ir.actions.act_window,name:account.action_account_analytic_account_form @@ -905,7 +905,7 @@ msgstr "Menotili" #. module: account #: wizard_field:account.move.line.reconcile,addendum,journal_id:0 msgid "Write-Off Journal" -msgstr "Poistojen päiväkirja" +msgstr "Arvonalennuspäiväkirja" #. module: account #: field:account.model.line,amount_currency:0 @@ -921,7 +921,7 @@ msgstr "Menoluokkatili" #. module: account #: wizard_field:account.fiscalyear.close,init,fy2_id:0 msgid "New Fiscal Year" -msgstr "Uusi verovuosi" +msgstr "Uusi tilikausi" #. module: account #: help:account.tax,tax_group:0 @@ -935,12 +935,12 @@ msgstr "" #. module: account #: wizard_field:account.open_closed_fiscalyear,init,fyear_id:0 msgid "Fiscal Year to Open" -msgstr "Verovuoden avaus" +msgstr "Avattava tilikausi" #. module: account #: view:account.config.wizard:0 msgid "Select Chart of Accounts" -msgstr "Valitse kaavio tileistä" +msgstr "Valitse tilikartta" #. module: account #: field:account.analytic.account,quantity:0 @@ -1035,7 +1035,7 @@ msgstr "Netto:" #: model:ir.model,name:account.model_account_fiscal_position #: field:res.partner,property_account_position:0 msgid "Fiscal Position" -msgstr "Verosijainti" +msgstr "Talouskanta" #. module: account #: field:account.analytic.line,product_uom_id:0 @@ -1057,7 +1057,7 @@ msgstr "Alatilit" #. module: account #: model:ir.model,name:account.model_account_fiscal_position_tax msgid "Fiscal Position Taxes Mapping" -msgstr "Verosijainin verokartoitus" +msgstr "Talouskannan verojen kartoitus" #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree2_new @@ -1080,7 +1080,7 @@ msgstr "Asiakaslasku" #. module: account #: wizard_view:account.open_closed_fiscalyear,init:0 msgid "Choose Fiscal Year" -msgstr "Valitse verovuosi" +msgstr "Valitse tilikausi" #. module: account #: field:account.sequence.fiscalyear,sequence_main_id:0 @@ -1110,7 +1110,7 @@ msgstr "" #. module: account #: field:account.bank.statement.reconcile,total_new:0 msgid "Total write-off" -msgstr "Poistot yhteensä" +msgstr "Arvonalennus yhteensä" #. module: account #: view:account.tax.template:0 @@ -1129,7 +1129,7 @@ msgstr "Varokoodit" #: field:account.tax.template,chart_template_id:0 #: field:wizard.multi.charts.accounts,chart_template_id:0 msgid "Chart Template" -msgstr "Tilikartan mallipohja" +msgstr "Tilikarttamalli" #. module: account #: field:account.chart.template,property_account_income_categ:0 @@ -1146,7 +1146,7 @@ msgstr "Uusi analyyttinen tili" #: model:ir.actions.act_window,name:account.action_account_fiscal_position_template_form #: model:ir.ui.menu,name:account.menu_action_account_fiscal_position_form_template msgid "Fiscal Position Templates" -msgstr "" +msgstr "Talouskantojen mallit" #. module: account #: rml:account.invoice:0 @@ -1172,13 +1172,13 @@ msgstr "Myyntipäiväkirja" #. module: account #: help:account.model.line,amount_currency:0 msgid "The amount expressed in an optional other currency." -msgstr "Määrä valinnaisena valuuttana." +msgstr "Summa ilmoitettuna valinnaisessa toisessa valuutassa." #. module: account #: view:account.fiscal.position.template:0 #: field:account.fiscal.position.template,name:0 msgid "Fiscal Position Template" -msgstr "" +msgstr "Talouskannan malli" #. module: account #: field:account.payment.term,line_ids:0 @@ -1194,12 +1194,12 @@ msgstr "Veroraportti" #: wizard_button:account.analytic.account.chart,init,open:0 #: wizard_button:account.chart,init,open:0 msgid "Open Charts" -msgstr "Avoimet kaaviot" +msgstr "Avoimet kartat" #. module: account #: wizard_view:account.fiscalyear.close.state,init:0 msgid "Are you sure you want to close the fiscal year ?" -msgstr "Oletko varma että haluat sulkea verovuoden?" +msgstr "Oletko varma että haluat sulkea tilikauden?" #. module: account #: selection:account.move,type:0 @@ -1249,17 +1249,17 @@ msgstr "Yritysvaluutta" #. module: account #: model:ir.model,name:account.model_account_fiscal_position_account_template msgid "Fiscal Position Template Account Mapping" -msgstr "" +msgstr "Talouskannan mallin tilien kartoitukset" #. module: account #: field:account.analytic.account,parent_id:0 msgid "Parent Analytic Account" -msgstr "" +msgstr "Ylempi analyyttinen tili" #. module: account #: wizard_button:account.move.line.reconcile,init_partial,addendum:0 msgid "Reconcile With Write-Off" -msgstr "" +msgstr "Suorita arvonalennuksella" #. module: account #: field:account.move.line,tax_amount:0 @@ -1300,12 +1300,12 @@ msgstr "Analyyttinen luotto" #: field:account.move.line,reconcile_partial_id:0 #: wizard_button:account.move.line.reconcile,init_partial,partial:0 msgid "Partial Reconcile" -msgstr "Osittainen sovitus" +msgstr "Osittaissuoritus" #. module: account #: wizard_field:account.automatic.reconcile,reconcile,unreconciled:0 msgid "Not reconciled transactions" -msgstr "Ei sovitettu transaktio" +msgstr "Suorittamattomat tapahtumat" #. module: account #: view:account.fiscal.position:0 @@ -1328,7 +1328,7 @@ msgstr "Arvo" #: wizard_field:account.invoice.pay,addendum,writeoff_acc_id:0 #: wizard_field:account.move.line.reconcile,addendum,writeoff_acc_id:0 msgid "Write-Off account" -msgstr "Poistotili" +msgstr "Arvonalennustili" #. module: account #: field:account.model.line,model_id:0 @@ -1340,12 +1340,12 @@ msgstr "Malli" #: model:ir.actions.wizard,name:account.wizard_fiscalyear_close_state #: model:ir.ui.menu,name:account.menu_wizard_fy_close_state msgid "Close a Fiscal Year" -msgstr "Sulje verovuosi" +msgstr "Sulje tilikausi" #. module: account #: field:account.journal,centralisation:0 msgid "Centralised counterpart" -msgstr "" +msgstr "Keskitetty vastine" #. module: account #: view:wizard.company.setup:0 @@ -1398,6 +1398,8 @@ msgid "" "If you unreconciliate transactions, you must also verify all the actions " "that are linked to those transactions because they will not be disable" msgstr "" +"Jos poistat suorituksia siirroista, sinun tulee myös varmistaa kaikki " +"siirtoihin liittyvät toiminnot koska niitä ei poisteta" #. module: account #: model:process.node,name:account.process_node_electronicfile0 @@ -1417,7 +1419,7 @@ msgstr "Verorivit" #. module: account #: field:ir.sequence,fiscal_ids:0 msgid "Sequences" -msgstr "" +msgstr "Sarjat" #. module: account #: model:ir.actions.act_window,name:account.action_account_type_form @@ -1472,7 +1474,7 @@ msgstr "Näytä tilit " #. module: account #: model:ir.model,name:account.model_account_bank_statement_reconcile_line msgid "Statement reconcile line" -msgstr "Tiliotteen sovittelurivi" +msgstr "Tiliotteen suoritusrivi" #. module: account #: view:account.tax:0 @@ -1486,7 +1488,7 @@ msgstr "Jätä tyhjäksi käyttääksesi tulotiliä" #: wizard_view:account.move.line.reconcile,init_full:0 #: wizard_view:account.move.line.reconcile,init_partial:0 msgid "Write-Off" -msgstr "Poisto" +msgstr "Arvonalennus" #. module: account #: help:account.invoice,partner_bank:0 @@ -1500,7 +1502,7 @@ msgstr "" #. module: account #: field:res.partner,debit:0 msgid "Total Payable" -msgstr "Maksettava yhteensä" +msgstr "Maksettavat yhteensä" #. module: account #: wizard_button:account.fiscalyear.close.state,init,close:0 @@ -1520,7 +1522,7 @@ msgstr "account.analytic.line.extended" #. module: account #: field:account.journal,refund_journal:0 msgid "Refund Journal" -msgstr "Hyvitysloki" +msgstr "Hyvityspäiväkirja" #. module: account #: model:account.account.type,name:account.account_type_income @@ -1558,7 +1560,7 @@ msgstr "Tulosta yleinen päiväkirja" #: model:ir.actions.act_window,name:account.action_account_chart_template_form #: model:ir.ui.menu,name:account.menu_action_account_chart_template_form msgid "Chart of Accounts Templates" -msgstr "Tilikarttapohjat" +msgstr "Tilikarttamallit" #. module: account #: field:account.invoice,move_id:0 @@ -1570,7 +1572,7 @@ msgstr "Laskun liikehdintä" #: model:ir.ui.menu,name:account.menu_wizard #: view:wizard.multi.charts.accounts:0 msgid "Generate Chart of Accounts from a Chart Template" -msgstr "Luo tilikartta mallipohjasta" +msgstr "Luo tilikartta mallista" #. module: account #: model:ir.ui.menu,name:account.menu_finance_legal_statement @@ -1581,7 +1583,7 @@ msgstr "Lailliset lausunnot" #: field:account.tax.code,parent_id:0 #: field:account.tax.code.template,parent_id:0 msgid "Parent Code" -msgstr "" +msgstr "Ylempi koodi" #. module: account #: wizard_button:account.move.line.reconcile.select,init,open:0 @@ -1613,20 +1615,20 @@ msgstr "Jätä tyhjäksi jos haluat käyttää kulutiliä" #. module: account #: wizard_field:account.automatic.reconcile,init,account_ids:0 msgid "Account to reconcile" -msgstr "Tili jolle kirjaukset tehdään" +msgstr "Tili suorituksille" #. module: account #: rml:account.invoice:0 #: field:account.model.line,partner_id:0 #: field:account.move.line,partner_id:0 msgid "Partner Ref." -msgstr "" +msgstr "Kumppanin viite" #. module: account #: selection:account.partner.balance.report,init,result_selection:0 #: selection:account.third_party_ledger.report,init,result_selection:0 msgid "Receivable and Payable Accounts" -msgstr "Vastaavien ja vastattavien tilit" +msgstr "Saatavat ja maksettavat tilit" #. module: account #: view:account.subscription:0 @@ -1757,7 +1759,7 @@ msgstr "Sivuluotto" #: model:ir.actions.wizard,name:account.wizard_reconcile_unreconcile #: model:ir.actions.wizard,name:account.wizard_unreconcile msgid "Unreconcile Entries" -msgstr "Ei sovitetut merkinnät" +msgstr "Poista merkintöjen suoritukset" #. module: account #: model:process.node,note:account.process_node_supplierdraftinvoices0 @@ -1779,7 +1781,7 @@ msgstr "Uusi tiliote" #: wizard_field:account.analytic.account.chart,init,from_date:0 #: wizard_field:account.analytic.line,init,from_date:0 msgid "From" -msgstr "" +msgstr "Mistä" #. module: account #: model:process.node,note:account.process_node_reconciliation0 @@ -1809,7 +1811,7 @@ msgstr "Prosentti" #. module: account #: model:ir.ui.menu,name:account.menu_finance_charts msgid "Charts" -msgstr "Kaaviot" +msgstr "Tilikartat" #. module: account #: selection:account.analytic.journal,type:0 @@ -1830,7 +1832,7 @@ msgstr "Seuraava" msgid "" "The fiscal position will determine taxes and the accounts used for the the " "partner." -msgstr "" +msgstr "Talouskanta määrittelee kumppaniin sovellettavat verot ja tilit." #. module: account #: rml:account.analytic.account.cost_ledger:0 @@ -1883,7 +1885,7 @@ msgstr "Aloituspäivä" #. module: account #: model:account.journal,name:account.refund_expenses_journal msgid "x Expenses Credit Notes Journal" -msgstr "Hyvityslaskujen kulupäiväkirja" +msgstr "x Hyvityslaskujen kulupäiväkirja" #. module: account #: field:account.analytic.journal,type:0 @@ -1926,7 +1928,7 @@ msgstr "Maksa lasku" #. module: account #: constraint:account.invoice:0 msgid "Error: Invalid Bvr Number (wrong checksum)." -msgstr "" +msgstr "Virhe: Virheellinen BVR-numero (väärä tarkistussumma)." #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree5 @@ -1960,7 +1962,7 @@ msgstr "Kumppanin viite tässä laskussa." #. module: account #: wizard_field:account.general.ledger.report,checktype,sortbydate:0 msgid "Sort by:" -msgstr "" +msgstr "Järjestys:" #. module: account #: field:account.move,to_check:0 @@ -1990,7 +1992,7 @@ msgstr "Li" #. module: account #: wizard_view:account.chart,init:0 msgid "Account charts" -msgstr "Tilikaaviot" +msgstr "Tilikartat" #. module: account #: help:account.tax,name:0 @@ -2032,7 +2034,7 @@ msgstr "Verotili" #. module: account #: rml:account.analytic.account.quantity_cost_ledger:0 msgid "J.C./Move name" -msgstr "" +msgstr "J.C. / Siirron nimi" #. module: account #: field:account.journal.period,name:0 @@ -2149,7 +2151,7 @@ msgstr "Maksamattomat laskut" #. module: account #: model:process.transition,name:account.process_transition_paymentreconcile0 msgid "Payment Reconcile" -msgstr "Maksun sovittelu" +msgstr "Maksun suoritusmerkinnät" #. module: account #: model:ir.actions.act_window,name:account.action_bank_statement_reconciliation_form @@ -2192,7 +2194,7 @@ msgstr "Arvon määrä" #. module: account #: model:ir.actions.act_window,name:account.act_account_acount_move_line_reconcile_open msgid "Reconciled entries" -msgstr "Sovitetut merkinnät" +msgstr "Suoritetut merkinnät" #. module: account #: field:account.invoice,address_contact_id:0 @@ -2229,7 +2231,7 @@ msgstr "Yksityiskohdat" #: selection:account.account,type:0 #: selection:account.account.template,type:0 msgid "Consolidation" -msgstr "Vahvistaminen" +msgstr "Yhdistetty" #. module: account #: field:account.chart.template,account_root_id:0 @@ -2243,6 +2245,8 @@ msgid "" "stay unpaid. Please, take appropriate measures in order to carry out this " "payment in the next 8 days." msgstr "" +"Seuraavat laskut ovat edelleen maksamatta. Ole hyvä ja maksa nämä laskut " +"seuraavan 8 päivän kuluessa." #. module: account #: rml:account.invoice:0 @@ -2256,28 +2260,28 @@ msgstr "ALV:" #: model:ir.ui.menu,name:account.menu_action_account_tree #: model:ir.ui.menu,name:account.menu_action_account_tree2 msgid "Chart of Accounts" -msgstr "Tilikaaviot" +msgstr "Tilikartat" #. module: account #: model:account.journal,name:account.check_journal msgid "x Checks Journal" -msgstr "" +msgstr "x Shekkipäiväkirja" #. module: account #: model:ir.actions.wizard,name:account.wizard_generate_subscription #: model:ir.ui.menu,name:account.menu_generate_subscription msgid "Create subscription entries" -msgstr "Luo ennakkomaksukohdat" +msgstr "Luo ennakkomaksun merkinnät" #. module: account #: wizard_field:account.fiscalyear.close,init,journal_id:0 msgid "Opening Entries Journal" -msgstr "Avataan merkintälokea" +msgstr "Avauspäiväkirja" #. module: account #: view:account.config.wizard:0 msgid "Create a Fiscal Year" -msgstr "Luo verovuosi" +msgstr "Luo uusi tilikausi" #. module: account #: field:product.template,taxes_id:0 @@ -2311,7 +2315,7 @@ msgstr "2" #. module: account #: wizard_view:account.chart,init:0 msgid "(If you do not select Fiscal year it will take all open fiscal years)" -msgstr "(Jos et valitse verovuotta se ottaa kaikki avoimet verovuodet)" +msgstr "(Jos et valitse tilikautta, käytetään kaikkia avoimia tilikausia)" #. module: account #: help:account.invoice.tax,base_code_id:0 @@ -2347,7 +2351,7 @@ msgstr "Viitetyyppi" #: wizard_button:account.move.line.unreconcile,init,unrec:0 #: wizard_button:account.reconcile.unreconcile,init,unrec:0 msgid "Unreconcile" -msgstr "Sovittelematon" +msgstr "Poista suoritukset" #. module: account #: field:account.tax,type:0 @@ -2375,12 +2379,12 @@ msgstr "Tilimallit" #. module: account #: view:account.chart.template:0 msgid "Chart of Accounts Template" -msgstr "Tilimallikartat" +msgstr "Tilikarttamalli" #. module: account #: model:account.journal,name:account.refund_sales_journal msgid "Journal d'extourne" -msgstr "Lokikirja d'extourne" +msgstr "Palautuspäiväkirja" #. module: account #: rml:account.journal.period.print:0 @@ -2401,7 +2405,7 @@ msgstr "Tuo lasku" #. module: account #: wizard_view:account.analytic.account.quantity_cost_ledger.report,init:0 msgid "and Journals" -msgstr "" +msgstr "ja päiväkirjat" #. module: account #: view:account.tax:0 @@ -2424,13 +2428,12 @@ msgid "" "Set if the tax computation is based on the computation of child taxes rather " "than on the total amount." msgstr "" -"Aseta jos verolaskelmat perustuvat mieluummin alaverokohtiin kuin " -"lopulliseen määrään." +"Määritä perustuuko verojen laskenta alemmille veroille vai loppusummaan." #. module: account #: rml:account.central.journal:0 msgid "Journal Code" -msgstr "Lokikoodi" +msgstr "Päiväkirjakoodi" #. module: account #: help:account.tax,applicable_type:0 @@ -2468,7 +2471,7 @@ msgstr "Soveltuva koodi (jos tyyppi=koodi)" #. module: account #: wizard_button:account.move.journal,init,open:0 msgid "Open Journal" -msgstr "Avoin loki" +msgstr "Avaa päiväkirja" #. module: account #: rml:account.analytic.account.journal:0 @@ -2481,7 +2484,7 @@ msgstr "" #: model:ir.ui.menu,name:account.account_entries_analytic_entries #: model:ir.ui.menu,name:account.menu_action_move_journal_line_form msgid "Entries Encoding by Line" -msgstr "Kohdat riveittäin" +msgstr "Merkinnät riveittäin" #. module: account #: help:account.chart.template,tax_template_ids:0 @@ -2511,12 +2514,12 @@ msgstr "Lisäsopimustiedot" #: model:process.transition,name:account.process_transition_entriesreconcile0 #: model:process.transition,name:account.process_transition_supplierentriesreconcile0 msgid "Entries Reconcile" -msgstr "Merkintä sovittelu" +msgstr "Merkintöjen suoritus" #. module: account #: help:account.bank.statement.reconcile,total_second_amount:0 msgid "The amount in the currency of the journal" -msgstr "" +msgstr "Summa tämän päiväkirjan valuutassa" #. module: account #: wizard_field:account.general.ledger.report,checktype,landscape:0 @@ -2615,7 +2618,7 @@ msgstr "Veroraportit" #. module: account #: field:res.partner,property_account_payable:0 msgid "Account Payable" -msgstr "Tili maksukelvollinen" +msgstr "Tili maksettavat" #. module: account #: wizard_view:populate_statement_from_inv,init:0 @@ -2635,13 +2638,14 @@ msgstr "Oletus luottotili" #. module: account #: model:process.node,name:account.process_node_supplierpaymentorder0 msgid "Payment Order" -msgstr "Maksujärjestys" +msgstr "Maksumääräys" #. module: account #: help:account.account.template,reconcile:0 msgid "" "Check this option if you want the user to reconcile entries in this account." -msgstr "Valitse tämä jos haluat käyttäjän sovittelevan kohdat tällä tilillä." +msgstr "" +"Valitse tämä jos haluat käyttäjän tekevän suoritusmerkinnät tällä tilillä." #. module: account #: rml:account.analytic.account.journal:0 @@ -2685,6 +2689,11 @@ msgid "" "partners accounts (for debit/credit computations), closed for deprecated " "accounts." msgstr "" +"Tyyppiä käytetään erottamaan tilejä joilla on OpenERP:ssä erityisiä " +"ominaisuuksia: \"näkymä\" ei voi sisältää merkintöjä, \"yhdistetty\" tili " +"muodostuu useammasta alatilistä (esim. useammasta yrityksestä), " +"\"maksettavat\" / \"saatavat\" ovat kumppanien tilejä (käytetään velka-" +"/luottolaskelmiin) ja \"suljettu\" tili on poistettu käytöstä." #. module: account #: model:ir.ui.menu,name:account.menu_account_end_year_treatments @@ -2730,17 +2739,17 @@ msgstr "" #: model:ir.ui.menu,name:account.account_analytic_def_chart #: model:ir.ui.menu,name:account.menu_action_analytic_account_tree2 msgid "Analytic Chart of Accounts" -msgstr "Analyyttienn kaavio tileistä" +msgstr "Analyyttinen tilikartat" #. module: account #: wizard_view:account.analytic.line,init:0 msgid "View Account Analytic Lines" -msgstr "Näytä tilien analyyttisetrivit" +msgstr "Näytä tilin analyyttiset rivit" #. module: account #: wizard_view:account.move.validate,init:0 msgid "Select Period and Journal for Validation" -msgstr "" +msgstr "Valitse jakso ja päiväkirja hyväksymistä varten" #. module: account #: field:account.invoice,number:0 @@ -2772,7 +2781,7 @@ msgstr "Vastaava analyyttinen saldo" #: field:account.tax,applicable_type:0 #: field:account.tax.template,applicable_type:0 msgid "Applicable Type" -msgstr "" +msgstr "Sovellettava tyyppi" #. module: account #: field:account.invoice,reference:0 @@ -2838,7 +2847,7 @@ msgstr "" #: field:account.journal.view,name:0 #: model:ir.model,name:account.model_account_journal_view msgid "Journal View" -msgstr "Lokinäkymä" +msgstr "Päiväkirjanäkymä" #. module: account #: selection:account.move.line,centralisation:0 @@ -2860,7 +2869,7 @@ msgstr "Kumppani tunnus" #: wizard_view:account.invoice.pay,addendum:0 #: wizard_view:account.move.line.reconcile,addendum:0 msgid "Write-Off Move" -msgstr "" +msgstr "Arvonalennussiirto" #. module: account #: view:account.move.line:0 @@ -2978,7 +2987,7 @@ msgstr "Sovittamattomat tapahtumat" #: model:process.transition,note:account.process_transition_paymentorderbank0 #: model:process.transition,note:account.process_transition_paymentorderreconcilation0 msgid "Reconcilation of entries from payment order." -msgstr "" +msgstr "Suoritusten kirjaus maksumääräyksestä." #. module: account #: field:account.bank.statement,move_line_ids:0 @@ -3015,7 +3024,7 @@ msgstr "Verokoodi" #. module: account #: rml:account.analytic.account.journal:0 msgid "Analytic Journal -" -msgstr "Analyyttinen loki -" +msgstr "Analyyttinen päiväkirja -" #. module: account #: rml:account.analytic.account.analytic.check:0 @@ -3045,6 +3054,9 @@ msgid "" "between the date of the creation action or the the date of the creation of " "the entries plus the partner payment terms." msgstr "" +"Luotujen merkintöjen erääntymispäivä tässä mallissa. Voit valita " +"päivämääräksi joko luomispäivän, tai luomispäivän päivämäärän johon lisätään " +"kumppanin maksuehdon mukainen aika." #. module: account #: selection:account.analytic.journal,type:0 @@ -3061,7 +3073,7 @@ msgstr "Dokumentti" #. module: account #: help:account.move.line,move_id:0 msgid "The move of this entry line." -msgstr "Siirry pois tältä merkintäriviltä" +msgstr "Merkinnän rivin siirto." #. module: account #: field:account.invoice.line,uos_id:0 @@ -3071,7 +3083,7 @@ msgstr "Yksikön mitta" #. module: account #: field:account.chart.template,property_account_receivable:0 msgid "Receivable Account" -msgstr "Saatavien tili" +msgstr "Saatavat tili" #. module: account #: help:account.journal,group_invoice_lines:0 @@ -3100,12 +3112,12 @@ msgstr "Peruuta valitut laskut" #: model:ir.actions.report.xml,name:account.analytic_journal_print #: model:ir.actions.wizard,name:account.account_analytic_account_journal_report msgid "Analytic Journal" -msgstr "Analyyttinen loki" +msgstr "Analyyttinen päiväkirja" #. module: account #: rml:account.general.ledger:0 msgid "Entry Label" -msgstr "" +msgstr "Merkinnän nimike" #. module: account #: model:process.transition,note:account.process_transition_paymentreconcile0 @@ -3135,7 +3147,7 @@ msgstr "Dokumentin viite joka on luonut tämän laskun." #: selection:account.account.template,type:0 #: selection:account.aged.trial.balance,init,result_selection:0 msgid "Payable" -msgstr "Maksettava" +msgstr "Maksettavat" #. module: account #: rml:account.invoice:0 @@ -3180,7 +3192,7 @@ msgstr "Ehdotus laskusta tarkistusta, vahvistusta ja tulostusta varten" #. module: account #: model:ir.actions.act_window,name:account.action_move_line_select msgid "account.move.line.select" -msgstr "" +msgstr "account.move.line.select" #. module: account #: view:account.account:0 @@ -3203,7 +3215,7 @@ msgstr "Tili" #. module: account #: model:account.journal,name:account.bank_journal msgid "Journal de Banque CHF" -msgstr "" +msgstr "Pankkipäiväkirja CHF" #. module: account #: selection:account.account.balance.report,checktype,state:0 @@ -3230,6 +3242,8 @@ msgid "" "The account moves of the invoice have been reconciled with account moves of " "the payment(s)." msgstr "" +"Laskun tilisiirtomerkinnät on suoritettu maksun (maksujen) " +"tilisiirtomerkinnöillä." #. module: account #: rml:account.invoice:0 @@ -3244,7 +3258,7 @@ msgstr "Verot" #. module: account #: wizard_view:account.fiscalyear.close,init:0 msgid "Close Fiscal Year with new entries" -msgstr "Sulje verovuosi uusilla merkinnöillä" +msgstr "Sulje tilikausi uusilla merkinnöillä" #. module: account #: selection:account.account,currency_mode:0 @@ -3255,7 +3269,7 @@ msgstr "Keskimääräinen kurssi" #: model:process.node,note:account.process_node_bankstatement0 #: model:process.node,note:account.process_node_supplierbankstatement0 msgid "Statement encoding produces payment entries" -msgstr "Tiliotekoodaus tuottaa maksurivit" +msgstr "Tiliotteen syöttäminen tuottaa maksumerkinnät" #. module: account #: field:account.account,code:0 @@ -3292,17 +3306,17 @@ msgstr "Ei mikään" #: model:ir.actions.wizard,name:account.wizard_fiscalyear_close #: model:ir.ui.menu,name:account.menu_wizard_fy_close msgid "Generate Fiscal Year Opening Entries" -msgstr "" +msgstr "Luo merkinnät tilikauden avaukselle" #. module: account #: model:ir.actions.wizard,name:account.wizard_reconcile msgid "Reconcile Entries" -msgstr "Sovitellut merkinnät" +msgstr "Tee suoritusmerkintöjä" #. module: account #: wizard_view:account.wizard_paid_open,init:0 msgid "(Invoice should be unreconciled if you want to open it)" -msgstr "(Laskun sovitus täytyisi purkaa jos haluat avata sen)" +msgstr "(Laskun suoritusmerkinnät tulisi poistaa jos se halutaan avata)" #. module: account #: view:account.invoice:0 @@ -3319,7 +3333,7 @@ msgstr "Veronimi" #. module: account #: wizard_view:account.fiscalyear.close.state,init:0 msgid " Close states of Fiscal year and periods" -msgstr "" +msgstr " Sulje tilikauden ja jaksojen tilat" #. module: account #: model:account.payment.term,name:account.account_payment_term @@ -3334,7 +3348,7 @@ msgstr "Juuriverokoodi" #. module: account #: constraint:account.invoice:0 msgid "Error: BVR reference is required." -msgstr "" +msgstr "Virhe: BVR-viite on pakollinen." #. module: account #: field:account.tax.code,notprintable:0 @@ -3367,7 +3381,7 @@ msgstr "Kokonais debet" #. module: account #: selection:account.analytic.account,state:0 msgid "Pending" -msgstr "" +msgstr "Odottaa" #. module: account #: view:wizard.multi.charts.accounts:0 @@ -3398,7 +3412,7 @@ msgstr "Kolmannen osapuolen tilikirja" msgid "" "This account will be used instead of the default one as the receivable " "account for the current partner" -msgstr "Tätä tiliä käytetään oletuksen sijaan kumppanin saataville" +msgstr "Tätä tiliä käytetään oletustilin sijasta tämän kumppanin saataville." #. module: account #: selection:account.tax,applicable_type:0 @@ -3446,12 +3460,12 @@ msgstr "Tuo lasku" #: view:wizard.company.setup:0 #: view:wizard.multi.charts.accounts:0 msgid "Create" -msgstr "" +msgstr "Luo" #. module: account #: model:process.transition.action,name:account.process_transition_action_createentries0 msgid "Create entry" -msgstr "Luo tapahtuma" +msgstr "Luo merkintä" #. module: account #: model:ir.model,name:account.model_account_invoice_line @@ -3470,8 +3484,8 @@ msgid "" "All draft account entries in this journal and period will be validated. It " "means you won't be able to modify their accouting fields." msgstr "" -"Kaikki tilin luonnoskohdat tässä lokissa ja jaksossa tarkistetaan. Se " -"tarkoittaa ettet voi muokata niiden tilikenttiä." +"Kaikki luonnostilassa olevat tilimerkinnät tässä päiväkirjassa hyväksytään. " +"Tämä tarkoittaa ettet voi enää muokata niiden tilikenttiä." #. module: account #: selection:account.model.line,date:0 @@ -3485,7 +3499,8 @@ msgid "" "The amount expressed in an optional other currency if it is a multi-currency " "entry." msgstr "" -"Määrä on pakotettu valinnaisessa valuutassa jos se on monivaluutta kohta." +"Summa on ilmoitettu valinnaisessa toisessa valuutassa jos tämä on " +"monivaluuttainen merkintä." #. module: account #: field:account.tax,parent_id:0 @@ -3518,18 +3533,18 @@ msgstr "Jaksojen suodatin" #. module: account #: field:res.partner,property_account_receivable:0 msgid "Account Receivable" -msgstr "Saatava -tili" +msgstr "Tili saatavat" #. module: account #: wizard_button:account.invoice.pay,addendum,reconcile:0 msgid "Pay and reconcile" -msgstr "Maksa ja sovita" +msgstr "Maksa ja suorita" #. module: account #: rml:account.central.journal:0 #: model:ir.actions.report.xml,name:account.account_central_journal msgid "Central Journal" -msgstr "" +msgstr "Keskitetty päiväkirja" #. module: account #: rml:account.third_party_ledger:0 @@ -3540,7 +3555,7 @@ msgstr "Saldoa tuotu eteenpäin" #. module: account #: field:account.account,child_consol_ids:0 msgid "Consolidated Children" -msgstr "Vahvistettu alajaos" +msgstr "Yhdistetyt alatilit" #. module: account #: wizard_field:account.account.balance.report,checktype,fiscalyear:0 @@ -3549,7 +3564,7 @@ msgstr "Vahvistettu alajaos" #: wizard_field:account.partner.balance.report,init,fiscalyear:0 #: wizard_field:account.third_party_ledger.report,init,fiscalyear:0 msgid "Fiscal year" -msgstr "" +msgstr "Tilikausi" #. module: account #: rml:account.overdue:0 @@ -3565,7 +3580,7 @@ msgstr "Saldo ei ole tasan 0" #. module: account #: selection:account.automatic.reconcile,init,power:0 msgid "3" -msgstr "" +msgstr "3" #. module: account #: model:ir.actions.report.xml,name:account.account_vat_declaration @@ -3575,7 +3590,7 @@ msgstr "Veroraportti" #. module: account #: selection:account.journal.period,state:0 msgid "Printed" -msgstr "" +msgstr "Tulostettu" #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree4_new @@ -3586,7 +3601,7 @@ msgstr "Uusi toimittajahyvitys" #. module: account #: view:account.model:0 msgid "Entry Model" -msgstr "Kohdemalli" +msgstr "Merkintämalli" #. module: account #: wizard_field:account.general.ledger.report,checktype,amount_currency:0 @@ -3606,7 +3621,7 @@ msgstr "Ennakkomaksu" #. module: account #: field:account.analytic.journal,code:0 msgid "Journal code" -msgstr "" +msgstr "Päiväkirjakoodi" #. module: account #: wizard_button:account.fiscalyear.close,init,close:0 @@ -3622,12 +3637,12 @@ msgstr "Projektirivi" #. module: account #: wizard_field:account.automatic.reconcile,init,max_amount:0 msgid "Maximum write-off amount" -msgstr "Suurin alennusmäärä" +msgstr "Maksimi arvonalennuksen määrä" #. module: account #: field:account.invoice.tax,manual:0 msgid "Manual" -msgstr "" +msgstr "Manuaalinen" #. module: account #: view:account.invoice:0 @@ -3650,7 +3665,7 @@ msgstr "Tätä maksuehtoa käytetään oletuksen sijaan nykyiselle kumppanille" #: wizard_field:account.invoice.pay,addendum,comment:0 #: wizard_field:account.invoice.pay,init,name:0 msgid "Entry Name" -msgstr "" +msgstr "Merkinnän nimi" #. module: account #: help:account.invoice,account_id:0 @@ -3676,17 +3691,17 @@ msgstr "Valitse tämä jos et halua ALV:tä liitettävän verokoodeihin laskuill #: field:account.tax.template,sequence:0 #: field:fiscalyear.seq,sequence_id:0 msgid "Sequence" -msgstr "" +msgstr "Sarja" #. module: account #: model:ir.model,name:account.model_account_fiscal_position_template msgid "Template for Fiscal Position" -msgstr "" +msgstr "Malli talouskannalle" #. module: account #: view:account.bank.statement:0 msgid "Entry encoding" -msgstr "Kohdan laittaminen" +msgstr "Merkinnän syöttäminen" #. module: account #: wizard_view:account.invoice.refund,init:0 @@ -3697,17 +3712,17 @@ msgstr "Luottoilmoitus" #. module: account #: model:ir.actions.todo,note:account.config_fiscalyear msgid "Define Fiscal Years and Select Charts of Account" -msgstr "" +msgstr "Määrittele tilikausi ja valitse tilikartat" #. module: account #: wizard_field:account.move.line.reconcile,addendum,period_id:0 msgid "Write-Off Period" -msgstr "Alennusjakso" +msgstr "Arvonalennusjakso" #. module: account #: selection:account.config.wizard,period:0 msgid "3 Months" -msgstr "" +msgstr "3 kuukautta" #. module: account #: wizard_view:account.move.journal,init:0 @@ -3732,7 +3747,7 @@ msgstr "Maksuehtorivi" #: selection:account.config.wizard,period:0 #: field:report.hr.timesheet.invoice.journal,name:0 msgid "Month" -msgstr "" +msgstr "Kuukausi" #. module: account #: model:ir.model,name:account.model_account_subscription @@ -3749,7 +3764,7 @@ msgstr "Eräpäivä" #. module: account #: view:account.subscription:0 msgid "Entry Subscription" -msgstr "Ennakkomaksukohta" +msgstr "Ennakkomaksun merkintä" #. module: account #: selection:account.print.journal.report,init,sort_selection:0 @@ -3766,7 +3781,7 @@ msgstr "Tilin ohjattu konfigurointi toiminto " #: field:account.fiscalyear,date_start:0 #: field:account.subscription,date_start:0 msgid "Start Date" -msgstr "" +msgstr "Aloituspäivämäärä" #. module: account #: wizard_view:account.general.ledger.report,account_selection:0 @@ -3777,7 +3792,7 @@ msgstr "Valitse kartta" #: selection:account.chart,init,target_move:0 #: model:ir.actions.report.xml,name:account.account_move_line_list msgid "All Entries" -msgstr "" +msgstr "Kaikki merkinnät" #. module: account #: model:process.node,name:account.process_node_draftinvoices0 @@ -3788,23 +3803,23 @@ msgstr "Luonnostele Laskut" #. module: account #: model:ir.model,name:account.model_account_fiscal_position_tax_template msgid "Fiscal Position Template Tax Mapping" -msgstr "" +msgstr "Talouskannan mallin veron kartoitukset" #. module: account #: rml:account.invoice:0 msgid "Invoice Date" -msgstr "" +msgstr "Laskun päivämäärä" #. module: account #: selection:account.account.type,close_method:0 msgid "Unreconciled" -msgstr "Sovittelematon" +msgstr "Suorittamaton" #. module: account #: field:account.account,note:0 #: field:account.account.template,note:0 msgid "Note" -msgstr "" +msgstr "Huomautus" #. module: account #: model:ir.module.module,description:account.module_meta_information @@ -3832,23 +3847,23 @@ msgstr "" #. module: account #: field:account.journal,sequence_id:0 msgid "Entry Sequence" -msgstr "" +msgstr "Merkinnän sarja" #. module: account #: selection:account.account,type:0 #: selection:account.account.template,type:0 msgid "Closed" -msgstr "" +msgstr "Suljettu" #. module: account #: model:process.node,name:account.process_node_paymententries0 msgid "Payment Entries" -msgstr "" +msgstr "Maksumerkinnät" #. module: account #: help:account.move.line,tax_code_id:0 msgid "The Account can either be a base tax code or tax code account." -msgstr "" +msgstr "Tili voi olla joko perusveron tai verokoodin tili." #. module: account #: help:account.automatic.reconcile,init,account_ids:0 @@ -3869,7 +3884,7 @@ msgstr "Myöhästyneen maksun viesti" #: selection:account.tax,tax_group:0 #: selection:account.tax.template,tax_group:0 msgid "Other" -msgstr "" +msgstr "Muu" #. module: account #: model:ir.actions.report.xml,name:account.account_general_ledger @@ -3882,12 +3897,12 @@ msgstr "Yleinen tilikirja" #. module: account #: field:account.journal.view,columns_id:0 msgid "Columns" -msgstr "" +msgstr "Sarakkeet" #. module: account #: selection:account.general.ledger.report,checktype,sortbydate:0 msgid "Movement" -msgstr "" +msgstr "Siirto" #. module: account #: help:account.period,special:0 @@ -3900,17 +3915,19 @@ msgid "" "This account will be used instead of the default one to value outgoing stock " "for the current product" msgstr "" +"Tätä tiliä käytetään oletustilin sijasta tämän tuotteen lähtevän varaston " +"arvottamiseen." #. module: account #: model:process.node,note:account.process_node_manually0 msgid "Encode manually the statement" -msgstr "" +msgstr "Syötä tiliote manuaalisesti" #. module: account #: model:ir.actions.act_window,name:account.action_account_journal_form #: model:ir.ui.menu,name:account.menu_action_account_journal_form msgid "Financial Journals" -msgstr "" +msgstr "Talouden päiväkirjat" #. module: account #: selection:account.account.balance.report,checktype,state:0 @@ -3928,7 +3945,7 @@ msgstr "Jätä tyhjäksi käyttääksesi nykyistä päivämäärää" #. module: account #: rml:account.overdue:0 msgid "." -msgstr "" +msgstr "." #. module: account #: field:account.analytic.account,quantity_max:0 @@ -3938,7 +3955,7 @@ msgstr "Maksimimäärä" #. module: account #: field:account.period,name:0 msgid "Period Name" -msgstr "" +msgstr "Jakson nimi" #. module: account #: help:account.analytic.journal,type:0 @@ -3947,11 +3964,14 @@ msgid "" "needs to create analytic entries, Open ERP will look for a matching journal " "of the same type." msgstr "" +"Asettaa päiväkirjan tyypin analyyttiseksi. Kun jokin dokumentti (esim. " +"lasku) vaatii analyyttisten merkintöjen kirjausta, OpenERP etsii tämän " +"tyyppisen vastaavan päiväkirjan." #. module: account #: field:account.journal,groups_id:0 msgid "Groups" -msgstr "" +msgstr "Ryhmät" #. module: account #: rml:account.analytic.account.quantity_cost_ledger:0 @@ -3967,7 +3987,7 @@ msgstr "Koodi/Päivämäärä" #: field:account.payment.term,active:0 #: field:account.tax,active:0 msgid "Active" -msgstr "" +msgstr "Aktiivinen" #. module: account #: model:process.node,note:account.process_node_electronicfile0 @@ -3977,7 +3997,7 @@ msgstr "Tuo pankkisi tiliotteista" #. module: account #: view:account.chart.template:0 msgid "Properties" -msgstr "" +msgstr "Ominaisuudet" #. module: account #: view:res.partner:0 @@ -3987,17 +4007,17 @@ msgstr "Asiakkaan kirjanpidon asetukset" #. module: account #: view:account.bank.statement:0 msgid "Select entries" -msgstr "" +msgstr "Valitse merkinnät" #. module: account #: selection:account.chart,init,target_move:0 msgid "All Posted Entries" -msgstr "" +msgstr "Kaikki viedyt merkinnät" #. module: account #: wizard_field:account.vat.declaration,init,based_on:0 msgid "Base on" -msgstr "" +msgstr "Peruste" #. module: account #: selection:account.move,type:0 @@ -4007,7 +4027,7 @@ msgstr "Käteismaksu" #. module: account #: field:account.chart.template,property_account_payable:0 msgid "Payable Account" -msgstr "Maksukelpoinen tili" +msgstr "Maksettavat tili" #. module: account #: field:account.account,currency_id:0 @@ -4033,7 +4053,7 @@ msgstr "Toissijainen valuutta" #: rml:account.vat.declaration:0 #: field:report.hr.timesheet.invoice.journal,cost:0 msgid "Credit" -msgstr "" +msgstr "Kredit" #. module: account #: help:account.tax.template,child_depend:0 @@ -4041,6 +4061,7 @@ msgid "" "Indicate if the tax computation is based on the value computed for the " "computation of child taxes or based on the total amount." msgstr "" +"Määritä perustuuko verojen laskenta alemmille veroille vai loppusummaan." #. module: account #: field:account.tax,account_paid_id:0 @@ -4073,17 +4094,17 @@ msgstr "Verotettu määrä" #. module: account #: field:account.invoice.line,price_subtotal:0 msgid "Subtotal w/o tax" -msgstr "" +msgstr "Välisumma ilman veroa" #. module: account #: field:account.invoice.line,invoice_id:0 msgid "Invoice Ref" -msgstr "" +msgstr "Laskun viite" #. module: account #: field:account.analytic.line,general_account_id:0 msgid "General Account" -msgstr "" +msgstr "Yleinen tili" #. module: account #: help:account.move.line,quantity:0 @@ -4091,14 +4112,14 @@ msgid "" "The optional quantity expressed by this line, eg: number of product sold. " "The quantity is not a legal requirement but is very usefull for some reports." msgstr "" -"Valinnainen määrä täytetään tälle riville, esim. myytyjen tuotteiden määrä. " -"Tämä ei ole laillinen vaatimus, mutta käytännöllinen esimerkiksi joissakin " +"Valinnainen lukumäärä tälle riville, esim. myytyjen tuotteiden lukumäärä. " +"Lukumäärä ei ole lain vaatima, mutta se on käytännöllinen joissain " "raporteissa." #. module: account #: wizard_field:account.third_party_ledger.report,init,reconcil:0 msgid " Include Reconciled Entries" -msgstr "" +msgstr " Sisällytä suoritetut merkinnät" #. module: account #: help:account.move.line,blocked:0 @@ -4106,6 +4127,7 @@ msgid "" "You can check this box to mark the entry line as a litigation with the " "associated partner" msgstr "" +"Tämä laatikko voidaan valita jos merkintä on riidanalainen kumppanin kanssa." #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree1 @@ -4116,7 +4138,7 @@ msgstr "Asiakas Laskutus" #. module: account #: field:res.partner,debit_limit:0 msgid "Payable Limit" -msgstr "" +msgstr "Maksettavat raja" #. module: account #: wizard_field:account.account.balance.report,checktype,state:0 @@ -4132,28 +4154,28 @@ msgstr "Päivämäärä/Jakso suodatin" #: selection:account.bank.statement.line,type:0 #: selection:account.journal,type:0 msgid "General" -msgstr "" +msgstr "Yleinen" #. module: account #: rml:account.general.journal:0 msgid "Credit Trans." -msgstr "" +msgstr "Kredit siirt." #. module: account #: field:wizard.multi.charts.accounts,seq_journal:0 msgid "Separated Journal Sequences" -msgstr "Erotellut lokijaksot" +msgstr "Erotellut päiväkirjan sarjat" #. module: account #: help:account.bank.statement.reconcile,total_second_currency:0 msgid "The currency of the journal" -msgstr "" +msgstr "Päiväkirjan valuutta" #. module: account #: view:account.journal.column:0 #: model:ir.model,name:account.model_account_journal_column msgid "Journal Column" -msgstr "" +msgstr "Päiväkirjan sarake" #. module: account #: selection:account.fiscalyear,state:0 @@ -4162,7 +4184,7 @@ msgstr "" #: selection:account.period,state:0 #: selection:account.subscription,state:0 msgid "Done" -msgstr "" +msgstr "Valmis" #. module: account #: wizard_field:account.account.balance.report,checktype,periods:0 @@ -4177,7 +4199,7 @@ msgstr "" #: model:ir.ui.menu,name:account.menu_action_account_period_form #: model:ir.ui.menu,name:account.next_id_23 msgid "Periods" -msgstr "" +msgstr "Jaksot" #. module: account #: rml:account.invoice:0 @@ -4186,7 +4208,7 @@ msgstr "" #: model:ir.model,name:account.model_account_invoice #: model:res.request.link,name:account.req_link_invoice msgid "Invoice" -msgstr "" +msgstr "Lasku" #. module: account #: selection:account.analytic.account,state:0 @@ -4194,7 +4216,7 @@ msgstr "" #: wizard_button:account.open_closed_fiscalyear,init,open:0 #: wizard_button:account_use_models,create,open_move:0 msgid "Open" -msgstr "" +msgstr "Avoin" #. module: account #: model:ir.ui.menu,name:account.next_id_29 @@ -4206,7 +4228,7 @@ msgstr "Etsintäkohteet" #: model:process.node,note:account.process_node_analyticcost0 msgid "Analytic costs to reinvoice purchases, timesheets, ..." msgstr "" -"Analyyttiset kustannukset myynnin uudelleen laskutuksesta, tuntilistat, ..." +"Analyyttiset kustannukset uudelleenlaskuttaa ostoja, tuntilistoja jne." #. module: account #: field:account.account,tax_ids:0 @@ -4218,7 +4240,7 @@ msgstr "Oletusverot" #: constraint:ir.model:0 msgid "" "The Object name must start with x_ and not contain any special character !" -msgstr "" +msgstr "Objektin nimen tulee alkaa x_ ja se ei saa sisältää erikoismerkkejä!" #. module: account #: help:account.account.type,sign:0 @@ -4228,12 +4250,12 @@ msgid "" "expenses accounts." msgstr "" "Sallii saldon etumerkin muuttamisen raporteilla, joten voit nähdä " -"positiivisia lukuja negatiivisten sijaan kustannuksissa." +"positiivisia lukuja negatiivisten sijasta esim. kustannuksissa." #. module: account #: help:account.config.wizard,code:0 msgid "Name of the fiscal year as displayed in reports." -msgstr "" +msgstr "Tilikauden nimi siten kun se näytetään raporteissa." #. module: account #: help:account.move.line,date_maturity:0 @@ -4241,6 +4263,8 @@ msgid "" "This field is used for payable and receivable entries. You can put the limit " "date for the payment of this entry line." msgstr "" +"Tätä kenttää käytetään merkintöihin maksettavista ja saatavista. Voit " +"asettaa rajapäivämäärän merkintärivin maksulle." #. module: account #: rml:account.tax.code.entries:0 @@ -4255,7 +4279,7 @@ msgstr "Ylävasen" #. module: account #: help:account.journal,sequence_id:0 msgid "The sequence gives the display order for a list of journals" -msgstr "" +msgstr "Sarja määrää päiväkirjojen järjestyksen niitä listattaessa" #. module: account #: field:account.journal,type_control_ids:0 @@ -4268,7 +4292,7 @@ msgstr "Tyyppihallinnat" #: rml:account.analytic.account.balance:0 #: rml:account.central.journal:0 msgid "Account Name" -msgstr "" +msgstr "Tilin nimi" #. module: account #: wizard_field:account.invoice.pay,init,date:0 @@ -4278,12 +4302,12 @@ msgstr "Maksu päivämäärä" #. module: account #: wizard_button:account_use_models,create,end:0 msgid "Ok" -msgstr "" +msgstr "OK" #. module: account #: rml:account.invoice:0 msgid "Taxes:" -msgstr "" +msgstr "Verot:" #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree7 @@ -4302,17 +4326,17 @@ msgstr "Toimittajan laskut" #: field:account.invoice.line,product_id:0 #: field:account.move.line,product_id:0 msgid "Product" -msgstr "" +msgstr "Tuote" #. module: account #: rml:account.tax.code.entries:0 msgid ")" -msgstr "" +msgstr ")" #. module: account #: field:res.partner,credit:0 msgid "Total Receivable" -msgstr "Kaikki saatavat" +msgstr "Saatavat yhteensä" #. module: account #: model:ir.model,name:account.model_account_period @@ -4322,12 +4346,12 @@ msgstr "Tilijakso" #. module: account #: wizard_field:account.invoice.pay,init,journal_id:0 msgid "Journal/Payment Mode" -msgstr "" +msgstr "Päiväkirja-/maksutyyppi" #. module: account #: rml:account.invoice:0 msgid "Canceled Invoice" -msgstr "" +msgstr "Peruutettu lasku" #. module: account #: view:account.subscription:0 @@ -4349,7 +4373,7 @@ msgstr "Tilimalli" #. module: account #: field:account.tax.code,sum:0 msgid "Year Sum" -msgstr "" +msgstr "Vuoden summa" #. module: account #: model:process.transition,note:account.process_transition_filestatement0 @@ -4365,13 +4389,13 @@ msgstr "Sisäinen tyyppi" #. module: account #: selection:account.automatic.reconcile,init,power:0 msgid "9" -msgstr "" +msgstr "9" #. module: account #: model:ir.actions.act_window,name:account.action_subscription_form_running #: model:ir.ui.menu,name:account.menu_action_subscription_form_running msgid "Running Subscriptions" -msgstr "Juoksevat ennakkomaksut" +msgstr "Voimassa olevat ennakkomaksut" #. module: account #: selection:account.move,type:0 @@ -4393,13 +4417,13 @@ msgstr "Luottotiedot" #: field:account.config.wizard,date2:0 #: field:account.fiscalyear,date_stop:0 msgid "End Date" -msgstr "" +msgstr "Lopetuspäivämäärä" #. module: account #: model:ir.actions.wizard,name:account.wizard_open_closed_fiscalyear #: model:ir.ui.menu,name:account.menu_wizard_open_closed_fy msgid "Cancel Opening Entries" -msgstr "" +msgstr "Peruuta avausmerkinnät" #. module: account #: model:process.transition,name:account.process_transition_invoicemanually0 @@ -4415,7 +4439,7 @@ msgstr "Kuukaudenpäivä" #: field:account.analytic.journal,line_ids:0 #: field:account.tax.code,line_ids:0 msgid "Lines" -msgstr "" +msgstr "Rivit" #. module: account #: rml:account.overdue:0 @@ -4447,12 +4471,12 @@ msgstr "Arkistotiliote" #. module: account #: view:ir.sequence:0 msgid "Fiscal Year Sequences" -msgstr "Tilivuoden Sekvenssit" +msgstr "Tilikausien sarjat" #. module: account #: view:account.model.line:0 msgid "Entry Model Line" -msgstr "" +msgstr "Merkintämallin rivi" #. module: account #: view:account.tax.template:0 @@ -4462,7 +4486,7 @@ msgstr "Tiliveron malli" #. module: account #: help:account.model,name:0 msgid "This is a model for recurring accounting entries" -msgstr "" +msgstr "Tämä on malli toistuvasta kirjanpidon merkinnästä" #. module: account #: wizard_view:account.wizard_paid_open,init:0 @@ -4492,26 +4516,26 @@ msgstr "Toimittajan velat" #. module: account #: help:account.model.line,quantity:0 msgid "The optional quantity on entries" -msgstr "" +msgstr "Valinnainen merkintöjen määrä" #. module: account #: rml:account.third_party_ledger:0 #: rml:account.third_party_ledger_other:0 msgid "JNRL" -msgstr "" +msgstr "JNRL" #. module: account #: view:account.fiscalyear:0 #: view:account.period:0 msgid "States" -msgstr "" +msgstr "Tilat" #. module: account #: view:account.move:0 #: model:process.node,name:account.process_node_accountingentries0 #: model:process.node,name:account.process_node_supplieraccountingentries0 msgid "Accounting Entries" -msgstr "" +msgstr "Kirjanpidon merkinnät" #. module: account #: model:ir.actions.act_window,name:account.act_account_partner_account_move_unreconciled @@ -4526,12 +4550,12 @@ msgstr "Yleinen Tilikirja -" #. module: account #: field:report.hr.timesheet.invoice.journal,quantity:0 msgid "Quantities" -msgstr "" +msgstr "Määrät" #. module: account #: field:account.analytic.account,date_start:0 msgid "Date Start" -msgstr "" +msgstr "Aloituspäivämäärä" #. module: account #: rml:account.analytic.account.analytic.check:0 @@ -4541,13 +4565,13 @@ msgstr "" #: field:account.invoice,amount_total:0 #: field:account.invoice,check_total:0 msgid "Total" -msgstr "" +msgstr "Yhteensä" #. module: account #: model:process.transition,note:account.process_transition_customerinvoice0 #: model:process.transition,note:account.process_transition_suppliercustomerinvoice0 msgid "Number of entries are generated" -msgstr "" +msgstr "Luotavien merkintöjen lukumäärä" #. module: account #: model:process.transition,name:account.process_transition_suppliervalidentries0 @@ -4560,7 +4584,7 @@ msgstr "Sallitut merkinnät" #: model:ir.actions.wizard,name:account.wizard_line_account_use_model #: model:ir.ui.menu,name:account.menu_account_use_model msgid "Create Entries From Models" -msgstr "" +msgstr "Luo merkinnät malleista" #. module: account #: field:account.account.template,reconcile:0 @@ -4573,7 +4597,7 @@ msgstr "Salli sovittelu" #: selection:account.partner.balance.report,init,state:0 #: selection:account.third_party_ledger.report,init,state:0 msgid "By Date" -msgstr "" +msgstr "Päivämäärän mukaan" #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree4 @@ -4584,7 +4608,7 @@ msgstr "Toimittajan hyvitykset" #. module: account #: help:account.model.line,date:0 msgid "The date of the generated entries" -msgstr "" +msgstr "Luotujen merkintöjen päivämäärä" #. module: account #: wizard_button:account.invoice.refund,init,modify_invoice:0 @@ -4607,21 +4631,21 @@ msgid "" "This will automatically configure your chart of accounts, bank accounts, " "taxes and journals according to the selected template" msgstr "" -"Toiminto konfiguroi automaattisesti kirjapitokartat, pankkitilit, verot ja " -"lokit valitun mallin mukaan" +"Tämä toiminto konfiguroi automaattisesti kirjanpidon tilikartat, " +"pankkitilit, verot ja päiväkirjat valitun mallin mukaan" #. module: account #: view:account.bank.statement:0 #: field:account.bank.statement.line,statement_id:0 #: field:account.move.line,statement_id:0 msgid "Statement" -msgstr "" +msgstr "Tiliote" #. module: account #: model:ir.actions.act_window,name:account.action_move_line_form_encode_by_move #: model:ir.ui.menu,name:account.menu_encode_entries_by_move msgid "Entries Encoding by Move" -msgstr "" +msgstr "Merkinnät siirroittain" #. module: account #: wizard_view:account.analytic.account.chart,init:0 @@ -4642,13 +4666,13 @@ msgstr "Vero lisätty hintaan" #: model:ir.actions.act_window,name:account.action_account_analytic_journal_tree2 #: model:ir.ui.menu,name:account.account_analytic_journal_entries msgid "Analytic Entries by Journal" -msgstr "" +msgstr "Analyyttiset merkinnät päiväkirjoittain" #. module: account #: model:process.transition,note:account.process_transition_suppliervalidentries0 #: model:process.transition,note:account.process_transition_validentries0 msgid "Valid entries from invoice" -msgstr "" +msgstr "Hyväksytyt merkinnät laskulta" #. module: account #: field:account.account,company_id:0 @@ -4668,17 +4692,17 @@ msgstr "" #: field:wizard.company.setup,company_id:0 #: field:wizard.multi.charts.accounts,company_id:0 msgid "Company" -msgstr "" +msgstr "Yritys" #. module: account #: rml:account.general.ledger:0 msgid "Crebit" -msgstr "" +msgstr "Kredit" #. module: account #: selection:account.subscription,state:0 msgid "Running" -msgstr "" +msgstr "Käytössä" #. module: account #: help:account.tax,include_base_amount:0 @@ -4686,8 +4710,8 @@ msgid "" "Indicate if the amount of tax must be included in the base amount for the " "computation of the next taxes" msgstr "" -"Kerro jos veronmäärä pitää olla sisällytettynä perusmäärään seuraavissa " -"verolaskelmissa" +"Ilmoita jos veron määrä täytyy sisällyttää perusmäärään seuraavia veroja " +"laskettaessa" #. module: account #: model:process.node,name:account.process_node_draftstatement0 @@ -4697,7 +4721,7 @@ msgstr "Luonnostiliote" #. module: account #: field:account.analytic.journal,name:0 msgid "Journal name" -msgstr "Lokinimi" +msgstr "Päiväkirjan nimi" #. module: account #: model:process.transition,note:account.process_transition_invoiceimport0 @@ -4707,7 +4731,7 @@ msgstr "Tuo lasku tiliotteesta" #. module: account #: selection:account.automatic.reconcile,init,power:0 msgid "4" -msgstr "" +msgstr "4" #. module: account #: model:ir.actions.act_window,name:account.action_account_fiscalyear_form @@ -4725,22 +4749,22 @@ msgstr "Tuo laskuista tai maksuista" #: model:ir.actions.wizard,name:account.wizard_reconcile_select #: model:ir.ui.menu,name:account.menu_reconcile_select msgid "Reconcile entries" -msgstr "" +msgstr "Tee suoritusmerkinnät" #. module: account #: xsl:account.transfer:0 msgid "Change" -msgstr "" +msgstr "Muuta" #. module: account #: field:account.journal.period,icon:0 msgid "Icon" -msgstr "" +msgstr "Kuvake" #. module: account #: model:ir.model,name:account.model_account_journal_period msgid "Journal - Period" -msgstr "Loki - Jakso" +msgstr "Päiväkirja - Jakso" #. module: account #: wizard_field:account.move.line.reconcile,init_full,credit:0 @@ -4756,7 +4780,7 @@ msgstr "Luo kuukausijaksot" #. module: account #: wizard_button:account.aged.trial.balance,init,print:0 msgid "Print Aged Trial Balance" -msgstr "" +msgstr "Tulosta välitase" #. module: account #: field:account.analytic.line,ref:0 @@ -4766,7 +4790,7 @@ msgstr "" #: rml:account.third_party_ledger:0 #: rml:account.third_party_ledger_other:0 msgid "Ref." -msgstr "" +msgstr "Viite" #. module: account #: field:account.invoice,address_invoice_id:0 @@ -4785,11 +4809,14 @@ msgid "" "new counterpart but will share the same counterpart. This is used in fiscal " "year closing." msgstr "" +"Valitse määrittääksesi että jokainen merkintä tähän päiväkirjaan ei luo " +"uutta vastinetta vaan käyttää jaettua vastinetta. Tätä käytetään tilikauden " +"päätökseen." #. module: account #: selection:account.invoice,state:0 msgid "Cancelled" -msgstr "" +msgstr "Peruttu" #. module: account #: model:ir.actions.act_window,name:account.action_bank_statement_draft_tree @@ -4805,19 +4832,19 @@ msgstr "Maksupäivä" #. module: account #: rml:account.journal.period.print:0 msgid "A/c No." -msgstr "" +msgstr "Tilinumero" #. module: account #: model:ir.actions.act_window,name:account.report_account_analytic_journal_tree_month #: model:ir.ui.menu,name:account.report_account_analytic_journal_print_month msgid "Account cost and revenue by journal (This Month)" -msgstr "Tilin kustannukset ja tuotot lokin mukaan (Tässä kuussa)" +msgstr "Tilin kustannukset ja tuotot päiväkirjan mukaan (Tässä kuussa)" #. module: account #: selection:account.partner.balance.report,init,result_selection:0 #: selection:account.third_party_ledger.report,init,result_selection:0 msgid "Receivable Accounts" -msgstr "Saatavat kirjanpidot" +msgstr "Saatavat tilit" #. module: account #: wizard_button:account.move.line.unreconcile.select,init,open:0 @@ -4833,7 +4860,7 @@ msgstr "Pankin tiliotteen rivi" #. module: account #: wizard_button:account.automatic.reconcile,reconcile,end:0 msgid "OK" -msgstr "" +msgstr "OK" #. module: account #: model:process.node,name:account.process_node_supplierinvoiceinvoice0 @@ -4845,7 +4872,7 @@ msgstr "Ohjaa laskua" #: selection:account.account.template,type:0 #: selection:account.aged.trial.balance,init,result_selection:0 msgid "Receivable" -msgstr "Saatava" +msgstr "Saatavat" #. module: account #: model:ir.actions.report.xml,name:account.account_account_balance @@ -4873,12 +4900,12 @@ msgstr "ALV:" #: rml:account.general.journal:0 #: rml:account.invoice:0 msgid "Total:" -msgstr "" +msgstr "Yhteensä:" #. module: account #: model:ir.model,name:account.model_account_analytic_journal msgid "account.analytic.journal" -msgstr "" +msgstr "account.analytic.journal" #. module: account #: view:account.fiscal.position:0 @@ -4901,7 +4928,7 @@ msgstr "Tili sovittelu" #: view:account.bank.statement:0 #: selection:account.bank.statement,state:0 msgid "Confirm" -msgstr "" +msgstr "Hyväksy" #. module: account #: wizard_view:account.account.balance.report,account_selection:0 @@ -4938,12 +4965,12 @@ msgstr "Analyyttinen kirjanpito" #: rml:account.invoice:0 #: selection:account.invoice,type:0 msgid "Supplier Invoice" -msgstr "" +msgstr "Toimittajan lasku" #. module: account #: selection:account.move.line,state:0 msgid "Valid" -msgstr "" +msgstr "Voimassa" #. module: account #: field:account.account,debit:0 @@ -4964,12 +4991,12 @@ msgstr "" #: rml:account.vat.declaration:0 #: field:report.hr.timesheet.invoice.journal,revenue:0 msgid "Debit" -msgstr "" +msgstr "Debet" #. module: account #: model:ir.ui.menu,name:account.next_id_42 msgid "All Months" -msgstr "" +msgstr "Kaikki kuukaudet" #. module: account #: wizard_field:account.invoice.refund,init,date:0 @@ -4979,7 +5006,7 @@ msgstr "Toimenpiteen päivämäärä" #. module: account #: field:account.invoice,invoice_line:0 msgid "Invoice Lines" -msgstr "" +msgstr "Laskurivit" #. module: account #: field:account.period,date_start:0 @@ -4989,12 +5016,12 @@ msgstr "Jakson alku" #. module: account #: wizard_field:account.fiscalyear.close,init,report_name:0 msgid "Name of new entries" -msgstr "" +msgstr "Uusien merkintöjen nimi" #. module: account #: wizard_button:account_use_models,init_form,create:0 msgid "Create Entries" -msgstr "" +msgstr "Luo merkinnät" #. module: account #: field:account.tax,ref_tax_code_id:0 @@ -5015,24 +5042,24 @@ msgstr "Linkitä automaattisesti luotuihin tilisiirtoihin" #. module: account #: wizard_field:account.automatic.reconcile,reconcile,reconciled:0 msgid "Reconciled transactions" -msgstr "Sovitellut liiketoimet" +msgstr "Suoritetut tapahtumat" #. module: account #: model:ir.ui.menu,name:account.menu_finance_reporting msgid "Reporting" -msgstr "" +msgstr "Raportointi" #. module: account #: rml:account.third_party_ledger:0 #: rml:account.third_party_ledger_other:0 msgid "/" -msgstr "" +msgstr "/" #. module: account #: model:process.node,note:account.process_node_invoiceinvoice0 #: model:process.node,note:account.process_node_supplierinvoiceinvoice0 msgid "Have a number and entries are generated" -msgstr "" +msgstr "On numero ja merkinnät luotu" #. module: account #: rml:account.analytic.account.analytic.check:0 @@ -5052,28 +5079,28 @@ msgstr "Ryhmittele laskurivit" #. module: account #: model:ir.ui.menu,name:account.menu_finance_configuration msgid "Configuration" -msgstr "" +msgstr "Konfiguraatio" #. module: account #: view:account.analytic.line:0 #: view:account.invoice:0 msgid "Total amount" -msgstr "" +msgstr "Yhteensä" #. module: account #: view:account.journal:0 msgid "Account Journal" -msgstr "" +msgstr "Tilipäiväkirja" #. module: account #: view:account.subscription.line:0 msgid "Subscription lines" -msgstr "Tilausrivit" +msgstr "Ennakkomaksun rivit" #. module: account #: field:account.chart.template,property_account_income:0 msgid "Income Account on Product Template" -msgstr "" +msgstr "Tili tuloille tuotteen mallissa" #. module: account #: help:account.account,currency_id:0 @@ -5085,7 +5112,7 @@ msgstr "Pakota kaikille siirroille tällä tilillä toissijainen valuutta." #: wizard_button:populate_statement_from_inv,go,end:0 #: wizard_button:populate_statement_from_inv,init,end:0 msgid "_Cancel" -msgstr "" +msgstr "_Peruuta" #. module: account #: wizard_view:account.general.ledger.report,checktype:0 @@ -5129,8 +5156,8 @@ msgid "" "Check this box if you want to use a different sequence for each created " "journal. Otherwise, all will use the same sequence." msgstr "" -"Valitse tämä jos haluat käyttää eri sekvenssiä jokaiselle luodulle lokille. " -"Muutoin kaikki käyttävät samaa sekvenssiä." +"Valitse tämä jos haluat käyttää eri sarjaa jokaiselle luodulle " +"päiväkirjalle. Muuten kaikki käyttävät samaa sarjaa." #. module: account #: model:ir.actions.wizard,name:account.wizard_populate_statement_from_inv @@ -5147,13 +5174,13 @@ msgstr "Sovittelematon" #. module: account #: model:ir.model,name:account.model_fiscalyear_seq msgid "Maintains Invoice sequences with Fiscal Year" -msgstr "Ylläpitää laskusekvenssejä Tilikauden kanssa" +msgstr "Ylläpitää laskusarjoja tilikauden kanssa" #. module: account #: selection:account.account.balance.report,checktype,display_account:0 #: selection:account.general.ledger.report,checktype,display_account:0 msgid "With movements" -msgstr "" +msgstr "Siirtojen kanssa" #. module: account #: field:account.tax,domain:0 @@ -5169,17 +5196,17 @@ msgstr "Tilitiedot" #. module: account #: view:account.tax.code.template:0 msgid "Account Tax Code Template" -msgstr "" +msgstr "Tilin verokoodin malli" #. module: account #: view:account.subscription:0 msgid "Subscription Periods" -msgstr "Ennakkomaksujaksot" +msgstr "Ennakkomaksun jaksot" #. module: account #: model:process.node,name:account.process_node_manually0 msgid "Manually" -msgstr "" +msgstr "Manuaalisesti" #. module: account #: view:account.invoice:0 @@ -5192,24 +5219,24 @@ msgstr "" #: model:ir.ui.menu,name:account.menu_finance_invoice #: wizard_field:populate_statement_from_inv,go,lines:0 msgid "Invoices" -msgstr "" +msgstr "Laskut" #. module: account #: selection:account.partner.balance.report,init,result_selection:0 #: selection:account.third_party_ledger.report,init,result_selection:0 msgid "Payable Accounts" -msgstr "" +msgstr "Maksettavat tilit" #. module: account #: view:account.invoice.line:0 #: field:account.invoice.tax,invoice_id:0 msgid "Invoice Line" -msgstr "" +msgstr "Laskun rivi" #. module: account #: wizard_field:account.invoice.pay,addendum,writeoff_journal_id:0 msgid "Write-Off journal" -msgstr "Arvonalennusloki" +msgstr "Arvonalennuspäiväkirja" #. module: account #: wizard_button:account.invoice.pay,init,writeoff_check:0 @@ -5219,7 +5246,7 @@ msgstr "Kokonaismaksu" #. module: account #: selection:account.move,type:0 msgid "Journal Purchase" -msgstr "" +msgstr "Päiväkirja osto" #. module: account #: selection:account.move,type:0 @@ -5235,34 +5262,34 @@ msgstr "Korvaava vero" #. module: account #: model:process.transition,note:account.process_transition_invoicemanually0 msgid "Encode manually statement comes into the draft statement" -msgstr "" +msgstr "Manuaalisesti syötetty tiliote tulee luonnostiliotteeseen" #. module: account #: model:ir.ui.menu,name:account.next_id_43 msgid "This Month" -msgstr "" +msgstr "Tässä kuussa" #. module: account #: field:account.account.type,sign:0 msgid "Sign on Reports" -msgstr "" +msgstr "Etumerkki raporteissa" #. module: account #: help:account.move.line,currency_id:0 msgid "The optional other currency if it is a multi-currency entry." -msgstr "" +msgstr "Valinnainen toinen valuutta jos merkintä on monivaluuttainen." #. module: account #: view:account.invoice:0 #: field:account.invoice,payment_ids:0 #: selection:account.vat.declaration,init,based_on:0 msgid "Payments" -msgstr "" +msgstr "Maksut" #. module: account #: model:process.node,note:account.process_node_accountingstatemententries0 msgid "Accounting entries at statement's confirmation" -msgstr "" +msgstr "Kirjanpidon merkinnät tiliotteen vahvistuksessa" #. module: account #: wizard_view:account_use_models,create:0 @@ -5272,12 +5299,12 @@ msgstr "käytä mallia" #. module: account #: wizard_button:account.wizard_paid_open,init,end:0 msgid "No" -msgstr "" +msgstr "Ei" #. module: account #: model:ir.actions.act_window,name:account.act_account_partner_account_move msgid "All account entries" -msgstr "" +msgstr "Kaikki tilin merkinnät" #. module: account #: help:account.invoice.tax,tax_code_id:0 @@ -5295,7 +5322,7 @@ msgstr "Päivämääräsuodatin" #. module: account #: wizard_view:populate_statement_from_inv,init:0 msgid "Choose Journal and Payment Date" -msgstr "" +msgstr "Valitse päiväkirja ja maksupäivä" #. module: account #: selection:account.analytic.account,state:0 @@ -5308,12 +5335,12 @@ msgstr "" #: selection:account.period,state:0 #: selection:account.subscription,state:0 msgid "Draft" -msgstr "" +msgstr "Luonnos" #. module: account #: rml:account.overdue:0 msgid "Paid" -msgstr "" +msgstr "Maksettu" #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree11 @@ -5335,17 +5362,17 @@ msgstr "Oletko varma?" #: rml:account.invoice:0 #: view:account.invoice:0 msgid "PRO-FORMA" -msgstr "" +msgstr "Proforma" #. module: account #: field:account.move.reconcile,line_partial_ids:0 msgid "Partial Entry lines" -msgstr "" +msgstr "Osittaiset merkintärivit" #. module: account #: help:account.move.line,statement_id:0 msgid "The bank statement used for bank reconciliation" -msgstr "" +msgstr "Pankkisuorituksiin käytettävä pankkitiliote" #. module: account #: view:account.fiscalyear:0 @@ -5355,13 +5382,13 @@ msgstr "Tilikausi" #. module: account #: wizard_button:account.analytic.line,init,open:0 msgid "Open Entries" -msgstr "" +msgstr "Avoimet merkinnät" #. module: account #: selection:account.analytic.account,type:0 #: selection:account.move.line,centralisation:0 msgid "Normal" -msgstr "" +msgstr "Normaali" #. module: account #: model:process.process,name:account.process_process_supplierinvoiceprocess0 @@ -5380,19 +5407,19 @@ msgstr "Toimittajan laskutus prosessi" #: rml:account.third_party_ledger_other:0 #: rml:account.vat.declaration:0 msgid "Page" -msgstr "" +msgstr "Sivu" #. module: account #: view:account.move:0 #: view:account.move.line:0 msgid "Optional Information" -msgstr "" +msgstr "Lisätiedot" #. module: account #: model:ir.actions.act_window,name:account.action_payment_term_form #: model:ir.ui.menu,name:account.menu_action_payment_term_form msgid "Payment Terms" -msgstr "" +msgstr "Maksuehdot" #. module: account #: selection:account.aged.trial.balance,init,result_selection:0 @@ -5403,12 +5430,12 @@ msgstr "Saatavat ja maksettavat" #: rml:account.account.balance:0 #: rml:account.general.journal:0 msgid ":" -msgstr "" +msgstr ":" #. module: account #: field:account.bank.statement.line,reconcile_amount:0 msgid "Amount reconciled" -msgstr "Soviteltu määrä" +msgstr "Suoritettu määrä" #. module: account #: selection:account.account,currency_mode:0 @@ -5422,13 +5449,16 @@ msgid "" "amount.If the tax account is base tax code, this field " "will contain the basic amount(without tax)." msgstr "" +"Jos verotili on verokooditili, tässä kentässä on veron määrä. Jos verotili " +"on perusverokoodi, tämä kenttä sisältää perusteena olevan summan (ilman " +"veroa)." #. module: account #: view:account.bank.statement:0 #: view:account.bank.statement.reconcile:0 #: view:account.subscription:0 msgid "Compute" -msgstr "" +msgstr "Laske" #. module: account #: help:account.invoice.line,account_id:0 @@ -5444,7 +5474,7 @@ msgstr "Verosovellus" #: model:ir.actions.act_window,name:account.action_subscription_form #: model:ir.ui.menu,name:account.menu_action_subscription_form msgid "Subscription Entries" -msgstr "" +msgstr "Ennakkomaksun merkinnät" #. module: account #: model:ir.actions.act_window,name:account.action_invoice_tree6 @@ -5466,19 +5496,19 @@ msgstr "Jaksojen määrä" #: wizard_field:account.analytic.account.quantity_cost_ledger.report,init,date2:0 #: wizard_field:account.automatic.reconcile,init,date2:0 msgid "End of period" -msgstr "" +msgstr "Jakson loppu" #. module: account #: view:account.move:0 #: model:ir.model,name:account.model_account_move msgid "Account Entry" -msgstr "" +msgstr "Tilimerkintä" #. module: account #: rml:account.general.journal:0 #: model:ir.actions.report.xml,name:account.account_general_journal msgid "General Journal" -msgstr "Yleinen loki" +msgstr "Yleinen päiväkirja" #. module: account #: field:account.account,balance:0 @@ -5498,7 +5528,7 @@ msgstr "Yleinen loki" #: rml:account.third_party_ledger:0 #: rml:account.third_party_ledger_other:0 msgid "Balance" -msgstr "" +msgstr "Saldo" #. module: account #: rml:account.invoice:0 @@ -5514,17 +5544,17 @@ msgstr "Laskuta vero" #: model:ir.actions.act_window,name:account.action_account_analytic_journal_form #: model:ir.ui.menu,name:account.account_def_analytic_journal msgid "Analytic Journal Definition" -msgstr "Analyyttisen lokin määritys" +msgstr "Analyyttisen päiväkirjan määritys" #. module: account #: model:ir.model,name:account.model_account_tax_template msgid "account.tax.template" -msgstr "" +msgstr "account.tax.template" #. module: account #: field:wizard.multi.charts.accounts,bank_accounts_id:0 msgid "Bank Accounts" -msgstr "" +msgstr "Pankkitilit" #. module: account #: constraint:account.period:0 @@ -5532,13 +5562,13 @@ msgid "" "Invalid period ! Some periods overlap or the date period is not in the scope " "of the fiscal year. " msgstr "" -"Virheellinen jakso ! Jotkin jaksot ovat päällekkäisiä tai jakson päivämäärä " -"ei ole tilikauden käsittävällä laajuudella. " +"Jakso on virheellinen! Jotkin jaksot ovat päällekkäisiä tai jakson " +"päivämäärä ei ole tilikaudella. " #. module: account #: help:account.journal,invoice_sequence_id:0 msgid "The sequence used for invoice numbers in this journal." -msgstr "" +msgstr "Sarja jota käytetään laskujen numeroihin tässä päiväkirjassa." #. module: account #: view:account.account:0 @@ -5547,7 +5577,7 @@ msgstr "" #: view:account.move:0 #: view:account.move.line:0 msgid "General Information" -msgstr "" +msgstr "Yleistiedot" #. module: account #: help:populate_statement_from_inv,init,journal_id:0 @@ -5556,21 +5586,23 @@ msgid "" "filtering the invoices. If you left this field empty, it will search on all " "sale, purchase and cash journals." msgstr "" +"Tällä kentällä voidaan valita päiväkirja josta laskuja etsitään. Jos tämä on " +"tyhjä, etsitään kaikista myynti-, osto- ja kassapäiväkirjoista." #. module: account #: constraint:account.fiscalyear:0 msgid "Error ! The duration of the Fiscal Year is invalid. " -msgstr "Virhe ! Tilikauden kesto on epäkelpo. " +msgstr "Virhe! Tilikauden pituus on virheellinen. " #. module: account #: selection:account.analytic.account,state:0 msgid "Close" -msgstr "" +msgstr "Sulje" #. module: account #: field:account.bank.statement.line,move_ids:0 msgid "Moves" -msgstr "" +msgstr "Siirrot" #. module: account #: selection:account.invoice,state:0 @@ -5587,7 +5619,7 @@ msgstr "Tililistaus" #: view:product.product:0 #: view:product.template:0 msgid "Sales Properties" -msgstr "" +msgstr "Myynnin ominaisuudet" #. module: account #: rml:account.general.journal:0 @@ -5603,7 +5635,7 @@ msgstr "Kustannustilikirja (Vain määrät)" #. module: account #: wizard_view:account.move.validate,init:0 msgid "Validate Account Entries" -msgstr "" +msgstr "Hyväksy tilimerkinnät" #. module: account #: selection:account.print.journal.report,init,sort_selection:0 @@ -5619,12 +5651,12 @@ msgstr "Kaikkiaan myöhässä:" #: wizard_field:account.analytic.account.chart,init,to_date:0 #: wizard_field:account.analytic.line,init,to_date:0 msgid "To" -msgstr "" +msgstr "päättyen" #. module: account #: model:ir.actions.act_window,name:account.action_account_analytic_journal_open_form msgid "Entries of Open Analytic Journals" -msgstr "" +msgstr "Avoimien analyyttisten päiväkirjojen merkinnät" #. module: account #: view:account.invoice.tax:0 @@ -5634,12 +5666,12 @@ msgstr "Laskuta verot manuaalisesti" #. module: account #: field:account.model.line,date:0 msgid "Current Date" -msgstr "" +msgstr "Nykyinen päivämäärä" #. module: account #: selection:account.move,type:0 msgid "Journal Sale" -msgstr "Myynnin loki" +msgstr "Päiväkirja myynti" #. module: account #: wizard_field:account.fiscalyear.close,init,fy_id:0 @@ -5657,12 +5689,12 @@ msgstr "Suljettava tilikausi" #: wizard_field:account.analytic.account.quantity_cost_ledger.report,init,date1:0 #: wizard_field:account.automatic.reconcile,init,date1:0 msgid "Start of period" -msgstr "" +msgstr "Jakson alku" #. module: account #: model:ir.ui.menu,name:account.account_template_folder msgid "Templates" -msgstr "" +msgstr "Mallit" #. module: account #: wizard_button:account.vat.declaration,init,report:0 @@ -5688,7 +5720,7 @@ msgstr "IntraCom" #: field:account.tax.code,info:0 #: field:account.tax.code.template,info:0 msgid "Description" -msgstr "" +msgstr "Kuvaus" #. module: account #: help:product.template,property_account_income:0 @@ -5702,7 +5734,7 @@ msgstr "" #. module: account #: field:account.tax,child_ids:0 msgid "Child Tax Accounts" -msgstr "" +msgstr "Alemmat verotilit" #. module: account #: field:account.account,parent_right:0 @@ -5729,7 +5761,8 @@ msgstr "Tilikonfigurointi" msgid "" "This account will be used instead of the default one as the payable account " "for the current partner" -msgstr "Tätä tiliä käytetään oletuksen sijaan kumppanin maksutilinä" +msgstr "" +"Tätä tiliä käytetään oletustilin sijasta tämän kumppanin maksettaville." #. module: account #: field:account.tax.code,code:0 @@ -5788,17 +5821,17 @@ msgstr "Kirjanpidon ominaisuudet" #. module: account #: model:ir.model,name:account.model_account_sequence_fiscalyear msgid "account.sequence.fiscalyear" -msgstr "" +msgstr "account.sequence.fiscalyear" #. module: account #: wizard_field:account.print.journal.report,init,sort_selection:0 msgid "Entries Sorted By" -msgstr "" +msgstr "Merkintöjen järjestelyn peruste" #. module: account #: rml:account.journal.period.print:0 msgid "Print Journal -" -msgstr "Tulosta loki -" +msgstr "Tulosta päiväkirja -" #. module: account #: field:account.bank.accounts.wizard,bank_account_id:0 @@ -5839,7 +5872,7 @@ msgstr "Erääntyneet" #: field:fiscalyear.seq,fiscalyear_id:0 #: model:ir.model,name:account.model_account_fiscalyear msgid "Fiscal Year" -msgstr "Tilivuosi" +msgstr "Tilikausi" #. module: account #: selection:account.aged.trial.balance,init,direction_selection:0 @@ -5853,7 +5886,7 @@ msgstr "Tulevat" #: help:account.partner.balance.report,init,fiscalyear:0 #: help:account.third_party_ledger.report,init,fiscalyear:0 msgid "Keep empty for all open fiscal year" -msgstr "Pidä tyhjänä avoimien tilivuosien aikana" +msgstr "Jätä tyhjäksi käyttääksesi kaikkia avoimia tilikausia" #. module: account #: rml:account.invoice:0 @@ -5865,12 +5898,12 @@ msgstr "Toimittajan hyvitys" #: model:process.transition,note:account.process_transition_entriesreconcile0 #: model:process.transition,note:account.process_transition_supplierentriesreconcile0 msgid "Reconcile Entries." -msgstr "" +msgstr "Suorita merkinnät." #. module: account #: field:account.subscription.line,move_id:0 msgid "Entry" -msgstr "" +msgstr "Merkintä" #. module: account #: model:process.node,note:account.process_node_paidinvoice0 @@ -5878,7 +5911,7 @@ msgstr "" #: model:process.transition,note:account.process_transition_reconcilepaid0 #: model:process.transition,note:account.process_transition_supplierreconcilepaid0 msgid "Paid invoice when reconciled." -msgstr "Maksettu lasku soviteltaessa." +msgstr "Lasku maksettu kun suoritukset on tehty." #. module: account #: field:account.tax,python_compute_inv:0 @@ -5889,7 +5922,7 @@ msgstr "Python -koodi (vastakohta)" #. module: account #: model:ir.module.module,shortdesc:account.module_meta_information msgid "Accounting and financial management" -msgstr "Kirjanpidon -ja taloudenhallinta" +msgstr "Kirjanpidon- ja taloudenhallinta" #. module: account #: view:account.fiscal.position.template:0 @@ -5938,7 +5971,7 @@ msgstr "Tilikoodi" #. module: account #: help:account.config.wizard,name:0 msgid "Name of the fiscal year as displayed on screens." -msgstr "Tilivuoden nimi (näkymä ruudulla)" +msgstr "Tilikauden nimi siten kun se näytetään ruudulla." #. module: account #: field:account.invoice,payment_term:0 @@ -5955,7 +5988,7 @@ msgstr "Maksuehto" #: model:ir.actions.act_window,name:account.action_account_fiscal_position_form #: model:ir.ui.menu,name:account.menu_action_account_fiscal_position_form msgid "Fiscal Positions" -msgstr "" +msgstr "Talouskannat" #. module: account #: model:process.process,name:account.process_process_statementprocess0 @@ -5965,7 +5998,7 @@ msgstr "Tilioteprosessi" #. module: account #: model:ir.model,name:account.model_account_bank_statement_reconcile msgid "Statement reconcile" -msgstr "Tiliote sovittelu" +msgstr "Tiliotteen suoritukset" #. module: account #: wizard_field:account.fiscalyear.close,init,sure:0 @@ -6004,11 +6037,13 @@ msgstr "Kyllä" msgid "" "Check this if the user is allowed to reconcile entries in this account." msgstr "" +"Valitse tämä jos käyttäjän on sallittua tehdä suoritusmerkintöjä tässä " +"tilissä." #. module: account #: wizard_button:account.subscription.generate,init,generate:0 msgid "Compute Entry Dates" -msgstr "Lasketut merkintäpäivät" +msgstr "Laske merkintäpäivät" #, python-format #~ msgid "No period found !" @@ -6021,23 +6056,6 @@ msgstr "Lasketut merkintäpäivät" #~ msgid "You must first select a partner !" #~ msgstr "Sinun täytyy ensiksi valita yhteistyökumppani!" -#~ msgid "" -#~ "Would your payment have been carried out after this mail was sent, please " -#~ "consider the present one as void. Do not hesitate to contact our accounting " -#~ "departement at +32 81 81 37 00." -#~ msgstr "" -#~ "Oliko maksusi suoritettu kun tämä sähköposti lähetettiin, ota huomioon " -#~ "nykyinen mitätöidyksi. Älä epäröi ottaa yhteyttä kirjanpito-osastoon +32 81 " -#~ "81 37 00" - -#, python-format -#~ msgid "" -#~ "You can not do this modification on a reconciled entry ! Please note that " -#~ "you can just change some non important fields !" -#~ msgstr "" -#~ "Et voi tehdä tätä muokkausta sovitetulle merkinnälle! Huomioi että voit " -#~ "muuttaa vain joitain ei tärkeitä kenttiä!" - #, python-format #~ msgid "No Data Available" #~ msgstr "Ei tietoa saatavilla" @@ -6049,14 +6067,6 @@ msgstr "Lasketut merkintäpäivät" #~ msgid "No Partner Defined !" #~ msgstr "Ei kumppania määriteltynä!" -#, python-format -#~ msgid "" -#~ "You can not do this modification on a confirmed entry ! Please note that you " -#~ "can just change some non important fields !" -#~ msgstr "" -#~ "Et voi muokata tätä hyväksyttyä merkintää! Ota huomioon että voit muuttaa " -#~ "ainoastaan ei tärkeitä kenttiä" - #, python-format #~ msgid "Cannot delete invoice(s) that are already opened or paid !" #~ msgstr "Laskua(laskuja) jotka ovat avatuja tai maksettuja ei voida poistaa" @@ -6072,18 +6082,6 @@ msgstr "Lasketut merkintäpäivät" #~ msgid "Configration Error !" #~ msgstr "Asetusvirhe" -#, python-format -#~ msgid "Some entries are already reconciled !" -#~ msgstr "Jotkut merkinnät ovat jo soviteltuja" - -#, python-format -#~ msgid "No Analytic Journal !" -#~ msgstr "Ei analyyttinen loki" - -#, python-format -#~ msgid "Already Reconciled" -#~ msgstr "Jo soviteltu" - #, python-format #~ msgid "Unable to change tax !" #~ msgstr "Veroa ei voida muuttaa!" @@ -6092,10 +6090,6 @@ msgstr "Lasketut merkintäpäivät" #~ msgid "No records found for your selection!" #~ msgstr "Tietoja ei löydy valinnalle" -#, python-format -#~ msgid "Unable to reconcile entry \"%s\": %.2f" -#~ msgstr "Merkintöä \"%s\": %.2f ei voida sovittaa" - #~ msgid "Move name" #~ msgstr "Siirrä nimi" @@ -6103,22 +6097,6 @@ msgstr "Lasketut merkintäpäivät" #~ msgid "Date to must be set between %s and %s" #~ msgstr "Päiväys täytyy asettaa välille %s ja %s" -#, python-format -#~ msgid "Sales Journal" -#~ msgstr "Myyntiloki" - -#, python-format -#~ msgid "You can not modify/delete a journal with entries for this period !" -#~ msgstr "Et voi muokata/poistaa lokikirjaa jossa merkintöjä tälle kaudelle" - -#, python-format -#~ msgid "Invoice is already reconciled" -#~ msgstr "Lasku on jo sovitettu" - -#, python-format -#~ msgid "The account is not defined to be reconcile !" -#~ msgstr "Tiliä ei ole määritelty sovitelluksi" - #, python-format #~ msgid "Entries: " #~ msgstr "Merkinnät: " diff --git a/addons/account_anglo_saxon/i18n/hi.po b/addons/account_anglo_saxon/i18n/hi.po new file mode 100644 index 00000000000..e05851e42f0 --- /dev/null +++ b/addons/account_anglo_saxon/i18n/hi.po @@ -0,0 +1,64 @@ +# Hindi translation for openobject-addons +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2009-11-24 12:50+0000\n" +"PO-Revision-Date: 2010-03-16 23:00+0000\n" +"Last-Translator: Neetesh Biswas \n" +"Language-Team: Hindi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#. module: account_anglo_saxon +#: view:product.category:0 +msgid " Accounting Property" +msgstr "" + +#. module: account_anglo_saxon +#: model:ir.module.module,description:account_anglo_saxon.module_meta_information +msgid "" +"This module will support the Anglo-Saxons accounting methodology by \n" +" changing the accounting logic with stock transactions. The difference " +"between the Anglo-Saxon accounting countries \n" +" and the Rhine or also called Continental accounting countries is the " +"moment of taking the Cost of Goods Sold versus Cost of Sales. \n" +" Anglo-Saxons accounting does take the cost when sales invoice is " +"created, Continental accounting will take the cost at he moment the goods " +"are shipped.\n" +" This module will add this functionality by using a interim account, to " +"store the value of shipped goods and will contra book this interim account \n" +" when the invoice is created to transfer this amount to the debtor or " +"creditor account." +msgstr "" + +#. module: account_anglo_saxon +#: model:ir.module.module,shortdesc:account_anglo_saxon.module_meta_information +msgid "Stock Account" +msgstr "" + +#. module: account_anglo_saxon +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "संरचना देखने के लिए अमान्य XML!" + +#. module: account_anglo_saxon +#: field:product.category,property_account_creditor_price_difference_categ:0 +#: field:product.template,property_account_creditor_price_difference:0 +msgid "Price Difference Account" +msgstr "" + +#. module: account_anglo_saxon +#: help:product.category,property_account_creditor_price_difference_categ:0 +#: help:product.template,property_account_creditor_price_difference:0 +msgid "" +"This account will be used to value price difference between purchase price " +"and cost price." +msgstr "" diff --git a/addons/account_balance/i18n/pt_BR.po b/addons/account_balance/i18n/pt_BR.po index 39d22acf820..ed13516eb17 100644 --- a/addons/account_balance/i18n/pt_BR.po +++ b/addons/account_balance/i18n/pt_BR.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0_rc3\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2009-09-08 15:49+0000\n" -"Last-Translator: Fabien (Open ERP) \n" +"PO-Revision-Date: 2010-03-18 02:19+0000\n" +"Last-Translator: Zergar \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 04:53+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: account_balance @@ -24,56 +24,56 @@ msgstr "" #. module: account_balance #: selection:account.balance.account.balance.report,init,account_choice:0 msgid "All accounts" -msgstr "" +msgstr "Todas as Contas" #. module: account_balance #: wizard_field:account.balance.account.balance.report,init,period_manner:0 msgid "Entries Selection Based on" -msgstr "" +msgstr "Seleção de entradas baseada em" #. module: account_balance #: wizard_view:account.balance.account.balance.report,backtoinit:0 #: wizard_view:account.balance.account.balance.report,zero_years:0 msgid "Notification" -msgstr "" +msgstr "Notificação" #. module: account_balance #: selection:account.balance.account.balance.report,init,period_manner:0 msgid "Financial Period" -msgstr "" +msgstr "Período Financeiro" #. module: account_balance #: model:ir.actions.report.xml,name:account_balance.account_account_balance #: model:ir.actions.report.xml,name:account_balance.account_account_balance_landscape msgid "Account balance" -msgstr "" +msgstr "Saldo da Conta" #. module: account_balance #: rml:account.account.balance.landscape:0 #: rml:account.balance.account.balance:0 msgid "Account Name" -msgstr "" +msgstr "Nome da Conta" #. module: account_balance #: rml:account.account.balance.landscape:0 #: rml:account.balance.account.balance:0 msgid "Debit" -msgstr "" +msgstr "Débito" #. module: account_balance #: wizard_button:account.balance.account.balance.report,init,checkyear:0 msgid "Print" -msgstr "" +msgstr "Impressão" #. module: account_balance #: wizard_view:account.balance.account.balance.report,init:0 msgid "Select Period(s)" -msgstr "" +msgstr "Selecione o(s) Período(s)" #. module: account_balance #: selection:account.balance.account.balance.report,init,compare_pattern:0 msgid "Percentage" -msgstr "" +msgstr "Porcentagem" #. module: account_balance #: wizard_field:account.balance.account.balance.report,init,compare_pattern:0 @@ -83,17 +83,17 @@ msgstr "" #. module: account_balance #: wizard_view:account.balance.account.balance.report,init:0 msgid "Select Fiscal Year(s)(Maximum Three Years)" -msgstr "" +msgstr "Selecione Ano(s) Fiscal(is) (máximo três anos)" #. module: account_balance #: wizard_field:account.balance.account.balance.report,init,select_account:0 msgid "Select Reference Account(for % comparision)" -msgstr "" +msgstr "Selecione conta de referência (para comparação %)" #. module: account_balance #: model:ir.actions.wizard,name:account_balance.wizard_account_balance_report msgid "Account balance-Compare Years" -msgstr "" +msgstr "Conta Saldo Comparar Anos" #. module: account_balance #: model:ir.module.module,description:account_balance.module_meta_information @@ -125,70 +125,70 @@ msgstr "" #. module: account_balance #: wizard_field:account.balance.account.balance.report,init,landscape:0 msgid "Show Report in Landscape Form" -msgstr "" +msgstr "Mostrar relatório em formato de paisagem" #. module: account_balance #: help:account.balance.account.balance.report,init,periods:0 msgid "All periods if empty" -msgstr "" +msgstr "Todos os períodos se vazio" #. module: account_balance #: selection:account.balance.account.balance.report,init,account_choice:0 msgid "With balance is not equal to 0" -msgstr "" +msgstr "Com saldo diferente de zero" #. module: account_balance #: rml:account.account.balance.landscape:0 #: rml:account.balance.account.balance:0 msgid "Total :" -msgstr "" +msgstr "Total :" #. module: account_balance #: rml:account.account.balance.landscape:0 #: rml:account.balance.account.balance:0 msgid "Account Balance -" -msgstr "" +msgstr "Saldo da conta -" #. module: account_balance #: wizard_field:account.balance.account.balance.report,init,format_perc:0 msgid "Show Comparision in %" -msgstr "" +msgstr "Mostrar comparação em %" #. module: account_balance #: wizard_view:account.balance.account.balance.report,init:0 msgid "Select Period" -msgstr "" +msgstr "Selecione o Período" #. module: account_balance #: wizard_view:account.balance.account.balance.report,init:0 msgid "Report Options" -msgstr "" +msgstr "Opções de Relatório" #. module: account_balance #: selection:account.balance.account.balance.report,init,account_choice:0 msgid "With movements" -msgstr "" +msgstr "Com movimentos" #. module: account_balance #: wizard_button:account.balance.account.balance.report,backtoinit,end:0 #: wizard_button:account.balance.account.balance.report,zero_years,end:0 msgid "Ok" -msgstr "" +msgstr "Ok" #. module: account_balance #: selection:account.balance.account.balance.report,init,compare_pattern:0 msgid "Cash" -msgstr "" +msgstr "Dinheiro" #. module: account_balance #: selection:account.balance.account.balance.report,init,compare_pattern:0 msgid "Don't Compare" -msgstr "" +msgstr "Não Comparar" #. module: account_balance #: wizard_field:account.balance.account.balance.report,init,account_choice:0 msgid "Show Accounts" -msgstr "" +msgstr "Mostrar Contas" #. module: account_balance #: rml:account.account.balance.landscape:0 diff --git a/addons/account_tax_include/i18n/fi.po b/addons/account_tax_include/i18n/fi.po new file mode 100644 index 00000000000..0b9ec7dbf7d --- /dev/null +++ b/addons/account_tax_include/i18n/fi.po @@ -0,0 +1,53 @@ +# Finnish translation for openobject-addons +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2009-08-28 16:01+0000\n" +"PO-Revision-Date: 2010-03-17 10:06+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Finnish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#. module: account_tax_include +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "Virheellinen XML näkymä-arkkitehtuurille!" + +#. module: account_tax_include +#: field:account.invoice,price_type:0 +msgid "Price method" +msgstr "Hinnan tyyppi" + +#. module: account_tax_include +#: model:ir.module.module,shortdesc:account_tax_include.module_meta_information +msgid "Invoices and prices with taxes included" +msgstr "Laskut ja hinnat veroilla" + +#. module: account_tax_include +#: selection:account.invoice,price_type:0 +msgid "Tax included" +msgstr "Vero sisältyy" + +#. module: account_tax_include +#: selection:account.invoice,price_type:0 +msgid "Tax excluded" +msgstr "Ilman veroa" + +#. module: account_tax_include +#: view:account.tax:0 +msgid "Compute Code for Taxes included prices" +msgstr "Laske koodi hinnoille joissa on vero mukana" + +#. module: account_tax_include +#: field:account.invoice.line,price_subtotal_incl:0 +msgid "Subtotal" +msgstr "Välisumma" diff --git a/addons/base_module_quality/i18n/zh_CN.po b/addons/base_module_quality/i18n/zh_CN.po index a968421924a..5df4212e113 100644 --- a/addons/base_module_quality/i18n/zh_CN.po +++ b/addons/base_module_quality/i18n/zh_CN.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2009-12-01 15:33+0000\n" -"Last-Translator: Wei \"oldrev\" Li \n" +"PO-Revision-Date: 2010-03-17 14:08+0000\n" +"Last-Translator: 英华 \n" "Language-Team: Simplified Chinese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:04+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base_module_quality @@ -86,7 +86,7 @@ msgstr "已跳过" msgid "" "The test will be completed only if the module is installed or if the test " "may be processed on uninstalled module." -msgstr "" +msgstr "只有模块已经安装或测试能在已卸载的模块上运行的情况下测试才能完成。" #. module: base_module_quality #: constraint:ir.ui.view:0 @@ -132,7 +132,7 @@ msgstr "概要" #. module: base_module_quality #: model:ir.actions.wizard,name:base_module_quality.quality_detail_save msgid "Report Save" -msgstr "" +msgstr "保存报告" #. module: base_module_quality #: wizard_view:quality_detail_save,init:0 diff --git a/addons/base_report_creator/i18n/hr.po b/addons/base_report_creator/i18n/hr.po index abef2835b05..2bf87d25ef5 100644 --- a/addons/base_report_creator/i18n/hr.po +++ b/addons/base_report_creator/i18n/hr.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2009-11-18 06:19+0000\n" -"Last-Translator: Fabien (Open ERP) \n" +"PO-Revision-Date: 2010-03-16 14:28+0000\n" +"Last-Translator: goranc \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:00+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base_report_creator @@ -23,6 +23,8 @@ msgid "" "records.\n" " e.g. res_partner.id=3" msgstr "" +"Unesite izraz za polje po kojem želite filtrirati zapise.\n" +"npr. res_partner.id=3" #. module: base_report_creator #: field:base_report_creator.report,view_graph_type:0 @@ -47,7 +49,7 @@ msgstr "Grafički" #. module: base_report_creator #: constraint:ir.actions.act_window:0 msgid "Invalid model name in the action definition." -msgstr "" +msgstr "Pogrešno ime modela u definiciji akcije." #. module: base_report_creator #: view:base_report_creator.report:0 @@ -158,7 +160,7 @@ msgstr "Kreiraj izbornik izvještaja" #: selection:base_report_creator.report,view_type2:0 #: selection:base_report_creator.report,view_type3:0 msgid "Form" -msgstr "" +msgstr "Ekran" #. module: base_report_creator #: selection:base_report_creator.report,view_type3:0 @@ -335,7 +337,7 @@ msgstr "Potvrdi filter" #. module: base_report_creator #: field:base_report_creator.report.filter,name:0 msgid "Filter Name" -msgstr "" +msgstr "Filter" #. module: base_report_creator #: model:ir.actions.wizard,name:base_report_creator.wizard_report_open diff --git a/addons/board_account/i18n/sv.po b/addons/board_account/i18n/sv.po index 978c89a0a0c..a59773f2d7e 100644 --- a/addons/board_account/i18n/sv.po +++ b/addons/board_account/i18n/sv.po @@ -7,19 +7,19 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2009-02-03 06:25+0000\n" -"Last-Translator: <>\n" +"PO-Revision-Date: 2010-03-16 08:14+0000\n" +"Last-Translator: Anders Wallenquist \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:01+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: board_account #: view:board.board:0 msgid "Analytic accounts to close" -msgstr "" +msgstr "Objektkonton att stänga" #. module: board_account #: view:board.board:0 diff --git a/addons/event_project/i18n/hi.po b/addons/event_project/i18n/hi.po index 3b14d462bc4..4fc025eee58 100644 --- a/addons/event_project/i18n/hi.po +++ b/addons/event_project/i18n/hi.po @@ -8,19 +8,19 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2010-01-15 13:24+0000\n" -"Last-Translator: vir (Open ERP) \n" +"PO-Revision-Date: 2010-03-16 22:57+0000\n" +"Last-Translator: Neetesh Biswas \n" "Language-Team: Hindi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:03+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: event_project #: constraint:ir.ui.view:0 msgid "Invalid XML for View Architecture!" -msgstr "" +msgstr "संरचना देखने के लिए अमान्य XML" #. module: event_project #: model:ir.actions.wizard,name:event_project.wizard_event_task diff --git a/addons/idea/i18n/ro.po b/addons/idea/i18n/ro.po index c1d68868d9f..7628b4a48ef 100644 --- a/addons/idea/i18n/ro.po +++ b/addons/idea/i18n/ro.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2009-11-17 06:57+0000\n" -"Last-Translator: Fabien (Open ERP) \n" +"PO-Revision-Date: 2010-03-16 13:31+0000\n" +"Last-Translator: George Dumitrescu \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 04:54+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:34+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: idea @@ -380,7 +380,7 @@ msgstr "Punctaj mediu" #. module: idea #: view:idea.idea:0 msgid "Open" -msgstr "Deschidere" +msgstr "Deschide" #. module: idea #: help:idea.idea,description:0 diff --git a/addons/mrp_subproduct/i18n/fi.po b/addons/mrp_subproduct/i18n/fi.po new file mode 100644 index 00000000000..67b65386f67 --- /dev/null +++ b/addons/mrp_subproduct/i18n/fi.po @@ -0,0 +1,89 @@ +# Finnish translation for openobject-addons +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2009-08-28 16:01+0000\n" +"PO-Revision-Date: 2010-03-16 10:41+0000\n" +"Last-Translator: smii \n" +"Language-Team: Finnish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#. module: mrp_subproduct +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "Virheellinen XML näkymä-arkkitehtuurille!" + +#. module: mrp_subproduct +#: constraint:ir.model:0 +msgid "" +"The Object name must start with x_ and not contain any special character !" +msgstr "Objektin nimen tulee alkaa x_ ja se ei saa sisältää erikoismerkkejä!" + +#. module: mrp_subproduct +#: view:mrp.bom:0 +msgid "sub products" +msgstr "" + +#. module: mrp_subproduct +#: field:mrp.subproduct,product_id:0 +msgid "Product" +msgstr "Tuote" + +#. module: mrp_subproduct +#: model:ir.model,name:mrp_subproduct.model_mrp_subproduct +msgid "Mrp Sub Product" +msgstr "" + +#. module: mrp_subproduct +#: field:mrp.subproduct,subproduct_type:0 +msgid "Quantity Type" +msgstr "" + +#. module: mrp_subproduct +#: field:mrp.subproduct,product_qty:0 +msgid "Product Qty" +msgstr "Tuotteen määrä" + +#. module: mrp_subproduct +#: field:mrp.subproduct,product_uom:0 +msgid "Product UOM" +msgstr "" + +#. module: mrp_subproduct +#: field:mrp.subproduct,bom_id:0 +msgid "BoM" +msgstr "" + +#. module: mrp_subproduct +#: view:mrp.bom:0 +msgid "Sub Products" +msgstr "" + +#. module: mrp_subproduct +#: selection:mrp.subproduct,subproduct_type:0 +msgid "Variable" +msgstr "" + +#. module: mrp_subproduct +#: field:mrp.bom,sub_products:0 +msgid "sub_products" +msgstr "" + +#. module: mrp_subproduct +#: selection:mrp.subproduct,subproduct_type:0 +msgid "Fixed" +msgstr "Ennalta määrätty" + +#. module: mrp_subproduct +#: model:ir.module.module,shortdesc:mrp_subproduct.module_meta_information +msgid "MRP Sub Product" +msgstr "" diff --git a/addons/multi_company/i18n/fi.po b/addons/multi_company/i18n/fi.po new file mode 100644 index 00000000000..88c76f9869d --- /dev/null +++ b/addons/multi_company/i18n/fi.po @@ -0,0 +1,192 @@ +# Finnish translation for openobject-addons +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2009-12-08 11:46+0000\n" +"PO-Revision-Date: 2010-03-16 10:12+0000\n" +"Last-Translator: smii \n" +"Language-Team: Finnish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#. module: multi_company +#: help:multi_company.default,object_id:0 +msgid "Object affect by this rules" +msgstr "" + +#. module: multi_company +#: constraint:ir.model:0 +msgid "" +"The Object name must start with x_ and not contain any special character !" +msgstr "Objektin nimen tulee alkaa x_ ja se ei saa sisältää erikoismerkkejä!" + +#. module: multi_company +#: constraint:product.template:0 +msgid "" +"Error: The default UOM and the purchase UOM must be in the same category." +msgstr "" + +#. module: multi_company +#: constraint:res.partner:0 +msgid "The VAT doesn't seem to be correct." +msgstr "ALV ei vaikuta olevan oikea." + +#. module: multi_company +#: constraint:ir.actions.act_window:0 +msgid "Invalid model name in the action definition." +msgstr "Virheellinen mallin nimi toiminnon määrittelyssä." + +#. module: multi_company +#: model:res.company,overdue_msg:multi_company.res_company_odoo +#: model:res.company,overdue_msg:multi_company.res_company_oerp_be +#: model:res.company,overdue_msg:multi_company.res_company_oerp_editor +#: model:res.company,overdue_msg:multi_company.res_company_oerp_in +#: model:res.company,overdue_msg:multi_company.res_company_oerp_us +msgid "" +"Would your payment have been carried out after this mail was sent, please " +"consider the present one as void. Do not hesitate to contact our accounting " +"department" +msgstr "" + +#. module: multi_company +#: field:multi_company.default,company_dest_id:0 +msgid "Default Company" +msgstr "" + +#. module: multi_company +#: field:multi_company.default,object_id:0 +msgid "Object" +msgstr "Objekti" + +#. module: multi_company +#: model:ir.module.module,shortdesc:multi_company.module_meta_information +#: view:multi_company.default:0 +msgid "Multi Company" +msgstr "" + +#. module: multi_company +#: model:ir.module.module,description:multi_company.module_meta_information +msgid "" +"This module add the possibility to easily manage \n" +" the default value for each object\n" +" " +msgstr "" + +#. module: multi_company +#: field:multi_company.default,company_id:0 +msgid "Main Company" +msgstr "Pääyritys" + +#. module: multi_company +#: view:multi_company.default:0 +msgid "Condition" +msgstr "Ehto" + +#. module: multi_company +#: help:multi_company.default,company_dest_id:0 +msgid "Company to store the current record" +msgstr "" + +#. module: multi_company +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "" + +#. module: multi_company +#: field:multi_company.default,name:0 +msgid "Name" +msgstr "Nimi" + +#. module: multi_company +#: constraint:product.template:0 +msgid "Error: UOS must be in a different category than the UOM" +msgstr "" + +#. module: multi_company +#: model:product.category,name:multi_company.Odoo1 +msgid "Odoo Offers" +msgstr "" + +#. module: multi_company +#: constraint:res.company:0 +msgid "Error! You can not create recursive companies." +msgstr "" + +#. module: multi_company +#: help:multi_company.default,name:0 +msgid "Name it to easily find a record" +msgstr "" + +#. module: multi_company +#: model:ir.ui.menu,name:multi_company.menu_custom_multicompany +msgid "Multi company" +msgstr "" + +#. module: multi_company +#: model:ir.model,name:multi_company.model_multi_company_default +msgid "multi_company.default" +msgstr "" + +#. module: multi_company +#: help:multi_company.default,company_id:0 +msgid "Company where the user is connected" +msgstr "" + +#. module: multi_company +#: model:ir.actions.act_window,name:multi_company.action_inventory_form +msgid "Default Company per Object" +msgstr "" + +#. module: multi_company +#: field:multi_company.default,expression:0 +msgid "Expression" +msgstr "Ilmaus" + +#. module: multi_company +#: model:product.template,name:multi_company.product_product_odoo1_product_template +msgid "Odoo Offer" +msgstr "" + +#. module: multi_company +#: field:multi_company.default,sequence:0 +msgid "Sequence" +msgstr "Jakso" + +#. module: multi_company +#: constraint:product.category:0 +msgid "Error ! You can not create recursive categories." +msgstr "Virhe! Et voi luoda rekursiivisia kategorioita." + +#. module: multi_company +#: constraint:product.product:0 +msgid "Error: Invalid ean code" +msgstr "Virhe: Virheellinen EAN-koodi" + +#. module: multi_company +#: help:multi_company.default,expression:0 +msgid "Expression, must be True to match" +msgstr "" + +#. module: multi_company +#: model:ir.ui.menu,name:multi_company.menu_action_inventory_form +msgid "Default company per Object" +msgstr "" + +#. module: multi_company +#: code:addons/multi_company/multi_company.py:0 +#, python-format +msgid " (copy)" +msgstr " (kopio)" + +#. module: multi_company +#: view:multi_company.default:0 +msgid "Matching" +msgstr "Vastaavuus" diff --git a/addons/report_document/i18n/it.po b/addons/report_document/i18n/it.po index d4686cae998..89af5318e35 100644 --- a/addons/report_document/i18n/it.po +++ b/addons/report_document/i18n/it.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-08-28 16:01+0000\n" -"PO-Revision-Date: 2009-09-08 13:50+0000\n" -"Last-Translator: LucaSub \n" +"PO-Revision-Date: 2010-03-16 16:02+0000\n" +"Last-Translator: yoruk \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-11 05:01+0000\n" +"X-Launchpad-Export-Date: 2010-03-18 04:35+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: report_document @@ -40,7 +40,7 @@ msgstr "" #: model:ir.ui.menu,name:report_document.menu_action_view_my_document_report_shame #: view:report.document.wall:0 msgid "Wall of Shame" -msgstr "" +msgstr "Muro della vergogna" #. module: report_document #: model:ir.model,name:report_document.model_report_files_partner @@ -52,7 +52,7 @@ msgstr "" #: field:report.document.user,file_size:0 #: field:report.files.partner,file_size:0 msgid "File Size" -msgstr "" +msgstr "Dimensione file" #. module: report_document #: constraint:ir.actions.act_window:0 @@ -68,7 +68,7 @@ msgstr "Tutti i Mesi" #: model:ir.ui.menu,name:report_document.menu_action_view_my_document_report_all_myfile #: model:ir.ui.menu,name:report_document.menu_action_view_my_document_report_this_myfile msgid "My files" -msgstr "" +msgstr "I Miei File" #. module: report_document #: view:report.document.user:0 @@ -78,7 +78,7 @@ msgstr "" #. module: report_document #: view:report.document.user:0 msgid "Files" -msgstr "" +msgstr "Files" #. module: report_document #: view:report.files.partner:0 @@ -157,7 +157,7 @@ msgstr "" #: field:report.document.user,user_id:0 #: field:report.document.wall,user_id:0 msgid "Owner" -msgstr "" +msgstr "Propietario" #. module: report_document #: field:report.document.file,nbr:0