From d5a68a7b692a6fa568c5fcebc580109afb5bb6d4 Mon Sep 17 00:00:00 2001
From: p_christeas <>
Date: Wed, 2 Dec 2009 11:06:57 +0530
Subject: [PATCH 001/123] [IMP]document : get improvement of document from
xrg-addons branch who made nice improvement in document
bzr revid: hmo@tinyerp.com-20091202053657-4oflezyhbolu3xvo
---
addons/document/__init__.py | 7 +
addons/document/__terp__.py | 8 +-
addons/document/content_index.py | 228 +++-
addons/document/directory_content.py | 113 ++
addons/document/directory_report.py | 64 +
addons/document/doc_conf_wizard.py | 163 +++
addons/document/document.py | 776 +----------
addons/document/document_data.xml | 104 +-
addons/document/document_demo.xml | 84 --
addons/document/document_directory.py | 312 +++++
addons/document/document_storage.py | 281 ++++
addons/document/document_view.xml | 178 +--
addons/document/ftpserver/__init__.py | 5 +-
addons/document/ftpserver/abstracted_fs.py | 37 +-
addons/document/ftpserver/authorizer.py | 26 +-
addons/document/ftpserver/ftpserver.py | 1375 +++++++++-----------
addons/document/nodes.py | 776 +++++++++++
addons/document/odt2txt.py | 1 +
addons/document/std_index.py | 111 ++
addons/document/test_cindex.py | 46 +
20 files changed, 2909 insertions(+), 1786 deletions(-)
create mode 100644 addons/document/directory_content.py
create mode 100644 addons/document/directory_report.py
create mode 100644 addons/document/doc_conf_wizard.py
create mode 100644 addons/document/document_directory.py
create mode 100644 addons/document/document_storage.py
create mode 100644 addons/document/nodes.py
create mode 100644 addons/document/std_index.py
create mode 100755 addons/document/test_cindex.py
diff --git a/addons/document/__init__.py b/addons/document/__init__.py
index 5c97428f05d..a9810a8b7b8 100644
--- a/addons/document/__init__.py
+++ b/addons/document/__init__.py
@@ -19,6 +19,13 @@
#
##############################################################################
+import content_index
+import std_index
+import document_storage
+import document_directory
+import directory_content
+import directory_report
+import doc_conf_wizard
import document
import ftpserver
diff --git a/addons/document/__terp__.py b/addons/document/__terp__.py
index d2246d270bf..be9eb6a9d3f 100644
--- a/addons/document/__terp__.py
+++ b/addons/document/__terp__.py
@@ -22,7 +22,7 @@
{
'name': 'Integrated Document Management System',
- 'version': '1.1',
+ 'version': '1.99',
'category': 'Generic Modules/Others',
'description': """This is a complete document management system:
* FTP Interface
@@ -32,17 +32,17 @@
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base', 'process'],
- 'init_xml': ['document_data.xml', 'document_demo.xml'],
+ 'init_xml': [],
'update_xml': [
'document_view.xml',
'document_data.xml',
'security/document_security.xml',
'security/ir.model.access.csv'
],
- 'demo_xml': [],
+ 'demo_xml': [ 'document_demo.xml',],
'installable': True,
'active': False,
- 'certificate': '0070515416461',
+ 'certificate': None,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/content_index.py b/addons/document/content_index.py
index 6c0f083b8ac..a063251c698 100644
--- a/addons/document/content_index.py
+++ b/addons/document/content_index.py
@@ -18,53 +18,195 @@
# along with this program. If not, see .
#
##############################################################################
-
-import time
import os
-import StringIO
-import odt2txt
import tempfile
-#
-# This should be the indexer
-#
-def _to_unicode(s):
- try:
- return s.decode('utf-8')
- except UnicodeError:
- try:
- return s.decode('latin')
- except UnicodeError:
- try:
- return s.encode('ascii')
- except UnicodeError:
- return s
+# A quick hack: if netsvc is not there, emulate it. Thus, work offline, too
+try:
+ import netsvc
+ def log(lvl,msg):
+ netsvc.Logger().notifyChannel("index",lvl,msg)
+except:
+ class netsvc:
+ LOG_NOTSET = 'notset'
+ LOG_DEBUG_RPC = 'debug_rpc'
+ LOG_DEBUG = 'debug'
+ LOG_DEBUG2 = 'debug2'
+ LOG_INFO = 'info'
+ LOG_WARNING = 'warn'
+ LOG_ERROR = 'error'
+ LOG_CRITICAL = 'critical'
+
+ def log(lvl,msg):
+ print msg
-def content_index(content, filename=None, content_type=None):
- fname,ext = os.path.splitext(filename)
- result = ''
- if ext in ('.doc'): #or content_type ?
- (stdin,stdout) = os.popen2('antiword -', 'b')
- stdin.write(content)
- stdin.close()
- result = _to_unicode(stdout.read())
- elif ext == '.pdf':
- file_descriptor, file_name = tempfile.mkstemp(suffix=ext)
- os.write(file_descriptor, content)
- os.close(file_descriptor)
- fp = os.popen('pdftotext -enc UTF-8 -nopgbrk '+file_name+' -', 'r')
- result = fp.read()
- fp.close()
- elif ext in ('.xls','.ods','.odt','.odp'):
- s = StringIO.StringIO(content)
- o = odt2txt.OpenDocumentTextFile(s)
- result = _to_unicode(o.toString())
- s.close()
- elif ext in ('.txt','.py','.patch','.html','.csv','.xml'):
- result = content
- #else:
- # result = content
- return result
+class NhException(Exception):
+ pass
+
+from subprocess import Popen, PIPE
+
+class indexer():
+ """ An indexer knows how to parse the content of some file.
+
+ Typically, one indexer should be instantiated per file
+ type.
+ Override this class to add more functionality. Note that
+ you should only override the Content or the File methods
+ that give an optimal result. """
+
+ def _getMimeTypes(self):
+ """ Return supported mimetypes """
+ return []
+
+ def _getExtensions(self):
+ return []
+
+ def _getDefMime(self,ext):
+ """ Return a mimetype for this document type, ideally the
+ closest to the extension ext. """
+ mts = self._getMimeTypes();
+ if len (mts):
+ return mts[0]
+ return None
+
+ def indexContent(self,content,filename=None, realfile = None):
+ """ Use either content or the real file, to index.
+ Some parsers will work better with the actual
+ content, others parse a file easier. Try the
+ optimal.
+ """
+ res = ''
+ try:
+ if content != None:
+ return self._doIndexContent(content)
+ except NhException:
+ pass
+
+ if realfile != None:
+ try:
+ return self._doIndexFile(realfile)
+ except NhException:
+ pass
+
+ fp = open(realfile,'rb')
+ content2 = fp.read()
+ fp.close()
+
+ # The not-handled exception may be raised here
+ return self._doIndexContent(content2)
+
+
+ # last try, with a tmp file
+ if content:
+ try:
+ fname,ext = filename and os.path.splitext(filename) or ('','')
+ fd, rfname = tempfile.mkstemp(suffix=ext)
+ os.write(fd, content)
+ os.close(fd)
+ res = self._doIndexFile(rfname)
+ os.unlink(rfname)
+ return res
+ except NhException:
+ pass
+
+ raise NhException('No appropriate method to index file')
+
+ def _doIndexContent(self,content):
+ raise NhException("Content not handled here")
+
+ def _doIndexFile(self,fpath):
+ raise NhException("Content not handled here")
+
+
+
+def mime_match(mime, mdict):
+ if mdict.has_key(mime):
+ return (mime, mdict[mime])
+ if '/' in mime:
+ mpat = mime.split('/')[0]+'/*'
+ if mdict.has_key(mpat):
+ return (mime, mdict[mpat])
+
+ return (None, None)
+
+class contentIndex() :
+ def __init__(self):
+ self.mimes = {}
+ self.exts = {}
+
+ def register(self, obj):
+ f = False
+ for mime in obj._getMimeTypes():
+ self.mimes[mime] = obj
+ f = True
+
+ for ext in obj._getExtensions():
+ self.exts[ext] = obj
+ f = True
+
+ if f:
+ log(netsvc.LOG_DEBUG, "Register content indexer: %r" % obj)
+ if not f:
+ raise Exception("Your indexer should at least suport a mimetype or extension")
+
+ def doIndex(self,content, filename=None, content_type=None, realfname = None, debug=False):
+ fobj = None
+ fname = None
+ mime = None
+ if content_type and self.mimes.has_key(content_type):
+ mime = content_type
+ fobj = self.mimes[content_type]
+ elif filename:
+ bname,ext = os.path.splitext(filename)
+ if self.exts.has_key(ext):
+ fobj = self.exts[ext]
+ mime = fobj._getDefMime(ext)
+
+ if content_type and not fobj:
+ mime,fobj = mime_match(content_type, self.mimes)
+
+ if not fobj:
+ try:
+ if realfname :
+ fname = realfname
+ else:
+ bname,ext = os.path.splitext(filename)
+ fd, fname = tempfile.mkstemp(suffix=ext)
+ os.write(fd, content)
+ os.close(fd)
+
+ fp = Popen(['file','-b','--mime-type',fname], shell=False, stdout=PIPE).stdout
+ result = fp.read()
+ fp.close()
+ mime2 = result.strip()
+ log(netsvc.LOG_DEBUG,"File gave us: %s" % mime2)
+ # Note that the temporary file still exists now.
+ mime,fobj = mime_match(mime2, self.mimes)
+ if not mime:
+ mime = mime2
+ except Exception, e:
+ log(netsvc.LOG_WARNING,"Cannot determine mime type: %s" % str(e))
+
+ try:
+ if fobj:
+ res = (mime, fobj.indexContent(content,filename,fname or realfname) )
+ else:
+ log(netsvc.LOG_DEBUG,"Have no object, return (%s, None)" % mime)
+ res = (mime, None )
+ except Exception, e:
+ log(netsvc.LOG_WARNING,"Could not index file, %s" % e)
+ res = None
+
+ # If we created a tmp file, unlink it now
+ if not realfname and fname:
+ try:
+ os.unlink(fname)
+ except Exception, e:
+ log(netsvc.LOG_WARNING,"Could not unlink %s, %s" %(fname, e))
+
+ return res
+
+cntIndex = contentIndex()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py
new file mode 100644
index 00000000000..4ccad653711
--- /dev/null
+++ b/addons/document/directory_content.py
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+import base64
+
+from osv import osv, fields
+from osv.orm import except_orm
+import urlparse
+
+import os
+import nodes
+
+class document_directory_content_type(osv.osv):
+ _name = 'document.directory.content.type'
+ _description = 'Directory Content Type'
+ _columns = {
+ 'name': fields.char('Content Type', size=64, required=True),
+ 'code': fields.char('Extension', size=4),
+ 'active': fields.boolean('Active'),
+ 'mimetype': fields.char('Mime Type',size=32)
+ }
+ _defaults = {
+ 'active': lambda *args: 1
+ }
+document_directory_content_type()
+
+class document_directory_content(osv.osv):
+ _name = 'document.directory.content'
+ _description = 'Directory Content'
+ _order = "sequence"
+ def _extension_get(self, cr, uid, context={}):
+ cr.execute('select code,name from document_directory_content_type where active')
+ res = cr.fetchall()
+ return res
+ _columns = {
+ 'name': fields.char('Content Name', size=64, required=True),
+ 'sequence': fields.integer('Sequence', size=16),
+ 'prefix': fields.char('Prefix', size=16),
+ 'suffix': fields.char('Suffix', size=16),
+ 'report_id': fields.many2one('ir.actions.report.xml', 'Report'),
+ 'extension': fields.selection(_extension_get, 'Document Type', required=True, size=4),
+ 'include_name': fields.boolean('Include Record Name', help="Check this field if you want that the name of the file start by the record name."),
+ 'directory_id': fields.many2one('document.directory', 'Directory'),
+ }
+ _defaults = {
+ 'extension': lambda *args: '.pdf',
+ 'sequence': lambda *args: 1,
+ 'include_name': lambda *args: 1,
+ }
+
+ def _file_get(self,cr,node, nodename, content, context=None):
+ """ return the nodes of a parent having a content
+ The return value MUST be false or a list of node_class objects.
+ """
+
+ # TODO: respect the context!
+ if content.include_name and not node.object2:
+ return False
+
+ res2 = []
+ tname = ''
+ if content.include_name:
+ content_name = node.object2.name
+ obj = pool.get(node.object.ressource_type_id.model)
+ name_for = obj._name.split('.')[-1]
+ if content_name and content_name.find(name_for) == 0 :
+ content_name = content_name.replace(name_for,'')
+ tname = (content.prefix or '') + content_name + (content.suffix or '') + (content.extension or '')
+ else:
+ tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '')
+ if tname.find('/'):
+ tname=tname.replace('/', '_')
+ if not nodename:
+ n = nodes.node_content(tname, node, node.context,content)
+ res2.append( n)
+ else:
+ if nodename == tname:
+ n = nodes.node_content(tname, node, node.context,content)
+ n.fill_fields(cr)
+ res2.append(n)
+ return res2
+
+ def process_write(self, cr, uid, node, data):
+ if node.extension != '.pdf':
+ raise Exception("Invalid content: %s" % node.extension)
+ return True
+ def process_read(self, cr, uid, node):
+ if node.extension != '.pdf':
+ raise Exception("Invalid content: %s" % node.extension)
+ report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.content.report_id.id)
+ srv = netsvc.LocalService('report.'+report.report_name)
+ pdf,pdftype = srv.create(cr, uid, [node.object.id], {}, {})
+ s = StringIO.StringIO(pdf)
+ s.name = node
+ return s
+document_directory_content()
diff --git a/addons/document/directory_report.py b/addons/document/directory_report.py
new file mode 100644
index 00000000000..b5a80adc7ec
--- /dev/null
+++ b/addons/document/directory_report.py
@@ -0,0 +1,64 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
+# $Id$
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import base64
+
+from osv import osv, fields
+from osv.orm import except_orm
+import urlparse
+
+import os
+
+class ir_action_report_xml(osv.osv):
+ _name="ir.actions.report.xml"
+ _inherit ="ir.actions.report.xml"
+
+ def _model_get(self, cr, uid, ids, name, arg, context):
+ res = {}
+ model_pool = self.pool.get('ir.model')
+ for data in self.read(cr,uid,ids,['model']):
+ model = data.get('model',False)
+ if model:
+ model_id =model_pool.search(cr,uid,[('model','=',model)])
+ if model_id:
+ res[data.get('id')] = model_id[0]
+ else:
+ res[data.get('id')] = False
+ return res
+
+ def _model_search(self, cr, uid, obj, name, args):
+ if not len(args):
+ return []
+ model_id= args[0][2]
+ if not model_id:
+ return []
+ model = self.pool.get('ir.model').read(cr,uid,[model_id])[0]['model']
+ report_id = self.search(cr,uid,[('model','=',model)])
+ if not report_id:
+ return [('id','=','0')]
+ return [('id','in',report_id)]
+
+ _columns={
+ 'model_id' : fields.function(_model_get,fnct_search=_model_search,method=True,string='Model Id'),
+ }
+
+ir_action_report_xml()
diff --git a/addons/document/doc_conf_wizard.py b/addons/document/doc_conf_wizard.py
new file mode 100644
index 00000000000..66354c8876b
--- /dev/null
+++ b/addons/document/doc_conf_wizard.py
@@ -0,0 +1,163 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import base64
+
+from osv import osv, fields
+from osv.orm import except_orm
+import urlparse
+
+import os
+
+class document_configuration_wizard(osv.osv_memory):
+ _name='document.configuration.wizard'
+ _rec_name = 'Auto Directory configuration'
+ _columns = {
+ 'host': fields.char('Server Address', size=64, help="Put here the server address or IP. " \
+ "Keep localhost if you don't know what to write.", required=True)
+ }
+
+ def detect_ip_addr(self, cr, uid, context=None):
+ def _detect_ip_addr(self, cr, uid, context=None):
+ from array import array
+ import socket
+ from struct import pack, unpack
+
+ try:
+ import fcntl
+ except ImportError:
+ fcntl = None
+
+ if not fcntl: # not UNIX:
+ host = socket.gethostname()
+ ip_addr = socket.gethostbyname(host)
+ else: # UNIX:
+ # get all interfaces:
+ nbytes = 128 * 32
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ names = array('B', '\0' * nbytes)
+ outbytes = unpack('iL', fcntl.ioctl( s.fileno(), 0x8912, pack('iL', nbytes, names.buffer_info()[0])))[0]
+ namestr = names.tostring()
+ ifaces = [namestr[i:i+32].split('\0', 1)[0] for i in range(0, outbytes, 32)]
+
+ for ifname in [iface for iface in ifaces if iface != 'lo']:
+ ip_addr = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, pack('256s', ifname[:15]))[20:24])
+ break
+ return ip_addr
+
+ try:
+ ip_addr = _detect_ip_addr(self, cr, uid, context)
+ except:
+ ip_addr = 'localhost'
+ return ip_addr
+
+ _defaults = {
+ 'host': detect_ip_addr,
+ }
+
+ def action_cancel(self,cr,uid,ids,conect=None):
+ return {
+ 'view_type': 'form',
+ "view_mode": 'form',
+ 'res_model': 'ir.actions.configuration.wizard',
+ 'type': 'ir.actions.act_window',
+ 'target':'new',
+ }
+
+ def action_config(self, cr, uid, ids, context=None):
+ conf = self.browse(cr, uid, ids[0], context)
+ obj=self.pool.get('document.directory')
+ objid=self.pool.get('ir.model.data')
+
+ if self.pool.get('sale.order'):
+ id = objid._get_id(cr, uid, 'document', 'dir_sale_order_all')
+ id = objid.browse(cr, uid, id, context=context).res_id
+ mid = self.pool.get('ir.model').search(cr, uid, [('model','=','sale.order')])
+ obj.write(cr, uid, [id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ 'domain': '[]',
+ })
+ aid = objid._get_id(cr, uid, 'sale', 'report_sale_order')
+ aid = objid.browse(cr, uid, aid, context=context).res_id
+
+ self.pool.get('document.directory.content').create(cr, uid, {
+ 'name': "Print Order",
+ 'suffix': "_print",
+ 'report_id': aid,
+ 'extension': '.pdf',
+ 'include_name': 1,
+ 'directory_id': id,
+ })
+ id = objid._get_id(cr, uid, 'document', 'dir_sale_order_quote')
+ id = objid.browse(cr, uid, id, context=context).res_id
+ obj.write(cr, uid, [id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ 'domain': "[('state','=','draft')]",
+ })
+
+ if self.pool.get('product.product'):
+ id = objid._get_id(cr, uid, 'document', 'dir_product')
+ id = objid.browse(cr, uid, id, context=context).res_id
+ mid = self.pool.get('ir.model').search(cr, uid, [('model','=','product.product')])
+ obj.write(cr, uid, [id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ })
+
+ if self.pool.get('stock.location'):
+ aid = objid._get_id(cr, uid, 'stock', 'report_product_history')
+ aid = objid.browse(cr, uid, aid, context=context).res_id
+
+ self.pool.get('document.directory.content').create(cr, uid, {
+ 'name': "Product Stock",
+ 'suffix': "_stock_forecast",
+ 'report_id': aid,
+ 'extension': '.pdf',
+ 'include_name': 1,
+ 'directory_id': id,
+ })
+
+ if self.pool.get('account.analytic.account'):
+ id = objid._get_id(cr, uid, 'document', 'dir_project')
+ id = objid.browse(cr, uid, id, context=context).res_id
+ mid = self.pool.get('ir.model').search(cr, uid, [('model','=','account.analytic.account')])
+ obj.write(cr, uid, [id], {
+ 'type':'ressource',
+ 'ressource_type_id': mid[0],
+ 'domain': '[]',
+ 'ressource_tree': 1
+ })
+
+ # Update the action for FTP browse.
+ aid = objid._get_id(cr, uid, 'document', 'action_document_browse')
+ aid = objid.browse(cr, uid, aid, context=context).res_id
+ self.pool.get('ir.actions.url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost')+':8021/'})
+
+ return {
+ 'view_type': 'form',
+ "view_mode": 'form',
+ 'res_model': 'ir.actions.configuration.wizard',
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+document_configuration_wizard()
diff --git a/addons/document/document.py b/addons/document/document.py
index cd3d667f8bf..1dffba0453d 100644
--- a/addons/document/document.py
+++ b/addons/document/document.py
@@ -22,498 +22,19 @@
import base64
from osv import osv, fields
-from osv.orm import except_orm
import urlparse
import os
import pooler
-from content_index import content_index
import netsvc
-import StringIO
+#import StringIO
-import random
-import string
from psycopg2 import Binary
-from tools import config
+#from tools import config
import tools
from tools.translate import _
-
-def random_name():
- random.seed()
- d = [random.choice(string.ascii_letters) for x in xrange(10) ]
- name = "".join(d)
- return name
-
-
-# Unsupported WebDAV Commands:
-# label
-# search
-# checkin
-# checkout
-# propget
-# propset
-
-#
-# An object that represent an uri
-# path: the uri of the object
-# content: the Content it belongs to (_print.pdf)
-# type: content or collection
-# content: objct = res.partner
-# collection: object = directory, object2 = res.partner
-# file: objct = ir.attachement
-# root: if we are at the first directory of a ressource
-#
-INVALID_CHARS={'*':str(hash('*')), '|':str(hash('|')) , "\\":str(hash("\\")), '/':'__', ':':str(hash(':')), '"':str(hash('"')), '<':str(hash('<')) , '>':str(hash('>')) , '?':str(hash('?'))}
-
-
-class node_class(object):
- def __init__(self, cr, uid, path, object, object2=False, context={}, content=False, type='collection', root=False):
- self.cr = cr
- self.uid = uid
- self.path = path
- self.object = object
- self.object2 = object2
- self.context = context
- self.content = content
- self.type=type
- self.root=root
-
- def _file_get(self, nodename=False):
- if not self.object:
- return []
- pool = pooler.get_pool(self.cr.dbname)
- fobj = pool.get('ir.attachment')
- res2 = []
- where = []
- if self.object2:
- where.append( ('res_model','=',self.object2._name) )
- where.append( ('res_id','=',self.object2.id) )
- else:
- where.append( ('parent_id','=',self.object.id) )
- where.append( ('res_id','=',False) )
- if nodename:
- where.append( (fobj._rec_name,'=',nodename) )
- for content in self.object.content_ids:
- if self.object2 or not content.include_name:
- if content.include_name:
- content_name = self.object2.name
- obj = pool.get(self.object.ressource_type_id.model)
- name_for = obj._name.split('.')[-1]
- if content_name and content_name.find(name_for) == 0 :
- content_name = content_name.replace(name_for,'')
- test_nodename = content_name + (content.suffix or '') + (content.extension or '')
- else:
- test_nodename = (content.suffix or '') + (content.extension or '')
- if test_nodename.find('/'):
- test_nodename=test_nodename.replace('/', '_')
- path = self.path+'/'+test_nodename
- if not nodename:
- n = node_class(self.cr, self.uid,path, self.object2, False, context=self.context, content=content, type='content', root=False)
- res2.append( n)
- else:
- if nodename == test_nodename:
- n = node_class(self.cr, self.uid, path, self.object2, False, context=self.context, content=content, type='content', root=False)
- res2.append(n)
-
- ids = fobj.search(self.cr, self.uid, where+[ ('parent_id','=',self.object and self.object.id or False) ])
- if self.object and self.root and (self.object.type=='ressource'):
- ids += fobj.search(self.cr, self.uid, where+[ ('parent_id','=',False) ])
- res = fobj.browse(self.cr, self.uid, ids, context=self.context)
- return map(lambda x: node_class(self.cr, self.uid, self.path+'/'+eval('x.'+fobj._rec_name), x, False, context=self.context, type='file', root=False), res) + res2
-
- def get_translation(self,value,lang):
- result = value
- #TODO : to get translation term
- return result
-
- def directory_list_for_child(self,nodename,parent=False):
- pool = pooler.get_pool(self.cr.dbname)
- where = []
- if nodename:
- nodename = self.get_translation(nodename, self.context['lang'])
- where.append(('name','=',nodename))
- if (self.object and self.object.type=='directory') or not self.object2:
- where.append(('parent_id','=',self.object and self.object.id or False))
- else:
- where.append(('parent_id','=',False))
- if self.object:
- where.append(('ressource_parent_type_id','=',self.object.ressource_type_id.id))
- else:
- where.append(('ressource_parent_type_id','=',False))
-
- ids = pool.get('document.directory').search(self.cr, self.uid, where+[('ressource_id','=',0)])
- if self.object2:
- ids += pool.get('document.directory').search(self.cr, self.uid, where+[('ressource_id','=',self.object2.id)])
- res = pool.get('document.directory').browse(self.cr, self.uid, ids, self.context)
- return res
-
- def _child_get(self, nodename=False):
- if self.type not in ('collection','database'):
- return []
- res = self.directory_list_for_child(nodename)
- result= map(lambda x: node_class(self.cr, self.uid, self.path+'/'+x.name, x, x.type=='directory' and self.object2 or False, context=self.context, root=self.root), res)
- if self.type=='database':
- pool = pooler.get_pool(self.cr.dbname)
- fobj = pool.get('ir.attachment')
- vargs = [('parent_id','=',False),('res_id','=',False)]
- if nodename:
- vargs.append((fobj._rec_name,'=',nodename))
- file_ids=fobj.search(self.cr,self.uid,vargs)
-
- res = fobj.browse(self.cr, self.uid, file_ids, context=self.context)
- result +=map(lambda x: node_class(self.cr, self.uid, self.path+'/'+eval('x.'+fobj._rec_name), x, False, context=self.context, type='file', root=self.root), res)
- if self.type=='collection' and self.object.type=="ressource":
- where = self.object.domain and eval(self.object.domain, {'active_id':self.root, 'uid':self.uid}) or []
- pool = pooler.get_pool(self.cr.dbname)
- obj = pool.get(self.object.ressource_type_id.model)
- _dirname_field = obj._rec_name
- if len(obj.fields_get(self.cr, self.uid, ['dirname'])):
- _dirname_field = 'dirname'
-
- name_for = obj._name.split('.')[-1]
- if nodename and nodename.find(name_for) == 0 :
- id = int(nodename.replace(name_for,''))
- where.append(('id','=',id))
- elif nodename:
- if nodename.find('__') :
- nodename=nodename.replace('__','/')
- for invalid in INVALID_CHARS:
- if nodename.find(INVALID_CHARS[invalid]) :
- nodename=nodename.replace(INVALID_CHARS[invalid],invalid)
- nodename = self.get_translation(nodename, self.context['lang'])
- where.append((_dirname_field,'=',nodename))
-
- if self.object.ressource_tree:
- if obj._parent_name in obj.fields_get(self.cr,self.uid):
- where.append((obj._parent_name,'=',self.object2 and self.object2.id or False))
- ids = obj.search(self.cr, self.uid, where)
- res = obj.browse(self.cr, self.uid, ids,self.context)
- result+= map(lambda x: node_class(self.cr, self.uid, self.path+'/'+x.name.replace('/','__'), self.object, x, context=self.context, root=x.id), res)
- return result
- else :
- if self.object2:
- return result
- else:
- if self.object2:
- return result
-
-
- ids = obj.search(self.cr, self.uid, where)
- res = obj.browse(self.cr, self.uid, ids,self.context)
- for r in res:
- if len(obj.fields_get(self.cr, self.uid, [_dirname_field])):
- r.name = eval('r.'+_dirname_field)
- else:
- r.name = False
- if not r.name:
- r.name = name_for + '%d'%r.id
- for invalid in INVALID_CHARS:
- if r.name.find(invalid) :
- r.name = r.name.replace(invalid,INVALID_CHARS[invalid])
- result2 = map(lambda x: node_class(self.cr, self.uid, self.path+'/'+x.name.replace('/','__'), self.object, x, context=self.context, root=x.id), res)
- if result2:
- if self.object.ressource_tree:
- result += result2
- else:
- result = result2
- return result
-
- def children(self):
- return self._child_get() + self._file_get()
-
- def child(self, name):
- res = self._child_get(name)
- if res:
- return res[0]
- res = self._file_get(name)
- if res:
- return res[0]
- return None
-
- def path_get(self):
- path = self.path
- if self.path[0]=='/':
- path = self.path[1:]
- return path
-
-class document_directory(osv.osv):
- _name = 'document.directory'
- _description = 'Document directory'
- _columns = {
- 'name': fields.char('Name', size=64, required=True, select=1),
- 'write_date': fields.datetime('Date Modified', readonly=True),
- 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
- 'create_date': fields.datetime('Date Created', readonly=True),
- 'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
- 'file_type': fields.char('Content Type', size=32),
- 'domain': fields.char('Domain', size=128, help="Use a domain if you want to apply an automatic filter on visible resources."),
- 'user_id': fields.many2one('res.users', 'Owner'),
- 'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
- 'parent_id': fields.many2one('document.directory', 'Parent Item'),
- 'child_ids': fields.one2many('document.directory', 'parent_id', 'Children'),
- 'file_ids': fields.one2many('ir.attachment', 'parent_id', 'Files'),
- 'content_ids': fields.one2many('document.directory.content', 'directory_id', 'Virtual Files'),
- 'type': fields.selection([('directory','Static Directory'),('ressource','Other Resources')], 'Type', required=True),
- 'ressource_type_id': fields.many2one('ir.model', 'Directories Mapped to Objects',
- help="Select an object here and Open ERP will create a mapping for each of these " \
- "objects, using the given domain, when browsing through FTP."),
- 'ressource_parent_type_id': fields.many2one('ir.model', 'Parent Model',
- help="If you put an object here, this directory template will appear bellow all of these objects. " \
- "Don't put a parent directory if you select a parent model."),
- 'ressource_id': fields.integer('Resource ID'),
- 'ressource_tree': fields.boolean('Tree Structure',
- help="Check this if you want to use the same tree structure as the object selected in the system."),
- }
- _defaults = {
- 'user_id': lambda self,cr,uid,ctx: uid,
- 'domain': lambda self,cr,uid,ctx: '[]',
- 'type': lambda *args: 'directory',
- 'ressource_id': lambda *a: 0
- }
- _sql_constraints = [
- ('dirname_uniq', 'unique (name,parent_id,ressource_id,ressource_parent_type_id)', 'The directory name must be unique !')
- ]
-
- def get_resource_path(self,cr,uid,dir_id,res_model,res_id):
- # this method will be used in process module
- # to be need test and Improvement if resource dir has parent resource (link resource)
- path=[]
- def _parent(dir_id,path):
- parent=self.browse(cr,uid,dir_id)
- if parent.parent_id and not parent.ressource_parent_type_id:
- _parent(parent.parent_id.id,path)
- path.append(parent.name)
- else:
- path.append(parent.name)
- return path
-
- directory=self.browse(cr,uid,dir_id)
- model_ids=self.pool.get('ir.model').search(cr,uid,[('model','=',res_model)])
- if directory:
- _parent(dir_id,path)
- if res_id:
- path.append(self.pool.get(directory.ressource_type_id.model).browse(cr,uid,res_id).name)
- user=self.pool.get('res.users').browse(cr,uid,uid)
- return "ftp://%s:%s@localhost:%s/%s/%s"%(user.login,user.password,config.get('ftp_server_port',8021),cr.dbname,'/'.join(path))
- return False
-
- def _check_recursion(self, cr, uid, ids):
- level = 100
- while len(ids):
- cr.execute('select distinct parent_id from document_directory where id in ('+','.join(map(str, ids))+')')
- ids = filter(None, map(lambda x:x[0], cr.fetchall()))
- if not level:
- return False
- level -= 1
- return True
-
- _constraints = [
- (_check_recursion, 'Error! You can not create recursive Directories.', ['parent_id'])
- ]
- def __init__(self, *args, **kwargs):
- res = super(document_directory, self).__init__(*args, **kwargs)
- self._cache = {}
-
- def onchange_content_id(self, cr, uid, ids, ressource_type_id):
- return {}
-
- def _get_childs(self, cr, uid, node, nodename=False, context={}):
- where = []
- if nodename:
- nodename = self.get_translation(nodename, self.context['lang'])
- where.append(('name','=',nodename))
- if object:
- where.append(('parent_id','=',object.id))
- ids = self.search(cr, uid, where, context)
- return self.browse(cr, uid, ids, context), False
-
- """
- PRE:
- uri: of the form "Sales Order/SO001"
- PORT:
- uri
- object: the object.directory or object.directory.content
- object2: the other object linked (if object.directory.content)
- """
- def get_object(self, cr, uid, uri, context={}):
- #TODO : set user's context_lang in context
- context.update({'lang':False})
- if not uri:
- return node_class(cr, uid, '', False, context=context, type='database')
- turi = tuple(uri)
- if False and (turi in self._cache):
- (path, oo, oo2, context, content,type,root) = self._cache[turi]
- if oo:
- object = self.pool.get(oo[0]).browse(cr, uid, oo[1], context)
- else:
- object = False
- if oo2:
- object2 = self.pool.get(oo2[0]).browse(cr, uid, oo2[1], context)
- else:
- object2 = False
- node = node_class(cr, uid, '/', False, context=context, type='database')
- return node
-
- node = node_class(cr, uid, '/', False, context=context, type='database')
- for path in uri[:]:
- if path:
- node = node.child(path)
- if not node:
- return False
- oo = node.object and (node.object._name, node.object.id) or False
- oo2 = node.object2 and (node.object2._name, node.object2.id) or False
- self._cache[turi] = (node.path, oo, oo2, node.context, node.content,node.type,node.root)
- return node
-
- def get_childs(self, cr, uid, uri, context={}):
- node = self.get_object(cr, uid, uri, context)
- if uri:
- children = node.children()
- else:
- children= [node]
- result = map(lambda node: node.path_get(), children)
- #childs,object2 = self._get_childs(cr, uid, object, False, context)
- #result = map(lambda x: urlparse.urljoin(path+'/',x.name), childs)
- return result
-
- def copy(self, cr, uid, id, default=None, context=None):
- if not default:
- default ={}
- name = self.read(cr, uid, [id])[0]['name']
- default.update({'name': name+ " (copy)"})
- return super(document_directory,self).copy(cr,uid,id,default,context)
-
- def _check_duplication(self, cr, uid,vals,ids=[],op='create'):
- name=vals.get('name',False)
- parent_id=vals.get('parent_id',False)
- ressource_parent_type_id=vals.get('ressource_parent_type_id',False)
- ressource_id=vals.get('ressource_id',0)
- if op=='write':
- for directory in self.browse(cr,uid,ids):
- if not name:
- name=directory.name
- if not parent_id:
- parent_id=directory.parent_id and directory.parent_id.id or False
- if not ressource_parent_type_id:
- ressource_parent_type_id=directory.ressource_parent_type_id and directory.ressource_parent_type_id.id or False
- if not ressource_id:
- ressource_id=directory.ressource_id and directory.ressource_id or 0
- res=self.search(cr,uid,[('id','<>',directory.id),('name','=',name),('parent_id','=',parent_id),('ressource_parent_type_id','=',ressource_parent_type_id),('ressource_id','=',ressource_id)])
- if len(res):
- return False
- if op=='create':
- res=self.search(cr,uid,[('name','=',name),('parent_id','=',parent_id),('ressource_parent_type_id','=',ressource_parent_type_id),('ressource_id','=',ressource_id)])
- if len(res):
- return False
- return True
- def write(self, cr, uid, ids, vals, context=None):
- if not self._check_duplication(cr,uid,vals,ids,op='write'):
- raise osv.except_osv(_('ValidateError'), _('Directory name must be unique!'))
- return super(document_directory,self).write(cr,uid,ids,vals,context=context)
-
- def create(self, cr, uid, vals, context=None):
- if not self._check_duplication(cr,uid,vals):
- raise osv.except_osv(_('ValidateError'), _('Directory name must be unique!'))
- if vals.get('name',False) and (vals.get('name').find('/')+1 or vals.get('name').find('@')+1 or vals.get('name').find('$')+1 or vals.get('name').find('#')+1) :
- raise osv.except_osv(_('ValidateError'), _('Directory name contains special characters!'))
- return super(document_directory,self).create(cr, uid, vals, context)
-
-document_directory()
-
-class document_directory_node(osv.osv):
- _inherit = 'process.node'
- _columns = {
- 'directory_id': fields.many2one('document.directory', 'Document directory', ondelete="set null"),
- }
-document_directory_node()
-
-class document_directory_content_type(osv.osv):
- _name = 'document.directory.content.type'
- _description = 'Directory Content Type'
- _columns = {
- 'name': fields.char('Content Type', size=64, required=True),
- 'code': fields.char('Extension', size=4),
- 'active': fields.boolean('Active'),
- }
- _defaults = {
- 'active': lambda *args: 1
- }
-document_directory_content_type()
-
-class document_directory_content(osv.osv):
- _name = 'document.directory.content'
- _description = 'Directory Content'
- _order = "sequence"
- def _extension_get(self, cr, uid, context={}):
- cr.execute('select code,name from document_directory_content_type where active')
- res = cr.fetchall()
- return res
- _columns = {
- 'name': fields.char('Content Name', size=64, required=True),
- 'sequence': fields.integer('Sequence', size=16),
- 'suffix': fields.char('Suffix', size=16),
- 'report_id': fields.many2one('ir.actions.report.xml', 'Report'),
- 'extension': fields.selection(_extension_get, 'Document Type', required=True, size=4),
- 'include_name': fields.boolean('Include Record Name', help="Check this field if you want that the name of the file start by the record name."),
- 'directory_id': fields.many2one('document.directory', 'Directory'),
- }
- _defaults = {
- 'extension': lambda *args: '.pdf',
- 'sequence': lambda *args: 1,
- 'include_name': lambda *args: 1,
- }
- def process_write_pdf(self, cr, uid, node, context={}):
- return True
- def process_read_pdf(self, cr, uid, node, context={}):
- report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.content.report_id.id)
- srv = netsvc.LocalService('report.'+report.report_name)
- pdf,pdftype = srv.create(cr, uid, [node.object.id], {}, {})
- s = StringIO.StringIO(pdf)
- s.name = node
- return s
-document_directory_content()
-
-class ir_action_report_xml(osv.osv):
- _name="ir.actions.report.xml"
- _inherit ="ir.actions.report.xml"
-
- def _model_get(self, cr, uid, ids, name, arg, context):
- res = {}
- model_pool = self.pool.get('ir.model')
- for data in self.read(cr,uid,ids,['model']):
- model = data.get('model',False)
- if model:
- model_id =model_pool.search(cr,uid,[('model','=',model)])
- if model_id:
- res[data.get('id')] = model_id[0]
- else:
- res[data.get('id')] = False
- return res
-
- def _model_search(self, cr, uid, obj, name, args):
- if not len(args):
- return []
- model_id= args[0][2]
- if not model_id:
- return []
- model = self.pool.get('ir.model').read(cr,uid,[model_id])[0]['model']
- report_id = self.search(cr,uid,[('model','=',model)])
- if not report_id:
- return [('id','=','0')]
- return [('id','in',report_id)]
-
- _columns={
- 'model_id' : fields.function(_model_get,fnct_search=_model_search,method=True,string='Model Id'),
- }
-
-ir_action_report_xml()
-
-def create_directory(path):
- dir_name = random_name()
- path = os.path.join(path,dir_name)
- os.makedirs(path)
- return dir_name
+import nodes
class document_file(osv.osv):
_inherit = 'ir.attachment'
@@ -522,70 +43,49 @@ class document_file(osv.osv):
return os.path.join(tools.config['root_path'], 'filestore', cr.dbname)
def _data_get(self, cr, uid, ids, name, arg, context):
+ fbrl = self.browse(cr,uid,ids,context=context)
+ nctx = nodes.get_node_context(cr,uid,context)
result = {}
- cr.execute('select id,store_fname,link from ir_attachment where id in ('+','.join(map(str, ids))+')')
- for id,r,l in cr.fetchall():
- try:
- value = file(os.path.join(self._get_filestore(cr), r), 'rb').read()
- result[id] = base64.encodestring(value)
- except:
- result[id]=''
-# if context.get('bin_size', False):
-# result[id] = tools.human_size(result[id])
+ bin_size = context.get('bin_size', False)
+ for fbro in fbrl:
+ fnode = nodes.node_file(None,None,nctx,fbro)
+ if not bin_size:
+ data = fnode.get_data(cr,fbro)
+ result[fbro.id] = base64.encodestring(data or '')
+ else:
+ result[fbro.id] = fnode.get_data_len(cr,fbro)
+
return result
#
# This code can be improved
#
- def _data_set(self, cr, uid, id, name, value, args=None, context={}):
+ def _data_set(self, cr, uid, id, name, value, arg, context):
if not value:
- filename = self.browse(cr, uid, id, context).store_fname
- try:
- os.unlink(os.path.join(self._get_filestore(cr), filename))
- except:
- pass
- cr.execute('update ir_attachment set store_fname=NULL WHERE id=%s', (id,) )
return True
- #if (not context) or context.get('store_method','fs')=='fs':
- try:
- path = self._get_filestore(cr)
- if not os.path.isdir(path):
- try:
- os.makedirs(path)
- except:
- raise except_orm(_('Permission Denied !'), _('You do not permissions to write on the server side.'))
-
- flag = None
- # This can be improved
- for dirs in os.listdir(path):
- if os.path.isdir(os.path.join(path,dirs)) and len(os.listdir(os.path.join(path,dirs)))<4000:
- flag = dirs
- break
- flag = flag or create_directory(path)
- filename = random_name()
- fname = os.path.join(path, flag, filename)
- fp = file(fname,'wb')
- v = base64.decodestring(value)
- fp.write(v)
- filesize = os.stat(fname).st_size
- cr.execute('update ir_attachment set store_fname=%s,store_method=%s,file_size=%s where id=%s', (os.path.join(flag,filename),'fs',len(v),id))
- return True
- except Exception,e :
- raise except_orm(_('Error!'), str(e))
+ fbro = self.browse(cr,uid,id,context=context)
+ nctx = nodes.get_node_context(cr,uid,context)
+ fnode = nodes.node_file(None,None,nctx,fbro)
+ res = fnode.set_data(cr,base64.decodestring(value),fbro)
+ return res
_columns = {
'user_id': fields.many2one('res.users', 'Owner', select=1),
'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
- 'parent_id': fields.many2one('document.directory', 'Directory', select=1),
+ # the directory id now is mandatory. It can still be computed automatically.
+ 'parent_id': fields.many2one('document.directory', 'Directory', select=1, required=True),
'file_size': fields.integer('File Size', required=True),
'file_type': fields.char('Content Type', size=32),
+ # If ir.attachment contained any data before document is installed, preserve
+ # the data, don't drop the column!
+ 'db_datas': fields.binary('Data',oldname='datas'),
'index_content': fields.text('Indexed Content'),
'write_date': fields.datetime('Date Modified', readonly=True),
'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
'create_date': fields.datetime('Date Created', readonly=True),
'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
'store_method': fields.selection([('db','Database'),('fs','Filesystem'),('link','Link')], "Storing Method"),
- 'datas': fields.function(_data_get,method=True,fnct_inv=_data_set,string='File Content',type="binary"),
+ 'datas': fields.function(_data_get,method=True,fnct_inv=_data_set,string='File Content',type="binary", nodrop=True),
'store_fname': fields.char('Stored Filename', size=200),
'res_model': fields.char('Attached Model', size=64), #res_model
'res_id': fields.integer('Attached ID'), #res_id
@@ -593,10 +93,15 @@ class document_file(osv.osv):
'title': fields.char('Resource Title',size=64),
}
+ def __get_def_directory(self,cr,uid, context = None):
+ dirobj = self.pool.get('document.directory')
+ return dirobj._get_root_directory(cr,uid,context)
+
_defaults = {
'user_id': lambda self,cr,uid,ctx:uid,
'file_size': lambda self,cr,uid,ctx:0,
- 'store_method': lambda *args: 'db'
+ 'store_method': lambda *args: 'db',
+ 'parent_id': __get_def_directory
}
_sql_constraints = [
('filename_uniq', 'unique (name,parent_id,res_id,res_model)', 'The file name must be unique !')
@@ -638,20 +143,11 @@ class document_file(osv.osv):
raise except_orm(_('ValidateError'), _('File name must be unique!'))
result = super(document_file,self).write(cr,uid,ids,vals,context=context)
cr.commit()
- try:
- for f in self.browse(cr, uid, ids, context=context):
- #if 'datas' not in vals:
- # vals['datas']=f.datas
- res = content_index(base64.decodestring(vals['datas']), f.datas_fname, f.file_type or None)
- super(document_file,self).write(cr, uid, ids, {
- 'index_content': res
- })
- cr.commit()
- except:
- pass
return result
- def create(self, cr, uid, vals, context={}):
+ def create(self, cr, uid, vals, context=None):
+ if not context:
+ context = {}
vals['title']=vals['name']
vals['parent_id'] = context.get('parent_id',False) or vals.get('parent_id',False)
if not vals.get('res_id', False) and context.get('default_res_id',False):
@@ -686,200 +182,30 @@ class document_file(osv.osv):
import urllib
datas=base64.encodestring(urllib.urlopen(vals['link']).read())
else:
- datas = vals.get('datas',False)
-
+ datas=vals.get('datas',False)
vals['file_size']= datas and len(datas) or 0
if not self._check_duplication(cr,uid,vals):
raise except_orm(_('ValidateError'), _('File name must be unique!'))
result = super(document_file,self).create(cr, uid, vals, context)
cr.commit()
- try:
- res = content_index(base64.decodestring(datas), vals['datas_fname'], vals.get('content_type', None))
- super(document_file,self).write(cr, uid, [result], {
- 'index_content': res,
- })
- cr.commit()
- except:
- pass
return result
def unlink(self,cr, uid, ids, context={}):
+ stor = self.pool.get('document.storage')
+ unres= []
+ # We have to do the unlink in 2 stages: prepare a list of actual
+ # files to be unlinked, update the db (safer to do first, can be
+ # rolled back) and then unlink the files. The list wouldn't exist
+ # after we discard the objects
+
for f in self.browse(cr, uid, ids, context):
- #if f.store_method=='fs':
- try:
- os.unlink(os.path.join(self._get_filestore(cr), f.store_fname))
- except:
- pass
- return super(document_file, self).unlink(cr, uid, ids, context)
+ # TODO: update the node cache
+ r = stor.prepare_unlink(cr,uid,f.parent_id.storage_id, f)
+ if r:
+ unres.append(r)
+ res = super(document_file, self).unlink(cr, uid, ids, context)
+ stor.do_unlink(cr,uid,unres)
+ return res
+
document_file()
-class document_configuration_wizard(osv.osv_memory):
- _name='document.configuration.wizard'
- _rec_name = 'Auto Directory configuration'
- _columns = {
- 'host': fields.char('Server Address', size=64, help="Put here the server address or IP. " \
- "Keep localhost if you don't know what to write.", required=True),
- 'suggested_host': fields.char('Suggested Server Address', size=64, readonly=True, help="This is the guessed server address"),
- 'port': fields.char('Server Port', size=5, help="Put here the server port. " \
- "Keep 8021 if you don't know what to write.", required=True)
- }
-
- def get_ftp_server_address(self, cr, uid, context=None):
- default_address = config.get('ftp_server_address', None)
- if default_address is None:
- default_address = tools.misc.detect_ip_addr()
-
- return default_address
-
- def get_ftp_server_port(self, cr, uid, context=None):
- return config.get('ftp_server_port', 8021)
-
- def get_suggested_ftp_server_address(self, cr, uid, context=None):
- return tools.misc.detect_ip_addr()
-
- _defaults = {
- 'host': get_ftp_server_address,
- 'suggested_host': get_suggested_ftp_server_address,
- 'port': get_ftp_server_port,
- }
-
- def action_cancel(self,cr,uid,ids,conect=None):
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'ir.actions.configuration.wizard',
- 'type': 'ir.actions.act_window',
- 'target':'new',
- }
-
- def action_config(self, cr, uid, ids, context=None):
- conf = self.browse(cr, uid, ids[0], context)
- obj=self.pool.get('document.directory')
- objid=self.pool.get('ir.model.data')
-
- if self.pool.get('sale.order'):
- id = objid._get_id(cr, uid, 'document', 'dir_sale_order_all')
- id = objid.browse(cr, uid, id, context=context).res_id
- mid = self.pool.get('ir.model').search(cr, uid, [('model','=','sale.order')])
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- 'domain': '[]',
- })
- aid = objid._get_id(cr, uid, 'sale', 'report_sale_order')
- aid = objid.browse(cr, uid, aid, context=context).res_id
-
- self.pool.get('document.directory.content').create(cr, uid, {
- 'name': "Print Order",
- 'suffix': "_print",
- 'report_id': aid,
- 'extension': '.pdf',
- 'include_name': 1,
- 'directory_id': id,
- })
- id = objid._get_id(cr, uid, 'document', 'dir_sale_order_quote')
- id = objid.browse(cr, uid, id, context=context).res_id
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- 'domain': "[('state','=','draft')]",
- })
-
- if self.pool.get('product.product'):
- id = objid._get_id(cr, uid, 'document', 'dir_product')
- id = objid.browse(cr, uid, id, context=context).res_id
- mid = self.pool.get('ir.model').search(cr, uid, [('model','=','product.product')])
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- })
-
- if self.pool.get('stock.location'):
- aid = objid._get_id(cr, uid, 'stock', 'report_product_history')
- aid = objid.browse(cr, uid, aid, context=context).res_id
-
- self.pool.get('document.directory.content').create(cr, uid, {
- 'name': "Product Stock",
- 'suffix': "_stock_forecast",
- 'report_id': aid,
- 'extension': '.pdf',
- 'include_name': 1,
- 'directory_id': id,
- })
-
- if self.pool.get('account.analytic.account'):
- id = objid._get_id(cr, uid, 'document', 'dir_project')
- id = objid.browse(cr, uid, id, context=context).res_id
- mid = self.pool.get('ir.model').search(cr, uid, [('model','=','account.analytic.account')])
- obj.write(cr, uid, [id], {
- 'type':'ressource',
- 'ressource_type_id': mid[0],
- 'domain': '[]',
- 'ressource_tree': 1
- })
-
- aid = objid._get_id(cr, uid, 'document', 'action_document_browse')
- aid = objid.browse(cr, uid, aid, context=context).res_id
- self.pool.get('ir.actions.url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost')+':'+conf.port+'/'})
-
- config['ftp_server_address'] = conf.host
- config['ftp_server_port'] = conf.port
- config.save()
-
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'ir.actions.configuration.wizard',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- }
-
-document_configuration_wizard()
-
-
-class document_configuration_ftpserver_wizard(osv.osv_memory):
- _name='document.configuration.ftp_server.wizard'
- _rec_name = 'Configure FTP server address'
- _columns = {
- 'host': fields.char('Server Address', size=64, help="Put here the server address or IP. " \
- "Keep localhost if you don't know what to write.", required=True),
- 'suggested_host': fields.char('Suggested Server Address', size=64, readonly=True, help="This is the guessed server address"),
- 'port': fields.char('Server Port', size=5, help="Put here the server port. " \
- "Keep 8021 if you don't know what to write.", required=True)
- }
-
- def get_ftp_server_address(self, cr, uid, context=None):
- default_address = tools.misc.detect_ip_addr()
- return config.get('ftp_server_address', default_address)
-
- def get_ftp_server_port(self, cr, uid, context=None):
- return config.get('ftp_server_port', '8021')
-
- def get_suggested_ftp_server_address(self, cr, uid, context=None):
- return tools.misc.detect_ip_addr()
-
- _defaults = {
- 'host': get_ftp_server_address,
- 'suggested_host': get_suggested_ftp_server_address,
- 'port': get_ftp_server_port,
- }
-
- def action_cancel(self,cr,uid,ids,conect=None):
- return {}
-
- def action_config(self, cr, uid, ids, context=None):
- conf = self.browse(cr, uid, ids[0], context)
- obj = self.pool.get('ir.model.data')
-
- aid = obj._get_id(cr, uid, 'document', 'action_document_browse')
- aid = obj.browse(cr, uid, aid, context=context).res_id
- self.pool.get('ir.actions.url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost')+':'+conf.port+'/'})
-
- config['ftp_server_address'] = conf.host
- config['ftp_server_port'] = conf.port
- config.save()
-
- return {}
-
-document_configuration_ftpserver_wizard()
-
diff --git a/addons/document/document_data.xml b/addons/document/document_data.xml
index 511de005b6f..77c80b078d1 100644
--- a/addons/document/document_data.xml
+++ b/addons/document/document_data.xml
@@ -1,10 +1,112 @@
-
+
.pdf
PDF Report
+ application/pdf
+
+
+
+ Default File storage
+
+
+
+
+ DB storage
+
+
+
+
+
+
+ Documents
+
+
+ 0
+
+
+
+ My Folder
+
+
+
+ 0
+
+
+
+
+ Partners by Category
+
+ ressource
+ 1
+
+ 0
+
+
+
+
+
+
+ Partners
+ ressource
+ [('category_id','in',[active_id])]
+
+
+
+ 0
+
+
+
+
+ Personnal Folders
+
+ ressource
+
+
+ 0
+
+
+
+
+ Products
+
+
+ 0
+
+
+
+
+ Sales Order
+
+
+ 0
+
+
+
+
+ All Sales Order
+
+
+ 0
+
+
+
+
+ Quotations
+
+
+ 0
+
+
+
+
+ Projects
+
+
+ 0
+
diff --git a/addons/document/document_demo.xml b/addons/document/document_demo.xml
index 95910e6031b..1c757a73909 100644
--- a/addons/document/document_demo.xml
+++ b/addons/document/document_demo.xml
@@ -2,90 +2,6 @@
-
- Documents
-
- 0
-
-
-
- My Folder
-
-
- 0
-
-
-
-
- Partners by Category
-
- ressource
- 1
- 0
-
-
-
-
-
-
- Partners
- ressource
- [('category_id','in',[active_id])]
-
-
-
- 0
-
-
-
-
- Personnal Folders
-
- ressource
-
- 0
-
-
-
-
- Products
-
-
- 0
-
-
-
-
- Sales Order
-
-
- 0
-
-
-
-
- All Sales Order
-
-
- 0
-
-
-
-
- Quotations
-
-
- 0
-
-
-
-
- Projects
-
-
- 0
-
-
diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py
new file mode 100644
index 00000000000..133927f9664
--- /dev/null
+++ b/addons/document/document_directory.py
@@ -0,0 +1,312 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import base64
+
+from osv import osv, fields
+from osv.orm import except_orm
+import urlparse
+
+import os
+import nodes
+
+class document_directory(osv.osv):
+ _name = 'document.directory'
+ _description = 'Document directory'
+ _columns = {
+ 'name': fields.char('Name', size=64, required=True, select=1),
+ 'write_date': fields.datetime('Date Modified', readonly=True),
+ 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
+ 'create_date': fields.datetime('Date Created', readonly=True),
+ 'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
+ 'file_type': fields.char('Content Type', size=32),
+ 'domain': fields.char('Domain', size=128, help="Use a domain if you want to apply an automatic filter on visible resources."),
+ 'user_id': fields.many2one('res.users', 'Owner'),
+ 'storage_id': fields.many2one('document.storage', 'Storage'),
+ 'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
+ 'parent_id': fields.many2one('document.directory', 'Parent Item'),
+ 'child_ids': fields.one2many('document.directory', 'parent_id', 'Children'),
+ 'file_ids': fields.one2many('ir.attachment', 'parent_id', 'Files'),
+ 'content_ids': fields.one2many('document.directory.content', 'directory_id', 'Virtual Files'),
+ 'type': fields.selection([('directory','Static Directory'),('ressource','Other Resources')], 'Type', required=True),
+ 'ressource_type_id': fields.many2one('ir.model', 'Directories Mapped to Objects',
+ help="Select an object here and Open ERP will create a mapping for each of these " \
+ "objects, using the given domain, when browsing through FTP."),
+ 'resource_field': fields.char('Name field',size=32,help='Field to be used as name on resource directories. If empty, the "name" will be used.'),
+ 'ressource_parent_type_id': fields.many2one('ir.model', 'Parent Model',
+ help="If you put an object here, this directory template will appear bellow all of these objects. " \
+ "Don't put a parent directory if you select a parent model."),
+ 'ressource_id': fields.integer('Resource ID'),
+ 'ressource_tree': fields.boolean('Tree Structure',
+ help="Check this if you want to use the same tree structure as the object selected in the system."),
+ 'dctx_ids': fields.one2many('document.directory.dctx', 'dir_id', 'Context fields'),
+ }
+ def _get_root_directory(self, cr,uid, context=None):
+ objid=self.pool.get('ir.model.data')
+ try:
+ mid = objid._get_id(cr, uid, 'document', 'dir_root')
+ if not mid:
+ return None
+ except Exception, e:
+ import netsvc
+ logger = netsvc.Logger()
+ logger.notifyChannel("document", netsvc.LOG_WARNING, 'Cannot set directory root:'+ str(e))
+ return None
+ return objid.browse(cr, uid, mid, context=context).res_id
+
+ def _get_def_storage(self,cr,uid,context=None):
+ if context and context.has_key('default_parent_id'):
+ # Use the same storage as the parent..
+ diro = self.browse(cr,uid,context['default_parent_id'])
+ if diro.storage_id:
+ return diro.storage_id.id
+ objid=self.pool.get('ir.model.data')
+ try:
+ mid = objid._get_id(cr, uid, 'document', 'storage_default')
+ return objid.browse(cr, uid, mid, context=context).res_id
+ except Exception:
+ return None
+
+ _defaults = {
+ 'user_id': lambda self,cr,uid,ctx: uid,
+ 'domain': lambda self,cr,uid,ctx: '[]',
+ 'type': lambda *args: 'directory',
+ 'ressource_id': lambda *a: 0,
+ 'parent_id': _get_root_directory,
+ 'storage_id': _get_def_storage,
+ }
+ _sql_constraints = [
+ ('dirname_uniq', 'unique (name,parent_id,ressource_id,ressource_parent_type_id)', 'The directory name must be unique !'),
+ ('no_selfparent', 'check(parent_id <> id)', 'Directory cannot be parent of itself!')
+ ]
+
+ def ol_get_resource_path(self,cr,uid,dir_id,res_model,res_id):
+ # this method will be used in process module
+ # to be need test and Improvement if resource dir has parent resource (link resource)
+ path=[]
+ def _parent(dir_id,path):
+ parent=self.browse(cr,uid,dir_id)
+ if parent.parent_id and not parent.ressource_parent_type_id:
+ _parent(parent.parent_id.id,path)
+ path.append(parent.name)
+ else:
+ path.append(parent.name)
+ return path
+
+ directory=self.browse(cr,uid,dir_id)
+ model_ids=self.pool.get('ir.model').search(cr,uid,[('model','=',res_model)])
+ if directory:
+ _parent(dir_id,path)
+ path.append(self.pool.get(directory.ressource_type_id.model).browse(cr,uid,res_id).name)
+ #user=self.pool.get('res.users').browse(cr,uid,uid)
+ #return "ftp://%s:%s@localhost:%s/%s/%s"%(user.login,user.password,config.get('ftp_server_port',8021),cr.dbname,'/'.join(path))
+ # No way we will return the password!
+ return "ftp://user:pass@host:port/test/this"
+ return False
+
+ def _check_recursion(self, cr, uid, ids):
+ level = 100
+ while len(ids):
+ cr.execute('select distinct parent_id from document_directory where id in ('+','.join(map(str,ids))+')')
+ ids = filter(None, map(lambda x:x[0], cr.fetchall()))
+ if not level:
+ return False
+ level -= 1
+ return True
+
+ _constraints = [
+ (_check_recursion, 'Error! You can not create recursive Directories.', ['parent_id'])
+ ]
+ def __init__(self, *args, **kwargs):
+ res = super(document_directory, self).__init__(*args, **kwargs)
+ #self._cache = {}
+
+ def onchange_content_id(self, cr, uid, ids, ressource_type_id):
+ return {}
+
+ """
+ PRE:
+ uri: of the form "Sales Order/SO001"
+ PORT:
+ uri
+ object: the object.directory or object.directory.content
+ object2: the other object linked (if object.directory.content)
+ """
+ def get_object(self, cr, uid, uri, context=None):
+ """ Return a node object for the given uri.
+ This fn merely passes the call to node_context
+ """
+ if not context:
+ context = {}
+ lang = context.get('lang',False)
+ if not lang:
+ user = self.pool.get('res.users').browse(cr, uid, uid)
+ lang = user.context_lang
+ context['lang'] = lang
+
+ try: #just instrumentation
+ return nodes.get_node_context(cr, uid, context).get_uri(cr,uri)
+ except Exception,e:
+ print "exception: ",e
+ raise
+
+
+ def _locate_child(self, cr,uid, root_id, uri,nparent, ncontext):
+ """ try to locate the node in uri,
+ Return a tuple (node_dir, remaining_path)
+ """
+ did = root_id
+ duri = uri
+ path = []
+ context = ncontext.context
+ while len(duri):
+ nid = self.search(cr,uid,[('parent_id','=',did),('name','=',duri[0]),('type','=','directory')], context=context)
+ if not nid:
+ break
+ if len(nid)>1:
+ print "Duplicate dir? p= %d, n=\"%s\"" %(did,duri[0])
+ path.append(duri[0])
+ duri = duri[1:]
+ did = nid[0]
+
+ return (nodes.node_dir(path, nparent,ncontext,self.browse(cr,uid,did, context)), duri)
+
+
+ nid = self.search(cr,uid,[('parent_id','=',did),('name','=',duri[0]),('type','=','ressource')], context=context)
+ if nid:
+ if len(nid)>1:
+ print "Duplicate dir? p= %d, n=\"%s\"" %(did,duri[0])
+ path.append(duri[0])
+ duri = duri[1:]
+ did = nid[0]
+ return nodes.node_res_dir(path, nparent,ncontext,self.browse(cr,uid,did, context))
+
+ # Here, we must find the appropriate non-dir child..
+ # Chech for files:
+ fil_obj = self.pool.get('ir.attachment')
+ nid = fil_obj.search(cr,uid,[('parent_id','=',did),('name','=',duri[0])],context=context)
+ if nid:
+ if len(duri)>1:
+ # cannot treat child as a dir
+ return None
+ if len(nid)>1:
+ print "Duplicate file?",did,duri[0]
+ path.append(duri[0])
+ return nodes.node_file(path,nparent,ncontext,fil_obj.browse(cr,uid,nid[0],context))
+
+ print "nothing found:",did, duri
+ #still, nothing found
+ return None
+
+ def old_code():
+ if not uri:
+ return node_database(cr, uid, context=context)
+ turi = tuple(uri)
+ node = node_class(cr, uid, '/', False, context=context, type='database')
+ for path in uri[:]:
+ if path:
+ node = node.child(path)
+ if not node:
+ return False
+ oo = node.object and (node.object._name, node.object.id) or False
+ oo2 = node.object2 and (node.object2._name, node.object2.id) or False
+ return node
+
+ def ol_get_childs(self, cr, uid, uri, context={}):
+ node = self.get_object(cr, uid, uri, context)
+ if uri:
+ children = node.children()
+ else:
+ children= [node]
+ result = map(lambda node: node.path_get(), children)
+ return result
+
+ def copy(self, cr, uid, id, default=None, context=None):
+ if not default:
+ default ={}
+ name = self.read(cr, uid, [id])[0]['name']
+ default.update({'name': name+ " (copy)"})
+ return super(document_directory,self).copy(cr,uid,id,default,context)
+
+ def _check_duplication(self, cr, uid,vals,ids=[],op='create'):
+ name=vals.get('name',False)
+ parent_id=vals.get('parent_id',False)
+ ressource_parent_type_id=vals.get('ressource_parent_type_id',False)
+ ressource_id=vals.get('ressource_id',0)
+ if op=='write':
+ for directory in self.browse(cr,uid,ids):
+ if not name:
+ name=directory.name
+ if not parent_id:
+ parent_id=directory.parent_id and directory.parent_id.id or False
+ if not ressource_parent_type_id:
+ ressource_parent_type_id=directory.ressource_parent_type_id and directory.ressource_parent_type_id.id or False
+ if not ressource_id:
+ ressource_id=directory.ressource_id and directory.ressource_id or 0
+ res=self.search(cr,uid,[('id','<>',directory.id),('name','=',name),('parent_id','=',parent_id),('ressource_parent_type_id','=',ressource_parent_type_id),('ressource_id','=',ressource_id)])
+ if len(res):
+ return False
+ if op=='create':
+ res=self.search(cr,uid,[('name','=',name),('parent_id','=',parent_id),('ressource_parent_type_id','=',ressource_parent_type_id),('ressource_id','=',ressource_id)])
+ if len(res):
+ return False
+ return True
+ def write(self, cr, uid, ids, vals, context=None):
+ if not self._check_duplication(cr,uid,vals,ids,op='write'):
+ raise osv.except_osv(_('ValidateError'), _('Directory name must be unique!'))
+ return super(document_directory,self).write(cr,uid,ids,vals,context=context)
+
+ def create(self, cr, uid, vals, context=None):
+ if not self._check_duplication(cr,uid,vals):
+ raise osv.except_osv(_('ValidateError'), _('Directory name must be unique!'))
+ if vals.get('name',False) and (vals.get('name').find('/')+1 or vals.get('name').find('@')+1 or vals.get('name').find('$')+1 or vals.get('name').find('#')+1) :
+ raise osv.except_osv(_('ValidateError'), _('Directory name contains special characters!'))
+ return super(document_directory,self).create(cr, uid, vals, context)
+
+document_directory()
+
+class document_directory_dctx(osv.osv):
+ """ In order to evaluate dynamic folders, child items could have a limiting
+ domain expression. For that, their parents will export a context where useful
+ information will be passed on.
+ If you define sth like "s_id" = "this.id" at a folder iterating over sales, its
+ children could have a domain like [('sale_id', = ,dctx_s_id )]
+ This system should be used recursively, that is, parent dynamic context will be
+ appended to all children down the tree.
+ """
+ _name = 'document.directory.dctx'
+ _description = 'Directory dynamic context'
+ _columns = {
+ 'dir_id': fields.many2one('document.directory', 'Directory', required=True),
+ 'field': fields.char('Field', size=20, required=True, select=1, help="The name of the field. Note that the prefix \"dctx_\" will be prepended to what is typed here."),
+ 'expr': fields.char('Expression', size=64, required=True, help="A python expression used to evaluate the field.\n" + \
+ "You can use 'dir_id' for current dir, 'res_id', 'res_model' as a reference to the current record, in dynamic folders"),
+ }
+
+document_directory_dctx()
+
+
+class document_directory_node(osv.osv):
+ _inherit = 'process.node'
+ _columns = {
+ 'directory_id': fields.many2one('document.directory', 'Document directory', ondelete="set null"),
+ }
+document_directory_node()
diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py
new file mode 100644
index 00000000000..d4096138800
--- /dev/null
+++ b/addons/document/document_storage.py
@@ -0,0 +1,281 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+#
+# Copyright (C) P. Christeas, 2009, all rights reserved
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from osv import osv, fields
+import os
+import tools
+import base64
+from tools.misc import ustr
+
+from osv.orm import except_orm
+
+import random
+import string
+import netsvc
+from content_index import cntIndex
+
+
+""" The algorithm of data storage
+
+We have to consider 3 cases of data /retrieval/:
+ Given (context,path) we need to access the file (aka. node).
+ given (directory, context), we need one of its children (for listings, views)
+ given (ir.attachment, context), we needs its data and metadata (node).
+
+For data /storage/ we have the cases:
+ Have (ir.attachment, context), we modify the file (save, update, rename etc).
+ Have (directory, context), we create a file.
+ Have (path, context), we create or modify a file.
+
+Note that in all above cases, we don't explicitly choose the storage media,
+but always require a context to be present.
+
+Note that a node will not always have a corresponding ir.attachment. Dynamic
+nodes, for once, won't. Their metadata will be computed by the parent storage
+media + directory.
+
+The algorithm says that in any of the above cases, our first goal is to locate
+the node for any combination of search criteria. It would be wise NOT to
+represent each node in the path (like node[/] + node[/dir1] + node[/dir1/dir2])
+but directly jump to the end node (like node[/dir1/dir2]) whenever possible.
+
+We also contain all the parenting loop code in one function. This is intentional,
+because one day this will be optimized in the db (Pg 8.4).
+
+
+"""
+
+def random_name():
+ random.seed()
+ d = [random.choice(string.ascii_letters) for x in xrange(10) ]
+ name = "".join(d)
+ return name
+
+INVALID_CHARS={'*':str(hash('*')), '|':str(hash('|')) , "\\":str(hash("\\")), '/':'__', ':':str(hash(':')), '"':str(hash('"')), '<':str(hash('<')) , '>':str(hash('>')) , '?':str(hash('?'))}
+
+
+def create_directory(path):
+ dir_name = random_name()
+ path = os.path.join(path,dir_name)
+ os.makedirs(path)
+ return dir_name
+
+
+class document_storage(osv.osv):
+ """ The primary object for data storage.
+ Each instance of this object is a storage media, in which our application
+ can store contents. The object here controls the behaviour of the storage
+ media.
+ The referring document.directory-ies will control the placement of data
+ into the storage.
+
+ It is a bad idea to have multiple document.storage objects pointing to
+ the same tree of filesystem storage.
+ """
+ _name = 'document.storage'
+ _description = 'Document storage media'
+ _columns = {
+ 'name': fields.char('Name', size=64, required=True, select=1),
+ 'write_date': fields.datetime('Date Modified', readonly=True),
+ 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
+ 'create_date': fields.datetime('Date Created', readonly=True),
+ 'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
+ 'user_id': fields.many2one('res.users', 'Owner'),
+ 'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
+ 'dir_ids': fields.one2many('document.directory', 'parent_id', 'Directories'),
+ 'type': fields.selection([('db','Database'),('filestore','Internal File storage'),
+ ('realstore','External file storage'), ('virtual','Virtual storage')], 'Type', required=True),
+ 'path': fields.char('Path',size=250,select=1,help="For file storage, the root path of the storage"),
+ 'online': fields.boolean('Online',help="If not checked, media is currently offline and its contents not available", required=True),
+ 'readonly': fields.boolean('Read Only', help="If set, media is for reading only"),
+ }
+
+ def _get_rootpath(self,cr,uid,context=None):
+ from tools import config
+ return os.path.join(tools.config['root_path'], 'filestore', cr.dbname)
+
+ _defaults = {
+ 'user_id': lambda self,cr,uid,ctx: uid,
+ 'online': lambda *args: True,
+ 'readonly': lambda *args: False,
+ # Note: the defaults below should only be used ONCE for the default
+ # storage media. All other times, we should create different paths at least.
+ 'type': lambda *args: 'filestore',
+ 'path': _get_rootpath,
+ }
+ _sql_constraints = [
+ # SQL note: a path = NULL doesn't have to be unique.
+ ('path_uniq', 'UNIQUE(type,path)', "The storage path must be unique!")
+ ]
+
+ def get_data(self, cr,uid, id, file_node,context = None, fil_obj = None):
+ """ retrieve the contents of some file_node having storage_id = id
+ optionally, fil_obj could point to the browse object of the file
+ (ir.attachment)
+ """
+ if not context:
+ context = {}
+ boo = self.browse(cr,uid,id,context)
+ if fil_obj:
+ ira = fil_obj
+ else:
+ ira = self.pool.get('ir.attachment').browse(cr,uid, file_node.file_id, context=context)
+ return self.__get_data_3(cr,uid,boo, ira, context)
+
+ def __get_data_3(self,cr,uid, boo, ira, context):
+ if not boo.online:
+ raise RuntimeError('media offline')
+ if boo.type == 'filestore':
+ if not ira.store_fname:
+ # On a migrated db, some files may have the wrong storage type
+ # try to fix their directory.
+ if ira.file_size:
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"ir.attachment #%d does not have a filename, but is at filestore, fix it!" %ira.id)
+ return None
+ fpath = os.path.join(boo.path,ira.store_fname)
+ print "Trying to read \"%s\".."% fpath
+ return file(fpath,'rb').read()
+ elif boo.type == 'db':
+ # TODO: we need a better api for large files
+ if ira.db_datas:
+ out=base64.decodestring(ira.db_datas)
+ else:
+ out=''
+ return out
+ elif boo.type == 'realstore':
+ # fpath = os.path.join(boo.path,
+ return None
+ else:
+ raise TypeError("No %s storage" % boo.type)
+
+ def set_data(self, cr,uid, id, file_node, data, context = None, fil_obj = None):
+ """ store the data.
+ This function MUST be used from an ir.attachment. It wouldn't make sense
+ to store things persistently for other types (dynamic).
+ """
+ if not context:
+ context = {}
+ boo = self.browse(cr,uid,id,context)
+ logger = netsvc.Logger()
+ if fil_obj:
+ ira = fil_obj
+ else:
+ ira = self.pool.get('ir.attachment').browse(cr,uid, file_node.file_id, context=context)
+
+ if not boo.online:
+ raise RuntimeError('media offline')
+ logger.notifyChannel('document',netsvc.LOG_DEBUG,"Store data for ir.attachment #%d" %ira.id)
+ store_fname = None
+ fname = None
+ if boo.type == 'filestore':
+ path = boo.path
+ try:
+ flag = None
+ # This can be improved
+ for dirs in os.listdir(path):
+ if os.path.isdir(os.path.join(path,dirs)) and len(os.listdir(os.path.join(path,dirs)))<4000:
+ flag = dirs
+ break
+ flag = flag or create_directory(path)
+ filename = random_name()
+ fname = os.path.join(path, flag, filename)
+ fp = file(fname,'wb')
+ fp.write(data)
+ fp.close()
+ logger.notifyChannel('document',netsvc.LOG_DEBUG,"Saved data to %s" % fname)
+ filesize = len(data) # os.stat(fname).st_size
+ store_fname = os.path.join(flag,filename)
+
+ # TODO Here, an old file would be left hanging.
+
+ except Exception,e :
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" %str(e))
+ raise except_orm(_('Error!'), str(e))
+ elif boo.type == 'db':
+ filesize = len(data)
+ # will that work for huge data? TODO
+ out=base64.encodestring(data)
+ cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s',
+ ( out, file_node.file_id ))
+ else:
+ raise TypeError("No %s storage" % boo.type)
+
+ # 2nd phase: store the metadata
+ try:
+ icont = ''
+ mime = ira.file_type
+ try:
+ mime,icont = cntIndex.doIndex(data, ira.datas_fname,
+ ira.file_type or None,fname)
+ except Exception,e:
+ logger.notifyChannel('document', netsvc.LOG_DEBUG, 'Cannot index file: %s' % str(e))
+ pass
+
+ # a hack: /assume/ that the calling write operation will not try
+ # to write the fname and size, and update them in the db concurrently.
+ # We cannot use a write() here, because we are already in one.
+ cr.execute('UPDATE ir_attachment SET store_fname = %s, file_size = %s, index_content = %s, file_type = %s WHERE id = %s',
+ (store_fname, filesize, ustr(icont), mime, file_node.file_id ))
+ file_node.content_length = filesize
+ file_node.content_type = mime
+ return True
+ except Exception,e :
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" %str(e))
+ # should we really rollback once we have written the actual data?
+ # at the db case (only), that rollback would be safe
+ raise except_orm(_('Error at doc write!'), str(e))
+
+ def prepare_unlink(self,cr,uid,storage_bo, fil_bo):
+ """ Before we unlink a file (fil_boo), prepare the list of real
+ files that have to be removed, too. """
+
+ if not storage_bo.online:
+ raise RuntimeError('media offline')
+
+ if storage_bo.type == 'filestore':
+ fname = fil_bo.store_fname
+ if not fname:
+ return None
+ path = storage_bo.path
+ return ( storage_bo.id, 'file', os.path.join(path,fname))
+ elif storage_bo.type == 'db':
+ return None
+ else:
+ raise TypeError("No %s storage" % boo.type)
+
+ def do_unlink(self, cr,uid,unres):
+ for id, ktype, fname in unres:
+ if ktype == 'file':
+ try:
+ os.unlink(fname)
+ except Exception,e:
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Could not remove file %s, please remove manually." % fname)
+ else:
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Unknown unlink key %s" % ktype)
+
+ return True
+
+
+document_storage()
+
+
+#eof
diff --git a/addons/document/document_view.xml b/addons/document/document_view.xml
index 6e570bb406a..babc5af33b3 100644
--- a/addons/document/document_view.xml
+++ b/addons/document/document_view.xml
@@ -3,6 +3,48 @@
+
+ document.storage
+ document.storage
+ form
+
+
+
+
+
+
+ document.storage
+ document.storage
+ tree
+
+
+
+
+
+
+
+
+
+
+
+ ir.actions.act_window
+ document.storage
+ form
+ tree,form
+
+
+
document.directory
document.directory
@@ -12,6 +54,7 @@
+
@@ -20,14 +63,17 @@
+
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
@@ -151,7 +210,7 @@
-
+
@@ -243,86 +302,45 @@
-
-
- Auto Configure Directory
- document.configuration.wizard
- form
-
-
-
-
+
+ Auto Configure Directory
+ document.configuration.wizard
+ form
+
+
+
+
-
- Auto Configure Directory
- ir.actions.act_window
- document.configuration.wizard
- form
- form
- new
-
+
+ Auto Configure Directory
+ ir.actions.act_window
+ document.configuration.wizard
+ form
+ form
+ new
+
-
- Auto Configure Directory
- This wizard will configure the URL of the server of the document management system. These ftp server address and port will be stored in the configuration file.
-
-
+
+ Auto Configure Directory
+ This wizard will configure the URL of the server of the document management system.
+
+
-
-
-
- Configure FTP server address
- document.configuration.ftp_server.wizard
- form
-
-
-
-
-
-
- Configure FTP server address
- ir.actions.act_window
- document.configuration.ftp_server.wizard
- form
- form
- new
-
-
-
+
diff --git a/addons/document/ftpserver/__init__.py b/addons/document/ftpserver/__init__.py
index 47615a442a6..3dc1f1b1202 100644
--- a/addons/document/ftpserver/__init__.py
+++ b/addons/document/ftpserver/__init__.py
@@ -28,7 +28,7 @@ import netsvc
from tools import config
from tools.misc import detect_ip_addr
HOST = ''
-PORT = int(config.get('ftp_server_port', 8021))
+PORT = 8021
PASSIVE_PORTS = None
pps = config.get('ftp_server_passive_ports', '').split(':')
if len(pps) == 2:
@@ -53,8 +53,7 @@ class ftp_server(threading.Thread):
ftpserver.logerror = lambda msg: self.log(netsvc.LOG_ERROR, msg)
HOST = config.get('ftp_server_address', detect_ip_addr())
- PORT = int(config.get('ftp_server_port', '8021'))
-
+ PORT = int(config.get('ftp_server_port', '8021'))
address = (HOST, PORT)
ftpd = ftpserver.FTPServer(address, ftpserver.FTPHandler)
ftpd.serve_forever()
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py
index 21b38d7dc4f..d795110d4ea 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document/ftpserver/abstracted_fs.py
@@ -1,24 +1,4 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# 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 .
-#
-##############################################################################
-
+# -*- encoding: utf-8 -*-
import os
import time
from tarfile import filemode
@@ -141,8 +121,8 @@ class abstracted_fs:
# Ok
def db_list(self):
#return pooler.pool_dic.keys()
- s = netsvc.LocalService('db')
- result = s.list()
+ s = netsvc.ExportService.getService('db')
+ result = s.exp_list()
self.db_name_list = []
for db_name in result:
db, cr = None, None
@@ -222,13 +202,18 @@ class abstracted_fs:
# Ok
def fs2ftp(self, node):
- res='/'
+ res = '/'
if node:
- res=os.path.normpath(node.path)
+ path = node.path
+ print '**********', path
+ if isinstance(path,list):
+ path = '/'.join(path)
+ res = os.path.normpath(path)
res = res.replace("\\", "/")
while res[:2] == '//':
res = res[1:]
- res='/' + node.cr.dbname + '/' + _to_decode(res)
+ if len(node.path):
+ res = '/' + node.path[0] + '/' + _to_decode(res)
#res = node and ('/' + node.cr.dbname + '/' + _to_decode(self.ftpnorm(node.path))) or '/'
return res
diff --git a/addons/document/ftpserver/authorizer.py b/addons/document/ftpserver/authorizer.py
index afa36680009..5a64ca8f7a0 100644
--- a/addons/document/ftpserver/authorizer.py
+++ b/addons/document/ftpserver/authorizer.py
@@ -1,26 +1,4 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# 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 .
-#
-##############################################################################
-
-import pooler
-from service import security
+# -*- encoding: utf-8 -*-
class authorizer:
read_perms = "elr"
@@ -69,7 +47,7 @@ class authorizer:
paths = path.split('/')
if not len(paths)>2:
return True
- db_name = paths[1]
+ db_name = paths[1]
db,pool = pooler.get_db_and_pool(db_name)
res = security.login(db_name, username, self.password)
return bool(res)
diff --git a/addons/document/ftpserver/ftpserver.py b/addons/document/ftpserver/ftpserver.py
index 3414fa78bbd..13c44287303 100644
--- a/addons/document/ftpserver/ftpserver.py
+++ b/addons/document/ftpserver/ftpserver.py
@@ -1,10 +1,12 @@
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
# ftpserver.py
#
# pyftpdlib is released under the MIT license, reproduced below:
# ======================================================================
# Copyright (C) 2007 Giampaolo Rodola'
# Hacked by Fabien Pinckaers (C) 2008
+#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
@@ -56,9 +58,6 @@ the backend functionality for the FTPd:
providing a high level, cross-platform interface compatible
with both Windows and UNIX style filesystems.
- [CallLater] - calls a function at a later time whithin the polling
- loop asynchronously.
-
[AuthorizerError] - base class for authorizers exceptions.
@@ -117,11 +116,11 @@ import traceback
import errno
import time
import glob
+import fnmatch
import tempfile
import warnings
import random
import stat
-import heapq
from tarfile import filemode
try:
@@ -131,80 +130,67 @@ except ImportError:
pwd = grp = None
+LOG_ACTIVE = True
+
__all__ = ['proto_cmds', 'Error', 'log', 'logline', 'logerror', 'DummyAuthorizer',
- 'AuthorizerError', 'FTPHandler', 'FTPServer', 'PassiveDTP',
- 'ActiveDTP', 'DTPHandler', 'FileProducer', 'BufferedIteratorProducer',
- 'AbstractedFS', 'CallLater']
+ 'FTPHandler', 'FTPServer', 'PassiveDTP', 'ActiveDTP', 'DTPHandler',
+ 'FileProducer', 'IteratorProducer', 'BufferedIteratorProducer',
+ 'AbstractedFS',]
__pname__ = 'Python FTP server library (pyftpdlib)'
-__ver__ = '0.5.1'
-__date__ = '2009-01-21'
+__ver__ = '0.4.0'
+__date__ = '2008-05-16'
__author__ = "Giampaolo Rodola' "
__web__ = 'http://code.google.com/p/pyftpdlib/'
proto_cmds = {
- # cmd : (perm, auth, arg, path, help)
- 'ABOR': (None, True, False, False, 'Syntax: ABOR (abort transfer).'),
- 'ALLO': (None, True, True, False, 'Syntax: ALLO bytes (noop; allocate storage).'),
- 'APPE': ('a', True, True, True, 'Syntax: APPE file-name (append data to an existent file).'),
- 'CDUP': ('e', True, False, True, 'Syntax: CDUP (go to parent directory).'),
- 'CWD' : ('e', True, None, True, 'Syntax: CWD [ dir-name] (change current working directory).'),
- 'DELE': ('d', True, True, True, 'Syntax: DELE file-name (delete file).'),
- 'EPRT': (None, True, True, False, 'Syntax: EPRT |proto|ip|port| (set server in extended active mode).'),
- 'EPSV': (None, True, None, False, 'Syntax: EPSV [ proto/"ALL"] (set server in extended passive mode).'),
- 'FEAT': (None, False, False, False, 'Syntax: FEAT (list all new features supported).'),
- 'HELP': (None, False, None, False, 'Syntax: HELP [ cmd] (show help).'),
- 'LIST': ('l', True, None, True, 'Syntax: LIST [ path-name] (list files).'),
- 'MDTM': (None, True, True, True, 'Syntax: MDTM [ file-name] (get last modification time).'),
- 'MLSD': ('l', True, None, True, 'Syntax: MLSD [ dir-name] (list files in a machine-processable form)'),
- 'MLST': (None, True, None, True, 'Syntax: MLST [ path-name] (show a path in a machine-processable form)'),
- 'MODE': (None, True, True, False, 'Syntax: MODE mode (noop; set data transfer mode).'),
- 'MKD' : ('m', True, True, True, 'Syntax: MDK dir-name (create directory).'),
- 'NLST': ('l', True, None, True, 'Syntax: NLST [ path-name] (list files in a compact form).'),
- 'NOOP': (None, False, False, False, 'Syntax: NOOP (just do nothing).'),
- 'OPTS': (None, True, True, False, 'Syntax: OPTS ftp-command [ option] (specify options for FTP commands)'),
- 'PASS': (None, False, True, False, 'Syntax: PASS user-name (set user password).'),
- 'PASV': (None, True, False, False, 'Syntax: PASV (set server in passive mode).'),
- 'PORT': (None, True, True, False, 'Syntax: PORT h1,h2,h3,h4,p1,p2 (set server in active mode).'),
- 'PWD' : (None, True, False, False, 'Syntax: PWD (get current working directory).'),
- 'QUIT': (None, False, False, False, 'Syntax: QUIT (quit current session).'),
- 'REIN': (None, True, False, False, 'Syntax: REIN (reinitialize / flush account).'),
- 'REST': (None, True, True, False, 'Syntax: REST marker (restart file position).'),
- 'RETR': ('r', True, True, True, 'Syntax: RETR file-name (retrieve a file).'),
- 'RMD' : ('d', True, True, True, 'Syntax: RMD dir-name (remove directory).'),
- 'RNFR': ('f', True, True, True, 'Syntax: RNFR file-name (file renaming (source name)).'),
- 'RNTO': (None, True, True, True, 'Syntax: RNTO file-name (file renaming (destination name)).'),
- 'SITE': (None, False, True, False, 'Syntax: SITE site-command (execute the specified SITE command).'),
- 'SITE HELP' : (None, False, None, False, 'Syntax: SITE HELP [ site-command] (show SITE command help).'),
- 'SIZE': (None, True, True, True, 'Syntax: HELP file-name (get file size).'),
- 'STAT': ('l', False, None, True, 'Syntax: STAT [ path name] (status information [list files]).'),
- 'STOR': ('w', True, True, True, 'Syntax: STOR file-name (store a file).'),
- 'STOU': ('w', True, None, True, 'Syntax: STOU [ file-name] (store a file with a unique name).'),
- 'STRU': (None, True, True, False, 'Syntax: STRU type (noop; set file structure).'),
- 'SYST': (None, False, False, False, 'Syntax: SYST (get operating system type).'),
- 'TYPE': (None, True, True, False, 'Syntax: TYPE [A | I] (set transfer type).'),
- 'USER': (None, False, True, False, 'Syntax: USER user-name (set username).'),
- 'XCUP': ('e', True, False, True, 'Syntax: XCUP (obsolete; go to parent directory).'),
- 'XCWD': ('e', True, None, True, 'Syntax: XCWD [ dir-name] (obsolete; change current directory).'),
- 'XMKD': ('m', True, True, True, 'Syntax: XMDK dir-name (obsolete; create directory).'),
- 'XPWD': (None, True, False, False, 'Syntax: XPWD (obsolete; get current dir).'),
- 'XRMD': ('d', True, True, True, 'Syntax: XRMD dir-name (obsolete; remove directory).'),
+ 'ABOR': 'Syntax: ABOR (abort transfer).',
+ 'ALLO': 'Syntax: ALLO bytes (obsolete; allocate storage).',
+ 'APPE': 'Syntax: APPE file-name (append data to an existent file).',
+ 'CDUP': 'Syntax: CDUP (go to parent directory).',
+ 'CWD' : 'Syntax: CWD dir-name (change current working directory).',
+ 'DELE': 'Syntax: DELE file-name (delete file).',
+ 'EPRT': 'Syntax: EPRT |proto|ip|port| (set server in extended active mode).',
+ 'EPSV': 'Syntax: EPSV [ proto/"ALL"] (set server in extended passive mode).',
+ 'FEAT': 'Syntax: FEAT (list all new features supported).',
+ 'HELP': 'Syntax: HELP [ cmd] (show help).',
+ 'LIST': 'Syntax: LIST [ path-name] (list files).',
+ 'MDTM': 'Syntax: MDTM file-name (get last modification time).',
+ 'MLSD': 'Syntax: MLSD [ dir-name] (list files in a machine-processable form)',
+ 'MLST': 'Syntax: MLST [ path-name] (show a path in a machine-processable form)',
+ 'MODE': 'Syntax: MODE mode (obsolete; set data transfer mode).',
+ 'MKD' : 'Syntax: MDK dir-name (create directory).',
+ 'NLST': 'Syntax: NLST [ path-name] (list files in a compact form).',
+ 'NOOP': 'Syntax: NOOP (just do nothing).',
+ 'OPTS': 'Syntax: OPTS ftp-command [ option] (specify options for FTP commands)',
+ 'PASS': 'Syntax: PASS user-name (set user password).',
+ 'PASV': 'Syntax: PASV (set server in passive mode).',
+ 'PORT': 'Syntax: PORT h1,h2,h3,h4,p1,p2 (set server in active mode).',
+ 'PWD' : 'Syntax: PWD (get current working directory).',
+ 'QUIT': 'Syntax: QUIT (quit current session).',
+ 'REIN': 'Syntax: REIN (reinitialize / flush account).',
+ 'REST': 'Syntax: REST marker (restart file position).',
+ 'RETR': 'Syntax: RETR file-name (retrieve a file).',
+ 'RMD' : 'Syntax: RMD dir-name (remove directory).',
+ 'RNFR': 'Syntax: RNFR file-name (file renaming (source name)).',
+ 'RNTO': 'Syntax: RNTO file-name (file renaming (destination name)).',
+ 'SIZE': 'Syntax: HELP file-name (get file size).',
+ 'STAT': 'Syntax: STAT [ path name] (status information [list files]).',
+ 'STOR': 'Syntax: STOR file-name (store a file).',
+ 'STOU': 'Syntax: STOU [ file-name] (store a file with a unique name).',
+ 'STRU': 'Syntax: STRU type (obsolete; set file structure).',
+ 'SYST': 'Syntax: SYST (get operating system type).',
+ 'TYPE': 'Syntax: TYPE [A | I] (set transfer type).',
+ 'USER': 'Syntax: USER user-name (set username).',
+ 'XCUP': 'Syntax: XCUP (obsolete; go to parent directory).',
+ 'XCWD': 'Syntax: XCWD dir-name (obsolete; change current directory).',
+ 'XMKD': 'Syntax: XMDK dir-name (obsolete; create directory).',
+ 'XPWD': 'Syntax: XPWD (obsolete; get current dir).',
+ 'XRMD': 'Syntax: XRMD dir-name (obsolete; remove directory).',
}
-class _CommandProperty:
- def __init__(self, perm, auth_needed, arg_needed, check_path, help):
- self.perm = perm
- self.auth_needed = auth_needed
- self.arg_needed = arg_needed
- self.check_path = check_path
- self.help = help
-
-for cmd, properties in proto_cmds.iteritems():
- proto_cmds[cmd] = _CommandProperty(*properties)
-del cmd, properties
-
# hack around format_exc function of traceback module to grant
# backward compatibility with python < 2.4
@@ -235,97 +221,6 @@ def _strerror(err):
else:
return err.strerror
-# the heap used for the scheduled tasks
-_tasks = []
-
-def _scheduler():
- """Run the scheduled functions due to expire soonest (if any)."""
- now = time.time()
- while _tasks and now >= _tasks[0].timeout:
- call = heapq.heappop(_tasks)
- if call.repush:
- heapq.heappush(_tasks, call)
- call.repush = False
- continue
- try:
- call.call()
- finally:
- if not call.cancelled:
- call.cancel()
-
-
-class CallLater:
- """Calls a function at a later time.
-
- It can be used to asynchronously schedule a call within the polling
- loop without blocking it. The instance returned is an object that
- can be used to cancel or reschedule the call.
- """
-
- def __init__(self, seconds, target, *args, **kwargs):
- """
- - (int) seconds: the number of seconds to wait
- - (obj) target: the callable object to call later
- - args: the arguments to call it with
- - kwargs: the keyword arguments to call it with
- """
- assert callable(target), "%s is not callable" %target
- assert sys.maxint >= seconds >= 0, "%s is not greater than or equal " \
- "to 0 seconds" % (seconds)
- self.__delay = seconds
- self.__target = target
- self.__args = args
- self.__kwargs = kwargs
- # seconds from the epoch at which to call the function
- self.timeout = time.time() + self.__delay
- self.repush = False
- self.cancelled = False
- heapq.heappush(_tasks, self)
-
- def __le__(self, other):
- return self.timeout <= other.timeout
-
- def call(self):
- """Call this scheduled function."""
- assert not self.cancelled, "Already cancelled"
- self.__target(*self.__args, **self.__kwargs)
-
- def reset(self):
- """Reschedule this call resetting the current countdown."""
- assert not self.cancelled, "Already cancelled"
- self.timeout = time.time() + self.__delay
- self.repush = True
-
- def delay(self, seconds):
- """Reschedule this call for a later time."""
- assert not self.cancelled, "Already cancelled."
- assert sys.maxint >= seconds >= 0, "%s is not greater than or equal " \
- "to 0 seconds" %(seconds)
- self.__delay = seconds
- newtime = time.time() + self.__delay
- if newtime > self.timeout:
- self.timeout = newtime
- self.repush = True
- else:
- # XXX - slow, can be improved
- self.timeout = newtime
- heapq.heapify(_tasks)
-
- def cancel(self):
- """Unschedule this call."""
- assert not self.cancelled, "Already cancelled"
- self.cancelled = True
- del self.__target, self.__args, self.__kwargs
- if self in _tasks:
- pos = _tasks.index(self)
- if pos == 0:
- heapq.heappop(_tasks)
- elif pos == len(_tasks) - 1:
- _tasks.pop(pos)
- else:
- _tasks[pos] = _tasks.pop()
- heapq._siftup(_tasks, pos)
-
# --- library defined exceptions
@@ -340,11 +235,13 @@ class AuthorizerError(Error):
def log(msg):
"""Log messages intended for the end user."""
- print msg
+ if LOG_ACTIVE:
+ print msg
def logline(msg):
"""Log commands and responses passing through the command channel."""
- print msg
+ if LOG_ACTIVE:
+ print msg
def logerror(msg):
"""Log traceback outputs occurring in case of errors."""
@@ -403,14 +300,20 @@ class DummyAuthorizer:
"""
if self.has_user(username):
raise AuthorizerError('User "%s" already exists' %username)
+ homedir = os.path.realpath(homedir)
if not os.path.isdir(homedir):
raise AuthorizerError('No such directory: "%s"' %homedir)
- homedir = os.path.realpath(homedir)
- self._check_permissions(username, perm)
+ for p in perm:
+ if p not in 'elradfmw':
+ raise AuthorizerError('No such permission "%s"' %p)
+ for p in perm:
+ if (p in self.write_perms) and (username == 'anonymous'):
+ warnings.warn("write permissions assigned to anonymous user.",
+ RuntimeWarning)
+ break
dic = {'pwd': str(password),
'home': homedir,
'perm': perm,
- 'operms': {},
'msg_login': str(msg_login),
'msg_quit': str(msg_quit)
}
@@ -438,26 +341,9 @@ class DummyAuthorizer:
"""Remove a user from the virtual users table."""
del self.user_table[username]
- def override_perm(self, username, directory, perm, recursive=False):
- """Override permissions for a given directory."""
- self._check_permissions(username, perm)
- if not os.path.isdir(directory):
- raise AuthorizerError('No such directory: "%s"' %directory)
- directory = os.path.normcase(os.path.realpath(directory))
- home = os.path.normcase(self.get_home_dir(username))
- if directory == home:
- raise AuthorizerError("Can't override home directory permissions")
- if not self._issubpath(directory, home):
- raise AuthorizerError("Path escapes user home directory")
- self.user_table[username]['operms'][directory] = perm, recursive
-
def validate_authentication(self, username, password):
"""Return True if the supplied username and password match the
stored credentials."""
- if not self.has_user(username):
- return False
- if username == 'anonymous':
- return True
return self.user_table[username]['pwd'] == password
def impersonate_user(self, username, password):
@@ -489,19 +375,6 @@ class DummyAuthorizer:
Expected perm argument is one of the following letters:
"elradfmw".
"""
- if path is None:
- return perm in self.user_table[username]['perm']
-
- path = os.path.normcase(path)
- for dir in self.user_table[username]['operms'].keys():
- operm, recursive = self.user_table[username]['operms'][dir]
- if self._issubpath(path, dir):
- if recursive:
- return perm in operm
- if (path == dir) or (os.path.dirname(path) == dir \
- and not os.path.isdir(path)):
- return perm in operm
-
return perm in self.user_table[username]['perm']
def get_perms(self, username):
@@ -520,23 +393,6 @@ class DummyAuthorizer:
"""Return the user's quitting message."""
return self.user_table[username]['msg_quit']
- def _check_permissions(self, username, perm):
- warned = 0
- for p in perm:
- if p not in self.read_perms + self.write_perms:
- raise AuthorizerError('No such permission "%s"' %p)
- if (username == 'anonymous') and (p in self.write_perms) and not warned:
- warnings.warn("Write permissions assigned to anonymous user.",
- RuntimeWarning)
- warned = 1
-
- def _issubpath(self, a, b):
- """Return True if a is a sub-path of b or if the paths are equal."""
- p1 = a.rstrip(os.sep).split(os.sep)
- p2 = b.rstrip(os.sep).split(os.sep)
- return p1[:len(p2)] == p2
-
-
# --- DTP classes
@@ -544,11 +400,7 @@ class PassiveDTP(asyncore.dispatcher):
"""This class is an asyncore.disptacher subclass. It creates a
socket listening on a local port, dispatching the resultant
connection to DTPHandler.
-
- - (int) timeout: the timeout for a remote client to establish
- connection with the listening socket. Defaults to 30 seconds.
"""
- timeout = 30
def __init__(self, cmd_channel, extmode=False):
"""Initialize the passive data server.
@@ -558,17 +410,13 @@ class PassiveDTP(asyncore.dispatcher):
"""
asyncore.dispatcher.__init__(self)
self.cmd_channel = cmd_channel
- if self.timeout:
- self.idler = CallLater(self.timeout, self.handle_timeout)
- else:
- self.idler = None
ip = self.cmd_channel.getsockname()[0]
self.create_socket(self.cmd_channel.af, socket.SOCK_STREAM)
- if self.cmd_channel.passive_ports is None:
- # By using 0 as port number value we let kernel choose a
- # free unprivileged random port.
+ if not self.cmd_channel.passive_ports:
+ # By using 0 as port number value we let kernel choose a free
+ # unprivileged random port.
self.bind((ip, 0))
else:
ports = list(self.cmd_channel.passive_ports)
@@ -613,12 +461,8 @@ class PassiveDTP(asyncore.dispatcher):
def handle_accept(self):
"""Called when remote client initiates a connection."""
- try:
- sock, addr = self.accept()
- except TypeError:
- # for some reason sometimes accept() returns None instead
- # of a socket
- return
+ sock, addr = self.accept()
+
# Check the origin of data connection. If not expressively
# configured we drop the incoming data connection if remote
# IP address does not match the client's IP address.
@@ -648,10 +492,6 @@ class PassiveDTP(asyncore.dispatcher):
self.cmd_channel.data_channel = handler
self.cmd_channel.on_dtp_connection()
- def handle_timeout(self):
- self.cmd_channel.respond("421 Passive data channel timed out.")
- self.close()
-
def writable(self):
return 0
@@ -664,21 +504,16 @@ class PassiveDTP(asyncore.dispatcher):
logerror(traceback.format_exc())
self.close()
- def close(self):
- if self.idler is not None and not self.idler.cancelled:
- self.idler.cancel()
- asyncore.dispatcher.close(self)
+ def handle_close(self):
+ """Called on closing the data connection."""
+ self.close()
class ActiveDTP(asyncore.dispatcher):
"""This class is an asyncore.disptacher subclass. It creates a
socket resulting from the connection to a remote user-port,
dispatching it to DTPHandler.
-
- - (int) timeout: the timeout for us to establish connection with
- the client's listening data socket.
"""
- timeout = 30
def __init__(self, ip, port, cmd_channel):
"""Initialize the active data channel attemping to connect
@@ -690,10 +525,6 @@ class ActiveDTP(asyncore.dispatcher):
"""
asyncore.dispatcher.__init__(self)
self.cmd_channel = cmd_channel
- if self.timeout:
- self.idler = CallLater(self.timeout, self.handle_timeout)
- else:
- self.idler = None
self.create_socket(self.cmd_channel.af, socket.SOCK_STREAM)
try:
self.connect((ip, port))
@@ -703,19 +534,11 @@ class ActiveDTP(asyncore.dispatcher):
# --- connection / overridden
- # NOOP, overridden to prevent unhandled read/write event
- # messages to be printed on Python < 2.6
-
def handle_write(self):
- pass
-
- def handle_read(self):
- pass
+ """NOOP, must be overridden to prevent unhandled write event."""
def handle_connect(self):
"""Called when connection is established."""
- if self.idler is not None and not self.idler.cancelled:
- self.idler.cancel()
self.cmd_channel.respond('200 Active data connection established.')
# delegate such connection to DTP handler
handler = self.cmd_channel.dtp_handler(self.socket, self.cmd_channel)
@@ -723,10 +546,6 @@ class ActiveDTP(asyncore.dispatcher):
self.cmd_channel.on_dtp_connection()
#self.close() # <-- (done automatically)
- def handle_timeout(self):
- self.cmd_channel.respond("421 Active data channel timed out.")
- self.close()
-
def handle_expt(self):
self.cmd_channel.respond("425 Can't connect to specified address.")
self.close()
@@ -744,11 +563,6 @@ class ActiveDTP(asyncore.dispatcher):
self.cmd_channel.respond("425 Can't connect to specified address.")
self.close()
- def close(self):
- if self.idler is not None and not self.idler.cancelled:
- self.idler.cancel()
- asyncore.dispatcher.close(self)
-
try:
from collections import deque
@@ -764,16 +578,15 @@ class DTPHandler(asyncore.dispatcher):
RFC-959) managing data-transfer operations involving sending
and receiving data.
- Class attributes:
+ Instance attributes defined in this class, initialized when
+ channel is opened:
- - (int) timeout: the timeout which roughly is the maximum time we
- permit data transfers to stall for with no progress. If the
- timeout triggers, the remote client will be kicked off
- (defaults 300).
-
- - (int) ac_in_buffer_size: incoming data buffer size (defaults 65536)
-
- - (int) ac_out_buffer_size: outgoing data buffer size (defaults 65536)
+ - (instance) cmd_channel: the command channel class instance.
+ - (file) file_obj: the file transferred (if any).
+ - (bool) receive: True if channel is used for receiving data.
+ - (bool) transfer_finished: True if transfer completed successfully.
+ - (int) tot_bytes_sent: the total bytes sent.
+ - (int) tot_bytes_received: the total bytes received.
DTPHandler implementation note:
@@ -795,9 +608,8 @@ class DTPHandler(asyncore.dispatcher):
available we use a list instead.
"""
- timeout = 300
- ac_in_buffer_size = 65536
- ac_out_buffer_size = 65536
+ ac_in_buffer_size = 8192
+ ac_out_buffer_size = 8192
def __init__(self, sock_obj, cmd_channel):
"""Initialize the command channel.
@@ -819,12 +631,6 @@ class DTPHandler(asyncore.dispatcher):
self.tot_bytes_sent = 0
self.tot_bytes_received = 0
self.data_wrapper = lambda x: x
- self._lastdata = 0
- self._closed = False
- if self.timeout:
- self.idler = CallLater(self.timeout, self.handle_timeout)
- else:
- self.idler = None
# --- utility methods
@@ -836,10 +642,7 @@ class DTPHandler(asyncore.dispatcher):
- (str) type: current transfer type, 'a' (ASCII) or 'i' (binary).
"""
if type == 'a':
- if os.linesep == '\r\n':
- self.data_wrapper = lambda x: x
- else:
- self.data_wrapper = lambda x: x.replace('\r\n', os.linesep)
+ self.data_wrapper = lambda x: x.replace('\r\n', os.linesep)
elif type == 'i':
self.data_wrapper = lambda x: x
else:
@@ -945,20 +748,6 @@ class DTPHandler(asyncore.dispatcher):
# we tried to send some actual data
return
- def handle_timeout(self):
- """Called cyclically to check if data trasfer is stalling with
- no progress in which case the client is kicked off.
- """
- if self.get_transmitted_bytes() > self._lastdata:
- self._lastdata = self.get_transmitted_bytes()
- self.idler = CallLater(self.timeout, self.handle_timeout)
- else:
- msg = "Data connection timed out."
- self.cmd_channel.log(msg)
- self.cmd_channel.respond("421 " + msg)
- self.cmd_channel.close_when_done()
- self.close()
-
def handle_expt(self):
"""Called on "exceptional" data events."""
self.cmd_channel.respond("426 Connection error; transfer aborted.")
@@ -1016,19 +805,10 @@ class DTPHandler(asyncore.dispatcher):
def close(self):
"""Close the data channel, first attempting to close any remaining
file handles."""
- if not self._closed:
- self._closed = True
- if self.file_obj is not None and not self.file_obj.closed:
- self.file_obj.close()
- if self.idler is not None and not self.idler.cancelled:
- self.idler.cancel()
- asyncore.dispatcher.close(self)
- if self.file_obj is not None and self.transfer_finished:
- if self.receive:
- self.cmd_channel.on_file_received(self.file_obj.name)
- else:
- self.cmd_channel.on_file_sent(self.file_obj.name)
- self.cmd_channel.on_dtp_close()
+ if self.file_obj and not self.file_obj.closed:
+ self.file_obj.close()
+ asyncore.dispatcher.close(self)
+ self.cmd_channel.on_dtp_close()
# --- producers
@@ -1047,10 +827,7 @@ class FileProducer:
self.done = False
self.file = file
if type == 'a':
- if os.linesep == '\r\n':
- self.data_wrapper = lambda x: x
- else:
- self.data_wrapper = lambda x: x.replace(os.linesep, '\r\n')
+ self.data_wrapper = lambda x: x.replace(os.linesep, '\r\n')
elif type == 'i':
self.data_wrapper = lambda x: x
else:
@@ -1068,6 +845,22 @@ class FileProducer:
return data
+class IteratorProducer:
+ """Producer for iterator objects."""
+
+ def __init__(self, iterator):
+ self.iterator = iterator
+
+ def more(self):
+ """Attempt a chunk of data from iterator by calling its next()
+ method.
+ """
+ try:
+ return self.iterator.next()
+ except StopIteration:
+ return ''
+
+
class BufferedIteratorProducer:
"""Producer for iterator objects with buffer capabilities."""
# how many times iterator.next() will be called before
@@ -1250,9 +1043,9 @@ class AbstractedFS:
os.chdir(basedir)
self.cwd = self.fs2ftp(path)
- def mkdir(self, path):
+ def mkdir(self, path, basename):
"""Create the specified directory."""
- os.mkdir(path)
+ os.mkdir(os.path.join(path, basename))
def listdir(self, path):
"""List the content of a directory."""
@@ -1330,6 +1123,17 @@ class AbstractedFS:
exists = lexists # alias for backward compatibility with 0.2.0
+ def glob1(self, dirname, pattern):
+ """Return a list of files matching a dirname pattern
+ non-recursively.
+
+ Unlike glob.glob1 raises exception if os.listdir() fails.
+ """
+ names = self.listdir(dirname)
+ if pattern[0] != '.':
+ names = filter(lambda x: x[0] != '.', names)
+ return fnmatch.filter(names, pattern)
+
# --- Listing utilities
# note: the following operations are no more blocking
@@ -1348,6 +1152,28 @@ class AbstractedFS:
self.lstat(path) # raise exc in case of problems
return self.format_list(basedir, [filename])
+ def get_stat_dir(self, rawline):
+ """Return an iterator object that yields a list of files
+ matching a dirname pattern non-recursively in a form
+ suitable for STAT command.
+
+ - (str) rawline: the raw string passed by client as command
+ argument.
+ """
+ ftppath = self.ftpnorm(rawline)
+ if not glob.has_magic(ftppath):
+ return self.get_list_dir(self.ftp2fs(rawline))
+ else:
+ basedir, basename = os.path.split(ftppath)
+ if glob.has_magic(basedir):
+ return iter(['Directory recursion not supported.\r\n'])
+ else:
+ basedir = self.ftp2fs(basedir)
+ listing = self.glob1(basedir, basename)
+ if listing:
+ listing.sort()
+ return self.format_list(basedir, listing)
+
def format_list(self, basedir, listing, ignore_err=True):
"""Return an iterator object that yields the entries of given
directory emulating the "/bin/ls -lA" UNIX command output.
@@ -1397,15 +1223,14 @@ class AbstractedFS:
# bogus values for owner and group
uname = "owner"
gname = "group"
+ # stat.st_mtime could fail (-1) if last mtime is too old
+ # in which case we return the local time as last mtime
try:
mtime = time.strftime("%b %d %H:%M", time.localtime(st.st_mtime))
except ValueError:
- # It could be raised if last mtime happens to be too
- # old (prior to year 1900) in which case we return
- # the current time as last mtime.
mtime = time.strftime("%b %d %H:%M")
# if the file is a symlink, resolve it, e.g. "symlink -> realfile"
- if stat.S_ISLNK(st.st_mode) and hasattr(os, 'readlink'):
+ if stat.S_ISLNK(st.st_mode):
basename = basename + " -> " + os.readlink(file)
# formatting is matched with proftpd ls output
@@ -1476,9 +1301,8 @@ class AbstractedFS:
try:
modify = 'modify=%s;' %time.strftime("%Y%m%d%H%M%S",
time.localtime(st.st_mtime))
- # it could be raised if last mtime happens to be too old
- # (prior to year 1900)
except ValueError:
+ # stat.st_mtime could fail (-1) if last mtime is too old
modify = ""
if 'create' in facts:
# on Windows we can provide also the creation time
@@ -1519,11 +1343,6 @@ class FTPHandler(asynchat.async_chat):
reproduced below and can be modified before instantiating this
class.
- - (int) timeout:
- The timeout which is the maximum time a remote client may spend
- between FTP commands. If the timeout triggers, the remote client
- will be kicked off. Defaults to 300 seconds.
-
- (str) banner: the string sent when client connects.
- (int) max_login_attempts:
@@ -1579,7 +1398,6 @@ class FTPHandler(asynchat.async_chat):
abstracted_fs = AbstractedFS
# session attributes (explained in the docstring)
- timeout = 300
banner = "pyftpdlib %s ready." %__ver__
max_login_attempts = 3
permit_foreign_addresses = False
@@ -1594,17 +1412,17 @@ class FTPHandler(asynchat.async_chat):
established connection.
- (instance) server: the ftp server class instance.
"""
- asynchat.async_chat.__init__(self, conn)
- self.set_terminator("\r\n")
- # try to handle urgent data inline
try:
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_OOBINLINE, 1)
- except socket.error:
- pass
-
- # public session attributes
+ asynchat.async_chat.__init__(self, conn=conn) # python2.5
+ except TypeError, e:
+ asynchat.async_chat.__init__(self, sock=conn) # python2.6
self.server = server
self.remote_ip, self.remote_port = self.socket.getpeername()[:2]
+ self.in_buffer = []
+ self.in_buffer_len = 0
+ self.set_terminator("\r\n")
+
+ # session attributes
self.fs = self.abstracted_fs()
self.authenticated = False
self.username = ""
@@ -1613,13 +1431,24 @@ class FTPHandler(asynchat.async_chat):
self.current_type = 'a'
self.restart_position = 0
self.quit_pending = False
- self.sleeping = False
+ self._epsvall = False
+ self.__in_dtp_queue = None
+ self.__out_dtp_queue = None
+
+ # mlsx facts attributes
+ self.current_facts = ['type', 'perm', 'size', 'modify']
+ if os.name == 'posix':
+ self.current_facts.append('unique')
+ self.available_facts = self.current_facts[:]
+ if pwd and grp:
+ self.available_facts += ['unix.mode', 'unix.uid', 'unix.gid']
+ if os.name == 'nt':
+ self.available_facts.append('create')
+
+ # dtp attributes
self.data_server = None
self.data_channel = None
- if self.timeout:
- self.idler = CallLater(self.timeout, self.handle_timeout)
- else:
- self.idler = None
+
if hasattr(self.socket, 'family'):
self.af = self.socket.family
else: # python < 2.5
@@ -1627,23 +1456,6 @@ class FTPHandler(asynchat.async_chat):
self.af = socket.getaddrinfo(ip, port, socket.AF_UNSPEC,
socket.SOCK_STREAM)[0][0]
- # private session attributes
- self._in_buffer = []
- self._in_buffer_len = 0
- self._epsvall = False
- self._in_dtp_queue = None
- self._out_dtp_queue = None
- self._closed = False
- self._extra_feats = []
- self._current_facts = ['type', 'perm', 'size', 'modify']
- if os.name == 'posix':
- self._current_facts.append('unique')
- self._available_facts = self._current_facts[:]
- if pwd and grp:
- self._available_facts += ['unix.mode', 'unix.uid', 'unix.gid']
- if os.name == 'nt':
- self._available_facts.append('create')
-
def handle(self):
"""Return a 220 'Ready' response to the client over the command
channel.
@@ -1675,33 +1487,37 @@ class FTPHandler(asynchat.async_chat):
self.log(msg)
self.close_when_done()
- def handle_timeout(self):
- """Called when client does not send any command within the time
- specified in attribute."""
- msg = "Control connection timed out."
- self.log(msg)
- self.respond("421 " + msg)
- self.close_when_done()
-
# --- asyncore / asynchat overridden methods
def readable(self):
# if there's a quit pending we stop reading data from socket
- return not self.sleeping
+ return not self.quit_pending
def collect_incoming_data(self, data):
"""Read incoming data and append to the input buffer."""
- self._in_buffer.append(data)
- self._in_buffer_len += len(data)
+ self.in_buffer.append(data)
+ self.in_buffer_len += len(data)
# Flush buffer if it gets too long (possible DoS attacks).
# RFC-959 specifies that a 500 response could be given in
# such cases
buflimit = 2048
- if self._in_buffer_len > buflimit:
+ if self.in_buffer_len > buflimit:
self.respond('500 Command too long.')
self.log('Command received exceeded buffer limit of %s.' %(buflimit))
- self._in_buffer = []
- self._in_buffer_len = 0
+ self.in_buffer = []
+ self.in_buffer_len = 0
+
+ # commands accepted before authentication
+ unauth_cmds = ('FEAT','HELP','NOOP','PASS','QUIT','STAT','SYST','USER')
+
+ # commands needing an argument
+ arg_cmds = ('ALLO','APPE','DELE','EPRT','MDTM','MODE','MKD','OPTS','PORT',
+ 'REST','RETR','RMD','RNFR','RNTO','SIZE', 'STOR','STRU',
+ 'TYPE','USER','XMKD','XRMD')
+
+ # commands needing no argument
+ unarg_cmds = ('ABOR','CDUP','FEAT','NOOP','PASV','PWD','QUIT','REIN',
+ 'SYST','XCUP','XPWD')
def found_terminator(self):
r"""Called when the incoming data stream matches the \r\n
@@ -1711,109 +1527,130 @@ class FTPHandler(asynchat.async_chat):
corresponding method (e.g. for received command "MKD pathname",
ftp_MKD() method is called with "pathname" as the argument).
"""
- if self.idler is not None and not self.idler.cancelled:
- self.idler.reset()
-
- line = ''.join(self._in_buffer)
- self._in_buffer = []
- self._in_buffer_len = 0
+ line = ''.join(self.in_buffer)
+ self.in_buffer = []
+ self.in_buffer_len = 0
cmd = line.split(' ')[0].upper()
- arg = line[len(cmd)+1:]
- if cmd == "SITE" and arg:
- cmd = "SITE %s" %arg.split(' ')[0].upper()
- arg = line[len(cmd)+1:]
+ space = line.find(' ')
+ if space != -1:
+ arg = line[space + 1:]
+ else:
+ arg = ""
if cmd != 'PASS':
self.logline("<== %s" %line)
else:
self.logline("<== %s %s" %(line.split(' ')[0], '*' * 6))
- # Recognize those commands having a "special semantic". They
- # should be sent by following the RFC-959 procedure of sending
- # Telnet IP/Synch sequence (chr 242 and 255) as OOB data but
- # since many ftp clients don't do it correctly we check the
- # last 4 characters only.
- if not cmd in proto_cmds:
- if cmd[-4:] in ('ABOR', 'STAT', 'QUIT'):
- cmd = cmd[-4:]
- else:
- self.respond('500 Command "%s" not understood.' %cmd)
- return
-
- if not arg and proto_cmds[cmd].arg_needed is True:
+ # let's check if user provided an argument for those commands
+ # needing one
+ if not arg and cmd in self.arg_cmds:
self.respond("501 Syntax error: command needs an argument.")
return
- if arg and proto_cmds[cmd].arg_needed is False:
+
+ # let's do the same for those commands requiring no argument.
+ elif arg and cmd in self.unarg_cmds:
self.respond("501 Syntax error: command does not accept arguments.")
return
- if not self.authenticated:
- if proto_cmds[cmd].auth_needed or (cmd == 'STAT' and arg):
+ # provide a limited set of commands if user isn't
+ # authenticated yet
+ if (not self.authenticated):
+ if cmd in self.unauth_cmds:
+ # we permit STAT during this phase but we don't want
+ # STAT to return a directory LISTing if the user is
+ # not authenticated yet (this could happen if STAT
+ # is used with an argument)
+ if (cmd == 'STAT') and arg:
+ self.respond("530 Log in with USER and PASS first.")
+ else:
+ method = getattr(self, 'ftp_' + cmd)
+ method(arg) # call the proper ftp_* method
+ elif cmd in proto_cmds:
self.respond("530 Log in with USER and PASS first.")
else:
- method = getattr(self, 'ftp_' + cmd.replace(' ', '_'))
- method(arg) # call the proper ftp_* method
- else:
- if cmd == 'STAT' and not arg:
- self.ftp_STAT('')
- return
+ self.respond('500 Command "%s" not understood.' %line)
- # for file-system related commands check whether real path
- # destination is valid
- if proto_cmds[cmd].check_path and cmd != 'STOU':
- if cmd in ('CWD', 'XCWD'):
- arg = arg or '/'
- elif cmd in ('CDUP', 'XCUP'):
- arg = '..'
- elif cmd == 'LIST':
- if arg.lower() in ('-a', '-l', '-al', '-la'):
- arg = self.fs.cwd
- else:
- arg = arg or self.fs.cwd
- elif cmd == 'STAT':
- if glob.has_magic(arg):
- self.respond('550 Globbing not supported.')
- return
- arg = arg or self.fs.cwd
- else: # LIST, NLST, MLSD, MLST
- arg = arg or self.fs.cwd
- if not self.fs.validpath(arg or '/'):
- line = self.fs.ftpnorm(arg)
+ # provide full command set
+ elif (self.authenticated) and (cmd in proto_cmds):
+ if not (self.__check_path(arg, arg)): # and self.__check_perm(cmd, arg)):
+ return
+ method = getattr(self, 'ftp_' + cmd)
+ method(arg) # call the proper ftp_* method
+
+ else:
+ # recognize those commands having "special semantics"
+ if 'ABOR' in cmd:
+ self.ftp_ABOR("")
+ elif 'STAT' in cmd:
+ self.ftp_STAT("")
+ # unknown command
+ else:
+ self.respond('500 Command "%s" not understood.' %line)
+
+ def __check_path(self, cmd, line):
+ """Check whether a path is valid."""
+ # For the following commands we have to make sure that the real
+ # path destination belongs to the user's root directory.
+ # If provided path is a symlink we follow its final destination
+ # to do so.
+ if cmd in ('APPE','CWD','DELE','MDTM','NLST','MLSD','MLST','RETR',
+ 'RMD','SIZE','STOR','XCWD','XRMD'):
+ datacr = None
+ datacr = self.fs.get_cr(line)
+ try:
+ if not self.fs.validpath(self.fs.ftp2fs(line, datacr)):
+ line = self.fs.ftpnorm(line)
err = '"%s" points to a path which is outside ' \
"the user's root directory" %line
self.respond("550 %s." %err)
- self.log('FAIL %s "%s". %s.' %(cmd, line, err))
- return
- # check permission
- perm = proto_cmds[cmd].perm
- if perm is not None and cmd != 'STOU':
- if not self.authorizer.has_perm(self.username, perm, arg or '/'):
- self.log('FAIL %s "%s". Not enough privileges.' \
- %(cmd, self.fs.fs2ftp(line)))
- self.respond("550 Can't %s. Not enough privileges." %cmd)
- return
- # call the proper ftp_* method
- method = getattr(self, 'ftp_' + cmd.replace(' ', '_'))
- method(arg)
+ self.log('FAIL %s "%s". %s.' %(cmd, line, err))
+ self.fs.close_cr(datacr)
+ return False
+ except:
+ pass
+ self.fs.close_cr(datacr)
+ return True
+
+ def __check_perm(self, cmd, line, datacr):
+ """Check permissions depending on issued command."""
+ map = {'CWD':'e', 'XCWD':'e', 'CDUP':'e', 'XCUP':'e',
+ 'LIST':'l', 'NLST':'l', 'MLSD':'l', 'STAT':'l',
+ 'RETR':'r',
+ 'APPE':'a',
+ 'DELE':'d', 'RMD':'d', 'XRMD':'d',
+ 'RNFR':'f',
+ 'MKD':'m', 'XMKD':'m',
+ 'STOR':'w'}
+ if cmd in map:
+ if cmd == 'STAT' and not line:
+ return True
+ perm = map[cmd]
+ if not line and (cmd in ('LIST','NLST','MLSD')):
+ path = self.fs.ftp2fs(self.fs.cwd, datacr)
+ else:
+ path = self.fs.ftp2fs(line, datacr)
+ if not self.authorizer.has_perm(self.username, perm, path):
+ self.log('FAIL %s "%s". Not enough privileges.' \
+ %(cmd, self.fs.ftpnorm(line)))
+ self.respond("550 Can't %s. Not enough privileges." %cmd)
+ return False
+ return True
def handle_expt(self):
- """Called when there is out of band (OOB) data to be read.
- This could happen in case of such clients strictly following
- the RFC-959 directives of sending Telnet IP and Synch as OOB
- data before issuing ABOR, STAT and QUIT commands.
- It should never be called since the SO_OOBINLINE option is
- enabled except on some systems like FreeBSD where it doesn't
- seem to have effect.
+ """Called when there is out of band (OOB) data for the socket
+ connection. This could happen in case of such commands needing
+ "special action" (typically STAT and ABOR) in which case we
+ append OOB data to incoming buffer.
"""
if hasattr(socket, 'MSG_OOB'):
try:
data = self.socket.recv(1024, socket.MSG_OOB)
- except socket.error, why:
- if why[0] == errno.EINVAL:
- return
+ except socket.error:
+ pass
else:
- self._in_buffer.append(data)
+ self.in_buffer.append(data)
return
self.log("Can't handle OOB data.")
self.close()
@@ -1838,23 +1675,21 @@ class FTPHandler(asynchat.async_chat):
def handle_close(self):
self.close()
+ _closed = False
def close(self):
"""Close the current channel disconnecting the client."""
if not self._closed:
self._closed = True
- if self.data_server is not None:
+ if self.data_server:
self.data_server.close()
del self.data_server
- if self.data_channel is not None:
+ if self.data_channel:
self.data_channel.close()
del self.data_channel
- del self._out_dtp_queue
- del self._in_dtp_queue
-
- if self.idler is not None and not self.idler.cancelled:
- self.idler.cancel()
+ del self.__out_dtp_queue
+ del self.__in_dtp_queue
# remove client IP address from ip map
self.server.ip_map.remove(self.remote_ip)
@@ -1863,16 +1698,6 @@ class FTPHandler(asynchat.async_chat):
# --- callbacks
- def on_file_sent(self, file):
- """Called every time a file has been succesfully sent.
- 'file' is the complete filename of the file being sent.
- """
-
- def on_file_received(self, file):
- """Called every time a file has been succesfully received.
- 'file' is the complete filename of the file being received.
- """
-
def on_dtp_connection(self):
"""Called every time data channel connects (either active or
passive).
@@ -1882,45 +1707,34 @@ class FTPHandler(asynchat.async_chat):
If awaiting inbound data, the data channel is enabled for
receiving.
"""
- if self.data_server is not None:
+ if self.data_server:
self.data_server.close()
self.data_server = None
- # stop the idle timer as long as the data transfer is not finished
- if self.idler is not None and not self.idler.cancelled:
- self.idler.cancel()
-
# check for data to send
- if self._out_dtp_queue is not None:
- data, isproducer, file = self._out_dtp_queue
- self._out_dtp_queue = None
+ if self.__out_dtp_queue:
+ data, isproducer, file = self.__out_dtp_queue
if file:
self.data_channel.file_obj = file
- try:
- if not isproducer:
- self.data_channel.push(data)
- else:
- self.data_channel.push_with_producer(data)
- if self.data_channel is not None:
- self.data_channel.close_when_done()
- except:
- # dealing with this exception is up to DTP (see bug #84)
- self.data_channel.handle_error()
+ if not isproducer:
+ self.data_channel.push(data)
+ else:
+ self.data_channel.push_with_producer(data)
+ if self.data_channel:
+ self.data_channel.close_when_done()
+ self.__out_dtp_queue = None
# check for data to receive
- elif self._in_dtp_queue is not None:
- self.data_channel.file_obj = self._in_dtp_queue
+ elif self.__in_dtp_queue:
+ self.data_channel.file_obj = self.__in_dtp_queue
self.data_channel.enable_receiving(self.current_type)
- self._in_dtp_queue = None
+ self.__in_dtp_queue = None
def on_dtp_close(self):
"""Called every time the data channel is closed."""
self.data_channel = None
if self.quit_pending:
self.close_when_done()
- elif self.timeout:
- # data transfer finished, restart the idle timer
- self.idler = CallLater(self.timeout, self.handle_timeout)
# --- utility
@@ -1943,26 +1757,22 @@ class FTPHandler(asynchat.async_chat):
- (bool) isproducer: whether treat data as a producer.
- (file) file: the file[-like] object to send (if any).
"""
- if self.data_channel is not None:
+ if self.data_channel:
self.respond("125 Data connection already open. Transfer starting.")
if file:
self.data_channel.file_obj = file
- try:
- if not isproducer:
- self.data_channel.push(data)
- else:
- self.data_channel.push_with_producer(data)
- if self.data_channel is not None:
- self.data_channel.close_when_done()
- except:
- # dealing with this exception is up to DTP (see bug #84)
- self.data_channel.handle_error()
+ if not isproducer:
+ self.data_channel.push(data)
+ else:
+ self.data_channel.push_with_producer(data)
+ if self.data_channel:
+ self.data_channel.close_when_done()
else:
self.respond("150 File status okay. About to open data connection.")
- self._out_dtp_queue = (data, isproducer, file)
+ self.__out_dtp_queue = (data, isproducer, file)
def log(self, msg):
- """Log a message, including additional identifying session data."""
+ """Log a message, including additional identifying session data."""
log("[%s]@%s:%s %s" %(self.username, self.remote_ip,
self.remote_port, msg))
@@ -1974,11 +1784,11 @@ class FTPHandler(asynchat.async_chat):
"""Flush account information by clearing attributes that need
to be reset on a REIN or new USER command.
"""
- if self.data_channel is not None:
+ if self.data_channel:
if not self.data_channel.transfer_in_progress():
self.data_channel.close()
self.data_channel = None
- if self.data_server is not None:
+ if self.data_server:
self.data_server.close()
self.data_server = None
@@ -1990,9 +1800,8 @@ class FTPHandler(asynchat.async_chat):
self.current_type = 'a'
self.restart_position = 0
self.quit_pending = False
- self.sleeping = False
- self._in_dtp_queue = None
- self._out_dtp_queue = None
+ self.__in_dtp_queue = None
+ self.__out_dtp_queue = None
def run_as_current_user(self, function, *args, **kwargs):
"""Execute a function impersonating the current logged-in user."""
@@ -2011,33 +1820,36 @@ class FTPHandler(asynchat.async_chat):
# FTP bounce attacks protection: according to RFC-2577 it's
# recommended to reject PORT if IP address specified in it
# does not match client IP address.
- if not self.permit_foreign_addresses and ip != self.remote_ip:
- self.log("Rejected data connection to foreign address %s:%s."
- %(ip, port))
- self.respond("501 Can't connect to a foreign address.")
- return
+ if not self.permit_foreign_addresses:
+ if ip != self.remote_ip:
+ self.log("Rejected data connection to foreign address %s:%s."
+ %(ip, port))
+ self.respond("501 Can't connect to a foreign address.")
+ return
# ...another RFC-2577 recommendation is rejecting connections
# to privileged ports (< 1024) for security reasons.
- if not self.permit_privileged_ports and port < 1024:
- self.log('PORT against the privileged port "%s" refused.' %port)
- self.respond("501 Can't connect over a privileged port.")
- return
+ if not self.permit_privileged_ports:
+ if port < 1024:
+ self.log('PORT against the privileged port "%s" refused.' %port)
+ self.respond("501 Can't connect over a privileged port.")
+ return
# close existent DTP-server instance, if any.
- if self.data_server is not None:
+ if self.data_server:
self.data_server.close()
self.data_server = None
- if self.data_channel is not None:
+ if self.data_channel:
self.data_channel.close()
self.data_channel = None
# make sure we are not hitting the max connections limit
- if self.server.max_cons and len(self._map) >= self.server.max_cons:
- msg = "Too many connections. Can't open data channel."
- self.respond("425 %s" %msg)
- self.log(msg)
- return
+ if self.server.max_cons:
+ if len(self._map) >= self.server.max_cons:
+ msg = "Too many connections. Can't open data channel."
+ self.respond("425 %s" %msg)
+ self.log(msg)
+ return
# open data channel
self.active_dtp(ip, port, self)
@@ -2049,20 +1861,21 @@ class FTPHandler(asynchat.async_chat):
which case extended passive mode will be used (see RFC-2428).
"""
# close existing DTP-server instance, if any
- if self.data_server is not None:
+ if self.data_server:
self.data_server.close()
self.data_server = None
- if self.data_channel is not None:
+ if self.data_channel:
self.data_channel.close()
self.data_channel = None
# make sure we are not hitting the max connections limit
- if self.server.max_cons and len(self._map) >= self.server.max_cons:
- msg = "Too many connections. Can't open data channel."
- self.respond("425 %s" %msg)
- self.log(msg)
- return
+ if self.server.max_cons:
+ if len(self._map) >= self.server.max_cons:
+ msg = "Too many connections. Can't open data channel."
+ self.respond("425 %s" %msg)
+ self.log(msg)
+ return
# open data channel
self.data_server = self.passive_dtp(self, extmode)
@@ -2123,7 +1936,7 @@ class FTPHandler(asynchat.async_chat):
assert len(octs) == 4
for x in octs:
assert 0 <= x <= 255
- except (AssertionError, ValueError, OverflowError):
+ except (AssertionError, ValueError, OverflowError), err:
self.respond("501 Invalid EPRT format.")
else:
self._make_eport(ip, port)
@@ -2186,7 +1999,12 @@ class FTPHandler(asynchat.async_chat):
self.respond('501 Unknown network protocol (use 2).')
def ftp_QUIT(self, line):
- """Quit the current session disconnecting the client."""
+ """Quit the current session."""
+ # From RFC-959:
+ # This command terminates a USER and if file transfer is not
+ # in progress, the server closes the control connection.
+ # If file transfer is in progress, the connection will remain
+ # open for result response and the server will then close it.
if self.authenticated:
msg_quit = self.authorizer.get_msg_quit(self.username)
else:
@@ -2197,15 +2015,12 @@ class FTPHandler(asynchat.async_chat):
self.push("221-%s\r\n" %msg_quit)
self.respond("221 ")
- # From RFC-959:
- # If file transfer is in progress, the connection will remain
- # open for result response and the server will then close it.
- # We also stop responding to any further command.
- if self.data_channel:
- self.quit_pending = True
- self.sleeping = True
- else:
+ if not self.data_channel:
self.close_when_done()
+ else:
+ # tell the cmd channel to stop responding to commands.
+ self.quit_pending = True
+
# --- data transferring
@@ -2216,30 +2031,35 @@ class FTPHandler(asynchat.async_chat):
# - If no argument, fall back on cwd as default.
# - Some older FTP clients erroneously issue /bin/ls-like LIST
# formats in which case we fall back on cwd as default.
- datacr = None
- try:
- datacr = self.fs.get_cr(line)
- path = self.fs.ftp2fs(line, datacr)
+ if not line or line.lower() in ('-a', '-l', '-al', '-la'):
+ line = self.fs.cwd
+ try:
+ data = None
+ data = self.fs.get_cr(line)
+ path = self.fs.ftp2fs(line, data)
line = self.fs.ftpnorm(line)
- iterator = self.run_as_current_user(self.fs.get_list_dir, path)
+ iterator = self.run_as_current_user(self.fs.get_list_dir, path)
except OSError, err:
+ self.fs.close_cr(data)
why = _strerror(err)
self.log('FAIL LIST "%s". %s.' %(line, why))
self.respond('550 %s.' %why)
else:
+ self.fs.close_cr(data)
self.log('OK LIST "%s". Transfer starting.' %line)
producer = BufferedIteratorProducer(iterator)
self.push_dtp_data(producer, isproducer=True)
- self.fs.close_cr(datacr)
def ftp_NLST(self, line):
"""Return a list of files in the specified directory in a
compact form to the client.
"""
- datacr = None
- try:
- datacr = self.fs.get_cr(line)
- path = self.fs.ftp2fs(line, datacr)
+ if not line:
+ line = self.fs.cwd
+ try:
+ data = None
+ data = self.fs.get_cr(line)
+ path = self.fs.ftp2fs(line, data)
line = self.fs.ftpnorm(line)
if self.fs.isdir(path):
listing = self.run_as_current_user(self.fs.listdir, path)
@@ -2248,19 +2068,21 @@ class FTPHandler(asynchat.async_chat):
# if path is a file we just list its name
self.fs.lstat(path) # raise exc in case of problems
basedir, filename = os.path.split(line)
- listing = [filename]
+ listing = [filename]
except OSError, err:
+ self.fs.close_cr(data)
why = _strerror(err)
self.log('FAIL NLST "%s". %s.' %(line, why))
self.respond('550 %s.' %why)
else:
+ self.fs.close_cr(data)
data = ''
if listing:
listing.sort()
data = '\r\n'.join(listing) + '\r\n'
self.log('OK NLST "%s". Transfer starting.' %line)
self.push_dtp_data(data)
- self.fs.close_cr(datacr)
+
# --- MLST and MLSD commands
# The MLST and MLSD commands are intended to standardize the file and
@@ -2271,9 +2093,12 @@ class FTPHandler(asynchat.async_chat):
def ftp_MLST(self, line):
"""Return information about a pathname in a machine-processable
form as defined in RFC-3659.
- """
- datacr = None
- try:
+ """
+ # if no argument, fall back on cwd as default
+ if not line:
+ line = self.fs.cwd
+ try:
+ datacr = None
datacr = self.fs.get_cr(line)
path = self.fs.ftp2fs(line, datacr)
line = self.fs.ftpnorm(line)
@@ -2281,7 +2106,7 @@ class FTPHandler(asynchat.async_chat):
perms = self.authorizer.get_perms(self.username)
iterator = self.run_as_current_user(self.fs.format_mlsx, basedir,
[basename], perms, self.current_facts, ignore_err=False)
- data = ''.join(iterator)
+ data = ''.join(iterator)
except OSError, err:
self.fs.close_cr(datacr)
why = _strerror(err)
@@ -2302,8 +2127,11 @@ class FTPHandler(asynchat.async_chat):
"""Return contents of a directory in a machine-processable form
as defined in RFC-3659.
"""
- datacr = None
- try:
+ # if no argument, fall back on cwd as default
+ if not line:
+ line = self.fs.cwd
+ try:
+ datacr = None
datacr = self.fs.get_cr(line)
path = self.fs.ftp2fs(line, datacr)
line = self.fs.ftpnorm(line)
@@ -2313,7 +2141,7 @@ class FTPHandler(asynchat.async_chat):
self.log('FAIL MLSD "%s". %s.' %(line, err))
self.respond("501 %s." %err)
return
- listing = self.run_as_current_user(self.fs.listdir, path)
+ listing = self.run_as_current_user(self.fs.listdir, path)
except OSError, err:
self.fs.close_cr(datacr)
why = _strerror(err)
@@ -2323,7 +2151,7 @@ class FTPHandler(asynchat.async_chat):
self.fs.close_cr(datacr)
perms = self.authorizer.get_perms(self.username)
iterator = self.fs.format_mlsx(path, listing, perms,
- self._current_facts)
+ self.current_facts)
producer = BufferedIteratorProducer(iterator)
self.log('OK MLSD "%s". Transfer starting.' %line)
self.push_dtp_data(producer, isproducer=True)
@@ -2332,14 +2160,18 @@ class FTPHandler(asynchat.async_chat):
"""Retrieve the specified file (transfer from the server to the
client)
"""
- datacr = None
- try:
+ try:
+ datacr = None
datacr = self.fs.get_cr(line)
file = self.fs.ftp2fs(line, datacr)
line = self.fs.ftpnorm(line)
- rest_pos = self.restart_position
- self.restart_position = 0
- fd = self.run_as_current_user(self.fs.open, file, 'rb')
+ fd = self.run_as_current_user(self.fs.open, file, 'rb')
+ except OSError, err:
+ self.fs.close_cr(datacr)
+ why = _strerror(err)
+ self.log('FAIL RETR "%s". %s.' %(line, why))
+ self.respond('550 %s.' %why)
+ return
except IOError, err:
self.fs.close_cr(datacr)
why = _strerror(err)
@@ -2347,7 +2179,7 @@ class FTPHandler(asynchat.async_chat):
self.respond('550 %s.' %why)
return
- if rest_pos:
+ if self.restart_position:
# Make sure that the requested offset is valid (within the
# size of the file being resumed).
# According to RFC-1123 a 554 reply may result in case that
@@ -2355,18 +2187,19 @@ class FTPHandler(asynchat.async_chat):
# the REST.
ok = 0
try:
- assert not rest_pos > self.fs.getsize(file)
- fd.seek(rest_pos)
+ assert not self.restart_position > self.fs.getsize(file)
+ fd.seek(self.restart_position)
ok = 1
except AssertionError:
why = "Invalid REST parameter"
except IOError, err:
why = _strerror(err)
- if not ok:
+ self.restart_position = 0
+ if not ok:
self.respond('554 %s' %why)
self.log('FAIL RETR "%s". %s.' %(line, why))
self.fs.close_cr(datacr)
- return
+ return
self.log('OK RETR "%s". Download starting.' %line)
producer = FileProducer(fd, self.current_type)
self.push_dtp_data(producer, isproducer=True, file=fd)
@@ -2383,7 +2216,7 @@ class FTPHandler(asynchat.async_chat):
cmd = 'APPE'
else:
cmd = 'STOR'
-
+
line = self.fs.ftpnorm(line)
basedir,basename = os.path.split(line)
@@ -2394,14 +2227,12 @@ class FTPHandler(asynchat.async_chat):
except OSError, err:
self.fs.close_cr(datacr)
- why = ftpserver._strerror(err)
+ why = _strerror(err)
self.log('FAIL %s "%s". %s.' %(cmd, line, why))
self.respond('550 %s.' %why)
return
-
- rest_pos = self.restart_position
- self.restart_position = 0
- if rest_pos:
+
+ if self.restart_position:
mode = 'r+'
try:
fd = self.run_as_current_user(self.fs.create, file, basename, mode + 'b')
@@ -2412,7 +2243,7 @@ class FTPHandler(asynchat.async_chat):
self.respond('550 %s.' %why)
return
- if rest_pos:
+ if self.restart_position:
# Make sure that the requested offset is valid (within the
# size of the file being resumed).
# According to RFC-1123 a 554 reply may result in case
@@ -2420,29 +2251,31 @@ class FTPHandler(asynchat.async_chat):
# specified in the REST.
ok = 0
try:
- assert not rest_pos > self.fs.getsize(file)
- fd.seek(rest_pos)
+ assert not self.restart_position > self.fs.getsize(self.fs.ftp2fs(line, datacr))
+ fd.seek(self.restart_position)
ok = 1
except AssertionError:
why = "Invalid REST parameter"
except IOError, err:
why = _strerror(err)
+ self.restart_position = 0
if not ok:
+ self.fs.close_cr(datacr)
self.respond('554 %s' %why)
self.log('FAIL %s "%s". %s.' %(cmd, line, why))
- self.fs.close_cr(datacr)
return
self.log('OK %s "%s". Upload starting.' %(cmd, line))
- if self.data_channel is not None:
+ if self.data_channel:
self.respond("125 Data connection already open. Transfer starting.")
self.data_channel.file_obj = fd
self.data_channel.enable_receiving(self.current_type)
else:
self.respond("150 File status okay. About to open data connection.")
- self._in_dtp_queue = fd
+ self.__in_dtp_queue = fd
self.fs.close_cr(datacr)
+
def ftp_STOU(self, line):
"""Store a file on the server with a unique name."""
# Note 1: RFC-959 prohibited STOU parameters, but this
@@ -2459,7 +2292,7 @@ class FTPHandler(asynchat.async_chat):
if self.restart_position:
self.respond("450 Can't STOU while REST request is pending.")
return
-
+
datacr = None
datacr = self.fs.get_cr(line)
@@ -2469,7 +2302,7 @@ class FTPHandler(asynchat.async_chat):
basedir = self.fs.ftp2fs(basedir, datacr)
#prefix = prefix + '.'
else:
- basedir = self.fs.ftp2fs(self.fs.cwd)
+ basedir = self.fs.ftp2fs(self.fs.cwd, datacr)
prefix = 'ftpd.'
try:
fd = self.run_as_current_user(self.fs.mkstemp, prefix=prefix,
@@ -2487,12 +2320,8 @@ class FTPHandler(asynchat.async_chat):
self.fs.close_cr(datacr)
return
- if not self.authorizer.has_perm(self.username, 'w', fd.name):
- try:
- fd.close()
- self.run_as_current_user(self.fs.remove, fd.name)
- except os.error:
- pass
+ filename = line
+ if not self.authorizer.has_perm(self.username, 'w', filename):
self.log('FAIL STOU "%s". Not enough privileges'
%self.fs.ftpnorm(line))
self.respond("550 Can't STOU: not enough privileges.")
@@ -2500,30 +2329,27 @@ class FTPHandler(asynchat.async_chat):
return
# now just acts like STOR except that restarting isn't allowed
- filename = os.path.basename(fd.name)
self.log('OK STOU "%s". Upload starting.' %filename)
- if self.data_channel is not None:
+ if self.data_channel:
self.respond("125 FILE: %s" %filename)
self.data_channel.file_obj = fd
self.data_channel.enable_receiving(self.current_type)
else:
self.respond("150 FILE: %s" %filename)
- self._in_dtp_queue = fd
+ self.__in_dtp_queue = fd
self.fs.close_cr(datacr)
- def ftp_APPE(self, file):
+
+ def ftp_APPE(self, line):
"""Append data to an existing file on the server."""
# watch for APPE preceded by REST, which makes no sense.
if self.restart_position:
- self.respond("450 Can't APPE while REST request is pending.")
+ self.respond("550 Can't APPE while REST request is pending.")
else:
- self.ftp_STOR(file, mode='a')
+ self.ftp_STOR(line, mode='a')
def ftp_REST(self, line):
"""Restart a file transfer from a previous mark."""
- if self.current_type == 'a':
- self.respond('501 Resuming transfers not allowed in ASCII mode.')
- return
try:
marker = int(line)
if marker < 0:
@@ -2531,7 +2357,9 @@ class FTPHandler(asynchat.async_chat):
except (ValueError, OverflowError):
self.respond("501 Invalid parameter.")
else:
- self.respond("350 Restarting at position %s." %marker)
+ self.respond("350 Restarting at position %s. " \
+ "Now use RETR/STOR for resuming." %marker)
+ self.log("OK REST %s." %marker)
self.restart_position = marker
def ftp_ABOR(self, line):
@@ -2542,7 +2370,7 @@ class FTPHandler(asynchat.async_chat):
resp = "225 No transfer to abort."
else:
# a PASV was received but connection wasn't made yet
- if self.data_server is not None:
+ if self.data_server:
self.data_server.close()
self.data_server = None
resp = "225 ABOR command successful; data channel closed."
@@ -2554,7 +2382,7 @@ class FTPHandler(asynchat.async_chat):
# was successfully processed.
# If no data has been transmitted we just respond with 225
# indicating that no transfer was in progress.
- if self.data_channel is not None:
+ if self.data_channel:
if self.data_channel.transfer_in_progress():
self.data_channel.close()
self.data_channel = None
@@ -2573,6 +2401,10 @@ class FTPHandler(asynchat.async_chat):
def ftp_USER(self, line):
"""Set the username for the current session."""
+ # we always treat anonymous user as lower-case string.
+ if line.lower() == "anonymous":
+ line = "anonymous"
+
# RFC-959 specifies a 530 response to the USER command if the
# username is not valid. If the username is valid is required
# ftpd returns a 331 response instead. In order to prevent a
@@ -2593,10 +2425,9 @@ class FTPHandler(asynchat.async_chat):
self.respond('331 %s, send password.' %msg)
self.username = line
- _auth_failed_timeout = 5
-
def ftp_PASS(self, line):
"""Check username's password against the authorizer."""
+
if self.authenticated:
self.respond("503 User already authenticated.")
return
@@ -2604,42 +2435,50 @@ class FTPHandler(asynchat.async_chat):
self.respond("503 Login with USER first.")
return
- def auth_failed(msg="Authentication failed."):
- if not self._closed:
+ # username ok
+ if self.authorizer.has_user(self.username):
+ if self.username == 'anonymous' \
+ or self.authorizer.validate_authentication(self.username, line):
+ msg_login = self.authorizer.get_msg_login(self.username)
+ if len(msg_login) <= 75:
+ self.respond('230 %s' %msg_login)
+ else:
+ self.push("230-%s\r\n" %msg_login)
+ self.respond("230 ")
+
+ self.authenticated = True
+ self.password = line
+ self.attempted_logins = 0
+ self.fs.root = self.authorizer.get_home_dir(self.username)
+ self.fs.username=self.username
+ self.fs.password=line
+ self.log("User %s logged in." %self.username)
+ else:
self.attempted_logins += 1
if self.attempted_logins >= self.max_login_attempts:
- msg = "530 " + msg + " Disconnecting."
- self.respond(msg)
- self.log(msg)
- self.close_when_done()
+ self.respond("530 Maximum login attempts. Disconnecting.")
+ self.close()
else:
- self.respond("530 " + msg)
- self.log(msg)
- self.sleeping = False
+ self.respond("530 Authentication failed.")
+ self.log('Authentication failed (user: "%s").' %self.username)
+ self.username = ""
- if self.authorizer.validate_authentication(self.username, line):
- msg_login = self.authorizer.get_msg_login(self.username)
- if len(msg_login) <= 75:
- self.respond('230 %s' %msg_login)
- else:
- self.push("230-%s\r\n" %msg_login)
- self.respond("230 ")
- self.authenticated = True
- self.password = line
- self.fs.username = self.username
- self.fs.password = line
- self.attempted_logins = 0
- self.fs.root = self.authorizer.get_home_dir(self.username)
- self.log("User %s logged in." %self.username)
+ # wrong username
else:
- self.username = ""
- self.fs.username = ""
- self.sleeping = True
- if self.username == 'anonymous':
- CallLater(self._auth_failed_timeout, auth_failed,
- "Anonymous access not allowed.")
+ self.attempted_logins += 1
+ if self.attempted_logins >= self.max_login_attempts:
+ self.log('Authentication failed: unknown username "%s".'
+ %self.username)
+ self.respond("530 Maximum login attempts. Disconnecting.")
+ self.close()
+ elif self.username.lower() == 'anonymous':
+ self.respond("530 Anonymous access not allowed.")
+ self.log('Authentication failed: anonymous access not allowed.')
else:
- CallLater(self._auth_failed_timeout, auth_failed)
+ self.respond("530 Authentication failed.")
+ self.log('Authentication failed: unknown username "%s".'
+ %self.username)
+ self.username = ""
def ftp_REIN(self, line):
"""Reinitialize user's current session."""
@@ -2665,6 +2504,9 @@ class FTPHandler(asynchat.async_chat):
def ftp_CWD(self, line):
"""Change the current working directory."""
+ # TODO: a lot of FTP servers go back to root directory if no
+ # arg is provided but this is not specified in RFC-959.
+ # Search for official references about this behaviour.
if not line:
line = '/'
datacr = None
@@ -2694,38 +2536,33 @@ class FTPHandler(asynchat.async_chat):
def ftp_SIZE(self, line):
"""Return size of file in a format suitable for using with
- RESTart as defined in RFC-3659."""
+ RESTart as defined in RFC-3659.
- # Implementation note: properly handling the SIZE command when
- # TYPE ASCII is used would require to scan the entire file to
- # perform the ASCII translation logic
- # (file.read().replace(os.linesep, '\r\n')) and then calculating
- # the len of such data which may be different than the actual
- # size of the file on the server. Considering that calculating
- # such result could be very resource-intensive and also dangerous
- # (DoS) we reject SIZE when the current TYPE is ASCII.
- # However, clients in general should not be resuming downloads
- # in ASCII mode. Resuming downloads in binary mode is the
- # recommended way as specified in RFC-3659.
-
- if self.current_type == 'a':
- why = "SIZE not allowed in ASCII mode"
- self.log('FAIL SIZE "%s". %s.' %(line, why))
- self.respond("550 %s." %why)
- return
- datacr = False
+ Implementation note:
+ properly handling the SIZE command when TYPE ASCII is used would
+ require to scan the entire file to perform the ASCII translation
+ logic (file.read().replace(os.linesep, '\r\n')) and then
+ calculating the len of such data which may be different than
+ the actual size of the file on the server. Considering that
+ calculating such result could be very resource-intensive it
+ could be easy for a malicious client to try a DoS attack, thus
+ we do not perform the ASCII translation.
+
+ However, clients in general should not be resuming downloads in
+ ASCII mode. Resuming downloads in binary mode is the recommended
+ way as specified in RFC-3659.
+ """
+ datacr = None
try:
datacr = self.fs.get_cr(line)
path = self.fs.ftp2fs(line, datacr)
line = self.fs.ftpnorm(line)
- if not self.fs.isfile(self.fs.realpath(path)):
+ if self.fs.isdir(path):
why = "%s is not retrievable" %line
self.log('FAIL SIZE "%s". %s.' %(line, why))
self.respond("550 %s." %why)
- self.fs.close_cr(datacr)
return
size = self.run_as_current_user(self.fs.getsize, path)
- size = self.run_as_current_user(self.fs.getsize, path)
except OSError, err:
why = _strerror(err)
self.log('FAIL SIZE "%s". %s.' %(line, why))
@@ -2739,7 +2576,7 @@ class FTPHandler(asynchat.async_chat):
"""Return last modification time of file to the client as an ISO
3307 style timestamp (YYYYMMDDHHMMSS) as defined in RFC-3659.
"""
- datacr = None
+ datacr = None
try:
datacr = self.fs.get_cr(line)
path = self.fs.ftp2fs(line, datacr)
@@ -2750,23 +2587,17 @@ class FTPHandler(asynchat.async_chat):
self.respond("550 %s." %why)
self.fs.close_cr(datacr)
return
- secs = self.run_as_current_user(self.fs.getmtime, path)
- lmt = self.run_as_current_user(self.fs.getmtime, path)
-
- except (OSError, ValueError), err:
- if isinstance(err, OSError):
- why = _strerror(err)
- else:
- # It could happen if file's last modification time
- # happens to be too old (prior to year 1900)
- why = "Can't determine file's last modification time"
+ lmt = self.run_as_current_user(self.fs.getmtime, path)
+ except OSError, err:
+ why = _strerror(err)
self.log('FAIL MDTM "%s". %s.' %(line, why))
self.respond('550 %s.' %why)
else:
+ lmt = time.strftime("%Y%m%d%H%M%S", time.localtime(lmt))
self.respond("213 %s" %lmt)
self.log('OK MDTM "%s".' %line)
self.fs.close_cr(datacr)
-
+
def ftp_MKD(self, line):
"""Create the specified directory."""
datacr = None
@@ -2782,15 +2613,12 @@ class FTPHandler(asynchat.async_chat):
self.respond('550 %s.' %why)
else:
self.log('OK MKD "%s".' %line)
- # The 257 response is supposed to include the directory
- # name and in case it contains embedded double-quotes
- # they must be doubled (see RFC-959, chapter 7, appendix 2).
- self.respond('257 "%s" directory created.' %line.replace('"', '""'))
+ self.respond("257 Directory created.")
self.fs.close_cr(datacr)
def ftp_RMD(self, line):
"""Remove the specified directory."""
- datacr = False
+ datacr = None
try:
datacr = self.fs.get_cr(line)
path = self.fs.ftp2fs(line, datacr)
@@ -2801,7 +2629,7 @@ class FTPHandler(asynchat.async_chat):
self.log('FAIL MKD "/". %s' %msg)
self.fs.close_cr(datacr)
return
- self.run_as_current_user(self.fs.rmdir, path)
+ self.run_as_current_user(self.fs.rmdir, path)
except OSError, err:
why = _strerror(err)
self.log('FAIL RMD "%s". %s.' %(line, why))
@@ -2810,7 +2638,7 @@ class FTPHandler(asynchat.async_chat):
self.log('OK RMD "%s".' %line)
self.respond("250 Directory removed.")
self.fs.close_cr(datacr)
-
+
def ftp_DELE(self, line):
"""Delete the specified file."""
datacr = None
@@ -2827,11 +2655,10 @@ class FTPHandler(asynchat.async_chat):
self.log('OK DELE "%s".' %line)
self.respond("250 File removed.")
self.fs.close_cr(datacr)
-
+
def ftp_RNFR(self, line):
"""Rename the specified (only the source name is specified
here, see RNTO command)"""
-
datacr = None
try:
datacr = self.fs.get_cr(line)
@@ -2855,7 +2682,7 @@ class FTPHandler(asynchat.async_chat):
if not self.fs.rnfr:
self.respond("503 Bad sequence of commands: use RNFR first.")
return
- datacr = None
+ datacr = None
try:
try:
datacr = self.fs.get_cr(line)
@@ -2878,50 +2705,35 @@ class FTPHandler(asynchat.async_chat):
self.fs.close_cr(datacr)
-
# --- others
def ftp_TYPE(self, line):
"""Set current type data type to binary/ascii"""
- type = line.upper().replace(' ', '')
- if type in ("A", "L7"):
+ line = line.upper()
+ if line in ("A", "AN", "A N"):
self.respond("200 Type set to: ASCII.")
self.current_type = 'a'
- elif type in ("I", "L8"):
+ elif line in ("I", "L8", "L 8"):
self.respond("200 Type set to: Binary.")
self.current_type = 'i'
else:
self.respond('504 Unsupported type "%s".' %line)
def ftp_STRU(self, line):
- """Set file structure ("F" is the only one supported (noop))."""
- stru = line.upper()
- if stru == 'F':
+ """Set file structure (obsolete)."""
+ # obsolete (backward compatibility with older ftp clients)
+ if line in ('f','F'):
self.respond('200 File transfer structure set to: F.')
- elif stru in ('P', 'R'):
- # R is required in minimum implementations by RFC-959, 5.1.
- # RFC-1123, 4.1.2.13, amends this to only apply to servers
- # whose file systems support record structures, but also
- # suggests that such a server "may still accept files with
- # STRU R, recording the byte stream literally".
- # Should we accept R but with no operational difference from
- # F? proftpd and wu-ftpd don't accept STRU R. We just do
- # the same.
- #
- # RFC-1123 recommends against implementing P.
- self.respond('504 Unimplemented STRU type.')
else:
- self.respond('501 Unrecognized STRU type.')
+ self.respond('504 Unimplemented STRU type.')
def ftp_MODE(self, line):
- """Set data transfer mode ("S" is the only one supported (noop))."""
- mode = line.upper()
- if mode == 'S':
+ """Set data transfer mode (obsolete)"""
+ # obsolete (backward compatibility with older ftp clients)
+ if line in ('s', 'S'):
self.respond('200 Transfer mode set to: S')
- elif mode in ('B', 'C'):
- self.respond('504 Unimplemented MODE type.')
else:
- self.respond('501 Unrecognized MODE type.')
+ self.respond('504 Unimplemented MODE type.')
def ftp_STAT(self, line):
"""Return statistics about current ftp session. If an argument
@@ -2929,15 +2741,17 @@ class FTPHandler(asynchat.async_chat):
Implementation note:
- RFC-959 does not explicitly mention globbing but many FTP
- servers do support it as a measure of convenience for FTP
- clients and users.
+ RFC-959 do not explicitly mention globbing; this means that FTP
+ servers are not required to support globbing in order to be
+ compliant. However, many FTP servers do support globbing as a
+ measure of convenience for FTP clients and users.
In order to search for and match the given globbing expression,
the code has to search (possibly) many directories, examine
each contained filename, and build a list of matching files in
memory. Since this operation can be quite intensive, both CPU-
- and memory-wise, we do not support globbing.
+ and memory-wise, we limit the search to only one directory
+ non-recursively, as LIST does.
"""
# return STATus information about ftpd
if not line:
@@ -2955,9 +2769,9 @@ class FTPHandler(asynchat.async_chat):
else:
type = 'Binary'
s.append("TYPE: %s; STRUcture: File; MODE: Stream" %type)
- if self.data_server is not None:
+ if self.data_server:
s.append('Passive data channel waiting for connection.')
- elif self.data_channel is not None:
+ elif self.data_channel:
bytes_sent = self.data_channel.tot_bytes_sent
bytes_recv = self.data_channel.tot_bytes_received
s.append('Data connection open:')
@@ -2976,22 +2790,19 @@ class FTPHandler(asynchat.async_chat):
datacr = self.fs.get_cr(line)
iterator = self.run_as_current_user(self.fs.get_stat_dir, line, datacr)
except OSError, err:
- why = _strerror(err)
- self.log('FAIL STAT "%s". %s.' %(line, why))
- self.respond('550 %s.' %why)
+ self.respond('550 %s.' %_strerror(err))
else:
- self.push('213-Status of "%s":\r\n' %line)
+ self.push('213-Status of "%s":\r\n' %self.fs.ftpnorm(line))
self.push_with_producer(BufferedIteratorProducer(iterator))
self.respond('213 End of status.')
self.fs.close_cr(datacr)
-
+
def ftp_FEAT(self, line):
"""List all new features supported as defined in RFC-2398."""
features = ['EPRT','EPSV','MDTM','MLSD','REST STREAM','SIZE','TVFS']
- features.extend(self._extra_feats)
s = ''
- for fact in self._available_facts:
- if fact in self._current_facts:
+ for fact in self.available_facts:
+ if fact in self.current_facts:
s += fact + '*;'
else:
s += fact + ';'
@@ -3016,8 +2827,8 @@ class FTPHandler(asynchat.async_chat):
self.respond('501 %s.' %err)
else:
facts = [x.lower() for x in arg.split(';')]
- self._current_facts = [x for x in facts if x in self._available_facts]
- f = ''.join([x + ';' for x in self._current_facts])
+ self.current_facts = [x for x in facts if x in self.available_facts]
+ f = ''.join([x + ';' for x in self.current_facts])
self.respond('200 MLST OPTS ' + f)
def ftp_NOOP(self, line):
@@ -3034,23 +2845,22 @@ class FTPHandler(asynchat.async_chat):
self.respond("215 UNIX Type: L8")
def ftp_ALLO(self, line):
- """Allocate bytes for storage (noop)."""
- # not necessary (always respond with 202)
+ """Allocate bytes for storage (obsolete)."""
+ # obsolete (always respond with 202)
self.respond("202 No storage allocation necessary.")
def ftp_HELP(self, line):
"""Return help text to the client."""
if line:
- line = line.upper()
- if line in proto_cmds:
- self.respond("214 %s" %proto_cmds[line].help)
+ if line.upper() in proto_cmds:
+ self.respond("214 %s" %proto_cmds[line.upper()])
else:
self.respond("501 Unrecognized command.")
else:
# provide a compact list of recognized commands
def formatted_help():
cmds = []
- keys = [x for x in proto_cmds.keys() if not x.startswith('SITE ')]
+ keys = proto_cmds.keys()
keys.sort()
while keys:
elems = tuple((keys[0:8]))
@@ -3062,30 +2872,6 @@ class FTPHandler(asynchat.async_chat):
self.push(formatted_help())
self.respond("214 Help command successful.")
- # --- site commands
-
- # No SITE commands aside from SITE HELP are implemented by default.
- # The user willing to add support for a specific SITE command has
- # to define a new ftp_SITE_%CMD% method in the subclass.
-
- def ftp_SITE_HELP(self, line):
- """Return help text to the client for a given SITE command."""
- if line:
- line = line.upper()
- if line in proto_cmds:
- self.respond("214 %s" %proto_cmds[line].help)
- else:
- self.respond("501 Unrecognized SITE command.")
- else:
- self.push("214-The following SITE commands are recognized:\r\n")
- site_cmds = []
- keys = proto_cmds.keys()
- keys.sort()
- for cmd in keys:
- if cmd.startswith('SITE '):
- site_cmds.append(' %s\r\n' %cmd[5:])
- self.push(''.join(site_cmds))
- self.respond("214 Help SITE command successful.")
# --- support for deprecated cmds
@@ -3186,50 +2972,43 @@ class FTPServer(asyncore.dispatcher):
return
asyncore.dispatcher.set_reuse_addr(self)
- def serve_forever(self, timeout=1, use_poll=False, map=None, count=None):
+ def serve_forever(self, **kwargs):
"""A wrap around asyncore.loop(); starts the asyncore polling
- loop including running the scheduler.
- The arguments are the same expected by original asyncore.loop()
- function.
+ loop.
+
+ The keyword arguments in kwargs are the same expected by
+ asyncore.loop() function: timeout, use_poll, map and count.
"""
- if map is None:
- map = asyncore.socket_map
- # backward compatibility for python versions < 2.4
+ if not 'count' in kwargs:
+ log("Serving FTP on %s:%s" %self.socket.getsockname()[:2])
+
+ # backward compatibility for python < 2.4
if not hasattr(self, '_map'):
+ if not 'map' in kwargs:
+ map = asyncore.socket_map
+ else:
+ map = kwargs['map']
self._map = self.handler._map = map
- if use_poll and hasattr(asyncore.select, 'poll'):
- poll_fun = asyncore.poll2
- else:
- poll_fun = asyncore.poll
-
- if count is None:
- log("Serving FTP on %s:%s" %self.socket.getsockname()[:2])
- try:
- while map or _tasks:
- if map:
- poll_fun(timeout, map)
- if _tasks:
- _scheduler()
- except (KeyboardInterrupt, SystemExit, asyncore.ExitNow):
- log("Shutting down FTP server.")
- self.close_all()
- else:
- while (map or _tasks) and count > 0:
- if map:
- poll_fun(timeout, map)
- if _tasks:
- _scheduler()
- count = count - 1
+ try:
+ # FIX #16, #26
+ # use_poll specifies whether to use select module's poll()
+ # with asyncore or whether to use asyncore's own poll()
+ # method Python versions < 2.4 need use_poll set to False
+ # This breaks on OS X systems if use_poll is set to True.
+ # All systems seem to work fine with it set to False
+ # (tested on Linux, Windows, and OS X platforms)
+ if kwargs:
+ asyncore.loop(**kwargs)
+ else:
+ asyncore.loop(timeout=1.0, use_poll=False)
+ except (KeyboardInterrupt, SystemExit, asyncore.ExitNow):
+ log("Shutting down FTPd.")
+ self.close_all()
def handle_accept(self):
"""Called when remote client initiates a connection."""
- try:
- sock_obj, addr = self.accept()
- except TypeError:
- # for some reason sometimes accept() returns None instead
- # of a socket
- return
+ sock_obj, addr = self.accept()
log("[]%s:%s Connected." %addr[:2])
handler = self.handler(sock_obj, self)
@@ -3268,7 +3047,7 @@ class FTPServer(asyncore.dispatcher):
self.close()
def close_all(self, map=None, ignore_all=False):
- """Stop serving and also disconnects all currently connected
+ """Stop serving; close all existent connections disconnecting
clients.
- (dict) map:
@@ -3281,11 +3060,13 @@ class FTPServer(asyncore.dispatcher):
Implementation note:
- This is how asyncore.close_all() is implemented starting from
+ Instead of using the current asyncore.close_all() function
+ which only close sockets, we iterate over all existent channels
+ calling close() method for each one of them, avoiding memory
+ leaks.
+
+ This is how asyncore.close_all() function should work in
Python 2.6.
- The previous versions of close_all() instead of iteratating over
- all opened channels and calling close() method for each one
- of them only closed sockets generating memory leaks.
"""
if map is None:
map = self._map
@@ -3307,13 +3088,15 @@ class FTPServer(asyncore.dispatcher):
def test():
# cmd line usage (provide a read-only anonymous ftp server):
- # python -m pyftpdlib.ftpserver
+ # python -m pyftpdlib.FTPServer
authorizer = DummyAuthorizer()
- authorizer.add_anonymous(os.getcwd())
+ authorizer.add_anonymous(os.getcwd(), perm='elradfmw')
FTPHandler.authorizer = authorizer
- address = ('', 21)
+ address = ('', 8021)
ftpd = FTPServer(address, FTPHandler)
ftpd.serve_forever()
if __name__ == '__main__':
test()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
new file mode 100644
index 00000000000..19efe97c7c1
--- /dev/null
+++ b/addons/document/nodes.py
@@ -0,0 +1,776 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import base64
+
+from osv import osv, fields
+from osv.orm import except_orm
+import urlparse
+import pooler
+from tools.safe_eval import safe_eval
+
+import os
+import time
+
+#
+# An object that represent an uri
+# path: the uri of the object
+# content: the Content it belongs to (_print.pdf)
+# type: content or collection
+# content: objct = res.partner
+# collection: object = directory, object2 = res.partner
+# file: objct = ir.attachement
+# root: if we are at the first directory of a ressource
+#
+
+def get_node_context(cr, uid, context):
+ return node_context(cr,uid,context)
+
+class node_context(object):
+ """ This is the root node, representing access to some particular
+ context """
+ cached_roots = {}
+
+ def __init__(self, cr, uid, context=None):
+ # we don't cache the cr!
+ #self.cr = cr
+ self.uid = uid
+ self.context = context
+ self._dirobj = pooler.get_pool(cr.dbname).get('document.directory')
+ assert self._dirobj
+ self.rootdir = self._dirobj._get_root_directory(cr,uid,context)
+
+ def get_uri(self, cr, uri):
+ """ Although this fn passes back to doc.dir, it is needed since
+ it is a potential caching point """
+
+ (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
+
+ while duri:
+ ndir = ndir.child(cr, duri[0])
+ if not ndir:
+ return False
+ duri = duri[1:]
+ return ndir
+
+
+class node_database():
+ """ A node representing the database directory
+ Useless?
+ """
+ def __init__(self,ncontext):
+ self.nctx = ncontext
+
+
+
+
+class node_class(object):
+ """ this is a superclass for our inodes
+ It is an API for all code that wants to access the document files.
+ Nodes have attributes which contain usual file properties
+ """
+ our_type = 'baseclass'
+ def __init__(self, path, parent, context):
+ assert isinstance(context,node_context)
+ assert (not parent ) or isinstance(parent,node_class)
+ self.path = path
+ self.context = context
+ self.type=self.our_type
+ self.parent = parent
+ self.mimetype = 'application/octet-stream'
+ self.create_date = None
+ self.write_date = None
+ self.content_length = 0
+ # dynamic context:
+ self.dctx = {}
+ if parent:
+ self.dctx = parent.dctx.copy()
+ self.displayname = 'Object'
+
+ def full_path(self):
+ if self.parent:
+ s = self.parent.full_path()
+ else:
+ s = []
+ if isinstance(self.path,list):
+ s+=self.path
+ else:
+ s.append(self.path)
+ return s
+
+ def children(self, cr):
+ print "node_class.children()"
+ return [] #stub
+
+ def child(self,cr, name):
+ print "node_class.child()"
+ return None
+
+ def path_get(self):
+ print "node_class.path_get()"
+ return False
+
+ def get_data(self,cr):
+ raise TypeError('no data for %s'% self.type)
+
+ def _get_storage(self,cr):
+ raise RuntimeError("no storage for base class")
+
+ def get_etag(self,cr):
+ """ Get a tag, unique per object + modification.
+
+ see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
+ return self._get_ttag(cr) + ':' + self._get_wtag(cr)
+
+ def _get_wtag(self,cr):
+ """ Return the modification time as a unique, compact string """
+ if self.write_date:
+ wtime = time.mktime(time.strptime(self.write_date,'%Y-%m-%d %H:%M:%S'))
+ else: wtime = time.time()
+ return str(wtime)
+
+ def _get_ttag(self,cr):
+ """ Get a unique tag for this type/id of object.
+ Must be overriden, so that each node is uniquely identified.
+ """
+ print "node_class.get_ttag()",self
+ raise RuntimeError("get_etag stub()")
+
+ def get_dav_props(self, cr):
+ """ If this class has special behaviour for GroupDAV etc, export
+ its capabilities """
+ return {}
+
+ def get_dav_eprop(self,cr,ns,prop):
+ return None
+
+class node_dir(node_class):
+ our_type = 'collection'
+ def __init__(self,path, parent, context, dirr, dctx=None):
+ super(node_dir,self).__init__(path, parent,context)
+ self.dir_id = dirr.id
+ #todo: more info from dirr
+ self.mimetype = 'application/x-directory'
+ # 'httpd/unix-directory'
+ self.create_date = dirr.create_date
+ # TODO: the write date should be MAX(file.write)..
+ self.write_date = dirr.write_date or dirr.create_date
+ self.content_length = 0
+ if dctx:
+ self.dctx.update(dctx)
+ dc2 = self.context.context
+ dc2.update(self.dctx)
+ dc2['dir_id'] = self.dir_id
+ self.displayname = dirr.name
+ for dfld in dirr.dctx_ids:
+ try:
+ self.dctx['dctx_' + dfld.field] = safe_eval(dfld.expr,dc2)
+ except Exception,e:
+ print "Cannot eval %s" % dfld.expr
+ print e
+ pass
+
+ def children(self,cr):
+ return self._child_get(cr) + self._file_get(cr)
+
+ def child(self,cr, name):
+ res = self._child_get(cr,name)
+ if res:
+ return res[0]
+ res = self._file_get(cr,name)
+ if res:
+ return res[0]
+ return None
+
+ def _file_get(self,cr, nodename=False):
+ res = []
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
+ for content in cntobj.browse(cr,uid,ids,context=ctx):
+ res3 = cntobj._file_get(cr,self,nodename,content)
+ if res3:
+ res.extend(res3)
+
+ return res
+
+ def get_dav_props(self, cr):
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
+ for content in cntobj.browse(cr,uid,ids,context=ctx):
+ if content.extension == '.ics': # FIXME: call the content class!
+ res['http://groupdav.org/'] = ('resourcetype',)
+ break
+ return res
+
+ def get_dav_eprop(self,cr,ns,prop):
+ if ns != 'http://groupdav.org/' or prop != 'resourcetype':
+ print "Who asked for %s:%s?" % (ns,prop)
+ return None
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
+ for content in cntobj.browse(cr,uid,ids,context=ctx):
+ if content.extension == '.ics': # FIXME: call the content class!
+ return ('vevent-collection','http://groupdav.org/')
+ return None
+
+ def _child_get(self,cr,name = None):
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('parent_id','=',self.dir_id) ]
+ if name:
+ where.append(('name','=',name))
+ ids = dirobj.search(cr, uid, where,context=ctx)
+ res = []
+ if ids:
+ for dirr in dirobj.browse(cr,uid,ids,context=ctx):
+ if dirr.type == 'directory':
+ res.append(node_dir(dirr.name,self,self.context,dirr))
+ elif dirr.type == 'ressource':
+ res.append(node_res_dir(dirr.name,self,self.context,dirr))
+
+ fil_obj=dirobj.pool.get('ir.attachment')
+ #where2 = where # + [('res_model', '=', None)]
+ ids = fil_obj.search(cr,uid,where,context=ctx)
+ if ids:
+ for fil in fil_obj.browse(cr,uid,ids,context=ctx):
+ res.append(node_file(fil.name,self,self.context,fil))
+
+ return res
+
+ def create_child(self,cr,path,data):
+ """ API function to create a child file object and node
+ Return the node_* created
+ """
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ fil_obj=dirobj.pool.get('ir.attachment')
+ val = {
+ 'name': path,
+ 'datas_fname': path,
+ 'parent_id': self.dir_id,
+ # Datas are not set here
+ }
+
+ fil_id = fil_obj.create(cr,uid, val, context=ctx)
+ fil = fil_obj.browse(cr,uid,fil_id,context=ctx)
+ fnode = node_file(path,self,self.context,fil)
+ fnode.set_data(cr,data,fil)
+ return fnode
+
+ def _get_ttag(self,cr):
+ return 'dir-%d' % self.dir_id
+
+class node_res_dir(node_class):
+ """ A special sibling to node_dir, which does only contain dynamically
+ created folders foreach resource in the foreign model.
+ All folders should be of type node_res_obj and merely behave like
+ node_dirs (with limited domain).
+ """
+ our_type = 'collection'
+ def __init__(self,path, parent, context, dirr, dctx=None ):
+ super(node_res_dir,self).__init__(path, parent,context)
+ self.dir_id = dirr.id
+ #todo: more info from dirr
+ self.mimetype = 'application/x-directory'
+ # 'httpd/unix-directory'
+ self.create_date = dirr.create_date
+ # TODO: the write date should be MAX(file.write)..
+ self.write_date = dirr.write_date or dirr.create_date
+ self.content_length = 0
+ self.res_model = dirr.ressource_type_id.model
+ self.resm_id = dirr.ressource_id
+ self.namefield = dirr.resource_field or 'name'
+ self.displayname = dirr.name
+ # Important: the domain is evaluated using the *parent* dctx!
+ self.domain = safe_eval(dirr.domain,self.dctx)
+ # and then, we add our own vars in the dctx:
+ if dctx:
+ self.dctx.update(dctx)
+
+ # and then, we prepare a dctx dict, for deferred evaluation:
+ self.dctx_dict = {}
+ for dfld in dirr.dctx_ids:
+ self.dctx_dict['dctx_' + dfld.field] = dfld.expr
+
+ def children(self,cr):
+ return self._child_get(cr)
+
+ def child(self,cr, name):
+ res = self._child_get(cr,name)
+ if res:
+ return res[0]
+ return None
+
+ def _child_get(self,cr,name = None):
+ """ return virtual children of resource, based on the
+ foreign object.
+
+ Note that many objects use NULL for a name, so we should
+ better call the name_search(),name_get() set of methods
+ """
+ obj = self.context._dirobj.pool.get(self.res_model)
+ if not obj:
+ print "couldn't find model", self.res_model
+ return []
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = []
+ if self.domain:
+ where.append(self.domain)
+ if self.resm_id:
+ where.append(('id','=',self.resm_id))
+
+ if name:
+ where.append((self.namefield,'=',name))
+ # print "Where clause for %s" % self.res_model, where
+
+ resids = obj.search(cr,uid, where, context=ctx)
+ res = []
+ for bo in obj.browse(cr,uid,resids,context=ctx):
+ if not bo:
+ continue
+ name = getattr(bo,self.namefield)
+ if not name:
+ continue
+ # Yes! we can't do better but skip nameless records.
+ res.append(node_res_obj(name,self,self.context,self.res_model, bo))
+ return res
+
+ def _get_ttag(self,cr):
+ return 'rdir-%d' % self.dir_id
+
+class node_res_obj(node_class):
+ """ A special sibling to node_dir, which does only contain dynamically
+ created folders foreach resource in the foreign model.
+ All folders should be of type node_res_obj and merely behave like
+ node_dirs (with limited domain).
+ """
+ our_type = 'collection'
+ def __init__(self,path, parent, context, res_model, res_bo, res_id = None):
+ super(node_res_obj,self).__init__(path, parent,context)
+ assert parent
+ #todo: more info from dirr
+ self.dir_id = parent.dir_id
+ self.mimetype = 'application/x-directory'
+ # 'httpd/unix-directory'
+ self.create_date = parent.create_date
+ # TODO: the write date should be MAX(file.write)..
+ self.write_date = parent.write_date
+ self.content_length = 0
+ self.res_model = res_model
+ self.domain = parent.domain
+ self.displayname = path
+
+ if res_bo:
+ self.res_id = res_bo.id
+ dc2 = self.context.context
+ dc2.update(self.dctx)
+ dc2['res_model'] = res_model
+ dc2['res_id'] = res_bo.id
+ dc2['this'] = res_bo
+ for fld,expr in parent.dctx_dict.items():
+ try:
+ self.dctx[fld] = safe_eval(expr,dc2)
+ except Exception,e:
+ print "Cannot eval %s for %s" % (expr, fld)
+ print e
+ pass
+ else:
+ self.res_id = res_id
+
+ def children(self,cr):
+ return self._child_get(cr) + self._file_get(cr)
+
+ def child(self,cr, name):
+ res = self._child_get(cr,name)
+ if res:
+ return res[0]
+ res = self._file_get(cr,name)
+ if res:
+ return res[0]
+ return None
+
+ def _file_get(self,cr, nodename=False):
+ res = []
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ #if self.domain:
+ # where.extend(self.domain)
+ # print "res_obj file_get clause", where
+ ids = cntobj.search(cr,uid,where,context=ctx)
+ for content in cntobj.browse(cr,uid,ids,context=ctx):
+ res3 = cntobj._file_get(cr,self,nodename,content, context=ctx)
+ if res3:
+ res.extend(res3)
+
+ return res
+
+ def get_dav_props(self, cr):
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
+ for content in cntobj.browse(cr,uid,ids,context=ctx):
+ if content.extension == '.ics': # FIXME: call the content class!
+ res['http://groupdav.org/'] = ('resourcetype',)
+ return res
+
+ def get_dav_eprop(self,cr,ns,prop):
+ if ns != 'http://groupdav.org/' or prop != 'resourcetype':
+ print "Who asked for %s:%s?" % (ns,prop)
+ return None
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
+ for content in cntobj.browse(cr,uid,ids,context=ctx):
+ if content.extension == '.ics': # FIXME: call the content class!
+ return ('vevent-collection','http://groupdav.org/')
+ return None
+
+ def _child_get(self,cr,name = None):
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('parent_id','=',self.dir_id) ]
+ if name:
+ where.append(('name','=',name))
+ ids = dirobj.search(cr, uid, where,context=ctx)
+ res = []
+ if ids:
+ for dirr in dirobj.browse(cr,uid,ids,context=ctx):
+ if dirr.type == 'directory':
+ res.append(node_res_obj(dirr.name,self,self.context,self.res_model,res_bo = None, res_id = self.res_id))
+ elif dirr.type == 'ressource':
+ # child resources can be controlled by properly set dctx
+ res.append(node_res_dir(dirr.name,self,self.context,dirr))
+
+ fil_obj=dirobj.pool.get('ir.attachment')
+ where2 = where + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)]
+ # print "where clause for dir_obj", where2
+ ids = fil_obj.search(cr,uid,where2,context=ctx)
+ if ids:
+ for fil in fil_obj.browse(cr,uid,ids,context=ctx):
+ res.append(node_file(fil.name,self,self.context,fil))
+
+ return res
+
+ def create_child(self,cr,path,data):
+ """ API function to create a child file object and node
+ Return the node_* created
+ """
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ fil_obj=dirobj.pool.get('ir.attachment')
+ val = {
+ 'name': path,
+ 'datas_fname': path,
+ 'parent_id': self.dir_id,
+ 'res_model': self.res_model,
+ 'res_id': self.res_id,
+ # Datas are not set here
+ }
+
+ fil_id = fil_obj.create(cr,uid, val, context=ctx)
+ fil = fil_obj.browse(cr,uid,fil_id,context=ctx)
+ fnode = node_file(path,self,self.context,fil)
+ fnode.set_data(cr,data,fil)
+ return fnode
+
+ def _get_ttag(self,cr):
+ return 'rodir-%d-%d' % (self.dir_id,self.res_id)
+
+class node_file(node_class):
+ our_type = 'file'
+ def __init__(self,path, parent, context, fil):
+ super(node_file,self).__init__(path, parent,context)
+ self.file_id = fil.id
+ #todo: more info from ir_attachment
+ if fil.file_type and '/' in fil.file_type:
+ self.mimetype = fil.file_type
+ self.create_date = fil.create_date
+ self.write_date = fil.write_date or fil.create_date
+ self.content_length = fil.file_size
+ self.displayname = fil.name
+
+ # This only propagates the problem to get_data. Better
+ # fix those files to point to the root dir.
+ if fil.parent_id:
+ self.storage_id = fil.parent_id.storage_id.id
+ else:
+ self.storage_id = None
+
+ def get_data(self, cr, fil_obj = None):
+ """ Retrieve the data for some file.
+ fil_obj may optionally be specified, and should be a browse object
+ for the file. This is useful when the caller has already initiated
+ the browse object. """
+ # this is where storage kicks in..
+ stor = self.storage_id
+ assert stor
+ stobj = self.context._dirobj.pool.get('document.storage')
+ return stobj.get_data(cr,self.context.uid,stor, self,self.context.context, fil_obj)
+
+ def get_data_len(self, cr, fil_obj = None):
+ # TODO: verify with the storage object!
+ return self.content_length
+
+ def set_data(self, cr, data, fil_obj = None):
+ """ Store data at some file.
+ fil_obj may optionally be specified, and should be a browse object
+ for the file. This is useful when the caller has already initiated
+ the browse object. """
+ # this is where storage kicks in..
+ stor = self.storage_id
+ assert stor
+ stobj = self.context._dirobj.pool.get('document.storage')
+ return stobj.set_data(cr,self.context.uid,stor, self, data, self.context.context, fil_obj)
+
+ def _get_ttag(self,cr):
+ return 'file-%d' % self.file_id
+
+class node_content(node_class):
+ our_type = 'content'
+ def __init__(self,path, parent, context, cnt, dctx = None, act_id=None):
+ super(node_content,self).__init__(path, parent,context)
+ self.cnt_id = cnt.id
+ self.create_date = False
+ self.write_date = False
+ self.content_length = False
+ self.extension = cnt.extension
+ self.report_id = cnt.report_id and cnt.report_id.id
+ #self.mimetype = cnt.extension.
+ self.displayname = path
+ if dctx:
+ self.dctx.update(dctx)
+ self.act_id = act_id
+
+ def fill_fields(self,cr,dctx = None):
+ """ Try to read the object and fill missing fields, like mimetype,
+ dates etc.
+ This function must be different from the constructor, because
+ it uses the db cursor.
+ """
+
+ cr.execute('SELECT DISTINCT mimetype FROM document_directory_content_type WHERE active AND code = %s;',
+ (self.extension,))
+ res = cr.fetchall()
+ if res and res[0][0]:
+ self.mimetype = res[0][0]
+
+
+ def get_data(self, cr, fil_obj = None):
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ data = cntobj.process_read(cr,self.context.uid,self,ctx)
+ if data:
+ self.content_length = len(data)
+ return data
+
+ def get_data_len(self, cr, fil_obj = None):
+ if not self.content_length:
+ self.get_data(cr,fil_obj)
+ return self.content_length
+
+ def set_data(self, cr, data, fil_obj = None):
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ return cntobj.process_write(cr,self.context.uid,self, data,ctx)
+
+ def _get_ttag(self,cr):
+ return 'cnt-%d%s' % (self.cnt_id,(self.act_id and ('-' + str(self.act_id))) or '')
+
+class old_class():
+ # the old code, remove..
+ def __init__(self, cr, uid, path, object, object2=False, context={}, content=False, type='collection', root=False):
+ self.cr = cr
+ def _file_get(self, nodename=False):
+ if not self.object:
+ return []
+ pool = pooler.get_pool(self.cr.dbname)
+ fobj = pool.get('ir.attachment')
+ res2 = []
+ where = []
+ if self.object2:
+ where.append( ('res_model','=',self.object2._name) )
+ where.append( ('res_id','=',self.object2.id) )
+ else:
+ where.append( ('parent_id','=',self.object.id) )
+ where.append( ('res_id','=',False) )
+ if nodename:
+ where.append( (fobj._rec_name,'=',nodename) )
+ for content in self.object.content_ids:
+ res3 = content._table._file_get(self,nodename,content)
+ if res3:
+ res2.extend(res3)
+
+ ids = fobj.search(self.cr, self.uid, where+[ ('parent_id','=',self.object and self.object.id or False) ])
+ if self.object and self.root and (self.object.type=='ressource'):
+ ids += fobj.search(self.cr, self.uid, where+[ ('parent_id','=',False) ])
+ res = fobj.browse(self.cr, self.uid, ids, context=self.context)
+ return map(lambda x: node_class(self.cr, self.uid, self.path+'/'+eval('x.'+fobj._rec_name), x, False, context=self.context, type='file', root=False), res) + res2
+
+ def get_translation(self,value,lang):
+ # Must go, it works on arbitrary models and could be ambiguous.
+ result = value
+ pool = pooler.get_pool(self.cr.dbname)
+ translation_ids = pool.get('ir.translation').search(self.cr, self.uid, [('value','=',value),('lang','=',lang),('type','=','model')])
+ if len(translation_ids):
+ tran_id = translation_ids[0]
+ translation = pool.get('ir.translation').read(self.cr, self.uid, tran_id, ['res_id','name'])
+ res_model,field_name = tuple(translation['name'].split(','))
+ res_id = translation['res_id']
+ res = pool.get(res_model).read(self.cr, self.uid, res_id, [field_name])
+ if res:
+ result = res[field_name]
+ return result
+
+ def directory_list_for_child(self,nodename,parent=False):
+ pool = pooler.get_pool(self.cr.dbname)
+ where = []
+ if nodename:
+ nodename = self.get_translation(nodename, self.context['lang'])
+ where.append(('name','=',nodename))
+ if (self.object and self.object.type=='directory') or not self.object2:
+ where.append(('parent_id','=',self.object and self.object.id or False))
+ else:
+ where.append(('parent_id','=',False))
+ if self.object:
+ where.append(('ressource_parent_type_id','=',self.object.ressource_type_id.id))
+ else:
+ where.append(('ressource_parent_type_id','=',False))
+
+ ids = pool.get('document.directory').search(self.cr, self.uid, where+[('ressource_id','=',0)])
+ if self.object2:
+ ids += pool.get('document.directory').search(self.cr, self.uid, where+[('ressource_id','=',self.object2.id)])
+ res = pool.get('document.directory').browse(self.cr, self.uid, ids, self.context)
+ return res
+
+ def _child_get(self, nodename=False):
+ if self.type not in ('collection','database'):
+ return []
+ res = self.directory_list_for_child(nodename)
+ result= map(lambda x: node_class(self.cr, self.uid, self.path+'/'+x.name, x, x.type=='directory' and self.object2 or False, context=self.context, root=self.root), res)
+ if self.type=='database':
+ pool = pooler.get_pool(self.cr.dbname)
+ fobj = pool.get('ir.attachment')
+ vargs = [('parent_id','=',False),('res_id','=',False)]
+ if nodename:
+ vargs.append((fobj._rec_name,'=',nodename))
+ file_ids=fobj.search(self.cr,self.uid,vargs)
+
+ res = fobj.browse(self.cr, self.uid, file_ids, context=self.context)
+ result +=map(lambda x: node_class(self.cr, self.uid, self.path+'/'+eval('x.'+fobj._rec_name), x, False, context=self.context, type='file', root=self.root), res)
+ if self.type=='collection' and self.object.type=="ressource":
+ where = self.object.domain and eval(self.object.domain, {'active_id':self.root, 'uid':self.uid}) or []
+ pool = pooler.get_pool(self.cr.dbname)
+ obj = pool.get(self.object.ressource_type_id.model)
+ _dirname_field = obj._rec_name
+ if len(obj.fields_get(self.cr, self.uid, ['dirname'])):
+ _dirname_field = 'dirname'
+
+ name_for = obj._name.split('.')[-1]
+ if nodename and nodename.find(name_for) == 0 :
+ id = int(nodename.replace(name_for,''))
+ where.append(('id','=',id))
+ elif nodename:
+ if nodename.find('__') :
+ nodename=nodename.replace('__','/')
+ for invalid in INVALID_CHARS:
+ if nodename.find(INVALID_CHARS[invalid]) :
+ nodename=nodename.replace(INVALID_CHARS[invalid],invalid)
+ nodename = self.get_translation(nodename, self.context['lang'])
+ where.append((_dirname_field,'=',nodename))
+
+ if self.object.ressource_tree:
+ if obj._parent_name in obj.fields_get(self.cr,self.uid):
+ where.append((obj._parent_name,'=',self.object2 and self.object2.id or False))
+ ids = obj.search(self.cr, self.uid, where)
+ res = obj.browse(self.cr, self.uid, ids,self.context)
+ result+= map(lambda x: node_class(self.cr, self.uid, self.path+'/'+x.name.replace('/','__'), self.object, x, context=self.context, root=x.id), res)
+ return result
+ else :
+ if self.object2:
+ return result
+ else:
+ if self.object2:
+ return result
+
+
+ ids = obj.search(self.cr, self.uid, where)
+ res = obj.browse(self.cr, self.uid, ids,self.context)
+ for r in res:
+ if len(obj.fields_get(self.cr, self.uid, [_dirname_field])):
+ r.name = eval('r.'+_dirname_field)
+ else:
+ r.name = False
+ if not r.name:
+ r.name = name_for + '%d'%r.id
+ for invalid in INVALID_CHARS:
+ if r.name.find(invalid) :
+ r.name = r.name.replace(invalid,INVALID_CHARS[invalid])
+ result2 = map(lambda x: node_class(self.cr, self.uid, self.path+'/'+x.name.replace('/','__'), self.object, x, context=self.context, root=x.id), res)
+ if result2:
+ if self.object.ressource_tree:
+ result += result2
+ else:
+ result = result2
+ return result
+
+
+ def path_get(self):
+ path = self.path
+ if self.path[0]=='/':
+ path = self.path[1:]
+ return path
diff --git a/addons/document/odt2txt.py b/addons/document/odt2txt.py
index 9ee9d088b0a..96acc6f7bd1 100644
--- a/addons/document/odt2txt.py
+++ b/addons/document/odt2txt.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python
# -*- coding: utf-8 -*-
##############################################################################
#
diff --git a/addons/document/std_index.py b/addons/document/std_index.py
new file mode 100644
index 00000000000..730e5082a1b
--- /dev/null
+++ b/addons/document/std_index.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import StringIO
+import odt2txt
+
+from content_index import indexer, cntIndex
+
+
+def _to_unicode(s):
+ try:
+ return s.decode('utf-8')
+ except UnicodeError:
+ try:
+ return s.decode('latin')
+ except UnicodeError:
+ try:
+ return s.encode('ascii')
+ except UnicodeError:
+ return s
+
+class TxtIndex(indexer):
+ def _getMimeTypes(self):
+ return ['text/plain','text/html','text/diff','text/xml', 'text/*',
+ 'application/xml']
+
+ def _getExtensions(self):
+ return ['.txt', '.py']
+
+ def _doIndexContent(self,content):
+ return content
+
+cntIndex.register(TxtIndex())
+
+class DocIndex(indexer):
+ def _getMimeTypes(self):
+ return [ 'application/ms-word']
+
+ def _getExtensions(self):
+ return ['.doc']
+
+ def _doIndexFile(self,fname):
+ fp = Popen(['antiword',fname], shell=False, stdout=PIPE).stdout
+ return _to_unicode( fp.read())
+
+cntIndex.register(DocIndex())
+
+class PdfIndex(indexer):
+ def _getMimeTypes(self):
+ return [ 'application/pdf']
+
+ def _getExtensions(self):
+ return ['.pdf']
+
+ def _doIndexFile(self,fname):
+ fp = Popen(['pdftotext', '-enc', 'UTF-8', '-nopgbrk', fname, '-'], shell=False, stdout=PIPE).stdout
+ return _to_unicode( fp.read())
+
+cntIndex.register(PdfIndex())
+
+class ImageNoIndex(indexer):
+ def _getMimeTypes(self):
+ return [ 'image/*']
+
+ def _getExtensions(self):
+ #better return no extension, and let 'file' do its magic
+ return []
+ #return ['.png','.jpg','.gif','.jpeg','.bmp','.tiff']
+
+ def _doIndexContent(self,content):
+ return 'image'
+
+
+cntIndex.register(ImageNoIndex())
+
+#class Doc(indexer):
+ #def _getDefMime(self,ext):
+
+#def content_index(content, filename=None, content_type=None):
+ #fname,ext = os.path.splitext(filename)
+ #result = ''
+ #elif ext in ('.xls','.ods','.odt','.odp'):
+ #s = StringIO.StringIO(content)
+ #o = odt2txt.OpenDocumentTextFile(s)
+ #result = _to_unicode(o.toString())
+ #s.close()
+ #elif ext in ('.txt','.py','.patch','.html','.csv','.xml'):
+ #result = content
+ #else:
+ #result = content
+ #return result
+
+#eof
diff --git a/addons/document/test_cindex.py b/addons/document/test_cindex.py
new file mode 100755
index 00000000000..9993ffad425
--- /dev/null
+++ b/addons/document/test_cindex.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+
+import sys
+import os
+import glob
+
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.add_option("-q", "--quiet",
+ action="store_false", dest="verbose", default=True,
+ help="don't print status messages to stdout")
+
+parser.add_option("-C", "--content",
+ action="store_true", dest="docontent", default=False,
+ help="Disect content, rather than the file.")
+
+(options, args) = parser.parse_args()
+
+import content_index, std_index
+
+from content_index import cntIndex
+
+for fname in args:
+ try:
+ if options.docontent:
+ fp = open(fname,'rb')
+ content = fp.read()
+ fp.close()
+ res = cntIndex.doIndex(content,fname,None,None,True)
+ else:
+ res = cntIndex.doIndex(None, fname, None, fname,True)
+
+ if res:
+ print "Result: ", res[0]
+ print res[1]
+ else:
+ print "No result"
+ except Exception,e:
+ import traceback,sys
+ tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
+ print "Traceback:",tb_s
+ print "Exception: ",e
+
+
+#eof
From 36c6824e5c14c3766f194ecc4eed6f1324313cfc Mon Sep 17 00:00:00 2001
From: p_christeas <>
Date: Wed, 2 Dec 2009 11:15:55 +0530
Subject: [PATCH 002/123] [IMP] document_ics : taken improveemnt from
xrg-addons
bzr revid: hmo@tinyerp.com-20091202054555-tm16uo4xwc45kgj0
---
addons/document_ics/__init__.py | 2 +-
addons/document_ics/document_data.xml | 1 +
addons/document_ics/document_ics.py | 335 ++++++++++++++++++++++++++
addons/document_ics/document_view.xml | 21 +-
4 files changed, 355 insertions(+), 4 deletions(-)
create mode 100644 addons/document_ics/document_ics.py
diff --git a/addons/document_ics/__init__.py b/addons/document_ics/__init__.py
index 2be140f3f0f..4c5cacb0f74 100644
--- a/addons/document_ics/__init__.py
+++ b/addons/document_ics/__init__.py
@@ -19,6 +19,6 @@
#
##############################################################################
-import document
+import document_ics
import document_ics_config_wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_ics/document_data.xml b/addons/document_ics/document_data.xml
index d2e83a35f40..55522621e17 100644
--- a/addons/document_ics/document_data.xml
+++ b/addons/document_ics/document_data.xml
@@ -5,6 +5,7 @@
.ics
ICS Calendar
+ text/calendar
diff --git a/addons/document_ics/document_ics.py b/addons/document_ics/document_ics.py
new file mode 100644
index 00000000000..61bddb2c306
--- /dev/null
+++ b/addons/document_ics/document_ics.py
@@ -0,0 +1,335 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+from osv import osv, fields
+from osv.orm import except_orm
+import os
+import StringIO
+import base64
+import datetime
+import time
+import random
+import tools
+import re
+
+from document import nodes
+
+from tools.safe_eval import safe_eval
+
+ICS_TAGS = {
+ 'summary':'normal',
+ 'uid':'normal' ,
+ 'dtstart':'date' ,
+ 'dtend':'date' ,
+ 'created':'date' ,
+ 'dtstamp':'date' ,
+ 'last-modified':'normal' ,
+ 'url':'normal' ,
+ 'attendee':'multiple',
+ 'location':'normal',
+ 'categories': 'normal',
+ 'description':'normal',
+
+ # TODO: handle the 'duration' property
+}
+
+ICS_FUNCTIONS = [
+ ('field', 'Use the field'),
+ ('const', 'Expression as constant'),
+ ('hours', 'Interval in hours'),
+ ]
+
+class document_directory_ics_fields(osv.osv):
+ _name = 'document.directory.ics.fields'
+ _columns = {
+ 'field_id': fields.many2one('ir.model.fields', 'Open ERP Field'),
+ 'name': fields.selection(map(lambda x: (x, x), ICS_TAGS.keys()), 'ICS Value', required=True),
+ 'content_id': fields.many2one('document.directory.content', 'Content', required=True, ondelete='cascade'),
+ 'expr': fields.char("Expression", size=64),
+ 'fn': fields.selection(ICS_FUNCTIONS,'Function',help="Alternate method of calculating the value", required=True)
+ }
+ _defaults = {
+ 'fn': lambda *a: 'field',
+ }
+
+document_directory_ics_fields()
+
+class document_directory_content(osv.osv):
+ _inherit = 'document.directory.content'
+ __rege = re.compile(r'OpenERP-([\w|\.]+)_([0-9]+)@(\w+)$')
+ _columns = {
+ 'object_id': fields.many2one('ir.model', 'Object', oldname= 'ics_object_id'),
+ 'obj_iterate': fields.boolean('Iterate object',help="If set, a separate instance will be created for each record of Object"),
+ 'fname_field': fields.char("Filename field",size=16,help="The field of the object used in the filename. Has to be a unique identifier."),
+ 'ics_domain': fields.char('Domain', size=64),
+ 'ics_field_ids': fields.one2many('document.directory.ics.fields', 'content_id', 'Fields Mapping')
+ }
+ _defaults = {
+ 'ics_domain': lambda *args: '[]'
+ }
+ def _file_get(self, cr, node, nodename, content, context=None):
+ if not content.obj_iterate:
+ return super(document_directory_content, self)._file_get(cr,node,nodename,content)
+ else:
+ # print "iterate over ", content.object_id.model
+ mod = self.pool.get(content.object_id.model)
+ uid = node.context.uid
+ fname_fld = content.fname_field or 'id'
+ where = []
+ if node.domain:
+ where.append(node.domain)
+ if nodename:
+ # Reverse-parse the nodename to deduce the clause:
+ prefix = (content.prefix or '')
+ suffix = (content.suffix or '') + (content.extension or '')
+ if not nodename.startswith(prefix):
+ return False
+ if not nodename.endswith(suffix):
+ return False
+ tval = nodename[len(prefix):0 - len(suffix)]
+ where.append((fname_fld,'=',tval))
+ # print "ics iterate clause:", where
+ resids = mod.search(cr,uid,where,context=context)
+ if not resids:
+ return False
+
+ res2 = []
+ for ro in mod.read(cr,uid,resids,['id', fname_fld]):
+ tname = (content.prefix or '') + str(ro[fname_fld])
+ tname += (content.suffix or '') + (content.extension or '')
+ dctx2 = { 'active_id': ro['id'] }
+ if fname_fld:
+ dctx2['active_'+fname_fld] = ro[fname_fld]
+ n = nodes.node_content(tname, node, node.context,content,dctx=dctx2, act_id = ro['id'])
+ n.fill_fields(cr, dctx2)
+ res2.append(n)
+ return res2
+
+ def process_write(self, cr, uid, node, data, context=None):
+ if node.extension != '.ics':
+ return super(document_directory_content).process_write(cr, uid, node, data, context)
+ import vobject
+ parsedCal = vobject.readOne(data)
+ fields = {}
+ funcs = {}
+ fexprs = {}
+ content = self.browse(cr, uid, node.cnt_id, context)
+
+ idomain = {}
+ ctx = (context or {})
+ ctx.update(node.context.context.copy())
+ ctx.update(node.dctx)
+ # print "ICS domain: ", type(content.ics_domain), content.ics_domain
+ if content.ics_domain:
+ for d in safe_eval(content.ics_domain,ctx):
+ # TODO: operator?
+ idomain[d[0]]=d[2]
+ for n in content.ics_field_ids:
+ fields[n.name] = n.field_id.name and str(n.field_id.name)
+ funcs[n.name] = n.fn
+ fexprs[n.name] = n.expr
+
+ if 'uid' not in fields:
+ print "uid not in ", fields
+ # FIXME: should pass
+ return True
+ for child in parsedCal.getChildren():
+ result = {}
+ uuid = None
+
+ for event in child.getChildren():
+ enl = event.name.lower()
+ if enl =='uid':
+ uuid = event.value
+ if not enl in fields:
+ # print "skip", enl
+ continue
+ if fields[enl] and funcs[enl] == 'field':
+ if ICS_TAGS[enl]=='normal':
+ result[fields[enl]] = event.value.encode('utf8')
+ elif ICS_TAGS[enl]=='date':
+ result[fields[enl]] = event.value.strftime('%Y-%m-%d %H:%M:%S')
+
+ # print "Field ",enl, result[fields[enl]]
+ elif fields[enl] and funcs[enl] == 'hours':
+ ntag = fexprs[enl] or 'dtstart'
+ ts_start = child.getChildValue(ntag, default=False)
+ if not ts_start:
+ raise Exception("Cannot parse hours (for %s) without %s" % (enl, ntag))
+ ts_end = event.value
+ assert isinstance(ts_start, datetime.datetime)
+ assert isinstance(ts_end, datetime.datetime)
+ td = ts_end - ts_start
+ result[fields[enl]] = td.days * 24.0 + ( td.seconds / 3600.0)
+
+ # put other functions here..
+ else:
+ # print "Unhandled tag in ICS:", enl
+ pass
+ # end for
+
+ if not uuid:
+ print "Skipping cal", child
+ # FIXME: should pass
+ continue
+
+ cmodel = content.object_id.model
+ wexpr = False
+ if fields['uid']:
+ wexpr = [(fields['uid'], '=', uuid.encode('utf8'))]
+ else:
+ # Parse back the uid from 'OpenERP-%s_%s@%s'
+ wematch = self.__rege.match(uuid.encode('utf8'))
+ # TODO: perhaps also add the domain to wexpr, restrict.
+ if not wematch:
+ raise Exception("Cannot locate UID in %s" % uuid)
+ if wematch.group(3) != cr.dbname:
+ raise Exception("Object is not for our db!")
+ if content.object_id:
+ if wematch.group(1) != cmodel:
+ raise Exception("ICS must be at the wrong folder, this one is for %s" % cmodel)
+ else:
+ # TODO: perhaps guess the model from the iCal, is it safe?
+ pass
+
+ wexpr = [ ( 'id', '=', wematch.group(2) ) ]
+
+ # print "Looking at ", cmodel, " for ", wexpr
+ # print "domain=", idomain
+
+ fobj = self.pool.get(content.object_id.model)
+
+ if not wexpr:
+ id = False
+ else:
+ id = fobj.search(cr, uid, wexpr, context=context)
+
+ if isinstance(id, list):
+ if len(id) > 1:
+ raise Exception("Multiple matches found for ICS")
+ if id:
+ print "writting at %s#%d:" %(cmodel, id[0]), result
+ fobj.write(cr, uid, id, result, context=context)
+ else:
+ r = idomain.copy()
+ r.update(result)
+ print "creating at %s#%d:" %(cmodel, id), result
+ fobj.create(cr, uid, r, context=context)
+
+ return True
+
+ def process_read(self, cr, uid, node, context=None):
+ def ics_datetime(idate, short=False):
+ if short:
+ return datetime.date.fromtimestamp(time.mktime(time.strptime(idate, '%Y-%m-%d')))
+ else:
+ return datetime.datetime.strptime(idate, '%Y-%m-%d %H:%M:%S')
+
+ if node.extension != '.ics':
+ return super(document_directory_content).process_read(cr, uid, node, context)
+
+ import vobject
+ ctx = (context or {})
+ ctx.update(node.context.context.copy())
+ ctx.update(node.dctx)
+ content = self.browse(cr, uid, node.cnt_id, ctx)
+ obj_class = self.pool.get(content.object_id.model)
+
+ if content.ics_domain:
+ domain = safe_eval(content.ics_domain,ctx)
+ else:
+ domain = []
+ if node.act_id:
+ domain.append(('id','=',node.act_id))
+ # print "process read clause:",domain
+ ids = obj_class.search(cr, uid, domain, context=ctx)
+ cal = vobject.iCalendar()
+ for obj in obj_class.browse(cr, uid, ids):
+ event = cal.add('vevent')
+ # Fix dtstamp et last-modified with create and write date on the object line
+ perm = obj_class.perm_read(cr, uid, [obj.id], context)
+ event.add('created').value = ics_datetime(time.strftime('%Y-%m-%d %H:%M:%S'))
+ event.add('dtstamp').value = ics_datetime(perm[0]['create_date'][:19])
+ if perm[0]['write_date']:
+ event.add('last-modified').value = ics_datetime(perm[0]['write_date'][:19])
+ for field in content.ics_field_ids:
+ if field.field_id.name:
+ value = getattr(obj, field.field_id.name)
+ else: value = None
+ if (not value) and field.name=='uid':
+ value = 'OpenERP-%s_%s@%s' % (content.object_id.model, str(obj.id), cr.dbname,)
+ # Why? obj_class.write(cr, uid, [obj.id], {field.field_id.name: value})
+ if ICS_TAGS[field.name]=='normal':
+ if type(value)==type(obj):
+ value=value.name
+ event.add(field.name).value = tools.ustr(value) or ''
+ elif ICS_TAGS[field.name]=='date' and value:
+ if field.name == 'dtstart':
+ date_start = start_date = datetime.datetime.fromtimestamp(time.mktime(time.strptime(value , "%Y-%m-%d %H:%M:%S")))
+ if field.name == 'dtend' and ( isinstance(value, float) or field.fn == 'hours'):
+ value = (start_date + datetime.timedelta(hours=value)).strftime('%Y-%m-%d %H:%M:%S')
+ if len(value)==10:
+ value = ics_datetime(value, True)
+ else:
+ value = ics_datetime(value)
+ event.add(field.name).value = value
+ s= cal.serialize()
+ cr.commit()
+ return s
+document_directory_content()
+
+class crm_case(osv.osv):
+ _inherit = 'crm.case'
+ _columns = {
+ 'code': fields.char('Calendar Code', size=64),
+ 'date_deadline': fields.datetime('Deadline', help="Deadline Date is automatically computed from Start Date + Duration"),
+ }
+
+ _defaults = {
+ 'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'crm.case'),
+ }
+
+ def copy(self, cr, uid, id, default=None, context=None):
+ """
+ code field must be unique in ICS file
+ """
+ if not default: default = {}
+ if not context: context = {}
+ default.update({'code': self.pool.get('ir.sequence').get(cr, uid, 'crm.case'), 'id': False})
+ return super(crm_case, self).copy(cr, uid, id, default, context)
+
+ def on_change_duration(self, cr, uid, id, date, duration):
+ if not date:
+ return {}
+ start_date = datetime.datetime.fromtimestamp(time.mktime(time.strptime(date, "%Y-%m-%d %H:%M:%S")))
+ if duration >= 0 :
+ end = start_date + datetime.timedelta(hours=duration)
+ if duration < 0:
+ raise osv.except_osv(_('Warning !'),
+ _('You can not set negative Duration.'))
+
+ res = {'value' : {'date_deadline' : end.strftime('%Y-%m-%d %H:%M:%S')}}
+ return res
+
+crm_case()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/document_ics/document_view.xml b/addons/document_ics/document_view.xml
index 1623be30af6..e5212fc7f66 100644
--- a/addons/document_ics/document_view.xml
+++ b/addons/document_ics/document_view.xml
@@ -1,20 +1,35 @@
-
+
document.directory
document.directory
form
+
+
+
+
+
+
+
+
+
+
+ document.directory
+ document.directory
+ form
+
-
-
+
+
+
From 84898328030e9172ce759067fe28a91d7210a49f Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Mon, 7 Dec 2009 18:41:11 +0530
Subject: [PATCH 003/123] [IMP] document: remove with four
bzr revid: hmo@tinyerp.com-20091207131111-x11rq6p0ixsgenq4
---
addons/document/content_index.py | 336 +++++------
addons/document/directory_content.py | 68 +--
addons/document/doc_conf_wizard.py | 2 +-
addons/document/document_directory.py | 6 +-
addons/document/document_storage.py | 284 ++++-----
addons/document/nodes.py | 830 +++++++++++++-------------
addons/document/std_index.py | 70 +--
addons/document/test_cindex.py | 38 +-
8 files changed, 817 insertions(+), 817 deletions(-)
diff --git a/addons/document/content_index.py b/addons/document/content_index.py
index a063251c698..b296c623465 100644
--- a/addons/document/content_index.py
+++ b/addons/document/content_index.py
@@ -23,189 +23,189 @@ import tempfile
# A quick hack: if netsvc is not there, emulate it. Thus, work offline, too
try:
- import netsvc
- def log(lvl,msg):
- netsvc.Logger().notifyChannel("index",lvl,msg)
+ import netsvc
+ def log(lvl,msg):
+ netsvc.Logger().notifyChannel("index",lvl,msg)
except:
- class netsvc:
- LOG_NOTSET = 'notset'
- LOG_DEBUG_RPC = 'debug_rpc'
- LOG_DEBUG = 'debug'
- LOG_DEBUG2 = 'debug2'
- LOG_INFO = 'info'
- LOG_WARNING = 'warn'
- LOG_ERROR = 'error'
- LOG_CRITICAL = 'critical'
-
- def log(lvl,msg):
- print msg
+ class netsvc:
+ LOG_NOTSET = 'notset'
+ LOG_DEBUG_RPC = 'debug_rpc'
+ LOG_DEBUG = 'debug'
+ LOG_DEBUG2 = 'debug2'
+ LOG_INFO = 'info'
+ LOG_WARNING = 'warn'
+ LOG_ERROR = 'error'
+ LOG_CRITICAL = 'critical'
+
+ def log(lvl,msg):
+ print msg
class NhException(Exception):
- pass
+ pass
from subprocess import Popen, PIPE
class indexer():
- """ An indexer knows how to parse the content of some file.
-
- Typically, one indexer should be instantiated per file
- type.
- Override this class to add more functionality. Note that
- you should only override the Content or the File methods
- that give an optimal result. """
-
- def _getMimeTypes(self):
- """ Return supported mimetypes """
- return []
-
- def _getExtensions(self):
- return []
-
- def _getDefMime(self,ext):
- """ Return a mimetype for this document type, ideally the
- closest to the extension ext. """
- mts = self._getMimeTypes();
- if len (mts):
- return mts[0]
- return None
+ """ An indexer knows how to parse the content of some file.
+
+ Typically, one indexer should be instantiated per file
+ type.
+ Override this class to add more functionality. Note that
+ you should only override the Content or the File methods
+ that give an optimal result. """
+
+ def _getMimeTypes(self):
+ """ Return supported mimetypes """
+ return []
+
+ def _getExtensions(self):
+ return []
+
+ def _getDefMime(self,ext):
+ """ Return a mimetype for this document type, ideally the
+ closest to the extension ext. """
+ mts = self._getMimeTypes();
+ if len (mts):
+ return mts[0]
+ return None
- def indexContent(self,content,filename=None, realfile = None):
- """ Use either content or the real file, to index.
- Some parsers will work better with the actual
- content, others parse a file easier. Try the
- optimal.
- """
- res = ''
- try:
- if content != None:
- return self._doIndexContent(content)
- except NhException:
- pass
-
- if realfile != None:
- try:
- return self._doIndexFile(realfile)
- except NhException:
- pass
-
- fp = open(realfile,'rb')
- content2 = fp.read()
- fp.close()
-
- # The not-handled exception may be raised here
- return self._doIndexContent(content2)
-
-
- # last try, with a tmp file
- if content:
- try:
- fname,ext = filename and os.path.splitext(filename) or ('','')
- fd, rfname = tempfile.mkstemp(suffix=ext)
- os.write(fd, content)
- os.close(fd)
- res = self._doIndexFile(rfname)
- os.unlink(rfname)
- return res
- except NhException:
- pass
+ def indexContent(self,content,filename=None, realfile = None):
+ """ Use either content or the real file, to index.
+ Some parsers will work better with the actual
+ content, others parse a file easier. Try the
+ optimal.
+ """
+ res = ''
+ try:
+ if content != None:
+ return self._doIndexContent(content)
+ except NhException:
+ pass
+
+ if realfile != None:
+ try:
+ return self._doIndexFile(realfile)
+ except NhException:
+ pass
+
+ fp = open(realfile,'rb')
+ content2 = fp.read()
+ fp.close()
+
+ # The not-handled exception may be raised here
+ return self._doIndexContent(content2)
+
+
+ # last try, with a tmp file
+ if content:
+ try:
+ fname,ext = filename and os.path.splitext(filename) or ('','')
+ fd, rfname = tempfile.mkstemp(suffix=ext)
+ os.write(fd, content)
+ os.close(fd)
+ res = self._doIndexFile(rfname)
+ os.unlink(rfname)
+ return res
+ except NhException:
+ pass
- raise NhException('No appropriate method to index file')
-
- def _doIndexContent(self,content):
- raise NhException("Content not handled here")
+ raise NhException('No appropriate method to index file')
+
+ def _doIndexContent(self,content):
+ raise NhException("Content not handled here")
- def _doIndexFile(self,fpath):
- raise NhException("Content not handled here")
-
-
+ def _doIndexFile(self,fpath):
+ raise NhException("Content not handled here")
+
+
def mime_match(mime, mdict):
- if mdict.has_key(mime):
- return (mime, mdict[mime])
- if '/' in mime:
- mpat = mime.split('/')[0]+'/*'
- if mdict.has_key(mpat):
- return (mime, mdict[mpat])
-
- return (None, None)
+ if mdict.has_key(mime):
+ return (mime, mdict[mime])
+ if '/' in mime:
+ mpat = mime.split('/')[0]+'/*'
+ if mdict.has_key(mpat):
+ return (mime, mdict[mpat])
+
+ return (None, None)
class contentIndex() :
- def __init__(self):
- self.mimes = {}
- self.exts = {}
-
- def register(self, obj):
- f = False
- for mime in obj._getMimeTypes():
- self.mimes[mime] = obj
- f = True
-
- for ext in obj._getExtensions():
- self.exts[ext] = obj
- f = True
-
- if f:
- log(netsvc.LOG_DEBUG, "Register content indexer: %r" % obj)
- if not f:
- raise Exception("Your indexer should at least suport a mimetype or extension")
-
- def doIndex(self,content, filename=None, content_type=None, realfname = None, debug=False):
- fobj = None
- fname = None
- mime = None
- if content_type and self.mimes.has_key(content_type):
- mime = content_type
- fobj = self.mimes[content_type]
- elif filename:
- bname,ext = os.path.splitext(filename)
- if self.exts.has_key(ext):
- fobj = self.exts[ext]
- mime = fobj._getDefMime(ext)
-
- if content_type and not fobj:
- mime,fobj = mime_match(content_type, self.mimes)
-
- if not fobj:
- try:
- if realfname :
- fname = realfname
- else:
- bname,ext = os.path.splitext(filename)
- fd, fname = tempfile.mkstemp(suffix=ext)
- os.write(fd, content)
- os.close(fd)
-
- fp = Popen(['file','-b','--mime-type',fname], shell=False, stdout=PIPE).stdout
- result = fp.read()
- fp.close()
- mime2 = result.strip()
- log(netsvc.LOG_DEBUG,"File gave us: %s" % mime2)
- # Note that the temporary file still exists now.
- mime,fobj = mime_match(mime2, self.mimes)
- if not mime:
- mime = mime2
- except Exception, e:
- log(netsvc.LOG_WARNING,"Cannot determine mime type: %s" % str(e))
-
- try:
- if fobj:
- res = (mime, fobj.indexContent(content,filename,fname or realfname) )
- else:
- log(netsvc.LOG_DEBUG,"Have no object, return (%s, None)" % mime)
- res = (mime, None )
- except Exception, e:
- log(netsvc.LOG_WARNING,"Could not index file, %s" % e)
- res = None
-
- # If we created a tmp file, unlink it now
- if not realfname and fname:
- try:
- os.unlink(fname)
- except Exception, e:
- log(netsvc.LOG_WARNING,"Could not unlink %s, %s" %(fname, e))
-
- return res
+ def __init__(self):
+ self.mimes = {}
+ self.exts = {}
+
+ def register(self, obj):
+ f = False
+ for mime in obj._getMimeTypes():
+ self.mimes[mime] = obj
+ f = True
+
+ for ext in obj._getExtensions():
+ self.exts[ext] = obj
+ f = True
+
+ if f:
+ log(netsvc.LOG_DEBUG, "Register content indexer: %r" % obj)
+ if not f:
+ raise Exception("Your indexer should at least suport a mimetype or extension")
+
+ def doIndex(self,content, filename=None, content_type=None, realfname = None, debug=False):
+ fobj = None
+ fname = None
+ mime = None
+ if content_type and self.mimes.has_key(content_type):
+ mime = content_type
+ fobj = self.mimes[content_type]
+ elif filename:
+ bname,ext = os.path.splitext(filename)
+ if self.exts.has_key(ext):
+ fobj = self.exts[ext]
+ mime = fobj._getDefMime(ext)
+
+ if content_type and not fobj:
+ mime,fobj = mime_match(content_type, self.mimes)
+
+ if not fobj:
+ try:
+ if realfname :
+ fname = realfname
+ else:
+ bname,ext = os.path.splitext(filename)
+ fd, fname = tempfile.mkstemp(suffix=ext)
+ os.write(fd, content)
+ os.close(fd)
+
+ fp = Popen(['file','-b','--mime-type',fname], shell=False, stdout=PIPE).stdout
+ result = fp.read()
+ fp.close()
+ mime2 = result.strip()
+ log(netsvc.LOG_DEBUG,"File gave us: %s" % mime2)
+ # Note that the temporary file still exists now.
+ mime,fobj = mime_match(mime2, self.mimes)
+ if not mime:
+ mime = mime2
+ except Exception, e:
+ log(netsvc.LOG_WARNING,"Cannot determine mime type: %s" % str(e))
+
+ try:
+ if fobj:
+ res = (mime, fobj.indexContent(content,filename,fname or realfname) )
+ else:
+ log(netsvc.LOG_DEBUG,"Have no object, return (%s, None)" % mime)
+ res = (mime, None )
+ except Exception, e:
+ log(netsvc.LOG_WARNING,"Could not index file, %s" % e)
+ res = None
+
+ # If we created a tmp file, unlink it now
+ if not realfname and fname:
+ try:
+ os.unlink(fname)
+ except Exception, e:
+ log(netsvc.LOG_WARNING,"Could not unlink %s, %s" %(fname, e))
+
+ return res
cntIndex = contentIndex()
diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py
index 4ccad653711..dbd801d6be0 100644
--- a/addons/document/directory_content.py
+++ b/addons/document/directory_content.py
@@ -66,44 +66,44 @@ class document_directory_content(osv.osv):
}
def _file_get(self,cr,node, nodename, content, context=None):
- """ return the nodes of a parent having a content
- The return value MUST be false or a list of node_class objects.
- """
-
- # TODO: respect the context!
- if content.include_name and not node.object2:
- return False
-
- res2 = []
- tname = ''
- if content.include_name:
- content_name = node.object2.name
- obj = pool.get(node.object.ressource_type_id.model)
- name_for = obj._name.split('.')[-1]
- if content_name and content_name.find(name_for) == 0 :
- content_name = content_name.replace(name_for,'')
- tname = (content.prefix or '') + content_name + (content.suffix or '') + (content.extension or '')
- else:
- tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '')
- if tname.find('/'):
- tname=tname.replace('/', '_')
- if not nodename:
- n = nodes.node_content(tname, node, node.context,content)
- res2.append( n)
- else:
- if nodename == tname:
- n = nodes.node_content(tname, node, node.context,content)
- n.fill_fields(cr)
- res2.append(n)
- return res2
+ """ return the nodes of a parent having a content
+ The return value MUST be false or a list of node_class objects.
+ """
+
+ # TODO: respect the context!
+ if content.include_name and not node.object2:
+ return False
+
+ res2 = []
+ tname = ''
+ if content.include_name:
+ content_name = node.object2.name
+ obj = pool.get(node.object.ressource_type_id.model)
+ name_for = obj._name.split('.')[-1]
+ if content_name and content_name.find(name_for) == 0 :
+ content_name = content_name.replace(name_for,'')
+ tname = (content.prefix or '') + content_name + (content.suffix or '') + (content.extension or '')
+ else:
+ tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '')
+ if tname.find('/'):
+ tname=tname.replace('/', '_')
+ if not nodename:
+ n = nodes.node_content(tname, node, node.context,content)
+ res2.append( n)
+ else:
+ if nodename == tname:
+ n = nodes.node_content(tname, node, node.context,content)
+ n.fill_fields(cr)
+ res2.append(n)
+ return res2
def process_write(self, cr, uid, node, data):
- if node.extension != '.pdf':
- raise Exception("Invalid content: %s" % node.extension)
+ if node.extension != '.pdf':
+ raise Exception("Invalid content: %s" % node.extension)
return True
def process_read(self, cr, uid, node):
- if node.extension != '.pdf':
- raise Exception("Invalid content: %s" % node.extension)
+ if node.extension != '.pdf':
+ raise Exception("Invalid content: %s" % node.extension)
report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.content.report_id.id)
srv = netsvc.LocalService('report.'+report.report_name)
pdf,pdftype = srv.create(cr, uid, [node.object.id], {}, {})
diff --git a/addons/document/doc_conf_wizard.py b/addons/document/doc_conf_wizard.py
index 66354c8876b..ea0d0ab1487 100644
--- a/addons/document/doc_conf_wizard.py
+++ b/addons/document/doc_conf_wizard.py
@@ -148,7 +148,7 @@ class document_configuration_wizard(osv.osv_memory):
'ressource_tree': 1
})
- # Update the action for FTP browse.
+ # Update the action for FTP browse.
aid = objid._get_id(cr, uid, 'document', 'action_document_browse')
aid = objid.browse(cr, uid, aid, context=context).res_id
self.pool.get('ir.actions.url').write(cr, uid, [aid], {'url': 'ftp://'+(conf.host or 'localhost')+':8021/'})
diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py
index 133927f9664..95e4d438b76 100644
--- a/addons/document/document_directory.py
+++ b/addons/document/document_directory.py
@@ -40,7 +40,7 @@ class document_directory(osv.osv):
'file_type': fields.char('Content Type', size=32),
'domain': fields.char('Domain', size=128, help="Use a domain if you want to apply an automatic filter on visible resources."),
'user_id': fields.many2one('res.users', 'Owner'),
- 'storage_id': fields.many2one('document.storage', 'Storage'),
+ 'storage_id': fields.many2one('document.storage', 'Storage'),
'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
'parent_id': fields.many2one('document.directory', 'Parent Item'),
'child_ids': fields.one2many('document.directory', 'parent_id', 'Children'),
@@ -118,8 +118,8 @@ class document_directory(osv.osv):
path.append(self.pool.get(directory.ressource_type_id.model).browse(cr,uid,res_id).name)
#user=self.pool.get('res.users').browse(cr,uid,uid)
#return "ftp://%s:%s@localhost:%s/%s/%s"%(user.login,user.password,config.get('ftp_server_port',8021),cr.dbname,'/'.join(path))
- # No way we will return the password!
- return "ftp://user:pass@host:port/test/this"
+ # No way we will return the password!
+ return "ftp://user:pass@host:port/test/this"
return False
def _check_recursion(self, cr, uid, ids):
diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py
index d4096138800..488a5ee7e6c 100644
--- a/addons/document/document_storage.py
+++ b/addons/document/document_storage.py
@@ -103,177 +103,177 @@ class document_storage(osv.osv):
'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
'dir_ids': fields.one2many('document.directory', 'parent_id', 'Directories'),
'type': fields.selection([('db','Database'),('filestore','Internal File storage'),
- ('realstore','External file storage'), ('virtual','Virtual storage')], 'Type', required=True),
- 'path': fields.char('Path',size=250,select=1,help="For file storage, the root path of the storage"),
- 'online': fields.boolean('Online',help="If not checked, media is currently offline and its contents not available", required=True),
- 'readonly': fields.boolean('Read Only', help="If set, media is for reading only"),
+ ('realstore','External file storage'), ('virtual','Virtual storage')], 'Type', required=True),
+ 'path': fields.char('Path',size=250,select=1,help="For file storage, the root path of the storage"),
+ 'online': fields.boolean('Online',help="If not checked, media is currently offline and its contents not available", required=True),
+ 'readonly': fields.boolean('Read Only', help="If set, media is for reading only"),
}
def _get_rootpath(self,cr,uid,context=None):
- from tools import config
+ from tools import config
return os.path.join(tools.config['root_path'], 'filestore', cr.dbname)
_defaults = {
'user_id': lambda self,cr,uid,ctx: uid,
- 'online': lambda *args: True,
- 'readonly': lambda *args: False,
+ 'online': lambda *args: True,
+ 'readonly': lambda *args: False,
# Note: the defaults below should only be used ONCE for the default
# storage media. All other times, we should create different paths at least.
'type': lambda *args: 'filestore',
'path': _get_rootpath,
}
_sql_constraints = [
- # SQL note: a path = NULL doesn't have to be unique.
- ('path_uniq', 'UNIQUE(type,path)', "The storage path must be unique!")
- ]
-
+ # SQL note: a path = NULL doesn't have to be unique.
+ ('path_uniq', 'UNIQUE(type,path)', "The storage path must be unique!")
+ ]
+
def get_data(self, cr,uid, id, file_node,context = None, fil_obj = None):
- """ retrieve the contents of some file_node having storage_id = id
- optionally, fil_obj could point to the browse object of the file
- (ir.attachment)
- """
- if not context:
- context = {}
+ """ retrieve the contents of some file_node having storage_id = id
+ optionally, fil_obj could point to the browse object of the file
+ (ir.attachment)
+ """
+ if not context:
+ context = {}
boo = self.browse(cr,uid,id,context)
- if fil_obj:
- ira = fil_obj
- else:
- ira = self.pool.get('ir.attachment').browse(cr,uid, file_node.file_id, context=context)
- return self.__get_data_3(cr,uid,boo, ira, context)
-
+ if fil_obj:
+ ira = fil_obj
+ else:
+ ira = self.pool.get('ir.attachment').browse(cr,uid, file_node.file_id, context=context)
+ return self.__get_data_3(cr,uid,boo, ira, context)
+
def __get_data_3(self,cr,uid, boo, ira, context):
- if not boo.online:
- raise RuntimeError('media offline')
- if boo.type == 'filestore':
- if not ira.store_fname:
- # On a migrated db, some files may have the wrong storage type
- # try to fix their directory.
- if ira.file_size:
- netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"ir.attachment #%d does not have a filename, but is at filestore, fix it!" %ira.id)
- return None
- fpath = os.path.join(boo.path,ira.store_fname)
- print "Trying to read \"%s\".."% fpath
- return file(fpath,'rb').read()
- elif boo.type == 'db':
- # TODO: we need a better api for large files
- if ira.db_datas:
- out=base64.decodestring(ira.db_datas)
- else:
- out=''
- return out
- elif boo.type == 'realstore':
- # fpath = os.path.join(boo.path,
- return None
- else:
- raise TypeError("No %s storage" % boo.type)
+ if not boo.online:
+ raise RuntimeError('media offline')
+ if boo.type == 'filestore':
+ if not ira.store_fname:
+ # On a migrated db, some files may have the wrong storage type
+ # try to fix their directory.
+ if ira.file_size:
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"ir.attachment #%d does not have a filename, but is at filestore, fix it!" %ira.id)
+ return None
+ fpath = os.path.join(boo.path,ira.store_fname)
+ print "Trying to read \"%s\".."% fpath
+ return file(fpath,'rb').read()
+ elif boo.type == 'db':
+ # TODO: we need a better api for large files
+ if ira.db_datas:
+ out=base64.decodestring(ira.db_datas)
+ else:
+ out=''
+ return out
+ elif boo.type == 'realstore':
+ # fpath = os.path.join(boo.path,
+ return None
+ else:
+ raise TypeError("No %s storage" % boo.type)
def set_data(self, cr,uid, id, file_node, data, context = None, fil_obj = None):
- """ store the data.
- This function MUST be used from an ir.attachment. It wouldn't make sense
- to store things persistently for other types (dynamic).
- """
- if not context:
- context = {}
+ """ store the data.
+ This function MUST be used from an ir.attachment. It wouldn't make sense
+ to store things persistently for other types (dynamic).
+ """
+ if not context:
+ context = {}
boo = self.browse(cr,uid,id,context)
- logger = netsvc.Logger()
- if fil_obj:
- ira = fil_obj
- else:
- ira = self.pool.get('ir.attachment').browse(cr,uid, file_node.file_id, context=context)
-
- if not boo.online:
- raise RuntimeError('media offline')
- logger.notifyChannel('document',netsvc.LOG_DEBUG,"Store data for ir.attachment #%d" %ira.id)
- store_fname = None
- fname = None
- if boo.type == 'filestore':
- path = boo.path
- try:
- flag = None
- # This can be improved
- for dirs in os.listdir(path):
- if os.path.isdir(os.path.join(path,dirs)) and len(os.listdir(os.path.join(path,dirs)))<4000:
- flag = dirs
+ logger = netsvc.Logger()
+ if fil_obj:
+ ira = fil_obj
+ else:
+ ira = self.pool.get('ir.attachment').browse(cr,uid, file_node.file_id, context=context)
+
+ if not boo.online:
+ raise RuntimeError('media offline')
+ logger.notifyChannel('document',netsvc.LOG_DEBUG,"Store data for ir.attachment #%d" %ira.id)
+ store_fname = None
+ fname = None
+ if boo.type == 'filestore':
+ path = boo.path
+ try:
+ flag = None
+ # This can be improved
+ for dirs in os.listdir(path):
+ if os.path.isdir(os.path.join(path,dirs)) and len(os.listdir(os.path.join(path,dirs)))<4000:
+ flag = dirs
break
- flag = flag or create_directory(path)
- filename = random_name()
- fname = os.path.join(path, flag, filename)
- fp = file(fname,'wb')
- fp.write(data)
- fp.close()
- logger.notifyChannel('document',netsvc.LOG_DEBUG,"Saved data to %s" % fname)
- filesize = len(data) # os.stat(fname).st_size
- store_fname = os.path.join(flag,filename)
-
- # TODO Here, an old file would be left hanging.
+ flag = flag or create_directory(path)
+ filename = random_name()
+ fname = os.path.join(path, flag, filename)
+ fp = file(fname,'wb')
+ fp.write(data)
+ fp.close()
+ logger.notifyChannel('document',netsvc.LOG_DEBUG,"Saved data to %s" % fname)
+ filesize = len(data) # os.stat(fname).st_size
+ store_fname = os.path.join(flag,filename)
+
+ # TODO Here, an old file would be left hanging.
except Exception,e :
- netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" %str(e))
- raise except_orm(_('Error!'), str(e))
- elif boo.type == 'db':
- filesize = len(data)
- # will that work for huge data? TODO
- out=base64.encodestring(data)
- cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s',
- ( out, file_node.file_id ))
- else:
- raise TypeError("No %s storage" % boo.type)
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" %str(e))
+ raise except_orm(_('Error!'), str(e))
+ elif boo.type == 'db':
+ filesize = len(data)
+ # will that work for huge data? TODO
+ out=base64.encodestring(data)
+ cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s',
+ ( out, file_node.file_id ))
+ else:
+ raise TypeError("No %s storage" % boo.type)
- # 2nd phase: store the metadata
- try:
- icont = ''
- mime = ira.file_type
- try:
- mime,icont = cntIndex.doIndex(data, ira.datas_fname,
- ira.file_type or None,fname)
- except Exception,e:
- logger.notifyChannel('document', netsvc.LOG_DEBUG, 'Cannot index file: %s' % str(e))
- pass
+ # 2nd phase: store the metadata
+ try:
+ icont = ''
+ mime = ira.file_type
+ try:
+ mime,icont = cntIndex.doIndex(data, ira.datas_fname,
+ ira.file_type or None,fname)
+ except Exception,e:
+ logger.notifyChannel('document', netsvc.LOG_DEBUG, 'Cannot index file: %s' % str(e))
+ pass
- # a hack: /assume/ that the calling write operation will not try
- # to write the fname and size, and update them in the db concurrently.
- # We cannot use a write() here, because we are already in one.
- cr.execute('UPDATE ir_attachment SET store_fname = %s, file_size = %s, index_content = %s, file_type = %s WHERE id = %s',
- (store_fname, filesize, ustr(icont), mime, file_node.file_id ))
- file_node.content_length = filesize
- file_node.content_type = mime
- return True
+ # a hack: /assume/ that the calling write operation will not try
+ # to write the fname and size, and update them in the db concurrently.
+ # We cannot use a write() here, because we are already in one.
+ cr.execute('UPDATE ir_attachment SET store_fname = %s, file_size = %s, index_content = %s, file_type = %s WHERE id = %s',
+ (store_fname, filesize, ustr(icont), mime, file_node.file_id ))
+ file_node.content_length = filesize
+ file_node.content_type = mime
+ return True
except Exception,e :
- netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" %str(e))
- # should we really rollback once we have written the actual data?
- # at the db case (only), that rollback would be safe
- raise except_orm(_('Error at doc write!'), str(e))
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Couldn't save data: %s" %str(e))
+ # should we really rollback once we have written the actual data?
+ # at the db case (only), that rollback would be safe
+ raise except_orm(_('Error at doc write!'), str(e))
def prepare_unlink(self,cr,uid,storage_bo, fil_bo):
- """ Before we unlink a file (fil_boo), prepare the list of real
- files that have to be removed, too. """
-
- if not storage_bo.online:
- raise RuntimeError('media offline')
-
- if storage_bo.type == 'filestore':
- fname = fil_bo.store_fname
- if not fname:
- return None
- path = storage_bo.path
- return ( storage_bo.id, 'file', os.path.join(path,fname))
- elif storage_bo.type == 'db':
- return None
- else:
- raise TypeError("No %s storage" % boo.type)
+ """ Before we unlink a file (fil_boo), prepare the list of real
+ files that have to be removed, too. """
+
+ if not storage_bo.online:
+ raise RuntimeError('media offline')
+
+ if storage_bo.type == 'filestore':
+ fname = fil_bo.store_fname
+ if not fname:
+ return None
+ path = storage_bo.path
+ return ( storage_bo.id, 'file', os.path.join(path,fname))
+ elif storage_bo.type == 'db':
+ return None
+ else:
+ raise TypeError("No %s storage" % boo.type)
def do_unlink(self, cr,uid,unres):
- for id, ktype, fname in unres:
- if ktype == 'file':
- try:
- os.unlink(fname)
- except Exception,e:
- netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Could not remove file %s, please remove manually." % fname)
- else:
- netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Unknown unlink key %s" % ktype)
-
- return True
-
+ for id, ktype, fname in unres:
+ if ktype == 'file':
+ try:
+ os.unlink(fname)
+ except Exception,e:
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Could not remove file %s, please remove manually." % fname)
+ else:
+ netsvc.Logger().notifyChannel('document',netsvc.LOG_WARNING,"Unknown unlink key %s" % ktype)
+
+ return True
+
document_storage()
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index 19efe97c7c1..845ba4e3ace 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -42,42 +42,42 @@ import time
#
def get_node_context(cr, uid, context):
- return node_context(cr,uid,context)
+ return node_context(cr,uid,context)
class node_context(object):
""" This is the root node, representing access to some particular
- context """
+ context """
cached_roots = {}
def __init__(self, cr, uid, context=None):
- # we don't cache the cr!
- #self.cr = cr
- self.uid = uid
- self.context = context
- self._dirobj = pooler.get_pool(cr.dbname).get('document.directory')
- assert self._dirobj
- self.rootdir = self._dirobj._get_root_directory(cr,uid,context)
+ # we don't cache the cr!
+ #self.cr = cr
+ self.uid = uid
+ self.context = context
+ self._dirobj = pooler.get_pool(cr.dbname).get('document.directory')
+ assert self._dirobj
+ self.rootdir = self._dirobj._get_root_directory(cr,uid,context)
def get_uri(self, cr, uri):
- """ Although this fn passes back to doc.dir, it is needed since
- it is a potential caching point """
-
- (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
-
- while duri:
- ndir = ndir.child(cr, duri[0])
- if not ndir:
- return False
- duri = duri[1:]
- return ndir
+ """ Although this fn passes back to doc.dir, it is needed since
+ it is a potential caching point """
+
+ (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
+
+ while duri:
+ ndir = ndir.child(cr, duri[0])
+ if not ndir:
+ return False
+ duri = duri[1:]
+ return ndir
class node_database():
""" A node representing the database directory
- Useless?
- """
+ Useless?
+ """
def __init__(self,ncontext):
- self.nctx = ncontext
+ self.nctx = ncontext
@@ -85,108 +85,108 @@ class node_database():
class node_class(object):
""" this is a superclass for our inodes
It is an API for all code that wants to access the document files.
- Nodes have attributes which contain usual file properties
- """
+ Nodes have attributes which contain usual file properties
+ """
our_type = 'baseclass'
def __init__(self, path, parent, context):
- assert isinstance(context,node_context)
- assert (not parent ) or isinstance(parent,node_class)
+ assert isinstance(context,node_context)
+ assert (not parent ) or isinstance(parent,node_class)
self.path = path
self.context = context
self.type=self.our_type
- self.parent = parent
- self.mimetype = 'application/octet-stream'
- self.create_date = None
- self.write_date = None
- self.content_length = 0
- # dynamic context:
- self.dctx = {}
- if parent:
- self.dctx = parent.dctx.copy()
- self.displayname = 'Object'
-
+ self.parent = parent
+ self.mimetype = 'application/octet-stream'
+ self.create_date = None
+ self.write_date = None
+ self.content_length = 0
+ # dynamic context:
+ self.dctx = {}
+ if parent:
+ self.dctx = parent.dctx.copy()
+ self.displayname = 'Object'
+
def full_path(self):
- if self.parent:
- s = self.parent.full_path()
- else:
- s = []
- if isinstance(self.path,list):
- s+=self.path
- else:
- s.append(self.path)
- return s
+ if self.parent:
+ s = self.parent.full_path()
+ else:
+ s = []
+ if isinstance(self.path,list):
+ s+=self.path
+ else:
+ s.append(self.path)
+ return s
def children(self, cr):
print "node_class.children()"
- return [] #stub
+ return [] #stub
def child(self,cr, name):
- print "node_class.child()"
+ print "node_class.child()"
return None
def path_get(self):
- print "node_class.path_get()"
- return False
-
+ print "node_class.path_get()"
+ return False
+
def get_data(self,cr):
- raise TypeError('no data for %s'% self.type)
+ raise TypeError('no data for %s'% self.type)
def _get_storage(self,cr):
- raise RuntimeError("no storage for base class")
+ raise RuntimeError("no storage for base class")
def get_etag(self,cr):
""" Get a tag, unique per object + modification.
-
- see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
- return self._get_ttag(cr) + ':' + self._get_wtag(cr)
+
+ see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
+ return self._get_ttag(cr) + ':' + self._get_wtag(cr)
def _get_wtag(self,cr):
- """ Return the modification time as a unique, compact string """
- if self.write_date:
- wtime = time.mktime(time.strptime(self.write_date,'%Y-%m-%d %H:%M:%S'))
- else: wtime = time.time()
- return str(wtime)
+ """ Return the modification time as a unique, compact string """
+ if self.write_date:
+ wtime = time.mktime(time.strptime(self.write_date,'%Y-%m-%d %H:%M:%S'))
+ else: wtime = time.time()
+ return str(wtime)
def _get_ttag(self,cr):
- """ Get a unique tag for this type/id of object.
- Must be overriden, so that each node is uniquely identified.
- """
- print "node_class.get_ttag()",self
- raise RuntimeError("get_etag stub()")
-
+ """ Get a unique tag for this type/id of object.
+ Must be overriden, so that each node is uniquely identified.
+ """
+ print "node_class.get_ttag()",self
+ raise RuntimeError("get_etag stub()")
+
def get_dav_props(self, cr):
""" If this class has special behaviour for GroupDAV etc, export
- its capabilities """
- return {}
+ its capabilities """
+ return {}
def get_dav_eprop(self,cr,ns,prop):
- return None
+ return None
class node_dir(node_class):
our_type = 'collection'
def __init__(self,path, parent, context, dirr, dctx=None):
- super(node_dir,self).__init__(path, parent,context)
- self.dir_id = dirr.id
- #todo: more info from dirr
- self.mimetype = 'application/x-directory'
- # 'httpd/unix-directory'
- self.create_date = dirr.create_date
- # TODO: the write date should be MAX(file.write)..
- self.write_date = dirr.write_date or dirr.create_date
- self.content_length = 0
- if dctx:
- self.dctx.update(dctx)
- dc2 = self.context.context
- dc2.update(self.dctx)
- dc2['dir_id'] = self.dir_id
- self.displayname = dirr.name
- for dfld in dirr.dctx_ids:
- try:
- self.dctx['dctx_' + dfld.field] = safe_eval(dfld.expr,dc2)
- except Exception,e:
- print "Cannot eval %s" % dfld.expr
- print e
- pass
+ super(node_dir,self).__init__(path, parent,context)
+ self.dir_id = dirr.id
+ #todo: more info from dirr
+ self.mimetype = 'application/x-directory'
+ # 'httpd/unix-directory'
+ self.create_date = dirr.create_date
+ # TODO: the write date should be MAX(file.write)..
+ self.write_date = dirr.write_date or dirr.create_date
+ self.content_length = 0
+ if dctx:
+ self.dctx.update(dctx)
+ dc2 = self.context.context
+ dc2.update(self.dctx)
+ dc2['dir_id'] = self.dir_id
+ self.displayname = dirr.name
+ for dfld in dirr.dctx_ids:
+ try:
+ self.dctx['dctx_' + dfld.field] = safe_eval(dfld.expr,dc2)
+ except Exception,e:
+ print "Cannot eval %s" % dfld.expr
+ print e
+ pass
def children(self,cr):
return self._child_get(cr) + self._file_get(cr)
@@ -201,132 +201,132 @@ class node_dir(node_class):
return None
def _file_get(self,cr, nodename=False):
- res = []
- cntobj = self.context._dirobj.pool.get('document.directory.content')
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('directory_id','=',self.dir_id) ]
- ids = cntobj.search(cr,uid,where,context=ctx)
+ res = []
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr,uid,ids,context=ctx):
- res3 = cntobj._file_get(cr,self,nodename,content)
- if res3:
- res.extend(res3)
+ res3 = cntobj._file_get(cr,self,nodename,content)
+ if res3:
+ res.extend(res3)
- return res
+ return res
def get_dav_props(self, cr):
- res = {}
- cntobj = self.context._dirobj.pool.get('document.directory.content')
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('directory_id','=',self.dir_id) ]
- ids = cntobj.search(cr,uid,where,context=ctx)
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr,uid,ids,context=ctx):
- if content.extension == '.ics': # FIXME: call the content class!
- res['http://groupdav.org/'] = ('resourcetype',)
- break
- return res
+ if content.extension == '.ics': # FIXME: call the content class!
+ res['http://groupdav.org/'] = ('resourcetype',)
+ break
+ return res
def get_dav_eprop(self,cr,ns,prop):
- if ns != 'http://groupdav.org/' or prop != 'resourcetype':
- print "Who asked for %s:%s?" % (ns,prop)
- return None
- res = {}
- cntobj = self.context._dirobj.pool.get('document.directory.content')
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('directory_id','=',self.dir_id) ]
- ids = cntobj.search(cr,uid,where,context=ctx)
+ if ns != 'http://groupdav.org/' or prop != 'resourcetype':
+ print "Who asked for %s:%s?" % (ns,prop)
+ return None
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr,uid,ids,context=ctx):
- if content.extension == '.ics': # FIXME: call the content class!
- return ('vevent-collection','http://groupdav.org/')
- return None
+ if content.extension == '.ics': # FIXME: call the content class!
+ return ('vevent-collection','http://groupdav.org/')
+ return None
def _child_get(self,cr,name = None):
- dirobj = self.context._dirobj
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('parent_id','=',self.dir_id) ]
- if name:
- where.append(('name','=',name))
- ids = dirobj.search(cr, uid, where,context=ctx)
- res = []
- if ids:
- for dirr in dirobj.browse(cr,uid,ids,context=ctx):
- if dirr.type == 'directory':
- res.append(node_dir(dirr.name,self,self.context,dirr))
- elif dirr.type == 'ressource':
- res.append(node_res_dir(dirr.name,self,self.context,dirr))
-
- fil_obj=dirobj.pool.get('ir.attachment')
- #where2 = where # + [('res_model', '=', None)]
- ids = fil_obj.search(cr,uid,where,context=ctx)
- if ids:
- for fil in fil_obj.browse(cr,uid,ids,context=ctx):
- res.append(node_file(fil.name,self,self.context,fil))
-
- return res
-
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('parent_id','=',self.dir_id) ]
+ if name:
+ where.append(('name','=',name))
+ ids = dirobj.search(cr, uid, where,context=ctx)
+ res = []
+ if ids:
+ for dirr in dirobj.browse(cr,uid,ids,context=ctx):
+ if dirr.type == 'directory':
+ res.append(node_dir(dirr.name,self,self.context,dirr))
+ elif dirr.type == 'ressource':
+ res.append(node_res_dir(dirr.name,self,self.context,dirr))
+
+ fil_obj=dirobj.pool.get('ir.attachment')
+ #where2 = where # + [('res_model', '=', None)]
+ ids = fil_obj.search(cr,uid,where,context=ctx)
+ if ids:
+ for fil in fil_obj.browse(cr,uid,ids,context=ctx):
+ res.append(node_file(fil.name,self,self.context,fil))
+
+ return res
+
def create_child(self,cr,path,data):
- """ API function to create a child file object and node
- Return the node_* created
- """
- dirobj = self.context._dirobj
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- fil_obj=dirobj.pool.get('ir.attachment')
- val = {
- 'name': path,
- 'datas_fname': path,
- 'parent_id': self.dir_id,
- # Datas are not set here
- }
+ """ API function to create a child file object and node
+ Return the node_* created
+ """
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ fil_obj=dirobj.pool.get('ir.attachment')
+ val = {
+ 'name': path,
+ 'datas_fname': path,
+ 'parent_id': self.dir_id,
+ # Datas are not set here
+ }
- fil_id = fil_obj.create(cr,uid, val, context=ctx)
- fil = fil_obj.browse(cr,uid,fil_id,context=ctx)
- fnode = node_file(path,self,self.context,fil)
- fnode.set_data(cr,data,fil)
- return fnode
-
+ fil_id = fil_obj.create(cr,uid, val, context=ctx)
+ fil = fil_obj.browse(cr,uid,fil_id,context=ctx)
+ fnode = node_file(path,self,self.context,fil)
+ fnode.set_data(cr,data,fil)
+ return fnode
+
def _get_ttag(self,cr):
- return 'dir-%d' % self.dir_id
+ return 'dir-%d' % self.dir_id
class node_res_dir(node_class):
""" A special sibling to node_dir, which does only contain dynamically
created folders foreach resource in the foreign model.
- All folders should be of type node_res_obj and merely behave like
- node_dirs (with limited domain).
- """
+ All folders should be of type node_res_obj and merely behave like
+ node_dirs (with limited domain).
+ """
our_type = 'collection'
def __init__(self,path, parent, context, dirr, dctx=None ):
- super(node_res_dir,self).__init__(path, parent,context)
- self.dir_id = dirr.id
- #todo: more info from dirr
- self.mimetype = 'application/x-directory'
- # 'httpd/unix-directory'
- self.create_date = dirr.create_date
- # TODO: the write date should be MAX(file.write)..
- self.write_date = dirr.write_date or dirr.create_date
- self.content_length = 0
- self.res_model = dirr.ressource_type_id.model
- self.resm_id = dirr.ressource_id
- self.namefield = dirr.resource_field or 'name'
- self.displayname = dirr.name
- # Important: the domain is evaluated using the *parent* dctx!
- self.domain = safe_eval(dirr.domain,self.dctx)
- # and then, we add our own vars in the dctx:
- if dctx:
- self.dctx.update(dctx)
-
- # and then, we prepare a dctx dict, for deferred evaluation:
- self.dctx_dict = {}
- for dfld in dirr.dctx_ids:
- self.dctx_dict['dctx_' + dfld.field] = dfld.expr
+ super(node_res_dir,self).__init__(path, parent,context)
+ self.dir_id = dirr.id
+ #todo: more info from dirr
+ self.mimetype = 'application/x-directory'
+ # 'httpd/unix-directory'
+ self.create_date = dirr.create_date
+ # TODO: the write date should be MAX(file.write)..
+ self.write_date = dirr.write_date or dirr.create_date
+ self.content_length = 0
+ self.res_model = dirr.ressource_type_id.model
+ self.resm_id = dirr.ressource_id
+ self.namefield = dirr.resource_field or 'name'
+ self.displayname = dirr.name
+ # Important: the domain is evaluated using the *parent* dctx!
+ self.domain = safe_eval(dirr.domain,self.dctx)
+ # and then, we add our own vars in the dctx:
+ if dctx:
+ self.dctx.update(dctx)
+
+ # and then, we prepare a dctx dict, for deferred evaluation:
+ self.dctx_dict = {}
+ for dfld in dirr.dctx_ids:
+ self.dctx_dict['dctx_' + dfld.field] = dfld.expr
def children(self,cr):
return self._child_get(cr)
@@ -339,81 +339,81 @@ class node_res_dir(node_class):
def _child_get(self,cr,name = None):
""" return virtual children of resource, based on the
- foreign object.
-
- Note that many objects use NULL for a name, so we should
- better call the name_search(),name_get() set of methods
- """
- obj = self.context._dirobj.pool.get(self.res_model)
- if not obj:
- print "couldn't find model", self.res_model
- return []
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = []
- if self.domain:
- where.append(self.domain)
- if self.resm_id:
- where.append(('id','=',self.resm_id))
-
- if name:
- where.append((self.namefield,'=',name))
- # print "Where clause for %s" % self.res_model, where
-
- resids = obj.search(cr,uid, where, context=ctx)
- res = []
- for bo in obj.browse(cr,uid,resids,context=ctx):
- if not bo:
- continue
- name = getattr(bo,self.namefield)
- if not name:
- continue
- # Yes! we can't do better but skip nameless records.
- res.append(node_res_obj(name,self,self.context,self.res_model, bo))
- return res
+ foreign object.
+
+ Note that many objects use NULL for a name, so we should
+ better call the name_search(),name_get() set of methods
+ """
+ obj = self.context._dirobj.pool.get(self.res_model)
+ if not obj:
+ print "couldn't find model", self.res_model
+ return []
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = []
+ if self.domain:
+ where.append(self.domain)
+ if self.resm_id:
+ where.append(('id','=',self.resm_id))
+
+ if name:
+ where.append((self.namefield,'=',name))
+ # print "Where clause for %s" % self.res_model, where
+
+ resids = obj.search(cr,uid, where, context=ctx)
+ res = []
+ for bo in obj.browse(cr,uid,resids,context=ctx):
+ if not bo:
+ continue
+ name = getattr(bo,self.namefield)
+ if not name:
+ continue
+ # Yes! we can't do better but skip nameless records.
+ res.append(node_res_obj(name,self,self.context,self.res_model, bo))
+ return res
def _get_ttag(self,cr):
- return 'rdir-%d' % self.dir_id
+ return 'rdir-%d' % self.dir_id
class node_res_obj(node_class):
""" A special sibling to node_dir, which does only contain dynamically
created folders foreach resource in the foreign model.
- All folders should be of type node_res_obj and merely behave like
- node_dirs (with limited domain).
- """
+ All folders should be of type node_res_obj and merely behave like
+ node_dirs (with limited domain).
+ """
our_type = 'collection'
def __init__(self,path, parent, context, res_model, res_bo, res_id = None):
- super(node_res_obj,self).__init__(path, parent,context)
- assert parent
- #todo: more info from dirr
- self.dir_id = parent.dir_id
- self.mimetype = 'application/x-directory'
- # 'httpd/unix-directory'
- self.create_date = parent.create_date
- # TODO: the write date should be MAX(file.write)..
- self.write_date = parent.write_date
- self.content_length = 0
- self.res_model = res_model
- self.domain = parent.domain
- self.displayname = path
+ super(node_res_obj,self).__init__(path, parent,context)
+ assert parent
+ #todo: more info from dirr
+ self.dir_id = parent.dir_id
+ self.mimetype = 'application/x-directory'
+ # 'httpd/unix-directory'
+ self.create_date = parent.create_date
+ # TODO: the write date should be MAX(file.write)..
+ self.write_date = parent.write_date
+ self.content_length = 0
+ self.res_model = res_model
+ self.domain = parent.domain
+ self.displayname = path
- if res_bo:
- self.res_id = res_bo.id
- dc2 = self.context.context
- dc2.update(self.dctx)
- dc2['res_model'] = res_model
- dc2['res_id'] = res_bo.id
- dc2['this'] = res_bo
- for fld,expr in parent.dctx_dict.items():
- try:
- self.dctx[fld] = safe_eval(expr,dc2)
- except Exception,e:
- print "Cannot eval %s for %s" % (expr, fld)
- print e
- pass
- else:
- self.res_id = res_id
+ if res_bo:
+ self.res_id = res_bo.id
+ dc2 = self.context.context
+ dc2.update(self.dctx)
+ dc2['res_model'] = res_model
+ dc2['res_id'] = res_bo.id
+ dc2['this'] = res_bo
+ for fld,expr in parent.dctx_dict.items():
+ try:
+ self.dctx[fld] = safe_eval(expr,dc2)
+ except Exception,e:
+ print "Cannot eval %s for %s" % (expr, fld)
+ print e
+ pass
+ else:
+ self.res_id = res_id
def children(self,cr):
return self._child_get(cr) + self._file_get(cr)
@@ -428,172 +428,172 @@ class node_res_obj(node_class):
return None
def _file_get(self,cr, nodename=False):
- res = []
- cntobj = self.context._dirobj.pool.get('document.directory.content')
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('directory_id','=',self.dir_id) ]
- #if self.domain:
- # where.extend(self.domain)
- # print "res_obj file_get clause", where
- ids = cntobj.search(cr,uid,where,context=ctx)
+ res = []
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ #if self.domain:
+ # where.extend(self.domain)
+ # print "res_obj file_get clause", where
+ ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr,uid,ids,context=ctx):
- res3 = cntobj._file_get(cr,self,nodename,content, context=ctx)
- if res3:
- res.extend(res3)
+ res3 = cntobj._file_get(cr,self,nodename,content, context=ctx)
+ if res3:
+ res.extend(res3)
- return res
+ return res
def get_dav_props(self, cr):
- res = {}
- cntobj = self.context._dirobj.pool.get('document.directory.content')
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('directory_id','=',self.dir_id) ]
- ids = cntobj.search(cr,uid,where,context=ctx)
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr,uid,ids,context=ctx):
- if content.extension == '.ics': # FIXME: call the content class!
- res['http://groupdav.org/'] = ('resourcetype',)
- return res
+ if content.extension == '.ics': # FIXME: call the content class!
+ res['http://groupdav.org/'] = ('resourcetype',)
+ return res
def get_dav_eprop(self,cr,ns,prop):
- if ns != 'http://groupdav.org/' or prop != 'resourcetype':
- print "Who asked for %s:%s?" % (ns,prop)
- return None
- res = {}
- cntobj = self.context._dirobj.pool.get('document.directory.content')
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('directory_id','=',self.dir_id) ]
- ids = cntobj.search(cr,uid,where,context=ctx)
+ if ns != 'http://groupdav.org/' or prop != 'resourcetype':
+ print "Who asked for %s:%s?" % (ns,prop)
+ return None
+ res = {}
+ cntobj = self.context._dirobj.pool.get('document.directory.content')
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('directory_id','=',self.dir_id) ]
+ ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr,uid,ids,context=ctx):
- if content.extension == '.ics': # FIXME: call the content class!
- return ('vevent-collection','http://groupdav.org/')
- return None
+ if content.extension == '.ics': # FIXME: call the content class!
+ return ('vevent-collection','http://groupdav.org/')
+ return None
def _child_get(self,cr,name = None):
- dirobj = self.context._dirobj
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- where = [('parent_id','=',self.dir_id) ]
- if name:
- where.append(('name','=',name))
- ids = dirobj.search(cr, uid, where,context=ctx)
- res = []
- if ids:
- for dirr in dirobj.browse(cr,uid,ids,context=ctx):
- if dirr.type == 'directory':
- res.append(node_res_obj(dirr.name,self,self.context,self.res_model,res_bo = None, res_id = self.res_id))
- elif dirr.type == 'ressource':
- # child resources can be controlled by properly set dctx
- res.append(node_res_dir(dirr.name,self,self.context,dirr))
-
- fil_obj=dirobj.pool.get('ir.attachment')
- where2 = where + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)]
- # print "where clause for dir_obj", where2
- ids = fil_obj.search(cr,uid,where2,context=ctx)
- if ids:
- for fil in fil_obj.browse(cr,uid,ids,context=ctx):
- res.append(node_file(fil.name,self,self.context,fil))
-
- return res
-
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ where = [('parent_id','=',self.dir_id) ]
+ if name:
+ where.append(('name','=',name))
+ ids = dirobj.search(cr, uid, where,context=ctx)
+ res = []
+ if ids:
+ for dirr in dirobj.browse(cr,uid,ids,context=ctx):
+ if dirr.type == 'directory':
+ res.append(node_res_obj(dirr.name,self,self.context,self.res_model,res_bo = None, res_id = self.res_id))
+ elif dirr.type == 'ressource':
+ # child resources can be controlled by properly set dctx
+ res.append(node_res_dir(dirr.name,self,self.context,dirr))
+
+ fil_obj=dirobj.pool.get('ir.attachment')
+ where2 = where + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)]
+ # print "where clause for dir_obj", where2
+ ids = fil_obj.search(cr,uid,where2,context=ctx)
+ if ids:
+ for fil in fil_obj.browse(cr,uid,ids,context=ctx):
+ res.append(node_file(fil.name,self,self.context,fil))
+
+ return res
+
def create_child(self,cr,path,data):
- """ API function to create a child file object and node
- Return the node_* created
- """
- dirobj = self.context._dirobj
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- fil_obj=dirobj.pool.get('ir.attachment')
- val = {
- 'name': path,
- 'datas_fname': path,
- 'parent_id': self.dir_id,
- 'res_model': self.res_model,
- 'res_id': self.res_id,
- # Datas are not set here
- }
+ """ API function to create a child file object and node
+ Return the node_* created
+ """
+ dirobj = self.context._dirobj
+ uid = self.context.uid
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ fil_obj=dirobj.pool.get('ir.attachment')
+ val = {
+ 'name': path,
+ 'datas_fname': path,
+ 'parent_id': self.dir_id,
+ 'res_model': self.res_model,
+ 'res_id': self.res_id,
+ # Datas are not set here
+ }
- fil_id = fil_obj.create(cr,uid, val, context=ctx)
- fil = fil_obj.browse(cr,uid,fil_id,context=ctx)
- fnode = node_file(path,self,self.context,fil)
- fnode.set_data(cr,data,fil)
- return fnode
+ fil_id = fil_obj.create(cr,uid, val, context=ctx)
+ fil = fil_obj.browse(cr,uid,fil_id,context=ctx)
+ fnode = node_file(path,self,self.context,fil)
+ fnode.set_data(cr,data,fil)
+ return fnode
def _get_ttag(self,cr):
- return 'rodir-%d-%d' % (self.dir_id,self.res_id)
+ return 'rodir-%d-%d' % (self.dir_id,self.res_id)
class node_file(node_class):
our_type = 'file'
def __init__(self,path, parent, context, fil):
- super(node_file,self).__init__(path, parent,context)
- self.file_id = fil.id
- #todo: more info from ir_attachment
- if fil.file_type and '/' in fil.file_type:
- self.mimetype = fil.file_type
- self.create_date = fil.create_date
- self.write_date = fil.write_date or fil.create_date
- self.content_length = fil.file_size
- self.displayname = fil.name
-
- # This only propagates the problem to get_data. Better
- # fix those files to point to the root dir.
- if fil.parent_id:
- self.storage_id = fil.parent_id.storage_id.id
- else:
- self.storage_id = None
-
+ super(node_file,self).__init__(path, parent,context)
+ self.file_id = fil.id
+ #todo: more info from ir_attachment
+ if fil.file_type and '/' in fil.file_type:
+ self.mimetype = fil.file_type
+ self.create_date = fil.create_date
+ self.write_date = fil.write_date or fil.create_date
+ self.content_length = fil.file_size
+ self.displayname = fil.name
+
+ # This only propagates the problem to get_data. Better
+ # fix those files to point to the root dir.
+ if fil.parent_id:
+ self.storage_id = fil.parent_id.storage_id.id
+ else:
+ self.storage_id = None
+
def get_data(self, cr, fil_obj = None):
- """ Retrieve the data for some file.
- fil_obj may optionally be specified, and should be a browse object
- for the file. This is useful when the caller has already initiated
- the browse object. """
- # this is where storage kicks in..
- stor = self.storage_id
- assert stor
- stobj = self.context._dirobj.pool.get('document.storage')
- return stobj.get_data(cr,self.context.uid,stor, self,self.context.context, fil_obj)
+ """ Retrieve the data for some file.
+ fil_obj may optionally be specified, and should be a browse object
+ for the file. This is useful when the caller has already initiated
+ the browse object. """
+ # this is where storage kicks in..
+ stor = self.storage_id
+ assert stor
+ stobj = self.context._dirobj.pool.get('document.storage')
+ return stobj.get_data(cr,self.context.uid,stor, self,self.context.context, fil_obj)
def get_data_len(self, cr, fil_obj = None):
- # TODO: verify with the storage object!
- return self.content_length
+ # TODO: verify with the storage object!
+ return self.content_length
def set_data(self, cr, data, fil_obj = None):
- """ Store data at some file.
- fil_obj may optionally be specified, and should be a browse object
- for the file. This is useful when the caller has already initiated
- the browse object. """
- # this is where storage kicks in..
- stor = self.storage_id
- assert stor
- stobj = self.context._dirobj.pool.get('document.storage')
- return stobj.set_data(cr,self.context.uid,stor, self, data, self.context.context, fil_obj)
+ """ Store data at some file.
+ fil_obj may optionally be specified, and should be a browse object
+ for the file. This is useful when the caller has already initiated
+ the browse object. """
+ # this is where storage kicks in..
+ stor = self.storage_id
+ assert stor
+ stobj = self.context._dirobj.pool.get('document.storage')
+ return stobj.set_data(cr,self.context.uid,stor, self, data, self.context.context, fil_obj)
def _get_ttag(self,cr):
- return 'file-%d' % self.file_id
+ return 'file-%d' % self.file_id
class node_content(node_class):
our_type = 'content'
def __init__(self,path, parent, context, cnt, dctx = None, act_id=None):
- super(node_content,self).__init__(path, parent,context)
- self.cnt_id = cnt.id
- self.create_date = False
- self.write_date = False
- self.content_length = False
- self.extension = cnt.extension
- self.report_id = cnt.report_id and cnt.report_id.id
- #self.mimetype = cnt.extension.
- self.displayname = path
- if dctx:
- self.dctx.update(dctx)
- self.act_id = act_id
-
+ super(node_content,self).__init__(path, parent,context)
+ self.cnt_id = cnt.id
+ self.create_date = False
+ self.write_date = False
+ self.content_length = False
+ self.extension = cnt.extension
+ self.report_id = cnt.report_id and cnt.report_id.id
+ #self.mimetype = cnt.extension.
+ self.displayname = path
+ if dctx:
+ self.dctx.update(dctx)
+ self.act_id = act_id
+
def fill_fields(self,cr,dctx = None):
""" Try to read the object and fill missing fields, like mimetype,
dates etc.
@@ -610,17 +610,17 @@ class node_content(node_class):
def get_data(self, cr, fil_obj = None):
cntobj = self.context._dirobj.pool.get('document.directory.content')
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- data = cntobj.process_read(cr,self.context.uid,self,ctx)
- if data:
- self.content_length = len(data)
- return data
+ ctx = self.context.context.copy()
+ ctx.update(self.dctx)
+ data = cntobj.process_read(cr,self.context.uid,self,ctx)
+ if data:
+ self.content_length = len(data)
+ return data
def get_data_len(self, cr, fil_obj = None):
- if not self.content_length:
- self.get_data(cr,fil_obj)
- return self.content_length
+ if not self.content_length:
+ self.get_data(cr,fil_obj)
+ return self.content_length
def set_data(self, cr, data, fil_obj = None):
cntobj = self.context._dirobj.pool.get('document.directory.content')
@@ -651,9 +651,9 @@ class old_class():
if nodename:
where.append( (fobj._rec_name,'=',nodename) )
for content in self.object.content_ids:
- res3 = content._table._file_get(self,nodename,content)
- if res3:
- res2.extend(res3)
+ res3 = content._table._file_get(self,nodename,content)
+ if res3:
+ res2.extend(res3)
ids = fobj.search(self.cr, self.uid, where+[ ('parent_id','=',self.object and self.object.id or False) ])
if self.object and self.root and (self.object.type=='ressource'):
diff --git a/addons/document/std_index.py b/addons/document/std_index.py
index 730e5082a1b..a35f1ab615d 100644
--- a/addons/document/std_index.py
+++ b/addons/document/std_index.py
@@ -38,61 +38,61 @@ def _to_unicode(s):
return s
class TxtIndex(indexer):
- def _getMimeTypes(self):
- return ['text/plain','text/html','text/diff','text/xml', 'text/*',
- 'application/xml']
-
- def _getExtensions(self):
- return ['.txt', '.py']
+ def _getMimeTypes(self):
+ return ['text/plain','text/html','text/diff','text/xml', 'text/*',
+ 'application/xml']
+
+ def _getExtensions(self):
+ return ['.txt', '.py']
- def _doIndexContent(self,content):
- return content
-
+ def _doIndexContent(self,content):
+ return content
+
cntIndex.register(TxtIndex())
class DocIndex(indexer):
- def _getMimeTypes(self):
- return [ 'application/ms-word']
-
- def _getExtensions(self):
- return ['.doc']
+ def _getMimeTypes(self):
+ return [ 'application/ms-word']
+
+ def _getExtensions(self):
+ return ['.doc']
- def _doIndexFile(self,fname):
- fp = Popen(['antiword',fname], shell=False, stdout=PIPE).stdout
- return _to_unicode( fp.read())
+ def _doIndexFile(self,fname):
+ fp = Popen(['antiword',fname], shell=False, stdout=PIPE).stdout
+ return _to_unicode( fp.read())
cntIndex.register(DocIndex())
class PdfIndex(indexer):
- def _getMimeTypes(self):
- return [ 'application/pdf']
-
- def _getExtensions(self):
- return ['.pdf']
+ def _getMimeTypes(self):
+ return [ 'application/pdf']
+
+ def _getExtensions(self):
+ return ['.pdf']
- def _doIndexFile(self,fname):
- fp = Popen(['pdftotext', '-enc', 'UTF-8', '-nopgbrk', fname, '-'], shell=False, stdout=PIPE).stdout
- return _to_unicode( fp.read())
+ def _doIndexFile(self,fname):
+ fp = Popen(['pdftotext', '-enc', 'UTF-8', '-nopgbrk', fname, '-'], shell=False, stdout=PIPE).stdout
+ return _to_unicode( fp.read())
cntIndex.register(PdfIndex())
class ImageNoIndex(indexer):
- def _getMimeTypes(self):
- return [ 'image/*']
-
- def _getExtensions(self):
- #better return no extension, and let 'file' do its magic
- return []
- #return ['.png','.jpg','.gif','.jpeg','.bmp','.tiff']
+ def _getMimeTypes(self):
+ return [ 'image/*']
+
+ def _getExtensions(self):
+ #better return no extension, and let 'file' do its magic
+ return []
+ #return ['.png','.jpg','.gif','.jpeg','.bmp','.tiff']
- def _doIndexContent(self,content):
- return 'image'
+ def _doIndexContent(self,content):
+ return 'image'
cntIndex.register(ImageNoIndex())
#class Doc(indexer):
- #def _getDefMime(self,ext):
+ #def _getDefMime(self,ext):
#def content_index(content, filename=None, content_type=None):
#fname,ext = os.path.splitext(filename)
diff --git a/addons/document/test_cindex.py b/addons/document/test_cindex.py
index 9993ffad425..dc5fcf7ebeb 100755
--- a/addons/document/test_cindex.py
+++ b/addons/document/test_cindex.py
@@ -22,25 +22,25 @@ import content_index, std_index
from content_index import cntIndex
for fname in args:
- try:
- if options.docontent:
- fp = open(fname,'rb')
- content = fp.read()
- fp.close()
- res = cntIndex.doIndex(content,fname,None,None,True)
- else:
- res = cntIndex.doIndex(None, fname, None, fname,True)
+ try:
+ if options.docontent:
+ fp = open(fname,'rb')
+ content = fp.read()
+ fp.close()
+ res = cntIndex.doIndex(content,fname,None,None,True)
+ else:
+ res = cntIndex.doIndex(None, fname, None, fname,True)
- if res:
- print "Result: ", res[0]
- print res[1]
- else:
- print "No result"
- except Exception,e:
- import traceback,sys
- tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
- print "Traceback:",tb_s
- print "Exception: ",e
-
+ if res:
+ print "Result: ", res[0]
+ print res[1]
+ else:
+ print "No result"
+ except Exception,e:
+ import traceback,sys
+ tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
+ print "Traceback:",tb_s
+ print "Exception: ",e
+
#eof
From 307898c2a8152de4dabdce9a90a37f1412d74d80 Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Tue, 8 Dec 2009 19:00:41 +0530
Subject: [PATCH 004/123] [FIX] document: fixed problem on mkdir, remove,
create file, rename
bzr revid: hmo@tinyerp.com-20091208133041-ikpo3by8r8xbrthb
---
addons/document/directory_content.py | 20 +-
addons/document/document_directory.py | 6 +-
addons/document/document_storage.py | 11 +-
addons/document/ftpserver/abstracted_fs.py | 282 ++++++++++++---------
addons/document/nodes.py | 19 +-
5 files changed, 193 insertions(+), 145 deletions(-)
diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py
index dbd801d6be0..a43b5730627 100644
--- a/addons/document/directory_content.py
+++ b/addons/document/directory_content.py
@@ -24,8 +24,10 @@ from osv import osv, fields
from osv.orm import except_orm
import urlparse
+import netsvc
import os
import nodes
+import StringIO
class document_directory_content_type(osv.osv):
_name = 'document.directory.content.type'
@@ -71,17 +73,16 @@ class document_directory_content(osv.osv):
"""
# TODO: respect the context!
- if content.include_name and not node.object2:
+ model = node.res_model
+ if content.include_name and not model:
return False
res2 = []
tname = ''
if content.include_name:
- content_name = node.object2.name
- obj = pool.get(node.object.ressource_type_id.model)
- name_for = obj._name.split('.')[-1]
- if content_name and content_name.find(name_for) == 0 :
- content_name = content_name.replace(name_for,'')
+ content_name = node.displayname or ''
+ obj = node.context._dirobj.pool.get(model)
+ if content_name:
tname = (content.prefix or '') + content_name + (content.suffix or '') + (content.extension or '')
else:
tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '')
@@ -101,12 +102,13 @@ class document_directory_content(osv.osv):
if node.extension != '.pdf':
raise Exception("Invalid content: %s" % node.extension)
return True
+
def process_read(self, cr, uid, node):
if node.extension != '.pdf':
raise Exception("Invalid content: %s" % node.extension)
- report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.content.report_id.id)
- srv = netsvc.LocalService('report.'+report.report_name)
- pdf,pdftype = srv.create(cr, uid, [node.object.id], {}, {})
+ report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.report_id)
+ srv = netsvc.Service._services['report.'+report.report_name]
+ pdf,pdftype = srv.create(cr, uid, [node.context.context['res_id']], {}, {})
s = StringIO.StringIO(pdf)
s.name = node
return s
diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py
index 95e4d438b76..1f95fd6a61a 100644
--- a/addons/document/document_directory.py
+++ b/addons/document/document_directory.py
@@ -176,9 +176,9 @@ class document_directory(osv.osv):
did = root_id
duri = uri
path = []
- context = ncontext.context
- while len(duri):
- nid = self.search(cr,uid,[('parent_id','=',did),('name','=',duri[0]),('type','=','directory')], context=context)
+ context = ncontext.context
+ while len(duri):
+ nid = self.search(cr,uid,[('parent_id','=',did),('name','=',duri[0]),('type','=','directory')], context=context)
if not nid:
break
if len(nid)>1:
diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py
index 488a5ee7e6c..54e4ad3f9cf 100644
--- a/addons/document/document_storage.py
+++ b/addons/document/document_storage.py
@@ -190,11 +190,12 @@ class document_storage(osv.osv):
path = boo.path
try:
flag = None
- # This can be improved
- for dirs in os.listdir(path):
- if os.path.isdir(os.path.join(path,dirs)) and len(os.listdir(os.path.join(path,dirs)))<4000:
- flag = dirs
- break
+ # This can be improved
+ if os.path.isdir(path):
+ for dirs in os.listdir(path):
+ if os.path.isdir(os.path.join(path,dirs)) and len(os.listdir(os.path.join(path,dirs)))<4000:
+ flag = dirs
+ break
flag = flag or create_directory(path)
filename = random_name()
fname = os.path.join(path, flag, filename)
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py
index d795110d4ea..11fd56f976e 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document/ftpserver/abstracted_fs.py
@@ -13,6 +13,7 @@ import netsvc
import os
from service import security
from osv import osv
+from document.nodes import node_res_dir, node_res_obj
import stat
def log(message):
@@ -202,18 +203,13 @@ class abstracted_fs:
# Ok
def fs2ftp(self, node):
- res = '/'
+ res='/'
if node:
- path = node.path
- print '**********', path
- if isinstance(path,list):
- path = '/'.join(path)
- res = os.path.normpath(path)
+ res=os.path.normpath(''.join(node.full_path()))
res = res.replace("\\", "/")
while res[:2] == '//':
res = res[1:]
- if len(node.path):
- res = '/' + node.path[0] + '/' + _to_decode(res)
+ res='/' + node.context.dbname + '/' + _to_decode(res)
#res = node and ('/' + node.cr.dbname + '/' + _to_decode(self.ftpnorm(node.path))) or '/'
return res
@@ -235,16 +231,16 @@ class abstracted_fs:
# Ok
def create(self, node, objname, mode):
- objname=_to_unicode(objname)
- cr = node.cr
- uid = node.uid
- pool = pooler.get_pool(cr.dbname)
- child = node.child(objname)
+ objname = _to_unicode(objname)
+ uid = node.context.uid
+ pool = pooler.get_pool(node.context.dbname)
+ cr = pooler.get_db(node.context.dbname).cursor()
+ child = node.child(cr, objname)
if child:
if child.type in ('collection','database'):
raise OSError(1, 'Operation not permited.')
- if child.type=='content':
- s = content_wrapper(cr.dbname, uid, pool, child)
+ if child.type == 'content':
+ s = content_wrapper(node.context.dbname, uid, pool, child)
return s
try:
fobj = pool.get('ir.attachment')
@@ -252,29 +248,34 @@ class abstracted_fs:
# TODO: test if already exist and modify in this case if node.type=file
### checked already exits
- object2=node and node.object2 or False
- object=node and node.object or False
- cid=False
-
- where=[('name','=',objname)]
+ object2 = False
+ if isinstance(node, node_res_obj):
+ object2 = node and pool.get(node.context.context['res_model']).browse(cr, uid, node.context.context['res_id']) or False
+
+ cid = False
+ object = node.context._dirobj.browse(cr, uid, node.dir_id)
+ where = [('name','=',objname)]
if object and (object.type in ('directory')) or object2:
where.append(('parent_id','=',object.id))
else:
where.append(('parent_id','=',False))
if object2:
- where +=[('res_id','=',object2.id),('res_model','=',object2._name)]
+ where += [('res_id','=',object2.id),('res_model','=',object2._name)]
cids = fobj.search(cr, uid,where)
if len(cids):
- cid=cids[0]
+ cid = cids[0]
if not cid:
val = {
'name': objname,
'datas_fname': objname,
+ 'parent_id' : node.dir_id,
'datas': '',
'file_size': 0L,
'file_type': ext,
+ 'store_method' : (object.storage_id.type == 'filestore' and 'fs')\
+ or (object.storage_id.type == 'db' and 'db')
}
if object and (object.type in ('directory')) or not object2:
val['parent_id']= object and object.id or False
@@ -292,9 +293,9 @@ class abstracted_fs:
cid = fobj.create(cr, uid, val, context={})
cr.commit()
- s = file_wrapper('', cid, cr.dbname, uid, )
+ s = file_wrapper('', cid, node.context.dbname, uid, )
return s
- except Exception,e:
+ except Exception,e:
log(e)
raise OSError(1, 'Operation not permited.')
@@ -304,16 +305,23 @@ class abstracted_fs:
raise OSError(1, 'Operation not permited.')
# Reading operation
if node.type=='file':
+ cr = pooler.get_db(node.context.dbname).cursor()
+ uid = node.context.uid
if not self.isfile(node):
raise OSError(1, 'Operation not permited.')
- s = StringIO.StringIO(base64.decodestring(node.object.datas or ''))
+ fobj = node.context._dirobj.pool.get('ir.attachment').browse(cr, uid, node.file_id, context=node.context.context)
+ if fobj.store_method and fobj.store_method== 'fs' :
+ s = StringIO.StringIO(node.get_data(cr, fobj))
+ else:
+ s = StringIO.StringIO(base64.decodestring(fobj.db_datas or ''))
s.name = node
return s
elif node.type=='content':
- cr = node.cr
- uid = node.uid
- pool = pooler.get_pool(cr.dbname)
- return getattr(pool.get('document.directory.content'), 'process_read_'+node.content.extension[1:])(cr, uid, node)
+# cr = node.cr
+ uid = node.context.uid
+ cr = pooler.get_db(node.context.dbname).cursor()
+ pool = pooler.get_pool(node.context.dbname)
+ return getattr(pool.get('document.directory.content'), 'process_read')(cr, uid, node)
else:
raise OSError(1, 'Operation not permited.')
@@ -344,7 +352,7 @@ class abstracted_fs:
if dir:
cr = dir.cr
uid = dir.uid
- pool = pooler.get_pool(cr.dbname)
+ pool = pooler.get_pool(node.context.dbname)
object=dir and dir.object or False
object2=dir and dir.object2 or False
res=pool.get('ir.attachment').search(cr,uid,[('name','like',prefix),('parent_id','=',object and object.type in ('directory','ressource') and object.id or False),('res_id','=',object2 and object2.id or False),('res_model','=',object2 and object2._name or False)])
@@ -359,8 +367,8 @@ class abstracted_fs:
# Ok
def chdir(self, path):
if not path:
- self.cwd='/'
- return None
+ self.cwd = '/'
+ return None
if path.type in ('collection','database'):
self.cwd = self.fs2ftp(path)
else:
@@ -369,31 +377,36 @@ class abstracted_fs:
# Ok
def mkdir(self, node, basename):
"""Create the specified directory."""
+ cr = False
if not node:
raise OSError(1, 'Operation not permited.')
try:
- basename=_to_unicode(basename)
- object2=node and node.object2 or False
- object=node and node.object or False
- cr = node.cr
- uid = node.uid
- pool = pooler.get_pool(cr.dbname)
- if node.object and (node.object.type=='ressource') and not node.object2:
+ basename =_to_unicode(basename)
+ cr = pooler.get_db(node.context.dbname).cursor()
+ uid = node.context.uid
+ pool = pooler.get_pool(node.context.dbname)
+ object2 = False
+ if isinstance(node, node_res_obj):
+ object2 = node and pool.get(node.context.context['res_model']).browse(cr, uid, node.context.context['res_id']) or False
+ obj = node.context._dirobj.browse(cr, uid, node.dir_id)
+ if obj and (obj.type == 'ressource') and not object2:
raise OSError(1, 'Operation not permited.')
val = {
'name': basename,
- 'ressource_parent_type_id': object and object.ressource_type_id.id or False,
+ 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False,
'ressource_id': object2 and object2.id or False
}
- if (object and (object.type in ('directory'))) or not object2:
- val['parent_id'] = object and object.id or False
+ #if (obj and (obj.type in ('directory'))) or not object2:
+ # val['parent_id'] = obj and obj.id or False
+ val['parent_id'] = node.dir_id
# Check if it alreayd exists !
pool.get('document.directory').create(cr, uid, val)
- cr.commit()
+ cr.commit()
except Exception,e:
log(e)
raise OSError(1, 'Operation not permited.')
-
+ finally:
+ if cr: cr.close()
# Ok
def close_cr(self, data):
@@ -421,8 +434,9 @@ class abstracted_fs:
# Ok
def listdir(self, path):
"""List the content of a directory."""
- class false_node:
- object = None
+ class false_node(object):
+ write_date = None
+ create_date = None
type = 'database'
def __init__(self, db):
self.path = '/'+db
@@ -434,55 +448,83 @@ class abstracted_fs:
uid = security.login(db, self.username, self.password)
if uid:
result.append(false_node(db))
- except osv.except_osv:
+ except osv.except_osv:
pass
return result
- return path.children()
+ cr = pooler.get_db(path.context.dbname).cursor()
+ return path.children(cr)
# Ok
def rmdir(self, node):
"""Remove the specified directory."""
- cr = node.cr
- uid = node.uid
- pool = pooler.get_pool(cr.dbname)
- object2=node and node.object2 or False
- object=node and node.object or False
- if object._table_name=='document.directory':
- if node.children():
+ assert node
+ cr = pooler.get_db(node.context.dbname).cursor()
+ uid = node.context.uid
+ pool = pooler.get_pool(node.context.dbname)
+ object = node.context._dirobj.browse(cr, uid, node.dir_id)
+ if not object:
+ raise OSError(2, 'Not such file or directory.')
+ if object._table_name == 'document.directory':
+ if node.children(cr):
raise OSError(39, 'Directory not empty.')
res = pool.get('document.directory').unlink(cr, uid, [object.id])
else:
- raise OSError(39, 'Directory not empty.')
+ raise OSError(1, 'Operation not permited.')
cr.commit()
+ cr.close()
# Ok
def remove(self, node):
+ assert node
+ if node.type == 'collection':
+ return self.rmdir(node)
+ elif node.type == 'file':
+ return self.rmfile(node)
+ raise OSError(1, 'Operation not permited.')
+
+ def rmfile(self, node):
"""Remove the specified file."""
- cr = node.cr
- uid = node.uid
- pool = pooler.get_pool(cr.dbname)
- object2=node and node.object2 or False
- object=node and node.object or False
+ assert node
+ if node.type == 'collection':
+ return self.rmdir(node)
+ uid = node.context.uid
+ pool = pooler.get_pool(node.context.dbname)
+ cr = pooler.get_db(node.context.dbname).cursor()
+ object = pool.get('ir.attachment').browse(cr, uid, node.file_id)
if not object:
raise OSError(2, 'Not such file or directory.')
- if object._table_name=='ir.attachment':
+ if object._table_name == 'ir.attachment':
res = pool.get('ir.attachment').unlink(cr, uid, [object.id])
else:
raise OSError(1, 'Operation not permited.')
cr.commit()
+ cr.close()
# Ok
- def rename(self, src, dst_basedir,dst_basename):
+ def rename(self, src, dst_basedir, dst_basename):
"""
Renaming operation, the effect depends on the src:
* A file: read, create and remove
* A directory: change the parent and reassign childs to ressource
"""
+ cr = False
try:
- dst_basename=_to_unicode(dst_basename)
- if src.type=='collection':
- if src.object._table_name <> 'document.directory':
+ dst_basename = _to_unicode(dst_basename)
+ cr = pooler.get_db(src.context.dbname).cursor()
+ uid = src.context.uid
+
+ if src.type == 'collection':
+ obj2 = False
+ dst_obj2 = False
+ pool = pooler.get_pool(src.context.dbname)
+ if isinstance(src, node_res_obj):
+ obj2 = src and pool.get(src.context.context['res_model']).browse(cr, uid, src.context.context['res_id']) or False
+ obj = src.context._dirobj.browse(cr, uid, src.dir_id)
+ if isinstance(dst_basedir, node_res_obj):
+ dst_obj2 = dst_basedir and pool.get(dst_basedir.context.context['res_model']).browse(cr, uid, dst_basedir.context.context['res_id']) or False
+ dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id)
+ if obj._table_name <> 'document.directory':
raise OSError(1, 'Operation not permited.')
result = {
'directory': [],
@@ -491,44 +533,41 @@ class abstracted_fs:
# Compute all childs to set the new ressource ID
child_ids = [src]
while len(child_ids):
- node = child_ids.pop(0)
- child_ids += node.children()
- if node.type =='collection':
- result['directory'].append(node.object.id)
- if (not node.object.ressource_id) and node.object2:
+ node = child_ids.pop(0)
+ child_ids += node.children(cr)
+ object2 = node and hasattr(node, "res_model") and node.res_model or False
+ object = node.context._dirobj.browse(cr, uid, node.dir_id)
+ if node.type == 'collection':
+ result['directory'].append(object.id)
+ if (not object.ressource_id) and object2:
raise OSError(1, 'Operation not permited.')
- elif node.type =='file':
- result['attachment'].append(node.object.id)
+ elif node.type == 'file':
+ result['attachment'].append(object.id)
- cr = src.cr
- uid = src.uid
- pool = pooler.get_pool(cr.dbname)
- object2=src and src.object2 or False
- object=src and src.object or False
- if object2 and not object.ressource_id:
+
+ if obj2 and not obj.ressource_id:
raise OSError(1, 'Operation not permited.')
val = {
'name':dst_basename,
}
- if (dst_basedir.object and (dst_basedir.object.type in ('directory'))) or not dst_basedir.object2:
- val['parent_id'] = dst_basedir.object and dst_basedir.object.id or False
+ if (dst_obj and (dst_obj.type in ('directory'))) or not dst_obj2:
+ val['parent_id'] = dst_obj and dst_obj.id or False
else:
val['parent_id'] = False
- res = pool.get('document.directory').write(cr, uid, [object.id],val)
+ res = pool.get('document.directory').write(cr, uid, [obj.id], val)
- if dst_basedir.object2:
- ressource_type_id = pool.get('ir.model').search(cr,uid,[('model','=',dst_basedir.object2._name)])[0]
- ressource_id = dst_basedir.object2.id
- title = dst_basedir.object2.name
- ressource_model = dst_basedir.object2._name
- if dst_basedir.object2._name=='res.partner':
- partner_id=dst_basedir.object2.id
- else:
- obj2=pool.get(dst_basedir.object2._name)
- partner_id= obj2.fields_get(cr,uid,['partner_id']) and dst_basedir.object2.partner_id.id or False
+ if dst_obj2:
+ ressource_type_id = pool.get('ir.model').search(cr, uid, [('model','=',dst_obj2._name)])[0]
+ ressource_id = dst_obj2.id
+ title = dst_obj2.name
+ ressource_model = dst_obj2._name
+ if dst_obj2._name == 'res.partner':
+ partner_id = dst_obj2.id
+ else:
+ partner_id= pool.get(dst_obj2._name).fields_get(cr, uid, ['partner_id']) and dst_obj2.partner_id.id or False
else:
ressource_type_id = False
- ressource_id=False
+ ressource_id = False
ressource_model = False
partner_id = False
title = False
@@ -545,11 +584,17 @@ class abstracted_fs:
}
pool.get('ir.attachment').write(cr, uid, result['attachment'], val)
if (not val['res_id']) and result['attachment']:
- dst_basedir.cr.execute('update ir_attachment set res_id=NULL where id in ('+','.join(map(str,result['attachment']))+')')
+ cr.execute('update ir_attachment set res_id=NULL where id in ('+','.join(map(str,result['attachment']))+')')
cr.commit()
- elif src.type=='file':
- pool = pooler.get_pool(src.cr.dbname)
+ elif src.type == 'file':
+ pool = pooler.get_pool(src.context.dbname)
+ obj = pool.get('ir.attachment').browse(cr, uid, src.file_id)
+ dst_obj2 = False
+ if isinstance(dst_basedir, node_res_dir):
+ dst_obj2 = dst_basedir and dst_basedir.res_model or False
+ dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id)
+
val = {
'partner_id':False,
#'res_id': False,
@@ -559,40 +604,40 @@ class abstracted_fs:
'title': dst_basename,
}
- if (dst_basedir.object and (dst_basedir.object.type in ('directory','ressource'))) or not dst_basedir.object2:
- val['parent_id'] = dst_basedir.object and dst_basedir.object.id or False
+ if (dst_obj and (dst_obj.type in ('directory','ressource'))) or not dst_obj2:
+ val['parent_id'] = dst_obj and dst_obj.id or False
else:
val['parent_id'] = False
- if dst_basedir.object2:
- val['res_model'] = dst_basedir.object2._name
- val['res_id'] = dst_basedir.object2.id
- val['title'] = dst_basedir.object2.name
- if dst_basedir.object2._name=='res.partner':
- val['partner_id']=dst_basedir.object2.id
- else:
- obj2=pool.get(dst_basedir.object2._name)
- val['partner_id']= obj2.fields_get(src.cr, src.uid,['partner_id']) and dst_basedir.object2.partner_id.id or False
- elif src.object.res_id:
+ if dst_obj2:
+ val['res_model'] = dst_obj2._name
+ val['res_id'] = dst_obj2.id
+ val['title'] = dst_obj2.name
+ if dst_obj2._name == 'res.partner':
+ val['partner_id'] = dst_obj2.id
+ else:
+ val['partner_id'] = pool.get(dst_obj2._name).fields_get(src.cr, src.uid, ['partner_id']) and dst_obj2.partner_id.id or False
+ elif obj.res_id:
# I had to do that because writing False to an integer writes 0 instead of NULL
# change if one day we decide to improve osv/fields.py
- dst_basedir.cr.execute('update ir_attachment set res_id=NULL where id=%s', (src.object.id,))
+ cr.execute('update ir_attachment set res_id=NULL where id=%s', (obj.id,))
- pool.get('ir.attachment').write(src.cr, src.uid, [src.object.id], val)
- src.cr.commit()
+ pool.get('ir.attachment').write(cr, uid, [obj.id], val)
+ cr.commit()
elif src.type=='content':
- src_file=self.open(src,'r')
- dst_file=self.create(dst_basedir,dst_basename,'w')
+ src_file = self.open(src,'r')
+ dst_file = self.create(dst_basedir, dst_basename, 'w')
dst_file.write(src_file.getvalue())
dst_file.close()
src_file.close()
- src.cr.commit()
+ cr.commit()
else:
raise OSError(1, 'Operation not permited.')
except Exception,err:
log(err)
raise OSError(1,'Operation not permited.')
-
+ finally:
+ if cr: cr.close()
@@ -635,15 +680,16 @@ class abstracted_fs:
"""Return the size of the specified file in bytes."""
result = 0L
if node.type=='file':
- result = node.object.file_size or 0L
+ result = node.content_length or 0L
return result
# Ok
def getmtime(self, node):
"""Return the last modified time as a number of seconds since
the epoch."""
- if node.object and node.type<>'content':
- dt = (node.object.write_date or node.object.create_date)[:19]
+
+ if node.write_date or node.create_date:
+ dt = (node.write_date or node.create_date)[:19]
result = time.mktime(time.strptime(dt, '%Y-%m-%d %H:%M:%S'))
else:
result = time.mktime(time.localtime())
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index 845ba4e3ace..42a0e21f2f7 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -51,7 +51,7 @@ class node_context(object):
def __init__(self, cr, uid, context=None):
# we don't cache the cr!
- #self.cr = cr
+ self.dbname = cr.dbname
self.uid = uid
self.context = context
self._dirobj = pooler.get_pool(cr.dbname).get('document.directory')
@@ -114,7 +114,7 @@ class node_class(object):
s+=self.path
else:
s.append(self.path)
- return s
+ return map(lambda x: '/' +x, s)
def children(self, cr):
print "node_class.children()"
@@ -318,6 +318,7 @@ class node_res_dir(node_class):
self.namefield = dirr.resource_field or 'name'
self.displayname = dirr.name
# Important: the domain is evaluated using the *parent* dctx!
+ self.dctx.update({'active_id': self.context.context['dir_id']})
self.domain = safe_eval(dirr.domain,self.dctx)
# and then, we add our own vars in the dctx:
if dctx:
@@ -353,14 +354,13 @@ class node_res_dir(node_class):
ctx.update(self.dctx)
where = []
if self.domain:
- where.append(self.domain)
+ where += self.domain
if self.resm_id:
where.append(('id','=',self.resm_id))
if name:
where.append((self.namefield,'=',name))
- # print "Where clause for %s" % self.res_model, where
-
+ # print "Where clause for %s" % self.res_model, where
resids = obj.search(cr,uid, where, context=ctx)
res = []
for bo in obj.browse(cr,uid,resids,context=ctx):
@@ -396,8 +396,7 @@ class node_res_obj(node_class):
self.content_length = 0
self.res_model = res_model
self.domain = parent.domain
- self.displayname = path
-
+ self.displayname = path
if res_bo:
self.res_id = res_bo.id
dc2 = self.context.context
@@ -415,10 +414,10 @@ class node_res_obj(node_class):
else:
self.res_id = res_id
- def children(self,cr):
+ def children(self,cr):
return self._child_get(cr) + self._file_get(cr)
- def child(self,cr, name):
+ def child(self,cr, name):
res = self._child_get(cr,name)
if res:
return res[0]
@@ -481,7 +480,7 @@ class node_res_obj(node_class):
ctx.update(self.dctx)
where = [('parent_id','=',self.dir_id) ]
if name:
- where.append(('name','=',name))
+ where.append(('name','=',name))
ids = dirobj.search(cr, uid, where,context=ctx)
res = []
if ids:
From 8777bb210a334f27f64e380131d7f050f2a35f8c Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Wed, 9 Dec 2009 17:10:28 +0530
Subject: [PATCH 005/123] [FIX] document :directory tree structure is work fine
now
bzr revid: hmo@tinyerp.com-20091209114028-wulu72g9qfd9e2rj
---
addons/document/ftpserver/abstracted_fs.py | 2 +-
addons/document/nodes.py | 54 ++++++++++++++++------
2 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py
index 11fd56f976e..8fcbac6734c 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document/ftpserver/abstracted_fs.py
@@ -451,7 +451,7 @@ class abstracted_fs:
except osv.except_osv:
pass
return result
- cr = pooler.get_db(path.context.dbname).cursor()
+ cr = pooler.get_db(path.context.dbname).cursor()
return path.children(cr)
# Ok
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index 42a0e21f2f7..fb377fed03c 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -64,7 +64,7 @@ class node_context(object):
(ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
- while duri:
+ while duri:
ndir = ndir.child(cr, duri[0])
if not ndir:
return False
@@ -320,6 +320,7 @@ class node_res_dir(node_class):
# Important: the domain is evaluated using the *parent* dctx!
self.dctx.update({'active_id': self.context.context['dir_id']})
self.domain = safe_eval(dirr.domain,self.dctx)
+ self.ressource_tree = dirr.ressource_tree
# and then, we add our own vars in the dctx:
if dctx:
self.dctx.update(dctx)
@@ -349,6 +350,7 @@ class node_res_dir(node_class):
if not obj:
print "couldn't find model", self.res_model
return []
+ dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
@@ -360,16 +362,24 @@ class node_res_dir(node_class):
if name:
where.append((self.namefield,'=',name))
- # print "Where clause for %s" % self.res_model, where
+ # print "Where clause for %s" % self.res_model, where
+ if self.ressource_tree:
+ object2 = False
+ if self.resm_id:
+ object2 = dirobj.pool.get(self.res_model).browse(cr, uid, self.resm_id) or False
+ if obj._parent_name in obj.fields_get(cr, uid):
+ where.append((obj._parent_name,'=',object2 and object2.id or False))
+
resids = obj.search(cr,uid, where, context=ctx)
- res = []
+ res = []
for bo in obj.browse(cr,uid,resids,context=ctx):
if not bo:
continue
name = getattr(bo,self.namefield)
if not name:
continue
- # Yes! we can't do better but skip nameless records.
+ # Yes! we can't do better but skip nameless records.
+
res.append(node_res_obj(name,self,self.context,self.res_model, bo))
return res
@@ -386,7 +396,7 @@ class node_res_obj(node_class):
def __init__(self,path, parent, context, res_model, res_bo, res_id = None):
super(node_res_obj,self).__init__(path, parent,context)
assert parent
- #todo: more info from dirr
+ #todo: more info from dirr
self.dir_id = parent.dir_id
self.mimetype = 'application/x-directory'
# 'httpd/unix-directory'
@@ -396,15 +406,16 @@ class node_res_obj(node_class):
self.content_length = 0
self.res_model = res_model
self.domain = parent.domain
- self.displayname = path
- if res_bo:
- self.res_id = res_bo.id
+ self.displayname = path
+ self.dctx_dict = parent.dctx_dict
+ if res_bo:
+ self.res_id = res_bo.id
dc2 = self.context.context
dc2.update(self.dctx)
dc2['res_model'] = res_model
dc2['res_id'] = res_bo.id
- dc2['this'] = res_bo
- for fld,expr in parent.dctx_dict.items():
+ dc2['this'] = res_bo
+ for fld,expr in self.dctx_dict.items():
try:
self.dctx[fld] = safe_eval(expr,dc2)
except Exception,e:
@@ -478,10 +489,27 @@ class node_res_obj(node_class):
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
- where = [('parent_id','=',self.dir_id) ]
+ directory = dirobj.browse(cr, uid, self.dir_id)
+ obj = dirobj.pool.get(self.res_model)
+ where = []
if name:
- where.append(('name','=',name))
- ids = dirobj.search(cr, uid, where,context=ctx)
+ where.append(('name','=',name))
+ if self.res_id and directory.ressource_tree:
+ if obj._parent_name in obj.fields_get(cr, uid):
+ where.append((obj._parent_name, '=', self.res_id))
+ resids = obj.search(cr,uid, where, context=ctx)
+ res = []
+ for bo in obj.browse(cr,uid,resids,context=ctx):
+ namefield = directory.resource_field or 'name'
+ if not bo:
+ continue
+ name = getattr(bo, namefield)
+ if not name:
+ continue
+ res.append(node_res_obj(name, self, self.context, self.res_model, res_bo = bo))
+ return res
+ where = [('parent_id','=',self.dir_id) ]
+ ids = dirobj.search(cr, uid, where,context=ctx)
res = []
if ids:
for dirr in dirobj.browse(cr,uid,ids,context=ctx):
From 21b45c94bca3e962c668bf7fd5574cdf695e20ea Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Wed, 9 Dec 2009 18:48:51 +0530
Subject: [PATCH 006/123] [FIX] document : fix problem to get files of res obj
node
bzr revid: hmo@tinyerp.com-20091209131851-07u1bp2gqwxv1ady
---
addons/document/nodes.py | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index fb377fed03c..ac15b0a359c 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -62,13 +62,12 @@ class node_context(object):
""" Although this fn passes back to doc.dir, it is needed since
it is a potential caching point """
- (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
-
+ (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
while duri:
ndir = ndir.child(cr, duri[0])
if not ndir:
- return False
- duri = duri[1:]
+ return False
+ duri = duri[1:]
return ndir
@@ -506,11 +505,11 @@ class node_res_obj(node_class):
name = getattr(bo, namefield)
if not name:
continue
- res.append(node_res_obj(name, self, self.context, self.res_model, res_bo = bo))
- return res
+ res.append(node_res_obj(name, self, self.context, self.res_model, res_bo = bo))
+ if name:
+ where.append(('name','=',name))
where = [('parent_id','=',self.dir_id) ]
- ids = dirobj.search(cr, uid, where,context=ctx)
- res = []
+ ids = dirobj.search(cr, uid, where,context=ctx)
if ids:
for dirr in dirobj.browse(cr,uid,ids,context=ctx):
if dirr.type == 'directory':
From 8041b935d8aad8c9f25ddef7a7681b7a2e6d1570 Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Wed, 9 Dec 2009 18:42:54 +0100
Subject: [PATCH 007/123] [FIX] #494620 missing company_id in domain that
return the bad company when there is a multiple rules for teh same
object
lp bug: https://launchpad.net/bugs/494620 fixed
bzr revid: christophe.chauvet@syleam.fr-20091209174254-pu5oxg8e4saqd48p
---
bin/addons/base/res/res_company.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/bin/addons/base/res/res_company.py b/bin/addons/base/res/res_company.py
index acd1e85a184..7ec19a971ff 100644
--- a/bin/addons/base/res/res_company.py
+++ b/bin/addons/base/res/res_company.py
@@ -94,13 +94,14 @@ class res_company(osv.osv):
"""
if not context:
context = {}
+ user_company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
proxy = self.pool.get('multi_company.default')
- ids = proxy.search(cr, uid, [('object_id.model', '=', object)])
+ ids = proxy.search(cr, uid, [('object_id.model', '=', object), ('company_id','=',user_company_id)])
for rule in proxy.browse(cr, uid, ids, context):
user = self.pool.get('res.users').browse(cr, uid, uid)
if eval(rule.expression, {'context': context, 'user': user}):
return rule.company_dest_id.id
- return self.pool.get('res.users').browse(cr, uid, uid).company_id.id
+ return user_company_id
def _get_child_ids(self, cr, uid, uid2, context={}):
company = self.pool.get('res.users').company_get(cr, uid, uid2)
From 74d49f77e36394f0cec0fd57b06463ba00d38a21 Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Wed, 9 Dec 2009 21:27:33 +0100
Subject: [PATCH 008/123] [IMP] Name field in default company is too small,
extend to 256
bzr revid: christophe.chauvet@syleam.fr-20091209202733-n8m5z275ms49r9jq
---
bin/addons/base/res/res_company.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/addons/base/res/res_company.py b/bin/addons/base/res/res_company.py
index 7ec19a971ff..d40894968e1 100644
--- a/bin/addons/base/res/res_company.py
+++ b/bin/addons/base/res/res_company.py
@@ -36,7 +36,7 @@ class multi_company_default(osv.osv):
_columns = {
'sequence': fields.integer('Sequence'),
- 'name': fields.char('Name', size=32, required=True, help='Name it to easily find a record'),
+ 'name': fields.char('Name', size=256, required=True, help='Name it to easily find a record'),
'company_id': fields.many2one('res.company', 'Main Company', required=True,
help='Company where the user is connected'),
'company_dest_id': fields.many2one('res.company', 'Default Company', required=True,
From ee05dd4cf652d34f0f9084b890044b30c188b52e Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 10 Dec 2009 12:00:00 +0530
Subject: [PATCH 009/123] [FIX] document: close cursor if not need
bzr revid: hmo@tinyerp.com-20091210063000-pu3q9dhpgnurw3eo
---
addons/document/ftpserver/abstracted_fs.py | 41 ++++++++++++++--------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py
index 8fcbac6734c..017ef584d51 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document/ftpserver/abstracted_fs.py
@@ -205,7 +205,7 @@ class abstracted_fs:
def fs2ftp(self, node):
res='/'
if node:
- res=os.path.normpath(''.join(node.full_path()))
+ res = os.path.normpath(''.join(node.full_path()))
res = res.replace("\\", "/")
while res[:2] == '//':
res = res[1:]
@@ -231,18 +231,19 @@ class abstracted_fs:
# Ok
def create(self, node, objname, mode):
- objname = _to_unicode(objname)
- uid = node.context.uid
- pool = pooler.get_pool(node.context.dbname)
- cr = pooler.get_db(node.context.dbname).cursor()
- child = node.child(cr, objname)
- if child:
- if child.type in ('collection','database'):
- raise OSError(1, 'Operation not permited.')
- if child.type == 'content':
- s = content_wrapper(node.context.dbname, uid, pool, child)
- return s
+ objname = _to_unicode(objname)
+ cr = None
try:
+ uid = node.context.uid
+ pool = pooler.get_pool(node.context.dbname)
+ cr = pooler.get_db(node.context.dbname).cursor()
+ child = node.child(cr, objname)
+ if child:
+ if child.type in ('collection','database'):
+ raise OSError(1, 'Operation not permited.')
+ if child.type == 'content':
+ s = content_wrapper(node.context.dbname, uid, pool, child)
+ return s
fobj = pool.get('ir.attachment')
ext = objname.find('.') >0 and objname.split('.')[1] or False
@@ -298,6 +299,9 @@ class abstracted_fs:
except Exception,e:
log(e)
raise OSError(1, 'Operation not permited.')
+ finally:
+ if cr:
+ cr.close()
# Ok
def open(self, node, mode):
@@ -315,13 +319,15 @@ class abstracted_fs:
else:
s = StringIO.StringIO(base64.decodestring(fobj.db_datas or ''))
s.name = node
+ cr.close()
return s
elif node.type=='content':
-# cr = node.cr
uid = node.context.uid
cr = pooler.get_db(node.context.dbname).cursor()
pool = pooler.get_pool(node.context.dbname)
- return getattr(pool.get('document.directory.content'), 'process_read')(cr, uid, node)
+ res = getattr(pool.get('document.directory.content'), 'process_read')(cr, uid, node)
+ cr.close()
+ return res
else:
raise OSError(1, 'Operation not permited.')
@@ -371,6 +377,9 @@ class abstracted_fs:
return None
if path.type in ('collection','database'):
self.cwd = self.fs2ftp(path)
+ elif path.type in ('file'):
+ parent_path = path.full_path()[:-1]
+ self.cwd = os.path.normpath(''.join(parent_path))
else:
raise OSError(1, 'Operation not permited.')
@@ -452,7 +461,9 @@ class abstracted_fs:
pass
return result
cr = pooler.get_db(path.context.dbname).cursor()
- return path.children(cr)
+ res = path.children(cr)
+ cr.close()
+ return res
# Ok
def rmdir(self, node):
From 51d35e7dd61b9491b32bd397db548d014d21322f Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 10 Dec 2009 12:02:55 +0530
Subject: [PATCH 010/123] [FIX] document : fixed small problem
bzr revid: hmo@tinyerp.com-20091210063255-492nlwzb80lwb3tc
---
addons/document/nodes.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index ac15b0a359c..4458e00ad4d 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -491,13 +491,13 @@ class node_res_obj(node_class):
directory = dirobj.browse(cr, uid, self.dir_id)
obj = dirobj.pool.get(self.res_model)
where = []
+ res = []
if name:
- where.append(('name','=',name))
+ where.append(('name','=',name))
if self.res_id and directory.ressource_tree:
if obj._parent_name in obj.fields_get(cr, uid):
where.append((obj._parent_name, '=', self.res_id))
- resids = obj.search(cr,uid, where, context=ctx)
- res = []
+ resids = obj.search(cr,uid, where, context=ctx)
for bo in obj.browse(cr,uid,resids,context=ctx):
namefield = directory.resource_field or 'name'
if not bo:
From 4a6d0a4a5112de7c89e8fe468f5ea0470ab01acf Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 10 Dec 2009 14:33:05 +0530
Subject: [PATCH 011/123] [FIX] document : child resources display now
bzr revid: hmo@tinyerp.com-20091210090305-nqg64404mn367nz5
---
addons/document/nodes.py | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index 4458e00ad4d..9bc3de05bfa 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -251,8 +251,9 @@ class node_dir(node_class):
ctx.update(self.dctx)
where = [('parent_id','=',self.dir_id) ]
if name:
- where.append(('name','=',name))
- ids = dirobj.search(cr, uid, where,context=ctx)
+ where.append(('name','=',name))
+
+ ids = dirobj.search(cr, uid, where + [('ressource_parent_type_id','=',False)],context=ctx)
res = []
if ids:
for dirr in dirobj.browse(cr,uid,ids,context=ctx):
@@ -316,9 +317,8 @@ class node_res_dir(node_class):
self.resm_id = dirr.ressource_id
self.namefield = dirr.resource_field or 'name'
self.displayname = dirr.name
- # Important: the domain is evaluated using the *parent* dctx!
- self.dctx.update({'active_id': self.context.context['dir_id']})
- self.domain = safe_eval(dirr.domain,self.dctx)
+ # Important: the domain is evaluated using the *parent* dctx!
+ self.domain = dirr.domain
self.ressource_tree = dirr.ressource_tree
# and then, we add our own vars in the dctx:
if dctx:
@@ -355,12 +355,13 @@ class node_res_dir(node_class):
ctx.update(self.dctx)
where = []
if self.domain:
- where += self.domain
+ where += safe_eval(self.domain, self.dctx)
if self.resm_id:
where.append(('id','=',self.resm_id))
if name:
where.append((self.namefield,'=',name))
+
# print "Where clause for %s" % self.res_model, where
if self.ressource_tree:
object2 = False
@@ -491,13 +492,16 @@ class node_res_obj(node_class):
directory = dirobj.browse(cr, uid, self.dir_id)
obj = dirobj.pool.get(self.res_model)
where = []
- res = []
+ res = []
if name:
- where.append(('name','=',name))
- if self.res_id and directory.ressource_tree:
+ where.append(('name','=',name))
+
+ # Directory Structure display in tree structure
+ if self.res_id and directory.ressource_tree:
+ where1 = where
if obj._parent_name in obj.fields_get(cr, uid):
- where.append((obj._parent_name, '=', self.res_id))
- resids = obj.search(cr,uid, where, context=ctx)
+ where1 += [(obj._parent_name, '=', self.res_id)]
+ resids = obj.search(cr,uid, where1, context=ctx)
for bo in obj.browse(cr,uid,resids,context=ctx):
namefield = directory.resource_field or 'name'
if not bo:
@@ -505,9 +509,15 @@ class node_res_obj(node_class):
name = getattr(bo, namefield)
if not name:
continue
- res.append(node_res_obj(name, self, self.context, self.res_model, res_bo = bo))
- if name:
- where.append(('name','=',name))
+ res.append(node_res_obj(name, self, self.context, self.res_model, res_bo = bo))
+
+ # Get Child Ressource Directories
+ where12 = [('ressource_parent_type_id','=',directory.ressource_type_id.id)]
+ dirids = dirobj.search(cr,uid, where12)
+ for dirr in dirobj.browse(cr, uid, dirids, context=ctx):
+ if dirr.type == 'ressource':
+ res.append(node_res_dir(dirr.name, self, self.context, dirr, {'active_id': self.res_id}))
+
where = [('parent_id','=',self.dir_id) ]
ids = dirobj.search(cr, uid, where,context=ctx)
if ids:
@@ -516,7 +526,7 @@ class node_res_obj(node_class):
res.append(node_res_obj(dirr.name,self,self.context,self.res_model,res_bo = None, res_id = self.res_id))
elif dirr.type == 'ressource':
# child resources can be controlled by properly set dctx
- res.append(node_res_dir(dirr.name,self,self.context,dirr))
+ res.append(node_res_dir(dirr.name,self,self.context, dirr, {'active_id': self.res_id}))
fil_obj=dirobj.pool.get('ir.attachment')
where2 = where + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)]
From 7c11b0e8fed2ff9ac716557eb352f661faa4fa09 Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Tue, 15 Dec 2009 16:18:10 +0530
Subject: [PATCH 012/123] [FIX+IMP] document: fixed problem on rename file and
directory of sub-directory of ressource directory
bzr revid: hmo@tinyerp.com-20091215104810-vi711k1ny28a55uc
---
addons/document/document_directory.py | 1 +
addons/document/ftpserver/abstracted_fs.py | 62 +++++++--------
addons/document/nodes.py | 90 ++++++++++++----------
3 files changed, 81 insertions(+), 72 deletions(-)
diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py
index 1f95fd6a61a..d4232caadb2 100644
--- a/addons/document/document_directory.py
+++ b/addons/document/document_directory.py
@@ -27,6 +27,7 @@ import urlparse
import os
import nodes
+from tools.translate import _
class document_directory(osv.osv):
_name = 'document.directory'
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py
index 017ef584d51..0073b26b9f2 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document/ftpserver/abstracted_fs.py
@@ -189,13 +189,13 @@ class abstracted_fs:
# Ok
def ftp2fs(self, path_orig, data):
- path = self.ftpnorm(path_orig)
+ path = self.ftpnorm(path_orig)
if not data or (path and path=='/'):
return None
path2 = filter(None,path.split('/'))[1:]
(cr, uid, pool) = data
if len(path2):
- path2[-1]=_to_unicode(path2[-1])
+ path2[-1]=_to_unicode(path2[-1])
res = pool.get('document.directory').get_object(cr, uid, path2[:])
if not res:
raise OSError(2, 'Not such file or directory.')
@@ -209,7 +209,7 @@ class abstracted_fs:
res = res.replace("\\", "/")
while res[:2] == '//':
res = res[1:]
- res='/' + node.context.dbname + '/' + _to_decode(res)
+ res = '/' + node.context.dbname + '/' + _to_decode(res)
#res = node and ('/' + node.cr.dbname + '/' + _to_decode(self.ftpnorm(node.path))) or '/'
return res
@@ -403,11 +403,11 @@ class abstracted_fs:
val = {
'name': basename,
'ressource_parent_type_id': obj and obj.ressource_type_id.id or False,
- 'ressource_id': object2 and object2.id or False
+ 'ressource_id': object2 and object2.id or False,
+ 'parent_id' : False
}
- #if (obj and (obj.type in ('directory'))) or not object2:
- # val['parent_id'] = obj and obj.id or False
- val['parent_id'] = node.dir_id
+ if (obj and (obj.type in ('directory'))) or not object2:
+ val['parent_id'] = obj and obj.id or False
# Check if it alreayd exists !
pool.get('document.directory').create(cr, uid, val)
cr.commit()
@@ -523,8 +523,7 @@ class abstracted_fs:
try:
dst_basename = _to_unicode(dst_basename)
cr = pooler.get_db(src.context.dbname).cursor()
- uid = src.context.uid
-
+ uid = src.context.uid
if src.type == 'collection':
obj2 = False
dst_obj2 = False
@@ -534,40 +533,39 @@ class abstracted_fs:
obj = src.context._dirobj.browse(cr, uid, src.dir_id)
if isinstance(dst_basedir, node_res_obj):
dst_obj2 = dst_basedir and pool.get(dst_basedir.context.context['res_model']).browse(cr, uid, dst_basedir.context.context['res_id']) or False
- dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id)
+ dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id)
if obj._table_name <> 'document.directory':
raise OSError(1, 'Operation not permited.')
result = {
'directory': [],
'attachment': []
}
- # Compute all childs to set the new ressource ID
+ # Compute all childs to set the new ressource ID
child_ids = [src]
while len(child_ids):
node = child_ids.pop(0)
- child_ids += node.children(cr)
- object2 = node and hasattr(node, "res_model") and node.res_model or False
- object = node.context._dirobj.browse(cr, uid, node.dir_id)
+ child_ids += node.children(cr)
if node.type == 'collection':
+ object2 = False
+ if isinstance(node, node_res_obj):
+ object2 = node and pool.get(node.context.context['res_model']).browse(cr, uid, node.context.context['res_id']) or False
+ object = node.context._dirobj.browse(cr, uid, node.dir_id)
result['directory'].append(object.id)
if (not object.ressource_id) and object2:
raise OSError(1, 'Operation not permited.')
elif node.type == 'file':
result['attachment'].append(object.id)
-
if obj2 and not obj.ressource_id:
raise OSError(1, 'Operation not permited.')
- val = {
- 'name':dst_basename,
- }
+
if (dst_obj and (dst_obj.type in ('directory'))) or not dst_obj2:
- val['parent_id'] = dst_obj and dst_obj.id or False
+ parent_id = dst_obj and dst_obj.id or False
else:
- val['parent_id'] = False
- res = pool.get('document.directory').write(cr, uid, [obj.id], val)
-
- if dst_obj2:
+ parent_id = False
+
+
+ if dst_obj2:
ressource_type_id = pool.get('ir.model').search(cr, uid, [('model','=',dst_obj2._name)])[0]
ressource_id = dst_obj2.id
title = dst_obj2.name
@@ -575,17 +573,18 @@ class abstracted_fs:
if dst_obj2._name == 'res.partner':
partner_id = dst_obj2.id
else:
- partner_id= pool.get(dst_obj2._name).fields_get(cr, uid, ['partner_id']) and dst_obj2.partner_id.id or False
+ partner_id = pool.get(dst_obj2._name).fields_get(cr, uid, ['partner_id']) and dst_obj2.partner_id.id or False
else:
ressource_type_id = False
ressource_id = False
ressource_model = False
partner_id = False
- title = False
-
+ title = False
pool.get('document.directory').write(cr, uid, result['directory'], {
+ 'name' : dst_basename,
'ressource_id': ressource_id,
- 'ressource_type_id': ressource_type_id
+ 'ressource_parent_type_id': ressource_type_id,
+ 'parent_id' : parent_id
})
val = {
'res_id': ressource_id,
@@ -598,12 +597,13 @@ class abstracted_fs:
cr.execute('update ir_attachment set res_id=NULL where id in ('+','.join(map(str,result['attachment']))+')')
cr.commit()
+
elif src.type == 'file':
pool = pooler.get_pool(src.context.dbname)
obj = pool.get('ir.attachment').browse(cr, uid, src.file_id)
- dst_obj2 = False
- if isinstance(dst_basedir, node_res_dir):
- dst_obj2 = dst_basedir and dst_basedir.res_model or False
+ dst_obj2 = False
+ if isinstance(dst_basedir, node_res_obj):
+ dst_obj2 = dst_basedir and pool.get(dst_basedir.context.context['res_model']).browse(cr, uid, dst_basedir.context.context['res_id']) or False
dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id)
val = {
@@ -627,7 +627,7 @@ class abstracted_fs:
if dst_obj2._name == 'res.partner':
val['partner_id'] = dst_obj2.id
else:
- val['partner_id'] = pool.get(dst_obj2._name).fields_get(src.cr, src.uid, ['partner_id']) and dst_obj2.partner_id.id or False
+ val['partner_id'] = pool.get(dst_obj2._name).fields_get(cr, uid, ['partner_id']) and dst_obj2.partner_id.id or False
elif obj.res_id:
# I had to do that because writing False to an integer writes 0 instead of NULL
# change if one day we decide to improve osv/fields.py
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index 9bc3de05bfa..e6a614bf6aa 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -60,14 +60,13 @@ class node_context(object):
def get_uri(self, cr, uri):
""" Although this fn passes back to doc.dir, it is needed since
- it is a potential caching point """
-
- (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
- while duri:
- ndir = ndir.child(cr, duri[0])
+ it is a potential caching point """
+ (ndir, duri) = self._dirobj._locate_child(cr,self.uid, self.rootdir,uri, None, self)
+ while duri:
+ ndir = ndir.child(cr, duri[0])
if not ndir:
return False
- duri = duri[1:]
+ duri = duri[1:]
return ndir
@@ -190,7 +189,7 @@ class node_dir(node_class):
def children(self,cr):
return self._child_get(cr) + self._file_get(cr)
- def child(self,cr, name):
+ def child(self,cr, name):
res = self._child_get(cr,name)
if res:
return res[0]
@@ -332,7 +331,7 @@ class node_res_dir(node_class):
def children(self,cr):
return self._child_get(cr)
- def child(self,cr, name):
+ def child(self,cr, name):
res = self._child_get(cr,name)
if res:
return res[0]
@@ -380,7 +379,7 @@ class node_res_dir(node_class):
continue
# Yes! we can't do better but skip nameless records.
- res.append(node_res_obj(name,self,self.context,self.res_model, bo))
+ res.append(node_res_obj(name, self.dir_id, self, self.context, self.res_model, bo))
return res
def _get_ttag(self,cr):
@@ -393,11 +392,11 @@ class node_res_obj(node_class):
node_dirs (with limited domain).
"""
our_type = 'collection'
- def __init__(self,path, parent, context, res_model, res_bo, res_id = None):
+ def __init__(self, path, dir_id, parent, context, res_model, res_bo, res_id = None):
super(node_res_obj,self).__init__(path, parent,context)
assert parent
- #todo: more info from dirr
- self.dir_id = parent.dir_id
+ #todo: more info from dirr
+ self.dir_id = dir_id
self.mimetype = 'application/x-directory'
# 'httpd/unix-directory'
self.create_date = parent.create_date
@@ -428,8 +427,8 @@ class node_res_obj(node_class):
def children(self,cr):
return self._child_get(cr) + self._file_get(cr)
- def child(self,cr, name):
- res = self._child_get(cr,name)
+ def child(self,cr, name):
+ res = self._child_get(cr,name)
if res:
return res[0]
res = self._file_get(cr,name)
@@ -484,7 +483,7 @@ class node_res_obj(node_class):
return ('vevent-collection','http://groupdav.org/')
return None
- def _child_get(self,cr,name = None):
+ def _child_get(self,cr,name = None):
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
@@ -498,44 +497,53 @@ class node_res_obj(node_class):
# Directory Structure display in tree structure
if self.res_id and directory.ressource_tree:
- where1 = where
+ where1 = []
if obj._parent_name in obj.fields_get(cr, uid):
- where1 += [(obj._parent_name, '=', self.res_id)]
+ where1 = where + [(obj._parent_name, '=', self.res_id)]
resids = obj.search(cr,uid, where1, context=ctx)
for bo in obj.browse(cr,uid,resids,context=ctx):
namefield = directory.resource_field or 'name'
if not bo:
continue
- name = getattr(bo, namefield)
- if not name:
+ res_name = getattr(bo, namefield)
+ if not res_name:
continue
- res.append(node_res_obj(name, self, self.context, self.res_model, res_bo = bo))
+ res.append(node_res_obj(res_name, self.dir_id, self, self.context, self.res_model, res_bo = bo))
+
+
+ where2 = where + [('parent_id','=',self.dir_id) ]
+ ids = dirobj.search(cr, uid, where2, context=ctx)
+ for dirr in dirobj.browse(cr, uid, ids, context=ctx):
+ if dirr.type == 'directory':
+ res.append(node_res_obj(dirr.name, dirr.id, self, self.context, self.res_model, res_bo = None, res_id = self.res_id))
+ elif dirr.type == 'ressource':
+ # child resources can be controlled by properly set dctx
+ res.append(node_res_dir(dirr.name,self,self.context, dirr, {'active_id': self.res_id}))
+
- # Get Child Ressource Directories
- where12 = [('ressource_parent_type_id','=',directory.ressource_type_id.id)]
- dirids = dirobj.search(cr,uid, where12)
- for dirr in dirobj.browse(cr, uid, dirids, context=ctx):
- if dirr.type == 'ressource':
- res.append(node_res_dir(dirr.name, self, self.context, dirr, {'active_id': self.res_id}))
+
- where = [('parent_id','=',self.dir_id) ]
- ids = dirobj.search(cr, uid, where,context=ctx)
- if ids:
- for dirr in dirobj.browse(cr,uid,ids,context=ctx):
- if dirr.type == 'directory':
- res.append(node_res_obj(dirr.name,self,self.context,self.res_model,res_bo = None, res_id = self.res_id))
- elif dirr.type == 'ressource':
- # child resources can be controlled by properly set dctx
- res.append(node_res_dir(dirr.name,self,self.context, dirr, {'active_id': self.res_id}))
-
- fil_obj=dirobj.pool.get('ir.attachment')
- where2 = where + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)]
+ fil_obj = dirobj.pool.get('ir.attachment')
+ where3 = where2 + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)]
# print "where clause for dir_obj", where2
- ids = fil_obj.search(cr,uid,where2,context=ctx)
+ ids = fil_obj.search(cr, uid, where3, context=ctx)
if ids:
- for fil in fil_obj.browse(cr,uid,ids,context=ctx):
- res.append(node_file(fil.name,self,self.context,fil))
+ for fil in fil_obj.browse(cr, uid, ids, context=ctx):
+ res.append(node_file(fil.name, self, self.context, fil))
+
+ # Get Child Ressource Directories
+ if directory.ressource_type_id and directory.ressource_type_id.id:
+ where4 = where + [('ressource_parent_type_id','=',directory.ressource_type_id.id)]
+ where5 = where4 + [('ressource_id','=',0)]
+ dirids = dirobj.search(cr,uid, where5)
+ where5 = where4 + [('ressource_id','=',self.res_id)]
+ dirids = dirids + dirobj.search(cr,uid, where5)
+ for dirr in dirobj.browse(cr, uid, dirids, context=ctx):
+ if dirr.type == 'directory' and not dirr.parent_id:
+ res.append(node_res_obj(dirr.name, dirr.id, self, self.context, self.res_model, res_bo = None, res_id = self.res_id))
+ if dirr.type == 'ressource':
+ res.append(node_res_dir(dirr.name, self, self.context, dirr, {'active_id': self.res_id}))
return res
def create_child(self,cr,path,data):
From 8507374543ed88c0a170459fe8cc3ab763dea8ff Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Tue, 15 Dec 2009 16:42:09 +0530
Subject: [PATCH 013/123] [FIX] document_ics: Replace with four
bzr revid: hmo@tinyerp.com-20091215111209-m2djy0ku9oe6nsk8
---
addons/document_ics/document_ics.py | 82 ++++++++++++++---------------
1 file changed, 41 insertions(+), 41 deletions(-)
diff --git a/addons/document_ics/document_ics.py b/addons/document_ics/document_ics.py
index 61bddb2c306..caccf25e3ce 100644
--- a/addons/document_ics/document_ics.py
+++ b/addons/document_ics/document_ics.py
@@ -30,7 +30,7 @@ import random
import tools
import re
-from document import nodes
+from document.nodes import node_content
from tools.safe_eval import safe_eval
@@ -86,42 +86,42 @@ class document_directory_content(osv.osv):
'ics_domain': lambda *args: '[]'
}
def _file_get(self, cr, node, nodename, content, context=None):
- if not content.obj_iterate:
- return super(document_directory_content, self)._file_get(cr,node,nodename,content)
- else:
- # print "iterate over ", content.object_id.model
- mod = self.pool.get(content.object_id.model)
- uid = node.context.uid
- fname_fld = content.fname_field or 'id'
- where = []
- if node.domain:
- where.append(node.domain)
- if nodename:
- # Reverse-parse the nodename to deduce the clause:
- prefix = (content.prefix or '')
- suffix = (content.suffix or '') + (content.extension or '')
- if not nodename.startswith(prefix):
- return False
- if not nodename.endswith(suffix):
- return False
- tval = nodename[len(prefix):0 - len(suffix)]
- where.append((fname_fld,'=',tval))
- # print "ics iterate clause:", where
- resids = mod.search(cr,uid,where,context=context)
- if not resids:
- return False
-
- res2 = []
- for ro in mod.read(cr,uid,resids,['id', fname_fld]):
- tname = (content.prefix or '') + str(ro[fname_fld])
- tname += (content.suffix or '') + (content.extension or '')
- dctx2 = { 'active_id': ro['id'] }
- if fname_fld:
- dctx2['active_'+fname_fld] = ro[fname_fld]
- n = nodes.node_content(tname, node, node.context,content,dctx=dctx2, act_id = ro['id'])
- n.fill_fields(cr, dctx2)
- res2.append(n)
- return res2
+ if not content.obj_iterate:
+ return super(document_directory_content, self)._file_get(cr,node,nodename,content)
+ else:
+ # print "iterate over ", content.object_id.model
+ mod = self.pool.get(content.object_id.model)
+ uid = node.context.uid
+ fname_fld = content.fname_field or 'id'
+ where = []
+ if node.domain:
+ where.append(node.domain)
+ if nodename:
+ # Reverse-parse the nodename to deduce the clause:
+ prefix = (content.prefix or '')
+ suffix = (content.suffix or '') + (content.extension or '')
+ if not nodename.startswith(prefix):
+ return False
+ if not nodename.endswith(suffix):
+ return False
+ tval = nodename[len(prefix):0 - len(suffix)]
+ where.append((fname_fld,'=',tval))
+ # print "ics iterate clause:", where
+ resids = mod.search(cr,uid,where,context=context)
+ if not resids:
+ return False
+
+ res2 = []
+ for ro in mod.read(cr,uid,resids,['id', fname_fld]):
+ tname = (content.prefix or '') + str(ro[fname_fld])
+ tname += (content.suffix or '') + (content.extension or '')
+ dctx2 = { 'active_id': ro['id'] }
+ if fname_fld:
+ dctx2['active_'+fname_fld] = ro[fname_fld]
+ n = node_content(tname, node, node.context,content,dctx=dctx2, act_id = ro['id'])
+ n.fill_fields(cr, dctx2)
+ res2.append(n)
+ return res2
def process_write(self, cr, uid, node, data, context=None):
if node.extension != '.ics':
@@ -148,8 +148,8 @@ class document_directory_content(osv.osv):
fexprs[n.name] = n.expr
if 'uid' not in fields:
- print "uid not in ", fields
- # FIXME: should pass
+ print "uid not in ", fields
+ # FIXME: should pass
return True
for child in parsedCal.getChildren():
result = {}
@@ -188,11 +188,11 @@ class document_directory_content(osv.osv):
if not uuid:
print "Skipping cal", child
- # FIXME: should pass
+ # FIXME: should pass
continue
cmodel = content.object_id.model
- wexpr = False
+ wexpr = False
if fields['uid']:
wexpr = [(fields['uid'], '=', uuid.encode('utf8'))]
else:
From 67dbab9d33991bf6c1e0aa8f413657c39c266986 Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Tue, 15 Dec 2009 19:32:50 +0530
Subject: [PATCH 014/123] [IMP+FIX] document_ics: fixed regression on open,
read ics files
bzr revid: hmo@tinyerp.com-20091215140250-aw7z7jsd90fxy85b
---
addons/document/directory_content.py | 2 +-
addons/document/ftpserver/abstracted_fs.py | 12 +-
addons/document/ftpserver/ftpserver.py | 2 +-
addons/document/nodes.py | 12 +-
addons/document_ics/document.py | 191 ---------------------
addons/document_ics/document_ics.py | 17 +-
6 files changed, 26 insertions(+), 210 deletions(-)
delete mode 100644 addons/document_ics/document.py
diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py
index a43b5730627..b82da1bce8a 100644
--- a/addons/document/directory_content.py
+++ b/addons/document/directory_content.py
@@ -67,7 +67,7 @@ class document_directory_content(osv.osv):
'include_name': lambda *args: 1,
}
- def _file_get(self,cr,node, nodename, content, context=None):
+ def _file_get(self, cr, node, nodename, content, context=None):
""" return the nodes of a parent having a content
The return value MUST be false or a list of node_class objects.
"""
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py
index 0073b26b9f2..46ddba18128 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document/ftpserver/abstracted_fs.py
@@ -307,8 +307,8 @@ class abstracted_fs:
def open(self, node, mode):
if not node:
raise OSError(1, 'Operation not permited.')
- # Reading operation
- if node.type=='file':
+ # Reading operation
+ if node.type == 'file':
cr = pooler.get_db(node.context.dbname).cursor()
uid = node.context.uid
if not self.isfile(node):
@@ -321,13 +321,15 @@ class abstracted_fs:
s.name = node
cr.close()
return s
- elif node.type=='content':
+ elif node.type == 'content':
uid = node.context.uid
cr = pooler.get_db(node.context.dbname).cursor()
pool = pooler.get_pool(node.context.dbname)
res = getattr(pool.get('document.directory.content'), 'process_read')(cr, uid, node)
- cr.close()
- return res
+ cr.close()
+ s = StringIO.StringIO(res)
+ s.name = node
+ return s
else:
raise OSError(1, 'Operation not permited.')
diff --git a/addons/document/ftpserver/ftpserver.py b/addons/document/ftpserver/ftpserver.py
index 13c44287303..e265987ae32 100644
--- a/addons/document/ftpserver/ftpserver.py
+++ b/addons/document/ftpserver/ftpserver.py
@@ -2165,7 +2165,7 @@ class FTPHandler(asynchat.async_chat):
datacr = self.fs.get_cr(line)
file = self.fs.ftp2fs(line, datacr)
line = self.fs.ftpnorm(line)
- fd = self.run_as_current_user(self.fs.open, file, 'rb')
+ fd = self.run_as_current_user(self.fs.open, file, 'rb')
except OSError, err:
self.fs.close_cr(datacr)
why = _strerror(err)
diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index e6a614bf6aa..6216d4c3428 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -168,7 +168,9 @@ class node_dir(node_class):
#todo: more info from dirr
self.mimetype = 'application/x-directory'
# 'httpd/unix-directory'
- self.create_date = dirr.create_date
+ self.create_date = dirr.create_date
+ self.domain = dirr.domain
+ self.res_model = dirr.ressource_type_id and dirr.ressource_type_id.model or False
# TODO: the write date should be MAX(file.write)..
self.write_date = dirr.write_date or dirr.create_date
self.content_length = 0
@@ -205,9 +207,9 @@ class node_dir(node_class):
ctx = self.context.context.copy()
ctx.update(self.dctx)
where = [('directory_id','=',self.dir_id) ]
- ids = cntobj.search(cr,uid,where,context=ctx)
- for content in cntobj.browse(cr,uid,ids,context=ctx):
- res3 = cntobj._file_get(cr,self,nodename,content)
+ ids = cntobj.search(cr, uid, where, context=ctx)
+ for content in cntobj.browse(cr, uid, ids, context=ctx):
+ res3 = cntobj._file_get(cr, self, nodename, content)
if res3:
res.extend(res3)
@@ -312,7 +314,7 @@ class node_res_dir(node_class):
# TODO: the write date should be MAX(file.write)..
self.write_date = dirr.write_date or dirr.create_date
self.content_length = 0
- self.res_model = dirr.ressource_type_id.model
+ self.res_model = dirr.ressource_type_id and dirr.ressource_type_id.model or False
self.resm_id = dirr.ressource_id
self.namefield = dirr.resource_field or 'name'
self.displayname = dirr.name
diff --git a/addons/document_ics/document.py b/addons/document_ics/document.py
deleted file mode 100644
index bf32009f404..00000000000
--- a/addons/document_ics/document.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# 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 .
-#
-##############################################################################
-
-from osv import osv, fields
-from osv.orm import except_orm
-import os
-import StringIO
-import base64
-import datetime
-import time
-import random
-import tools
-
-ICS_TAGS = {
- 'summary':'normal',
- 'uid':'normal' ,
- 'dtstart':'date' ,
- 'dtend':'date' ,
- 'created':'date' ,
- 'dtstamp':'date' ,
- 'last-modified':'normal' ,
- 'url':'normal' ,
- 'attendee':'multiple',
- 'location':'normal',
- 'categories': 'normal',
- 'description':'normal',
-
- # TODO: handle the 'duration' property
-}
-
-class document_directory_ics_fields(osv.osv):
- _name = 'document.directory.ics.fields'
- _columns = {
- 'field_id': fields.many2one('ir.model.fields', 'Open ERP Field', required=True),
- 'name': fields.selection(map(lambda x: (x, x), ICS_TAGS.keys()), 'ICS Value', required=True),
- 'content_id': fields.many2one('document.directory.content', 'Content', required=True, ondelete='cascade')
- }
-document_directory_ics_fields()
-
-class document_directory_content(osv.osv):
- _inherit = 'document.directory.content'
- _columns = {
- 'ics_object_id': fields.many2one('ir.model', 'Object'),
- 'ics_domain': fields.char('Domain', size=64),
- 'ics_field_ids': fields.one2many('document.directory.ics.fields', 'content_id', 'Fields Mapping')
- }
- _defaults = {
- 'ics_domain': lambda *args: '[]'
- }
- def process_write_ics(self, cr, uid, node, data, context={}):
- import vobject
- parsedCal = vobject.readOne(data)
- fields = {}
- fobj = self.pool.get('document.directory.content')
- content = fobj.browse(cr, uid, node.content.id, context)
-
- idomain = {}
- for d in eval(content.ics_domain):
- idomain[d[0]]=d[2]
- for n in content.ics_field_ids:
- fields[n.name] = n.field_id.name
- if 'uid' not in fields:
- return True
- for child in parsedCal.getChildren():
- result = {}
- uuid = None
- for event in child.getChildren():
- if event.name.lower()=='uid':
- uuid = event.value
- if event.name.lower() in fields:
- if ICS_TAGS[event.name.lower()]=='normal':
- result[fields[event.name.lower()]] = event.value.encode('utf8')
- elif ICS_TAGS[event.name.lower()]=='date':
- result[fields[event.name.lower()]] = event.value.strftime('%Y-%m-%d %H:%M:%S')
- if not uuid:
- continue
-
- fobj = self.pool.get(content.ics_object_id.model)
- id = fobj.search(cr, uid, [(fields['uid'], '=', uuid.encode('utf8'))], context=context)
- if id:
- fobj.write(cr, uid, id, result, context=context)
- else:
- r = idomain.copy()
- r.update(result)
- fobj.create(cr, uid, r, context=context)
-
- return True
-
- def process_read_ics(self, cr, uid, node, context={}):
- def ics_datetime(idate, short=False):
- if short:
- return datetime.date.fromtimestamp(time.mktime(time.strptime(idate, '%Y-%m-%d')))
- else:
- return datetime.datetime.strptime(idate, '%Y-%m-%d %H:%M:%S')
-
- import vobject
- obj_class = self.pool.get(node.content.ics_object_id.model)
- # Can be improved to use context and active_id !
- domain = eval(node.content.ics_domain)
- ids = obj_class.search(cr, uid, domain, context)
- cal = vobject.iCalendar()
- for obj in obj_class.browse(cr, uid, ids, context):
- event = cal.add('vevent')
- # Fix dtstamp et last-modified with create and write date on the object line
- perm = obj_class.perm_read(cr, uid, [obj.id], context)
- event.add('created').value = ics_datetime(time.strftime('%Y-%m-%d %H:%M:%S'))
- event.add('dtstamp').value = ics_datetime(perm[0]['create_date'][:19])
- if perm[0]['write_date']:
- event.add('last-modified').value = ics_datetime(perm[0]['write_date'][:19])
- for field in node.content.ics_field_ids:
- value = getattr(obj, field.field_id.name)
- value = value and tools.ustr(value)
- if (not value) and field.name=='uid':
- value = 'OpenERP-%s_%s@%s' % (node.content.ics_object_id.model, str(obj.id), cr.dbname,)
- obj_class.write(cr, uid, [obj.id], {field.field_id.name: value})
- if ICS_TAGS[field.name]=='normal':
- if type(value)==type(obj):
- value=value.name
- value = value or ''
- event.add(field.name).value = value or ''
- elif ICS_TAGS[field.name]=='date' and value:
- if field.name == 'dtstart':
- date_start = start_date = datetime.datetime.fromtimestamp(time.mktime(time.strptime(value , "%Y-%m-%d %H:%M:%S")))
- if field.name == 'dtend' and isinstance(value, float):
- value = (start_date + datetime.timedelta(hours=value)).strftime('%Y-%m-%d %H:%M:%S')
- if len(value)==10:
- value = ics_datetime(value, True)
- else:
- value = ics_datetime(value)
- event.add(field.name).value = value
- s= StringIO.StringIO(cal.serialize())
- s.name = node
- cr.commit()
- return s
-document_directory_content()
-
-class crm_case(osv.osv):
- _inherit = 'crm.case'
- _columns = {
- 'code': fields.char('Calendar Code', size=64),
- 'date_deadline': fields.datetime('Deadline', help="Deadline Date is automatically computed from Start Date + Duration"),
- }
-
- _defaults = {
- 'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'crm.case'),
- }
-
- def copy(self, cr, uid, id, default=None, context=None):
- """
- code field must be unique in ICS file
- """
- if not default: default = {}
- if not context: context = {}
- default.update({'code': self.pool.get('ir.sequence').get(cr, uid, 'crm.case'), 'id': False})
- return super(crm_case, self).copy(cr, uid, id, default, context)
-
- def on_change_duration(self, cr, uid, id, date, duration):
- if not date:
- return {}
- start_date = datetime.datetime.fromtimestamp(time.mktime(time.strptime(date, "%Y-%m-%d %H:%M:%S")))
- if duration >= 0 :
- end = start_date + datetime.timedelta(hours=duration)
- if duration < 0:
- raise osv.except_osv(_('Warning !'),
- _('You can not set negative Duration.'))
-
- res = {'value' : {'date_deadline' : end.strftime('%Y-%m-%d %H:%M:%S')}}
- return res
-
-crm_case()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/document_ics/document_ics.py b/addons/document_ics/document_ics.py
index caccf25e3ce..1fb8518050b 100644
--- a/addons/document_ics/document_ics.py
+++ b/addons/document_ics/document_ics.py
@@ -87,15 +87,16 @@ class document_directory_content(osv.osv):
}
def _file_get(self, cr, node, nodename, content, context=None):
if not content.obj_iterate:
- return super(document_directory_content, self)._file_get(cr,node,nodename,content)
+ return super(document_directory_content, self)._file_get(cr, node, nodename, content)
else:
- # print "iterate over ", content.object_id.model
+ if not content.object_id:
+ return False
mod = self.pool.get(content.object_id.model)
uid = node.context.uid
fname_fld = content.fname_field or 'id'
- where = []
+ where = []
if node.domain:
- where.append(node.domain)
+ where += eval(node.domain)
if nodename:
# Reverse-parse the nodename to deduce the clause:
prefix = (content.prefix or '')
@@ -107,7 +108,7 @@ class document_directory_content(osv.osv):
tval = nodename[len(prefix):0 - len(suffix)]
where.append((fname_fld,'=',tval))
# print "ics iterate clause:", where
- resids = mod.search(cr,uid,where,context=context)
+ resids = mod.search(cr, uid, where, context=context)
if not resids:
return False
@@ -244,13 +245,15 @@ class document_directory_content(osv.osv):
return datetime.datetime.strptime(idate, '%Y-%m-%d %H:%M:%S')
if node.extension != '.ics':
- return super(document_directory_content).process_read(cr, uid, node, context)
+ return super(document_directory_content).process_read(cr, uid, node, context)
import vobject
ctx = (context or {})
ctx.update(node.context.context.copy())
ctx.update(node.dctx)
content = self.browse(cr, uid, node.cnt_id, ctx)
+ if not content.object_id:
+ return super(document_directory_content).process_read(cr, uid, node, context)
obj_class = self.pool.get(content.object_id.model)
if content.ics_domain:
@@ -261,7 +264,7 @@ class document_directory_content(osv.osv):
domain.append(('id','=',node.act_id))
# print "process read clause:",domain
ids = obj_class.search(cr, uid, domain, context=ctx)
- cal = vobject.iCalendar()
+ cal = vobject.iCalendar()
for obj in obj_class.browse(cr, uid, ids):
event = cal.add('vevent')
# Fix dtstamp et last-modified with create and write date on the object line
From 6082127d5da37e2a2314fe96e68ad413fa5af3bf Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Tue, 15 Dec 2009 20:01:05 +0530
Subject: [PATCH 015/123] [FIX] document_webdav : Replace with four
bzr revid: hmo@tinyerp.com-20091215143105-3m1zuyf0fas65opf
---
addons/document_webdav/cache.py | 68 +-
addons/document_webdav/dav_fs.py | 1008 +++++++++++------------
addons/document_webdav/webdav_server.py | 44 +-
3 files changed, 560 insertions(+), 560 deletions(-)
diff --git a/addons/document_webdav/cache.py b/addons/document_webdav/cache.py
index bc75114c4ae..7f03aa6da13 100644
--- a/addons/document_webdav/cache.py
+++ b/addons/document_webdav/cache.py
@@ -2,38 +2,38 @@ import time
import heapq
def memoize(maxsize):
- """decorator to 'memoize' a function - caching its results"""
- def decorating_function(f):
- cache = {} # map from key to value
- heap = [] # list of keys, in LRU heap
- cursize = 0 # because len() is slow
- def wrapper(*args):
- key = repr(args)
- # performance crap
- _cache=cache
- _heap=heap
- _heappop = heapq.heappop
- _heappush = heapq.heappush
- _time = time.time
- _cursize = cursize
- _maxsize = maxsize
- if not _cache.has_key(key):
- if _cursize == _maxsize:
- # pop oldest element
- (_,oldkey) = _heappop(_heap)
- _cache.pop(oldkey)
- else:
- _cursize += 1
- # insert this element
- _cache[key] = f(*args)
- _heappush(_heap,(_time(),key))
- wrapper.misses += 1
- else:
- wrapper.hits += 1
- return cache[key]
- wrapper.__doc__ = f.__doc__
- wrapper.__name__ = f.__name__
- wrapper.hits = wrapper.misses = 0
- return wrapper
- return decorating_function
+ """decorator to 'memoize' a function - caching its results"""
+ def decorating_function(f):
+ cache = {} # map from key to value
+ heap = [] # list of keys, in LRU heap
+ cursize = 0 # because len() is slow
+ def wrapper(*args):
+ key = repr(args)
+ # performance crap
+ _cache=cache
+ _heap=heap
+ _heappop = heapq.heappop
+ _heappush = heapq.heappush
+ _time = time.time
+ _cursize = cursize
+ _maxsize = maxsize
+ if not _cache.has_key(key):
+ if _cursize == _maxsize:
+ # pop oldest element
+ (_,oldkey) = _heappop(_heap)
+ _cache.pop(oldkey)
+ else:
+ _cursize += 1
+ # insert this element
+ _cache[key] = f(*args)
+ _heappush(_heap,(_time(),key))
+ wrapper.misses += 1
+ else:
+ wrapper.hits += 1
+ return cache[key]
+ wrapper.__doc__ = f.__doc__
+ wrapper.__name__ = f.__name__
+ wrapper.hits = wrapper.misses = 0
+ return wrapper
+ return decorating_function
diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py
index 4cd4b2d6405..0d8331b8959 100644
--- a/addons/document_webdav/dav_fs.py
+++ b/addons/document_webdav/dav_fs.py
@@ -56,33 +56,33 @@ urlparse.uses_netloc.append('webdav')
urlparse.uses_netloc.append('webdavs')
class tinydav_handler(dav_interface):
- """
- This class models a Tiny ERP interface for the DAV server
- """
- PROPS={'DAV:': dav_interface.PROPS['DAV:'], }
+ """
+ This class models a Tiny ERP interface for the DAV server
+ """
+ PROPS={'DAV:': dav_interface.PROPS['DAV:'], }
- M_NS={ "DAV:" : dav_interface.M_NS['DAV:'], }
+ M_NS={ "DAV:" : dav_interface.M_NS['DAV:'], }
- def __init__(self, parent, verbose=False):
- self.db_name = False
- self.directory_id=False
- self.db_name_list=[]
- self.parent = parent
- self.baseuri = parent.baseuri
+ def __init__(self, parent, verbose=False):
+ self.db_name = False
+ self.directory_id=False
+ self.db_name_list=[]
+ self.parent = parent
+ self.baseuri = parent.baseuri
def get_propnames(self,uri):
- props = self.PROPS
- self.parent.log_message('get propnames: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- if not dbname:
- cr.close()
- return props
- node = self.uri2object(cr,uid,pool, uri2)
- if node:
- props.update(node.get_dav_props(cr))
- cr.close()
- return props
+ props = self.PROPS
+ self.parent.log_message('get propnames: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ cr.close()
+ return props
+ node = self.uri2object(cr,uid,pool, uri2)
+ if node:
+ props.update(node.get_dav_props(cr))
+ cr.close()
+ return props
def get_prop(self,uri,ns,propname):
""" return the value of a given property
@@ -97,557 +97,557 @@ class tinydav_handler(dav_interface):
if uri[-1]=='/':uri=uri[:-1]
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
- cr.close()
+ cr.close()
raise DAV_NotFound
node = self.uri2object(cr,uid,pool, uri2)
if not node:
- cr.close()
+ cr.close()
raise DAV_NotFound
res = node.get_dav_eprop(cr,ns,propname)
cr.close()
return res
#
-# def get_db(self,uri):
-# names=self.uri2local(uri).split('/')
-# self.db_name=False
-# if len(names) > 1:
-# self.db_name=self.uri2local(uri).split('/')[1]
-# if self.db_name=='':
-# raise Exception,'Plese specify Database name in folder'
-# return self.db_name
+# def get_db(self,uri):
+# names=self.uri2local(uri).split('/')
+# self.db_name=False
+# if len(names) > 1:
+# self.db_name=self.uri2local(uri).split('/')[1]
+# if self.db_name=='':
+# raise Exception,'Plese specify Database name in folder'
+# return self.db_name
#
- def later_get_db_from_path(self,path):
- return "aaa"
+ def later_get_db_from_path(self,path):
+ return "aaa"
- def urijoin(self,*ajoin):
- """ Return the base URI of this request, or even join it with the
- ajoin path elements
- """
- return self.baseuri+ '/'.join(ajoin)
+ def urijoin(self,*ajoin):
+ """ Return the base URI of this request, or even join it with the
+ ajoin path elements
+ """
+ return self.baseuri+ '/'.join(ajoin)
- @memoize(4)
- def db_list(self):
- s = netsvc.LocalService('db')
- result = s.list()
- self.db_name_list=[]
- for db_name in result:
- db = pooler.get_db_only(db_name)
- cr = db.cursor()
- cr.execute("select id from ir_module_module where name = 'document' and state='installed' ")
- res=cr.fetchone()
- if res and len(res):
- self.db_name_list.append(db_name)
- cr.close()
- return self.db_name_list
+ @memoize(4)
+ def db_list(self):
+ s = netsvc.LocalService('db')
+ result = s.list()
+ self.db_name_list=[]
+ for db_name in result:
+ db = pooler.get_db_only(db_name)
+ cr = db.cursor()
+ cr.execute("select id from ir_module_module where name = 'document' and state='installed' ")
+ res=cr.fetchone()
+ if res and len(res):
+ self.db_name_list.append(db_name)
+ cr.close()
+ return self.db_name_list
- def get_childs(self,uri):
- """ return the child objects as self.baseuris for the given URI """
- self.parent.log_message('get childs: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
-
- if not dbname:
- s = netsvc.LocalService('db')
- return map(lambda x: self.urijoin(x), self.db_list())
- result = []
- node = self.uri2object(cr,uid,pool, uri2[:])
- if not node:
- cr.close()
- raise DAV_NotFound(uri2)
- else:
- fp = node.full_path()
- if fp and len(fp):
- self.parent.log_message('childs: @%s' % fp)
- fp = '/'.join(fp)
- else:
- fp = None
- for d in node.children(cr):
- self.parent.log_message('child: %s' % d.path)
- if fp:
- result.append( self.urijoin(dbname,fp,d.path) )
- else:
- result.append( self.urijoin(dbname,d.path) )
- cr.close()
- return result
+ def get_childs(self,uri):
+ """ return the child objects as self.baseuris for the given URI """
+ self.parent.log_message('get childs: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+
+ if not dbname:
+ s = netsvc.LocalService('db')
+ return map(lambda x: self.urijoin(x), self.db_list())
+ result = []
+ node = self.uri2object(cr,uid,pool, uri2[:])
+ if not node:
+ cr.close()
+ raise DAV_NotFound(uri2)
+ else:
+ fp = node.full_path()
+ if fp and len(fp):
+ self.parent.log_message('childs: @%s' % fp)
+ fp = '/'.join(fp)
+ else:
+ fp = None
+ for d in node.children(cr):
+ self.parent.log_message('child: %s' % d.path)
+ if fp:
+ result.append( self.urijoin(dbname,fp,d.path) )
+ else:
+ result.append( self.urijoin(dbname,d.path) )
+ cr.close()
+ return result
- def uri2local(self, uri):
- uparts=urlparse.urlparse(uri)
- reluri=uparts[2]
- if reluri and reluri[-1]=="/":
- reluri=reluri[:-1]
- return reluri
+ def uri2local(self, uri):
+ uparts=urlparse.urlparse(uri)
+ reluri=uparts[2]
+ if reluri and reluri[-1]=="/":
+ reluri=reluri[:-1]
+ return reluri
- #
- # pos: -1 to get the parent of the uri
- #
- def get_cr(self, uri):
- pdb = self.parent.auth_proxy.last_auth
- reluri = self.uri2local(uri)
- try:
- dbname = reluri.split('/')[2]
- except:
- dbname = False
- if not dbname:
- return None, None, None, False, None
- if not pdb and dbname:
- # if dbname was in our uri, we should have authenticated
- # against that.
- raise Exception("Programming error")
- assert pdb == dbname, " %s != %s" %(pdb, dbname)
- user, passwd, dbn2, uid = self.parent.auth_proxy.auth_creds[pdb]
- db,pool = pooler.get_db_and_pool(dbname)
- cr = db.cursor()
- uri2 = reluri.split('/')[3:]
- return cr, uid, pool, dbname, uri2
+ #
+ # pos: -1 to get the parent of the uri
+ #
+ def get_cr(self, uri):
+ pdb = self.parent.auth_proxy.last_auth
+ reluri = self.uri2local(uri)
+ try:
+ dbname = reluri.split('/')[2]
+ except:
+ dbname = False
+ if not dbname:
+ return None, None, None, False, None
+ if not pdb and dbname:
+ # if dbname was in our uri, we should have authenticated
+ # against that.
+ raise Exception("Programming error")
+ assert pdb == dbname, " %s != %s" %(pdb, dbname)
+ user, passwd, dbn2, uid = self.parent.auth_proxy.auth_creds[pdb]
+ db,pool = pooler.get_db_and_pool(dbname)
+ cr = db.cursor()
+ uri2 = reluri.split('/')[3:]
+ return cr, uid, pool, dbname, uri2
- def uri2object(self, cr,uid, pool,uri):
- if not uid:
- return None
- return pool.get('document.directory').get_object(cr, uid, uri)
+ def uri2object(self, cr,uid, pool,uri):
+ if not uid:
+ return None
+ return pool.get('document.directory').get_object(cr, uid, uri)
- def get_data(self,uri):
- self.parent.log_message('GET: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- try:
- if not dbname:
- raise DAV_Error, 409
- node = self.uri2object(cr,uid,pool, uri2)
- if not node:
- raise DAV_NotFound(uri2)
- try:
- datas = node.get_data(cr)
- except TypeError,e:
- import traceback
- self.parent.log_error("GET typeError: %s", str(e))
- self.parent.log_message("Exc: %s",traceback.format_exc())
- raise DAV_Forbidden
- except IndexError,e :
- self.parent.log_error("GET IndexError: %s", str(e))
- raise DAV_NotFound(uri2)
- except Exception,e:
- import traceback
- self.parent.log_error("GET exception: %s",str(e))
- self.parent.log_message("Exc: %s", traceback.format_exc())
- raise DAV_Error, 409
- return datas
- finally:
- cr.close()
+ def get_data(self,uri):
+ self.parent.log_message('GET: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ try:
+ if not dbname:
+ raise DAV_Error, 409
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ raise DAV_NotFound(uri2)
+ try:
+ datas = node.get_data(cr)
+ except TypeError,e:
+ import traceback
+ self.parent.log_error("GET typeError: %s", str(e))
+ self.parent.log_message("Exc: %s",traceback.format_exc())
+ raise DAV_Forbidden
+ except IndexError,e :
+ self.parent.log_error("GET IndexError: %s", str(e))
+ raise DAV_NotFound(uri2)
+ except Exception,e:
+ import traceback
+ self.parent.log_error("GET exception: %s",str(e))
+ self.parent.log_message("Exc: %s", traceback.format_exc())
+ raise DAV_Error, 409
+ return datas
+ finally:
+ cr.close()
- @memoize(CACHE_SIZE)
- def _get_dav_resourcetype(self,uri):
- """ return type of object """
- self.parent.log_message('get RT: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- try:
- if not dbname:
- return COLLECTION
- node = self.uri2object(cr,uid,pool, uri2)
- if not node:
- raise DAV_NotFound(uri2)
- if node.type in ('collection','database'):
- return COLLECTION
- return OBJECT
- finally:
- cr.close()
+ @memoize(CACHE_SIZE)
+ def _get_dav_resourcetype(self,uri):
+ """ return type of object """
+ self.parent.log_message('get RT: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ try:
+ if not dbname:
+ return COLLECTION
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ raise DAV_NotFound(uri2)
+ if node.type in ('collection','database'):
+ return COLLECTION
+ return OBJECT
+ finally:
+ cr.close()
- def _get_dav_displayname(self,uri):
- self.parent.log_message('get DN: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- if not dbname:
- cr.close()
- return COLLECTION
- node = self.uri2object(cr,uid,pool, uri2)
- if not node:
- cr.close()
- raise DAV_NotFound(uri2)
- cr.close()
- return node.displayname
+ def _get_dav_displayname(self,uri):
+ self.parent.log_message('get DN: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ cr.close()
+ return COLLECTION
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ cr.close()
+ raise DAV_NotFound(uri2)
+ cr.close()
+ return node.displayname
- @memoize(CACHE_SIZE)
- def _get_dav_getcontentlength(self,uri):
- """ return the content length of an object """
- self.parent.log_message('get length: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- result = 0
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- if not dbname:
- cr.close()
- return '0'
- node = self.uri2object(cr, uid, pool, uri2)
- if not node:
- cr.close()
- raise DAV_NotFound(uri2)
- result = node.content_length or 0
- cr.close()
- return str(result)
+ @memoize(CACHE_SIZE)
+ def _get_dav_getcontentlength(self,uri):
+ """ return the content length of an object """
+ self.parent.log_message('get length: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ result = 0
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ cr.close()
+ return '0'
+ node = self.uri2object(cr, uid, pool, uri2)
+ if not node:
+ cr.close()
+ raise DAV_NotFound(uri2)
+ result = node.content_length or 0
+ cr.close()
+ return str(result)
- @memoize(CACHE_SIZE)
- def _get_dav_getetag(self,uri):
- """ return the ETag of an object """
- self.parent.log_message('get etag: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- result = 0
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- if not dbname:
- cr.close()
- return '0'
- node = self.uri2object(cr, uid, pool, uri2)
- if not node:
- cr.close()
- raise DAV_NotFound(uri2)
- result = node.get_etag(cr)
- cr.close()
- return str(result)
+ @memoize(CACHE_SIZE)
+ def _get_dav_getetag(self,uri):
+ """ return the ETag of an object """
+ self.parent.log_message('get etag: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ result = 0
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ cr.close()
+ return '0'
+ node = self.uri2object(cr, uid, pool, uri2)
+ if not node:
+ cr.close()
+ raise DAV_NotFound(uri2)
+ result = node.get_etag(cr)
+ cr.close()
+ return str(result)
- @memoize(CACHE_SIZE)
- def get_lastmodified(self,uri):
- """ return the last modified date of the object """
- if uri[-1]=='/':uri=uri[:-1]
- today = time.time()
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- try:
- if not dbname:
- return today
- node = self.uri2object(cr,uid,pool, uri2)
- if not node:
- raise DAV_NotFound(uri2)
- if node.write_date:
- return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S'))
- else:
- return today
- finally:
- cr.close()
+ @memoize(CACHE_SIZE)
+ def get_lastmodified(self,uri):
+ """ return the last modified date of the object """
+ if uri[-1]=='/':uri=uri[:-1]
+ today = time.time()
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ try:
+ if not dbname:
+ return today
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ raise DAV_NotFound(uri2)
+ if node.write_date:
+ return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S'))
+ else:
+ return today
+ finally:
+ cr.close()
- @memoize(CACHE_SIZE)
- def get_creationdate(self,uri):
- """ return the last modified date of the object """
+ @memoize(CACHE_SIZE)
+ def get_creationdate(self,uri):
+ """ return the last modified date of the object """
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- try:
- if not dbname:
- raise DAV_Error, 409
- node = self.uri2object(cr,uid,pool, uri2)
- if not node:
- raise DAV_NotFound(uri2)
- if node.create_date:
- result = time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S')
- else:
- result = time.gmtime()
- return result
- finally:
- cr.close()
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ try:
+ if not dbname:
+ raise DAV_Error, 409
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ raise DAV_NotFound(uri2)
+ if node.create_date:
+ result = time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S')
+ else:
+ result = time.gmtime()
+ return result
+ finally:
+ cr.close()
- @memoize(CACHE_SIZE)
- def _get_dav_getcontenttype(self,uri):
- self.parent.log_message('get contenttype: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- try:
- if not dbname:
- return 'httpd/unix-directory'
- node = self.uri2object(cr,uid,pool, uri2)
- if not node:
- raise DAV_NotFound(uri2)
-
- result = 'application/octet-stream'
- #if node.type=='collection':
- #result ='httpd/unix-directory'
- #else:
- result = node.mimetype
- return result
- #raise DAV_NotFound, 'Could not find %s' % path
- finally:
- cr.close()
+ @memoize(CACHE_SIZE)
+ def _get_dav_getcontenttype(self,uri):
+ self.parent.log_message('get contenttype: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ try:
+ if not dbname:
+ return 'httpd/unix-directory'
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ raise DAV_NotFound(uri2)
+
+ result = 'application/octet-stream'
+ #if node.type=='collection':
+ #result ='httpd/unix-directory'
+ #else:
+ result = node.mimetype
+ return result
+ #raise DAV_NotFound, 'Could not find %s' % path
+ finally:
+ cr.close()
- def mkcol(self,uri):
- """ create a new collection """
- self.parent.log_message('MKCOL: %s' % uri)
- if uri[-1]=='/':uri=uri[:-1]
- parent='/'.join(uri.split('/')[:-1])
- if not parent.startswith(self.baseuri):
- parent=self.baseuri + ''.join(parent[1:])
- if not uri.startswith(self.baseuri):
- uri=self.baseuri + ''.join(uri[1:])
+ def mkcol(self,uri):
+ """ create a new collection """
+ self.parent.log_message('MKCOL: %s' % uri)
+ if uri[-1]=='/':uri=uri[:-1]
+ parent='/'.join(uri.split('/')[:-1])
+ if not parent.startswith(self.baseuri):
+ parent=self.baseuri + ''.join(parent[1:])
+ if not uri.startswith(self.baseuri):
+ uri=self.baseuri + ''.join(uri[1:])
- cr, uid, pool,dbname, uri2 = self.get_cr(uri)
- if not dbname:
- raise DAV_Error, 409
- node = self.uri2object(cr,uid,pool, uri2[:-1])
- object2=node and node.object2 or False
- object=node and node.object or False
+ cr, uid, pool,dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ raise DAV_Error, 409
+ node = self.uri2object(cr,uid,pool, uri2[:-1])
+ object2=node and node.object2 or False
+ object=node and node.object or False
- objname = uri2[-1]
- if not object:
- pool.get('document.directory').create(cr, uid, {
- 'name': objname,
- 'parent_id': False,
- 'ressource_type_id': False,
- 'ressource_id': False
- })
- else:
- pool.get('document.directory').create(cr, uid, {
- 'name': objname,
- 'parent_id': object.id,
- 'ressource_type_id': object.ressource_type_id.id,
- 'ressource_id': object2 and object2.id or False
- })
+ objname = uri2[-1]
+ if not object:
+ pool.get('document.directory').create(cr, uid, {
+ 'name': objname,
+ 'parent_id': False,
+ 'ressource_type_id': False,
+ 'ressource_id': False
+ })
+ else:
+ pool.get('document.directory').create(cr, uid, {
+ 'name': objname,
+ 'parent_id': object.id,
+ 'ressource_type_id': object.ressource_type_id.id,
+ 'ressource_id': object2 and object2.id or False
+ })
- cr.commit()
- cr.close()
- return True
+ cr.commit()
+ cr.close()
+ return True
- def put(self,uri,data,content_type=None):
- """ put the object into the filesystem """
- self.parent.log_message('Putting %s (%d), %s'%( unicode(uri,'utf8'), len(data), content_type))
- parent='/'.join(uri.split('/')[:-1])
- cr, uid, pool,dbname, uri2 = self.get_cr(uri)
- if not dbname:
- raise DAV_Forbidden
- try:
- node = self.uri2object(cr,uid,pool, uri2[:])
- except:
- node = False
- objname = uri2[-1]
- ext = objname.find('.') >0 and objname.split('.')[1] or False
+ def put(self,uri,data,content_type=None):
+ """ put the object into the filesystem """
+ self.parent.log_message('Putting %s (%d), %s'%( unicode(uri,'utf8'), len(data), content_type))
+ parent='/'.join(uri.split('/')[:-1])
+ cr, uid, pool,dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ raise DAV_Forbidden
+ try:
+ node = self.uri2object(cr,uid,pool, uri2[:])
+ except:
+ node = False
+ objname = uri2[-1]
+ ext = objname.find('.') >0 and objname.split('.')[1] or False
- if not node:
- dir_node = self.uri2object(cr,uid,pool, uri2[:-1])
- if not dir_node:
- raise DAV_NotFound('Parent folder not found')
- try:
- dir_node.create_child(cr,objname,data)
- except Exception,e:
- import traceback
- self.parent.log_error("Cannot create %s: %s", objname, str(e))
- self.parent.log_message("Exc: %s",traceback.format_exc())
- raise DAV_Forbidden
- else:
- try:
- node.set_data(cr,data)
- except Exception,e:
- import traceback
- self.parent.log_error("Cannot save %s: %s", objname, str(e))
- self.parent.log_message("Exc: %s",traceback.format_exc())
- raise DAV_Forbidden
-
- cr.commit()
+ if not node:
+ dir_node = self.uri2object(cr,uid,pool, uri2[:-1])
+ if not dir_node:
+ raise DAV_NotFound('Parent folder not found')
+ try:
+ dir_node.create_child(cr,objname,data)
+ except Exception,e:
+ import traceback
+ self.parent.log_error("Cannot create %s: %s", objname, str(e))
+ self.parent.log_message("Exc: %s",traceback.format_exc())
+ raise DAV_Forbidden
+ else:
+ try:
+ node.set_data(cr,data)
+ except Exception,e:
+ import traceback
+ self.parent.log_error("Cannot save %s: %s", objname, str(e))
+ self.parent.log_message("Exc: %s",traceback.format_exc())
+ raise DAV_Forbidden
+
+ cr.commit()
- return 201
+ return 201
- def rmcol(self,uri):
- """ delete a collection """
- if uri[-1]=='/':uri=uri[:-1]
+ def rmcol(self,uri):
+ """ delete a collection """
+ if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- if True or not dbname: # *-*
- raise DAV_Error, 409
- node = self.uri2object(cr,uid,pool, uri2)
- object2=node and node.object2 or False
- object=node and node.object or False
- if object._table_name=='document.directory':
- if object.child_ids:
- raise DAV_Forbidden # forbidden
- if object.file_ids:
- raise DAV_Forbidden # forbidden
- res = pool.get('document.directory').unlink(cr, uid, [object.id])
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if True or not dbname: # *-*
+ raise DAV_Error, 409
+ node = self.uri2object(cr,uid,pool, uri2)
+ object2=node and node.object2 or False
+ object=node and node.object or False
+ if object._table_name=='document.directory':
+ if object.child_ids:
+ raise DAV_Forbidden # forbidden
+ if object.file_ids:
+ raise DAV_Forbidden # forbidden
+ res = pool.get('document.directory').unlink(cr, uid, [object.id])
- cr.commit()
- cr.close()
- return 204
+ cr.commit()
+ cr.close()
+ return 204
- def rm(self,uri):
- if uri[-1]=='/':uri=uri[:-1]
+ def rm(self,uri):
+ if uri[-1]=='/':uri=uri[:-1]
- object=False
- cr, uid, pool,dbname, uri2 = self.get_cr(uri)
- #if not dbname:
- if True:
- raise DAV_Error, 409
- node = self.uri2object(cr,uid,pool, uri2)
- object2=node and node.object2 or False
- object=node and node.object or False
- if not object:
- raise DAV_NotFound
+ object=False
+ cr, uid, pool,dbname, uri2 = self.get_cr(uri)
+ #if not dbname:
+ if True:
+ raise DAV_Error, 409
+ node = self.uri2object(cr,uid,pool, uri2)
+ object2=node and node.object2 or False
+ object=node and node.object or False
+ if not object:
+ raise DAV_NotFound
- self.parent.log_message(' rm %s "%s"'%(object._table_name,uri))
- if object._table_name=='ir.attachment':
- res = pool.get('ir.attachment').unlink(cr, uid, [object.id])
- else:
- raise DAV_Forbidden # forbidden
- parent='/'.join(uri.split('/')[:-1])
- cr.commit()
- cr.close()
- return 204
+ self.parent.log_message(' rm %s "%s"'%(object._table_name,uri))
+ if object._table_name=='ir.attachment':
+ res = pool.get('ir.attachment').unlink(cr, uid, [object.id])
+ else:
+ raise DAV_Forbidden # forbidden
+ parent='/'.join(uri.split('/')[:-1])
+ cr.commit()
+ cr.close()
+ return 204
- ### DELETE handlers (examples)
- ### (we use the predefined methods in davcmd instead of doing
- ### a rm directly
- ###
+ ### DELETE handlers (examples)
+ ### (we use the predefined methods in davcmd instead of doing
+ ### a rm directly
+ ###
- def delone(self,uri):
- """ delete a single resource
+ def delone(self,uri):
+ """ delete a single resource
- You have to return a result dict of the form
- uri:error_code
- or None if everything's ok
+ You have to return a result dict of the form
+ uri:error_code
+ or None if everything's ok
- """
- if uri[-1]=='/':uri=uri[:-1]
- res=delone(self,uri)
- parent='/'.join(uri.split('/')[:-1])
- return res
+ """
+ if uri[-1]=='/':uri=uri[:-1]
+ res=delone(self,uri)
+ parent='/'.join(uri.split('/')[:-1])
+ return res
- def deltree(self,uri):
- """ delete a collection
+ def deltree(self,uri):
+ """ delete a collection
- You have to return a result dict of the form
- uri:error_code
- or None if everything's ok
- """
- if uri[-1]=='/':uri=uri[:-1]
- res=deltree(self,uri)
- parent='/'.join(uri.split('/')[:-1])
- return res
+ You have to return a result dict of the form
+ uri:error_code
+ or None if everything's ok
+ """
+ if uri[-1]=='/':uri=uri[:-1]
+ res=deltree(self,uri)
+ parent='/'.join(uri.split('/')[:-1])
+ return res
- ###
- ### MOVE handlers (examples)
- ###
+ ###
+ ### MOVE handlers (examples)
+ ###
- def moveone(self,src,dst,overwrite):
- """ move one resource with Depth=0
+ def moveone(self,src,dst,overwrite):
+ """ move one resource with Depth=0
- an alternative implementation would be
+ an alternative implementation would be
- result_code=201
- if overwrite:
- result_code=204
- r=os.system("rm -f '%s'" %dst)
- if r: return 412
- r=os.system("mv '%s' '%s'" %(src,dst))
- if r: return 412
- return result_code
+ result_code=201
+ if overwrite:
+ result_code=204
+ r=os.system("rm -f '%s'" %dst)
+ if r: return 412
+ r=os.system("mv '%s' '%s'" %(src,dst))
+ if r: return 412
+ return result_code
- (untested!). This would not use the davcmd functions
- and thus can only detect errors directly on the root node.
- """
- res=moveone(self,src,dst,overwrite)
- return res
+ (untested!). This would not use the davcmd functions
+ and thus can only detect errors directly on the root node.
+ """
+ res=moveone(self,src,dst,overwrite)
+ return res
- def movetree(self,src,dst,overwrite):
- """ move a collection with Depth=infinity
+ def movetree(self,src,dst,overwrite):
+ """ move a collection with Depth=infinity
- an alternative implementation would be
+ an alternative implementation would be
- result_code=201
- if overwrite:
- result_code=204
- r=os.system("rm -rf '%s'" %dst)
- if r: return 412
- r=os.system("mv '%s' '%s'" %(src,dst))
- if r: return 412
- return result_code
+ result_code=201
+ if overwrite:
+ result_code=204
+ r=os.system("rm -rf '%s'" %dst)
+ if r: return 412
+ r=os.system("mv '%s' '%s'" %(src,dst))
+ if r: return 412
+ return result_code
- (untested!). This would not use the davcmd functions
- and thus can only detect errors directly on the root node"""
+ (untested!). This would not use the davcmd functions
+ and thus can only detect errors directly on the root node"""
- res=movetree(self,src,dst,overwrite)
- return res
+ res=movetree(self,src,dst,overwrite)
+ return res
- ###
- ### COPY handlers
- ###
+ ###
+ ### COPY handlers
+ ###
- def copyone(self,src,dst,overwrite):
- """ copy one resource with Depth=0
+ def copyone(self,src,dst,overwrite):
+ """ copy one resource with Depth=0
- an alternative implementation would be
+ an alternative implementation would be
- result_code=201
- if overwrite:
- result_code=204
- r=os.system("rm -f '%s'" %dst)
- if r: return 412
- r=os.system("cp '%s' '%s'" %(src,dst))
- if r: return 412
- return result_code
+ result_code=201
+ if overwrite:
+ result_code=204
+ r=os.system("rm -f '%s'" %dst)
+ if r: return 412
+ r=os.system("cp '%s' '%s'" %(src,dst))
+ if r: return 412
+ return result_code
- (untested!). This would not use the davcmd functions
- and thus can only detect errors directly on the root node.
- """
- res=copyone(self,src,dst,overwrite)
- return res
+ (untested!). This would not use the davcmd functions
+ and thus can only detect errors directly on the root node.
+ """
+ res=copyone(self,src,dst,overwrite)
+ return res
- def copytree(self,src,dst,overwrite):
- """ copy a collection with Depth=infinity
+ def copytree(self,src,dst,overwrite):
+ """ copy a collection with Depth=infinity
- an alternative implementation would be
+ an alternative implementation would be
- result_code=201
- if overwrite:
- result_code=204
- r=os.system("rm -rf '%s'" %dst)
- if r: return 412
- r=os.system("cp -r '%s' '%s'" %(src,dst))
- if r: return 412
- return result_code
+ result_code=201
+ if overwrite:
+ result_code=204
+ r=os.system("rm -rf '%s'" %dst)
+ if r: return 412
+ r=os.system("cp -r '%s' '%s'" %(src,dst))
+ if r: return 412
+ return result_code
- (untested!). This would not use the davcmd functions
- and thus can only detect errors directly on the root node"""
- res=copytree(self,src,dst,overwrite)
- return res
+ (untested!). This would not use the davcmd functions
+ and thus can only detect errors directly on the root node"""
+ res=copytree(self,src,dst,overwrite)
+ return res
- ###
- ### copy methods.
- ### This methods actually copy something. low-level
- ### They are called by the davcmd utility functions
- ### copytree and copyone (not the above!)
- ### Look in davcmd.py for further details.
- ###
+ ###
+ ### copy methods.
+ ### This methods actually copy something. low-level
+ ### They are called by the davcmd utility functions
+ ### copytree and copyone (not the above!)
+ ### Look in davcmd.py for further details.
+ ###
- def copy(self,src,dst):
- src=urllib.unquote(src)
- dst=urllib.unquote(dst)
- ct = self._get_dav_getcontenttype(src)
- data = self.get_data(src)
- self.put(dst,data,ct)
- return 201
+ def copy(self,src,dst):
+ src=urllib.unquote(src)
+ dst=urllib.unquote(dst)
+ ct = self._get_dav_getcontenttype(src)
+ data = self.get_data(src)
+ self.put(dst,data,ct)
+ return 201
- def copycol(self,src,dst):
- """ copy a collection.
+ def copycol(self,src,dst):
+ """ copy a collection.
- As this is not recursive (the davserver recurses itself)
- we will only create a new directory here. For some more
- advanced systems we might also have to copy properties from
- the source to the destination.
- """
- print " copy a collection."
- return self.mkcol(dst)
+ As this is not recursive (the davserver recurses itself)
+ we will only create a new directory here. For some more
+ advanced systems we might also have to copy properties from
+ the source to the destination.
+ """
+ print " copy a collection."
+ return self.mkcol(dst)
- def exists(self,uri):
- """ test if a resource exists """
- result = False
- cr, uid, pool,dbname, uri2 = self.get_cr(uri)
- if not dbname:
- return True
- try:
- node = self.uri2object(cr,uid,pool, uri2)
- if node:
- result = True
- except:
- pass
- cr.close()
- return result
+ def exists(self,uri):
+ """ test if a resource exists """
+ result = False
+ cr, uid, pool,dbname, uri2 = self.get_cr(uri)
+ if not dbname:
+ return True
+ try:
+ node = self.uri2object(cr,uid,pool, uri2)
+ if node:
+ result = True
+ except:
+ pass
+ cr.close()
+ return result
- @memoize(CACHE_SIZE)
- def is_collection(self,uri):
- """ test if the given uri is a collection """
- return self._get_dav_resourcetype(uri)==COLLECTION
+ @memoize(CACHE_SIZE)
+ def is_collection(self,uri):
+ """ test if the given uri is a collection """
+ return self._get_dav_resourcetype(uri)==COLLECTION
diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py
index f04315e13c9..37ce38e6709 100644
--- a/addons/document_webdav/webdav_server.py
+++ b/addons/document_webdav/webdav_server.py
@@ -35,13 +35,13 @@ from service.websrv_lib import HTTPDir,FixSendError
class DAVHandler(FixSendError,DAVRequestHandler):
verbose = False
-
+
def get_userinfo(self,user,pw):
- print "get_userinfo"
- return False
+ print "get_userinfo"
+ return False
def _log(self, message):
- netsvc.Logger().notifyChannel("webdav",netsvc.LOG_DEBUG,message)
-
+ netsvc.Logger().notifyChannel("webdav",netsvc.LOG_DEBUG,message)
+
def handle(self):
pass
@@ -49,30 +49,30 @@ class DAVHandler(FixSendError,DAVRequestHandler):
pass
def setup(self):
- davpath = '/'+config.get_misc('webdav','vdir','webdav')+'/'
- self.baseuri = "http://%s:%d%s"% (self.server.server_name,self.server.server_port,davpath)
- self.IFACE_CLASS = tinydav_handler(self)
- pass
-
+ davpath = '/'+config.get_misc('webdav','vdir','webdav')+'/'
+ self.baseuri = "http://%s:%d%s"% (self.server.server_name,self.server.server_port,davpath)
+ self.IFACE_CLASS = tinydav_handler(self)
+ pass
+
def log_message(self, format, *args):
- netsvc.Logger().notifyChannel('webdav',netsvc.LOG_DEBUG_RPC,format % args)
+ netsvc.Logger().notifyChannel('webdav',netsvc.LOG_DEBUG_RPC,format % args)
def log_error(self, format, *args):
- netsvc.Logger().notifyChannel('xmlrpc',netsvc.LOG_WARNING,format % args)
+ netsvc.Logger().notifyChannel('xmlrpc',netsvc.LOG_WARNING,format % args)
try:
- from service.http_server import reg_http_service,OpenERPAuthProvider
- if (config.get_misc('webdav','enable',False)):
- davpath = '/'+config.get_misc('webdav','vdir','webdav')+'/'
- handler = DAVHandler
- handler.verbose = config.get_misc('webdav','verbose',True)
- handler.debug = config.get_misc('webdav','debug',True)
- reg_http_service(HTTPDir(davpath,DAVHandler,OpenERPAuthProvider()))
- netsvc.Logger().notifyChannel('webdav',netsvc.LOG_INFO,"WebDAV service registered at path: %s/ "% davpath)
+ from service.http_server import reg_http_service,OpenERPAuthProvider
+ if (config.get_misc('webdav','enable',False)):
+ davpath = '/'+config.get_misc('webdav','vdir','webdav')+'/'
+ handler = DAVHandler
+ handler.verbose = config.get_misc('webdav','verbose',True)
+ handler.debug = config.get_misc('webdav','debug',True)
+ reg_http_service(HTTPDir(davpath,DAVHandler,OpenERPAuthProvider()))
+ netsvc.Logger().notifyChannel('webdav',netsvc.LOG_INFO,"WebDAV service registered at path: %s/ "% davpath)
except Exception, e:
- logger = netsvc.Logger()
- logger.notifyChannel('webdav', netsvc.LOG_ERROR, 'Cannot launch webdav: %s' % e)
+ logger = netsvc.Logger()
+ logger.notifyChannel('webdav', netsvc.LOG_ERROR, 'Cannot launch webdav: %s' % e)
#eof
From 575035a2050fd5328fe0dad3cdab3d453abaf430 Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Wed, 16 Dec 2009 11:39:18 +0530
Subject: [PATCH 016/123] [FIX] document_webdav : Replace char with four
bzr revid: hmo@tinyerp.com-20091216060918-vadie86sxpakwp8u
---
addons/document_webdav/DAV/WebDAVServer.py | 48 +++++++++++-----------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/addons/document_webdav/DAV/WebDAVServer.py b/addons/document_webdav/DAV/WebDAVServer.py
index cb4db2c0204..5f409773c18 100644
--- a/addons/document_webdav/DAV/WebDAVServer.py
+++ b/addons/document_webdav/DAV/WebDAVServer.py
@@ -81,8 +81,8 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def send_body(self,DATA,code,msg,desc,ctype='application/octet-stream',headers=None):
""" send a body in one part """
- if not headers:
- headers = {}
+ if not headers:
+ headers = {}
self.send_response(code,message=msg)
self.send_header("Connection", "keep-alive")
self.send_header("Accept-Ranges", "bytes")
@@ -122,7 +122,7 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.send_response(200)
self.send_header("Allow", "GET, HEAD, COPY, MOVE, POST, PUT, PROPFIND, PROPPATCH, OPTIONS, MKCOL, DELETE, TRACE")
self.send_header("Content-Type", "text/plain")
- self.send_header("Connection", "keep-alive")
+ self.send_header("Connection", "keep-alive")
self.send_header("DAV", "1")
self.end_headers()
@@ -162,9 +162,9 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
try:
DATA=pf.createResponse()
DATA=DATA+"\n"
- # print "Data:", DATA
- except DAV_NotFound,(ec,dd):
- return self.send_notFound(dd, uri)
+ # print "Data:", DATA
+ except DAV_NotFound,(ec,dd):
+ return self.send_notFound(dd, uri)
except DAV_Error, (ec,dd):
return self.send_error(ec,dd)
@@ -172,10 +172,10 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def geturi(self):
buri = self.IFACE_CLASS.baseuri
- if buri[-1] == '/':
- return urllib.unquote(buri[:-1]+self.path)
- else:
- return urllib.unquote(buri+self.path)
+ if buri[-1] == '/':
+ return urllib.unquote(buri[:-1]+self.path)
+ else:
+ return urllib.unquote(buri+self.path)
def do_GET(self):
"""Serve a GET request."""
@@ -209,7 +209,7 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
""" Send a HEAD response """
dc=self.IFACE_CLASS
uri=self.geturi()
-
+
# get the last modified date
try:
lm=dc.get_prop(uri,"DAV:","getlastmodified")
@@ -243,12 +243,12 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
uri=self.geturi()
try:
res = dc.mkcol(uri)
- if res:
- self.send_body(None,201,"Created",'')
- else:
- self.send_body(None,415,"Cannot create",'')
- #self.send_header("Connection", "keep-alive")
- # Todo: some content, too
+ if res:
+ self.send_body(None,201,"Created",'')
+ else:
+ self.send_body(None,415,"Cannot create",'')
+ #self.send_header("Connection", "keep-alive")
+ # Todo: some content, too
except DAV_Error, (ec,dd):
self.send_body(None,int(ec),dd,dd)
@@ -370,10 +370,10 @@ class DAVRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def send_notFound(self,descr,uri):
body = """
-
- %s
-
- %s
-
- """
- return self.send_status(404,descr, body=body % (uri,descr))
+
+ %s
+
+ %s
+
+ """
+ return self.send_status(404,descr, body=body % (uri,descr))
From a2c91a7733c40402f5c228bea50b909f3b02004c Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Wed, 16 Dec 2009 16:57:50 +0100
Subject: [PATCH 017/123] [IMP] Add comment on table base on description [IMP]
Add comment on column base on field name [IMP] Add comment on relation table
(many2many)
bzr revid: christophe.chauvet@syleam.fr-20091216155750-mpujuc3v3zojwhw6
---
bin/osv/orm.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 280b5020704..08d8bfc2664 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -1843,6 +1843,7 @@ class orm(orm_template):
cr.execute("SELECT relname FROM pg_class WHERE relkind in ('r','v') AND relname='%s'" % self._table)
if not cr.rowcount:
cr.execute("CREATE TABLE \"%s\" (id SERIAL NOT NULL, PRIMARY KEY(id)) WITH OIDS" % self._table)
+ cr.execute("COMMENT ON TABLE \"%s\" IS '%s'" % (self._table, self._description.replace("'","''")))
create = True
cr.commit()
if self._parent_store:
@@ -1907,6 +1908,7 @@ class orm(orm_template):
cr.execute('CREATE TABLE "%s" ("%s" INTEGER NOT NULL REFERENCES "%s" ON DELETE CASCADE, "%s" INTEGER NOT NULL REFERENCES "%s" ON DELETE CASCADE) WITH OIDS' % (f._rel, f._id1, self._table, f._id2, ref))
cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id1, f._rel, f._id1))
cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id2, f._rel, f._id2))
+ cr.execute("COMMENT ON TABLE \"%s\" IS 'RELATION BETWEEN %s AND %s'" % (f._rel, self._table, ref))
cr.commit()
else:
cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \
@@ -1935,6 +1937,7 @@ class orm(orm_template):
# add the missing field
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
+ cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'","''")))
# initialize it
if not create and k in self._defaults:
From 17a627ced93809fc50b002b5785c4e7003a58f05 Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Wed, 16 Dec 2009 17:40:44 +0100
Subject: [PATCH 018/123] [IMP] Don't use OIDS when create database, because
- There is a primary key on all tables - OIDS are disable since 8.0
bzr revid: christophe.chauvet@syleam.fr-20091216164044-stzqgdxsbl019x41
---
bin/osv/orm.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 08d8bfc2664..f9e216ec5a8 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -1842,7 +1842,7 @@ class orm(orm_template):
if not hasattr(self, "_auto") or self._auto:
cr.execute("SELECT relname FROM pg_class WHERE relkind in ('r','v') AND relname='%s'" % self._table)
if not cr.rowcount:
- cr.execute("CREATE TABLE \"%s\" (id SERIAL NOT NULL, PRIMARY KEY(id)) WITH OIDS" % self._table)
+ cr.execute("CREATE TABLE \"%s\" (id SERIAL NOT NULL, PRIMARY KEY(id)) WITHOUT OIDS" % self._table)
cr.execute("COMMENT ON TABLE \"%s\" IS '%s'" % (self._table, self._description.replace("'","''")))
create = True
cr.commit()
@@ -1905,7 +1905,7 @@ class orm(orm_template):
ref = self.pool.get(f._obj)._table
except AttributeError:
ref = f._obj.replace('.', '_')
- cr.execute('CREATE TABLE "%s" ("%s" INTEGER NOT NULL REFERENCES "%s" ON DELETE CASCADE, "%s" INTEGER NOT NULL REFERENCES "%s" ON DELETE CASCADE) WITH OIDS' % (f._rel, f._id1, self._table, f._id2, ref))
+ cr.execute('CREATE TABLE "%s" ("%s" INTEGER NOT NULL REFERENCES "%s" ON DELETE CASCADE, "%s" INTEGER NOT NULL REFERENCES "%s" ON DELETE CASCADE) WITHOUT OIDS' % (f._rel, f._id1, self._table, f._id2, ref))
cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id1, f._rel, f._id1))
cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id2, f._rel, f._id2))
cr.execute("COMMENT ON TABLE \"%s\" IS 'RELATION BETWEEN %s AND %s'" % (f._rel, self._table, ref))
From ad5882ec42eb4f923f38cb73c9e23559bff1594b Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 17 Dec 2009 14:12:14 +0530
Subject: [PATCH 019/123] [IMP] document: remove ftp Integration from document
and make seperate module for FTP Integration
bzr revid: hmo@tinyerp.com-20091217084214-6mve0dt68u8jdded
---
addons/document/__init__.py | 2 -
addons/document/__terp__.py | 3 +-
addons/document/document_view.xml | 51 +----------------
addons/document/nodes.py | 6 +-
addons/document/security/ir.model.access.csv | 2 -
addons/document_ftp/__init__.py | 24 ++++++++
addons/document_ftp/__terp__.py | 43 ++++++++++++++
.../doc_conf_wizard.py | 0
addons/document_ftp/document_ftp_view.xml | 56 +++++++++++++++++++
.../ftpserver/__init__.py | 0
.../ftpserver/abstracted_fs.py | 4 +-
.../ftpserver/authorizer.py | 0
.../ftpserver/ftpserver.py | 0
.../document_ftp/security/ir.model.access.csv | 3 +
14 files changed, 137 insertions(+), 57 deletions(-)
create mode 100644 addons/document_ftp/__init__.py
create mode 100644 addons/document_ftp/__terp__.py
rename addons/{document => document_ftp}/doc_conf_wizard.py (100%)
create mode 100644 addons/document_ftp/document_ftp_view.xml
rename addons/{document => document_ftp}/ftpserver/__init__.py (100%)
rename addons/{document => document_ftp}/ftpserver/abstracted_fs.py (99%)
rename addons/{document => document_ftp}/ftpserver/authorizer.py (100%)
rename addons/{document => document_ftp}/ftpserver/ftpserver.py (100%)
create mode 100644 addons/document_ftp/security/ir.model.access.csv
diff --git a/addons/document/__init__.py b/addons/document/__init__.py
index a9810a8b7b8..f624cfa850b 100644
--- a/addons/document/__init__.py
+++ b/addons/document/__init__.py
@@ -25,8 +25,6 @@ import document_storage
import document_directory
import directory_content
import directory_report
-import doc_conf_wizard
import document
-import ftpserver
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/__terp__.py b/addons/document/__terp__.py
index be9eb6a9d3f..edd5ebe83af 100644
--- a/addons/document/__terp__.py
+++ b/addons/document/__terp__.py
@@ -24,8 +24,7 @@
'name': 'Integrated Document Management System',
'version': '1.99',
'category': 'Generic Modules/Others',
- 'description': """This is a complete document management system:
- * FTP Interface
+ 'description': """This is a complete document management system:
* User Authentication
* Document Indexation
""",
diff --git a/addons/document/document_view.xml b/addons/document/document_view.xml
index babc5af33b3..e23b3ac5025 100644
--- a/addons/document/document_view.xml
+++ b/addons/document/document_view.xml
@@ -146,19 +146,7 @@
-
-
- Browse Files
- ftp://localhost:8021/
-
-
+ parent="menu_document_configuration"/>
ir.attachment
@@ -301,42 +289,7 @@
-
-
-
- Auto Configure Directory
- document.configuration.wizard
- form
-
-
-
-
-
-
- Auto Configure Directory
- ir.actions.act_window
- document.configuration.wizard
- form
- form
- new
-
-
-
- Auto Configure Directory
- This wizard will configure the URL of the server of the document management system.
-
-
-
+
).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+import doc_conf_wizard
+import ftpserver
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_ftp/__terp__.py b/addons/document_ftp/__terp__.py
new file mode 100644
index 00000000000..13da099768c
--- /dev/null
+++ b/addons/document_ftp/__terp__.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+
+{
+ 'name': 'Integrated FTP Server with Document Management System',
+ 'version': '1.99',
+ 'category': 'Generic Modules/Others',
+ 'description': """This is a support FTP Interface with document management system:
+""",
+ 'author': 'Tiny',
+ 'website': 'http://www.openerp.com',
+ 'depends': ['base', 'document'],
+ 'init_xml': [],
+ 'update_xml': [
+ 'document_ftp_view.xml',
+ 'security/ir.model.access.csv'
+ ],
+ 'demo_xml': [],
+ 'installable': True,
+ 'active': False,
+ 'certificate': None,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/doc_conf_wizard.py b/addons/document_ftp/doc_conf_wizard.py
similarity index 100%
rename from addons/document/doc_conf_wizard.py
rename to addons/document_ftp/doc_conf_wizard.py
diff --git a/addons/document_ftp/document_ftp_view.xml b/addons/document_ftp/document_ftp_view.xml
new file mode 100644
index 00000000000..793dbfb7dea
--- /dev/null
+++ b/addons/document_ftp/document_ftp_view.xml
@@ -0,0 +1,56 @@
+
+
+
+ Browse Files
+ ftp://localhost:8021/
+
+
+
+
+
+
+
+ Auto Configure Directory
+ document.configuration.wizard
+ form
+
+
+
+
+
+
+ Auto Configure Directory
+ ir.actions.act_window
+ document.configuration.wizard
+ form
+ form
+ new
+
+
+
+ Auto Configure Directory
+ This wizard will configure the URL of the server of the document management system.
+
+
+
+
+
+
+
+
diff --git a/addons/document/ftpserver/__init__.py b/addons/document_ftp/ftpserver/__init__.py
similarity index 100%
rename from addons/document/ftpserver/__init__.py
rename to addons/document_ftp/ftpserver/__init__.py
diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document_ftp/ftpserver/abstracted_fs.py
similarity index 99%
rename from addons/document/ftpserver/abstracted_fs.py
rename to addons/document_ftp/ftpserver/abstracted_fs.py
index 46ddba18128..34a62e8683a 100644
--- a/addons/document/ftpserver/abstracted_fs.py
+++ b/addons/document_ftp/ftpserver/abstracted_fs.py
@@ -205,7 +205,9 @@ class abstracted_fs:
def fs2ftp(self, node):
res='/'
if node:
- res = os.path.normpath(''.join(node.full_path()))
+ paths = node.full_path()
+ paths = map(lambda x: '/' +x, paths)
+ res = os.path.normpath(''.join(paths))
res = res.replace("\\", "/")
while res[:2] == '//':
res = res[1:]
diff --git a/addons/document/ftpserver/authorizer.py b/addons/document_ftp/ftpserver/authorizer.py
similarity index 100%
rename from addons/document/ftpserver/authorizer.py
rename to addons/document_ftp/ftpserver/authorizer.py
diff --git a/addons/document/ftpserver/ftpserver.py b/addons/document_ftp/ftpserver/ftpserver.py
similarity index 100%
rename from addons/document/ftpserver/ftpserver.py
rename to addons/document_ftp/ftpserver/ftpserver.py
diff --git a/addons/document_ftp/security/ir.model.access.csv b/addons/document_ftp/security/ir.model.access.csv
new file mode 100644
index 00000000000..c9c082f4397
--- /dev/null
+++ b/addons/document_ftp/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_document_configuation_wizard","document.configuration.wizard document manager","model_document_configuration_wizard","document.group_document_manager",1,1,1,1
+"access_document_configuation_wizard_sytem","document.configuration.wizard group system","model_document_configuration_wizard","base.group_system",1,1,1,1
From 33f9180c0cc11b1fbb4a5fee8caeb7faffd2de68 Mon Sep 17 00:00:00 2001
From: "P. Christeas"
Date: Thu, 17 Dec 2009 14:32:52 +0530
Subject: [PATCH 020/123] [FIX] document_webdav: close another 2 cursors, avoid
deadlock. taken from xrg git branch:fc70e930c1e89c868c613fdc83534e9f853dcfa2
bzr revid: hmo@tinyerp.com-20091217090252-f9thyune5j2dcxa6
---
addons/document_webdav/dav_fs.py | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py
index 0d8331b8959..68f0bd71c40 100644
--- a/addons/document_webdav/dav_fs.py
+++ b/addons/document_webdav/dav_fs.py
@@ -150,6 +150,7 @@ class tinydav_handler(dav_interface):
if not dbname:
s = netsvc.LocalService('db')
+ cr.close()
return map(lambda x: self.urijoin(x), self.db_list())
result = []
node = self.uri2object(cr,uid,pool, uri2[:])
@@ -354,11 +355,6 @@ class tinydav_handler(dav_interface):
node = self.uri2object(cr,uid,pool, uri2)
if not node:
raise DAV_NotFound(uri2)
-
- result = 'application/octet-stream'
- #if node.type=='collection':
- #result ='httpd/unix-directory'
- #else:
result = node.mimetype
return result
#raise DAV_NotFound, 'Could not find %s' % path
@@ -469,6 +465,7 @@ class tinydav_handler(dav_interface):
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
#if not dbname:
if True:
+ cr.close()
raise DAV_Error, 409
node = self.uri2object(cr,uid,pool, uri2)
object2=node and node.object2 or False
@@ -637,6 +634,7 @@ class tinydav_handler(dav_interface):
result = False
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
if not dbname:
+ cr.close()
return True
try:
node = self.uri2object(cr,uid,pool, uri2)
From 23dd94d600e40a07435a688da6ce16fd456d474b Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 17 Dec 2009 14:34:37 +0530
Subject: [PATCH 021/123] [IMP] document_webdav : Replace with four
bzr revid: hmo@tinyerp.com-20091217090437-56n5zq91e1fzy8rf
---
addons/document_webdav/DAV/iface.py | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/addons/document_webdav/DAV/iface.py b/addons/document_webdav/DAV/iface.py
index 8f6daa5eaa8..c8f5fe2594d 100644
--- a/addons/document_webdav/DAV/iface.py
+++ b/addons/document_webdav/DAV/iface.py
@@ -67,19 +67,19 @@ class dav_interface:
if self.M_NS.has_key(ns):
prefix=self.M_NS[ns]
else:
- print "No namespace:",ns
+ print "No namespace:",ns, "( for prop:", propname,")"
raise DAV_NotFound
mname=prefix+"_"+propname
- if not hasattr(self,mname):
- raise DAV_NotFound
+ if not hasattr(self,mname):
+ raise DAV_NotFound
try:
m=getattr(self,mname)
r=m(uri)
return r
except AttributeError, e:
- print 'Property %s not supported' % propname
- print "Exception:", e
+ print 'Property %s not supported' % propname
+ print "Exception:", e
raise DAV_NotFound
###
@@ -110,15 +110,15 @@ class dav_interface:
""" return the creationdate of a resource """
d=self.get_creationdate(uri)
# format it
- if isinstance(d, int) or isinstance(d, float):
- d = time.localtimetime(d)
+ if isinstance(d, int) or isinstance(d, float):
+ d = time.localtimetime(d)
return time.strftime("%Y-%m-%dT%H:%M:%S%Z",d)
def _get_dav_getlastmodified(self,uri):
""" return the last modified date of a resource """
d=self.get_lastmodified(uri)
- if isinstance(d, int) or isinstance(d, float):
- d = time.localtime(d)
+ if isinstance(d, int) or isinstance(d, float):
+ d = time.localtime(d)
# format it
return time.asctime(d)
From 1b8c310a0a009b9c031e6bb177673bdf65a84b90 Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 17 Dec 2009 17:26:04 +0530
Subject: [PATCH 022/123] [FIX] document_webdav: fixed regration in mkcol,
rmcol, rm
bzr revid: hmo@tinyerp.com-20091217115604-g5h8vr9zmcaam4dv
---
addons/document_webdav/DAV/utils.py | 2 +-
addons/document_webdav/dav_fs.py | 87 ++++++++++++++---------------
2 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/addons/document_webdav/DAV/utils.py b/addons/document_webdav/DAV/utils.py
index a764a6d96c9..c4bb4d1a4c0 100755
--- a/addons/document_webdav/DAV/utils.py
+++ b/addons/document_webdav/DAV/utils.py
@@ -135,7 +135,7 @@ def get_parenturi(uri):
def make_xmlresponse(result):
""" construct a response from a dict of uri:error_code elements """
- doc = Document.Document(None)
+ doc = Document(None)
ms=doc.createElement("D:multistatus")
ms.setAttribute("xmlns:D","DAV:")
doc.appendChild(ms)
diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py
index 68f0bd71c40..750b06a4b65 100644
--- a/addons/document_webdav/dav_fs.py
+++ b/addons/document_webdav/dav_fs.py
@@ -46,9 +46,9 @@ from DAV.iface import *
import urllib
from DAV.davcmd import copyone, copytree, moveone, movetree, delone, deltree
-
+from document.nodes import node_res_dir, node_res_obj
from cache import memoize
-
+from tools import misc
CACHE_SIZE=20000
#hack for urlparse: add webdav in the net protocols
@@ -183,9 +183,9 @@ class tinydav_handler(dav_interface):
#
# pos: -1 to get the parent of the uri
#
- def get_cr(self, uri):
+ def get_cr(self, uri):
pdb = self.parent.auth_proxy.last_auth
- reluri = self.uri2local(uri)
+ reluri = self.uri2local(uri)
try:
dbname = reluri.split('/')[2]
except:
@@ -195,7 +195,7 @@ class tinydav_handler(dav_interface):
if not pdb and dbname:
# if dbname was in our uri, we should have authenticated
# against that.
- raise Exception("Programming error")
+ raise Exception("Programming error")
assert pdb == dbname, " %s != %s" %(pdb, dbname)
user, passwd, dbn2, uid = self.parent.auth_proxy.auth_creds[pdb]
db,pool = pooler.get_db_and_pool(dbname)
@@ -376,32 +376,32 @@ class tinydav_handler(dav_interface):
if not dbname:
raise DAV_Error, 409
node = self.uri2object(cr,uid,pool, uri2[:-1])
- object2=node and node.object2 or False
- object=node and node.object or False
+ object2 = False
+ if isinstance(node, node_res_obj):
+ object2 = node and pool.get(node.context.context['res_model']).browse(cr, uid, node.context.context['res_id']) or False
+
+ obj = node.context._dirobj.browse(cr, uid, node.dir_id)
+ if obj and (obj.type == 'ressource') and not object2:
+ raise OSError(1, 'Operation not permited.')
objname = uri2[-1]
- if not object:
- pool.get('document.directory').create(cr, uid, {
+ val = {
'name': objname,
- 'parent_id': False,
- 'ressource_type_id': False,
- 'ressource_id': False
- })
- else:
- pool.get('document.directory').create(cr, uid, {
- 'name': objname,
- 'parent_id': object.id,
- 'ressource_type_id': object.ressource_type_id.id,
- 'ressource_id': object2 and object2.id or False
- })
-
- cr.commit()
+ 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False,
+ 'ressource_id': object2 and object2.id or False,
+ 'parent_id' : False
+ }
+ if (obj and (obj.type in ('directory'))) or not object2:
+ val['parent_id'] = obj and obj.id or False
+
+ pool.get('document.directory').create(cr, uid, val)
+ cr.commit()
cr.close()
return True
def put(self,uri,data,content_type=None):
""" put the object into the filesystem """
- self.parent.log_message('Putting %s (%d), %s'%( unicode(uri,'utf8'), len(data), content_type))
+ self.parent.log_message('Putting %s (%d), %s'%( misc.ustr(uri), len(data), content_type))
parent='/'.join(uri.split('/')[:-1])
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
if not dbname:
@@ -434,25 +434,27 @@ class tinydav_handler(dav_interface):
raise DAV_Forbidden
cr.commit()
-
+ cr.close()
return 201
def rmcol(self,uri):
""" delete a collection """
if uri[-1]=='/':uri=uri[:-1]
- cr, uid, pool, dbname, uri2 = self.get_cr(uri)
- if True or not dbname: # *-*
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if not dbname: # *-*
raise DAV_Error, 409
- node = self.uri2object(cr,uid,pool, uri2)
- object2=node and node.object2 or False
- object=node and node.object or False
+ node = self.uri2object(cr, uid, pool, uri2)
+ object = node.context._dirobj.browse(cr, uid, node.dir_id)
+
+ if not object:
+ raise OSError(2, 'Not such file or directory.')
if object._table_name=='document.directory':
- if object.child_ids:
- raise DAV_Forbidden # forbidden
- if object.file_ids:
- raise DAV_Forbidden # forbidden
+ if node.children(cr):
+ raise OSError(39, 'Directory not empty.')
res = pool.get('document.directory').unlink(cr, uid, [object.id])
+ else:
+ raise OSError(1, 'Operation not permited.')
cr.commit()
cr.close()
@@ -463,22 +465,19 @@ class tinydav_handler(dav_interface):
object=False
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
- #if not dbname:
- if True:
- cr.close()
+ if not dbname:
+ cr.close()
raise DAV_Error, 409
node = self.uri2object(cr,uid,pool, uri2)
- object2=node and node.object2 or False
- object=node and node.object or False
- if not object:
- raise DAV_NotFound
-
+ object = pool.get('ir.attachment').browse(cr, uid, node.file_id)
self.parent.log_message(' rm %s "%s"'%(object._table_name,uri))
- if object._table_name=='ir.attachment':
+ if not object:
+ raise OSError(2, 'Not such file or directory.')
+ if object._table_name == 'ir.attachment':
res = pool.get('ir.attachment').unlink(cr, uid, [object.id])
else:
- raise DAV_Forbidden # forbidden
- parent='/'.join(uri.split('/')[:-1])
+ raise OSError(1, 'Operation not permited.')
+
cr.commit()
cr.close()
return 204
From 0ada27a1e5bf97ebafe6bb0faf3801443bda2455 Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Thu, 17 Dec 2009 17:30:11 +0530
Subject: [PATCH 023/123] [FIX]: report_analytic_planning: improved search
method
bzr revid: uco@tinyerp.co.in-20091217120011-znd2lxznuxdw0z70
---
addons/report_analytic_planning/report_analytic_planning.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/addons/report_analytic_planning/report_analytic_planning.py b/addons/report_analytic_planning/report_analytic_planning.py
index 509f2250f85..ee1e04816af 100644
--- a/addons/report_analytic_planning/report_analytic_planning.py
+++ b/addons/report_analytic_planning/report_analytic_planning.py
@@ -198,6 +198,8 @@ class project_task(osv.osv):
}
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
+ if not context:
+ context = {}
if not context.get('planning'):
return super(project_task,self).search(cr, user, args, offset, limit, order, context)
cr.execute(" SELECT t.id, t.name \
From 6d32891c048f51d1c678e9f343dfdf3210fdd2b6 Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)"
Date: Thu, 17 Dec 2009 18:52:31 +0530
Subject: [PATCH 024/123] [FIX] document, document_ics, document_ftp : solved
problem to read content data
bzr revid: hmo@tinyerp.com-20091217132231-a4zcin2lvd2qjjsn
---
addons/document/directory_content.py | 10 ++++------
addons/document_ftp/ftpserver/abstracted_fs.py | 8 ++++----
addons/document_ics/document_ics.py | 9 ++++-----
3 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py
index b82da1bce8a..0b1b444e83a 100644
--- a/addons/document/directory_content.py
+++ b/addons/document/directory_content.py
@@ -98,18 +98,16 @@ class document_directory_content(osv.osv):
res2.append(n)
return res2
- def process_write(self, cr, uid, node, data):
+ def process_write(self, cr, uid, node, data, context=None):
if node.extension != '.pdf':
raise Exception("Invalid content: %s" % node.extension)
return True
- def process_read(self, cr, uid, node):
+ def process_read(self, cr, uid, node, context=None):
if node.extension != '.pdf':
raise Exception("Invalid content: %s" % node.extension)
report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.report_id)
srv = netsvc.Service._services['report.'+report.report_name]
- pdf,pdftype = srv.create(cr, uid, [node.context.context['res_id']], {}, {})
- s = StringIO.StringIO(pdf)
- s.name = node
- return s
+ pdf,pdftype = srv.create(cr, uid, [node.context.context['res_id']], {}, {})
+ return pdf
document_directory_content()
diff --git a/addons/document_ftp/ftpserver/abstracted_fs.py b/addons/document_ftp/ftpserver/abstracted_fs.py
index 34a62e8683a..82a860b95d1 100644
--- a/addons/document_ftp/ftpserver/abstracted_fs.py
+++ b/addons/document_ftp/ftpserver/abstracted_fs.py
@@ -328,10 +328,10 @@ class abstracted_fs:
cr = pooler.get_db(node.context.dbname).cursor()
pool = pooler.get_pool(node.context.dbname)
res = getattr(pool.get('document.directory.content'), 'process_read')(cr, uid, node)
- cr.close()
- s = StringIO.StringIO(res)
- s.name = node
- return s
+ res = StringIO.StringIO(res)
+ res.name = node
+ cr.close()
+ return res
else:
raise OSError(1, 'Operation not permited.')
diff --git a/addons/document_ics/document_ics.py b/addons/document_ics/document_ics.py
index 1fb8518050b..440d043d880 100644
--- a/addons/document_ics/document_ics.py
+++ b/addons/document_ics/document_ics.py
@@ -126,7 +126,7 @@ class document_directory_content(osv.osv):
def process_write(self, cr, uid, node, data, context=None):
if node.extension != '.ics':
- return super(document_directory_content).process_write(cr, uid, node, data, context)
+ return super(document_directory_content, self).process_write(cr, uid, node, data, context)
import vobject
parsedCal = vobject.readOne(data)
fields = {}
@@ -245,7 +245,7 @@ class document_directory_content(osv.osv):
return datetime.datetime.strptime(idate, '%Y-%m-%d %H:%M:%S')
if node.extension != '.ics':
- return super(document_directory_content).process_read(cr, uid, node, context)
+ return super(document_directory_content, self).process_read(cr, uid, node, context)
import vobject
ctx = (context or {})
@@ -253,7 +253,7 @@ class document_directory_content(osv.osv):
ctx.update(node.dctx)
content = self.browse(cr, uid, node.cnt_id, ctx)
if not content.object_id:
- return super(document_directory_content).process_read(cr, uid, node, context)
+ return super(document_directory_content, self).process_read(cr, uid, node, context)
obj_class = self.pool.get(content.object_id.model)
if content.ics_domain:
@@ -294,8 +294,7 @@ class document_directory_content(osv.osv):
else:
value = ics_datetime(value)
event.add(field.name).value = value
- s= cal.serialize()
- cr.commit()
+ s = cal.serialize()
return s
document_directory_content()
From d1df64b2ce8cbd9050698af6c18e37db908a9ae4 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Thu, 17 Dec 2009 19:38:20 +0100
Subject: [PATCH 025/123] [FIX] osv_memory inherit osv
bzr revid: fp@tinyerp.com-20091217183820-93ylh4pfvvfbgpu2
---
bin/osv/orm.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 0d8e36031f7..a326b6b23e3 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -1531,7 +1531,7 @@ class orm_memory(orm_template):
_check_time = 20
def __init__(self, cr):
- orm_template.__init__(self, cr)
+ super(orm_memory, self).__init__(cr)
self.datas = {}
self.next_id = 0
self.check_id = 0
From 121d3c2222f3f2ef872d13557331fd140dd14b10 Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Thu, 17 Dec 2009 22:37:00 +0100
Subject: [PATCH 026/123] [FIX] change size for multi company default from 32
to 256 [IMP] Prepare _company_default_get to support rules on object's field
lp bug: https://launchpad.net/bugs/497685 fixed
bzr revid: christophe.chauvet@syleam.fr-20091217213700-k1i6fdgojhn0uccs
---
bin/addons/base/res/res_company.py | 11 ++++++++---
bin/addons/base/res/res_company_view.xml | 5 ++++-
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/bin/addons/base/res/res_company.py b/bin/addons/base/res/res_company.py
index acd1e85a184..70af44da6a4 100644
--- a/bin/addons/base/res/res_company.py
+++ b/bin/addons/base/res/res_company.py
@@ -36,7 +36,7 @@ class multi_company_default(osv.osv):
_columns = {
'sequence': fields.integer('Sequence'),
- 'name': fields.char('Name', size=32, required=True, help='Name it to easily find a record'),
+ 'name': fields.char('Name', size=256, required=True, help='Name it to easily find a record'),
'company_id': fields.many2one('res.company', 'Main Company', required=True,
help='Company where the user is connected'),
'company_dest_id': fields.many2one('res.company', 'Default Company', required=True,
@@ -45,6 +45,7 @@ class multi_company_default(osv.osv):
help='Object affect by this rules'),
'expression': fields.char('Expression', size=32, required=True,
help='Expression, must be True to match'),
+ 'field_id': fields.many2one('ir.model.fields', 'Field', help='Select field property'),
}
_defaults = {
@@ -88,14 +89,18 @@ class res_company(osv.osv):
}
- def _company_default_get(self, cr, uid, object=False, context=None):
+ def _company_default_get(self, cr, uid, object=False, field=False, context=None):
"""
Check if the object for this company have a default value
"""
if not context:
context = {}
proxy = self.pool.get('multi_company.default')
- ids = proxy.search(cr, uid, [('object_id.model', '=', object)])
+ args = [
+ ('object_id.model', '=', object),
+ ('field_id.name','=',field),
+ ]
+ ids = proxy.search(cr, uid, args)
for rule in proxy.browse(cr, uid, ids, context):
user = self.pool.get('res.users').browse(cr, uid, uid)
if eval(rule.expression, {'context': context, 'user': user}):
diff --git a/bin/addons/base/res/res_company_view.xml b/bin/addons/base/res/res_company_view.xml
index cfaab5abd38..34e58b75b6c 100644
--- a/bin/addons/base/res/res_company_view.xml
+++ b/bin/addons/base/res/res_company_view.xml
@@ -11,6 +11,7 @@
+
@@ -30,10 +31,12 @@
-
+
+
+
From 981e7408bd583ded90afbdc236e5cd895c1bd89a Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Thu, 17 Dec 2009 22:38:28 +0100
Subject: [PATCH 027/123] [IMP] Extended the field.property to new type field
(char, integer, float, date, ...) By default, when there are no multi
company default, we keep the compatibility with 5.0 else we match to
find the company_id for this fields.
bzr revid: christophe.chauvet@syleam.fr-20091217213828-f8edggbqnhzw41h2
---
bin/addons/base/res/ir_property.py | 13 +-------
bin/osv/fields.py | 53 +++++++++++++++++-------------
2 files changed, 32 insertions(+), 34 deletions(-)
diff --git a/bin/addons/base/res/ir_property.py b/bin/addons/base/res/ir_property.py
index e14e365dce3..b02ba593a02 100644
--- a/bin/addons/base/res/ir_property.py
+++ b/bin/addons/base/res/ir_property.py
@@ -25,17 +25,6 @@ from osv import osv,fields
# Properties
# -------------------------------------------------------------------------
-def _models_get2(self, cr, uid, context={}):
- obj = self.pool.get('ir.model.fields')
- ids = obj.search(cr, uid, [('view_load','=',1)])
- res = []
- done = {}
- for o in obj.browse(cr, uid, ids, context=context):
- if o.relation not in done:
- res.append( [o.relation, o.relation])
- done[o.relation] = True
- return res
-
def _models_get(self, cr, uid, context={}):
obj = self.pool.get('ir.model.fields')
ids = obj.search(cr, uid, [('view_load','=',1)])
@@ -51,7 +40,7 @@ class ir_property(osv.osv):
_name = 'ir.property'
_columns = {
'name': fields.char('Name', size=128),
- 'value': fields.reference('Value', selection=_models_get2, size=128),
+ 'value': fields.char('Value', size=128),
'res_id': fields.reference('Resource', selection=_models_get, size=128),
'company_id': fields.many2one('res.company', 'Company'),
'fields_id': fields.many2one('ir.model.fields', 'Fields', ondelete='cascade', required=True)
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 09d51e6bd82..50b7a233b3b 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -856,9 +856,12 @@ class property(function):
if nid:
default_val = property.browse(cr, uid, nid[0], context).value
- company_id = obj.pool.get('res.users').company_get(cr, uid, uid)
+ company_id = obj.pool.get('res.company')._company_default_get(cr, uid, obj._name, prop, context=context)
res = False
- newval = (id_val and obj_dest+','+str(id_val)) or False
+ if val[0]:
+ newval = (id_val and obj_dest+','+str(id_val)) or False
+ else:
+ newval = id_val or False
if (newval != default_val) and newval:
propdef = obj.pool.get('ir.model.fields').browse(cr, uid,
definition_id, context=context)
@@ -892,27 +895,33 @@ class property(function):
for id in ids:
res[id] = default_val
for prop in property.browse(cr, uid, nids):
- res[int(prop.res_id.split(',')[1])] = (prop.value and \
- int(prop.value.split(',')[1])) or False
-
- obj = obj.pool.get(self._obj)
-
- to_check = res.values()
- if default_val and default_val not in to_check:
- to_check += [default_val]
- existing_ids = obj.search(cr, uid, [('id', 'in', to_check)])
-
- for id, res_id in res.items():
- if res_id not in existing_ids:
- cr.execute('DELETE FROM ir_property WHERE value=%s', ((obj._name+','+str(res_id)),))
- res[id] = default_val
-
- names = dict(obj.name_get(cr, uid, existing_ids, context))
- for r in res.keys():
- if res[r] and res[r] in names:
- res[r] = (res[r], names[res[r]])
+ if prop.value.find(',') >= 0:
+ res[int(prop.res_id.split(',')[1])] = (prop.value and \
+ int(prop.value.split(',')[1])) or False
else:
- res[r] = False
+ res[int(prop.res_id.split(',')[1])] = prop.value or ''
+
+ try:
+ obj = obj.pool.get(self._obj)
+
+ to_check = res.values()
+ if default_val and default_val not in to_check:
+ to_check += [default_val]
+ existing_ids = obj.search(cr, uid, [('id', 'in', to_check)])
+
+ for id, res_id in res.items():
+ if res_id not in existing_ids:
+ cr.execute('DELETE FROM ir_property WHERE value=%s', ((obj._name+','+str(res_id)),))
+ res[id] = default_val
+
+ names = dict(obj.name_get(cr, uid, existing_ids, context))
+ for r in res.keys():
+ if res[r] and res[r] in names:
+ res[r] = (res[r], names[res[r]])
+ else:
+ res[r] = False
+ except:
+ pass
return res
def _field_get(self, cr, uid, model_name, prop):
From d5b63d3e712b8e111844790699f373e61845e05b Mon Sep 17 00:00:00 2001
From: Launchpad Code Hosting
Date: Fri, 18 Dec 2009 04:32:11 +0000
Subject: [PATCH 028/123] Launchpad automatic translations update.
bzr revid: codehost@crowberry-20091218043211-a33bhc5qr5dxomlh
---
bin/addons/base/i18n/he.po | 6 +++---
bin/addons/base/i18n/lv.po | 8 ++++----
debian/po/nl.po | 6 +++---
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/bin/addons/base/i18n/he.po b/bin/addons/base/i18n/he.po
index 69b016efba9..5a07918b3fa 100644
--- a/bin/addons/base/i18n/he.po
+++ b/bin/addons/base/i18n/he.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-12-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-16 06:38+0000\n"
+"PO-Revision-Date: 2009-12-17 09:51+0000\n"
"Last-Translator: Ddorda \n"
"Language-Team: Hebrew \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-17 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -7105,7 +7105,7 @@ msgstr "גבוה"
#. module: base
#: field:ir.exports.line,export_id:0
msgid "Export"
-msgstr "יצוא"
+msgstr "ייצוא"
#. module: base
#: help:res.bank,bic:0
diff --git a/bin/addons/base/i18n/lv.po b/bin/addons/base/i18n/lv.po
index 7b88c983472..f202c0b1a13 100644
--- a/bin/addons/base/i18n/lv.po
+++ b/bin/addons/base/i18n/lv.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-12-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-15 06:30+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-17 07:02+0000\n"
+"Last-Translator: Normunds \n"
"Language-Team: Latvian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:01+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -3196,7 +3196,7 @@ msgstr "Montserrata"
#. module: base
#: model:ir.ui.menu,name:base.menu_translation_app
msgid "Application Terms"
-msgstr "Izmantotie nosacījumi"
+msgstr "Izmantotie Termini"
#. module: base
#: selection:ir.report.custom.fields,operation:0
diff --git a/debian/po/nl.po b/debian/po/nl.po
index fa3715b3451..6ce8ed61821 100644
--- a/debian/po/nl.po
+++ b/debian/po/nl.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
-"PO-Revision-Date: 2009-12-16 08:28+0000\n"
-"Last-Translator: Pieter J. Kersten (EduSense BV) \n"
+"PO-Revision-Date: 2009-12-17 06:04+0000\n"
+"Last-Translator: Fabien (Open ERP) \n"
"Language-Team: Dutch \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-17 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. Type: string
From 4e84477b839a88fc8ec9afe75df22811f2e43c33 Mon Sep 17 00:00:00 2001
From: Launchpad Code Hosting
Date: Fri, 18 Dec 2009 04:32:51 +0000
Subject: [PATCH 029/123] Launchpad automatic translations update.
bzr revid: codehost@crowberry-20091218043251-vxlp1682pmjt2tdh
---
addons/account/i18n/bg.po | 6 +-
addons/account/i18n/vi.po | 2 +-
addons/account_analytic_default/i18n/el.po | 8 +-
addons/account_analytic_default/i18n/fi.po | 10 +-
addons/account_balance/i18n/bg.po | 8 +-
addons/account_invoice_layout/i18n/fi.po | 46 +++----
addons/auction/i18n/ro.po | 152 ++++++++++-----------
addons/base_setup/i18n/fi.po | 6 +-
addons/base_vat/i18n/fi.po | 6 +-
addons/board/i18n/el.po | 8 +-
addons/board_manufacturing/i18n/el.po | 8 +-
addons/hr/i18n/el.po | 8 +-
addons/hr_attendance/i18n/el.po | 8 +-
addons/mrp/i18n/el.po | 32 +++--
addons/mrp_repair/i18n/fi.po | 10 +-
addons/point_of_sale/i18n/ro.po | 86 ++++++------
addons/product/i18n/el.po | 6 +-
addons/product/i18n/zh_CN.po | 12 +-
addons/product_margin/i18n/el.po | 8 +-
addons/profile_manufacturing/i18n/el.po | 8 +-
addons/sale/i18n/fi.po | 16 +--
21 files changed, 230 insertions(+), 224 deletions(-)
diff --git a/addons/account/i18n/bg.po b/addons/account/i18n/bg.po
index ab3fd643aee..f83bee3fc8a 100644
--- a/addons/account/i18n/bg.po
+++ b/addons/account/i18n/bg.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-12-14 23:34+0000\n"
-"Last-Translator: Antoan Georgiev \n"
+"PO-Revision-Date: 2009-12-17 23:18+0000\n"
+"Last-Translator: Sianna \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: 2009-12-16 05:10+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
diff --git a/addons/account/i18n/vi.po b/addons/account/i18n/vi.po
index 5a891035cb9..73290bbaaa4 100644
--- a/addons/account/i18n/vi.po
+++ b/addons/account/i18n/vi.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-17 04:44+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
diff --git a/addons/account_analytic_default/i18n/el.po b/addons/account_analytic_default/i18n/el.po
index 50fcb8258e7..3b1b6386515 100644
--- a/addons/account_analytic_default/i18n/el.po
+++ b/addons/account_analytic_default/i18n/el.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-09-08 12:32+0000\n"
-"Last-Translator: Makis Nicolaou \n"
+"PO-Revision-Date: 2009-12-17 18:53+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: Greek \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:18+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_analytic_default
@@ -85,7 +85,7 @@ msgstr "Χρήστης"
#. module: account_analytic_default
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: account_analytic_default
#: model:ir.actions.act_window,name:account_analytic_default.act_account_acount_move_line_open
diff --git a/addons/account_analytic_default/i18n/fi.po b/addons/account_analytic_default/i18n/fi.po
index f2b853695e4..5009e43913d 100644
--- a/addons/account_analytic_default/i18n/fi.po
+++ b/addons/account_analytic_default/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: 2009-11-12 07:43+0000\n"
-"Last-Translator: NightSpirit \n"
+"PO-Revision-Date: 2009-12-17 19:17+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:18+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_analytic_default
@@ -32,7 +32,7 @@ msgstr "Tilin analyyttiset oletukset"
#. module: account_analytic_default
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr "Virheellinen XML näkymäarkkitehtuurille!"
+msgstr "Virheellinen XML näkymä-arkkitehtuurille!"
#. module: account_analytic_default
#: constraint:ir.model:0
@@ -83,7 +83,7 @@ msgstr "Käyttäjä"
#. module: account_analytic_default
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Virheellinen mallin nimi toimenpiteen määrittelyssä."
#. module: account_analytic_default
#: model:ir.actions.act_window,name:account_analytic_default.act_account_acount_move_line_open
diff --git a/addons/account_balance/i18n/bg.po b/addons/account_balance/i18n/bg.po
index e137a643404..4591f6a3701 100644
--- a/addons/account_balance/i18n/bg.po
+++ b/addons/account_balance/i18n/bg.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 09:36+0000\n"
-"Last-Translator: lem0na \n"
+"PO-Revision-Date: 2009-12-17 22:20+0000\n"
+"Last-Translator: Sianna \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: 2009-12-16 05:14+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_balance
@@ -210,7 +210,7 @@ msgstr ""
#: rml:account.account.balance.landscape:0
#: rml:account.balance.account.balance:0
msgid "Year :"
-msgstr ""
+msgstr "Година :"
#. module: account_balance
#: wizard_view:account.balance.account.balance.report,backtoinit:0
diff --git a/addons/account_invoice_layout/i18n/fi.po b/addons/account_invoice_layout/i18n/fi.po
index f346ba8bd24..44748efb05c 100644
--- a/addons/account_invoice_layout/i18n/fi.po
+++ b/addons/account_invoice_layout/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: 2009-09-08 12:39+0000\n"
-"Last-Translator: Marko Virtanen \n"
+"PO-Revision-Date: 2009-12-17 19:03+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:17+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_invoice_layout
@@ -83,7 +83,7 @@ msgstr "Yksikköhinta"
#. module: account_invoice_layout
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Virheellinen mallin nimi toimenpiteen määrittelyssä."
#. module: account_invoice_layout
#: model:ir.model,name:account_invoice_layout.model_notify_message
@@ -128,7 +128,7 @@ msgstr "Tyyppi"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Price"
-msgstr ""
+msgstr "Hinta"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
@@ -138,7 +138,7 @@ msgstr ""
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Taxes:"
-msgstr ""
+msgstr "Verot:"
#. module: account_invoice_layout
#: field:account.invoice.line,functional_field:0
@@ -178,32 +178,32 @@ msgstr ""
#. module: account_invoice_layout
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "Virheellinen XML näkymä-arkkitehtuurille!"
#. module: account_invoice_layout
#: selection:account.invoice.line,state:0
msgid "Page Break"
-msgstr ""
+msgstr "Sivunvaihto"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Document:"
-msgstr ""
+msgstr "Asiakirja:"
#. module: account_invoice_layout
#: wizard_view:wizard.notify_message,init:0
msgid "Select Message"
-msgstr ""
+msgstr "Valitse viesti"
#. module: account_invoice_layout
#: view:notify.message:0
msgid "Messages"
-msgstr ""
+msgstr "Viestit"
#. module: account_invoice_layout
#: selection:account.invoice.line,state:0
msgid "Product"
-msgstr ""
+msgstr "Tuote"
#. module: account_invoice_layout
#: model:ir.actions.report.xml,name:account_invoice_layout.account_invoices_1
@@ -228,22 +228,22 @@ msgstr ""
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Draft Invoice"
-msgstr ""
+msgstr "Laskun luonnos"
#. module: account_invoice_layout
#: field:account.invoice.line,sequence:0
msgid "Sequence Number"
-msgstr ""
+msgstr "Järjestysnumero"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Quantity"
-msgstr ""
+msgstr "Määrä"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Refund"
-msgstr ""
+msgstr "Hyvitys"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
@@ -258,7 +258,7 @@ msgstr ""
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Supplier Invoice"
-msgstr ""
+msgstr "Toimittajan lasku"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
@@ -268,7 +268,7 @@ msgstr ""
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Tax"
-msgstr ""
+msgstr "Vero"
#. module: account_invoice_layout
#: model:ir.module.module,shortdesc:account_invoice_layout.module_meta_information
@@ -283,27 +283,27 @@ msgstr ""
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Invoice"
-msgstr ""
+msgstr "Lasku"
#. module: account_invoice_layout
#: wizard_button:wizard.notify_message,init,end:0
msgid "Cancel"
-msgstr ""
+msgstr "Peruuta"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Supplier Refund"
-msgstr ""
+msgstr "Toimittajan hyvitys"
#. module: account_invoice_layout
#: wizard_field:wizard.notify_message,init,message:0
msgid "Message"
-msgstr ""
+msgstr "Viesti"
#. module: account_invoice_layout
#: rml:account.invoice.layout:0
msgid "Total"
-msgstr ""
+msgstr "Yhteensä"
#. module: account_invoice_layout
#: model:ir.ui.menu,name:account_invoice_layout.menu_notify_mesage_tree_form
diff --git a/addons/auction/i18n/ro.po b/addons/auction/i18n/ro.po
index f871048f9a3..ec731ed1e13 100644
--- a/addons/auction/i18n/ro.po
+++ b/addons/auction/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-12-10 11:25+0000\n"
+"PO-Revision-Date: 2009-12-17 16:54+0000\n"
"Last-Translator: geopop65 \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: 2009-12-16 05:19+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: auction
@@ -1386,7 +1386,7 @@ msgstr "Vânzători"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Metal Ware"
-msgstr ""
+msgstr "Antichităţi/Feronerie"
#. module: auction
#: model:ir.actions.report.xml,name:auction.res_w_buyer
@@ -1487,7 +1487,7 @@ msgstr "#"
#. module: auction
#: field:auction.lots,ach_emp:0
msgid "Taken Away"
-msgstr ""
+msgstr "Ridicat"
#. module: auction
#: view:report.object.encoded.manager:0
@@ -2143,7 +2143,7 @@ msgstr "Est."
#. module: auction
#: model:ir.ui.menu,name:auction.auction_report_menu
msgid "Reporting"
-msgstr ""
+msgstr "Raportare"
#. module: auction
#: view:auction.lots:0
@@ -2185,65 +2185,65 @@ msgstr "Ultima zi de expunere"
#: model:ir.actions.act_window,name:auction.action_auction_report_allmonth_view2
#: model:ir.actions.act_window,name:auction.action_auction_report_thismonth_view2
msgid "Auction report"
-msgstr ""
+msgstr "Raport licitaţie"
#. module: auction
#: model:ir.model,name:auction.model_auction_lot_category
msgid "auction.lot.category"
-msgstr ""
+msgstr "auction.lot.category"
#. module: auction
#: field:auction.artists,name:0
msgid "Artist/Author Name"
-msgstr ""
+msgstr "Nume Artist/Autor"
#. module: auction
#: field:auction.lots,image:0
msgid "Image"
-msgstr ""
+msgstr "Imagine"
#. module: auction
#: selection:report.object.encoded,state:0
msgid "Invoiced"
-msgstr ""
+msgstr "Facturat"
#. module: auction
#: view:auction.lots:0
#: selection:auction.lots,state:0
msgid "Taken away"
-msgstr ""
+msgstr "Ridicat"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Collectible & art objects"
-msgstr ""
+msgstr "Antichităţi/Colecţii şi obiecte de artă"
#. module: auction
#: xsl:report.auction.lots.list.landscape:0
msgid "BID:"
-msgstr ""
+msgstr "Licitare:"
#. module: auction
#: model:ir.actions.act_window,name:auction.action_auction_buyer_reporting
#: model:ir.actions.act_window,name:auction.action_auction_buyer_reporting2
#: model:ir.actions.act_window,name:auction.action_auction_buyer_reporting_all1
msgid "Buyer's auction"
-msgstr ""
+msgstr "Licitaţie cumpărător"
#. module: auction
#: view:report.seller.auction2:0
msgid "Auction reporting2 tree view"
-msgstr ""
+msgstr "Vedere arbore raport2 licitaţie"
#. module: auction
#: view:auction.deposit:0
msgid "Deposit Costs"
-msgstr ""
+msgstr "Costuri depozite"
#. module: auction
#: constraint:res.partner:0
msgid "Error ! You can not create recursive associated members."
-msgstr ""
+msgstr "Eroare ! Nu puteţi crea membri asociaţi recursiv."
#. module: auction
#: selection:auction.dates,state:0
@@ -2253,48 +2253,48 @@ msgstr ""
#: selection:report.seller.auction,state:0
#: selection:report.unclassified.objects,state:0
msgid "Draft"
-msgstr ""
+msgstr "Ciornă"
#. module: auction
#: rml:buyer.list:0
msgid "........."
-msgstr ""
+msgstr "........."
#. module: auction
#: xsl:report.auction.ach_bordereau:0
msgid "Buyer Cost:"
-msgstr ""
+msgstr "Cost cumpărător"
#. module: auction
#: xsl:report.auction.lots.list.landscape:0
msgid "NET"
-msgstr ""
+msgstr "NET"
#. module: auction
#: rml:report.auction.buyer.result:0
msgid "Adj"
-msgstr ""
+msgstr "Adj"
#. module: auction
#: view:auction.dates:0
#: model:ir.ui.menu,name:auction.auction_date_menu
msgid "Auction Dates"
-msgstr ""
+msgstr "Date licitaţii"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Furnitures"
-msgstr ""
+msgstr "Antichităţi/Mobilier"
#. module: auction
#: xsl:report.auction.ach_bordereau:0
msgid "Customer Contact"
-msgstr ""
+msgstr "Contact client"
#. module: auction
#: xsl:report.auction.lots.list.landscape:0
msgid "Inv, Name"
-msgstr ""
+msgstr "Inv, Nume"
#. module: auction
#: field:report.auction.adjudication,user_id:0
@@ -2303,124 +2303,124 @@ msgstr ""
#: field:report.object.encoded,user_id:0
#: field:report.object.encoded.manager,user_id:0
msgid "User"
-msgstr ""
+msgstr "Utilizator"
#. module: auction
#: view:report.unplanned.object:0
msgid "Unplanned Objects"
-msgstr ""
+msgstr "Obiecte neplanificate"
#. module: auction
#: field:report.buyer.auction2,gross_revenue:0
msgid "Gross Revenue"
-msgstr ""
+msgstr "Venit brut"
#. module: auction
#: field:auction.artists,pseudo:0
msgid "Pseudo"
-msgstr ""
+msgstr "Pseudo"
#. module: auction
#: field:auction.lots,important:0
msgid "To be Emphatized"
-msgstr ""
+msgstr "De subliniat"
#. module: auction
#: view:auction.lots:0
msgid "Not sold"
-msgstr ""
+msgstr "Nevândut"
#. module: auction
#: model:account.tax,name:auction.auction_tax3
#: field:auction.dates,buyer_costs:0
msgid "Buyer Costs"
-msgstr ""
+msgstr "Costuri cumpărător"
#. module: auction
#: model:ir.actions.wizard,name:auction.wizard_numerotate_automatic
msgid "Numerotation (automatic)"
-msgstr ""
+msgstr "Numerotare (automat)"
#. module: auction
#: rml:auction.total.rml:0
msgid "Auction Date:"
-msgstr ""
+msgstr "Data licitaţiei:"
#. module: auction
#: field:auction.lots,ach_inv_id:0
msgid "Buyer Invoice"
-msgstr ""
+msgstr "Factură cumpărător"
#. module: auction
#: rml:auction.bids:0
msgid "Tel"
-msgstr ""
+msgstr "Tel"
#. module: auction
#: wizard_field:auction.pay.buy,init,total:0
msgid "Amount to paid"
-msgstr ""
+msgstr "Sumă de plată"
#. module: auction
#: field:auction.lots,artist_id:0
msgid "Artist/Author"
-msgstr ""
+msgstr "Artist/Autor"
#. module: auction
#: model:account.tax,name:auction.auction_tax1
msgid "TVA"
-msgstr ""
+msgstr "TVA"
#. module: auction
#: model:ir.actions.report.xml,name:auction.total_result1
msgid "Auction Totals with lists"
-msgstr ""
+msgstr "Totaluri licitaţii cu liste"
#. module: auction
#: wizard_button:auction.lots.buyer_map,done,end:0
msgid "Close"
-msgstr ""
+msgstr "Închidere"
#. module: auction
#: model:ir.model,name:auction.model_report_object_encoded
#: model:ir.model,name:auction.model_report_object_encoded_manager
msgid "Object encoded"
-msgstr ""
+msgstr "Obiect înregistrat"
#. module: auction
#: rml:bids.phones.details:0
msgid "Est"
-msgstr ""
+msgstr "Est"
#. module: auction
#: field:report.auction.view,nbuyer:0
msgid "No of buyers"
-msgstr ""
+msgstr "Nr de cumpărători"
#. module: auction
#: field:report.seller.auction,avg_price:0
msgid "Avg adjudication"
-msgstr ""
+msgstr "Adjudecare medie"
#. module: auction
#: view:report.object.encoded.manager:0
msgid "Object statistic"
-msgstr ""
+msgstr "Statistică obiecte"
#. module: auction
#: field:auction.dates,auction2:0
msgid "Last Auction Day"
-msgstr ""
+msgstr "Ultima zi de licitaţie"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_auction_dates_next1
msgid "Next Auction Dates"
-msgstr ""
+msgstr "Datele următoare de licitaţie"
#. module: auction
#: model:ir.model,name:auction.model_report_attendance
msgid "Report Sign In/Out"
-msgstr ""
+msgstr "Raportare acces"
#. module: auction
#: view:auction.deposit:0
@@ -2434,29 +2434,29 @@ msgstr ""
#: xsl:report.auction.lots.list.landscape:0
#: xsl:report.auction.vnd_bordereau:0
msgid "Description"
-msgstr ""
+msgstr "Descriere"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Cont. Art/Arts"
-msgstr ""
+msgstr "Artă cont./Arte"
#. module: auction
#: field:auction.lots,obj_price:0
#: field:report.auction.view,adj_price:0
#: field:report.unclassified.objects,obj_price:0
msgid "Adjudication price"
-msgstr ""
+msgstr "Preţ de adjudecare"
#. module: auction
#: model:ir.ui.menu,name:auction.menu_all_objects_to_sell
msgid "Objects to sell"
-msgstr ""
+msgstr "Obiecte de vândut"
#. module: auction
#: xsl:flagey.huissier:0
msgid "Ref."
-msgstr ""
+msgstr "Ref."
#. module: auction
#: wizard_field:auction.lots.send.aie,date_ask,password:0
@@ -2465,108 +2465,108 @@ msgstr ""
#: wizard_field:auction.lots.send.aie.results,init,password:0
#: wizard_field:auction.lots.sms_send,init,password:0
msgid "Password"
-msgstr ""
+msgstr "Parolă"
#. module: auction
#: field:auction.lots,ach_avance:0
msgid "Buyer Advance"
-msgstr ""
+msgstr "Avans cumpărător"
#. module: auction
#: field:auction.lots,name:0
#: wizard_field:auction.lots.numerotate,search,name:0
#: field:report.unclassified.objects,name:0
msgid "Short Description"
-msgstr ""
+msgstr "Descriere scurtă"
#. module: auction
#: model:ir.ui.menu,name:auction.auction_report_employees_menu
msgid "Employees"
-msgstr ""
+msgstr "Angajați"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Clocks and watches"
-msgstr ""
+msgstr "Antichităţi/Ceasuri şi orologii"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Scientific Instruments"
-msgstr ""
+msgstr "Antichităţi/Instrumente ştiinţifice"
#. module: auction
#: wizard_view:auction.lots.enable,init:0
msgid "Confirmation enable taken away"
-msgstr ""
+msgstr "Confirmare ridicabil"
#. module: auction
#: wizard_view:auction.pay.buy,init:0
msgid "Pay objects"
-msgstr ""
+msgstr "Plată obiecte"
#. module: auction
#: view:report.object.encoded:0
#: view:report.object.encoded.manager:0
msgid "# objects"
-msgstr ""
+msgstr "Nr. obiecte"
#. module: auction
#: rml:auction.total.rml:0
msgid "Adjudication:"
-msgstr ""
+msgstr "Adjudecare:"
#. module: auction
#: field:report.buyer.auction2,sumadj:0
msgid "Sum of adjustication"
-msgstr ""
+msgstr "Sumă de adjudecare"
#. module: auction
#: model:ir.actions.report.xml,name:auction.details_bids_phones
msgid "Bids per lot (phone)"
-msgstr ""
+msgstr "Licitări pe lot (telefon)"
#. module: auction
#: field:report.buyer.auction,buyer_login:0
#: field:report.buyer.auction2,buyer_login:0
msgid "Buyer Login"
-msgstr ""
+msgstr "Utilizator cumpărător"
#. module: auction
#: field:auction.deposit,tax_id:0
msgid "Expenses"
-msgstr ""
+msgstr "Cheltuieli"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Wine"
-msgstr ""
+msgstr "Antichităţi/Vinuri"
#. module: auction
#: rml:auction.total.rml:0
msgid "Auction name:"
-msgstr ""
+msgstr "Denumire licitaţie:"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/African Arts"
-msgstr ""
+msgstr "Antichităţi/Arte africane"
#. module: auction
#: model:ir.actions.report.xml,name:auction.art2
msgid "Artists Biography"
-msgstr ""
+msgstr "Biografii artişti"
#. module: auction
#: selection:auction.lot.category,aie_categ:0
msgid "Antique/Posters"
-msgstr ""
+msgstr "Antichităţi/Postere"
#. module: auction
#: field:auction.lots,history_ids:0
msgid "Auction history"
-msgstr ""
+msgstr "Istoric licitaţie"
#. module: auction
#: xsl:report.auction.lots.list.landscape:0
msgid "Orders"
-msgstr ""
+msgstr "Comenzi"
diff --git a/addons/base_setup/i18n/fi.po b/addons/base_setup/i18n/fi.po
index 5aaa1f4e496..f777d6b8811 100644
--- a/addons/base_setup/i18n/fi.po
+++ b/addons/base_setup/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: 2009-11-23 08:34+0000\n"
-"Last-Translator: NightSpirit \n"
+"PO-Revision-Date: 2009-12-17 20:11+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:10+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base_setup
diff --git a/addons/base_vat/i18n/fi.po b/addons/base_vat/i18n/fi.po
index 13bcc9cbd91..46621c30073 100644
--- a/addons/base_vat/i18n/fi.po
+++ b/addons/base_vat/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: 2009-11-23 08:36+0000\n"
-"Last-Translator: NightSpirit \n"
+"PO-Revision-Date: 2009-12-17 18:47+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:09+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base_vat
diff --git a/addons/board/i18n/el.po b/addons/board/i18n/el.po
index 70e91ac272d..8fa9923fdd1 100644
--- a/addons/board/i18n/el.po
+++ b/addons/board/i18n/el.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-06-15 07:18+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 18:55+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:20+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -56,7 +56,7 @@ msgstr "Πλάτος"
#. module: board
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: board
#: field:board.board.line,name:0
diff --git a/addons/board_manufacturing/i18n/el.po b/addons/board_manufacturing/i18n/el.po
index 0f37f365c8c..77a835ca217 100644
--- a/addons/board_manufacturing/i18n/el.po
+++ b/addons/board_manufacturing/i18n/el.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-06-15 07:18+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 18:57+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:06+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -51,7 +51,7 @@ msgstr "Παραγωγή"
#. module: board_manufacturing
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: board_manufacturing
#: model:ir.actions.act_window,name:board_manufacturing.open_board_manufacturing
diff --git a/addons/hr/i18n/el.po b/addons/hr/i18n/el.po
index 0471c8c165e..6bc78e3a906 100644
--- a/addons/hr/i18n/el.po
+++ b/addons/hr/i18n/el.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-06-15 07:19+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 18:59+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:21+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -60,7 +60,7 @@ msgstr ""
#. module: hr
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: hr
#: view:hr.department:0
diff --git a/addons/hr_attendance/i18n/el.po b/addons/hr_attendance/i18n/el.po
index 6b01d015132..0068081a768 100644
--- a/addons/hr_attendance/i18n/el.po
+++ b/addons/hr_attendance/i18n/el.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-05-16 08:06+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 19:02+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:24+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -98,7 +98,7 @@ msgstr "Εκτύπωση Σφαλμάτων Παρουσιολογίου"
#. module: hr_attendance
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: hr_attendance
#: model:ir.actions.wizard,name:hr_attendance.print_week
diff --git a/addons/mrp/i18n/el.po b/addons/mrp/i18n/el.po
index 719c2df67eb..af01beb990d 100644
--- a/addons/mrp/i18n/el.po
+++ b/addons/mrp/i18n/el.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 12:41+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 19:14+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: l10n_chart_gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:05+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -48,7 +48,7 @@ msgstr "Σχεδίαση Πηγών Βιομηχανικής Παραγωγής
#. module: mrp
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: mrp
#: field:mrp.bom.revision,indice:0
@@ -371,7 +371,7 @@ msgstr "Δαιδικασία Τροφοδοσίας"
#. module: mrp
#: field:mrp.production,date_planned_date:0
msgid "Scheduled Date"
-msgstr ""
+msgstr "Προγραμματισμένη Ημερομηνία"
#. module: mrp
#: selection:mrp.procurement,priority:0
@@ -1017,7 +1017,7 @@ msgstr "Αρ. ωρών"
#. module: mrp
#: view:mrp.procurement:0
msgid "Notes"
-msgstr ""
+msgstr "Σημειώσεις"
#. module: mrp
#: model:ir.model,name:mrp.model_mrp_bom
@@ -1136,6 +1136,8 @@ msgstr "Προς Αποθήκευση"
#: model:process.transition,note:mrp.process_transition_servicemto0
msgid "If product type is service and procure method is Make to order"
msgstr ""
+"Αν ο τύπος του είδους είναι Υπηρεσία και μέθοδος προμήθειας είναι Προς "
+"Παραγγελία"
#. module: mrp
#: field:res.company,schedule_range:0
@@ -1156,7 +1158,7 @@ msgstr "Προμήθειες"
#. module: mrp
#: model:ir.actions.wizard,name:mrp.product_procurement_wizard
msgid "Procurement Request"
-msgstr ""
+msgstr "Αίτηση Προμήθειας"
#. module: mrp
#: model:ir.actions.wizard,name:mrp.wizard_price
@@ -1409,6 +1411,8 @@ msgstr "Παραγόμενα Προϊόντα"
#: model:process.transition,note:mrp.process_transition_stockproduct0
msgid "Product type is Stockable and procure method is make to stock"
msgstr ""
+"Ο τύπος του είδους είναι αποθηκεύσιμο και η μέθοδος προμήθειας είναι Προς "
+"Αποθήκευση"
#. module: mrp
#: help:mrp.bom,date_start:0
@@ -1497,11 +1501,13 @@ msgstr "numeric indices"
#: model:process.transition,note:mrp.process_transition_servicerfq0
msgid "If Procure method is Make to order and supply method is buy"
msgstr ""
+"Aν η μέθοδος προμήθειας είναι Προς Παραγγελία και η μέθοδος απόκτησης είναι "
+"Αγορά"
#. module: mrp
#: model:process.transition,note:mrp.process_transition_procurestockableproduct0
msgid "if Product type is Stockable in procurement order"
-msgstr ""
+msgstr "Αν ο τύπος προϊόντος είναι Αποθηκεύσιμο σε εντολή προμήθειας"
#. module: mrp
#: model:ir.model,name:mrp.model_mrp_production_workcenter_line
@@ -1593,7 +1599,7 @@ msgstr "Υπολογισμός Προμηθειών Μόνο"
#. module: mrp
#: field:mrp.production,product_uos_qty:0
msgid "Product UoS Qty"
-msgstr ""
+msgstr "Πόσοτητα σε ΜοΠ του Προϊόντος"
#. module: mrp
#: rml:bom.structure:0
@@ -1666,7 +1672,7 @@ msgstr "Στρογγυλοποίηση Προϊόντος"
#. module: mrp
#: field:mrp.production.workcenter.line,name:0
msgid "Work Order"
-msgstr ""
+msgstr "Εντολή εργασίας"
#. module: mrp
#: view:mrp.production:0
@@ -1767,7 +1773,7 @@ msgstr ""
#. module: mrp
#: selection:mrp.production,state:0
msgid "Waiting Goods"
-msgstr ""
+msgstr "Σε αναμονή υλικών"
#. module: mrp
#: model:process.process,name:mrp.process_process_stockableproductprocess0
@@ -1856,7 +1862,7 @@ msgstr "Κατάσταση Υλικών"
#. module: mrp
#: model:process.transition,note:mrp.process_transition_procureserviceproduct0
msgid "In procurement order, if product type is service"
-msgstr ""
+msgstr "Σε εντολή προμήθειας, αν ο τύπος του είδους είναι υπηρεσία"
#. module: mrp
#: selection:mrp.procurement,procure_method:0
@@ -1980,7 +1986,7 @@ msgstr ""
#. module: mrp
#: field:mrp.production,date_planned_end:0
msgid "Scheduled End"
-msgstr ""
+msgstr "Προγραμματισμένη Λήξη"
#. module: mrp
#: selection:mrp.bom,method:0
diff --git a/addons/mrp_repair/i18n/fi.po b/addons/mrp_repair/i18n/fi.po
index 1c1ca79032c..3b7c05e251b 100644
--- a/addons/mrp_repair/i18n/fi.po
+++ b/addons/mrp_repair/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: 2009-12-01 17:57+0000\n"
-"Last-Translator: T Kortehisto \n"
+"PO-Revision-Date: 2009-12-17 19:31+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:26+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: mrp_repair
@@ -602,7 +602,7 @@ msgstr "Korjauksen viite"
#. module: mrp_repair
#: view:mrp.repair:0
msgid "UoM"
-msgstr ""
+msgstr "Mittayksikkö"
#. module: mrp_repair
#: selection:mrp.repair.line,type:0
@@ -619,7 +619,7 @@ msgstr "Peruuta korjaus...??"
#: field:mrp.repair.fee,product_uom:0
#: field:mrp.repair.line,product_uom:0
msgid "Product UoM"
-msgstr ""
+msgstr "Tuotteen mittayksikkö"
#. module: mrp_repair
#: field:mrp.repair,partner_invoice_id:0
diff --git a/addons/point_of_sale/i18n/ro.po b/addons/point_of_sale/i18n/ro.po
index 7607761ca57..6f3e83b978c 100644
--- a/addons/point_of_sale/i18n/ro.po
+++ b/addons/point_of_sale/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-02-03 06:25+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-17 17:02+0000\n"
+"Last-Translator: geopop65 \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: 2009-12-16 05:07+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: point_of_sale
@@ -67,7 +67,7 @@ msgstr ""
#. module: point_of_sale
#: rml:pos.invoice:0
msgid "Document"
-msgstr ""
+msgstr "Document"
#. module: point_of_sale
#: wizard_view:pos.add_product,init:0
@@ -77,208 +77,208 @@ msgstr ""
#. module: point_of_sale
#: rml:pos.lines:0
msgid "Net Total"
-msgstr ""
+msgstr "Total net"
#. module: point_of_sale
#: model:ir.ui.menu,name:point_of_sale.menu_action_pos_order_tree2
msgid "Orders of the day"
-msgstr ""
+msgstr "Comenzi azi"
#. module: point_of_sale
#: model:ir.actions.report.xml,name:point_of_sale.pos_details_summary
msgid "Sales (summary)"
-msgstr ""
+msgstr "Vânzări (rezumat)"
#. module: point_of_sale
#: help:pos.order,user_id:0
msgid "This is the logged in user (not necessarily the salesman)."
-msgstr ""
+msgstr "Utilizator conectat (nu neapărat agentul)"
#. module: point_of_sale
#: wizard_view:pos.sale.get,init:0
msgid "Select an Open Sale Order"
-msgstr ""
+msgstr "Selectare comandă deschisă"
#. module: point_of_sale
#: rml:pos.lines:0
msgid "Company"
-msgstr ""
+msgstr "Companie"
#. module: point_of_sale
#: rml:pos.invoice:0
msgid "Invoice Date"
-msgstr ""
+msgstr "Data facturii"
#. module: point_of_sale
#: rml:pos.receipt:0
msgid ","
-msgstr ""
+msgstr ","
#. module: point_of_sale
#: model:ir.actions.report.xml,name:point_of_sale.pos_lines_detail
msgid "Details of Sales"
-msgstr ""
+msgstr "Detalii vânzare"
#. module: point_of_sale
#: rml:pos.invoice:0
msgid "Base"
-msgstr ""
+msgstr "Bază"
#. module: point_of_sale
#: wizard_view:pos.scan_product,init:0
msgid "Scan product"
-msgstr ""
+msgstr "Scanare produs"
#. module: point_of_sale
#: field:pos.order.line,price_subtotal:0
msgid "Subtotal"
-msgstr ""
+msgstr "Subtotal"
#. module: point_of_sale
#: rml:pos.invoice:0
msgid "Partner Ref."
-msgstr ""
+msgstr "Ref. partener"
#. module: point_of_sale
#: rml:pos.receipt:0
msgid "Tel : + 32 (0) 2 231 04 35"
-msgstr ""
+msgstr "Tel : + 32 (0) 2 231 04 35"
#. module: point_of_sale
#: field:pos.order.line,name:0
msgid "Line Description"
-msgstr ""
+msgstr "Descriere linie"
#. module: point_of_sale
#: field:pos.order,shop_id:0
msgid "Shop"
-msgstr ""
+msgstr "Magazin"
#. module: point_of_sale
#: wizard_button:pos.refund_order,init,refund_n_quit:0
msgid "Ok"
-msgstr ""
+msgstr "Ok"
#. module: point_of_sale
#: view:pos.order:0
#: field:pos.order,note:0
msgid "Notes"
-msgstr ""
+msgstr "Note"
#. module: point_of_sale
#: field:stock.picking,pos_order:0
msgid "Pos order"
-msgstr ""
+msgstr "Comandă POS"
#. module: point_of_sale
#: rml:pos.details:0
#: rml:pos.details_summary:0
msgid "Detail of Sales"
-msgstr ""
+msgstr "Detalii vânzări"
#. module: point_of_sale
#: rml:pos.invoice:0
#: rml:pos.lines:0
#: field:pos.order,amount_tax:0
msgid "Taxes"
-msgstr ""
+msgstr "Taxe"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_pos_order_line
#: model:ir.actions.act_window,name:point_of_sale.action_pos_order_line_day
msgid "Sale line"
-msgstr ""
+msgstr "Rând vânzare"
#. module: point_of_sale
#: rml:pos.lines:0
msgid "No. Of Articles"
-msgstr ""
+msgstr "Nr de articole"
#. module: point_of_sale
#: field:pos.config.journal,code:0
#: rml:pos.details:0
msgid "Code"
-msgstr ""
+msgstr "Cod"
#. module: point_of_sale
#: field:pos.order,date_validity:0
#: wizard_field:pos.refund_order,init,date_validity:0
msgid "Validity Date"
-msgstr ""
+msgstr "Data expirării"
#. module: point_of_sale
#: view:pos.order:0
#: field:pos.order,pickings:0
msgid "Picking"
-msgstr ""
+msgstr "Selecţie"
#. module: point_of_sale
#: rml:pos.details:0
#: rml:pos.lines:0
msgid "VAT"
-msgstr ""
+msgstr "TVA"
#. module: point_of_sale
#: model:ir.actions.wizard,name:point_of_sale.pos_refund
msgid "Refund Orders"
-msgstr ""
+msgstr "Restituire comenzi"
#. module: point_of_sale
#: field:pos.order,last_out_picking:0
msgid "Last Output Picking"
-msgstr ""
+msgstr "Ultima selecţie de ieşire"
#. module: point_of_sale
#: wizard_view:pos.config.journal,init:0
msgid "Select default journals"
-msgstr ""
+msgstr "Selectare jurnale implicite"
#. module: point_of_sale
#: rml:pos.details:0
#: rml:pos.receipt:0
msgid "Qty"
-msgstr ""
+msgstr "Cant."
#. module: point_of_sale
#: field:pos.order,user_id:0
msgid "Logged in User"
-msgstr ""
+msgstr "Utilizator conectat"
#. module: point_of_sale
#: rml:pos.details:0
msgid "VAT(%)"
-msgstr ""
+msgstr "TVA (%)"
#. module: point_of_sale
#: rml:pos.invoice:0
msgid "Tax"
-msgstr ""
+msgstr "Taxă"
#. module: point_of_sale
#: view:report.transaction.pos:0
msgid "Total Transaction"
-msgstr ""
+msgstr "Total tranzacţie"
#. module: point_of_sale
#: rml:pos.details:0
msgid "Disc"
-msgstr ""
+msgstr "Disc"
#. module: point_of_sale
#: rml:pos.invoice:0
#: rml:pos.receipt:0
msgid "Fax :"
-msgstr ""
+msgstr "Fax :"
#. module: point_of_sale
#: wizard_view:pos.scan_product,init:0
msgid "Scan Barcode"
-msgstr ""
+msgstr "Scanare cod de bare"
#. module: point_of_sale
#: field:pos.order,partner_id:0
msgid "Partner"
-msgstr ""
+msgstr "Partener"
#. module: point_of_sale
#: field:pos.order,payments:0
diff --git a/addons/product/i18n/el.po b/addons/product/i18n/el.po
index 148d0362df7..326bc1c88b8 100644
--- a/addons/product/i18n/el.po
+++ b/addons/product/i18n/el.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-16 19:08+0000\n"
+"PO-Revision-Date: 2009-12-17 19:10+0000\n"
"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: Greek \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-17 04:44+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: product
@@ -813,7 +813,7 @@ msgstr ""
#. module: product
#: field:product.template,supply_method:0
msgid "Supply method"
-msgstr "Μέθοδος Προμήθειας"
+msgstr "Μέθοδος απόκτησης"
#. module: product
#: model:product.category,name:product.product_category_11
diff --git a/addons/product/i18n/zh_CN.po b/addons/product/i18n/zh_CN.po
index 355d8ae895e..a1e4b4bd4bc 100644
--- a/addons/product/i18n/zh_CN.po
+++ b/addons/product/i18n/zh_CN.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-12-03 13:03+0000\n"
-"Last-Translator: Wei \"oldrev\" Li \n"
+"PO-Revision-Date: 2009-12-18 02:27+0000\n"
+"Last-Translator: Jeroen Vet \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: 2009-12-16 05:16+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: product
@@ -102,12 +102,12 @@ msgstr "如果这规则只适合一种货品模板则设置一个模板.为所
#. module: product
#: field:product.template,procure_method:0
msgid "Procure Method"
-msgstr "采购方式"
+msgstr "获得方式"
#. module: product
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr "操作定义中使用了无效的模式名称。"
+msgstr "在行动定义中的模式名称无效"
#. module: product
#: model:process.process,name:product.process_process_productprocess0
@@ -220,7 +220,7 @@ msgstr "接收"
#. module: product
#: selection:product.template,procure_method:0
msgid "Make to Stock"
-msgstr "计划性生产"
+msgstr "备货型生产"
#. module: product
#: view:product.product:0
diff --git a/addons/product_margin/i18n/el.po b/addons/product_margin/i18n/el.po
index a1fa934b5bb..ec627433804 100644
--- a/addons/product_margin/i18n/el.po
+++ b/addons/product_margin/i18n/el.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-06-15 07:21+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 20:31+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:25+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -156,7 +156,7 @@ msgstr "Αναμενόμενο Περιθώριο"
#. module: product_margin
#: help:product.product,total_margin:0
msgid "Turnorder - Total Cost"
-msgstr ""
+msgstr "Τζίρος - Συνολικό Κόστος"
#. module: product_margin
#: view:product.product:0
diff --git a/addons/profile_manufacturing/i18n/el.po b/addons/profile_manufacturing/i18n/el.po
index 072335ce151..66619344e6a 100644
--- a/addons/profile_manufacturing/i18n/el.po
+++ b/addons/profile_manufacturing/i18n/el.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-06-15 07:21+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-17 20:25+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:20+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -84,7 +84,7 @@ msgstr ""
#. module: profile_manufacturing
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: profile_manufacturing
#: model:ir.actions.act_window,name:profile_manufacturing.action_config_install_module
diff --git a/addons/sale/i18n/fi.po b/addons/sale/i18n/fi.po
index bc3914af34b..d28766ec360 100644
--- a/addons/sale/i18n/fi.po
+++ b/addons/sale/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: 2009-11-19 17:49+0000\n"
-"Last-Translator: Ville Liski \n"
+"PO-Revision-Date: 2009-12-17 19:10+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:14+0000\n"
+"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: sale
@@ -45,7 +45,7 @@ msgstr "Jakelukumppani"
#. module: sale
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Virheellinen mallin nimi toimenpiteen määrittelyssä."
#. module: sale
#: selection:sale.order,state:0
@@ -480,7 +480,7 @@ msgstr "Virheellinen XML näkymäarkkitehtuurille!"
#. module: sale
#: field:sale.order,picking_ids:0
msgid "Related Packing"
-msgstr ""
+msgstr "Liittyvä pakkaus"
#. module: sale
#: field:sale.shop,payment_account_id:0
@@ -495,7 +495,7 @@ msgstr "Virhe: Myyntiyksikkö täytyy olla eri kategoriassa kuin mittayksikkö"
#. module: sale
#: field:sale.order,client_order_ref:0
msgid "Customer Ref"
-msgstr ""
+msgstr "Asiakkaan viite"
#. module: sale
#: view:sale.order:0
@@ -969,7 +969,7 @@ msgstr ""
#. module: sale
#: selection:sale.order,state:0
msgid "In Progress"
-msgstr ""
+msgstr "Käynnissä"
#. module: sale
#: wizard_view:sale.advance_payment_inv,init:0
@@ -1279,7 +1279,7 @@ msgstr "Kerätty"
#. module: sale
#: view:sale.shop:0
msgid "Accounting"
-msgstr ""
+msgstr "Kirjanpito"
#. module: sale
#: selection:sale.config.picking_policy,order_policy:0
From 0700f9286fa400e36f16a3503d0efe1048b13de0 Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Fri, 18 Dec 2009 09:41:26 +0100
Subject: [PATCH 030/123] [IMP] Update the template for translation
bzr revid: christophe.chauvet@syleam.fr-20091218084126-fwa0yt6cg0x160qj
---
bin/addons/base/i18n/base.pot | 168 +++++++++++++++++-----------------
1 file changed, 86 insertions(+), 82 deletions(-)
diff --git a/bin/addons/base/i18n/base.pot b/bin/addons/base/i18n/base.pot
index ad77b86e94f..79662043441 100644
--- a/bin/addons/base/i18n/base.pot
+++ b/bin/addons/base/i18n/base.pot
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.6\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
-"POT-Creation-Date: 2009-12-09 10:13:57+0000\n"
-"PO-Revision-Date: 2009-12-10 07:54+0000\n"
+"POT-Creation-Date: 2009-12-18 08:39:22+0000\n"
+"PO-Revision-Date: 2009-12-18 08:39:22+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -189,11 +189,6 @@ msgstr ""
msgid "Number of Modules"
msgstr ""
-#. module: base
-#: help:multi_company.default,company_dest_id:0
-msgid "Company to store the current record"
-msgstr ""
-
#. module: base
#: field:res.partner.bank.type.field,size:0
msgid "Max. Size"
@@ -718,6 +713,12 @@ msgstr ""
msgid "Iran"
msgstr ""
+#. module: base
+#: model:ir.actions.act_window,name:base.res_request-act
+#: model:ir.ui.menu,name:base.menu_res_request_act
+msgid "My Requests"
+msgstr ""
+
#. module: base
#: field:ir.sequence,name:0
#: field:ir.sequence.type,name:0
@@ -1077,6 +1078,11 @@ msgstr ""
msgid "Fixed Width"
msgstr ""
+#. module: base
+#: model:res.company,overdue_msg:base.main_company
+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 at (+32).81.81.37.00."
+msgstr ""
+
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "terp-calendar"
@@ -1112,13 +1118,8 @@ msgid "7. %H:%M:%S ==> 18:25:20"
msgstr ""
#. module: base
-#: model:ir.actions.act_window,name:base.action_partner_form
-#: model:ir.ui.menu,name:base.menu_base_partner
-#: model:ir.ui.menu,name:base.menu_partner_form
-#: view:res.partner:0
-#: view:res.partner.category:0
-#: field:res.partner.category,partner_ids:0
-msgid "Partners"
+#: help:res.users,company_id:0
+msgid "The company this user is currently working on."
msgstr ""
#. module: base
@@ -1317,6 +1318,11 @@ msgstr ""
msgid "Groups"
msgstr ""
+#. module: base
+#: constraint:res.users:0
+msgid "This user can not connect using this company !"
+msgstr ""
+
#. module: base
#: model:res.country,name:base.bz
msgid "Belize"
@@ -1529,6 +1535,12 @@ msgstr ""
msgid "Field Mappings"
msgstr ""
+#. module: base
+#: model:ir.actions.act_window,name:base.res_request-closed
+#: model:ir.ui.menu,name:base.next_id_12_close
+msgid "My Closed Requests"
+msgstr ""
+
#. module: base
#: model:ir.ui.menu,name:base.menu_custom
msgid "Customization"
@@ -1585,11 +1597,6 @@ msgstr ""
msgid "Iteration Actions"
msgstr ""
-#. module: base
-#: help:multi_company.default,company_id:0
-msgid "Company where the user is connected"
-msgstr ""
-
#. module: base
#: field:maintenance.contract,date_stop:0
msgid "Ending Date"
@@ -1792,11 +1799,6 @@ msgstr ""
msgid "Dependencies"
msgstr ""
-#. module: base
-#: field:multi_company.default,company_id:0
-msgid "Main Company"
-msgstr ""
-
#. module: base
#: field:ir.report.custom.fields,bgcolor:0
msgid "Background Color"
@@ -1912,6 +1914,12 @@ msgstr ""
msgid "Module"
msgstr ""
+#. module: base
+#: model:ir.actions.act_window,name:base.action_res_bank_form
+#: model:ir.ui.menu,name:base.menu_action_res_bank_form
+msgid "Bank List"
+msgstr ""
+
#. module: base
#: field:ir.attachment,description:0
#: field:ir.module.module,description:0
@@ -2275,11 +2283,6 @@ msgstr ""
msgid "6. %d, %m ==> 05, 12"
msgstr ""
-#. module: base
-#: help:multi_company.default,expression:0
-msgid "Expression, must be True to match"
-msgstr ""
-
#. module: base
#: help:res.partner,customer:0
msgid "Check this box if the partner is a customer."
@@ -2384,11 +2387,6 @@ msgstr ""
msgid "Summary"
msgstr ""
-#. module: base
-#: field:multi_company.default,expression:0
-msgid "Expression"
-msgstr ""
-
#. module: base
#: help:ir.actions.server,subject:0
msgid "Specify the subject. You can use fields from the object, e.g. `Hello [[ object.partner_id.name ]]`"
@@ -2974,6 +2972,7 @@ msgstr ""
#. module: base
#: field:ir.rule,field_id:0
#: selection:ir.translation,type:0
+#: field:multi_company.default,field_id:0
msgid "Field"
msgstr ""
@@ -3039,7 +3038,6 @@ msgstr ""
#: field:ir.rule.group,name:0
#: field:ir.values,name:0
#: field:maintenance.contract.module,name:0
-#: field:multi_company.default,name:0
#: field:res.bank,name:0
#: field:res.config.view,name:0
#: field:res.lang,name:0
@@ -3560,8 +3558,6 @@ msgid "Signal (button Name)"
msgstr ""
#. module: base
-#: model:ir.actions.act_window,name:base.action_res_bank_form
-#: model:ir.ui.menu,name:base.menu_action_res_bank_form
#: view:res.bank:0
#: field:res.partner,bank_ids:0
msgid "Banks"
@@ -3820,6 +3816,7 @@ msgid "On Multiple Doc."
msgstr ""
#. module: base
+#: model:ir.ui.menu,name:base.menu_base_config_contact
#: field:res.partner,address:0
#: view:res.partner.address:0
msgid "Contacts"
@@ -3830,11 +3827,6 @@ msgstr ""
msgid "Faroe Islands"
msgstr ""
-#. module: base
-#: help:multi_company.default,object_id:0
-msgid "Object affect by this rules"
-msgstr ""
-
#. module: base
#: model:ir.actions.wizard,name:base.wizard_upgrade
#: model:ir.ui.menu,name:base.menu_wizard_upgrade
@@ -4218,11 +4210,6 @@ msgstr ""
msgid "French (CH) / Français (CH)"
msgstr ""
-#. module: base
-#: model:ir.model,name:base.model_res_company
-msgid "List of Company"
-msgstr ""
-
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_NEW"
@@ -4333,6 +4320,11 @@ msgstr ""
msgid "res.partner.event"
msgstr ""
+#. module: base
+#: field:res.company,user_ids:0
+msgid "Accepted Users"
+msgstr ""
+
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_UNDERLINE"
@@ -4450,13 +4442,6 @@ msgstr ""
msgid "iCal id"
msgstr ""
-#. module: base
-#: model:ir.actions.act_window,name:base.action_partner_function_form
-#: model:ir.ui.menu,name:base.menu_partner_function_form
-#: view:res.partner.function:0
-msgid "Partner Functions"
-msgstr ""
-
#. module: base
#: wizard_view:res.partner.sms_send,init:0
msgid "Bulk SMS send"
@@ -4589,11 +4574,6 @@ msgstr ""
msgid "Full"
msgstr ""
-#. module: base
-#: field:multi_company.default,company_dest_id:0
-msgid "Default Company"
-msgstr ""
-
#. module: base
#: model:res.country,name:base.as
msgid "American Samoa"
@@ -4831,6 +4811,7 @@ msgstr ""
#. module: base
#: model:ir.actions.act_window,name:base.action_res_company_form
#: model:ir.ui.menu,name:base.menu_action_res_company_form
+#: model:ir.ui.menu,name:base.menu_res_company_global
#: view:res.company:0
msgid "Companies"
msgstr ""
@@ -5256,9 +5237,10 @@ msgid "Active Partner Events"
msgstr ""
#. module: base
-#: model:ir.actions.act_window,name:base.action_rule
-#: model:ir.ui.menu,name:base.menu_action_rule
-msgid "Record Rules"
+#: model:ir.actions.act_window,name:base.action_partner_function_form
+#: model:ir.ui.menu,name:base.menu_partner_function_form
+#: view:res.partner.function:0
+msgid "Contact Functions"
msgstr ""
#. module: base
@@ -5551,8 +5533,6 @@ msgid "Martinique (French)"
msgstr ""
#. module: base
-#: model:ir.actions.act_window,name:base.res_request-act
-#: model:ir.ui.menu,name:base.menu_res_request_act
#: model:ir.ui.menu,name:base.next_id_12
#: view:res.request:0
msgid "Requests"
@@ -5809,6 +5789,11 @@ msgstr ""
msgid "Rounding factor"
msgstr ""
+#. module: base
+#: model:ir.model,name:base.model_res_company
+msgid "res.company"
+msgstr ""
+
#. module: base
#: wizard_view:module.upgrade,end:0
#: wizard_view:module.upgrade,start:0
@@ -5889,6 +5874,11 @@ msgstr ""
msgid "Hour 00->24: %(h24)s"
msgstr ""
+#. module: base
+#: help:multi_company.default,field_id:0
+msgid "Select field property"
+msgstr ""
+
#. module: base
#: field:res.request.history,date_sent:0
msgid "Date sent"
@@ -5908,7 +5898,6 @@ msgstr ""
#: view:ir.sequence:0
#: field:ir.ui.menu,sequence:0
#: field:ir.ui.view_sc,sequence:0
-#: field:multi_company.default,sequence:0
#: field:res.partner.bank,sequence:0
#: field:wizard.ir.model.menu.create.line,sequence:0
msgid "Sequence"
@@ -5973,6 +5962,11 @@ msgstr ""
msgid "Parent"
msgstr ""
+#. module: base
+#: view:multi_company.default:0
+msgid "Returning"
+msgstr ""
+
#. module: base
#: field:ir.actions.act_window,res_model:0
#: field:ir.actions.report.custom,model:0
@@ -5991,7 +5985,6 @@ msgstr ""
#: selection:ir.translation,type:0
#: field:ir.ui.view,model:0
#: field:ir.values,model_id:0
-#: field:multi_company.default,object_id:0
#: field:res.request.link,object:0
#: field:wizard.ir.model.menu.create,model_id:0
#: field:workflow.triggers,model:0
@@ -6688,6 +6681,17 @@ msgstr ""
msgid "Landscape"
msgstr ""
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_form
+#: model:ir.ui.menu,name:base.menu_base_config_partner
+#: model:ir.ui.menu,name:base.menu_base_partner
+#: model:ir.ui.menu,name:base.menu_partner_form
+#: view:res.partner:0
+#: view:res.partner.category:0
+#: field:res.partner.category,partner_ids:0
+msgid "Partners"
+msgstr ""
+
#. module: base
#: model:ir.ui.menu,name:base.menu_administration
msgid "Administration"
@@ -6902,11 +6906,6 @@ msgstr ""
msgid "Second field should be figures"
msgstr ""
-#. module: base
-#: help:multi_company.default,name:0
-msgid "Name it to easily find a record"
-msgstr ""
-
#. module: base
#: model:ir.actions.act_window,name:base.action_model_grid_security
#: model:ir.ui.menu,name:base.menu_ir_access_grid
@@ -7029,11 +7028,6 @@ msgstr ""
msgid "Bank Accounts"
msgstr ""
-#. module: base
-#: model:ir.model,name:base.model_multi_company_default
-msgid "Default multi company"
-msgstr ""
-
#. module: base
#: view:res.request:0
msgid "Send"
@@ -7122,12 +7116,6 @@ msgstr ""
msgid "https://translations.launchpad.net/openobject"
msgstr ""
-#. module: base
-#: model:ir.actions.act_window,name:base.action_partner_title
-#: model:ir.ui.menu,name:base.menu_partner_title
-msgid "Titles"
-msgstr ""
-
#. module: base
#: field:ir.actions.todo,start_date:0
msgid "Start Date"
@@ -7199,6 +7187,11 @@ msgstr ""
msgid "Delete Permission"
msgstr ""
+#. module: base
+#: model:ir.model,name:base.model_multi_company_default
+msgid "multi_company.default"
+msgstr ""
+
#. module: base
#: selection:workflow.activity,join_mode:0
#: selection:workflow.activity,split_mode:0
@@ -7455,6 +7448,11 @@ msgstr ""
msgid "Rwanda"
msgstr ""
+#. module: base
+#: constraint:res.partner:0
+msgid "The VAT doesn't seem to be correct."
+msgstr ""
+
#. module: base
#: selection:ir.report.custom.fields,operation:0
msgid "Calculate Sum"
@@ -7592,6 +7590,12 @@ msgstr ""
msgid "ir.actions.server"
msgstr ""
+#. module: base
+#: model:ir.actions.act_window,name:base.action_rule
+#: model:ir.ui.menu,name:base.menu_action_rule
+msgid "Record Rules"
+msgstr ""
+
#. module: base
#: view:ir.actions.report.custom:0
msgid "Report custom"
From d41f2ec159e003d338ca2cf0f00f00ba657aa26d Mon Sep 17 00:00:00 2001
From: "mra (Open ERP)"
Date: Fri, 18 Dec 2009 15:09:34 +0530
Subject: [PATCH 031/123] [FIX] base/i18n: remove python code strings on
translation files
lp bug: https://launchpad.net/bugs/484298 fixed
bzr revid: mra@tinyerp.com-20091218093934-tzp9x6gzqcnwxt4d
---
bin/addons/base/i18n/ar.po | 16 +--------------
bin/addons/base/i18n/bg.po | 16 +--------------
bin/addons/base/i18n/bs.po | 16 +--------------
bin/addons/base/i18n/ca.po | 16 +--------------
bin/addons/base/i18n/cs.po | 16 +--------------
bin/addons/base/i18n/da.po | 16 +--------------
bin/addons/base/i18n/de.po | 16 +--------------
bin/addons/base/i18n/el.po | 16 +--------------
bin/addons/base/i18n/es.po | 16 +--------------
bin/addons/base/i18n/es_AR.po | 16 +--------------
bin/addons/base/i18n/es_EC.po | 16 +--------------
bin/addons/base/i18n/et.po | 16 +--------------
bin/addons/base/i18n/fi.po | 16 +--------------
bin/addons/base/i18n/fr.po | 16 +--------------
bin/addons/base/i18n/gl.po | 16 +--------------
bin/addons/base/i18n/he.po | 16 +--------------
bin/addons/base/i18n/hr.po | 16 +--------------
bin/addons/base/i18n/hu.po | 16 +--------------
bin/addons/base/i18n/id.po | 16 +--------------
bin/addons/base/i18n/is.po | 16 +--------------
bin/addons/base/i18n/it.po | 16 +--------------
bin/addons/base/i18n/ja.po | 16 +--------------
bin/addons/base/i18n/ko.po | 16 +--------------
bin/addons/base/i18n/lt.po | 16 +--------------
bin/addons/base/i18n/lt_LT.po | 16 +--------------
bin/addons/base/i18n/lv.po | 16 +--------------
bin/addons/base/i18n/mn.po | 16 +--------------
bin/addons/base/i18n/nl.po | 32 ++---------------------------
bin/addons/base/i18n/nl_BE.po | 16 +--------------
bin/addons/base/i18n/nl_NL.po | 16 +--------------
bin/addons/base/i18n/pl.po | 16 +--------------
bin/addons/base/i18n/pt.po | 32 ++---------------------------
bin/addons/base/i18n/pt_BR.po | 16 +--------------
bin/addons/base/i18n/ro.po | 16 +--------------
bin/addons/base/i18n/ru.po | 16 +--------------
bin/addons/base/i18n/sk.po | 16 +--------------
bin/addons/base/i18n/sl.po | 16 +--------------
bin/addons/base/i18n/sq.po | 16 +--------------
bin/addons/base/i18n/sr.po | 16 +--------------
bin/addons/base/i18n/sv.po | 16 +--------------
bin/addons/base/i18n/th.po | 16 +--------------
bin/addons/base/i18n/tlh.po | 16 +--------------
bin/addons/base/i18n/tr.po | 16 +--------------
bin/addons/base/i18n/uk.po | 16 +--------------
bin/addons/base/i18n/uk_UA.po | 16 +--------------
bin/addons/base/i18n/vi.po | 16 +--------------
bin/addons/base/i18n/zh_CN.po | 38 +----------------------------------
bin/addons/base/i18n/zh_TW.po | 16 +--------------
48 files changed, 50 insertions(+), 772 deletions(-)
diff --git a/bin/addons/base/i18n/ar.po b/bin/addons/base/i18n/ar.po
index eedfffc7a37..ccc0b253f29 100644
--- a/bin/addons/base/i18n/ar.po
+++ b/bin/addons/base/i18n/ar.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/bg.po b/bin/addons/base/i18n/bg.po
index ec1db214ed7..b1bbc3cd59d 100644
--- a/bin/addons/base/i18n/bg.po
+++ b/bin/addons/base/i18n/bg.po
@@ -996,21 +996,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/bs.po b/bin/addons/base/i18n/bs.po
index 3c9f28cb276..afcf55fca17 100644
--- a/bin/addons/base/i18n/bs.po
+++ b/bin/addons/base/i18n/bs.po
@@ -986,21 +986,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/ca.po b/bin/addons/base/i18n/ca.po
index ff630734c97..051d6ddc618 100644
--- a/bin/addons/base/i18n/ca.po
+++ b/bin/addons/base/i18n/ca.po
@@ -1008,21 +1008,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/cs.po b/bin/addons/base/i18n/cs.po
index 2e3d0e3bbcb..190016ce8da 100644
--- a/bin/addons/base/i18n/cs.po
+++ b/bin/addons/base/i18n/cs.po
@@ -984,21 +984,7 @@ msgstr "STOCK_KOPÍROVAT"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/da.po b/bin/addons/base/i18n/da.po
index e28ec968125..e12c4a5db1e 100644
--- a/bin/addons/base/i18n/da.po
+++ b/bin/addons/base/i18n/da.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/de.po b/bin/addons/base/i18n/de.po
index e74916ab978..47e33938728 100644
--- a/bin/addons/base/i18n/de.po
+++ b/bin/addons/base/i18n/de.po
@@ -1006,21 +1006,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/el.po b/bin/addons/base/i18n/el.po
index c4eb8c94c29..bdb2fe69ee2 100644
--- a/bin/addons/base/i18n/el.po
+++ b/bin/addons/base/i18n/el.po
@@ -1011,21 +1011,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/es.po b/bin/addons/base/i18n/es.po
index ca266b534e9..ef6d3721dd7 100644
--- a/bin/addons/base/i18n/es.po
+++ b/bin/addons/base/i18n/es.po
@@ -1011,21 +1011,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/es_AR.po b/bin/addons/base/i18n/es_AR.po
index bfd786a50ee..78c0061c090 100644
--- a/bin/addons/base/i18n/es_AR.po
+++ b/bin/addons/base/i18n/es_AR.po
@@ -1020,21 +1020,7 @@ msgstr "STOCK_COPY"
#: code:addons/addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/es_EC.po b/bin/addons/base/i18n/es_EC.po
index cdc7b705060..292fecf1d42 100644
--- a/bin/addons/base/i18n/es_EC.po
+++ b/bin/addons/base/i18n/es_EC.po
@@ -1032,21 +1032,7 @@ msgstr "STOCK_COPY"
#: code:addons/addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/et.po b/bin/addons/base/i18n/et.po
index 0f8bfdcc1a3..6bec88e69bc 100644
--- a/bin/addons/base/i18n/et.po
+++ b/bin/addons/base/i18n/et.po
@@ -996,21 +996,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/fi.po b/bin/addons/base/i18n/fi.po
index 2a72521da63..d08c66c9de0 100644
--- a/bin/addons/base/i18n/fi.po
+++ b/bin/addons/base/i18n/fi.po
@@ -1007,21 +1007,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/fr.po b/bin/addons/base/i18n/fr.po
index a9bfe113b54..6d117fc2799 100644
--- a/bin/addons/base/i18n/fr.po
+++ b/bin/addons/base/i18n/fr.po
@@ -1013,21 +1013,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/gl.po b/bin/addons/base/i18n/gl.po
index 22d5221e728..ec17267b817 100644
--- a/bin/addons/base/i18n/gl.po
+++ b/bin/addons/base/i18n/gl.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/he.po b/bin/addons/base/i18n/he.po
index 5a07918b3fa..a320a211ae1 100644
--- a/bin/addons/base/i18n/he.po
+++ b/bin/addons/base/i18n/he.po
@@ -1002,21 +1002,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/hr.po b/bin/addons/base/i18n/hr.po
index 7922b2d3362..2baa827c81d 100644
--- a/bin/addons/base/i18n/hr.po
+++ b/bin/addons/base/i18n/hr.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/hu.po b/bin/addons/base/i18n/hu.po
index 58b6d5beeab..985a83f663c 100644
--- a/bin/addons/base/i18n/hu.po
+++ b/bin/addons/base/i18n/hu.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/id.po b/bin/addons/base/i18n/id.po
index 9e6ca6e7b78..f1a0ec4e7fb 100644
--- a/bin/addons/base/i18n/id.po
+++ b/bin/addons/base/i18n/id.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/is.po b/bin/addons/base/i18n/is.po
index 2da0c73e9d0..66a9f734a2f 100644
--- a/bin/addons/base/i18n/is.po
+++ b/bin/addons/base/i18n/is.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/it.po b/bin/addons/base/i18n/it.po
index 20c61df95ab..17981e3c925 100644
--- a/bin/addons/base/i18n/it.po
+++ b/bin/addons/base/i18n/it.po
@@ -1001,21 +1001,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/ja.po b/bin/addons/base/i18n/ja.po
index 95bbfb2d8f3..144ebdb1473 100644
--- a/bin/addons/base/i18n/ja.po
+++ b/bin/addons/base/i18n/ja.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/ko.po b/bin/addons/base/i18n/ko.po
index 6c8337017f6..a597ca00b3f 100644
--- a/bin/addons/base/i18n/ko.po
+++ b/bin/addons/base/i18n/ko.po
@@ -993,21 +993,7 @@ msgstr "재고_복사"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/lt.po b/bin/addons/base/i18n/lt.po
index d56336d7fac..b01b8a2d46f 100644
--- a/bin/addons/base/i18n/lt.po
+++ b/bin/addons/base/i18n/lt.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/lt_LT.po b/bin/addons/base/i18n/lt_LT.po
index e78fb6a9fba..aaeb0ca628f 100644
--- a/bin/addons/base/i18n/lt_LT.po
+++ b/bin/addons/base/i18n/lt_LT.po
@@ -972,21 +972,7 @@ msgstr ""
#. module: base
#: code:addons/addons/base/ir/ir_model.py:0
#, python-format
-msgid "Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+msgid "Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/lv.po b/bin/addons/base/i18n/lv.po
index f202c0b1a13..62d942d51ba 100644
--- a/bin/addons/base/i18n/lv.po
+++ b/bin/addons/base/i18n/lv.po
@@ -1008,21 +1008,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/mn.po b/bin/addons/base/i18n/mn.po
index 75c614400f7..1c7d3d7b51e 100644
--- a/bin/addons/base/i18n/mn.po
+++ b/bin/addons/base/i18n/mn.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/nl.po b/bin/addons/base/i18n/nl.po
index 1a25187f9ba..b89949b0067 100644
--- a/bin/addons/base/i18n/nl.po
+++ b/bin/addons/base/i18n/nl.po
@@ -1011,37 +1011,9 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
-"Model %s bestaat niet !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s bestaat niet !"
#. module: base
#: code:addons/base/module/module.py:0
diff --git a/bin/addons/base/i18n/nl_BE.po b/bin/addons/base/i18n/nl_BE.po
index eb3fb17cf89..7875ffe4c9a 100644
--- a/bin/addons/base/i18n/nl_BE.po
+++ b/bin/addons/base/i18n/nl_BE.po
@@ -1018,21 +1018,7 @@ msgstr "STOCK_COPY"
#: code:addons/addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/nl_NL.po b/bin/addons/base/i18n/nl_NL.po
index 62e7de86a37..7923932bf59 100644
--- a/bin/addons/base/i18n/nl_NL.po
+++ b/bin/addons/base/i18n/nl_NL.po
@@ -1029,21 +1029,7 @@ msgstr "STOCK_COPY"
#: code:addons/addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/pl.po b/bin/addons/base/i18n/pl.po
index ae01c45f2b7..41758632d74 100644
--- a/bin/addons/base/i18n/pl.po
+++ b/bin/addons/base/i18n/pl.po
@@ -1006,21 +1006,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/pt.po b/bin/addons/base/i18n/pt.po
index a7252582700..537e8197a29 100644
--- a/bin/addons/base/i18n/pt.po
+++ b/bin/addons/base/i18n/pt.po
@@ -1007,37 +1007,9 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
-"O modelo %s não existe!\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"O modelo %s não existe!"
#. module: base
#: code:addons/base/module/module.py:0
diff --git a/bin/addons/base/i18n/pt_BR.po b/bin/addons/base/i18n/pt_BR.po
index 7380b787054..3e8f7e495d3 100644
--- a/bin/addons/base/i18n/pt_BR.po
+++ b/bin/addons/base/i18n/pt_BR.po
@@ -1005,21 +1005,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/ro.po b/bin/addons/base/i18n/ro.po
index 7e8fb00b756..309fecbb1a6 100644
--- a/bin/addons/base/i18n/ro.po
+++ b/bin/addons/base/i18n/ro.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/ru.po b/bin/addons/base/i18n/ru.po
index 47980c35df6..6d027fdda5d 100644
--- a/bin/addons/base/i18n/ru.po
+++ b/bin/addons/base/i18n/ru.po
@@ -992,21 +992,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/sk.po b/bin/addons/base/i18n/sk.po
index aaa3b85cc45..823310eade0 100644
--- a/bin/addons/base/i18n/sk.po
+++ b/bin/addons/base/i18n/sk.po
@@ -992,21 +992,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/sl.po b/bin/addons/base/i18n/sl.po
index 021d4b9698c..705a61afba9 100644
--- a/bin/addons/base/i18n/sl.po
+++ b/bin/addons/base/i18n/sl.po
@@ -990,21 +990,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/sq.po b/bin/addons/base/i18n/sq.po
index dcc34f74e80..07a5105dad7 100644
--- a/bin/addons/base/i18n/sq.po
+++ b/bin/addons/base/i18n/sq.po
@@ -990,21 +990,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/sr.po b/bin/addons/base/i18n/sr.po
index 41d4a6eff86..f8618b3a933 100644
--- a/bin/addons/base/i18n/sr.po
+++ b/bin/addons/base/i18n/sr.po
@@ -1008,21 +1008,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/sv.po b/bin/addons/base/i18n/sv.po
index 97b6ea42897..c61ff39fbe6 100644
--- a/bin/addons/base/i18n/sv.po
+++ b/bin/addons/base/i18n/sv.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/th.po b/bin/addons/base/i18n/th.po
index 7422cf1592d..ff67a9f0ece 100644
--- a/bin/addons/base/i18n/th.po
+++ b/bin/addons/base/i18n/th.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/tlh.po b/bin/addons/base/i18n/tlh.po
index 9591b4c08df..fe8213253d0 100644
--- a/bin/addons/base/i18n/tlh.po
+++ b/bin/addons/base/i18n/tlh.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/tr.po b/bin/addons/base/i18n/tr.po
index b3f1de1fd69..43b045b5c45 100644
--- a/bin/addons/base/i18n/tr.po
+++ b/bin/addons/base/i18n/tr.po
@@ -989,21 +989,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/uk.po b/bin/addons/base/i18n/uk.po
index 16349b20d9f..eff183eebd2 100644
--- a/bin/addons/base/i18n/uk.po
+++ b/bin/addons/base/i18n/uk.po
@@ -1001,21 +1001,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/uk_UA.po b/bin/addons/base/i18n/uk_UA.po
index 7b4bd684de2..fe1776abd64 100644
--- a/bin/addons/base/i18n/uk_UA.po
+++ b/bin/addons/base/i18n/uk_UA.po
@@ -989,21 +989,7 @@ msgstr "STOCK_COPY"
#. module: base
#: code:addons/addons/base/ir/ir_model.py:0
#, python-format
-msgid "Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+msgid "Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/vi.po b/bin/addons/base/i18n/vi.po
index c477d6cb878..d6b923cfc13 100644
--- a/bin/addons/base/i18n/vi.po
+++ b/bin/addons/base/i18n/vi.po
@@ -985,21 +985,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/zh_CN.po b/bin/addons/base/i18n/zh_CN.po
index f441f698c14..d860132b646 100644
--- a/bin/addons/base/i18n/zh_CN.po
+++ b/bin/addons/base/i18n/zh_CN.po
@@ -990,21 +990,6 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
msgstr ""
#. module: base
@@ -8208,29 +8193,8 @@ msgstr "俄语 / русский язык"
#, python-format
#~ msgid ""
-#~ "Cannot delete Purchase Order(s) which are in %s State!' % s['state']))\n"
-#~ " return super(purchase_order, self).unlink(cr, uid, unlink_ids, "
-#~ "context=context)\n"
-#~ "\n"
-#~ " def button_dummy(self, cr, uid, ids, context={}):\n"
-#~ " return True\n"
-#~ "\n"
-#~ " def onchange_dest_address_id(self, cr, uid, ids, adr_id):\n"
-#~ " if not adr_id:\n"
-#~ " return {}\n"
-#~ " part_id = self.pool.get('res.partner.address"
#~ msgstr ""
-#~ "无法删除在%s状态的采购订单!' % s['state']))\n"
-#~ " return super(purchase_order, self).unlink(cr, uid, unlink_ids, \n"
-#~ "context=context)\n"
-#~ "\n"
-#~ " def button_dummy(self, cr, uid, ids, context={}):\n"
-#~ " return True\\n\n"
-#~ "\n"
-#~ " def onchange_dest_address_id(self, cr, uid, ids, adr_id):\n"
-#~ " if not adr_id:\n"
-#~ " return {}\n"
-#~ " part_id = self.pool.get('res.partner.address"
+#~ "无法删除在%s状态的采购订单!"
#, python-format
#~ msgid ""
diff --git a/bin/addons/base/i18n/zh_TW.po b/bin/addons/base/i18n/zh_TW.po
index 7dbb6804f87..ac66f2dfe29 100644
--- a/bin/addons/base/i18n/zh_TW.po
+++ b/bin/addons/base/i18n/zh_TW.po
@@ -984,21 +984,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
From 2ba5fbfb892018a151eb37049eeaf1b16107fbf4 Mon Sep 17 00:00:00 2001
From: "NCH (Open ERP)" <>
Date: Fri, 18 Dec 2009 15:55:13 +0530
Subject: [PATCH 032/123] [FIX] crm: after upgrade module, base setup wizard
called, configuration wizard is crash
bzr revid: hmo@tinyerp.com-20091218102513-1benptetg7q2x4qu
---
addons/crm/crm_calendar.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/addons/crm/crm_calendar.py b/addons/crm/crm_calendar.py
index 4770216a439..2714306fde8 100644
--- a/addons/crm/crm_calendar.py
+++ b/addons/crm/crm_calendar.py
@@ -477,7 +477,12 @@ virtual_report_spool()
class virtual_wizard(web_services.wizard):
def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
if wiz_id not in self.wiz_uid:
- super(virtual_wizard,self).exp_create(db, uid, 'module.upgrade', datas)
+ # TODO : To Check why need it
+ if wiz_id == 1:
+ wiz_name ='base_setup.base_setup'
+ if wiz_id == 2:
+ wiz_name ='module.upgrade'
+ super(virtual_wizard,self).exp_create(db, uid, wiz_name, datas)
new_ids = []
if 'id' in datas:
datas['id'] = caldevIDs2readIDs(datas['id'])
@@ -487,4 +492,4 @@ class virtual_wizard(web_services.wizard):
res=super(virtual_wizard, self).exp_execute(db, uid, wiz_id, datas, action, context)
return res
-virtual_wizard()
\ No newline at end of file
+virtual_wizard()
From 25d298f4b81f97c18826f4fd7a2f909e114913ca Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Fri, 18 Dec 2009 17:20:40 +0530
Subject: [PATCH 033/123] [IMP]: Made function for recurrent date generic,
Improvement for vtodo
bzr revid: rpa@tinyerp.com-20091218115040-65ak3t01hi733oeb
---
addons/caldav/calendar.py | 70 ++++++++++++++++++++++++++++++---------
1 file changed, 54 insertions(+), 16 deletions(-)
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index ddf59efe34f..2c20a348d1a 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -69,6 +69,19 @@ def map_data(cr, uid, obj):
class CalDAV(object):
__attribute__ = {
}
+ def get_recurrent_dates(self, rrulestring, exdate, startdate=None):
+ todate = parser.parse
+ if not startdate:
+ startdate = datetime.now()
+ else:
+ startdate = todate(''.join((re.compile('\d')).findall(startdate)) + 'Z')
+ rset1 = rrulestr(rrulestring, dtstart=startdate, forceset=True)
+ for date in exdate:
+ datetime_obj = datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
+ rset1._exdate.append(datetime_obj)
+ re_dates = rset1._iter()
+ recurrent_dates = map(lambda x:x.strftime('%Y-%m-%d %H:%M:%S'), re_dates)
+ return recurrent_dates
def ical_set(self, name, value, type):
if name in self.__attribute__ and self.__attribute__[name]:
@@ -117,6 +130,7 @@ class CalDAV(object):
def import_ical(self, cr, uid, ical_data):
parsedCal = vobject.readOne(ical_data)
att_data = []
+ todo_data = []
for child in parsedCal.getChildren():
for cal_data in child.getChildren():
if cal_data.name.lower() == 'attendee':
@@ -192,25 +206,47 @@ class Event(CalDAV, osv.osv_memory):
'dtend': None, # Use: O-1, Type: DATE-TIME, Specifies the date and time that a calendar component ends.
}
- def get_recurrent_dates(self, rrulestring, exdate, startdate=None):
- todate = parser.parse
- if not startdate:
- startdate = datetime.now()
- else:
- startdate = todate(''.join((re.compile('\d')).findall(startdate)) + 'Z')
- rset1 = rrulestr(rrulestring, dtstart=startdate, forceset=True)
- for date in exdate:
- datetime_obj = datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
- rset1._exdate.append(datetime_obj)
- re_dates = rset1._iter()
- recurrent_dates = map(lambda x:x.strftime('%Y-%m-%d %H:%M:%S'), re_dates)
- return recurrent_dates
-
Event()
-class ToDo(CalDAV):
+class ToDo(CalDAV, osv.osv_memory):
+ _name = 'caldav.todo'
+
__attribute__ = {
- }
+ 'class': None,
+ 'completed': None,
+ 'created': None,
+ 'description': None,
+ 'dtstamp': None,
+ 'dtstart': None,
+ 'duration': None,
+ 'due': None,
+ 'geo': None,
+ 'last-mod ': None,
+ 'location': None,
+ 'organizer': None,
+ 'percent': None,
+ 'priority': None,
+ 'recurid': None,
+ 'seq': None,
+ 'status': None,
+ 'summary': None,
+ 'uid': None,
+ 'url': None,
+ 'attach': None,
+ 'attendee': None,
+ 'categories': None,
+ 'comment': None,
+ 'contact': None,
+ 'exdate': None,
+ 'exrule': None,
+ 'rstatus': None,
+ 'related': None,
+ 'resources': None,
+ 'rdate': None,
+ 'rrule': None,
+ }
+
+ToDo()
class Journal(CalDAV):
__attribute__ = {
@@ -341,6 +377,8 @@ class Attendee(CalDAV, osv.osv_memory):
self.ical_set(para.lower(), ical_data.params[para][0]+':'+ ical_data.value, 'value')
else:
self.ical_set(para.lower(), ical_data.params[para][0], 'value')
+ if not ical_data.params.get('CN'):
+ self.ical_set('cn', ical_data.value, 'value')
vals = map_data(cr, uid, self)
return vals
From 0f148f391ccd5e32a70d1927fb9489ee35f01845 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Fri, 18 Dec 2009 17:54:20 +0530
Subject: [PATCH 034/123] [ADD]: Added new module project_calendar that is used
to import/export ical data of project tasks
bzr revid: rpa@tinyerp.com-20091218122420-817voetdl2q61n5r
---
addons/project_calendar/__init__.py | 25 ++
addons/project_calendar/__terp__.py | 37 ++
addons/project_calendar/project_calendar.py | 333 ++++++++++++++++++
.../project_calendar_view.xml | 126 +++++++
.../project_calendar_wizard.xml | 8 +
.../security/ir.model.access.csv | 3 +
addons/project_calendar/wizard/__init__.py | 24 ++
.../wizard/wizard_cal_import.py | 67 ++++
8 files changed, 623 insertions(+)
create mode 100644 addons/project_calendar/__init__.py
create mode 100644 addons/project_calendar/__terp__.py
create mode 100644 addons/project_calendar/project_calendar.py
create mode 100644 addons/project_calendar/project_calendar_view.xml
create mode 100644 addons/project_calendar/project_calendar_wizard.xml
create mode 100644 addons/project_calendar/security/ir.model.access.csv
create mode 100644 addons/project_calendar/wizard/__init__.py
create mode 100644 addons/project_calendar/wizard/wizard_cal_import.py
diff --git a/addons/project_calendar/__init__.py b/addons/project_calendar/__init__.py
new file mode 100644
index 00000000000..08bcccf6426
--- /dev/null
+++ b/addons/project_calendar/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import project_calendar
+import wizard
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_calendar/__terp__.py b/addons/project_calendar/__terp__.py
new file mode 100644
index 00000000000..6d7dd6763d9
--- /dev/null
+++ b/addons/project_calendar/__terp__.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+{
+ "name" : "Caldav task management",
+ "version" : "1.0",
+ "author" : "Tiny",
+ "category" : "Generic Modules/Others",
+ "description": """ Synchronize between Project task and Caldav Vtodo.""",
+ "depends" : ["project", "caldav"],
+ "init_xml" : [],
+ "demo_xml" : [],
+ "update_xml" : ["project_calendar_view.xml",
+ "project_calendar_wizard.xml",
+ "security/ir.model.access.csv"],
+ "active": False,
+ "website": "http://www.openerp.com",
+ "installable": True,
+}
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
new file mode 100644
index 00000000000..d37026df747
--- /dev/null
+++ b/addons/project_calendar/project_calendar.py
@@ -0,0 +1,333 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+from datetime import datetime
+from osv import fields, osv
+from service import web_services
+import base64
+
+def caldevIDs2readIDs(caldev_ID = None):
+ if caldev_ID:
+ if isinstance(caldev_ID, str):
+ return int(caldev_ID.split('-')[0])
+ return caldev_ID
+
+class crm_caldav_attendee(osv.osv):
+ _name = 'crm.caldav.attendee'
+ _description = 'Attendee information'
+ _rec_name = 'cutype'
+
+ __attribute__ = {
+ 'cutype': {'field':'cutype', 'type':'text'},
+ 'member': {'field':'member', 'type':'text'},
+ 'role': {'field':'role', 'type':'selection'},
+ 'partstat': {'field':'partstat', 'type':'text'},
+ 'rsvp': {'field':'rsvp', 'type':'boolean'},
+ 'delegated-to': {'field':'delegated_to', 'type':'char'},
+ 'delegated-from': {'field':'delegated_from', 'type':'char'},
+ 'sent-by': {'field':'sent_by', 'type':'text'},
+ 'cn': {'field':'cn', 'type':'text'},
+ 'dir': {'field':'dir', 'type':'text'},
+ 'language': {'field':'language', 'type':'text'},
+ }
+
+ _columns = {
+ 'cutype': fields.selection([('INDIVIDUAL', 'INDIVIDUAL'), ('GROUP', 'GROUP'), \
+ ('RESOURCE', 'RESOURCE'), ('ROOM', 'ROOM'), \
+ ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE'),
+ 'member': fields.char('Member', size=124),
+ 'role': fields.selection([ ('REQ-PARTICIPANT', 'REQ-PARTICIPANT'), \
+ ('CHAIR', 'CHAIR'), ('OPT-PARTICIPANT', 'OPT-PARTICIPANT'), \
+ ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE'),
+ 'partstat': fields.selection([('NEEDS-ACTION', 'NEEDS-ACTION'), \
+ ('ACCEPTED', 'ACCEPTED'), ('DECLINED', 'DECLINED'), \
+ ('TENTATIVE', 'TENTATIVE'), \
+ ('DELEGATED', 'DELEGATED')], 'PARTSTAT'),
+ 'rsvp': fields.boolean('RSVP'),
+ 'delegated_to': fields.char('DELEGATED-TO', size=124),
+ 'delegated_from': fields.char('DELEGATED-FROM', size=124),
+ 'sent_by': fields.char('SENT-BY', size=124),
+ 'cn': fields.char('CN', size=124),
+ 'dir': fields.char('DIR', size=124),
+ 'language': fields.char('LANGUAGE', size=124),
+ }
+ _defaults = {
+ 'cn': lambda *x: 'MAILTO:',
+ }
+
+crm_caldav_attendee()
+
+class crm_caldav_alarm(osv.osv):
+ _name = 'crm.caldav.alarm'
+ _description = 'Event alarm information'
+
+ __attribute__ = {
+ 'action': {'field': 'action', 'type': 'text'},
+ 'description': {'field': 'name', 'type': 'text'},
+ 'summary': {'field': 'description', 'type': 'text'},
+ 'attendee': {'field': 'attendee_ids', 'type': 'text'},
+ 'trigger_related': {'field': 'trigger_related', 'type': 'text'},
+ 'trigger_duration': {'field': 'trigger_duration', 'type': 'text'},
+ 'trigger_occurs': {'field': 'trigger_occurs', 'type': 'text'},
+ 'trigger_interval': {'field': 'trigger_interval', 'type': 'text'},
+ 'duration': {'field': 'duration', 'type': 'text'},
+ 'repeat': {'field': 'repeat', 'type': 'text'},
+ 'attach': {'field': 'attach', 'type': 'text'},
+ }
+
+ _columns = {
+ 'name': fields.char('Summary', size=124),
+ 'action': fields.selection([('AUDIO', 'AUDIO'), ('DISPLAY', 'DISPLAY'), \
+ ('PROCEDURE', 'PROCEDURE'), ('EMAIL', 'EMAIL') ], 'Action', required=True),
+ 'description': fields.text('Description'),
+ 'attendee_ids': fields.many2many('crm.caldav.attendee', 'alarm_attendee_rel', \
+ 'alarm_id', 'attendee_id', 'Attendees'),
+ 'trigger_occurs': fields.selection([('BEFORE', 'BEFORE'), ('AFTER', 'AFTER')], \
+ 'Trigger time', required=True),
+ 'trigger_interval': fields.selection([('MINUTES', 'MINUTES'), ('HOURS', 'HOURS'), \
+ ('DAYS', 'DAYS')], 'Trugger duration', required=True),
+ 'trigger_duration': fields.integer('TIme', required=True),
+ 'trigger_related': fields.selection([('start', 'The event starts'), ('end', \
+ 'The event ends')], 'Trigger Occures at', required=True),
+ 'duration': fields.integer('Duration'),
+ 'repeat': fields.integer('Repeat'), # TODO
+ 'attach': fields.binary('Attachment'),
+ 'active': fields.boolean('Active'),
+ }
+
+ _defaults = {
+ 'action': lambda *x: 'EMAIL',
+ 'trigger_interval': lambda *x: 'MINUTES',
+ 'trigger_duration': lambda *x: 5,
+ 'trigger_occurs': lambda *x: 'BEFORE',
+ 'trigger_related': lambda *x: 'start',
+ }
+
+crm_caldav_alarm()
+
+class project_task(osv.osv):
+ _inherit = "project.task"
+
+ def _get_rdates(self, cr, uid, ids, name, arg, context=None):
+ res = {}
+ context.update({'read':True})
+ for task in self.read(cr, uid, ids, ['date_start', 'rrule'], context=context):
+ if task['rrule']:
+ rule = task['rrule'].split('\n')[0]
+ if rule.upper().find('COUNT') < 0: # Temp fix, needs review
+ rule += ';COUNT=5'
+ exdate = task['rrule'].split('\n')[1:]
+ todo_obj = self.pool.get('caldav.todo')
+ res[task['id']] = str(todo_obj.get_recurrent_dates(str(rule), exdate, task['date_start']))
+ return res
+
+ _columns = {
+ 'class': fields.selection([('PUBLIC', 'PUBLIC'), ('PRIVATE', 'PRIVATE'), \
+ ('CONFIDENTIAL', 'CONFIDENTIAL')], 'Class'),
+ 'location': fields.text('Location'),
+ 'rrule': fields.text('Recurrent Rule'),
+ 'rdates': fields.function(_get_rdates, method=True, string='Recurrent Dates', \
+ store=True, type='text'),
+ 'attendee_ids': fields.many2many('crm.caldav.attendee', 'crm_attendee_rel', 'case_id', \
+ 'attendee_id', 'Attendees'),
+ 'alarm_id': fields.many2one('crm.caldav.alarm', 'Alarm'),
+ 'caldav_url': fields.char('Caldav URL', size=34),
+ }
+
+ __attribute__ = {
+ 'class': {'field': 'class', 'type': 'text'},
+ 'completed': {'field': 'date_close', 'type': 'datetime'},
+ 'description': {'field': 'description', 'type': 'text'},
+ 'dtstart': {'field': 'date_start', 'type': 'datetime'},
+ 'duration': {'field': 'planned_hours', 'type': 'int'},
+ 'due': {'field': 'date_deadline', 'type': 'datetime'},
+ 'location': {'field': 'location', 'type': 'text'}, # To add
+ 'organizer': {'field': 'partner_id', 'type': 'many2one', 'object': 'res.partner'},
+ 'percent': {'field': 'progress_rate', 'type': 'int'},
+ 'priority': {'field': 'priority', 'type': 'text'},
+ 'seq': {'field': 'sequence', 'type': 'text'},
+ 'status': {'field': 'state', 'type': 'selection', 'mapping': {'NEEDS-ACTION': 'draft', \
+ 'COMPLETED': 'done', 'IN-PROCESS': 'open', \
+ 'CANCELLED': 'cancelled'}},
+ 'summary': {'field': 'name', 'type': 'text'},
+ 'url': {'field': 'caldav_url', 'type': 'text'}, # To add
+ 'attendee': {'field': 'attendee_ids', 'type': 'many2many', 'object': 'crm.caldav.attendee'},
+# 'categories': {'field': 'type', 'type': 'text'}, # Needs review
+ 'comment': {'field': 'notes', 'type': 'text'},
+ 'rrule': {'field': 'rrule', 'type': 'text'},
+ }
+
+ def import_cal(self, cr, uid, ids, data, context={}):
+ file_content = base64.decodestring(data['form']['file_path'])
+ todo_obj = self.pool.get('caldav.todo')
+ todo_obj.__attribute__.update(self.__attribute__)
+
+ attendee_obj = self.pool.get('caldav.attendee')
+ crm_attendee = self.pool.get('crm.caldav.attendee')
+ attendee_obj.__attribute__.update(crm_attendee.__attribute__)
+
+ alarm_obj = self.pool.get('caldav.alarm')
+ crm_alarm = self.pool.get('crm.caldav.alarm')
+ alarm_obj.__attribute__.update(crm_alarm.__attribute__)
+
+ vals = todo_obj.import_ical(cr, uid, file_content)
+ if not vals.has_key('duration'):
+ # 'Compute duration'
+ vals['planned_hours'] = 16
+ task_id = self.create(cr, uid, vals)
+ return
+
+ def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
+ """ logic for recurrent task
+ example : 123-20091111170822""", ids, fields, context
+ if context and context.has_key('read'):
+ return super(project_task, self).read(cr, uid, ids, fields, context, load)
+ if not type(ids) == list :
+ return super(project_task, self).read(cr, uid, caldevIDs2readIDs(ids),\
+ fields=fields, context=context, load=load)
+ else:
+ ids = map(lambda x:caldevIDs2readIDs(x), ids)
+ res = super(project_task, self).read(cr, uid, ids, fields=fields, context=context, load=load)
+ read_ids = ",".join([str(x) for x in ids])
+ if not read_ids:
+ return []
+ cr.execute('select id,rrule,rdates from project_task where id in (%s)' % read_ids)
+ rrules = filter(lambda x: not x['rrule']==None, cr.dictfetchall())
+ rdates = []
+ if not rrules:
+ return res
+ result = res + []
+ for data in rrules:
+ if data['rrule'] and data['rdates']:
+ rdates = eval(data['rdates'])
+ for res_temp in res:
+ if res_temp['id'] == data['id']:
+ val = res_temp
+ if rdates:
+ result.remove(val)
+
+ for rdate in rdates:
+ import re
+ idval = (re.compile('\d')).findall(rdate)
+ val['date'] = rdate
+ id = str(val['id']).split('-')[0]
+ val['id'] = id + '-' + ''.join(idval)
+ val1 = val.copy()
+ result += [val1]
+ return result
+
+project_task()
+
+class ir_attachment(osv.osv):
+ _name = 'ir.attachment'
+ _inherit = 'ir.attachment'
+
+ def search_count(self, cr, user, args, context=None):
+ args1 = []
+ for arg in args:
+ args1.append(map(lambda x:str(x).split('-')[0], arg))
+ return super(ir_attachment, self).search_count(cr, user, args1, context)
+
+ def search(self, cr, uid, args, offset=0, limit=None, order=None,
+ context=None, count=False):
+ new_args = []
+ if len(args) > 1:
+ new_args = [args[0]]
+ if args[1][0] == 'res_id':
+ new_args.append((args[1][0], args[1][1], caldevIDs2readIDs(args[1][2])))
+ if new_args:
+ args = new_args
+ return super(ir_attachment, self).search(cr, uid, args, offset=offset,
+ limit=limit, order=order,
+ context=context, count=False)
+ir_attachment()
+
+class ir_values(osv.osv):
+ _inherit = 'ir.values'
+
+ def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, \
+ meta=False, preserve_user=False, company=False):
+ new_model = []
+ for data in models:
+ if type(data) in (list, tuple):
+ new_model.append((data[0], caldevIDs2readIDs(data[1])))
+ else:
+ new_model.append(data)
+ return super(ir_values, self).set(cr, uid, key, key2, name, new_model, value, \
+ replace, isobject, meta, preserve_user, company)
+
+ def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, \
+ without_user=True, key2_req=True):
+ new_model = []
+ for data in models:
+ if type(data) in (list, tuple):
+ new_model.append((data[0], caldevIDs2readIDs(data[1])))
+ else:
+ new_model.append(data)
+ return super(ir_values, self).get(cr, uid, key, key2, new_model, meta, context, \
+ res_id_req, without_user, key2_req)
+
+ir_values()
+
+class ir_model(osv.osv):
+
+ _inherit = 'ir.model'
+
+ def read(self, cr, uid, ids, fields=None, context={},
+ load='_classic_read'):
+ data = super(ir_model, self).read(cr, uid, ids, fields=fields, context=context, load=load)
+ if data:
+ for val in data:
+ val['id'] = caldevIDs2readIDs(val['id'])
+ return data
+
+ir_model()
+
+class virtual_report_spool(web_services.report_spool):
+
+ def exp_report(self, db, uid, object, ids, datas=None, context=None):
+ if object == 'printscreen.list':
+ return super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context)
+ new_ids = []
+ for id in ids:
+ new_ids.append(caldevIDs2readIDs(id))
+ datas['id'] = caldevIDs2readIDs(datas['id'])
+ super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
+ return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
+
+virtual_report_spool()
+
+class virtual_wizard(web_services.wizard):
+ def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
+ if wiz_id not in self.wiz_uid:
+ super(virtual_wizard,self).exp_create(db, uid, 'module.upgrade', datas)
+ new_ids = []
+ if 'id' in datas:
+ datas['id'] = caldevIDs2readIDs(datas['id'])
+ for id in datas['ids']:
+ new_ids.append(caldevIDs2readIDs(id))
+ datas['ids'] = new_ids
+ res=super(virtual_wizard, self).exp_execute(db, uid, wiz_id, datas, action, context)
+ return res
+
+virtual_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_calendar/project_calendar_view.xml b/addons/project_calendar/project_calendar_view.xml
new file mode 100644
index 00000000000..826d0788b04
--- /dev/null
+++ b/addons/project_calendar/project_calendar_view.xml
@@ -0,0 +1,126 @@
+
+
+
+
+ crm.case.caldav.attendee
+ crm.caldav.attendee
+ form
+
+
+
+
+
+
+ crm.case.caldav.attendee
+ crm.caldav.attendee
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ crm.case.caldav.alarm.form
+ crm.caldav.alarm
+ form
+
+
+
+
+
+
+ crm.case.caldav.alarm.tree
+ crm.caldav.alarm
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ project.task.caldav.tree
+ project.task
+ tree
+
+
+
+
+
+
+
+
+
+ project.task.caldav.form
+ project.task
+
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/project_calendar/project_calendar_wizard.xml b/addons/project_calendar/project_calendar_wizard.xml
new file mode 100644
index 00000000000..9d3ea03ddda
--- /dev/null
+++ b/addons/project_calendar/project_calendar_wizard.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/addons/project_calendar/security/ir.model.access.csv b/addons/project_calendar/security/ir.model.access.csv
new file mode 100644
index 00000000000..f65c32af108
--- /dev/null
+++ b/addons/project_calendar/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_crm_caldav_attendee","crm.caldav.attendee","model_crm_caldav_attendee",,1,1,1,1
+"access_crm_caldav_alarm","crm.caldav.alarm","model_crm_caldav_alarm",,1,1,1,1
diff --git a/addons/project_calendar/wizard/__init__.py b/addons/project_calendar/wizard/__init__.py
new file mode 100644
index 00000000000..030daa5cb83
--- /dev/null
+++ b/addons/project_calendar/wizard/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import wizard_cal_import
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/project_calendar/wizard/wizard_cal_import.py b/addons/project_calendar/wizard/wizard_cal_import.py
new file mode 100644
index 00000000000..7ca19bcee6e
--- /dev/null
+++ b/addons/project_calendar/wizard/wizard_cal_import.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import time
+import tools
+import wizard
+import os
+import mx.DateTime
+import base64
+import pooler
+import vobject
+
+
+class project_cal_imp_wizard(wizard.interface):
+ form1 = '''
+ '''
+
+ form1_fields = {
+ 'file_path': {
+ 'string': 'Select ICS file',
+ 'type': 'binary',
+ 'required': True,
+ 'filters': '*.ics'
+ }
+ }
+
+ def _process_imp_ics(self, cr, uid, data, context=None):
+ task_obj = pooler.get_pool(cr.dbname).get('project.task')
+ task_obj.import_cal(cr, uid, data['ids'], data, context)
+ return {}
+
+ states = {
+ 'init': {
+ 'actions': [],
+ 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, \
+ 'state': [('end', '_Cancel', 'gtk-cancel'), ('open', '_Import', 'gtk-ok')]}
+ },
+ 'open': {
+ 'actions': [],
+ 'result': {'type': 'action', 'action':_process_imp_ics, 'state':'end'}
+ }
+ }
+
+project_cal_imp_wizard('caldav.project.import')
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
From 207e86e1bdcf358b73d93716814d65ac4a13c0eb Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Fri, 18 Dec 2009 19:14:31 +0530
Subject: [PATCH 035/123] [IMP]: * Added Task Export wizard * Restructuring of
caldav + crm + project_calendar separated common data * Minimized code
bzr revid: rpa@tinyerp.com-20091218134431-12oqmdbkbp3nyd10
---
addons/caldav/__init__.py | 1 +
addons/caldav/calendar.py | 33 ++-
addons/caldav/common.py | 219 +++++++++++++++
addons/caldav/security/ir.model.access.csv | 2 +
addons/crm/crm_caldav_view.xml | 11 -
addons/crm/crm_calendar.py | 210 +-------------
addons/crm/security/ir.model.access.csv | 2 -
addons/project_calendar/__terp__.py | 3 +-
addons/project_calendar/project_calendar.py | 265 ++++++------------
.../project_calendar_wizard.xml | 4 +
.../security/ir.model.access.csv | 3 -
addons/project_calendar/wizard/__init__.py | 1 +
.../wizard/wizard_cal_export.py | 63 +++++
13 files changed, 400 insertions(+), 417 deletions(-)
create mode 100644 addons/caldav/common.py
delete mode 100644 addons/project_calendar/security/ir.model.access.csv
create mode 100644 addons/project_calendar/wizard/wizard_cal_export.py
diff --git a/addons/caldav/__init__.py b/addons/caldav/__init__.py
index 444d7e1b4af..c90e00d11f2 100644
--- a/addons/caldav/__init__.py
+++ b/addons/caldav/__init__.py
@@ -20,5 +20,6 @@
##############################################################################
import calendar
+import common
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index 2c20a348d1a..ee0522c23d0 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -1,22 +1,21 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
-# $Id$
+# Copyright (C) 2004-2009 Tiny SPRL ().
#
# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
#
##############################################################################
@@ -101,10 +100,10 @@ class CalDAV(object):
else:
return self.__attribute__.get(name, None)
- def export_ical(self, cr, uid, datas):
+ def export_ical(self, cr, uid, datas, vobj=None):
ical = vobject.iCalendar()
for data in datas:
- vevent = ical.add('vevent')
+ vevent = ical.add(vobj)
for field in self.__attribute__.keys():
map_field = self.ical_get(field, 'field')
map_type = self.ical_get(field, 'type')
@@ -205,7 +204,9 @@ class Event(CalDAV, osv.osv_memory):
'duration': None, # Use: O-1, Type: DURATION, Specifies a positive duration of time.
'dtend': None, # Use: O-1, Type: DATE-TIME, Specifies the date and time that a calendar component ends.
}
-
+ def export_ical(self, cr, uid, datas):
+ return super(Event, self).export_ical(cr, uid, datas, 'vevent')
+
Event()
class ToDo(CalDAV, osv.osv_memory):
@@ -245,6 +246,9 @@ class ToDo(CalDAV, osv.osv_memory):
'rdate': None,
'rrule': None,
}
+
+ def export_ical(self, cr, uid, datas):
+ return super(ToDo, self).export_ical(cr, uid, datas, 'vtodo')
ToDo()
@@ -395,3 +399,6 @@ class Attendee(CalDAV, osv.osv_memory):
return vevent
Attendee()
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/caldav/common.py b/addons/caldav/common.py
new file mode 100644
index 00000000000..e8c74ef563a
--- /dev/null
+++ b/addons/caldav/common.py
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+from osv import fields, osv
+from service import web_services
+
+def caldevIDs2readIDs(caldev_ID = None):
+ if caldev_ID:
+ if isinstance(caldev_ID, str):
+ return int(caldev_ID.split('-')[0])
+ return caldev_ID
+
+
+class crm_caldav_attendee(osv.osv):
+ _name = 'crm.caldav.attendee'
+ _description = 'Attendee information'
+ _rec_name = 'cutype'
+
+ __attribute__ = {
+ 'cutype': {'field':'cutype', 'type':'text'},
+ 'member': {'field':'member', 'type':'text'},
+ 'role': {'field':'role', 'type':'selection'},
+ 'partstat': {'field':'partstat', 'type':'text'},
+ 'rsvp': {'field':'rsvp', 'type':'boolean'},
+ 'delegated-to': {'field':'delegated_to', 'type':'char'},
+ 'delegated-from': {'field':'delegated_from', 'type':'char'},
+ 'sent-by': {'field':'sent_by', 'type':'text'},
+ 'cn': {'field':'cn', 'type':'text'},
+ 'dir': {'field':'dir', 'type':'text'},
+ 'language': {'field':'language', 'type':'text'},
+ }
+
+ _columns = {
+ 'cutype': fields.selection([('INDIVIDUAL', 'INDIVIDUAL'), ('GROUP', 'GROUP'), \
+ ('RESOURCE', 'RESOURCE'), ('ROOM', 'ROOM'), \
+ ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE'),
+ 'member': fields.char('Member', size=124),
+ 'role': fields.selection([ ('REQ-PARTICIPANT', 'REQ-PARTICIPANT'), \
+ ('CHAIR', 'CHAIR'), ('OPT-PARTICIPANT', 'OPT-PARTICIPANT'), \
+ ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE'),
+ 'partstat': fields.selection([('NEEDS-ACTION', 'NEEDS-ACTION'), \
+ ('ACCEPTED', 'ACCEPTED'), ('DECLINED', 'DECLINED'), \
+ ('TENTATIVE', 'TENTATIVE'), \
+ ('DELEGATED', 'DELEGATED')], 'PARTSTAT'),
+ 'rsvp': fields.boolean('RSVP'),
+ 'delegated_to': fields.char('DELEGATED-TO', size=124),
+ 'delegated_from': fields.char('DELEGATED-FROM', size=124),
+ 'sent_by': fields.char('SENT-BY', size=124),
+ 'cn': fields.char('CN', size=124),
+ 'dir': fields.char('DIR', size=124),
+ 'language': fields.char('LANGUAGE', size=124),
+ }
+ _defaults = {
+ 'cn': lambda *x: 'MAILTO:',
+ }
+
+crm_caldav_attendee()
+
+class crm_caldav_alarm(osv.osv):
+ _name = 'crm.caldav.alarm'
+ _description = 'Event alarm information'
+
+ __attribute__ = {
+ 'action': {'field': 'action', 'type': 'text'},
+ 'description': {'field': 'name', 'type': 'text'},
+ 'summary': {'field': 'description', 'type': 'text'},
+ 'attendee': {'field': 'attendee_ids', 'type': 'text'},
+ 'trigger_related': {'field': 'trigger_related', 'type': 'text'},
+ 'trigger_duration': {'field': 'trigger_duration', 'type': 'text'},
+ 'trigger_occurs': {'field': 'trigger_occurs', 'type': 'text'},
+ 'trigger_interval': {'field': 'trigger_interval', 'type': 'text'},
+ 'duration': {'field': 'duration', 'type': 'text'},
+ 'repeat': {'field': 'repeat', 'type': 'text'},
+ 'attach': {'field': 'attach', 'type': 'text'},
+ }
+
+ _columns = {
+ 'name': fields.char('Summary', size=124),
+ 'action': fields.selection([('AUDIO', 'AUDIO'), ('DISPLAY', 'DISPLAY'), \
+ ('PROCEDURE', 'PROCEDURE'), ('EMAIL', 'EMAIL') ], 'Action', required=True),
+ 'description': fields.text('Description'),
+ 'attendee_ids': fields.many2many('crm.caldav.attendee', 'alarm_attendee_rel', \
+ 'alarm_id', 'attendee_id', 'Attendees'),
+ 'trigger_occurs': fields.selection([('BEFORE', 'BEFORE'), ('AFTER', 'AFTER')], \
+ 'Trigger time', required=True),
+ 'trigger_interval': fields.selection([('MINUTES', 'MINUTES'), ('HOURS', 'HOURS'), \
+ ('DAYS', 'DAYS')], 'Trugger duration', required=True),
+ 'trigger_duration': fields.integer('TIme', required=True),
+ 'trigger_related': fields.selection([('start', 'The event starts'), ('end', \
+ 'The event ends')], 'Trigger Occures at', required=True),
+ 'duration': fields.integer('Duration'),
+ 'repeat': fields.integer('Repeat'), # TODO
+ 'attach': fields.binary('Attachment'),
+ 'active': fields.boolean('Active'),
+ }
+
+ _defaults = {
+ 'action': lambda *x: 'EMAIL',
+ 'trigger_interval': lambda *x: 'MINUTES',
+ 'trigger_duration': lambda *x: 5,
+ 'trigger_occurs': lambda *x: 'BEFORE',
+ 'trigger_related': lambda *x: 'start',
+ }
+
+crm_caldav_alarm()
+
+class ir_attachment(osv.osv):
+ _name = 'ir.attachment'
+ _inherit = 'ir.attachment'
+
+ def search_count(self, cr, user, args, context=None):
+ args1 = []
+ for arg in args:
+ args1.append(map(lambda x:str(x).split('-')[0], arg))
+ return super(ir_attachment, self).search_count(cr, user, args1, context)
+
+ def search(self, cr, uid, args, offset=0, limit=None, order=None,
+ context=None, count=False):
+ new_args = []
+ if len(args) > 1:
+ new_args = [args[0]]
+ if args[1][0] == 'res_id':
+ new_args.append((args[1][0], args[1][1], caldevIDs2readIDs(args[1][2])))
+ if new_args:
+ args = new_args
+ return super(ir_attachment, self).search(cr, uid, args, offset=offset,
+ limit=limit, order=order,
+ context=context, count=False)
+ir_attachment()
+
+class ir_values(osv.osv):
+ _inherit = 'ir.values'
+
+ def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, \
+ meta=False, preserve_user=False, company=False):
+ new_model = []
+ for data in models:
+ if type(data) in (list, tuple):
+ new_model.append((data[0], caldevIDs2readIDs(data[1])))
+ else:
+ new_model.append(data)
+ return super(ir_values, self).set(cr, uid, key, key2, name, new_model, value, \
+ replace, isobject, meta, preserve_user, company)
+
+ def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, \
+ without_user=True, key2_req=True):
+ new_model = []
+ for data in models:
+ if type(data) in (list, tuple):
+ new_model.append((data[0], caldevIDs2readIDs(data[1])))
+ else:
+ new_model.append(data)
+ return super(ir_values, self).get(cr, uid, key, key2, new_model, meta, context, \
+ res_id_req, without_user, key2_req)
+
+ir_values()
+
+class ir_model(osv.osv):
+
+ _inherit = 'ir.model'
+
+ def read(self, cr, uid, ids, fields=None, context={},
+ load='_classic_read'):
+ data = super(ir_model, self).read(cr, uid, ids, fields=fields, context=context, load=load)
+ if data:
+ for val in data:
+ val['id'] = caldevIDs2readIDs(val['id'])
+ return data
+
+ir_model()
+
+class virtual_report_spool(web_services.report_spool):
+
+ def exp_report(self, db, uid, object, ids, datas=None, context=None):
+ if object == 'printscreen.list':
+ return super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context)
+ new_ids = []
+ for id in ids:
+ new_ids.append(caldevIDs2readIDs(id))
+ datas['id'] = caldevIDs2readIDs(datas['id'])
+ super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
+ return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
+
+virtual_report_spool()
+
+class virtual_wizard(web_services.wizard):
+ def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
+ if wiz_id not in self.wiz_uid:
+ super(virtual_wizard,self).exp_create(db, uid, 'module.upgrade', datas)
+ new_ids = []
+ if 'id' in datas:
+ datas['id'] = caldevIDs2readIDs(datas['id'])
+ for id in datas['ids']:
+ new_ids.append(caldevIDs2readIDs(id))
+ datas['ids'] = new_ids
+ res=super(virtual_wizard, self).exp_execute(db, uid, wiz_id, datas, action, context)
+ return res
+
+virtual_wizard()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/caldav/security/ir.model.access.csv b/addons/caldav/security/ir.model.access.csv
index 2e90b4d26f9..8c38869bd6b 100644
--- a/addons/caldav/security/ir.model.access.csv
+++ b/addons/caldav/security/ir.model.access.csv
@@ -2,3 +2,5 @@
"caldav_calendar_all","caldav.calendar","model_caldav_calendar",,1,1,1,1
"caldav_event_all","caldav.event","model_caldav_event",,1,1,1,1
"caldav_attendee_all","caldav.attendee","model_caldav_attendee",,1,1,1,1
+"access_crm_caldav_attendee","crm.caldav.attendee","model_crm_caldav_attendee",,1,1,1,1
+"access_crm_caldav_alarm","crm.caldav.alarm","model_crm_caldav_alarm",,1,1,1,1
diff --git a/addons/crm/crm_caldav_view.xml b/addons/crm/crm_caldav_view.xml
index 1fe77e63f3b..eefa9cd280f 100644
--- a/addons/crm/crm_caldav_view.xml
+++ b/addons/crm/crm_caldav_view.xml
@@ -113,17 +113,6 @@
-
- crm.case.caldav.form1
- crm.case
- form
-
-
-
-
-
-
-
crm.case.caldav.tree1
crm.case
diff --git a/addons/crm/crm_calendar.py b/addons/crm/crm_calendar.py
index 2714306fde8..730184aab2c 100644
--- a/addons/crm/crm_calendar.py
+++ b/addons/crm/crm_calendar.py
@@ -1,22 +1,21 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
-# $Id$
+# Copyright (C) 2004-2009 Tiny SPRL ().
#
# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
#
##############################################################################
@@ -40,97 +39,6 @@ def caldevIDs2readIDs(caldev_ID = None):
return caldev_ID
-class crm_caldav_attendee(osv.osv):
- _name = 'crm.caldav.attendee'
- _description = 'Attendee information'
- _rec_name = 'cutype'
-
- __attribute__ = {
- 'cutype' : {'field':'cutype', 'type':'text'}, # Use: 0-1 Specify the type of calendar user specified by the property like "INDIVIDUAL"/"GROUP"/"RESOURCE"/"ROOM"/"UNKNOWN".
- 'member' : {'field':'member', 'type':'text'}, # Use: 0-1 Specify the group or list membership of the calendar user specified by the property.
- 'role' : {'field':'role', 'type':'selection'}, # Use: 0-1 Specify the participation role for the calendar user specified by the property like "CHAIR"/"REQ-PARTICIPANT"/"OPT-PARTICIPANT"/"NON-PARTICIPANT"
- 'partstat' : {'field':'partstat', 'type':'text'}, # Use: 0-1 Specify the participation status for the calendar user specified by the property. like use for VEVENT :- "NEEDS-ACTION"/"ACCEPTED"/"DECLINED"/"TENTATIVE"/"DELEGATED", use for VTODO :-"NEEDS-ACTION"/"ACCEPTED"/"DECLINED"/"TENTATIVE"/"DELEGATED"/"COMPLETED"/"IN-PROCESS" and use for VJOURNAL :- "NEEDS-ACTION"/"ACCEPTED"/"DECLINED".
- 'rsvp' : {'field':'rsvp', 'type':'boolean'}, # Use: 0-1 Specify whether there is an expectation of a favor of a reply from the calendar user specified by the property value like TRUE / FALSE.
- 'delegated-to' : {'field':'delegated_to', 'type':'char'}, # Use: 0-1 Specify the calendar users to whom the calendar user specified by the property has delegated participation.
- 'delegated-from' : {'field':'delegated_from', 'type':'char'}, # Use: 0-1 Specify the calendar users that have delegated their participation to the calendar user specified by the property.
- 'sent-by' : {'field':'sent_by', 'type':'text'}, # Use: 0-1 Specify the calendar user that is acting on behalf of the calendar user specified by the property.
- 'cn' : {'field':'cn', 'type':'text'}, # Use: 0-1 Specify the common name to be associated with the calendar user specified by the property.
- 'dir' : {'field':'dir', 'type':'text'}, # Use: 0-1 Specify reference to a directory entry associated with the calendar user specified by the property.
- 'language' : {'field':'language', 'type':'text'}, # Use: 0-1 Specify the language for text values in a property or property parameter.
- }
-
- _columns = {
- 'cutype' : fields.selection([('INDIVIDUAL', 'INDIVIDUAL'), ('GROUP', 'GROUP'), \
- ('RESOURCE', 'RESOURCE'), ('ROOM', 'ROOM'), ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE'),
- 'member' : fields.char('Member', size=124),
- 'role' : fields.selection([('CHAIR', 'CHAIR'), ('REQ-PARTICIPANT', 'REQ-PARTICIPANT'), \
- ('OPT-PARTICIPANT', 'OPT-PARTICIPANT'), ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE'),
- 'partstat' : fields.selection([('NEEDS-ACTION', 'NEEDS-ACTION'), ('ACCEPTED', 'ACCEPTED'), \
- ('DECLINED', 'DECLINED'), ('TENTATIVE', 'TENTATIVE'), \
- ('DELEGATED', 'DELEGATED')], 'PARTSTAT'),
- 'rsvp' : fields.boolean('RSVP'),
- 'delegated_to' : fields.char('DELEGATED-TO', size=124),
- 'delegated_from' : fields.char('DELEGATED-FROM', size=124),
- 'sent_by' : fields.char('SENT-BY', size=124),
- 'cn' : fields.char('CN', size=124),
- 'dir' : fields.char('DIR', size=124),
- 'language' : fields.char('LANGUAGE', size=124),
- }
- _defaults = {
- 'cn' : lambda *x: 'MAILTO:',
- }
-
-crm_caldav_attendee()
-
-
-class crm_caldav_alarm(osv.osv):
- _name = 'crm.caldav.alarm'
- _description = 'Event alarm information'
-
- __attribute__ = {
- 'action': {'field': 'action', 'type': 'text'},
- 'description': {'field': 'name', 'type': 'text'},
- 'summary': {'field': 'description', 'type': 'text'},
- 'attendee': {'field': 'attendee', 'type': 'text'},
- 'trigger_related': {'field': 'trigger_related', 'type': 'text'},
- 'trigger_duration': {'field': 'trigger_duration', 'type': 'text'},
- 'trigger_occurs': {'field': 'trigger_occurs', 'type': 'text'},
- 'trigger_interval': {'field': 'trigger_interval', 'type': 'text'},
- 'duration': {'field': 'duration', 'type': 'text'},
- 'repeat': {'field': 'repeat', 'type': 'text'},
- 'attach': {'field': 'attach', 'type': 'text'},
- }
-
- _columns = {
- 'name' : fields.char('Summary', size=124),
- 'action' : fields.selection([('AUDIO', 'AUDIO'), ('DISPLAY', 'DISPLAY'), \
- ('PROCEDURE', 'PROCEDURE'), ('EMAIL', 'EMAIL') ], 'Action' , required=True),
- 'description' : fields.text('Description'),
- 'attendee': fields.many2many('crm.caldav.attendee', 'alarm_attendee_rel', \
- 'alarm_id', 'attendee_id', 'Attendees'),
- 'trigger_occurs' : fields.selection([('BEFORE', 'BEFORE'), ('AFTER', 'AFTER')]\
- , 'Trigger time', required=True),
- 'trigger_interval' : fields.selection([('MINUTES', 'MINUTES'), ('HOURS', 'HOURS'), \
- ('DAYS', 'DAYS')], 'Trugger duration', required=True),
- 'trigger_duration' : fields.integer('TIme' , required=True),
- 'trigger_related' : fields.selection([('start', 'The event starts'), ('end', \
- 'The event ends')], 'Trigger Occures at', required=True),
- 'duration' : fields.integer('Duration'),
- 'repeat' : fields.integer('Repeat'), # TODO
- 'attach' : fields.binary('Attachment'),
- 'active' : fields.boolean('Active'),
- }
-
- _defaults = {
- 'action' : lambda *x: 'EMAIL',
- 'trigger_interval' : lambda *x: 'MINUTES',
- 'trigger_duration' : lambda *x: 5,
- 'trigger_occurs' : lambda *x: 'BEFORE',
- 'trigger_related' : lambda *x: 'start',
- }
-
-crm_caldav_alarm()
-
class crm_case(osv.osv):
_name = 'crm.case'
_inherit = 'crm.case'
@@ -245,7 +153,6 @@ class crm_case(osv.osv):
if alarmdata['trigger_interval'] == 'MINUTES':
delta = datetime.timedelta(minutes=alarmdata['trigger_duration'])
alarm_time = dtstart + (alarmdata['trigger_occurs']== 'AFTER' and delta or -delta)
- print 'alarm_time', alarm_time
if datetime.datetime.now() >= alarm_time:
case_val = case_obj.browse(cr, uid, alarmdata.get('id'), context)[0]
for att in case_val.attendees:
@@ -395,101 +302,4 @@ class crm_case(osv.osv):
crm_case()
-class ir_attachment(osv.osv):
- _name = 'ir.attachment'
- _inherit = 'ir.attachment'
-
- def search_count(self, cr, user, args, context=None):
- args1 = []
- for arg in args:
- args1.append(map(lambda x:str(x).split('-')[0], arg))
- return super(ir_attachment, self).search_count(cr, user, args1, context)
-
- def search(self, cr, uid, args, offset=0, limit=None, order=None,
- context=None, count=False):
- new_args = []
- if len(args) > 1:
- new_args = [args[0]]
- if args[1][0] == 'res_id':
- new_args.append((args[1][0], args[1][1], caldevIDs2readIDs(args[1][2])))
- if new_args:
- args = new_args
- return super(ir_attachment, self).search(cr, uid, args, offset=offset,
- limit=limit, order=order,
- context=context, count=False)
-ir_attachment()
-
-class ir_values(osv.osv):
- _inherit = 'ir.values'
-
- def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, \
- meta=False, preserve_user=False, company=False):
- new_model = []
- for data in models:
- if type(data) in (list, tuple):
- new_model.append((data[0], caldevIDs2readIDs(data[1])))
- else:
- new_model.append(data)
- return super(ir_values, self).set(cr, uid, key, key2, name, new_model, value, \
- replace, isobject, meta, preserve_user, company)
-
- def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, \
- without_user=True, key2_req=True):
- new_model = []
- for data in models:
- if type(data) in (list, tuple):
- new_model.append((data[0], caldevIDs2readIDs(data[1])))
- else:
- new_model.append(data)
- return super(ir_values, self).get(cr, uid, key, key2, new_model, meta, context, \
- res_id_req, without_user, key2_req)
-
-ir_values()
-
-class ir_model(osv.osv):
-
- _inherit = 'ir.model'
-
- def read(self, cr, uid, ids, fields=None, context={},
- load='_classic_read'):
- data = super(ir_model, self).read(cr, uid, ids, fields=fields, context=context, load=load)
- if data:
- for val in data:
- val['id'] = caldevIDs2readIDs(val['id'])
- return data
-
-ir_model()
-
-class virtual_report_spool(web_services.report_spool):
-
- def exp_report(self, db, uid, object, ids, datas=None, context=None):
- if object == 'printscreen.list':
- return super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context)
- new_ids = []
- for id in ids:
- new_ids.append(caldevIDs2readIDs(id))
- datas['id'] = caldevIDs2readIDs(datas['id'])
- super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
- return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
-
-virtual_report_spool()
-
-class virtual_wizard(web_services.wizard):
- def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
- if wiz_id not in self.wiz_uid:
- # TODO : To Check why need it
- if wiz_id == 1:
- wiz_name ='base_setup.base_setup'
- if wiz_id == 2:
- wiz_name ='module.upgrade'
- super(virtual_wizard,self).exp_create(db, uid, wiz_name, datas)
- new_ids = []
- if 'id' in datas:
- datas['id'] = caldevIDs2readIDs(datas['id'])
- for id in datas['ids']:
- new_ids.append(caldevIDs2readIDs(id))
- datas['ids'] = new_ids
- res=super(virtual_wizard, self).exp_execute(db, uid, wiz_id, datas, action, context)
- return res
-
-virtual_wizard()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv
index 4325a52d178..c1b4b1738d6 100644
--- a/addons/crm/security/ir.model.access.csv
+++ b/addons/crm/security/ir.model.access.csv
@@ -34,5 +34,3 @@
"access_crm_generic_wizard_manager","crm.generic_wizard","model_crm_generic_wizard","crm.group_crm_manager",1,1,1,1
"access_crm_generic_wizard_manager","crm.generic_wizard","model_crm_generic_wizard","crm.group_crm_user",1,0,0,0
"access_crm_calendar_config_wizard","crm.calendar.config_wizard","model_crm_calendar_config_wizard",,1,1,1,1
-"access_crm_caldav_attendee","crm.caldav.attendee","model_crm_caldav_attendee",,1,1,1,1
-"access_crm_caldav_alarm","crm.caldav.alarm","model_crm_caldav_alarm",,1,1,1,1
diff --git a/addons/project_calendar/__terp__.py b/addons/project_calendar/__terp__.py
index 6d7dd6763d9..cc314f5d873 100644
--- a/addons/project_calendar/__terp__.py
+++ b/addons/project_calendar/__terp__.py
@@ -29,8 +29,7 @@
"init_xml" : [],
"demo_xml" : [],
"update_xml" : ["project_calendar_view.xml",
- "project_calendar_wizard.xml",
- "security/ir.model.access.csv"],
+ "project_calendar_wizard.xml"],
"active": False,
"website": "http://www.openerp.com",
"installable": True,
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
index d37026df747..8f8c44c4f9d 100644
--- a/addons/project_calendar/project_calendar.py
+++ b/addons/project_calendar/project_calendar.py
@@ -30,99 +30,6 @@ def caldevIDs2readIDs(caldev_ID = None):
return int(caldev_ID.split('-')[0])
return caldev_ID
-class crm_caldav_attendee(osv.osv):
- _name = 'crm.caldav.attendee'
- _description = 'Attendee information'
- _rec_name = 'cutype'
-
- __attribute__ = {
- 'cutype': {'field':'cutype', 'type':'text'},
- 'member': {'field':'member', 'type':'text'},
- 'role': {'field':'role', 'type':'selection'},
- 'partstat': {'field':'partstat', 'type':'text'},
- 'rsvp': {'field':'rsvp', 'type':'boolean'},
- 'delegated-to': {'field':'delegated_to', 'type':'char'},
- 'delegated-from': {'field':'delegated_from', 'type':'char'},
- 'sent-by': {'field':'sent_by', 'type':'text'},
- 'cn': {'field':'cn', 'type':'text'},
- 'dir': {'field':'dir', 'type':'text'},
- 'language': {'field':'language', 'type':'text'},
- }
-
- _columns = {
- 'cutype': fields.selection([('INDIVIDUAL', 'INDIVIDUAL'), ('GROUP', 'GROUP'), \
- ('RESOURCE', 'RESOURCE'), ('ROOM', 'ROOM'), \
- ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE'),
- 'member': fields.char('Member', size=124),
- 'role': fields.selection([ ('REQ-PARTICIPANT', 'REQ-PARTICIPANT'), \
- ('CHAIR', 'CHAIR'), ('OPT-PARTICIPANT', 'OPT-PARTICIPANT'), \
- ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE'),
- 'partstat': fields.selection([('NEEDS-ACTION', 'NEEDS-ACTION'), \
- ('ACCEPTED', 'ACCEPTED'), ('DECLINED', 'DECLINED'), \
- ('TENTATIVE', 'TENTATIVE'), \
- ('DELEGATED', 'DELEGATED')], 'PARTSTAT'),
- 'rsvp': fields.boolean('RSVP'),
- 'delegated_to': fields.char('DELEGATED-TO', size=124),
- 'delegated_from': fields.char('DELEGATED-FROM', size=124),
- 'sent_by': fields.char('SENT-BY', size=124),
- 'cn': fields.char('CN', size=124),
- 'dir': fields.char('DIR', size=124),
- 'language': fields.char('LANGUAGE', size=124),
- }
- _defaults = {
- 'cn': lambda *x: 'MAILTO:',
- }
-
-crm_caldav_attendee()
-
-class crm_caldav_alarm(osv.osv):
- _name = 'crm.caldav.alarm'
- _description = 'Event alarm information'
-
- __attribute__ = {
- 'action': {'field': 'action', 'type': 'text'},
- 'description': {'field': 'name', 'type': 'text'},
- 'summary': {'field': 'description', 'type': 'text'},
- 'attendee': {'field': 'attendee_ids', 'type': 'text'},
- 'trigger_related': {'field': 'trigger_related', 'type': 'text'},
- 'trigger_duration': {'field': 'trigger_duration', 'type': 'text'},
- 'trigger_occurs': {'field': 'trigger_occurs', 'type': 'text'},
- 'trigger_interval': {'field': 'trigger_interval', 'type': 'text'},
- 'duration': {'field': 'duration', 'type': 'text'},
- 'repeat': {'field': 'repeat', 'type': 'text'},
- 'attach': {'field': 'attach', 'type': 'text'},
- }
-
- _columns = {
- 'name': fields.char('Summary', size=124),
- 'action': fields.selection([('AUDIO', 'AUDIO'), ('DISPLAY', 'DISPLAY'), \
- ('PROCEDURE', 'PROCEDURE'), ('EMAIL', 'EMAIL') ], 'Action', required=True),
- 'description': fields.text('Description'),
- 'attendee_ids': fields.many2many('crm.caldav.attendee', 'alarm_attendee_rel', \
- 'alarm_id', 'attendee_id', 'Attendees'),
- 'trigger_occurs': fields.selection([('BEFORE', 'BEFORE'), ('AFTER', 'AFTER')], \
- 'Trigger time', required=True),
- 'trigger_interval': fields.selection([('MINUTES', 'MINUTES'), ('HOURS', 'HOURS'), \
- ('DAYS', 'DAYS')], 'Trugger duration', required=True),
- 'trigger_duration': fields.integer('TIme', required=True),
- 'trigger_related': fields.selection([('start', 'The event starts'), ('end', \
- 'The event ends')], 'Trigger Occures at', required=True),
- 'duration': fields.integer('Duration'),
- 'repeat': fields.integer('Repeat'), # TODO
- 'attach': fields.binary('Attachment'),
- 'active': fields.boolean('Active'),
- }
-
- _defaults = {
- 'action': lambda *x: 'EMAIL',
- 'trigger_interval': lambda *x: 'MINUTES',
- 'trigger_duration': lambda *x: 5,
- 'trigger_occurs': lambda *x: 'BEFORE',
- 'trigger_related': lambda *x: 'start',
- }
-
-crm_caldav_alarm()
-
class project_task(osv.osv):
_inherit = "project.task"
@@ -155,24 +62,39 @@ class project_task(osv.osv):
__attribute__ = {
'class': {'field': 'class', 'type': 'text'},
'completed': {'field': 'date_close', 'type': 'datetime'},
+# 'created': {'field': 'field', 'type': 'text'},
'description': {'field': 'description', 'type': 'text'},
+# 'dtstamp': {'field': 'field', 'type': 'text'},
'dtstart': {'field': 'date_start', 'type': 'datetime'},
'duration': {'field': 'planned_hours', 'type': 'int'},
'due': {'field': 'date_deadline', 'type': 'datetime'},
+# 'geo': {'field': 'field', 'type': 'text'},
+# 'last-mod ': {'field': 'field', 'type': 'text'},
'location': {'field': 'location', 'type': 'text'}, # To add
'organizer': {'field': 'partner_id', 'type': 'many2one', 'object': 'res.partner'},
'percent': {'field': 'progress_rate', 'type': 'int'},
'priority': {'field': 'priority', 'type': 'text'},
+# 'recurid': {'field': 'field', 'type': 'text'},
'seq': {'field': 'sequence', 'type': 'text'},
'status': {'field': 'state', 'type': 'selection', 'mapping': {'NEEDS-ACTION': 'draft', \
'COMPLETED': 'done', 'IN-PROCESS': 'open', \
'CANCELLED': 'cancelled'}},
'summary': {'field': 'name', 'type': 'text'},
+ 'uid': {'field': 'id', 'type': 'int'},
'url': {'field': 'caldav_url', 'type': 'text'}, # To add
+# 'attach': {'field': 'field', 'type': 'text'},
'attendee': {'field': 'attendee_ids', 'type': 'many2many', 'object': 'crm.caldav.attendee'},
# 'categories': {'field': 'type', 'type': 'text'}, # Needs review
'comment': {'field': 'notes', 'type': 'text'},
+# 'contact': {'field': 'field', 'type': 'text'},
+# 'exdate': {'field': 'field', 'type': 'text'},
+# 'exrule': {'field': 'field', 'type': 'text'},
+# 'rstatus': {'field': 'field', 'type': 'text'},
+# 'related': {'field': 'field', 'type': 'text'},
+# 'resources': {'field': 'field', 'type': 'text'},
+# 'rdate': {'field': 'field', 'type': 'text'},
'rrule': {'field': 'rrule', 'type': 'text'},
+ 'valarm' : {'field':'alarm_id', 'type':'many2one', 'object' : 'crm.caldav.alarm'},
}
def import_cal(self, cr, uid, ids, data, context={}):
@@ -192,15 +114,40 @@ class project_task(osv.osv):
if not vals.has_key('duration'):
# 'Compute duration'
vals['planned_hours'] = 16
+# start = datetime.strptime(vals.get('date_start'), '%Y-%m-%d %H:%M:%S')
+# end = datetime.strptime(vals.get('date_deadline'), '%Y-%m-%d %H:%M:%S')
+# difference = float((end - start).seconds) / 3600
+## minutes, seconds = divmod(difference.seconds, 60)
+## hours, minutes = divmod(minutes, 60)
+ vals.pop('id')
task_id = self.create(cr, uid, vals)
return
+ def export_cal(self, cr, uid, ids, context={}):
+ task_data = self.read(cr, uid, ids, [], context ={'read': True})
+ todo_obj = self.pool.get('caldav.todo')
+ todo_obj.__attribute__.update(self.__attribute__)
+
+ attendee_obj = self.pool.get('caldav.attendee')
+ attendee = self.pool.get('crm.caldav.attendee')
+ attendee_obj.__attribute__.update(attendee.__attribute__)
+
+ alarm_obj = self.pool.get('caldav.alarm')
+ alarm = self.pool.get('crm.caldav.alarm')
+ alarm_obj.__attribute__.update(alarm.__attribute__)
+
+ ical = todo_obj.export_ical(cr, uid, task_data)
+ caendar_val = ical.serialize()
+ caendar_val = caendar_val.replace('"', '').strip()
+ return caendar_val
+
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
""" logic for recurrent task
example : 123-20091111170822""", ids, fields, context
if context and context.has_key('read'):
return super(project_task, self).read(cr, uid, ids, fields, context, load)
if not type(ids) == list :
+ # Called from code
return super(project_task, self).read(cr, uid, caldevIDs2readIDs(ids),\
fields=fields, context=context, load=load)
else:
@@ -227,107 +174,53 @@ class project_task(osv.osv):
for rdate in rdates:
import re
idval = (re.compile('\d')).findall(rdate)
- val['date'] = rdate
+ val['date_start'] = rdate
id = str(val['id']).split('-')[0]
val['id'] = id + '-' + ''.join(idval)
val1 = val.copy()
result += [val1]
return result
-
-project_task()
-
-class ir_attachment(osv.osv):
- _name = 'ir.attachment'
- _inherit = 'ir.attachment'
-
- def search_count(self, cr, user, args, context=None):
- args1 = []
- for arg in args:
- args1.append(map(lambda x:str(x).split('-')[0], arg))
- return super(ir_attachment, self).search_count(cr, user, args1, context)
-
def search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False):
- new_args = []
- if len(args) > 1:
- new_args = [args[0]]
- if args[1][0] == 'res_id':
- new_args.append((args[1][0], args[1][1], caldevIDs2readIDs(args[1][2])))
- if new_args:
- args = new_args
- return super(ir_attachment, self).search(cr, uid, args, offset=offset,
- limit=limit, order=order,
- context=context, count=False)
-ir_attachment()
-
-class ir_values(osv.osv):
- _inherit = 'ir.values'
-
- def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, \
- meta=False, preserve_user=False, company=False):
- new_model = []
- for data in models:
- if type(data) in (list, tuple):
- new_model.append((data[0], caldevIDs2readIDs(data[1])))
- else:
- new_model.append(data)
- return super(ir_values, self).set(cr, uid, key, key2, name, new_model, value, \
- replace, isobject, meta, preserve_user, company)
-
- def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, \
- without_user=True, key2_req=True):
- new_model = []
- for data in models:
- if type(data) in (list, tuple):
- new_model.append((data[0], caldevIDs2readIDs(data[1])))
- else:
- new_model.append(data)
- return super(ir_values, self).get(cr, uid, key, key2, new_model, meta, context, \
- res_id_req, without_user, key2_req)
-
-ir_values()
-
-class ir_model(osv.osv):
-
- _inherit = 'ir.model'
-
- def read(self, cr, uid, ids, fields=None, context={},
- load='_classic_read'):
- data = super(ir_model, self).read(cr, uid, ids, fields=fields, context=context, load=load)
- if data:
- for val in data:
- val['id'] = caldevIDs2readIDs(val['id'])
- return data
-
-ir_model()
-
-class virtual_report_spool(web_services.report_spool):
-
- def exp_report(self, db, uid, object, ids, datas=None, context=None):
- if object == 'printscreen.list':
- return super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context)
- new_ids = []
- for id in ids:
- new_ids.append(caldevIDs2readIDs(id))
- datas['id'] = caldevIDs2readIDs(datas['id'])
- super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
- return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
-
-virtual_report_spool()
-
-class virtual_wizard(web_services.wizard):
- def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
- if wiz_id not in self.wiz_uid:
- super(virtual_wizard,self).exp_create(db, uid, 'module.upgrade', datas)
- new_ids = []
- if 'id' in datas:
- datas['id'] = caldevIDs2readIDs(datas['id'])
- for id in datas['ids']:
- new_ids.append(caldevIDs2readIDs(id))
- datas['ids'] = new_ids
- res=super(virtual_wizard, self).exp_execute(db, uid, wiz_id, datas, action, context)
+ res = super(project_task, self).search(cr, uid, args, offset,
+ limit, order, context, count)
return res
-virtual_wizard()
+ def write(self, cr, uid, ids, vals, context=None):
+ new_ids = []
+ for id in ids:
+ id = caldevIDs2readIDs(id)
+ if not id in new_ids:
+ new_ids.append(id)
+ res = super(project_task, self).write(cr, uid, new_ids, vals, context=context)
+ return res
+
+ def browse(self, cr, uid, select, context=None, list_class=None, fields_process={}):
+ if not isinstance(select, list): select = [select]
+ select = map(lambda x:caldevIDs2readIDs(x), select)
+ return super(project_task, self).browse(cr, uid, select, context, list_class, fields_process)
+
+ def copy(self, cr, uid, id, default=None, context={}):
+ return super(project_task, self).copy(cr, uid, caldevIDs2readIDs(id), default, context)
+
+ def unlink(self, cr, uid, ids, context=None):
+ #TODO: Change RRULE
+ for id in ids:
+ if len(str(id).split('-')) > 1:
+ date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
+ time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
+ for record in self.read(cr, uid, [caldevIDs2readIDs(id)], ['date_start', 'rdates', 'rrule']):
+ if record['date_start'] == date_new:
+ self.write(cr, uid, [caldevIDs2readIDs(id)], \
+ {'rrule' : record['rrule'] +"\n" + str(date_new)})
+ else:
+ return super(project_task, self).unlink(cr, uid, ids)
+
+ def create(self, cr, uid, vals, context={}):
+ if 'case_id' in vals:
+ vals['case_id'] = caldevIDs2readIDs(vals['case_id'])
+ return super(project_task, self).create(cr, uid, vals, context)
+project_task()
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_calendar/project_calendar_wizard.xml b/addons/project_calendar/project_calendar_wizard.xml
index 9d3ea03ddda..190adce3ce8 100644
--- a/addons/project_calendar/project_calendar_wizard.xml
+++ b/addons/project_calendar/project_calendar_wizard.xml
@@ -4,5 +4,9 @@
name="caldav.project.import" id="wizard_project_cal_import"
multi="True"
/>
+
diff --git a/addons/project_calendar/security/ir.model.access.csv b/addons/project_calendar/security/ir.model.access.csv
deleted file mode 100644
index f65c32af108..00000000000
--- a/addons/project_calendar/security/ir.model.access.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
-"access_crm_caldav_attendee","crm.caldav.attendee","model_crm_caldav_attendee",,1,1,1,1
-"access_crm_caldav_alarm","crm.caldav.alarm","model_crm_caldav_alarm",,1,1,1,1
diff --git a/addons/project_calendar/wizard/__init__.py b/addons/project_calendar/wizard/__init__.py
index 030daa5cb83..009d377ad04 100644
--- a/addons/project_calendar/wizard/__init__.py
+++ b/addons/project_calendar/wizard/__init__.py
@@ -19,6 +19,7 @@
#
##############################################################################
+import wizard_cal_export
import wizard_cal_import
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/project_calendar/wizard/wizard_cal_export.py b/addons/project_calendar/wizard/wizard_cal_export.py
new file mode 100644
index 00000000000..600d80c9a05
--- /dev/null
+++ b/addons/project_calendar/wizard/wizard_cal_export.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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 .
+#
+##############################################################################
+
+import time
+import tools
+import wizard
+import os
+import mx.DateTime
+import base64
+import pooler
+import vobject
+
+
+class project_cal_export_wizard(wizard.interface):
+ form1 = '''
+ '''
+
+ form1_fields = {
+ 'file_path': {
+ 'string': 'Select ICS file',
+ 'type': 'binary',
+ 'required': True,
+ 'filters': '*.ics'
+ }
+ }
+
+ def _process_export_ics(self, cr, uid, data, context):
+ task_obj = pooler.get_pool(cr.dbname).get('project.task')
+ calendar = task_obj.export_cal(cr, uid, data['ids'], context)
+ return {'file_path': base64.encodestring(calendar)}
+
+ states = {
+ 'init': {
+ 'actions': [_process_export_ics],
+ 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, \
+ 'state': [('end', '_Cancel', 'gtk-cancel'), ('end', 'Ok', 'gtk-ok')]}
+ },
+ }
+
+project_cal_export_wizard('caldav.project.export')
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
From 1e4d933cbc36503a6caec7119a512201024d10c3 Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Fri, 18 Dec 2009 18:09:27 +0100
Subject: [PATCH 036/123] [FIX] Regression on global object
bzr revid: christophe.chauvet@syleam.fr-20091218170927-5m05rgb8rp09o21s
---
bin/addons/base/res/res_company.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/bin/addons/base/res/res_company.py b/bin/addons/base/res/res_company.py
index 70af44da6a4..b514e40b9fe 100644
--- a/bin/addons/base/res/res_company.py
+++ b/bin/addons/base/res/res_company.py
@@ -98,8 +98,11 @@ class res_company(osv.osv):
proxy = self.pool.get('multi_company.default')
args = [
('object_id.model', '=', object),
- ('field_id.name','=',field),
]
+ if field:
+ args.append(('field_id.name','=',field))
+ else:
+ args.append(('field_id','=',False))
ids = proxy.search(cr, uid, args)
for rule in proxy.browse(cr, uid, ids, context):
user = self.pool.get('res.users').browse(cr, uid, uid)
From 82d5e1c2dff76a32d4a7d0abbac605a5a1567c8f Mon Sep 17 00:00:00 2001
From: Launchpad Code Hosting
Date: Mon, 21 Dec 2009 04:43:09 +0000
Subject: [PATCH 037/123] Launchpad automatic translations update.
bzr revid: codehost@crowberry-20091219043315-nxro2ufs7qwa3ldl
bzr revid: codehost@crowberry-20091220043549-tedq3hfaca2elaka
bzr revid: codehost@crowberry-20091221044309-jdhl84asvzyjjuw2
---
bin/addons/base/i18n/he.po | 20 +++++-
bin/addons/base/i18n/lv.po | 22 +++++--
bin/addons/base/i18n/nl.po | 41 +++++++++++--
bin/addons/base/i18n/pt.po | 39 ++++++++++--
bin/addons/base/i18n/ro.po | 123 ++++++++++++++++++++++---------------
debian/po/ro.po | 42 +++++++++++++
6 files changed, 222 insertions(+), 65 deletions(-)
create mode 100644 debian/po/ro.po
diff --git a/bin/addons/base/i18n/he.po b/bin/addons/base/i18n/he.po
index a320a211ae1..27cfa03c14e 100644
--- a/bin/addons/base/i18n/he.po
+++ b/bin/addons/base/i18n/he.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-12-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-17 09:51+0000\n"
+"PO-Revision-Date: 2009-12-18 17:51+0000\n"
"Last-Translator: Ddorda \n"
"Language-Team: Hebrew \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -1002,7 +1002,21 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !"
+"Model %s Does not Exist !\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/lv.po b/bin/addons/base/i18n/lv.po
index 62d942d51ba..bacf9e66fb4 100644
--- a/bin/addons/base/i18n/lv.po
+++ b/bin/addons/base/i18n/lv.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-12-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-17 07:02+0000\n"
-"Last-Translator: Normunds \n"
+"PO-Revision-Date: 2009-12-18 17:53+0000\n"
+"Last-Translator: Fabien (Open ERP) \n"
"Language-Team: Latvian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -1008,7 +1008,21 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !"
+"Model %s Does not Exist !\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/nl.po b/bin/addons/base/i18n/nl.po
index b89949b0067..bef8dede540 100644
--- a/bin/addons/base/i18n/nl.po
+++ b/bin/addons/base/i18n/nl.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-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-16 08:24+0000\n"
-"Last-Translator: Pieter J. Kersten (EduSense BV) \n"
+"PO-Revision-Date: 2009-12-19 06:26+0000\n"
+"Last-Translator: mra (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: 2009-12-17 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -1011,9 +1011,37 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !"
+"Model %s Does not Exist !\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
msgstr ""
-"Model %s bestaat niet !"
+"Model %s bestaat niet !\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
#. module: base
#: code:addons/base/module/module.py:0
@@ -8103,3 +8131,6 @@ msgstr "Sri Lanka"
#: selection:module.lang.install,init,lang:0
msgid "Russian / русский язык"
msgstr "Russisch / русский язык"
+
+#~ msgid "Model %s Does not Exist !"
+#~ msgstr "Model %s bestaat niet !"
diff --git a/bin/addons/base/i18n/pt.po b/bin/addons/base/i18n/pt.po
index 537e8197a29..bafef8ae13e 100644
--- a/bin/addons/base/i18n/pt.po
+++ b/bin/addons/base/i18n/pt.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-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-13 06:37+0000\n"
+"PO-Revision-Date: 2009-12-19 06:22+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: 2009-12-15 05:02+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -1007,9 +1007,37 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !"
+"Model %s Does not Exist !\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
msgstr ""
-"O modelo %s não existe!"
+"O modelo %s não existe!\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
#. module: base
#: code:addons/base/module/module.py:0
@@ -8119,3 +8147,6 @@ msgstr "Russo / русский язык"
#, python-format
#~ msgid "The unlink method is not implemented on this object !"
#~ msgstr "O método remover (unlink) não está implementado neste objecto!"
+
+#~ msgid "Model %s Does not Exist !"
+#~ msgstr "O modelo %s não existe!"
diff --git a/bin/addons/base/i18n/ro.po b/bin/addons/base/i18n/ro.po
index 309fecbb1a6..77c39d2300d 100644
--- a/bin/addons/base/i18n/ro.po
+++ b/bin/addons/base/i18n/ro.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-12-09 10:13+0000\n"
-"PO-Revision-Date: 2009-11-30 08:49+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-20 16:39+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: 2009-12-15 05:02+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
#: model:res.country,name:base.sh
msgid "Saint Helena"
-msgstr ""
+msgstr "Sfanta Elena"
#. module: base
#: wizard_view:res.partner.sms_send,init:0
@@ -29,71 +29,72 @@ msgstr "SMS - Gateway: clickatell"
#. module: base
#: view:res.lang:0
msgid "%j - Day of the year as a decimal number [001,366]."
-msgstr ""
+msgstr "%j - Ziua anului ca numar zecimal [001,366]"
#. module: base
#: field:ir.values,meta_unpickle:0
msgid "Metadata"
-msgstr ""
+msgstr "Metadata"
#. module: base
#: field:ir.ui.view,arch:0
#: field:ir.ui.view.custom,arch:0
msgid "View Architecture"
-msgstr "Architectura vederii (view)"
+msgstr "Alcatuirea afisarii"
#. module: base
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid "You can not create this kind of document! (%s)"
-msgstr ""
+msgstr "Nu puteti crea acest tip de document! (%s)"
#. module: base
#: wizard_field:module.lang.import,init,code:0
msgid "Code (eg:en__US)"
-msgstr ""
+msgstr "Cod (eg:en__US)"
#. module: base
#: view:workflow:0
#: field:workflow.activity,wkf_id:0
#: field:workflow.instance,wkf_id:0
msgid "Workflow"
-msgstr "Workflow"
+msgstr "Flux"
#. module: base
#: view:wizard.module.lang.export:0
msgid "To browse official translations, you can visit this link: "
msgstr ""
+"Pentru a naviga printre traducerile oficiale, puteti vizita acest link: "
#. module: base
#: selection:module.lang.install,init,lang:0
msgid "Hungarian / Magyar"
-msgstr ""
+msgstr "Maghiara / Magyar"
#. module: base
#: field:ir.actions.server,wkf_model_id:0
msgid "Workflow On"
-msgstr ""
+msgstr "Activare Flux"
#. module: base
#: view:ir.module.module:0
msgid "Created Views"
-msgstr ""
+msgstr "Afisari Create"
#. module: base
#: view:workflow.activity:0
msgid "Outgoing transitions"
-msgstr ""
+msgstr "Tranzitii iesire"
#. module: base
#: selection:ir.report.custom,frequency:0
msgid "Yearly"
-msgstr ""
+msgstr "Anual"
#. module: base
#: field:ir.actions.act_window,target:0
msgid "Target Window"
-msgstr ""
+msgstr "Fereastra tinta"
#. module: base
#: model:ir.actions.todo,note:base.config_wizard_simple_view
@@ -106,102 +107,108 @@ msgid ""
"understand. You will be able to switch to the extended view later.\n"
" "
msgstr ""
+"Alegeti intre \"Interfata Simplificata\" sau cea extinsa.\n"
+"Daca utilizati pentru prima data, sau doriti sa testati OpenERP\n"
+"pentru prima data, va sugeram sa folositi Interfata Simplificata,\n"
+"care are mai putine optiuni si campuri, dar este mult mai usor de inteles.\n"
+"Puteti sa schimbati mai tarziu in cea extinsa.\n"
+" "
#. module: base
#: field:ir.rule,operand:0
msgid "Operand"
-msgstr ""
+msgstr "Operand"
#. module: base
#: model:res.country,name:base.kr
msgid "South Korea"
-msgstr ""
+msgstr "Coreea de Sud"
#. module: base
#: model:ir.actions.act_window,name:base.action_workflow_transition_form
#: model:ir.ui.menu,name:base.menu_workflow_transition
#: view:workflow.activity:0
msgid "Transitions"
-msgstr ""
+msgstr "Tranzitii"
#. module: base
#: model:ir.model,name:base.model_ir_ui_view_custom
msgid "ir.ui.view.custom"
-msgstr ""
+msgstr "ir.ui.view.custom"
#. module: base
#: model:res.country,name:base.sz
msgid "Swaziland"
-msgstr ""
+msgstr "Elvetia"
#. module: base
#: model:ir.model,name:base.model_ir_actions_report_custom
#: selection:ir.ui.menu,action:0
msgid "ir.actions.report.custom"
-msgstr ""
+msgstr "ir.actions.report.custom"
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_CANCEL"
-msgstr ""
+msgstr "STOCK_CANCEL"
#. module: base
#: field:ir.report.custom,sortby:0
msgid "Sorted By"
-msgstr "Sorteaza"
+msgstr "Sortat dupa"
#. module: base
#: field:ir.sequence,number_increment:0
msgid "Increment Number"
-msgstr "Incrementare numar"
+msgstr "Increment"
#. module: base
#: model:ir.actions.act_window,name:base.action_res_company_tree
#: model:ir.ui.menu,name:base.menu_action_res_company_tree
msgid "Company's Structure"
-msgstr ""
+msgstr "Structura Companiei"
#. module: base
#: model:ir.model,name:base.model_ir_report_custom_fields
msgid "ir.report.custom.fields"
-msgstr ""
+msgstr "ir.report.custom.fields"
#. module: base
#: view:res.partner:0
msgid "Search Partner"
-msgstr ""
+msgstr "Cautare Partener"
#. module: base
#: code:addons/base/module/wizard/wizard_export_lang.py:0
#, python-format
msgid "new"
-msgstr ""
+msgstr "nou"
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_GOTO_TOP"
-msgstr ""
+msgstr "STOCK_GOTO_TOP"
#. module: base
#: field:ir.actions.report.custom,multi:0
#: field:ir.actions.report.xml,multi:0
msgid "On multiple doc."
-msgstr ""
+msgstr "In documente multiple"
#. module: base
#: field:ir.module.category,module_nr:0
msgid "Number of Modules"
-msgstr ""
+msgstr "Numar de Module"
#. module: base
#: help:multi_company.default,company_dest_id:0
msgid "Company to store the current record"
-msgstr ""
+msgstr "Compania unde se face inregistrarea"
#. module: base
#: field:res.partner.bank.type.field,size:0
msgid "Max. Size"
-msgstr ""
+msgstr "Dimensiunea Maxima"
#. module: base
#: field:res.partner.address,name:0
@@ -215,86 +222,90 @@ msgid ""
"Save this document to a %s file and edit it with a specific software or a "
"text editor. The file encoding is UTF-8."
msgstr ""
+"Salvati acest document intr-un fisier %s si editati-l cu un soft adecvat sau "
+"un editor de text. Folositi codarea UTF-8."
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_DELETE"
-msgstr ""
+msgstr "STOCK_DELETE"
#. module: base
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid "Password mismatch !"
-msgstr ""
+msgstr "Parola este gresita!"
#. module: base
#: code:addons/base/module/module.py:0
#, python-format
msgid "This url '%s' must provide an html file with links to zip modules"
msgstr ""
+"Acest url '%s' trebuie sa duca la un fisier html cu legaturi catre module in "
+"format zip"
#. module: base
#: selection:res.request,state:0
msgid "active"
-msgstr ""
+msgstr "activ"
#. module: base
#: field:ir.actions.wizard,wiz_name:0
msgid "Wizard Name"
-msgstr ""
+msgstr "Nume Asistent"
#. module: base
#: view:res.lang:0
msgid "%y - Year without century as a decimal number [00,99]."
-msgstr ""
+msgstr "%y - An fara secol ca numar zecimal [00,99]."
#. module: base
#: selection:ir.ui.menu,icon:0
msgid "STOCK_GOTO_FIRST"
-msgstr ""
+msgstr "STOCK_GOTO_FIRST"
#. module: base
#: help:ir.rule.group,rules:0
msgid "The rule is satisfied if at least one test is True"
-msgstr ""
+msgstr "Regula este satisfacuta daca cel putin un test este Adevarat"
#. module: base
#: selection:ir.report.custom.fields,operation:0
msgid "Get Max"
-msgstr ""
+msgstr "Incarca Max"
#. module: base
#: help:ir.actions.act_window,limit:0
msgid "Default limit for the list view"
-msgstr ""
+msgstr "Limita implicita pentru Vizualizare Lista"
#. module: base
#: field:ir.model.data,date_update:0
msgid "Update Date"
-msgstr ""
+msgstr "Data Actualizare"
#. module: base
#: field:ir.actions.act_window,src_model:0
msgid "Source Object"
-msgstr ""
+msgstr "Obiect Sursa"
#. module: base
#: model:ir.actions.act_window,name:base.act_ir_actions_todo_form
#: view:ir.actions.todo:0
#: model:ir.ui.menu,name:base.menu_ir_actions_todo_form
msgid "Config Wizard Steps"
-msgstr ""
+msgstr "Configurare Pasi Asistare"
#. module: base
#: model:ir.model,name:base.model_ir_ui_view_sc
msgid "ir.ui.view_sc"
-msgstr ""
+msgstr "ir.ui.view_sc"
#. module: base
#: field:ir.model.access,group_id:0
#: field:ir.rule,rule_group:0
msgid "Group"
-msgstr ""
+msgstr "Grup"
#. module: base
#: field:ir.exports.line,name:0
@@ -984,7 +995,21 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !"
+"Model %s Does not Exist !\" % vals['relation']))\n"
+" \n"
+" if self.pool.get(vals['model']):\n"
+" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
+" self.pool.get(vals['model'])._auto_init(cr, {})\n"
+" \n"
+" return res\n"
+"ir_model_fields()\n"
+"\n"
+"class ir_model_access(osv.osv):\n"
+" _name = 'ir.model.access'\n"
+" _columns = {\n"
+" 'name': fields.char('Name', size=64, required=True),\n"
+" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
+" 'group_id': fields.many2one('res.groups', 'Group"
msgstr ""
#. module: base
diff --git a/debian/po/ro.po b/debian/po/ro.po
new file mode 100644
index 00000000000..e24cc887fd6
--- /dev/null
+++ b/debian/po/ro.po
@@ -0,0 +1,42 @@
+# Romanian translation for openobject-server
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the openobject-server package.
+# FIRST AUTHOR , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-server\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2009-08-24 22:41+0300\n"
+"PO-Revision-Date: 2009-12-20 09:24+0000\n"
+"Last-Translator: Valentin Caragea \n"
+"Language-Team: Romanian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#. Type: string
+#. Description
+#: ../openerp-server.templates:1001
+msgid "Dedicated system account for the Open ERP server:"
+msgstr "Contul sistem dedicat serverului Open ERP"
+
+#. Type: string
+#. Description
+#: ../openerp-server.templates:1001
+msgid ""
+"The Open ERP server must use a dedicated account for its operation so that "
+"the system's security is not compromised by running it with superuser "
+"privileges."
+msgstr ""
+"Serverul Open ERP trebuie sa utilizeze un cont dedicat operatiilor sale "
+"astfel incat sa nu fie compromisa securitatea sistemului prin rularea cu "
+"privilegii de root"
+
+#. Type: string
+#. Description
+#: ../openerp-server.templates:1001
+msgid "Please choose that account's username."
+msgstr "Alege numele utilizatorului (username)"
From 225c229780727660960090e33083cfe3919bb6d3 Mon Sep 17 00:00:00 2001
From: Launchpad Code Hosting
Date: Mon, 21 Dec 2009 04:43:37 +0000
Subject: [PATCH 038/123] Launchpad automatic translations update.
bzr revid: codehost@crowberry-20091219043342-g6yxefj169bgeka3
bzr revid: codehost@crowberry-20091220043618-ahq2v3u2j5al90n1
bzr revid: codehost@crowberry-20091221044337-amjdbdasgxnofbfi
---
addons/account/i18n/ar.po | 16 +-
addons/account/i18n/bg.po | 2 +-
addons/account/i18n/fi.po | 10 +-
addons/account/i18n/lv.po | 101 +++---
addons/account/i18n/ru.po | 8 +-
addons/account_analytic_default/i18n/hr.po | 18 +-
addons/account_reporting/i18n/el.po | 94 +++---
addons/board_account/i18n/el.po | 12 +-
addons/board_sale/i18n/el.po | 8 +-
addons/crm/i18n/el.po | 30 +-
addons/crm_configuration/i18n/el.po | 24 +-
addons/document/i18n/hr.po | 174 ++++++-----
addons/document_ics/i18n/hr.po | 120 ++++----
addons/document_webdav/i18n/hr.po | 31 ++
addons/google_map/i18n/hr.po | 17 +-
addons/hr_holidays/i18n/el.po | 12 +-
addons/hr_holidays/i18n/zh_CN.po | 72 ++---
addons/hr_timesheet/i18n/el.po | 38 +--
addons/hr_timesheet_invoice/i18n/el.po | 10 +-
addons/idea/i18n/ar.po | 130 ++++----
addons/multi_company/i18n/zh_CN.po | 192 ++++++++++++
addons/product/i18n/ar.po | 63 ++--
addons/product/i18n/zh_CN.po | 38 +--
addons/profile_service/i18n/zh_CN.po | 34 ++-
addons/project_mrp/i18n/zh_CN.po | 10 +-
addons/purchase/i18n/zh_CN.po | 104 +++----
addons/report_analytic/i18n/el.po | 8 +-
addons/report_crm/i18n/el.po | 339 +++++++++++++++++++++
addons/report_purchase/i18n/el.po | 206 +++++++++++++
addons/report_timesheet/i18n/zh_CN.po | 14 +-
addons/scrum/i18n/ca.po | 13 +-
addons/scrum/i18n/es.po | 11 +-
addons/stock/i18n/zh_CN.po | 14 +-
33 files changed, 1406 insertions(+), 567 deletions(-)
create mode 100644 addons/document_webdav/i18n/hr.po
create mode 100644 addons/multi_company/i18n/zh_CN.po
create mode 100644 addons/report_crm/i18n/el.po
create mode 100644 addons/report_purchase/i18n/el.po
diff --git a/addons/account/i18n/ar.po b/addons/account/i18n/ar.po
index b016cbe7468..2dcf62a1dbb 100644
--- a/addons/account/i18n/ar.po
+++ b/addons/account/i18n/ar.po
@@ -7,35 +7,35 @@ 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-10-09 08:32+0000\n"
-"Last-Translator: Jay (Open ERP) \n"
+"PO-Revision-Date: 2009-12-20 12:49+0000\n"
+"Last-Translator: Hend Awad \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: 2009-12-16 05:10+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
#: field:account.tax.template,description:0
msgid "Internal Name"
-msgstr ""
+msgstr "اسم داخلي"
#. module: account
#: view:account.tax.code:0
msgid "Account Tax Code"
-msgstr ""
+msgstr "كود الحساب الضريبي"
#. module: account
#: model:ir.actions.act_window,name:account.action_invoice_tree9
#: model:ir.ui.menu,name:account.menu_action_invoice_tree9
msgid "Unpaid Supplier Invoices"
-msgstr ""
+msgstr "فواتير الموردين الغير مدفوعة"
#. module: account
#: model:ir.ui.menu,name:account.menu_finance_entries
msgid "Entries Encoding"
-msgstr ""
+msgstr "تشفير المدخلات"
#. module: account
#: model:ir.actions.todo,note:account.config_wizard_account_base_setup_form
@@ -50,7 +50,7 @@ msgstr ""
#. module: account
#: model:account.account.type,name:account.account_type_asset
msgid "Asset"
-msgstr ""
+msgstr "أصل"
#. module: account
#: constraint:ir.actions.act_window:0
diff --git a/addons/account/i18n/bg.po b/addons/account/i18n/bg.po
index f83bee3fc8a..82f383117ef 100644
--- a/addons/account/i18n/bg.po
+++ b/addons/account/i18n/bg.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-18 04:32+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
diff --git a/addons/account/i18n/fi.po b/addons/account/i18n/fi.po
index 1dd7b1df654..2186fea139f 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: 2009-12-11 08:18+0000\n"
-"Last-Translator: NightSpirit \n"
+"PO-Revision-Date: 2009-12-19 13:33+0000\n"
+"Last-Translator: Omar Bedretdin \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: 2009-12-16 05:11+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -461,12 +461,12 @@ msgstr "Maksamattomat toimittajan korvaukset"
#: view:account.tax:0
#: view:account.tax.template:0
msgid "Special Computation"
-msgstr "Erikois laskenta"
+msgstr "Erikoislaskenta"
#. module: account
#: model:process.transition,note:account.process_transition_confirmstatementfromdraft0
msgid "Confirm statement with/without reconciliation from draft statement"
-msgstr "Hyväksy lause sovituksen kanssa tai ilman luonnostiliotteesta"
+msgstr "Vahvista ote käsin kirjaten luonnosotteesta tai automaattisesti"
#. module: account
#: wizard_view:account.move.bank.reconcile,init:0
diff --git a/addons/account/i18n/lv.po b/addons/account/i18n/lv.po
index f4e1b013b10..9fe80ce3fd3 100644
--- a/addons/account/i18n/lv.po
+++ b/addons/account/i18n/lv.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-11-18 06:21+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-19 12:50+0000\n"
+"Last-Translator: Normunds \n"
"Language-Team: Latvian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:12+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -25,7 +25,7 @@ msgstr "Iekšējais Nosaukums"
#. module: account
#: view:account.tax.code:0
msgid "Account Tax Code"
-msgstr ""
+msgstr "Konta Nodokļa Kods"
#. module: account
#: model:ir.actions.act_window,name:account.action_invoice_tree9
@@ -41,12 +41,12 @@ msgstr "Rindu Ievade"
#. module: account
#: model:ir.actions.todo,note:account.config_wizard_account_base_setup_form
msgid "Specify The Message for the Overdue Payment Report."
-msgstr ""
+msgstr "Paziņojums, par kavētiem maksājumiem."
#. module: account
#: model:process.transition,name:account.process_transition_confirmstatementfromdraft0
msgid "Confirm statement from draft"
-msgstr ""
+msgstr "Apstiprināt melnraksta pārskatu"
#. module: account
#: model:account.account.type,name:account.account_type_asset
@@ -56,12 +56,12 @@ msgstr "Aktīvi"
#. module: account
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Procesa definīcijā nepareizs modeļa nosaukums."
#. module: account
#: help:account.journal,currency:0
msgid "The currency used to enter statement"
-msgstr ""
+msgstr "Atskaitē lietotā vaūta"
#. module: account
#: wizard_view:account_use_models,init_form:0
@@ -79,7 +79,7 @@ msgstr ""
#. module: account
#: help:account.invoice,period_id:0
msgid "Keep empty to use the period of the validation(invoice) date."
-msgstr ""
+msgstr "Atstāt tukšu lai tiktu izmantots rēķina apstiprināšanas datums."
#. module: account
#: wizard_view:account.automatic.reconcile,reconcile:0
@@ -197,7 +197,7 @@ msgstr "Ieraksta iezīme"
#. module: account
#: model:ir.model,name:account.model_account_model_line
msgid "Account Model Entries"
-msgstr ""
+msgstr "Tipveida ieraksti"
#. module: account
#: field:account.tax.code,sum_period:0
@@ -269,6 +269,10 @@ msgid ""
"in which order. You can create your own view for a faster encoding in each "
"journal."
msgstr ""
+"Tiek piedāvāts skatījums- rakstot vai pārskatot žurnāla ierakstus. Skatījums "
+"nosaka, kuri lauki būs redzami vai nepieciešami, to kārtību un vai tajos var "
+"ievadīt informāciju. Var veidot savus skatījumus ātrākai informācijas "
+"ievadei katram žurnālam."
#. module: account
#: help:account.invoice,date_due:0
@@ -279,6 +283,11 @@ msgid ""
"date empty, it means direct payment. The payment term may compute several "
"due dates, for example 50% now, 50% in one month."
msgstr ""
+"Ja tiek izmantoti apmaksas noteikumi, tad apmaksas termiņš tiks aprēķināts "
+"automātiski, ģenerējot grāmatvedības ierakstus. Ja apmaksas noteikumi un "
+"termiņš tiek atstāti neaizpildīti, tad tas tiek uzskatīts par tiešo "
+"maksājumu. Apmaksas noteikumi var saturēt vairākus apmaksas termiņus, "
+"piemēram, 50% tagad, 50% mēneša laikā."
#. module: account
#: selection:account.tax,type:0
@@ -290,7 +299,7 @@ msgstr "Fiksēts"
#: model:ir.actions.report.xml,name:account.account_overdue
#: view:res.company:0
msgid "Overdue Payments"
-msgstr ""
+msgstr "Kavētie Maksājumi"
#. module: account
#: wizard_view:account.account.balance.report,checktype:0
@@ -339,7 +348,7 @@ msgstr "Delta debets"
#: field:account.invoice,amount_tax:0
#: field:account.move.line,account_tax_id:0
msgid "Tax"
-msgstr ""
+msgstr "Nodoklis"
#. module: account
#: rml:account.general.journal:0
@@ -375,7 +384,7 @@ msgstr "Apraksts uz rēķiniem"
#. module: account
#: constraint:account.analytic.account:0
msgid "Error! You can not create recursive analytic accounts."
-msgstr ""
+msgstr "Kļūda! Nevar veidot rekursīvus analītiskos kontus."
#. module: account
#: field:account.bank.statement.reconcile,total_entry:0
@@ -402,7 +411,7 @@ msgstr "Maksājumu Sasaiste"
#. module: account
#: model:account.journal,name:account.expenses_journal
msgid "Journal de frais"
-msgstr ""
+msgstr "Izdevumu Žurnāls"
#. module: account
#: model:ir.actions.act_window,name:account.act_acc_analytic_acc_5_report_hr_timesheet_invoice_journal
@@ -422,7 +431,7 @@ msgstr "Negatīvs"
#. module: account
#: rml:account.partner.balance:0
msgid "(Account/Partner) Name"
-msgstr ""
+msgstr "(Konts/Klients) Nosaukums"
#. module: account
#: selection:account.move,type:0
@@ -443,7 +452,7 @@ msgstr "Statuss"
#: model:ir.actions.act_window,name:account.action_invoice_tree13
#: model:ir.ui.menu,name:account.menu_action_invoice_tree13
msgid "Unpaid Supplier Refunds"
-msgstr ""
+msgstr "Neapmaksātie Piegādātāja atgrieztie maksājumi"
#. module: account
#: view:account.tax:0
@@ -466,7 +475,7 @@ msgstr "Bankas sasaiste"
#. module: account
#: rml:account.invoice:0
msgid "Disc.(%)"
-msgstr ""
+msgstr "Atlaide %"
#. module: account
#: rml:account.general.ledger:0
@@ -475,12 +484,12 @@ msgstr ""
#: rml:account.overdue:0
#: field:account.subscription,ref:0
msgid "Ref"
-msgstr ""
+msgstr "Norāde"
#. module: account
#: field:account.tax.template,type_tax_use:0
msgid "Tax Use In"
-msgstr ""
+msgstr "Nodokļa lietojums"
#. module: account
#: help:account.tax.template,include_base_amount:0
@@ -488,6 +497,8 @@ msgid ""
"Set if the amount of tax must be included in the base amount before "
"computing the next taxes."
msgstr ""
+"Norādīt, lai nodoklis tiktu ieskaitīts bāzes summā, pirms tiek aprēķināti "
+"citi nodokļi."
#. module: account
#: model:ir.ui.menu,name:account.menu_finance_periodical_processing
@@ -497,13 +508,13 @@ msgstr "Periodiskās Darbības"
#. module: account
#: view:report.hr.timesheet.invoice.journal:0
msgid "Analytic Entries Stats"
-msgstr ""
+msgstr "Analītisko Ierakstu Tabula"
#. module: account
#: 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 ""
+msgstr "Nodokļu Kodu Šabloni"
#. module: account
#: view:account.invoice:0
@@ -514,18 +525,18 @@ msgstr "Piegādātāja rēķins"
#: model:process.transition,name:account.process_transition_reconcilepaid0
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
msgid "Reconcile Paid"
-msgstr ""
+msgstr "Atzīmēt kā Samaksāts."
#. module: account
#: wizard_field:account.chart,init,target_move:0
msgid "Target Moves"
-msgstr ""
+msgstr "Mērķa Grāmatojumi"
#. module: account
#: 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 ""
+msgstr "Nodokļu Šabloni"
#. module: account
#: field:account.invoice,reconciled:0
@@ -535,7 +546,7 @@ msgstr "Apmaksāts / Sasaistīts"
#. module: account
#: field:account.account.type,close_method:0
msgid "Deferral Method"
-msgstr ""
+msgstr "Atliktā maksājuma Metode"
#. module: account
#: field:account.tax.template,include_base_amount:0
@@ -562,7 +573,7 @@ msgstr ""
#: selection:account.tax,applicable_type:0
#: selection:account.tax.template,applicable_type:0
msgid "True"
-msgstr ""
+msgstr "Jā"
#. module: account
#: help:account.payment.term.line,days:0
@@ -608,7 +619,7 @@ msgstr ""
#: wizard_view:account.analytic.account.chart,init:0
#: wizard_view:account.analytic.line,init:0
msgid "(Keep empty to open the current situation)"
-msgstr ""
+msgstr "(Atstāt tukšu, lai atvērtu esošo stāvokli)"
#. module: account
#: model:ir.model,name:account.model_account_fiscal_position_account
@@ -645,17 +656,17 @@ msgstr "Atlaide (%)"
#: 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 ""
+msgstr "Norakstīt Daudzumu"
#. module: account
#: help:account.fiscalyear,company_id:0
msgid "Keep empty if the fiscal year belongs to several companies."
-msgstr ""
+msgstr "Atstāt tukšu, ja Fiskālais gads attiecas uz vairākiem uzņēmumiem."
#. module: account
#: model:ir.ui.menu,name:account.menu_analytic_accounting
msgid "Analytic Accounting"
-msgstr ""
+msgstr "Analītiskā Uzskaite"
#. module: account
#: rml:account.overdue:0
@@ -673,7 +684,7 @@ msgstr "Analītiskie Ieraksti"
#. module: account
#: selection:account.subscription,period_type:0
msgid "month"
-msgstr ""
+msgstr "mēnesis"
#. module: account
#: field:account.analytic.account,partner_id:0
@@ -688,12 +699,12 @@ msgstr "Papildus Informācija"
#. module: account
#: selection:account.invoice,type:0
msgid "Customer Refund"
-msgstr ""
+msgstr "Atgrieztie maksājumi Klientiem"
#. module: account
#: wizard_view:account.analytic.account.chart,init:0
msgid "Select the Period for Analysis"
-msgstr ""
+msgstr "Izvēlēties Analīzes periodu"
#. module: account
#: field:account.tax,ref_tax_sign:0
@@ -706,7 +717,7 @@ msgstr ""
#. module: account
#: help:res.partner,credit:0
msgid "Total amount this customer owes you."
-msgstr ""
+msgstr "Kopējais daudzums, ko klients ir parādā."
#. module: account
#: view:account.move.line:0
@@ -721,7 +732,7 @@ msgstr "account.move.line"
#. module: account
#: model:process.transition,name:account.process_transition_supplieranalyticcost0
msgid "Analytic Invoice"
-msgstr ""
+msgstr "Analītiskais Rēķins"
#. module: account
#: field:account.journal.column,field:0
@@ -743,12 +754,12 @@ msgstr ""
#: view:product.product:0
#: view:product.template:0
msgid "Purchase Properties"
-msgstr ""
+msgstr "Iepirkuma Parametri"
#. module: account
#: model:process.node,note:account.process_node_paymententries0
msgid "Can be draft or validated"
-msgstr ""
+msgstr "Var būt melnrakstā, vai apstiprināts"
#. module: account
#: wizard_button:account.invoice.pay,init,reconcile:0
@@ -768,13 +779,13 @@ msgstr "Grāmatojumi Veikti."
#: field:account.period,state:0
#: field:account.subscription,state:0
msgid "Status"
-msgstr ""
+msgstr "Stāvoklis"
#. module: account
#: rml:account.analytic.account.cost_ledger:0
#: rml:account.analytic.account.quantity_cost_ledger:0
msgid "Period to"
-msgstr ""
+msgstr "Periods līdz"
#. module: account
#: field:account.account.type,partner_account:0
@@ -784,7 +795,7 @@ msgstr "Partnera konts"
#. module: account
#: wizard_view:account.subscription.generate,init:0
msgid "Generate entries before:"
-msgstr ""
+msgstr "Ģenerēt ierakstus pirms:"
#. module: account
#: rml:account.analytic.account.cost_ledger:0
@@ -800,7 +811,7 @@ msgstr ""
#: 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 ""
+msgstr "(Atstāt tukšu visiem nenoslēgtajiem fiskālajiem gadiem)"
#. module: account
#: field:account.invoice,move_lines:0
@@ -838,7 +849,7 @@ msgstr "Bankas Sasaiste"
#. module: account
#: model:ir.model,name:account.model_account_account_template
msgid "Templates for Accounts"
-msgstr ""
+msgstr "Kontu Šabloni"
#. module: account
#: model:ir.actions.act_window,name:account.action_account_analytic_account_form
@@ -912,12 +923,12 @@ msgstr ""
#. module: account
#: wizard_field:account.open_closed_fiscalyear,init,fyear_id:0
msgid "Fiscal Year to Open"
-msgstr ""
+msgstr "Atvērt Fiskālo gadu"
#. module: account
#: view:account.config.wizard:0
msgid "Select Chart of Accounts"
-msgstr ""
+msgstr "Izvēlēties Kontu Plānu"
#. module: account
#: field:account.analytic.account,quantity:0
@@ -948,7 +959,7 @@ msgstr ""
#. module: account
#: help:account.journal,user_id:0
msgid "The user responsible for this journal"
-msgstr ""
+msgstr "Atbildīgais par žurnālu."
#. module: account
#: field:account.journal,default_debit_account_id:0
diff --git a/addons/account/i18n/ru.po b/addons/account/i18n/ru.po
index 790fb9f3a06..0328d6e1681 100644
--- a/addons/account/i18n/ru.po
+++ b/addons/account/i18n/ru.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-12-16 08:27+0000\n"
-"Last-Translator: Casufi \n"
+"PO-Revision-Date: 2009-12-18 20:11+0000\n"
+"Last-Translator: Andrei Andreyanau \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: 2009-12-17 04:44+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account
@@ -220,7 +220,7 @@ msgstr "Проводка по счету"
#. module: account
#: wizard_view:account.aged.trial.balance,init:0
msgid "Aged Trial Balance"
-msgstr ""
+msgstr "Возрастной пробный баланс"
#. module: account
#: model:ir.ui.menu,name:account.menu_finance_recurrent_entries
diff --git a/addons/account_analytic_default/i18n/hr.po b/addons/account_analytic_default/i18n/hr.po
index 6112fb8e036..9356d0d43ee 100644
--- a/addons/account_analytic_default/i18n/hr.po
+++ b/addons/account_analytic_default/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-17 09:38+0000\n"
-"Last-Translator: dzuvela \n"
+"PO-Revision-Date: 2009-12-21 01:11+0000\n"
+"Last-Translator: Jožek Prikratki \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: 2009-12-16 05:18+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_analytic_default
@@ -21,12 +21,12 @@ msgstr ""
#: model:ir.actions.act_window,name:account_analytic_default.action_analytic_default_form
#: model:ir.ui.menu,name:account_analytic_default.menu_analytic_defaul_form
msgid "Analytic Defaults"
-msgstr ""
+msgstr "Uobičajene postavke analitike"
#. module: account_analytic_default
#: model:ir.module.module,shortdesc:account_analytic_default.module_meta_information
msgid "Account Analytic Default"
-msgstr ""
+msgstr "Uobičajene postavke analize računa"
#. module: account_analytic_default
#: constraint:ir.ui.view:0
@@ -43,7 +43,7 @@ msgstr ""
#. module: account_analytic_default
#: view:account.analytic.default:0
msgid "Seq"
-msgstr ""
+msgstr "Redoslijed"
#. module: account_analytic_default
#: field:account.analytic.default,date_stop:0
@@ -58,7 +58,7 @@ msgstr "Tvrtka"
#. module: account_analytic_default
#: field:account.analytic.default,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Redoslijed"
#. module: account_analytic_default
#: field:account.analytic.default,product_id:0
@@ -68,7 +68,7 @@ msgstr "Proizvod"
#. module: account_analytic_default
#: field:account.analytic.default,analytic_id:0
msgid "Analytic Account"
-msgstr ""
+msgstr "Analitički račun"
#. module: account_analytic_default
#: model:ir.model,name:account_analytic_default.model_account_analytic_default
@@ -83,7 +83,7 @@ msgstr "Korisnik"
#. module: account_analytic_default
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Nevažeće ime modela u definiciji akcije."
#. module: account_analytic_default
#: model:ir.actions.act_window,name:account_analytic_default.act_account_acount_move_line_open
diff --git a/addons/account_reporting/i18n/el.po b/addons/account_reporting/i18n/el.po
index 88e75a585d9..1c1be01e6f5 100644
--- a/addons/account_reporting/i18n/el.po
+++ b/addons/account_reporting/i18n/el.po
@@ -8,86 +8,88 @@ 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-10-18 06:54+0000\n"
-"Last-Translator: FULL NAME \n"
+"PO-Revision-Date: 2009-12-20 05:51+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: Greek \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:20+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_reporting
#: field:color.rml,code:0
msgid "code"
-msgstr ""
+msgstr "κωδικός"
#. module: account_reporting
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
+"Το όνομα του Αντικειμένου πρέπει να ξεκινά με x_ και δεν πρέπει να περιέχει "
+"ειδικούς χαρακτήρες!"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Helvetica-Bold"
-msgstr ""
+msgstr "Helvetica-Bold"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Helvetica"
-msgstr ""
+msgstr "Helvetica"
#. module: account_reporting
#: field:account.report.bs,note:0
msgid "Note"
-msgstr ""
+msgstr "Σημείωση"
#. module: account_reporting
#: field:account.report.bs,report_type:0
msgid "Report Type"
-msgstr ""
+msgstr "Τύπος Αναφοράς"
#. module: account_reporting
#: model:ir.ui.menu,name:account_reporting.action_account_report_bs_form
#: model:ir.ui.menu,name:account_reporting.menu_finan_config_BSheet
msgid "Balance Sheet Report"
-msgstr ""
+msgstr "Αναφορρά φύλλων ισοζυγίων"
#. module: account_reporting
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Courier"
-msgstr ""
+msgstr "Courier"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Courier-BoldOblique"
-msgstr ""
+msgstr "Courier-BoldOblique"
#. module: account_reporting
#: wizard_button:account.account.balancesheet.report,init,report:0
msgid "Print BalanceSheet"
-msgstr ""
+msgstr "Εκτύπωση φύλλου ισοζυγίου"
#. module: account_reporting
#: help:account.account.balancesheet.report,init,periods:0
msgid "All periods if empty"
-msgstr ""
+msgstr "Όλες οι περίοδοι άν είναι κενό"
#. module: account_reporting
#: field:account.report.bs,color_font:0
msgid "Font Color"
-msgstr ""
+msgstr "Χρώμα γραμματοσειράς"
#. module: account_reporting
#: selection:account.report.bs,report_type:0
msgid "Report Objects With Accounts and child of Accounts"
-msgstr ""
+msgstr "Αναφορά αντικειμένων με λογαριασμούς και υπολογαριασμούς"
#. module: account_reporting
#: model:ir.module.module,description:account_reporting.module_meta_information
@@ -95,150 +97,152 @@ msgid ""
"Financial and accounting reporting\n"
" Balance Sheet Report"
msgstr ""
+"Οικονομική και λογιστική αναφορά\n"
+" Αναφορά Φύλλων Ισοζυγίων"
#. module: account_reporting
#: selection:account.report.bs,report_type:0
msgid "Report Objects With Accounts"
-msgstr ""
+msgstr "Αναφορά αντικειμένων με λογαριασμούς"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Courier-Oblique"
-msgstr ""
+msgstr "Courier-Oblique"
#. module: account_reporting
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "Άκυρο XML για την Αρχιτεκτονική Όψης!"
#. module: account_reporting
#: field:account.report.bs,name:0
#: field:color.rml,name:0
msgid "Name"
-msgstr ""
+msgstr "Όνομα"
#. module: account_reporting
#: view:account.report.bs:0
msgid "Account reporting"
-msgstr ""
+msgstr "Αναφορές λογαριασμού"
#. module: account_reporting
#: model:ir.ui.menu,name:account_reporting.bs_report_action_form
msgid "Balance Sheet Report Form"
-msgstr ""
+msgstr "Φόρμα αναφοράς φύλλων ισοζυγίων"
#. module: account_reporting
#: view:account.report.bs:0
msgid "Notes"
-msgstr ""
+msgstr "Σημειώσεις"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Times-BoldItalic"
-msgstr ""
+msgstr "Times-BoldItalic"
#. module: account_reporting
#: model:ir.model,name:account_reporting.model_account_report_bs
msgid "Account reporting for Balance Sheet"
-msgstr ""
+msgstr "Αναφορά λογαριασμού για φύλλα ισοζυγίων"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Courier-Bold"
-msgstr ""
+msgstr "Courier-Bold"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Times-Italic"
-msgstr ""
+msgstr "Times-Italic"
#. module: account_reporting
#: selection:account.report.bs,report_type:0
msgid "Report Objects Only"
-msgstr ""
+msgstr "Μόνο αντικείμενα αναφοράς"
#. module: account_reporting
#: model:ir.model,name:account_reporting.model_color_rml
msgid "Rml Colors"
-msgstr ""
+msgstr "Rml Colors"
#. module: account_reporting
#: model:ir.module.module,shortdesc:account_reporting.module_meta_information
msgid "Reporting of Balancesheet for accounting"
-msgstr ""
+msgstr "Αναφορά φύλλων ισοζυγίων για την λογιστική"
#. module: account_reporting
#: field:account.report.bs,code:0
msgid "Code"
-msgstr ""
+msgstr "Κωδικός"
#. module: account_reporting
#: field:account.report.bs,parent_id:0
msgid "Parent"
-msgstr ""
+msgstr "Μητρικός"
#. module: account_reporting
#: field:account.report.bs,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Αλληλουχία"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Times-Bold"
-msgstr ""
+msgstr "Times-Bold"
#. module: account_reporting
#: view:account.report.bs:0
msgid "General"
-msgstr ""
+msgstr "Γενικά"
#. module: account_reporting
#: wizard_field:account.account.balancesheet.report,init,fiscalyear:0
msgid "Fiscal year"
-msgstr ""
+msgstr "Οικονομική χρήση"
#. module: account_reporting
#: view:account.report.bs:0
#: field:account.report.bs,account_id:0
msgid "Accounts"
-msgstr ""
+msgstr "Λογαριασμοί"
#. module: account_reporting
#: wizard_field:account.account.balancesheet.report,init,periods:0
msgid "Periods"
-msgstr ""
+msgstr "Περίοδοι"
#. module: account_reporting
#: field:account.report.bs,color_back:0
msgid "Back Color"
-msgstr ""
+msgstr "Χρώμα φόντου"
#. module: account_reporting
#: field:account.report.bs,child_id:0
msgid "Children"
-msgstr ""
+msgstr "Υπό Κατηγορίες"
#. module: account_reporting
#: wizard_button:account.account.balancesheet.report,init,end:0
msgid "Cancel"
-msgstr ""
+msgstr "Ακύρωση"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Times-Roman"
-msgstr ""
+msgstr "Times-Roman"
#. module: account_reporting
#: selection:account.report.bs,font_style:0
msgid "Helvetica-Oblique"
-msgstr ""
+msgstr "Helvetica-Oblique"
#. module: account_reporting
#: field:account.report.bs,font_style:0
msgid "Font"
-msgstr ""
+msgstr "Γραμματοσειρά"
#. module: account_reporting
#: wizard_view:account.account.balancesheet.report,init:0
msgid "Customize Report"
-msgstr ""
+msgstr "Παραμετροποίηση Αναφοράς"
diff --git a/addons/board_account/i18n/el.po b/addons/board_account/i18n/el.po
index 6e1f6d6fbad..6225de39af9 100644
--- a/addons/board_account/i18n/el.po
+++ b/addons/board_account/i18n/el.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-06-15 07:18+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 19:22+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:21+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -60,7 +60,7 @@ msgstr "Κόστη για τιμολόγηση"
#. module: board_account
#: view:board.board:0
msgid "Aged receivables"
-msgstr ""
+msgstr "Παλαιωμένα εισπρακτέα"
#. module: board_account
#: model:ir.module.module,shortdesc:board_account.module_meta_information
@@ -80,7 +80,7 @@ msgstr "Οι δείκτες μου"
#. module: board_account
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: board_account
#: model:ir.ui.menu,name:board_account.next_id_68
@@ -95,4 +95,4 @@ msgstr "Πίνακας Λογαριασμού"
#. module: board_account
#: view:board.board:0
msgid "Aged income"
-msgstr ""
+msgstr "Παλαιωμένα έσοδα"
diff --git a/addons/board_sale/i18n/el.po b/addons/board_sale/i18n/el.po
index 1572023fade..4dad2989cce 100644
--- a/addons/board_sale/i18n/el.po
+++ b/addons/board_sale/i18n/el.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-06-15 07:18+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 19:11+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:06+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -58,7 +58,7 @@ msgstr "Οι ανοικτές προσφορές μου"
#. module: board_sale
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: board_sale
#: model:ir.ui.menu,name:board_sale.next_id_88
diff --git a/addons/crm/i18n/el.po b/addons/crm/i18n/el.po
index 6d0ebd37000..feaed4d0449 100644
--- a/addons/crm/i18n/el.po
+++ b/addons/crm/i18n/el.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-06-15 07:18+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 13:49+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:08+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -51,6 +51,7 @@ msgstr "Όλα τα Θέματα"
#: wizard_view:crm.case.section.menu,init:0
msgid "this wizard will create all sub-menus, within the selected menu."
msgstr ""
+"αυτός ο βοηθός θα δημιουργήσει όλα τα υπομενού, μέσα σε ένα επιλεγμένο μενού"
#. module: crm
#: field:crm.case.rule,act_remind_partner:0
@@ -71,7 +72,7 @@ msgstr "Κατηγορία Συνεργάτη"
#. module: crm
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: crm
#: field:crm.segmentation,sales_purchase_active:0
@@ -148,7 +149,7 @@ msgstr "%(case_user) = Όνομα υπευθύνου"
#. module: crm
#: field:crm.case.section,allow_unlink:0
msgid "Allow Delete"
-msgstr ""
+msgstr "Επιτρέπεται η διαγραφή"
#. module: crm
#: field:crm.case.rule,act_email_cc:0
@@ -184,7 +185,7 @@ msgstr "<"
#. module: crm
#: view:crm.case.rule:0
msgid "%(case_description)s = Case description"
-msgstr ""
+msgstr "%(case_description)s = Case description"
#. module: crm
#: field:crm.case,email_cc:0
@@ -706,7 +707,7 @@ msgstr "Μέγιστη ID Συνεργάτη που επεξεργάστηκε"
#. module: crm
#: view:crm.case.rule:0
msgid "Condition on Communication History"
-msgstr ""
+msgstr "Συνθήκη ιστορικού επικοινωνίας"
#. module: crm
#: view:crm.case.rule:0
@@ -924,6 +925,8 @@ msgstr "Εκκρεμμή"
msgid ""
"You may want to create a new parent menu to put all the created menus in."
msgstr ""
+"Ίσως να θέλετε να δημιουργήσετε ένα νέο μενού για να βάλετε όλα τα μενιύ που "
+"δημιουργήσατε μέσα."
#. module: crm
#: field:crm.case,state:0
@@ -954,6 +957,11 @@ msgid ""
"has decreased because he probably bought goods to another supplier. Use this "
"functionality for recurring businesses."
msgstr ""
+"Μια περίοδος είναι ο αριθμός ημερών μεταξύ δύο αγορών ή πωλήσεων για αυτό το "
+"τμήμα. Βασικά χρησιμοποιείται αν ένας συνεργάτης δεν έχει αγοράσει ή "
+"πουλήσει τίποτα για πολύ καιρό, οπότε υποθέτουμε ότι η γνώμη του έχει "
+"αλλάξει αφού μάλλον αγόρασε από κάπου αλλού. Χρησιμοποιήστε αυτήν την "
+"δυνατότητα σε επαναλαμβανόμενες πωλήσεις."
#. module: crm
#: selection:crm.case,priority:0
@@ -1298,7 +1306,7 @@ msgstr "Περιγραφή"
#. module: crm
#: field:crm.case.rule,trg_max_history:0
msgid "Maximum Communication History"
-msgstr ""
+msgstr "Μέγιστο ιστορικό επικοινωνίας"
#. module: crm
#: wizard_field:crm.case.section.menu,design_menu,menu11:0
@@ -1341,7 +1349,7 @@ msgstr "Καταμερισμός"
#. module: crm
#: field:crm.segmentation.line,operator:0
msgid "Mandatory / Optional"
-msgstr ""
+msgstr "Υποχρεωτικό / Προαιρετικό"
#. module: crm
#: selection:crm.segmentation.line,expr_name:0
@@ -1368,6 +1376,8 @@ msgstr "Κανόνας Θέματος"
#: help:crm.case,date_deadline:0
msgid "Deadline Date is automatically computed from Start Date + Duration"
msgstr ""
+"Η ημερομηνία λήξης υπολογίζεται αυτόματα από την Ημερομηνία Έναρξης + "
+"Διάρκεια"
#. module: crm
#: selection:crm.segmentation.line,expr_operator:0
@@ -1461,7 +1471,7 @@ msgstr "Όλατ Ιστορικά"
#. module: crm
#: help:crm.case.section,allow_unlink:0
msgid "Allows to delete non draft cases"
-msgstr ""
+msgstr "Επιτρέπει την διαγραφή μη πρόχειρων θεμάτων"
#. module: crm
#: wizard_field:crm.case.section.menu,design_menu,menu4:0
diff --git a/addons/crm_configuration/i18n/el.po b/addons/crm_configuration/i18n/el.po
index 35342b26884..7df0a27788c 100644
--- a/addons/crm_configuration/i18n/el.po
+++ b/addons/crm_configuration/i18n/el.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-06-15 07:19+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 13:54+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:22+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -43,7 +43,7 @@ msgstr "Κλείσιμο Συνδέσμου"
#. module: crm_configuration
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: crm_configuration
#: model:ir.actions.act_window,name:crm_configuration.crm_case_categ0_act_all3
@@ -64,7 +64,7 @@ msgstr "Όνομα Σταδίου"
#. module: crm_configuration
#: model:ir.ui.menu,name:crm_configuration.menu_action_report_crm_case_oppor_categ_categ2
msgid "Cases by Opportunities, Category and Type"
-msgstr ""
+msgstr "Θέματα ανά ευκαιρίες, κατηγορίες και τύπους"
#. module: crm_configuration
#: view:crm.case:0
@@ -628,7 +628,7 @@ msgstr "Επόμενο"
#. module: crm_configuration
#: model:ir.ui.menu,name:crm_configuration.menu_action_report_crm_case_oppor_categ_stage
msgid "Cases by Opportunities, Category and Stage"
-msgstr ""
+msgstr "Θέματα ανά ευκαιρίες, κατηγορίες και καταστάσεις"
#. module: crm_configuration
#: model:crm.case.category2,name:crm_configuration.category_lead4
@@ -1039,7 +1039,7 @@ msgstr "Εισερχόμενα"
#. module: crm_configuration
#: constraint:crm.case.section:0
msgid "Error ! You cannot create recursive sections."
-msgstr ""
+msgstr "Σφάλμα! Δεν μπορείτε να δημιουργήσετε ανάδρομα τμήματα."
#. module: crm_configuration
#: help:crm.menu.config_wizard,document_ics:0
@@ -1662,7 +1662,7 @@ msgstr "Προθεσμίες"
#. module: crm_configuration
#: model:ir.ui.menu,name:crm_configuration.menu_action_report_crm_case_lead_categ
msgid "Cases by Leads and Type"
-msgstr ""
+msgstr "Θέματα ανά στοιχεία και τύπο."
#. module: crm_configuration
#: model:ir.actions.act_window,name:crm_configuration.crm_case_category_act_my3
@@ -1703,7 +1703,7 @@ msgstr "Μη Ανατεθειμένοι Σύνδεσμοι"
#: model:ir.ui.menu,name:crm_configuration.menu_crm_case_section_categ_tree_month
#: view:report.crm.case.section.categ2:0
msgid "Cases by Section and Type"
-msgstr ""
+msgstr "Θέματα ανά τμήμα και τύπο"
#. module: crm_configuration
#: model:ir.ui.menu,name:crm_configuration.menu_aftersale
@@ -1758,7 +1758,7 @@ msgstr "Όλες οι Ανοικτές Ευκαιρίες"
#. module: crm_configuration
#: model:ir.ui.menu,name:crm_configuration.menu_action_report_crm_case_oppor_categ
msgid "Cases by Opportunities and Type"
-msgstr ""
+msgstr "Θέματα ανά ευκαιρίες και τύπο"
#. module: crm_configuration
#: field:report.crm.case.section.categ.categ2,section_id:0
@@ -2021,7 +2021,7 @@ msgstr "Χρήστης"
#: model:ir.ui.menu,name:crm_configuration.menu_crm_case_section_categ_categ2_tree_month
#: view:report.crm.case.section.categ.categ2:0
msgid "Cases by Section, Category and Type"
-msgstr ""
+msgstr "Θέματα ανά τμήμα, κατηγορία και τύπο"
#. module: crm_configuration
#: model:crm.case.category2,name:crm_configuration.category_job2
@@ -2195,7 +2195,7 @@ msgstr "crm.menu.config_wizard"
#. module: crm_configuration
#: field:crm.case.stage,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Αλληλουχία"
#. module: crm_configuration
#: model:crm.case.category2,name:crm_configuration.category_lead8
diff --git a/addons/document/i18n/hr.po b/addons/document/i18n/hr.po
index bcb0ebe4e2f..4c4dfd7b52c 100644
--- a/addons/document/i18n/hr.po
+++ b/addons/document/i18n/hr.po
@@ -7,70 +7,71 @@ 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:26+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-21 01:41+0000\n"
+"Last-Translator: Jožek Prikratki \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: 2009-12-16 05:25+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document
#: field:document.directory,create_date:0
msgid "Date Created"
-msgstr ""
+msgstr "Datum stvaranja"
#. module: document
#: field:document.directory,ressource_id:0
msgid "Resource ID"
-msgstr ""
+msgstr "ID resursa"
#. module: document
#: field:document.directory.content,include_name:0
msgid "Include Record Name"
-msgstr ""
+msgstr "Uključi naziv stavke"
#. module: document
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
+"Naziv objekta mora počinjati sa x_ i ne smije sadržavati specijalne znakove!"
#. module: document
#: field:ir.actions.report.xml,model_id:0
msgid "Model Id"
-msgstr ""
+msgstr "ID modela"
#. module: document
#: constraint:document.directory:0
msgid "Error! You can not create recursive Directories."
-msgstr ""
+msgstr "Pogreška! Ne možete stvarati rekurzivne mape."
#. module: document
#: model:ir.ui.menu,name:document.menu_document_configuration
msgid "Document Configuration"
-msgstr ""
+msgstr "Postavke dokumenta"
#. module: document
#: view:ir.attachment:0
msgid "Preview"
-msgstr ""
+msgstr "Pretpregled"
#. module: document
#: field:ir.attachment,store_method:0
msgid "Storing Method"
-msgstr ""
+msgstr "Metoda pohrane"
#. module: document
#: model:ir.actions.act_window,name:document.action_config_auto_directory
msgid "Auto Configure Directory"
-msgstr ""
+msgstr "Automatski konfiguriraj mapu"
#. module: document
#: field:ir.attachment,file_size:0
msgid "File Size"
-msgstr ""
+msgstr "Veličina datoteke"
#. module: document
#: help:document.directory.content,include_name:0
@@ -78,47 +79,50 @@ msgid ""
"Check this field if you want that the name of the file start by the record "
"name."
msgstr ""
+"Uključite ovu opciju ako želite da naziv datoteke počinje s nazivom stavke"
#. module: document
#: selection:document.directory,type:0
msgid "Other Resources"
-msgstr ""
+msgstr "Drugi resursi"
#. module: document
#: field:document.directory,ressource_parent_type_id:0
msgid "Parent Model"
-msgstr ""
+msgstr "Model roditelj"
#. module: document
#: view:document.configuration.wizard:0
msgid "Document Management System."
-msgstr ""
+msgstr "Sustav za upravljanje dokumentima"
#. module: document
#: view:ir.attachment:0
msgid "Attachment"
-msgstr ""
+msgstr "Privitak"
#. module: document
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Nevažeće ime modela u definiciji akcije."
#. module: document
#: selection:document.directory,type:0
msgid "Static Directory"
-msgstr ""
+msgstr "Statična mapa"
#. module: document
#: model:ir.model,name:document.model_document_directory_content_type
msgid "Directory Content Type"
-msgstr ""
+msgstr "Vrsta sadržaja u mapi"
#. module: document
#: help:document.directory,domain:0
msgid ""
"Use a domain if you want to apply an automatic filter on visible resources."
msgstr ""
+"Koristite domenu ako želite postaviti automatski filter nad vidljivim "
+"resursima"
#. module: document
#: help:document.directory,ressource_tree:0
@@ -126,59 +130,61 @@ msgid ""
"Check this if you want to use the same tree structure as the object selected "
"in the system."
msgstr ""
+"Odaberite ovu opciju ako želite koristiti istu strukturu stabla kao odabrani "
+"objekt u sustavu."
#. module: document
#: field:document.directory,type:0
msgid "Type"
-msgstr ""
+msgstr "Tip"
#. module: document
#: model:ir.actions.act_window,name:document.action_document_directory_tree
#: model:ir.ui.menu,name:document.menu_document_directories_tree
msgid "Directorie's Structure"
-msgstr ""
+msgstr "Struktura mape"
#. module: document
#: field:document.directory,parent_id:0
msgid "Parent Item"
-msgstr ""
+msgstr "Roditelj"
#. module: document
#: view:ir.attachment:0
msgid "File Information"
-msgstr ""
+msgstr "Podaci o datoteci"
#. module: document
#: field:document.directory,file_ids:0
#: view:ir.attachment:0
msgid "Files"
-msgstr ""
+msgstr "Datoteke"
#. module: document
#: field:ir.attachment,store_fname:0
msgid "Stored Filename"
-msgstr ""
+msgstr "Pohranjeni naziv datoteke"
#. module: document
#: field:document.directory,write_uid:0
#: field:ir.attachment,write_uid:0
msgid "Last Modification User"
-msgstr ""
+msgstr "Korisnik posljednje promjene"
#. module: document
#: view:document.configuration.wizard:0
msgid "Configure"
-msgstr ""
+msgstr "Postavi"
#. module: document
#: field:document.directory,ressource_tree:0
msgid "Tree Structure"
-msgstr ""
+msgstr "Struktura stabla"
#. module: document
#: field:ir.attachment,title:0
msgid "Resource Title"
-msgstr ""
+msgstr "Naslov resursa"
#. module: document
#: model:ir.actions.todo,note:document.config_auto_directory
@@ -186,11 +192,12 @@ msgid ""
"This wizard will configure the URL of the server of the document management "
"system."
msgstr ""
+"Ovaj će agent postaviti URL poslužitelja sustava za upravljanje dokumentima."
#. module: document
#: model:ir.model,name:document.model_document_directory_content
msgid "Directory Content"
-msgstr ""
+msgstr "Sadržaj mape"
#. module: document
#: help:document.directory,ressource_parent_type_id:0
@@ -198,32 +205,35 @@ msgid ""
"If you put an object here, this directory template will appear bellow all of "
"these objects. Don't put a parent directory if you select a parent model."
msgstr ""
+"Ako ovdje postavite objekt, predložak ove mape će biti prikazan ispod svih "
+"takvih objekata. Nemojte postaviti mapu roditelja ako odabirete model "
+"roditelja."
#. module: document
#: model:ir.ui.menu,name:document.menu_document
msgid "Document Management"
-msgstr ""
+msgstr "Upravljanje dokumentima"
#. module: document
#: selection:ir.attachment,store_method:0
msgid "Link"
-msgstr ""
+msgstr "Poveznica"
#. module: document
#: view:document.directory:0
msgid "Directory Type"
-msgstr ""
+msgstr "Vrsta mape"
#. module: document
#: field:document.directory,group_ids:0
#: field:ir.attachment,group_ids:0
msgid "Groups"
-msgstr ""
+msgstr "Grupe"
#. module: document
#: field:document.directory.content,report_id:0
msgid "Report"
-msgstr ""
+msgstr "Izvještaj"
#. module: document
#: help:document.configuration.wizard,host:0
@@ -231,6 +241,8 @@ msgid ""
"Put here the server address or IP. Keep localhost if you don't know what to "
"write."
msgstr ""
+"Ovdje upišite adresu poslužitelja ili IP adresu. Ostavite localhost ako ne "
+"znate što biste napisali."
#. module: document
#: view:document.configuration.wizard:0
@@ -238,32 +250,34 @@ msgid ""
"This wizard will automatically configure the document management system "
"according to modules installed on your system."
msgstr ""
+"Agent će automatski postaviti sustav za upravljanje dokumentima ovisno o "
+"modulima koji su instalirani na vašem sustavu."
#. module: document
#: view:ir.attachment:0
msgid "Data"
-msgstr ""
+msgstr "Podaci"
#. module: document
#: view:ir.attachment:0
msgid "Notes"
-msgstr ""
+msgstr "Bilješke"
#. module: document
#: view:ir.attachment:0
#: field:ir.attachment,index_content:0
msgid "Indexed Content"
-msgstr ""
+msgstr "Indeksirani dokument"
#. module: document
#: view:document.directory:0
msgid "Definition"
-msgstr ""
+msgstr "Definicija"
#. module: document
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "Nevažeći XML za Arhitekturu Prikaza!"
#. module: document
#: model:ir.module.module,description:document.module_meta_information
@@ -273,97 +287,101 @@ msgid ""
" * User Authentication\n"
" * Document Indexation\n"
msgstr ""
+"Ovo je potpuni sustav za upravljanje dokumentima:\n"
+" * FTP sučelje\n"
+" * Autentifikacija korisnika\n"
+" * Indeksiranje dokumenata\n"
#. module: document
#: field:document.directory,name:0
msgid "Name"
-msgstr ""
+msgstr "Naziv"
#. module: document
#: field:document.directory.content.type,code:0
msgid "Extension"
-msgstr ""
+msgstr "Ekstenzija"
#. module: document
#: selection:ir.attachment,store_method:0
msgid "Database"
-msgstr ""
+msgstr "Baza podataka"
#. module: document
#: field:document.directory,content_ids:0
msgid "Virtual Files"
-msgstr ""
+msgstr "Virtualne datoteke"
#. module: document
#: view:document.directory:0
#: model:ir.ui.menu,name:document.menu_document_directories
msgid "Directories"
-msgstr ""
+msgstr "Mape"
#. module: document
#: view:document.directory:0
msgid "Seq."
-msgstr ""
+msgstr "Redoslijed"
#. module: document
#: model:ir.module.module,shortdesc:document.module_meta_information
msgid "Integrated Document Management System"
-msgstr ""
+msgstr "Integrirani sustav za upravljanje dokumentima"
#. module: document
#: field:document.directory.content,directory_id:0
#: field:ir.attachment,parent_id:0
msgid "Directory"
-msgstr ""
+msgstr "Mapa"
#. module: document
#: field:document.directory,user_id:0
#: field:ir.attachment,user_id:0
msgid "Owner"
-msgstr ""
+msgstr "Vlasnik"
#. module: document
#: model:ir.model,name:document.model_document_configuration_wizard
msgid "document.configuration.wizard"
-msgstr ""
+msgstr "document.configuration.wizard"
#. module: document
#: view:ir.attachment:0
msgid "Attached To"
-msgstr ""
+msgstr "Vezano uz"
#. module: document
#: selection:ir.attachment,store_method:0
msgid "Filesystem"
-msgstr ""
+msgstr "Datotečni sustav"
#. module: document
#: field:document.directory,file_type:0
#: field:document.directory.content.type,name:0
#: field:ir.attachment,file_type:0
msgid "Content Type"
-msgstr ""
+msgstr "Vrsta datoteke"
#. module: document
#: view:document.directory:0
#: view:ir.attachment:0
msgid "Security"
-msgstr ""
+msgstr "Sigurnost"
#. module: document
#: model:ir.ui.menu,name:document.menu_document_browse
msgid "Browse Files Using FTP"
-msgstr ""
+msgstr "Pregledaj datoteke koristeći FTP"
#. module: document
#: field:document.directory,ressource_type_id:0
msgid "Directories Mapped to Objects"
-msgstr ""
+msgstr "Mape vezane uz objekte"
#. module: document
#: view:ir.attachment:0
msgid "History"
-msgstr ""
+msgstr "Povijest"
#. module: document
#: help:document.directory,ressource_type_id:0
@@ -371,100 +389,102 @@ msgid ""
"Select an object here and Open ERP will create a mapping for each of these "
"objects, using the given domain, when browsing through FTP."
msgstr ""
+"Ovdje odaberite objekt i Open ERP će uspostaviti mapiranje za svaki od ovih "
+"objekata, koristeći zadanu domenu, prilikom predleda kroz FTP."
#. module: document
#: view:ir.attachment:0
msgid "Others Info"
-msgstr ""
+msgstr "Ostale informacije"
#. module: document
#: field:document.directory,domain:0
msgid "Domain"
-msgstr ""
+msgstr "Domena"
#. module: document
#: field:document.directory,write_date:0
#: field:ir.attachment,write_date:0
msgid "Date Modified"
-msgstr ""
+msgstr "Datum izmjene"
#. module: document
#: field:document.directory.content,suffix:0
msgid "Suffix"
-msgstr ""
+msgstr "Nastavak"
#. module: document
#: field:document.configuration.wizard,host:0
msgid "Server Address"
-msgstr ""
+msgstr "Adresa poslužitelja"
#. module: document
#: model:ir.actions.url,name:document.action_document_browse
msgid "Browse Files"
-msgstr ""
+msgstr "Pretraži Datoteke"
#. module: document
#: field:document.directory.content,name:0
msgid "Content Name"
-msgstr ""
+msgstr "Naziv sadržaja"
#. module: document
#: model:ir.model,name:document.model_document_directory
#: field:process.node,directory_id:0
msgid "Document directory"
-msgstr ""
+msgstr "Mapa dokumenta"
#. module: document
#: field:document.directory,create_uid:0
msgid "Creator"
-msgstr ""
+msgstr "Autor"
#. module: document
#: view:document.directory:0
msgid "Auto-Generated Files"
-msgstr ""
+msgstr "Automatski generirane datoteke"
#. module: document
#: field:document.directory.content,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Redoslijed"
#. module: document
#: model:ir.ui.menu,name:document.menu_document_files
msgid "Search a File"
-msgstr ""
+msgstr "Pronađi datoteku"
#. module: document
#: view:document.configuration.wizard:0
msgid "Auto Configure"
-msgstr ""
+msgstr "Podesi automatski"
#. module: document
#: view:document.configuration.wizard:0
msgid "Cancel"
-msgstr ""
+msgstr "Odustani"
#. module: document
#: field:ir.attachment,partner_id:0
msgid "Partner"
-msgstr ""
+msgstr "Stranka"
#. module: document
#: view:document.directory:0
msgid "PDF Report"
-msgstr ""
+msgstr "PDF izvještaj"
#. module: document
#: field:document.directory.content,extension:0
msgid "Document Type"
-msgstr ""
+msgstr "Vrsta dokumenta"
#. module: document
#: field:document.directory,child_ids:0
msgid "Children"
-msgstr ""
+msgstr "Djeca"
#. module: document
#: view:document.directory:0
msgid "Contents"
-msgstr ""
+msgstr "Sadržaji"
diff --git a/addons/document_ics/i18n/hr.po b/addons/document_ics/i18n/hr.po
index 0eb5eb5e25a..545d4866ceb 100644
--- a/addons/document_ics/i18n/hr.po
+++ b/addons/document_ics/i18n/hr.po
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.1\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-10-01 07:47+0000\n"
-"Last-Translator: Miro Glavić \n"
+"PO-Revision-Date: 2009-12-21 02:05+0000\n"
+"Last-Translator: Jožek Prikratki \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: 2009-12-16 05:24+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document_ics
@@ -21,71 +21,73 @@ msgstr ""
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
+"Naziv objekta mora počinjati sa x_ i ne smije sadržavati specijalne znakove!"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "uid"
-msgstr ""
+msgstr "uid"
#. module: document_ics
#: constraint:document.directory:0
msgid "Error! You can not create recursive Directories."
-msgstr ""
+msgstr "Pogreška! Ne možete stvarati rekurzivne mape."
#. module: document_ics
#: field:document.ics.crm.wizard,jobs:0
msgid "Jobs Hiring Process"
-msgstr ""
+msgstr "Proces zapošljavanja"
#. module: document_ics
#: view:document.ics.crm.wizard:0
msgid "Configure Calendars for CRM Sections"
-msgstr ""
+msgstr "Postavi kalendare za CRM dijelove"
#. module: document_ics
#: field:document.ics.crm.wizard,helpdesk:0
msgid "Helpdesk"
-msgstr ""
+msgstr "Helpdesk"
#. module: document_ics
#: field:document.directory.ics.fields,field_id:0
msgid "Open ERP Field"
-msgstr ""
+msgstr "Open ERP polje"
#. module: document_ics
#: view:document.ics.crm.wizard:0
msgid "Next"
-msgstr ""
+msgstr "Dalje"
#. module: document_ics
#: field:document.directory.ics.fields,content_id:0
msgid "Content"
-msgstr ""
+msgstr "Sadržaj"
#. module: document_ics
#: field:document.ics.crm.wizard,meeting:0
msgid "Calendar of Meetings"
-msgstr ""
+msgstr "Kalendar sastanaka"
#. module: document_ics
#: model:crm.case.section,name:document_ics.section_meeting
msgid "Shared Calendar Meetings"
-msgstr ""
+msgstr "Sastanci zajedničkog kalendara"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "url"
-msgstr ""
+msgstr "url"
#. module: document_ics
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Nevažeće ime modela u definiciji akcije."
#. module: document_ics
#: help:document.ics.crm.wizard,bugs:0
msgid "Used by companies to track bugs and support requests on softwares"
msgstr ""
+"Korišten od tvrtki za praćenje pogrešaka i zahtjeva za podrškom na programima"
#. module: document_ics
#: model:ir.actions.todo,note:document_ics.config_wizard_step_case_section_menu
@@ -93,11 +95,13 @@ msgid ""
"This Configuration step use to create Calendars in document for all Case "
"Sections"
msgstr ""
+"Ovaj korak postavki koristi se za stvaranje kalendara u dokumentima ze sve "
+"slučaj sekcije"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "dtend"
-msgstr ""
+msgstr "dtend"
#. module: document_ics
#: help:document.ics.crm.wizard,jobs:0
@@ -105,77 +109,81 @@ msgid ""
"Help you to organise the jobs hiring process: evaluation, meetings, email "
"integration..."
msgstr ""
+"Pomaže vam organizirati proces zapošljavanja: procjena, sastanci, "
+"integracija elektroničke pošte..."
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "description"
-msgstr ""
+msgstr "opis"
#. module: document_ics
#: model:ir.actions.act_window,name:document_ics.action_view_document_ics_config_directories
msgid "Configure Calendars for Sections "
-msgstr ""
+msgstr "Postavi kalendare za sekcije "
#. module: document_ics
#: help:document.ics.crm.wizard,opportunity:0
msgid "Tracks identified business opportunities for your sales pipeline."
-msgstr ""
+msgstr "Prati prepoznate poslovne prilike za vaš prodajni cjevovod."
#. module: document_ics
#: help:document.ics.crm.wizard,fund:0
msgid ""
"This may help associations in their fund raising process and tracking."
msgstr ""
+"Ovo može pomoći udrugama u procesu prikupljanja i praćenja sredstava za "
+"financiranje."
#. module: document_ics
#: help:document.ics.crm.wizard,helpdesk:0
msgid "Manages an Helpdesk service."
-msgstr ""
+msgstr "Upravlja helpdesk uslugom"
#. module: document_ics
#: field:document.ics.crm.wizard,fund:0
msgid "Fund Raising Operations"
-msgstr ""
+msgstr "Operacije za skupljanje sredstava"
#. module: document_ics
#: field:document.directory.content,ics_object_id:0
msgid "Object"
-msgstr ""
+msgstr "Objekt"
#. module: document_ics
#: constraint:crm.case.section:0
msgid "Error ! You cannot create recursive sections."
-msgstr ""
+msgstr "Pogreška ! Ne možete stvarati rekurzivne sekcije."
#. module: document_ics
#: model:ir.module.module,shortdesc:document_ics.module_meta_information
msgid "Support for iCal based on Document Management System"
-msgstr ""
+msgstr "Podrška za iCal temeljem sustava za upravljanje dokumentima."
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "location"
-msgstr ""
+msgstr "lokacija"
#. module: document_ics
#: view:document.directory:0
msgid "ICS Calendar"
-msgstr ""
+msgstr "ICS kalendar"
#. module: document_ics
#: field:document.directory.ics.fields,name:0
msgid "ICS Value"
-msgstr ""
+msgstr "ICS vrijednost"
#. module: document_ics
#: model:ir.module.module,description:document_ics.module_meta_information
msgid "Allows to synchronise calendars with others applications."
-msgstr ""
+msgstr "Omogući sinkronizaciju kalendara s drugim aplikacijama"
#. module: document_ics
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "Nevažeći XML za Arhitekturu Prikaza!"
#. module: document_ics
#: help:document.ics.crm.wizard,lead:0
@@ -183,21 +191,23 @@ msgid ""
"Allows you to track and manage prospects which are pre-sales requests or "
"contacts, the very first contact with a customer request."
msgstr ""
+"Omogućava vam da pratite i upravljate prilikama koje uključuju predprodajne "
+"upite ili kontakte, prvi kontakt s upitom korisnika."
#. module: document_ics
#: field:document.ics.crm.wizard,name:0
msgid "Name"
-msgstr ""
+msgstr "Naziv"
#. module: document_ics
#: help:document.ics.crm.wizard,meeting:0
msgid "Manages the calendar of meetings of the users."
-msgstr ""
+msgstr "Upravlja kalendarom sastanaka korisnika"
#. module: document_ics
#: field:document.directory.content,ics_domain:0
msgid "Domain"
-msgstr ""
+msgstr "Domena"
#. module: document_ics
#: help:document.ics.crm.wizard,claims:0
@@ -205,31 +215,33 @@ msgid ""
"Manages the supplier and customers claims, including your corrective or "
"preventive actions."
msgstr ""
+"Upravlja pritužbama dobavljača i kupaca, uključujući korektivne ili "
+"preventivne akcije."
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "last-modified"
-msgstr ""
+msgstr "posljednja-promjena"
#. module: document_ics
#: view:document.directory:0
msgid "ICS Mapping"
-msgstr ""
+msgstr "ICS mapiranje"
#. module: document_ics
#: view:crm.case:0
msgid "Duration(In Hour)"
-msgstr ""
+msgstr "Trajanje (u satima)"
#. module: document_ics
#: field:document.ics.crm.wizard,document_ics:0
msgid "Shared Calendar"
-msgstr ""
+msgstr "Dijeljeni kalendar"
#. module: document_ics
#: field:document.ics.crm.wizard,claims:0
msgid "Claims"
-msgstr ""
+msgstr "Pritužbe"
#. module: document_ics
#: help:document.ics.crm.wizard,phonecall:0
@@ -237,83 +249,85 @@ msgid ""
"Help you to encode the result of a phone call or to planify a list of phone "
"calls to process."
msgstr ""
+"Pomaže vam unijeti rezultate telefonskog poziva ili planirati popis poziva "
+"za obradu."
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "dtstart"
-msgstr ""
+msgstr "dtstart"
#. module: document_ics
#: field:document.ics.crm.wizard,phonecall:0
msgid "Phone Calls"
-msgstr ""
+msgstr "Telefonski pozivi"
#. module: document_ics
#: field:document.ics.crm.wizard,bugs:0
msgid "Bug Tracking"
-msgstr ""
+msgstr "Praćenje pogrešaka"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "categories"
-msgstr ""
+msgstr "kategorije"
#. module: document_ics
#: field:document.ics.crm.wizard,lead:0
msgid "Prospect"
-msgstr ""
+msgstr "Prilika"
#. module: document_ics
#: view:document.ics.crm.wizard:0
msgid "Create Pre-Configured Calendars"
-msgstr ""
+msgstr "Napravi predkonfigurirani kalendar"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "created"
-msgstr ""
+msgstr "kreiran"
#. module: document_ics
#: field:crm.case,code:0
msgid "Calendar Code"
-msgstr ""
+msgstr "Šifra kalendara"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "summary"
-msgstr ""
+msgstr "sažetak"
#. module: document_ics
#: model:ir.model,name:document_ics.model_document_ics_crm_wizard
msgid "document.ics.crm.wizard"
-msgstr ""
+msgstr "document.ics.crm.wizard"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "attendee"
-msgstr ""
+msgstr "prisutan"
#. module: document_ics
#: model:ir.model,name:document_ics.model_document_directory_ics_fields
msgid "document.directory.ics.fields"
-msgstr ""
+msgstr "document.directory.ics.fields"
#. module: document_ics
#: field:document.directory.content,ics_field_ids:0
msgid "Fields Mapping"
-msgstr ""
+msgstr "Mapiranje polja"
#. module: document_ics
#: view:document.ics.crm.wizard:0
msgid "Cancel"
-msgstr ""
+msgstr "Odustani"
#. module: document_ics
#: field:document.ics.crm.wizard,opportunity:0
msgid "Business Opportunities"
-msgstr ""
+msgstr "Poslovne prilike"
#. module: document_ics
#: selection:document.directory.ics.fields,name:0
msgid "dtstamp"
-msgstr ""
+msgstr "dtstamp"
diff --git a/addons/document_webdav/i18n/hr.po b/addons/document_webdav/i18n/hr.po
new file mode 100644
index 00000000000..c2766b9ba68
--- /dev/null
+++ b/addons/document_webdav/i18n/hr.po
@@ -0,0 +1,31 @@
+# Croatian translation for openobject-addons
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2009-05-30 15:14+0000\n"
+"PO-Revision-Date: 2009-12-21 01:43+0000\n"
+"Last-Translator: Jožek Prikratki \n"
+"Language-Team: Croatian
\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#. module: document_webdav_old
+#: model:ir.module.module,description:document_webdav_old.module_meta_information
+msgid ""
+"This is a complete document management system:\n"
+"\t* WebDav Interface\n"
+"\t* User Authentification\n"
+"\t* Document Indexation\n"
+msgstr ""
+"Ovo je potpuni sustav za upravljanje dokumentima.\n"
+"\t*WebDav sučelje\n"
+"\t*Autentifikacija korisnika\n"
+"\t*Indeksiranje dokumenata\n"
diff --git a/addons/google_map/i18n/hr.po b/addons/google_map/i18n/hr.po
index b0696d47c2b..c1edeb483bb 100644
--- a/addons/google_map/i18n/hr.po
+++ b/addons/google_map/i18n/hr.po
@@ -7,30 +7,30 @@ 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:26+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-21 01:16+0000\n"
+"Last-Translator: Jožek Prikratki \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: 2009-12-16 05:03+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: google_map
#: model:ir.actions.wizard,name:google_map.wizard_google_map
msgid "Launch Google Map"
-msgstr ""
+msgstr "Pokreni Google zemljovid"
#. module: google_map
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "Neispravan XML za arhitekturu prikaza!"
#. module: google_map
#: view:res.partner:0
#: view:res.partner.address:0
msgid "Street2 : "
-msgstr ""
+msgstr "Ulica 2 : "
#. module: google_map
#: model:ir.module.module,description:google_map.module_meta_information
@@ -39,9 +39,12 @@ msgid ""
"so that we can directly open google map from the\n"
"url widget."
msgstr ""
+"Modul dodaje Google zemljovid u polje adrese stranke\n"
+"tako da je moguće izravno otvoriti Google mapu iz\n"
+"URL komponente."
#. module: google_map
#: view:res.partner:0
#: view:res.partner.address:0
msgid "Map"
-msgstr ""
+msgstr "Zemljovid"
diff --git a/addons/hr_holidays/i18n/el.po b/addons/hr_holidays/i18n/el.po
index 33f8d99cb75..b007208070a 100644
--- a/addons/hr_holidays/i18n/el.po
+++ b/addons/hr_holidays/i18n/el.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-06-15 11:18+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 13:38+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:20+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -32,7 +32,7 @@ msgstr "Όλες οι Αίτήσεις Αδείας"
#. module: hr_holidays
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: hr_holidays
#: field:hr.holidays.per.user,remaining_leaves:0
@@ -264,7 +264,7 @@ msgstr "Υπάλληλος"
#. module: hr_holidays
#: selection:hr.holidays,state:0
msgid "Waiting Validation"
-msgstr ""
+msgstr "Σε αναμονή έγκρισης"
#. module: hr_holidays
#: model:process.transition,note:hr_holidays.process_transition_employeeholidays0
@@ -666,7 +666,7 @@ msgstr "Case"
#. module: hr_holidays
#: field:hr.holidays,holiday_user_id:0
msgid "Holiday per user"
-msgstr ""
+msgstr "Άδειες ανα χρήστη"
#. module: hr_holidays
#: model:process.node,note:hr_holidays.process_node_holidays0
diff --git a/addons/hr_holidays/i18n/zh_CN.po b/addons/hr_holidays/i18n/zh_CN.po
index 0d84f5cbd4d..82a7df34d99 100644
--- a/addons/hr_holidays/i18n/zh_CN.po
+++ b/addons/hr_holidays/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-02 13:59+0000\n"
+"PO-Revision-Date: 2009-12-20 15:10+0000\n"
"Last-Translator: Wei \"oldrev\" Li \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: 2009-12-16 05:20+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: hr_holidays
@@ -50,7 +50,7 @@ msgstr "淡蓝色"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
msgid "Brown"
-msgstr ""
+msgstr "棕色"
#. module: hr_holidays
#: xsl:holidays.summary:0
@@ -60,7 +60,7 @@ msgstr ""
#. module: hr_holidays
#: xsl:holidays.summary:0
msgid "Off-Days' Summary"
-msgstr ""
+msgstr "请假概述"
#. module: hr_holidays
#: view:hr.holidays:0
@@ -72,7 +72,7 @@ msgstr "员工假日"
#. module: hr_holidays
#: view:hr.holidays:0
msgid "Set to Draft"
-msgstr ""
+msgstr "设为草稿"
#. module: hr_holidays
#: view:hr.holidays.per.user:0
@@ -80,88 +80,88 @@ msgstr ""
#: model:ir.model,name:hr_holidays.model_hr_holidays
#: model:process.node,name:hr_holidays.process_node_holidays0
msgid "Holidays"
-msgstr ""
+msgstr "假日"
#. module: hr_holidays
#: xsl:holidays.summary:0
msgid "to"
-msgstr ""
+msgstr "至"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
msgid "Light Cyan"
-msgstr ""
+msgstr "淡青色"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
msgid "Light Green"
-msgstr ""
+msgstr "淡绿色"
#. module: hr_holidays
#: model:process.transition,name:hr_holidays.process_transition_employeedeclaration0
msgid "Employee Declaration"
-msgstr ""
+msgstr "员工声明"
#. module: hr_holidays
#: view:hr.holidays:0
#: selection:hr.holidays,state:0
#: model:process.transition.action,name:hr_holidays.process_transition_action_validate0
msgid "Validate"
-msgstr ""
+msgstr "批准"
#. module: hr_holidays
#: model:process.transition,name:hr_holidays.process_transition_refusedrequest0
msgid "Refused Request"
-msgstr ""
+msgstr "拒绝申请"
#. module: hr_holidays
#: model:process.node,name:hr_holidays.process_node_approved0
msgid "Approved"
-msgstr ""
+msgstr "已核准"
#. module: hr_holidays
#: selection:hr.holidays.summary.employee,init,holiday_type:0
msgid "Both"
-msgstr ""
+msgstr "两者"
#. module: hr_holidays
#: view:hr.holidays:0
msgid "Refuse"
-msgstr ""
+msgstr "拒绝"
#. module: hr_holidays
#: wizard_button:hr.holidays.summary,notify,end:0
#: wizard_button:hr.holidays.summary.employee,notify,end:0
msgid "Ok"
-msgstr ""
+msgstr "确定"
#. module: hr_holidays
#: model:ir.ui.menu,name:hr_holidays.menu_action_my_holiday
msgid "My Holidays Requests"
-msgstr ""
+msgstr "我的假日申请"
#. module: hr_holidays
#: field:hr.holidays,notes:0
#: field:hr.holidays.per.user,notes:0
msgid "Notes"
-msgstr ""
+msgstr "备注"
#. module: hr_holidays
#: field:hr.holidays,holiday_status:0
#: field:hr.holidays.log,holiday_status:0
#: field:hr.holidays.per.user,holiday_status:0
msgid "Holiday's Status"
-msgstr ""
+msgstr "假日状态"
#. module: hr_holidays
#: model:process.transition,note:hr_holidays.process_transition_refusedrequest0
msgid "Request is refused."
-msgstr ""
+msgstr "申请被拒绝。"
#. module: hr_holidays
#: model:ir.ui.menu,name:hr_holidays.menu_open_ask_holidays
msgid "Holidays Management"
-msgstr ""
+msgstr "假日管理"
#. module: hr_holidays
#: xsl:holidays.summary:0
@@ -171,7 +171,7 @@ msgstr ""
#. module: hr_holidays
#: model:ir.actions.report.xml,name:hr_holidays.report_holidays_summary
msgid "Summary Of Holidays"
-msgstr ""
+msgstr "假日概要"
#. module: hr_holidays
#: model:process.node,note:hr_holidays.process_node_calendar0
@@ -181,66 +181,66 @@ msgstr ""
#. module: hr_holidays
#: view:hr.holidays.status:0
msgid "Holiday status"
-msgstr ""
+msgstr "假日状态"
#. module: hr_holidays
#: model:ir.model,name:hr_holidays.model_hr_holidays_status
msgid "Holidays Status"
-msgstr ""
+msgstr "假日状态"
#. module: hr_holidays
#: field:hr.holidays,date_to:0
msgid "Vacation end day"
-msgstr ""
+msgstr "假期结束日"
#. module: hr_holidays
#: view:hr.holidays.per.user:0
msgid "Holidays Allowed"
-msgstr ""
+msgstr "允许的假日"
#. module: hr_holidays
#: model:process.node,note:hr_holidays.process_node_legaldeclaration0
msgid "Legal Declaration Document to declare new employee"
-msgstr ""
+msgstr "申报一个新员工的法律文档"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
msgid "Magenta"
-msgstr ""
+msgstr "品红色"
#. module: hr_holidays
#: model:ir.model,name:hr_holidays.model_hr_holidays_per_user
msgid "Holidays Per User"
-msgstr ""
+msgstr "各个用户的假日"
#. module: hr_holidays
#: view:hr.holidays.status:0
msgid "Define holiday status"
-msgstr ""
+msgstr "定义假日状态"
#. module: hr_holidays
#: selection:hr.holidays.summary,init,holiday_type:0
#: selection:hr.holidays.summary.employee,init,holiday_type:0
msgid "Confirmed"
-msgstr ""
+msgstr "已确认"
#. module: hr_holidays
#: wizard_field:hr.holidays.summary,init,date_from:0
#: wizard_field:hr.holidays.summary.employee,init,date_from:0
msgid "From"
-msgstr ""
+msgstr "来自"
#. module: hr_holidays
#: view:hr.holidays:0
#: model:process.transition.action,name:hr_holidays.process_transition_action_confirm0
msgid "Confirm"
-msgstr ""
+msgstr "确认"
#. module: hr_holidays
#: model:ir.actions.act_window,name:hr_holidays.action_my_holiday_waiting
#: model:ir.ui.menu,name:hr_holidays.menu_action_my_holiday_waiting
msgid "My Awaiting Confirmation Holidays Requests"
-msgstr ""
+msgstr "我的待确认假日申请"
#. module: hr_holidays
#: field:hr.holidays,user_id:0
@@ -257,7 +257,7 @@ msgstr ""
#: field:hr.holidays.log,employee_id:0
#: field:hr.holidays.per.user,employee_id:0
msgid "Employee"
-msgstr ""
+msgstr "员工"
#. module: hr_holidays
#: selection:hr.holidays,state:0
@@ -272,7 +272,7 @@ msgstr ""
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
msgid "Light Salmon"
-msgstr ""
+msgstr "浅橙色"
#. module: hr_holidays
#: selection:hr.holidays.status,color_name:0
diff --git a/addons/hr_timesheet/i18n/el.po b/addons/hr_timesheet/i18n/el.po
index ff4f46a8dff..237113a9857 100644
--- a/addons/hr_timesheet/i18n/el.po
+++ b/addons/hr_timesheet/i18n/el.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-05-16 08:36+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 19:09+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:16+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -78,7 +78,7 @@ msgstr "Τρέχουσα Ημερ/νία"
#. module: hr_timesheet
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: hr_timesheet
#: wizard_button:hr.analytical.timesheet,init,report:0
@@ -113,7 +113,7 @@ msgstr "Προϊον"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "août"
-msgstr ""
+msgstr "Αύγουστος"
#. module: hr_timesheet
#: field:hr.employee,journal_id:0
@@ -129,7 +129,7 @@ msgstr "Ώρα"
#: model:ir.actions.wizard,name:hr_timesheet.wizard_hr_timesheet
#: model:ir.ui.menu,name:hr_timesheet.menu_wizard_hr_timesheet
msgid "Employee Timesheet"
-msgstr ""
+msgstr "Φύλλο Xρόνου Eργασίας Υπαλλήλου"
#. module: hr_timesheet
#: view:account.analytic.account:0
@@ -158,7 +158,7 @@ msgstr "Σύνολο Χρόνου"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "juillet"
-msgstr ""
+msgstr "Ιούλιος"
#. module: hr_timesheet
#: xsl:hr.analytical.timesheet:0
@@ -172,20 +172,20 @@ msgstr "Φύλλo Xρόνου Eργασίας"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "janvier"
-msgstr ""
+msgstr "Γενάρης"
#. module: hr_timesheet
#: selection:hr.analytical.timesheet,init,month:0
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "juin"
-msgstr ""
+msgstr "Ιούνιος"
#. module: hr_timesheet
#: model:ir.actions.wizard,name:hr_timesheet.wizard_hr_timesheet_my
#: model:ir.ui.menu,name:hr_timesheet.menu_wizard_hr_timesheet_my
msgid "Print My Timesheet"
-msgstr ""
+msgstr "Εκτύπωσε το φύλλο εργασίας μου"
#. module: hr_timesheet
#: wizard_field:hr.analytical.timesheet,init,user_id:0
@@ -234,7 +234,7 @@ msgstr "Invalid XML for View Architecture!"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "avril"
-msgstr ""
+msgstr "Απρίλιος"
#. module: hr_timesheet
#: field:hr.analytic.timesheet,line_id:0
@@ -256,7 +256,7 @@ msgstr "Επιλογή Χρηστών"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "novembre"
-msgstr ""
+msgstr "Νοέμβριος"
#. module: hr_timesheet
#: wizard_view:hr_timesheet.si_so,sign_out:0
@@ -284,7 +284,7 @@ msgstr "Παρούσα Κατάσταση"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "octobre"
-msgstr ""
+msgstr "Οκτώβριος"
#. module: hr_timesheet
#: view:account.analytic.account:0
@@ -296,7 +296,7 @@ msgstr "Στατιστικά Ανάλυσης"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "décembre"
-msgstr ""
+msgstr "Δεκέμβριος"
#. module: hr_timesheet
#: wizard_field:hr_timesheet.si_so,sign_in,info:0
@@ -346,7 +346,7 @@ msgstr "Ανθρώπινο Δυναμικό (Κωδικοποίηση Φύλλω
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "mars"
-msgstr ""
+msgstr "Μάρτιος"
#. module: hr_timesheet
#: xsl:hr.analytical.timesheet:0
@@ -359,7 +359,7 @@ msgstr "Σύνολο"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "mai"
-msgstr ""
+msgstr "Μάιος"
#. module: hr_timesheet
#: wizard_button:hr_timesheet.si_so,sign_out,si_result:0
@@ -376,7 +376,7 @@ msgstr "Αλλαγή Εργασίας"
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "février"
-msgstr ""
+msgstr "Φλεβάρης"
#. module: hr_timesheet
#: view:account.analytic.account:0
@@ -463,14 +463,14 @@ msgstr "Προς Τιμολόγηση"
#: model:ir.actions.wizard,name:hr_timesheet.wizard_hr_timesheet_users
#: model:ir.ui.menu,name:hr_timesheet.menu_wizard_hr_timesheet_users
msgid "Employees Timesheet"
-msgstr ""
+msgstr "Φύλλο Xρόνου Eργασίας Υπαλλήλων"
#. module: hr_timesheet
#: selection:hr.analytical.timesheet,init,month:0
#: selection:hr.analytical.timesheet.my,init,month:0
#: selection:hr.analytical.timesheet_users,init,month:0
msgid "septembre"
-msgstr ""
+msgstr "Σεπτέμβριος"
#. module: hr_timesheet
#: view:hr.employee:0
diff --git a/addons/hr_timesheet_invoice/i18n/el.po b/addons/hr_timesheet_invoice/i18n/el.po
index 1c3db39ee70..a2dd0f16eae 100644
--- a/addons/hr_timesheet_invoice/i18n/el.po
+++ b/addons/hr_timesheet_invoice/i18n/el.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-06-15 07:20+0000\n"
-"Last-Translator: Panagiotis Kranidiotis \n"
+"PO-Revision-Date: 2009-12-19 19:10+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: nls@hellug.gr \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:17+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
@@ -37,7 +37,7 @@ msgstr "Χρήση συγκεκριμένου προϊόντος"
#. module: hr_timesheet_invoice
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: hr_timesheet_invoice
#: rml:account.analytic.profit:0
@@ -121,7 +121,7 @@ msgstr "Ως τη λήξη περιόδου"
#. module: hr_timesheet_invoice
#: wizard_button:hr.timesheet.invoice.create,init,create:0
msgid "Create Invoices"
-msgstr ""
+msgstr "Δημιουργία τιμολογίων"
#. module: hr_timesheet_invoice
#: rml:account.analytic.profit:0
diff --git a/addons/idea/i18n/ar.po b/addons/idea/i18n/ar.po
index 558dd581beb..d63a7f58039 100644
--- a/addons/idea/i18n/ar.po
+++ b/addons/idea/i18n/ar.po
@@ -7,208 +7,208 @@ 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: 2009-12-20 14:28+0000\n"
+"Last-Translator: hamada_away \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: 2009-12-16 05:14+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: idea
#: field:idea.category,name:0
#: field:idea.idea,category_id:0
msgid "Category"
-msgstr ""
+msgstr "الفئة"
#. module: idea
#: selection:idea.idea,my_vote:0
#: selection:idea.vote,score:0
#: selection:idea.vote.stat,score:0
msgid "Very Good"
-msgstr ""
+msgstr "جيد جدا"
#. module: idea
#: view:idea.idea:0
#: field:idea.idea,stat_vote_ids:0
msgid "Statistics"
-msgstr ""
+msgstr "الإحصائيات"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_idea_my_idea
#: model:ir.ui.menu,name:idea.menu_idea_idea_my_idea
msgid "My Ideas"
-msgstr ""
+msgstr "أفكاري"
#. module: idea
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "اسم النموذج غير صالح في تعريف العمل."
#. module: idea
#: selection:idea.idea,my_vote:0
#: selection:idea.vote,score:0
#: selection:idea.vote.stat,score:0
msgid "Not Voted"
-msgstr ""
+msgstr "لا تصويت"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_idea_open_my
#: model:ir.ui.menu,name:idea.menu_idea_idea_open_my
msgid "My Open Ideas"
-msgstr ""
+msgstr "أفكاري المفتوحة"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_idea
#: model:ir.ui.menu,name:idea.menu_ideas
#: model:ir.ui.menu,name:idea.menu_ideas1
msgid "Ideas"
-msgstr ""
+msgstr "أفكار"
#. module: idea
#: field:idea.category,child_ids:0
msgid "Child Categories"
-msgstr ""
+msgstr "تصنيقات فرعية"
#. module: idea
#: view:idea.idea:0
msgid "New Idea"
-msgstr ""
+msgstr "فكرة جديدة"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_category_tree
#: model:ir.ui.menu,name:idea.menu_idea_category_tree
msgid "Ideas by Categories"
-msgstr ""
+msgstr "نسخ النص الأفكار عن طريق التصنيفات"
#. module: idea
#: field:idea.vote,score:0
#: field:idea.vote.stat,score:0
msgid "Score"
-msgstr ""
+msgstr "النتيجة"
#. module: idea
#: selection:idea.idea,state:0
msgid "Draft"
-msgstr ""
+msgstr "مسوّدة"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_vote
msgid "Idea's vote"
-msgstr ""
+msgstr "فكرة تصويت"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_vote_stat
msgid "Statistics on Votes"
-msgstr ""
+msgstr "إحصاءات عن الأصوات"
#. module: idea
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
-msgstr ""
+msgstr "اسم الكائن يجب أن يبدأ ب \"_x\" ولا يحتوي على رموز خاصة"
#. module: idea
#: model:ir.model,name:idea.model_idea_category
msgid "Category for an idea"
-msgstr ""
+msgstr "تصنيف الفكره"
#. module: idea
#: model:ir.module.module,shortdesc:idea.module_meta_information
msgid "Idea Manager"
-msgstr ""
+msgstr "مدير اﻻفكار"
#. module: idea
#: model:ir.ui.menu,name:idea.menu_idea_vote_stat
msgid "Vote Statistics"
-msgstr ""
+msgstr "إحصاءات التصويت"
#. module: idea
#: selection:idea.idea,state:0
msgid "Opened"
-msgstr ""
+msgstr "مفتوحه"
#. module: idea
#: field:idea.idea,state:0
msgid "Status"
-msgstr ""
+msgstr "الحالة"
#. module: idea
#: selection:idea.idea,my_vote:0
#: selection:idea.vote,score:0
#: selection:idea.vote.stat,score:0
msgid "Good"
-msgstr ""
+msgstr "جيد"
#. module: idea
#: field:idea.idea,description:0
msgid "Description"
-msgstr ""
+msgstr "وصف"
#. module: idea
#: selection:idea.idea,my_vote:0
#: selection:idea.vote,score:0
#: selection:idea.vote.stat,score:0
msgid "Normal"
-msgstr ""
+msgstr "عادي"
#. module: idea
#: model:ir.ui.menu,name:idea.menu_reporting
msgid "Reporting"
-msgstr ""
+msgstr "التقارير"
#. module: idea
#: model:ir.model,name:idea.model_idea_vote_stat
msgid "Idea Votes Statistics"
-msgstr ""
+msgstr "إحصاء الأصوات لفكرة"
#. module: idea
#: model:ir.model,name:idea.model_idea_vote
msgid "idea.vote"
-msgstr ""
+msgstr "التصويت لفكره"
#. module: idea
#: field:idea.comment,user_id:0
#: field:idea.vote,user_id:0
msgid "User"
-msgstr ""
+msgstr "المستخدم"
#. module: idea
#: view:idea.idea:0
msgid "Your comment"
-msgstr ""
+msgstr "تعليقك"
#. module: idea
#: model:ir.ui.menu,name:idea.menu_config
msgid "Configuration"
-msgstr ""
+msgstr "الاعدادات"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_category
#: model:ir.ui.menu,name:idea.menu_idea_category
msgid "Categories"
-msgstr ""
+msgstr "الفئات"
#. module: idea
#: view:idea.stat:0
msgid "stat"
-msgstr ""
+msgstr "القانون الأساسي"
#. module: idea
#: field:idea.idea,my_vote:0
msgid "My Vote"
-msgstr ""
+msgstr "تصويتي"
#. module: idea
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "XML عرض للبنيان باطل!"
#. module: idea
#: view:idea.vote:0
msgid "Votes"
-msgstr ""
+msgstr "أصوات"
#. module: idea
#: model:ir.module.module,description:idea.module_meta_information
@@ -225,17 +225,17 @@ msgstr ""
#: field:idea.comment,create_date:0
#: field:idea.idea,create_date:0
msgid "Creation date"
-msgstr ""
+msgstr "تاريخ الإنشاء"
#. module: idea
#: field:idea.idea,count_votes:0
msgid "Count of votes"
-msgstr ""
+msgstr "فرز الأصوات"
#. module: idea
#: field:idea.vote.stat,nbr:0
msgid "Number of Votes"
-msgstr ""
+msgstr "عدد الأصوات"
#. module: idea
#: model:ir.model,name:idea.model_idea_idea
@@ -246,25 +246,25 @@ msgstr ""
#: model:ir.actions.act_window,name:idea.action_idea_idea_draft_my
#: model:ir.ui.menu,name:idea.menu_idea_idea_draft_my
msgid "My Draft Ideas"
-msgstr ""
+msgstr "مسوده افكارى"
#. module: idea
#: field:idea.idea,vote_ids:0
msgid "Vote"
-msgstr ""
+msgstr "تصويت"
#. module: idea
#: selection:idea.idea,my_vote:0
#: selection:idea.vote,score:0
#: selection:idea.vote.stat,score:0
msgid "Bad"
-msgstr ""
+msgstr "سىء"
#. module: idea
#: view:idea.idea:0
#: model:ir.ui.menu,name:idea.menu_idea_idea
msgid "All Ideas"
-msgstr ""
+msgstr "كل اﻻفكار"
#. module: idea
#: view:idea.comment:0
@@ -272,62 +272,62 @@ msgstr ""
#: field:idea.idea,comment_ids:0
#: model:ir.model,name:idea.model_idea_comment
msgid "Comments"
-msgstr ""
+msgstr "تعليقات"
#. module: idea
#: field:idea.idea,count_comments:0
msgid "Count of comments"
-msgstr ""
+msgstr "عدد التعليقات"
#. module: idea
#: field:idea.idea,title:0
msgid "Idea Summary"
-msgstr ""
+msgstr "ملخص اﻻفكار"
#. module: idea
#: view:idea.category:0
msgid "Category of ideas"
-msgstr ""
+msgstr "تصنيف الافكار"
#. module: idea
#: field:idea.category,summary:0
msgid "Summary"
-msgstr ""
+msgstr "موجز"
#. module: idea
#: model:ir.actions.act_window,name:idea.action_idea_idea_categ_open
#: model:ir.actions.act_window,name:idea.action_idea_idea_open
#: model:ir.ui.menu,name:idea.menu_idea_idea_open
msgid "Open Ideas"
-msgstr ""
+msgstr "اﻻفكار المتاحه"
#. module: idea
#: view:idea.idea:0
#: view:idea.vote.stat:0
msgid "vote_stat of ideas"
-msgstr ""
+msgstr "vote_stat of ideas"
#. module: idea
#: view:idea.comment:0
#: field:idea.comment,content:0
#: view:idea.idea:0
msgid "Comment"
-msgstr ""
+msgstr "التعليق"
#. module: idea
#: field:idea.category,parent_id:0
msgid "Parent Categories"
-msgstr ""
+msgstr "تصنيف فرعى"
#. module: idea
#: field:idea.idea,user_id:0
msgid "Creator"
-msgstr ""
+msgstr "المُنشأ"
#. module: idea
#: model:ir.ui.menu,name:idea.menu_tools
msgid "Tools"
-msgstr ""
+msgstr "أدوات"
#. module: idea
#: field:idea.comment,idea_id:0
@@ -335,46 +335,46 @@ msgstr ""
#: field:idea.vote,idea_id:0
#: field:idea.vote.stat,idea_id:0
msgid "Idea"
-msgstr ""
+msgstr "فكره"
#. module: idea
#: selection:idea.idea,my_vote:0
#: selection:idea.vote,score:0
#: selection:idea.vote.stat,score:0
msgid "Very Bad"
-msgstr ""
+msgstr "سىء جدا"
#. module: idea
#: selection:idea.idea,state:0
msgid "Canceled"
-msgstr ""
+msgstr "ملغى"
#. module: idea
#: model:ir.ui.menu,name:idea.menu_idea_vote
msgid "All Votes"
-msgstr ""
+msgstr "كل التصويتات"
#. module: idea
#: view:idea.idea:0
msgid "Cancel"
-msgstr ""
+msgstr "إلغاء"
#. module: idea
#: view:idea.idea:0
msgid "Close"
-msgstr ""
+msgstr "إغلاق"
#. module: idea
#: field:idea.idea,vote_avg:0
msgid "Average Score"
-msgstr ""
+msgstr "متوسط نقاط"
#. module: idea
#: view:idea.idea:0
msgid "Open"
-msgstr ""
+msgstr "فتح"
#. module: idea
#: help:idea.idea,description:0
msgid "Content of the idea"
-msgstr ""
+msgstr "مضمون الفكرة"
diff --git a/addons/multi_company/i18n/zh_CN.po b/addons/multi_company/i18n/zh_CN.po
new file mode 100644
index 00000000000..cbfde2794b3
--- /dev/null
+++ b/addons/multi_company/i18n/zh_CN.po
@@ -0,0 +1,192 @@
+# Chinese (Simplified) translation for openobject-addons
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2009.
+#
+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: 2009-12-19 07:40+0000\n"
+"Last-Translator: Silence \n"
+"Language-Team: Chinese (Simplified) \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+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 "对象名必须要以X_开头并且不能含有特殊字符!"
+
+#. 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 "增值税似乎不正确。"
+
+#. module: multi_company
+#: constraint:ir.actions.act_window:0
+msgid "Invalid model name in the action definition."
+msgstr "在操作定义中的模式名称无效"
+
+#. 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 "对象"
+
+#. 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 "母公司"
+
+#. module: multi_company
+#: view:multi_company.default:0
+msgid "Condition"
+msgstr "状态"
+
+#. 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 "无效XML视图结构!"
+
+#. module: multi_company
+#: field:multi_company.default,name:0
+msgid "Name"
+msgstr "名称"
+
+#. 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 "表达式"
+
+#. 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 "顺序"
+
+#. module: multi_company
+#: constraint:product.category:0
+msgid "Error ! You can not create recursive categories."
+msgstr "错误!您不能创建循环分类。"
+
+#. module: multi_company
+#: constraint:product.product:0
+msgid "Error: Invalid ean code"
+msgstr "错误:无效的(EAN)条码"
+
+#. 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 " (副本)"
+
+#. module: multi_company
+#: view:multi_company.default:0
+msgid "Matching"
+msgstr "匹配"
diff --git a/addons/product/i18n/ar.po b/addons/product/i18n/ar.po
index 021d32ead36..97522de2c4c 100644
--- a/addons/product/i18n/ar.po
+++ b/addons/product/i18n/ar.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-02-03 06:25+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-20 15:50+0000\n"
+"Last-Translator: Hend Awad \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: 2009-12-16 05:15+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: product
@@ -78,6 +78,8 @@ msgid ""
"Quantities of products that are planned to arrive in selected locations or "
"all internal if none have been selected."
msgstr ""
+"كميات المنتجات المخطط إستلامها في المواقع المحددة، أو كل المخازن الداخليه في "
+"حالة عدم تحديد أي من الإختيارات"
#. module: product
#: help:product.product,virtual_available:0
@@ -90,7 +92,7 @@ msgstr ""
#. module: product
#: field:product.packaging,width:0
msgid "Width"
-msgstr ""
+msgstr "العرض"
#. module: product
#: help:product.pricelist.item,product_tmpl_id:0
@@ -102,17 +104,17 @@ msgstr ""
#. module: product
#: field:product.template,procure_method:0
msgid "Procure Method"
-msgstr ""
+msgstr "أسلوب الشراء"
#. module: product
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "اسم النموذج غير صالح في تعريف العمل."
#. module: product
#: model:process.process,name:product.process_process_productprocess0
msgid "Product Process"
-msgstr ""
+msgstr "عملية الإنتاج"
#. module: product
#: help:product.price.type,field:0
@@ -122,22 +124,22 @@ msgstr ""
#. module: product
#: selection:product.template,cost_method:0
msgid "Standard Price"
-msgstr ""
+msgstr "السعر القياسي"
#. module: product
#: help:product.packaging,height:0
msgid "The height of the package"
-msgstr ""
+msgstr "إرتفاع عبوة التخزين"
#. module: product
#: view:product.pricelist:0
msgid "Products Price List"
-msgstr ""
+msgstr "قائمة أسعار المنتجات"
#. module: product
#: model:product.category,name:product.cat1
msgid "Sellable"
-msgstr ""
+msgstr "قابل للبيع"
#. module: product
#: model:product.template,name:product.product_product_26_product_template
@@ -152,12 +154,12 @@ msgstr ""
#. module: product
#: field:product.product,price:0
msgid "Customer Price"
-msgstr ""
+msgstr "سعر العميل/المستهلك"
#. module: product
#: field:product.template,company_id:0
msgid "Company"
-msgstr ""
+msgstr "الشركة"
#. module: product
#: field:product.template,rental:0
@@ -173,7 +175,7 @@ msgstr ""
#: model:ir.actions.act_window,name:product.product_price_type_action
#: model:ir.ui.menu,name:product.menu_product_price_type_action
msgid "Prices Types"
-msgstr ""
+msgstr "أنواع الأسعار/ التسعير"
#. module: product
#: selection:product.template,type:0
@@ -183,7 +185,7 @@ msgstr ""
#. module: product
#: model:product.category,name:product.product_category_services
msgid "Services"
-msgstr ""
+msgstr "الخدمات"
#. module: product
#: help:product.template,list_price:0
@@ -191,11 +193,12 @@ msgid ""
"Base price for computing the customer price. Sometimes called the catalog "
"price."
msgstr ""
+"السعر الأساسي (لحساب سعر البيع للعميل/المستهلك و يسمي أحيانا سعر الكاتالوج)"
#. module: product
#: field:pricelist.partnerinfo,min_quantity:0
msgid "Quantity"
-msgstr ""
+msgstr "الكمية"
#. module: product
#: model:product.template,name:product.product_product_cpu3_product_template
@@ -210,12 +213,12 @@ msgstr ""
#. module: product
#: help:product.pricelist.version,date_start:0
msgid "Starting date for this pricelist version to be valid."
-msgstr ""
+msgstr "تاريخ بدء صلاحية قائمة الأسعار"
#. module: product
#: field:product.product,incoming_qty:0
msgid "Incoming"
-msgstr ""
+msgstr "الوارد"
#. module: product
#: selection:product.template,procure_method:0
@@ -226,7 +229,7 @@ msgstr ""
#: view:product.product:0
#: view:product.template:0
msgid "Weigths"
-msgstr ""
+msgstr "الأوزان"
#. module: product
#: model:product.template,name:product.product_product_fan2_product_template
@@ -243,7 +246,7 @@ msgstr ""
#. module: product
#: model:process.transition,note:product.process_transition_supplierofproduct0
msgid "You can see the list of suppliers for that product."
-msgstr ""
+msgstr "يمكنك الإطلاع علي قائمة مورّدي هذا المنتج"
#. module: product
#: help:product.packaging,rows:0
@@ -254,7 +257,7 @@ msgstr ""
#: model:product.pricelist.type,name:product.pricelist_type_sale
#: field:res.partner,property_product_pricelist:0
msgid "Sale Pricelist"
-msgstr ""
+msgstr "قائمة اسعار البيع"
#. module: product
#: field:product.pricelist.item,base_pricelist_id:0
@@ -268,7 +271,7 @@ msgstr ""
#: model:ir.ui.menu,name:product.menu_products
#: view:product.product:0
msgid "Products"
-msgstr ""
+msgstr "المنتجات"
#. module: product
#: help:product.pricelist.item,price_round:0
@@ -281,23 +284,23 @@ msgstr ""
#. module: product
#: view:product.pricelist.item:0
msgid "New Price ="
-msgstr ""
+msgstr "السعر الجديد ="
#. module: product
#: field:product.product,virtual_available:0
msgid "Virtual Stock"
-msgstr ""
+msgstr "المخازن الإفتراضية"
#. module: product
#: selection:product.template,mes_type:0
msgid "Fixed"
-msgstr ""
+msgstr "ثابت"
#. module: product
#: model:ir.actions.act_window,name:product.product_uom_categ_form_action
#: model:ir.ui.menu,name:product.menu_product_uom_categ_form_action
msgid "Units of Measure Categories"
-msgstr ""
+msgstr "وحدات القياس"
#. module: product
#: help:product.pricelist.item,product_id:0
@@ -311,18 +314,18 @@ msgstr ""
#: field:product.pricelist,type:0
#: view:product.pricelist.type:0
msgid "Pricelist Type"
-msgstr ""
+msgstr "نوع قائمة الأسعار"
#. module: product
#: view:product.product:0
#: view:product.template:0
msgid "Base Prices"
-msgstr ""
+msgstr "السعر الأساسي"
#. module: product
#: model:ir.ui.menu,name:product.menu_price
msgid "Prices Computations"
-msgstr ""
+msgstr "حساب الأسعار"
#. module: product
#: field:product.pricelist.item,name:0
@@ -332,7 +335,7 @@ msgstr ""
#. module: product
#: model:ir.ui.menu,name:product.menu_config_product
msgid "Configuration"
-msgstr ""
+msgstr "الإعدادات"
#. module: product
#: field:product.packaging,rows:0
diff --git a/addons/product/i18n/zh_CN.po b/addons/product/i18n/zh_CN.po
index a1e4b4bd4bc..514e4feb40b 100644
--- a/addons/product/i18n/zh_CN.po
+++ b/addons/product/i18n/zh_CN.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-12-18 02:27+0000\n"
+"PO-Revision-Date: 2009-12-18 09:29+0000\n"
"Last-Translator: Jeroen Vet \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: 2009-12-18 04:32+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: product
@@ -470,7 +470,7 @@ msgstr "根据需求硬盘型号"
#: field:product.uom,factor_inv:0
#: field:product.uom,factor_inv_data:0
msgid "Factor"
-msgstr "满意度"
+msgstr "因数"
#. module: product
#: wizard_button:product.price_list,init,price:0
@@ -580,7 +580,7 @@ msgstr "价格表版本"
#. module: product
#: view:product.pricelist.item:0
msgid "Rules Test Match"
-msgstr "定价规则"
+msgstr "规则匹配测试"
#. module: product
#: help:res.partner,property_product_pricelist:0
@@ -704,7 +704,7 @@ msgstr "希捷 7200.8 160GB 硬盘"
#. module: product
#: view:product.product:0
msgid "Product Variant"
-msgstr "产品系列"
+msgstr "产品变体"
#. module: product
#: field:product.packaging,ul:0
@@ -729,7 +729,7 @@ msgstr "装箱"
#. module: product
#: field:product.product,ean13:0
msgid "EAN13"
-msgstr "条码"
+msgstr "(EAN13)欧洲商品编号"
#. module: product
#: view:product.product:0
@@ -768,7 +768,7 @@ msgstr "业务伙伴货品名称将用在询价上。留空为使用内部名称
#. module: product
#: field:product.template,supply_method:0
msgid "Supply method"
-msgstr "采购方式"
+msgstr "供应方式"
#. module: product
#: model:product.category,name:product.product_category_11
@@ -785,7 +785,7 @@ msgstr "计量单位分类"
#: field:product.packaging,sequence:0
#: field:product.pricelist.item,sequence:0
msgid "Sequence"
-msgstr "序号"
+msgstr "顺序"
#. module: product
#: view:product.supplierinfo:0
@@ -800,7 +800,7 @@ msgstr "供应商信息"
#: view:product.product:0
#: view:product.ul:0
msgid "Packaging"
-msgstr "装箱"
+msgstr "包装"
#. module: product
#: field:product.price.type,currency_id:0
@@ -941,13 +941,13 @@ msgid ""
"Used by companies that manages two unit of measure: invoicing and inventory "
"management. For example, in food industries, you will manage a stock of ham "
"but invoice in Kg. Keep empty to use the default UOM."
-msgstr ""
+msgstr "处理发票和库存管理两个计量单位的公司使用。例如,在食品工业中,您在库存中管理火腿,但发票使用公斤为计量单位。留空以使用默认计量单位。"
#. module: product
#: view:product.product:0
#: view:product.template:0
msgid "Procurement & Locations"
-msgstr "采购与货位"
+msgstr "需求单与地点"
#. module: product
#: view:product.product:0
@@ -1071,7 +1071,7 @@ msgstr "pricelist.partnerinfo"
#: model:product.price.type,name:product.standard_price
#: field:product.template,standard_price:0
msgid "Cost Price"
-msgstr "标准价格"
+msgstr "成本价格"
#. module: product
#: view:product.product:0
@@ -1110,7 +1110,7 @@ msgstr "最小价格差额"
#. module: product
#: help:product.packaging,ean:0
msgid "The EAN code of the package unit."
-msgstr "包装上的条码"
+msgstr "包装的欧洲商品编号(EAN)"
#. module: product
#: field:product.template,weight:0
@@ -1285,7 +1285,7 @@ msgstr "根据要求内存容量"
#: selection:product.ul,type:0
#: model:product.uom.categ,name:product.product_uom_categ_unit
msgid "Unit"
-msgstr "个"
+msgstr "单位"
#. module: product
#: model:product.template,name:product.product_product_hdd2_product_template
@@ -1463,7 +1463,7 @@ msgstr "生产"
#. module: product
#: selection:product.template,procure_method:0
msgid "Make to Order"
-msgstr "来单生产"
+msgstr "订货型生产"
#. module: product
#: field:product.pricelist.item,price_surcharge:0
@@ -1545,7 +1545,7 @@ msgstr "可采购"
#. module: product
#: field:product.template,uos_coeff:0
msgid "UOM -> UOS Coeff"
-msgstr "UOM -> UOS系数"
+msgstr "计量单位->销售单位 系数"
#. module: product
#: model:product.template,name:product.product_product_cpu2_product_template
@@ -1582,7 +1582,7 @@ msgstr "满箱或托盘重量"
#. module: product
#: selection:product.template,state:0
msgid "End of Lifecycle"
-msgstr "周期结束"
+msgstr "生命周期终止"
#. module: product
#: model:ir.module.module,shortdesc:product.module_meta_information
@@ -1672,7 +1672,7 @@ msgstr "采购订单采用的计量单位。它必须与默认计量单位属于
#. module: product
#: constraint:product.product:0
msgid "Error: Invalid ean code"
-msgstr "错误:无效的条码"
+msgstr "错误:无效的(EAN)条码"
#. module: product
#: field:product.pricelist.item,min_quantity:0
@@ -1709,4 +1709,4 @@ msgstr "千克"
#. module: product
#: field:product.pricelist.item,price_discount:0
msgid "Price Discount"
-msgstr "折扣"
+msgstr "降价"
diff --git a/addons/profile_service/i18n/zh_CN.po b/addons/profile_service/i18n/zh_CN.po
index 352217b3098..79cb0da325f 100644
--- a/addons/profile_service/i18n/zh_CN.po
+++ b/addons/profile_service/i18n/zh_CN.po
@@ -7,30 +7,30 @@ 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-01-30 13:15+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-18 11:03+0000\n"
+"Last-Translator: Silence \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: 2009-12-16 05:15+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: profile_service
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
-msgstr ""
+msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
#. module: profile_service
#: view:profile.service.config.install_modules_wizard:0
msgid "Services Management"
-msgstr ""
+msgstr "服务管理"
#. module: profile_service
#: view:profile.service.config.install_modules_wizard:0
msgid "Relationship Management"
-msgstr ""
+msgstr "关系管理"
#. module: profile_service
#: help:profile.service.config.install_modules_wizard,project_mrp:0
@@ -54,6 +54,8 @@ msgid ""
"documents, printed reports, calendar system). It opens an FTP access for the "
"users to easily browse association's document."
msgstr ""
+"Open ERP的单据管理系统,运行你保存、浏览、自动索引、搜索和预览所有单据(包括内部单据、打印报表、日历系统)。It opens an FTP "
+"access for the users to easily browse association's document."
#. module: profile_service
#: help:profile.service.config.install_modules_wizard,account_budget_crossover:0
@@ -65,7 +67,7 @@ msgstr ""
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,project_timesheet:0
msgid "Timesheets"
-msgstr ""
+msgstr "时间表"
#. module: profile_service
#: constraint:ir.actions.act_window:0
@@ -75,7 +77,7 @@ msgstr ""
#. module: profile_service
#: view:profile.service.config.install_modules_wizard:0
msgid "Resources Management"
-msgstr ""
+msgstr "资源管理"
#. module: profile_service
#: model:ir.actions.act_window,name:profile_service.action_config_install_module
@@ -108,7 +110,7 @@ msgstr ""
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,board_document:0
msgid "Document Management"
-msgstr ""
+msgstr "文档管理"
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,portal:0
@@ -125,7 +127,7 @@ msgstr ""
#. module: profile_service
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "无效XML视图结构!"
#. module: profile_service
#: help:profile.service.config.install_modules_wizard,scrum:0
@@ -160,7 +162,7 @@ msgstr ""
#. module: profile_service
#: view:profile.service.config.install_modules_wizard:0
msgid "Install"
-msgstr ""
+msgstr "安装"
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,hr_expense:0
@@ -175,7 +177,7 @@ msgstr ""
#. module: profile_service
#: view:profile.service.config.install_modules_wizard:0
msgid "Install Extra Module"
-msgstr ""
+msgstr "安装扩展模块"
#. module: profile_service
#: help:profile.service.config.install_modules_wizard,project_timesheet:0
@@ -187,12 +189,12 @@ msgstr ""
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,wiki:0
msgid "Wiki"
-msgstr ""
+msgstr "Wiki"
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,project_gtd:0
msgid "Getting Things Done"
-msgstr ""
+msgstr "把事情做好"
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,hr_timesheet_invoice:0
@@ -227,7 +229,7 @@ msgstr ""
#. module: profile_service
#: field:profile.service.config.install_modules_wizard,project_mrp:0
msgid "Sales Management"
-msgstr ""
+msgstr "销售管理"
#. module: profile_service
#: model:ir.module.module,description:profile_service.module_meta_information
@@ -237,7 +239,7 @@ msgstr ""
#. module: profile_service
#: view:profile.service.config.install_modules_wizard:0
msgid "Cancel"
-msgstr ""
+msgstr "取消"
#. module: profile_service
#: help:profile.service.config.install_modules_wizard,base_contact:0
diff --git a/addons/project_mrp/i18n/zh_CN.po b/addons/project_mrp/i18n/zh_CN.po
index bee6fe216fd..856ef88ec46 100644
--- a/addons/project_mrp/i18n/zh_CN.po
+++ b/addons/project_mrp/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-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-01-30 13:15+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-18 11:07+0000\n"
+"Last-Translator: Silence \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: 2009-12-16 05:18+0000\n"
+"X-Launchpad-Export-Date: 2009-12-19 04:33+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: project_mrp
@@ -25,7 +25,7 @@ msgstr ""
#: model:process.node,name:project_mrp.process_node_mrptask0
#: model:process.node,name:project_mrp.process_node_procuretasktask0
msgid "Task"
-msgstr ""
+msgstr "任务"
#. module: project_mrp
#: model:process.transition,note:project_mrp.process_transition_ordertask0
@@ -40,7 +40,7 @@ msgstr ""
#. module: project_mrp
#: field:project.task,procurement_id:0
msgid "Procurement"
-msgstr ""
+msgstr "需求单"
#. module: project_mrp
#: model:process.transition,note:project_mrp.process_transition_createtask0
diff --git a/addons/purchase/i18n/zh_CN.po b/addons/purchase/i18n/zh_CN.po
index d3971153442..d224e34c91c 100644
--- a/addons/purchase/i18n/zh_CN.po
+++ b/addons/purchase/i18n/zh_CN.po
@@ -7,44 +7,44 @@ 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-12-03 13:38+0000\n"
-"Last-Translator: Wei \"oldrev\" Li \n"
+"PO-Revision-Date: 2009-12-21 04:01+0000\n"
+"Last-Translator: Jeroen Vet \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: 2009-12-16 05:06+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: purchase
#: field:purchase.order,invoiced:0
msgid "Invoiced & Paid"
-msgstr "已开票"
+msgstr "已开票并付清"
#. module: purchase
#: model:process.node,note:purchase.process_node_invoiceafterpacking0
msgid "Supplier Invoice pre-generated on receptions for control"
-msgstr ""
+msgstr "收货时预生成供应商的发票用来核对"
#. module: purchase
#: field:purchase.order,location_id:0
msgid "Destination"
-msgstr "目的地"
+msgstr "目的货位"
#. module: purchase
#: selection:purchase.order,invoice_method:0
msgid "From Picking"
-msgstr ""
+msgstr "根据分拣"
#. module: purchase
#: rml:purchase.order:0
msgid "Validated By"
-msgstr "确认人"
+msgstr "审核人"
#. module: purchase
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr "操作定义中使用了无效的模式名称。"
+msgstr "在行动定义中的模式名称无效"
#. module: purchase
#: field:purchase.order,partner_id:0
@@ -54,7 +54,7 @@ msgstr "供应商"
#. module: purchase
#: view:purchase.order:0
msgid "Delivery"
-msgstr "交货"
+msgstr "递送"
#. module: purchase
#: field:purchase.order.line,product_qty:0
@@ -64,7 +64,7 @@ msgstr "数量"
#. module: purchase
#: selection:purchase.order,invoice_method:0
msgid "From Order"
-msgstr "来自订单"
+msgstr "根据采购订单"
#. module: purchase
#: model:process.node,name:purchase.process_node_confirmpurchaseorder0
@@ -74,7 +74,7 @@ msgstr "已确认采购"
#. module: purchase
#: selection:purchase.order,state:0
msgid "Invoice Exception"
-msgstr "发票例外项"
+msgstr "发票异常"
#. module: purchase
#: model:product.pricelist,name:purchase.list0
@@ -91,7 +91,7 @@ msgstr "创建发票"
msgid ""
"This pricelist will be used, instead of the default one, for purchases from "
"the current partner"
-msgstr "当从当前业务伙伴采购时该价格表将替代默认价格表"
+msgstr "这价格表将取代默认的价格表用于当前业务伙伴采购"
#. module: purchase
#: rml:purchase.order:0
@@ -101,14 +101,14 @@ msgstr "传真:"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_productrecept0
msgid "Create invoice from product recept"
-msgstr "从货品收据创建发票"
+msgstr "根据收货分拣创建发票"
#. module: purchase
#: help:purchase.order,pricelist_id:0
msgid ""
"The pricelist sets the currency used for this purchase order. It also "
"computes the supplier price for the selected products/quantities."
-msgstr ""
+msgstr "该采购订单货币是被价格表设定.它还计算选定产品的供应商价格/数量"
#. module: purchase
#: model:process.process,name:purchase.process_process_purchaseprocess0
@@ -123,7 +123,7 @@ msgstr "装箱单发票"
#. module: purchase
#: view:purchase.order:0
msgid "Approve Purchase"
-msgstr "审核采购"
+msgstr "批准采购"
#. module: purchase
#: selection:purchase.order,state:0
@@ -154,7 +154,7 @@ msgstr "注解"
#: field:purchase.order,amount_tax:0
#: field:purchase.order.line,taxes_id:0
msgid "Taxes"
-msgstr "税"
+msgstr "税收"
#. module: purchase
#: model:ir.actions.report.xml,name:purchase.report_purchase_order
@@ -168,12 +168,12 @@ msgstr "采购订单"
#. module: purchase
#: rml:purchase.quotation:0
msgid "Regards,"
-msgstr "致意,"
+msgstr "敬意,"
#. module: purchase
#: rml:purchase.order:0
msgid "Net Total :"
-msgstr "总净重:"
+msgstr "净总额:"
#. module: purchase
#: selection:purchase.order,state:0
@@ -190,6 +190,8 @@ msgid ""
"received, the state becomes 'Done'. If a cancel action occurs in the invoice "
"or in the reception of goods, the state becomes in exception."
msgstr ""
+"该采购订单或报价请求的状态。报价请求是'草稿'状态下的采购订单。报价请求必须被用户确认,状态才能转变为‘确认’。然后,供应商必须确认采购订单,以将状态改变"
+"为‘批准’。当采购订单支付和接收,状态变成‘完成’。如果在发票或在货物接收时取消,状态则变为‘异常’。"
#. module: purchase
#: field:purchase.order,origin:0
@@ -199,7 +201,7 @@ msgstr "来源"
#. module: purchase
#: model:process.node,name:purchase.process_node_packinglist0
msgid "Incoming Products"
-msgstr "进来的产品"
+msgstr "入库货品"
#. module: purchase
#: rml:purchase.order:0
@@ -210,12 +212,12 @@ msgstr "数量"
#. module: purchase
#: view:purchase.order:0
msgid "Manually Corrected"
-msgstr "已是手工修正"
+msgstr "手动更正"
#. module: purchase
#: view:purchase.order:0
msgid "Reference"
-msgstr "引用"
+msgstr "参照"
#. module: purchase
#: rml:purchase.order:0
@@ -256,7 +258,7 @@ msgstr ""
#. module: purchase
#: model:process.node,note:purchase.process_node_packinginvoice0
msgid "Invoice based on deliveries"
-msgstr ""
+msgstr "根据收货分拣创建发票"
#. module: purchase
#: rml:purchase.order:0
@@ -266,7 +268,7 @@ msgstr "净价"
#. module: purchase
#: view:purchase.order.line:0
msgid "Order Line"
-msgstr "订单行"
+msgstr "采购订单明细"
#. module: purchase
#: selection:purchase.order,state:0
@@ -276,7 +278,7 @@ msgstr "已审核"
#. module: purchase
#: model:process.node,name:purchase.process_node_productrecept0
msgid "Product Receipt"
-msgstr "商品收据"
+msgstr "接收货品"
#. module: purchase
#: model:process.transition.action,name:purchase.process_transition_action_confirmpurchaseorder0
@@ -286,13 +288,13 @@ msgstr "确认"
#. module: purchase
#: view:purchase.order:0
msgid "Invoice Control"
-msgstr "发票管理"
+msgstr "发票核对"
#. module: purchase
#: model:process.node,name:purchase.process_node_draftpurchaseorder0
#: model:process.node,name:purchase.process_node_draftpurchaseorder1
msgid "RFQ"
-msgstr "询价请求"
+msgstr "报价请求"
#. module: purchase
#: selection:purchase.order,state:0
@@ -302,7 +304,7 @@ msgstr "等待中"
#. module: purchase
#: field:purchase.order,picking_ids:0
msgid "Picking List"
-msgstr "领料单"
+msgstr "分拣单"
#. module: purchase
#: field:purchase.order,warehouse_id:0
@@ -312,12 +314,12 @@ msgstr "仓库"
#. module: purchase
#: field:purchase.order,order_line:0
msgid "Order Lines"
-msgstr "订单细目"
+msgstr "采购订单细目"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_confirmingpurchaseorder1
msgid "Confirm Purchase order from Request for quotation without origin"
-msgstr ""
+msgstr "确认没有单据来源的报价请求转为采购订单"
#. module: purchase
#: rml:purchase.quotation:0
@@ -358,7 +360,7 @@ msgstr "供应商审核通过"
#. module: purchase
#: model:ir.actions.act_window,name:purchase.act_purchase_order_2_stock_picking
msgid "Packing"
-msgstr "装箱"
+msgstr "分拣"
#. module: purchase
#: model:ir.actions.wizard,name:purchase.purchase_order_merge
@@ -373,7 +375,7 @@ msgstr "预定目的地"
#. module: purchase
#: field:purchase.order,name:0
msgid "Order Reference"
-msgstr "订单引用"
+msgstr "订单编号"
#. module: purchase
#: selection:purchase.order,state:0
@@ -388,7 +390,7 @@ msgstr "价格表"
#. module: purchase
#: model:process.node,note:purchase.process_node_purchaseorder0
msgid "When controlling invoice from orders"
-msgstr ""
+msgstr "当从采购订单核对发票"
#. module: purchase
#: constraint:ir.ui.view:0
@@ -398,27 +400,27 @@ msgstr "无效的 XML 视图结构"
#. module: purchase
#: model:process.node,note:purchase.process_node_invoicecontrol0
msgid "Pre-generated supplier invoice to control based on order"
-msgstr ""
+msgstr "根据采购订单预生成供应商发票用来核对"
#. module: purchase
#: model:process.transition,name:purchase.process_transition_invoicefrompurchase0
msgid "Invoice from Purchase"
-msgstr "采购发票"
+msgstr "根据采购订单生成发票"
#. module: purchase
#: model:process.node,note:purchase.process_node_packinglist0
msgid "Packing is created for the products reception control."
-msgstr ""
+msgstr "创建分拣单用来核对货品接收"
#. module: purchase
#: selection:purchase.order,invoice_method:0
msgid "Manual"
-msgstr "手工"
+msgstr "手动"
#. module: purchase
#: model:process.transition,name:purchase.process_transition_confirmingpurchaseorder1
msgid "Confirming Purchase"
-msgstr "确认采购"
+msgstr "确认采购订单"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_approvingpurchaseorder0
@@ -428,19 +430,19 @@ msgstr "确认后批准采购订单"
#. module: purchase
#: selection:purchase.order,state:0
msgid "Shipping Exception"
-msgstr ""
+msgstr "运送异常"
#. module: purchase
#: model:process.node,note:purchase.process_node_draftpurchaseorder1
msgid "Encoded manually by the user."
-msgstr "用户手工编号。"
+msgstr "用户手动输入。"
#. module: purchase
#: help:purchase.order,minimum_planned_date:0
msgid ""
"This is computed as the minimum scheduled date of all purchase order lines' "
"products."
-msgstr ""
+msgstr "该计算作为采购所有明细中货品的最早计划日期"
#. module: purchase
#: model:ir.actions.act_window,name:purchase.act_res_partner_2_purchase_order
@@ -453,28 +455,28 @@ msgid ""
"Put an address if you want to deliver directly from the supplier to the "
"customer.In this case, it will remove the warehouse link and set the "
"customer location."
-msgstr ""
+msgstr "如果你想直接从供应商送货到客户请填入地址.在这种情况下,它将删除与仓库的链接并设置客户地址。"
#. module: purchase
#: rml:purchase.quotation:0
msgid "Request for Quotation :"
-msgstr "询价请求:"
+msgstr "报价请求:"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_confirmingpurchaseorder0
msgid "Confirm Purchase order from Request for quotation"
-msgstr "从询价请求确认采购订单"
+msgstr "以报价请求确认转为采购订单"
#. module: purchase
#: view:purchase.order:0
msgid "Confirm Purchase Order"
-msgstr "审核采购单"
+msgstr "审核采购订单"
#. module: purchase
#: help:purchase.order,picking_ids:0
msgid ""
"This is the list of picking list that have been generated for this purchase"
-msgstr "这是为本次采购生成的装箱单列表"
+msgstr "这是为本次采购生成的分拣单列表"
#. module: purchase
#: model:ir.module.module,shortdesc:purchase.module_meta_information
@@ -485,7 +487,7 @@ msgstr "采购管理"
#. module: purchase
#: field:purchase.order,partner_ref:0
msgid "Partner Ref."
-msgstr "业务伙伴引用"
+msgstr "业务伙伴编号"
#. module: purchase
#: rml:purchase.order:0
@@ -537,22 +539,22 @@ msgstr "采购订单"
#. module: purchase
#: model:process.node,note:purchase.process_node_draftpurchaseorder0
msgid "Request for quotation is proposed by the system."
-msgstr "询价请求已由系统提出。"
+msgstr "报价请求已由系统提出。"
#. module: purchase
#: model:process.transition,name:purchase.process_transition_packinginvoice0
msgid "Packing Invoice"
-msgstr "包装发票"
+msgstr "分拣单发票"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_invoicefrompackinglist0
msgid "Creates invoice from packin list"
-msgstr ""
+msgstr "根据分拣单生成发票"
#. module: purchase
#: help:purchase.order,date_order:0
msgid "Date on which this document has been created."
-msgstr ""
+msgstr "该文件已创建日期"
#. module: purchase
#: view:purchase.order:0
diff --git a/addons/report_analytic/i18n/el.po b/addons/report_analytic/i18n/el.po
index 55b2ec49aaa..db38b6e9f2a 100644
--- a/addons/report_analytic/i18n/el.po
+++ b/addons/report_analytic/i18n/el.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-09-08 14:43+0000\n"
-"Last-Translator: Makis Nicolaou \n"
+"PO-Revision-Date: 2009-12-19 19:13+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
"Language-Team: Greek \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:06+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_analytic
@@ -58,7 +58,7 @@ msgstr "Χρονικό Όριο"
#. module: report_analytic
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
#. module: report_analytic
#: model:ir.module.module,shortdesc:report_analytic.module_meta_information
diff --git a/addons/report_crm/i18n/el.po b/addons/report_crm/i18n/el.po
new file mode 100644
index 00000000000..184db1b0bd4
--- /dev/null
+++ b/addons/report_crm/i18n/el.po
@@ -0,0 +1,339 @@
+# Greek translation for openobject-addons
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2009.
+#
+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: 2009-12-19 16:49+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
+"Language-Team: Greek \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#. module: report_crm
+#: field:report.crm.case.categ,categ_id:0
+msgid "Category"
+msgstr "Κατηγορία"
+
+#. module: report_crm
+#: field:report.crm.case.categ,probability:0
+#: field:report.crm.case.user,probability:0
+msgid "Avg. Probability"
+msgstr "Μέση πιθανότητα"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,planned_revenue:0
+msgid "Planned Revenue"
+msgstr "Προγραμματισμένα Έσοδα"
+
+#. module: report_crm
+#: constraint:ir.actions.act_window:0
+msgid "Invalid model name in the action definition."
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
+
+#. module: report_crm
+#: model:ir.model,name:report_crm.model_report_crm_case_categ
+msgid "Cases by section and category"
+msgstr "Θέματα ανά τμήμα και κατηγορία"
+
+#. module: report_crm
+#: field:report.crm.case.categ,section_id:0
+#: field:report.crm.case.section,section_id:0
+#: field:report.crm.case.user,section_id:0
+msgid "Section"
+msgstr "Τμήμα"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,user_id:0
+msgid "Responsible"
+msgstr "Υπεύθυνος"
+
+#. module: report_crm
+#: field:report.crm.case.section,perc_done:0
+msgid "%Done"
+msgstr "%Έτοιμο"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,planned_cost:0
+msgid "Planned Costs"
+msgstr "Προγραμματισμένο Κόστος"
+
+#. module: report_crm
+#: field:report.crm.case.section,nbr_cases:0
+#: field:report.crm.case.user,nbr:0
+msgid "# of Cases"
+msgstr "# Θεμάτων"
+
+#. module: report_crm
+#: model:ir.module.module,shortdesc:report_crm.module_meta_information
+msgid "CRM Management - Reporting"
+msgstr "Διαχείρηση CRM - Αναφορές"
+
+#. module: report_crm
+#: field:report.crm.case.categ,delay_close:0
+msgid "Delay Close"
+msgstr "Καθυστέρηση Κλεισίματος"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_section_tree
+#: model:ir.model,name:report_crm.model_report_crm_case_section
+#: view:report.crm.case.section:0
+msgid "Cases by Section"
+msgstr "Θέματα ανά τμήμα"
+
+#. module: report_crm
+#: selection:report.crm.case.categ,state:0
+#: selection:report.crm.case.service.dashboard,state:0
+#: selection:report.crm.case.user,state:0
+msgid "Draft"
+msgstr "Πρόχειρο"
+
+#. module: report_crm
+#: selection:report.crm.case.categ,state:0
+#: selection:report.crm.case.service.dashboard,state:0
+#: selection:report.crm.case.user,state:0
+msgid "Closed"
+msgstr "Κλειστό"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_categ_tree_month
+#: model:ir.ui.menu,name:report_crm.menu_crm_case_categ_tree_month
+msgid "Cases by categories and section (this month)"
+msgstr "Θέματα ανά κατηγορία και τμήμα (αυτόν τον μήνα)"
+
+#. module: report_crm
+#: model:ir.ui.menu,name:report_crm.next_id_66
+msgid "All Months"
+msgstr "Όλοι οι Μήνες"
+
+#. module: report_crm
+#: constraint:ir.model:0
+msgid ""
+"The Object name must start with x_ and not contain any special character !"
+msgstr ""
+"Το όνομα του αντικειμένου πρέπει να ξεκινάει από x_ και να μην περιέχει "
+"ειδικούς χαρακτήρες!"
+
+#. module: report_crm
+#: field:report.crm.case.categ,amount_revenue_prob:0
+#: field:report.crm.case.user,amount_revenue_prob:0
+msgid "Est. Rev*Prob."
+msgstr "Εκτίμηση Έσοδα*Πιθανότητα"
+
+#. module: report_crm
+#: selection:report.crm.case.categ,state:0
+#: selection:report.crm.case.service.dashboard,state:0
+#: selection:report.crm.case.user,state:0
+msgid "Pending"
+msgstr "Εκκρεμμή"
+
+#. module: report_crm
+#: field:report.crm.case.section,avg_answers:0
+msgid "Avg. Answers"
+msgstr "Μέσος όρος Απαντήσεων"
+
+#. module: report_crm
+#: field:report.crm.case.categ,state:0
+#: field:report.crm.case.service.dashboard,state:0
+#: field:report.crm.case.user,state:0
+msgid "Status"
+msgstr "Κατάσταση"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,name:0
+msgid "Description"
+msgstr "Περιγραφή"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_user_tree_month
+#: model:ir.ui.menu,name:report_crm.menu_crm_case_user_tree_month
+msgid "Cases by user and section (this month)"
+msgstr "Θέματα ανά χρήστη και τμήμα (αυτόν τον μήνα)"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.act_crm_case_section_2_report_crm_case_user
+msgid "Monthly cases by user"
+msgstr "Θέματα ανά χρήστη και μήνα"
+
+#. module: report_crm
+#: model:ir.ui.menu,name:report_crm.next_id_64
+msgid "Reporting"
+msgstr "Αναφορές"
+
+#. module: report_crm
+#: view:report.crm.case.service.dashboard:0
+msgid "Planned costs"
+msgstr "Προγραμματισμένα κόστοι"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_view_closed_crm_case_dashboard
+msgid "Closed CRM Cases Within Past 15 Days"
+msgstr "Κλεισμένα θέματα CRM τις τελευταίες 15 ημέρες"
+
+#. module: report_crm
+#: field:report.crm.case.categ,amount_costs:0
+#: field:report.crm.case.user,amount_costs:0
+msgid "Est.Cost"
+msgstr "Εκτιμώμενο κόστος"
+
+#. module: report_crm
+#: field:report.crm.case.user,user_id:0
+msgid "User"
+msgstr "Χρήστης"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.act_crm_case_section_2_report_crm_case_categ
+msgid "Monthly cases by section"
+msgstr "Θέματα ανά τμήμα και μήνα"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,date:0
+msgid "Date"
+msgstr "Ημερομηνία"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_user_tree_month_my
+#: model:ir.ui.menu,name:report_crm.menu_crm_case_user_tree_month_my
+msgid "My cases by section (this month)"
+msgstr "Τα θέματα μου ανά τμήμα (αυτόν τον μήνα)"
+
+#. module: report_crm
+#: model:ir.ui.menu,name:report_crm.next_id_65
+msgid "This Month"
+msgstr "Αυτόν τον μήνα"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_view_open_crm_case_dashboard
+msgid "Open CRM Cases Within Past 15 Days"
+msgstr "Ανοιχτά θέματα CRM τις τελευταίες 15 ημέρες"
+
+#. module: report_crm
+#: constraint:ir.ui.view:0
+msgid "Invalid XML for View Architecture!"
+msgstr "Άκυρο XML για την Αρχιτεκτονική Όψης!"
+
+#. module: report_crm
+#: model:ir.model,name:report_crm.model_report_crm_case_service_dashboard
+msgid "Report of Closed and Open CRM Cases within past 15 days"
+msgstr ""
+"Αναφορά των ανοικτών και κλειστών θεμάτων CRM τις τελευταίες 15 ημέρες"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_user_tree
+#: model:ir.ui.menu,name:report_crm.menu_crm_case_user_tree
+#: view:report.crm.case.categ:0
+#: view:report.crm.case.user:0
+msgid "Cases by User and Section"
+msgstr "Θέματα ανά Χρήστη και Τμήμα"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.act_crm_case_categ_2_report_crm_case_categ
+#: model:ir.actions.act_window,name:report_crm.act_res_users_2_report_crm_case_user
+msgid "Monthly cases"
+msgstr "Θέματα ανά μήνα"
+
+#. module: report_crm
+#: field:report.crm.case.categ,amount_revenue:0
+#: field:report.crm.case.user,amount_revenue:0
+msgid "Est.Revenue"
+msgstr "Εκτιμ. Έσοδα"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,date_closed:0
+msgid "Date Closed"
+msgstr "Ημερομηνία Κλεισίματος"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,priority:0
+msgid "Priority"
+msgstr "Προτεραιότητα"
+
+#. module: report_crm
+#: field:report.crm.case.section,perc_cancel:0
+msgid "%Cancel"
+msgstr "%Άκυρο"
+
+#. module: report_crm
+#: field:report.crm.case.section,delay_close:0
+#: field:report.crm.case.user,delay_close:0
+msgid "Delay to close"
+msgstr "Καθυστέρηση στο κλείσιμο"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_categ_tree
+#: model:ir.ui.menu,name:report_crm.menu_crm_case_categ_tree
+msgid "Cases by Categories and Section"
+msgstr "Θέματα ανά κατηγορία και τμήμα"
+
+#. module: report_crm
+#: view:report.crm.case.service.dashboard:0
+msgid "CRM Cases"
+msgstr "Θέματα CRM"
+
+#. module: report_crm
+#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_user_tree_my
+#: model:ir.ui.menu,name:report_crm.menu_crm_case_user_tree_my
+msgid "My cases by section"
+msgstr "Τα θέματά μου ανά μήνα"
+
+#. module: report_crm
+#: field:report.crm.case.categ,name:0
+#: field:report.crm.case.section,name:0
+#: field:report.crm.case.user,name:0
+msgid "Month"
+msgstr "Μήνας"
+
+#. module: report_crm
+#: selection:report.crm.case.categ,state:0
+#: selection:report.crm.case.service.dashboard,state:0
+#: selection:report.crm.case.user,state:0
+msgid "Canceled"
+msgstr "Ακυρώθηκε"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,create_date:0
+msgid "Create Date"
+msgstr "Ημερομηνία Δημιουργίας"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,date_deadline:0
+msgid "Deadline"
+msgstr "Προθεσμία"
+
+#. module: report_crm
+#: model:ir.model,name:report_crm.model_report_crm_case_user
+msgid "Cases by user and section"
+msgstr "Θέματα ανά χρήστη και τμήμα"
+
+#. module: report_crm
+#: field:report.crm.case.service.dashboard,partner_id:0
+msgid "Partner"
+msgstr "Συνεργάτης"
+
+#. module: report_crm
+#: model:ir.module.module,description:report_crm.module_meta_information
+msgid ""
+"A module that adds new reports based on CRM cases.\n"
+" Case By section, Case By category"
+msgstr ""
+"Ένα άρθρωμα που προσθέτει νέες αναφορές βασισμένες στα θέματα CRM\n"
+" Θέματα ανά τμήμα, ανά κατηγορία"
+
+#. module: report_crm
+#: selection:report.crm.case.categ,state:0
+#: selection:report.crm.case.service.dashboard,state:0
+#: selection:report.crm.case.user,state:0
+msgid "Open"
+msgstr "Ανοιχτό"
+
+#. module: report_crm
+#: view:report.crm.case.service.dashboard:0
+msgid "Planned revenue"
+msgstr "Προγραμματισμένα 'Εσοδα"
diff --git a/addons/report_purchase/i18n/el.po b/addons/report_purchase/i18n/el.po
new file mode 100644
index 00000000000..a143c9c6033
--- /dev/null
+++ b/addons/report_purchase/i18n/el.po
@@ -0,0 +1,206 @@
+# Greek translation for openobject-addons
+# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR , 2009.
+#
+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: 2009-12-19 19:20+0000\n"
+"Last-Translator: Andreas Porevopoulos \n"
+"Language-Team: Greek \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:35+0000\n"
+"X-Generator: Launchpad (build Unknown)\n"
+
+#. module: report_purchase
+#: field:report.purchase.order.category,price_average:0
+#: field:report.purchase.order.product,price_average:0
+msgid "Average Price"
+msgstr "Μέση Τιμή"
+
+#. module: report_purchase
+#: field:report.purchase.order.category,state:0
+#: field:report.purchase.order.product,state:0
+msgid "Order State"
+msgstr "Κατάσταση Εντολής"
+
+#. module: report_purchase
+#: model:ir.actions.act_window,name:report_purchase.action_order_category_tree_all
+#: model:ir.ui.menu,name:report_purchase.menu_report_order_category_all
+#: view:report.purchase.order.category:0
+msgid "Purchases by Category of Products"
+msgstr "Αγορές ανά κατηγορία ειδών"
+
+#. module: report_purchase
+#: model:ir.model,name:report_purchase.model_report_purchase_order_product
+msgid "Purchases Orders by Products"
+msgstr "Εντολές αγορών ανά είδος"
+
+#. module: report_purchase
+#: model:ir.actions.act_window,name:report_purchase.action_order_product_tree_all
+#: model:ir.ui.menu,name:report_purchase.menu_report_order_product_all
+msgid "Purchases by Products"
+msgstr "Αγορές ανά είδος"
+
+#. module: report_purchase
+#: constraint:ir.actions.act_window:0
+msgid "Invalid model name in the action definition."
+msgstr "Λανθασμένο όνομα μοντέλου στην δήλωση ενέργειας"
+
+#. module: report_purchase
+#: model:ir.ui.menu,name:report_purchase.next_id_75
+msgid "All Months"
+msgstr "Όλοι οι Μήνες"
+
+#. module: report_purchase
+#: constraint:ir.model:0
+msgid ""
+"The Object name must start with x_ and not contain any special character !"
+msgstr ""
+"Το όνομα του Αντικειμένου πρέπει να ξεκινά με x_ και δεν πρέπει να περιέχει "
+"ειδικούς χαρακτήρες!"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Waiting Schedule"
+msgstr "Σε αναμονή προγραμματισμού"
+
+#. module: report_purchase
+#: model:ir.actions.act_window,name:report_purchase.action_order_product_tree
+#: model:ir.ui.menu,name:report_purchase.menu_report_order_product
+msgid "Purchases by Products (this month)"
+msgstr "Αγορές ανά είδος (αυτόν τον μήνα)"
+
+#. module: report_purchase
+#: model:ir.model,name:report_purchase.model_report_purchase_order_category
+msgid "Purchases Orders by Categories"
+msgstr "Εντολές αγορών ανά κατηγορία"
+
+#. module: report_purchase
+#: field:report.purchase.order.product,product_id:0
+msgid "Product"
+msgstr "Προϊόν"
+
+#. module: report_purchase
+#: model:ir.ui.menu,name:report_purchase.next_id_73
+msgid "Reporting"
+msgstr "Αναφορές"
+
+#. module: report_purchase
+#: model:ir.module.module,shortdesc:report_purchase.module_meta_information
+msgid "Purchase Management - Reporting"
+msgstr "Διαχείρηση αγορών - Αναφορές"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Invoice Exception"
+msgstr "Εξαίρεση Τιμολογίου"
+
+#. module: report_purchase
+#: field:report.purchase.order.category,price_total:0
+#: field:report.purchase.order.product,price_total:0
+msgid "Total Price"
+msgstr "Συνολική Τιμή"
+
+#. module: report_purchase
+#: field:report.purchase.order.category,quantity:0
+#: field:report.purchase.order.product,quantity:0
+msgid "# of Products"
+msgstr "# Προϊόντων"
+
+#. module: report_purchase
+#: view:report.purchase.order.product:0
+msgid "Purchases by products"
+msgstr "Αγορές ανά είδος"
+
+#. module: report_purchase
+#: model:ir.actions.act_window,name:report_purchase.act_product_category_2_report_purchase_order_category
+#: model:ir.actions.act_window,name:report_purchase.act_product_product_2_report_purchases_order_product
+msgid "Monthly purchases"
+msgstr "Μηνιαίες αγορές"
+
+#. module: report_purchase
+#: model:ir.ui.menu,name:report_purchase.next_id_74
+msgid "This Month"
+msgstr "Αυτόν τον μήνα"
+
+#. module: report_purchase
+#: model:ir.module.module,description:report_purchase.module_meta_information
+msgid ""
+"Module to add views like\n"
+" Purchase By Product, Purchase By Category of Product, All Months, "
+"Current Month."
+msgstr ""
+"Άρθρωμα που προσθέτει Όψης όπως:\n"
+" Αγορές ανά είδος, Αγορές νά κατηγορία είδους, Όλους τους μήνες, Τρέχων "
+"μήνα."
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Quotation"
+msgstr "Προσφορά"
+
+#. module: report_purchase
+#: constraint:ir.ui.view:0
+msgid "Invalid XML for View Architecture!"
+msgstr "Άκυρο XML για την Αρχιτεκτονική Όψης!"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Manual in progress"
+msgstr "Ιδιόχειρη σε εξέλιξη"
+
+#. module: report_purchase
+#: model:ir.actions.act_window,name:report_purchase.action_order_category_tree
+#: model:ir.ui.menu,name:report_purchase.menu_report_order_category
+msgid "Purchases by Category of Product (this month)"
+msgstr "Αγορές ανά κατηγορία ειδών (τρέχων μήνας)"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Shipping Exception"
+msgstr "Εξαίρεση Αποστολής"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "In progress"
+msgstr "Σε εξέλιξη"
+
+#. module: report_purchase
+#: field:report.purchase.order.category,name:0
+#: field:report.purchase.order.product,name:0
+msgid "Month"
+msgstr "Μήνας"
+
+#. module: report_purchase
+#: field:report.purchase.order.product,count:0
+msgid "# of Lines"
+msgstr "# Γραμμών"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Done"
+msgstr "Ολοκληρώθηκε"
+
+#. module: report_purchase
+#: field:report.purchase.order.category,category_id:0
+msgid "Categories"
+msgstr "Κατηγορίες"
+
+#. module: report_purchase
+#: selection:report.purchase.order.category,state:0
+#: selection:report.purchase.order.product,state:0
+msgid "Cancel"
+msgstr "Άκυρο"
diff --git a/addons/report_timesheet/i18n/zh_CN.po b/addons/report_timesheet/i18n/zh_CN.po
index 56253fae31d..d33985dec32 100644
--- a/addons/report_timesheet/i18n/zh_CN.po
+++ b/addons/report_timesheet/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-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-01-30 13:19+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-19 07:49+0000\n"
+"Last-Translator: Silence \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: 2009-12-16 05:17+0000\n"
+"X-Launchpad-Export-Date: 2009-12-20 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_timesheet
@@ -37,7 +37,7 @@ msgstr ""
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
-msgstr ""
+msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
#. module: report_timesheet
#: view:report_timesheet.account:0
@@ -48,7 +48,7 @@ msgstr ""
#: model:ir.actions.act_window,name:report_timesheet.act_res_users_2_report_timesheet_invoice
#: model:ir.model,name:report_timesheet.model_report_timesheet_invoice
msgid "Costs to invoice"
-msgstr ""
+msgstr "费用发票"
#. module: report_timesheet
#: model:ir.actions.act_window,name:report_timesheet.action_timesheet_user_stat_my
@@ -65,12 +65,12 @@ msgstr ""
#. module: report_timesheet
#: model:ir.actions.act_window,name:report_timesheet.act_account_analytic_account_2_report_timehsheet_account
msgid "Timesheets"
-msgstr ""
+msgstr "时间表"
#. module: report_timesheet
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "在操作定义中的模式名称无效"
#. module: report_timesheet
#: model:ir.actions.act_window,name:report_timesheet.act_res_users_2_report_timehsheet_account
diff --git a/addons/scrum/i18n/ca.po b/addons/scrum/i18n/ca.po
index 8f44a886ad1..3f2ceefeb51 100644
--- a/addons/scrum/i18n/ca.po
+++ b/addons/scrum/i18n/ca.po
@@ -7,13 +7,14 @@ 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-17 10:41+0000\n"
-"Last-Translator: Raimon Esteve \n"
+"PO-Revision-Date: 2009-12-20 17:36+0000\n"
+"Last-Translator: Jordi Esteve - http://www.zikzakmedia.com "
+"\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: 2009-12-16 05:06+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: scrum
@@ -671,10 +672,10 @@ msgid ""
"projects. It enables you to connect projects with budgets, planning, cost "
"and revenue analysis, timesheets on projects, etc."
msgstr ""
-"Enllaceu aquest projecte a un compte analític si necessiteu la gestió "
+"Enllaceu aquest projecte a un compte analític si necessita la gestió "
"financera dels projectes. Us permet connectar els projectes amb "
-"pressupostos, planificació, anàlisi de costos i ingressos, planificació del "
-"temps en els projectes, etc."
+"pressupostos, planificació, anàlisi de costos i ingressos, temps dedicat en "
+"els projectes, etc."
#. module: scrum
#: selection:scrum.product.backlog,state:0
diff --git a/addons/scrum/i18n/es.po b/addons/scrum/i18n/es.po
index 3e325e3ed09..4679d7bc315 100644
--- a/addons/scrum/i18n/es.po
+++ b/addons/scrum/i18n/es.po
@@ -7,13 +7,14 @@ 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-28 14:20+0000\n"
-"Last-Translator: viktor \n"
+"PO-Revision-Date: 2009-12-20 17:46+0000\n"
+"Last-Translator: Jordi Esteve - http://www.zikzakmedia.com "
+"\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: 2009-12-16 05:06+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: scrum
@@ -673,8 +674,8 @@ msgid ""
msgstr ""
"Enlace este proyecto a una cuenta analítica si necesita la gestión "
"financiera de los proyectos. Le permite conectar los proyectos con "
-"presupuestos, planificación, análisis de costes e ingresos, planificación "
-"del tiempo en los proyectos, etc."
+"presupuestos, planificación, análisis de costes e ingresos, tiempo dedicado "
+"en los proyectos, etc."
#. module: scrum
#: selection:scrum.product.backlog,state:0
diff --git a/addons/stock/i18n/zh_CN.po b/addons/stock/i18n/zh_CN.po
index 36a09dc4265..05d3d7fdf3e 100644
--- a/addons/stock/i18n/zh_CN.po
+++ b/addons/stock/i18n/zh_CN.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-12-03 13:41+0000\n"
+"PO-Revision-Date: 2009-12-20 15:06+0000\n"
"Last-Translator: Wei \"oldrev\" Li \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: 2009-12-16 05:04+0000\n"
+"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: stock
@@ -50,7 +50,7 @@ msgstr "操作定义中使用了无效的模式名称。"
#: model:ir.module.module,shortdesc:stock.module_meta_information
#: model:ir.ui.menu,name:stock.menu_stock_root
msgid "Inventory Management"
-msgstr ""
+msgstr "库存管理"
#. module: stock
#: selection:stock.location,icon:0
@@ -284,7 +284,7 @@ msgstr "订单(来源)"
#: rml:lot.stock.overview:0
#: rml:lot.stock.overview_all:0
msgid "Grand Total:"
-msgstr ""
+msgstr "总计:"
#. module: stock
#: view:stock.location:0
@@ -1170,7 +1170,7 @@ msgstr "库存调拨"
#: field:product.category,property_stock_account_output_categ:0
#: field:product.template,property_stock_account_output:0
msgid "Stock Output Account"
-msgstr ""
+msgstr "出库帐目"
#. module: stock
#: selection:stock.location,chained_auto_packing:0
@@ -1415,7 +1415,7 @@ msgstr "计划时间"
#: model:ir.actions.act_window,name:stock.action_picking_tree
#: model:ir.ui.menu,name:stock.menu_action_picking_tree
msgid "Outgoing Products"
-msgstr ""
+msgstr "发出货品"
#. module: stock
#: selection:stock.location,icon:0
@@ -1845,7 +1845,7 @@ msgstr "来源存货地点"
#. module: stock
#: view:product.template:0
msgid "Accounting Entries"
-msgstr ""
+msgstr "会计分录"
#. module: stock
#: selection:stock.location,icon:0
From 9b2de76cab27591b02722aafa5343ccc9f420fc7 Mon Sep 17 00:00:00 2001
From: "mra (Open ERP)"
Date: Mon, 21 Dec 2009 11:53:44 +0530
Subject: [PATCH 039/123] [IMP] base po files
bzr revid: mra@tinyerp.com-20091221062344-iaxb17z3xuk1uhi0
---
bin/addons/base/i18n/base.pot | 18 ++----------------
bin/addons/base/i18n/he.po | 16 +---------------
bin/addons/base/i18n/lv.po | 16 +---------------
bin/addons/base/i18n/nl.po | 32 ++------------------------------
bin/addons/base/i18n/pt.po | 32 ++------------------------------
bin/addons/base/i18n/ro.po | 16 +---------------
6 files changed, 9 insertions(+), 121 deletions(-)
diff --git a/bin/addons/base/i18n/base.pot b/bin/addons/base/i18n/base.pot
index ad77b86e94f..a5b23229161 100644
--- a/bin/addons/base/i18n/base.pot
+++ b/bin/addons/base/i18n/base.pot
@@ -393,7 +393,7 @@ msgid "Country Name"
msgstr ""
#. module: base
-#: model:res.country,name:base.co
+#: model:res.country,name:base.coreturn
msgid "Colombia"
msgstr ""
@@ -966,21 +966,7 @@ msgstr ""
#. module: base
#: code:addons/base/ir/ir_model.py:0
#, python-format
-msgid "Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+msgid "Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/he.po b/bin/addons/base/i18n/he.po
index 27cfa03c14e..8022091b977 100644
--- a/bin/addons/base/i18n/he.po
+++ b/bin/addons/base/i18n/he.po
@@ -1002,21 +1002,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/lv.po b/bin/addons/base/i18n/lv.po
index bacf9e66fb4..848ae75a916 100644
--- a/bin/addons/base/i18n/lv.po
+++ b/bin/addons/base/i18n/lv.po
@@ -1008,21 +1008,7 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/bin/addons/base/i18n/nl.po b/bin/addons/base/i18n/nl.po
index bef8dede540..02e88c61b58 100644
--- a/bin/addons/base/i18n/nl.po
+++ b/bin/addons/base/i18n/nl.po
@@ -1011,37 +1011,9 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
-"Model %s bestaat niet !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s bestaat niet !"
#. module: base
#: code:addons/base/module/module.py:0
diff --git a/bin/addons/base/i18n/pt.po b/bin/addons/base/i18n/pt.po
index bafef8ae13e..35d0b6b5279 100644
--- a/bin/addons/base/i18n/pt.po
+++ b/bin/addons/base/i18n/pt.po
@@ -1007,37 +1007,9 @@ msgstr "STOCK_COPY"
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
-"O modelo %s não existe!\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"O modelo %s não existe!"
#. module: base
#: code:addons/base/module/module.py:0
diff --git a/bin/addons/base/i18n/ro.po b/bin/addons/base/i18n/ro.po
index 77c39d2300d..4065135be01 100644
--- a/bin/addons/base/i18n/ro.po
+++ b/bin/addons/base/i18n/ro.po
@@ -995,21 +995,7 @@ msgstr ""
#: code:addons/base/ir/ir_model.py:0
#, python-format
msgid ""
-"Model %s Does not Exist !\" % vals['relation']))\n"
-" \n"
-" if self.pool.get(vals['model']):\n"
-" self.pool.get(vals['model']).__init__(self.pool, cr)\n"
-" self.pool.get(vals['model'])._auto_init(cr, {})\n"
-" \n"
-" return res\n"
-"ir_model_fields()\n"
-"\n"
-"class ir_model_access(osv.osv):\n"
-" _name = 'ir.model.access'\n"
-" _columns = {\n"
-" 'name': fields.char('Name', size=64, required=True),\n"
-" 'model_id': fields.many2one('ir.model', 'Object', required=True),\n"
-" 'group_id': fields.many2one('res.groups', 'Group"
+"Model %s Does not Exist !"
msgstr ""
#. module: base
From 5def3a5412fab8207d94e0a24122d9fb4a913a06 Mon Sep 17 00:00:00 2001
From: "Jay (Open ERP)"
Date: Mon, 21 Dec 2009 12:43:57 +0530
Subject: [PATCH 040/123] [FIX] Account Payment : Menu added for Payment term.
lp bug: https://launchpad.net/bugs/498252 fixed
bzr revid: jvo@tinyerp.com-20091221071357-5vpp8776xncf33sn
---
addons/account_payment/payment_view.xml | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/addons/account_payment/payment_view.xml b/addons/account_payment/payment_view.xml
index df1e25a419c..863cd0ed5fb 100644
--- a/addons/account_payment/payment_view.xml
+++ b/addons/account_payment/payment_view.xml
@@ -51,6 +51,13 @@
+
+
+ Payment Type
+ payment.type
+ form
+ tree,form
+
payment.mode.tree
@@ -83,8 +90,12 @@
tree,form
-
-
+
+
+
+
+
+
payment.order.form
payment.order
From a9145eb71477901e176ed212e1b2ea494af337b2 Mon Sep 17 00:00:00 2001
From: "mra (Open ERP)"
Date: Mon, 21 Dec 2009 14:17:54 +0530
Subject: [PATCH 041/123] [FIX] base/i18n: nl and pt files error solved
(duplicate msgid ending)
bzr revid: mra@tinyerp.com-20091221084754-jh8b5wasbfcwzgiq
---
bin/addons/base/i18n/nl.po | 3 ---
bin/addons/base/i18n/pt.po | 3 ---
2 files changed, 6 deletions(-)
diff --git a/bin/addons/base/i18n/nl.po b/bin/addons/base/i18n/nl.po
index 02e88c61b58..5acf7c65e19 100644
--- a/bin/addons/base/i18n/nl.po
+++ b/bin/addons/base/i18n/nl.po
@@ -8103,6 +8103,3 @@ msgstr "Sri Lanka"
#: selection:module.lang.install,init,lang:0
msgid "Russian / русский язык"
msgstr "Russisch / русский язык"
-
-#~ msgid "Model %s Does not Exist !"
-#~ msgstr "Model %s bestaat niet !"
diff --git a/bin/addons/base/i18n/pt.po b/bin/addons/base/i18n/pt.po
index 35d0b6b5279..97565aac2f3 100644
--- a/bin/addons/base/i18n/pt.po
+++ b/bin/addons/base/i18n/pt.po
@@ -8119,6 +8119,3 @@ msgstr "Russo / русский язык"
#, python-format
#~ msgid "The unlink method is not implemented on this object !"
#~ msgstr "O método remover (unlink) não está implementado neste objecto!"
-
-#~ msgid "Model %s Does not Exist !"
-#~ msgstr "O modelo %s não existe!"
From 6ff8fbdabbad88d8add9b13e689aa6d24c731fad Mon Sep 17 00:00:00 2001
From: "Harry (Open ERP)" <>
Date: Mon, 21 Dec 2009 14:56:03 +0530
Subject: [PATCH 042/123] [IMP]: Caldav: Moved fix from
hmo@tinyerp.com-20091218102513-1benptetg7q2x4qu to common file for
configuration wizard problem
bzr revid: rpa@tinyerp.com-20091221092603-yblvo0r8jxelwhf5
---
addons/caldav/common.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/addons/caldav/common.py b/addons/caldav/common.py
index e8c74ef563a..c3e08fc878d 100644
--- a/addons/caldav/common.py
+++ b/addons/caldav/common.py
@@ -204,7 +204,12 @@ virtual_report_spool()
class virtual_wizard(web_services.wizard):
def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
if wiz_id not in self.wiz_uid:
- super(virtual_wizard,self).exp_create(db, uid, 'module.upgrade', datas)
+ # TODO : To Check why need it
+ if wiz_id == 1:
+ wiz_name ='base_setup.base_setup'
+ if wiz_id == 2:
+ wiz_name ='module.upgrade'
+ super(virtual_wizard,self).exp_create(db, uid, wiz_name, datas)
new_ids = []
if 'id' in datas:
datas['id'] = caldevIDs2readIDs(datas['id'])
From fa4d7a2bc97fe434a9ba4a1d01a7d3713d770260 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Mon, 21 Dec 2009 15:19:00 +0530
Subject: [PATCH 043/123] [IMP]: Caldav+crm+project_calendar: Improvement for
importing more than one event and tasks, Set proper message after import
bzr revid: rpa@tinyerp.com-20091221094900-s4wy1qec4hff4dfo
---
addons/caldav/calendar.py | 14 ++++--
addons/crm/crm_calendar.py | 16 +++----
addons/crm/wizard/wizard_cal_export.py | 9 +---
addons/crm/wizard/wizard_cal_import.py | 44 +++++++++++++------
addons/project_calendar/project_calendar.py | 18 +++-----
.../wizard/wizard_cal_export.py | 5 ---
.../wizard/wizard_cal_import.py | 39 +++++++++++-----
7 files changed, 87 insertions(+), 58 deletions(-)
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index ee0522c23d0..6ec234a6f4b 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -100,6 +100,12 @@ class CalDAV(object):
else:
return self.__attribute__.get(name, None)
+ def ical_reset(self, type):
+ for name in self.__attribute__:
+ if self.__attribute__[name]:
+ self.__attribute__[name][type] = None
+ return True
+
def export_ical(self, cr, uid, datas, vobj=None):
ical = vobject.iCalendar()
for data in datas:
@@ -129,7 +135,7 @@ class CalDAV(object):
def import_ical(self, cr, uid, ical_data):
parsedCal = vobject.readOne(ical_data)
att_data = []
- todo_data = []
+ res = []
for child in parsedCal.getChildren():
for cal_data in child.getChildren():
if cal_data.name.lower() == 'attendee':
@@ -144,8 +150,10 @@ class CalDAV(object):
continue
if cal_data.name.lower() in self.__attribute__:
self.ical_set(cal_data.name.lower(), cal_data.value, 'value')
- vals = map_data(cr, uid, self)
- return vals
+ vals = map_data(cr, uid, self)
+ if vals : res.append(vals)
+ self.ical_reset('value')
+ return res
class Calendar(CalDAV, osv.osv_memory):
diff --git a/addons/crm/crm_calendar.py b/addons/crm/crm_calendar.py
index 730184aab2c..4ce6b6038e5 100644
--- a/addons/crm/crm_calendar.py
+++ b/addons/crm/crm_calendar.py
@@ -204,15 +204,15 @@ class crm_case(osv.osv):
alarm_obj = self.pool.get('caldav.alarm')
crm_alarm = self.pool.get('crm.caldav.alarm')
alarm_obj.__attribute__.update(crm_alarm.__attribute__)
-
vals = event_obj.import_ical(cr, uid, file_content)
- # TODO: Select proper section
- section_id = self.pool.get('crm.case.section').search(cr, uid, [])[0]
- vals.update({'section_id' : section_id})
- vals.pop('id')
- vals.pop('create_date')
- case_id = self.create(cr, uid, vals)
- return
+ for val in vals:
+ # TODO: Select proper section
+ section_id = self.pool.get('crm.case.section').search(cr, uid, [])[0]
+ val.update({'section_id' : section_id})
+ val.pop('id')
+ val.pop('create_date')
+ case_id = self.create(cr, uid, val)
+ return {'count': len(vals)}
def search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False):
diff --git a/addons/crm/wizard/wizard_cal_export.py b/addons/crm/wizard/wizard_cal_export.py
index 53b0f92fc64..08e9de56945 100644
--- a/addons/crm/wizard/wizard_cal_export.py
+++ b/addons/crm/wizard/wizard_cal_export.py
@@ -19,14 +19,9 @@
#
##############################################################################
-import time
-import tools
import wizard
-import os
-import mx.DateTime
import base64
import pooler
-import vobject
class crm_cal_export_wizard(wizard.interface):
@@ -53,8 +48,8 @@ class crm_cal_export_wizard(wizard.interface):
states = {
'init': {
'actions': [_process_export_ics],
- 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', '_Cancel', 'gtk-cancel'), ('end', 'Ok', 'gtk-ok')]}
- },
+ 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, \
+ 'state': [('end', '_Cancel', 'gtk-cancel'), ('end', 'Ok', 'gtk-ok')]}},
}
crm_cal_export_wizard('caldav.crm.export')
diff --git a/addons/crm/wizard/wizard_cal_import.py b/addons/crm/wizard/wizard_cal_import.py
index 0898ec671e5..8784198a7d1 100644
--- a/addons/crm/wizard/wizard_cal_import.py
+++ b/addons/crm/wizard/wizard_cal_import.py
@@ -19,14 +19,8 @@
#
##############################################################################
-import time
-import tools
import wizard
-import os
-import mx.DateTime
-import base64
import pooler
-import vobject
class crm_cal_import_wizard(wizard.interface):
@@ -40,25 +34,49 @@ class crm_cal_import_wizard(wizard.interface):
'file_path': {
'string': 'Select ICS file',
'type': 'binary',
- 'required' : True,
- 'filters' : '*.ics'
+ 'required': True,
+ 'filters': '*.ics'
}
}
+ display = '''
+ '''
- def _process_import_ics(self, cr, uid, data, context=None):
+ display_fields = {
+ 'msg': {
+ 'string': '',
+ 'type': 'text',
+ 'readonly': True,
+ }
+ }
+
+ def _process_imp_ics(self, cr, uid, data, context=None):
case_obj = pooler.get_pool(cr.dbname).get('crm.case')
- case_obj.import_cal(cr, uid, data['ids'], data, context)
+ vals = case_obj.import_cal(cr, uid, data['ids'], data, context)
+ if vals:
+ global cnt
+ cnt = vals['count']
return {}
+ def _result_set(self, cr, uid, data, context=None):
+ return {'msg': 'Imported %s Event(s)' % cnt}
+
states = {
'init': {
'actions': [],
- 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', '_Cancel', 'gtk-cancel'), ('open', '_Import', 'gtk-ok')]}
+ 'result': {'type': 'form', 'arch': form1, 'fields': form1_fields, \
+ 'state': [('end', '_Cancel', 'gtk-cancel'), ('open', '_Import', 'gtk-ok')]}
},
'open': {
'actions': [],
- 'result': {'type': 'action', 'action':_process_import_ics, 'state':'end'}
- }
+ 'result': {'type': 'action', 'action': _process_imp_ics, 'state': 'display'}
+ },
+ 'display': {
+ 'actions': [_result_set],
+ 'result': {'type': 'form', 'arch': display, 'fields': display_fields, \
+ 'state': [('end', 'Ok', 'gtk-ok')]}
+ },
}
crm_cal_import_wizard('caldav.crm.import')
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
index 8f8c44c4f9d..593a3825c03 100644
--- a/addons/project_calendar/project_calendar.py
+++ b/addons/project_calendar/project_calendar.py
@@ -111,17 +111,13 @@ class project_task(osv.osv):
alarm_obj.__attribute__.update(crm_alarm.__attribute__)
vals = todo_obj.import_ical(cr, uid, file_content)
- if not vals.has_key('duration'):
- # 'Compute duration'
- vals['planned_hours'] = 16
-# start = datetime.strptime(vals.get('date_start'), '%Y-%m-%d %H:%M:%S')
-# end = datetime.strptime(vals.get('date_deadline'), '%Y-%m-%d %H:%M:%S')
-# difference = float((end - start).seconds) / 3600
-## minutes, seconds = divmod(difference.seconds, 60)
-## hours, minutes = divmod(minutes, 60)
- vals.pop('id')
- task_id = self.create(cr, uid, vals)
- return
+ for val in vals:
+ if not val.has_key('duration'):
+ # 'Compute duration'
+ val['planned_hours'] = 16
+ val.pop('id')
+ task_id = self.create(cr, uid, val)
+ return {'count': len(vals)}
def export_cal(self, cr, uid, ids, context={}):
task_data = self.read(cr, uid, ids, [], context ={'read': True})
diff --git a/addons/project_calendar/wizard/wizard_cal_export.py b/addons/project_calendar/wizard/wizard_cal_export.py
index 600d80c9a05..430654d90f6 100644
--- a/addons/project_calendar/wizard/wizard_cal_export.py
+++ b/addons/project_calendar/wizard/wizard_cal_export.py
@@ -19,14 +19,9 @@
#
##############################################################################
-import time
-import tools
import wizard
-import os
-import mx.DateTime
import base64
import pooler
-import vobject
class project_cal_export_wizard(wizard.interface):
diff --git a/addons/project_calendar/wizard/wizard_cal_import.py b/addons/project_calendar/wizard/wizard_cal_import.py
index 7ca19bcee6e..ef99f75d09d 100644
--- a/addons/project_calendar/wizard/wizard_cal_import.py
+++ b/addons/project_calendar/wizard/wizard_cal_import.py
@@ -19,15 +19,8 @@
#
##############################################################################
-import time
-import tools
import wizard
-import os
-import mx.DateTime
-import base64
import pooler
-import vobject
-
class project_cal_imp_wizard(wizard.interface):
form1 = '''
@@ -44,22 +37,46 @@ class project_cal_imp_wizard(wizard.interface):
'filters': '*.ics'
}
}
+ display = '''
+ '''
+ display_fields = {
+ 'msg': {
+ 'string': '',
+ 'type': 'text',
+ 'readonly': True,
+ 'default': 'Imported %s Tasks'
+ }
+ }
+
def _process_imp_ics(self, cr, uid, data, context=None):
task_obj = pooler.get_pool(cr.dbname).get('project.task')
- task_obj.import_cal(cr, uid, data['ids'], data, context)
+ vals = task_obj.import_cal(cr, uid, data['ids'], data, context)
+ if vals:
+ global cnt
+ cnt = vals['count']
return {}
+ def _result_set(self, cr, uid, data, context=None):
+ return {'msg': 'Imported %s Task(s)' % cnt}
+
states = {
'init': {
'actions': [],
- 'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, \
+ 'result': {'type': 'form', 'arch': form1, 'fields': form1_fields, \
'state': [('end', '_Cancel', 'gtk-cancel'), ('open', '_Import', 'gtk-ok')]}
},
'open': {
'actions': [],
- 'result': {'type': 'action', 'action':_process_imp_ics, 'state':'end'}
- }
+ 'result': {'type': 'action', 'action': _process_imp_ics, 'state': 'display'}
+ },
+ 'display': {
+ 'actions': [_result_set],
+ 'result': {'type': 'form', 'arch': display, 'fields': display_fields, \
+ 'state': [('end', 'Ok', 'gtk-ok')]}
+ },
}
project_cal_imp_wizard('caldav.project.import')
From c9f66f69f04999a3beee59b2b9e0779d543bb36b Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Mon, 21 Dec 2009 15:20:54 +0530
Subject: [PATCH 044/123] [IMP]: Tooltip improvements: Typo errors and
improvements
bzr revid: uco@tinyerp.co.in-20091221095054-do0gbj9907u3oyxc
---
addons/account/account.py | 16 ++++++------
addons/account/account_move_line.py | 6 ++---
addons/account/partner.py | 2 +-
addons/account/project/project.py | 2 +-
addons/auction/auction.py | 2 +-
addons/crm/crm_config.py | 2 +-
addons/hr/hr.py | 2 +-
addons/hr_attendance/hr_attendance.py | 2 +-
addons/hr_contract/hr_contract.py | 2 +-
addons/hr_expense/hr_expense.py | 2 +-
addons/hr_holidays/hr.py | 4 +--
.../hr_timesheet_invoice.py | 6 ++---
addons/mrp/mrp.py | 18 ++++++-------
addons/mrp_operations/mrp_operations.py | 4 +--
addons/product/partner.py | 3 +--
addons/product/product.py | 26 +++++++++----------
addons/purchase/purchase.py | 4 +--
addons/sale/sale.py | 2 +-
addons/stock/product.py | 8 +++---
addons/stock/stock.py | 6 ++---
20 files changed, 59 insertions(+), 60 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index 549f257b124..967eeff9279 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -266,7 +266,7 @@ class account_account(osv.osv):
_columns = {
'name': fields.char('Name', size=128, required=True, select=True),
- 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Force all moves for this account to have this secondary currency."),
+ 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
'code': fields.char('Code', size=64, required=True),
'type': fields.selection([
('receivable', 'Receivable'),
@@ -468,7 +468,7 @@ class account_journal(osv.osv):
'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view'), ('type', '<>', 'closed')]),
'active': fields.boolean('Active'),
- 'view_id': fields.many2one('account.journal.view', 'View', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tell Open ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
+ 'view_id': fields.many2one('account.journal.view', 'View', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tells Open ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]"),
'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account', domain="[('type','!=','view')]"),
'centralisation': fields.boolean('Centralised counterpart', help="Check this box to determine that each entry of this journal won't create a new counterpart but will share the same counterpart. This is used in fiscal year closing."),
@@ -1270,7 +1270,7 @@ class account_tax(osv.osv):
'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the VAT declaration."),
'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
- 'include_base_amount': fields.boolean('Include in base amount', help="Indicate if the amount of tax must be included in the base amount for the computation of the next taxes"),
+ 'include_base_amount': fields.boolean('Included in base amount', help="Indicates if the amount of tax must be included in the base amount for the computation of the next taxes"),
'company_id': fields.many2one('res.company', 'Company', required=True),
'description': fields.char('Tax Code',size=32),
'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
@@ -1591,8 +1591,8 @@ class account_model_line(osv.osv):
'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency."),
'currency_id': fields.many2one('res.currency', 'Currency'),
- 'partner_id': fields.many2one('res.partner', 'Partner Ref.'),
- 'date_maturity': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Maturity date', help="The maturity date of the generated entries for this model. You can chosse between the date of the creation action or the the date of the creation of the entries plus the partner payment terms."),
+ 'partner_id': fields.many2one('res.partner', 'Partner'),
+ 'date_maturity': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Maturity date', help="The maturity date of the generated entries for this model. You can choose between the creation date or the creation date of the entries plus the partner payment terms."),
'date': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Current Date', required=True, help="The date of the generated entries"),
}
_defaults = {
@@ -1797,7 +1797,7 @@ class account_account_template(osv.osv):
_columns = {
'name': fields.char('Name', size=128, required=True, select=True),
- 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Force all moves for this account to have this secondary currency."),
+ 'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Forces all moves for this account to have this secondary currency."),
'code': fields.char('Code', size=64),
'type': fields.selection([
('receivable','Receivable'),
@@ -1811,8 +1811,8 @@ class account_account_template(osv.osv):
"can have children accounts for multi-company consolidations, payable/receivable are for "\
"partners accounts (for debit/credit computations), closed for deprecated accounts."),
'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
- help="These types are defined according to your country. The type contain more information "\
- "about the account and it's specificities."),
+ help="These types are defined according to your country. The type contains more information "\
+ "about the account and its specificities."),
'reconcile': fields.boolean('Allow Reconciliation', help="Check this option if you want the user to reconcile entries in this account."),
'shortcut': fields.char('Shortcut', size=12),
'note': fields.text('Note'),
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index c8a02d00ea4..f0639b9af0d 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -349,7 +349,7 @@ class account_move_line(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'quantity': fields.float('Quantity', digits=(16,2), help="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."),
+ 'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity expressed by this line, eg: number of product sold. The quantity is not a legal requirement but is very useful for some reports."),
'product_uom_id': fields.many2one('product.uom', 'UoM'),
'product_id': fields.many2one('product.product', 'Product'),
'debit': fields.float('Debit', digits=(16,int(tools.config['price_accuracy']))),
@@ -368,7 +368,7 @@ class account_move_line(osv.osv):
'journal_id': fields.many2one('account.journal', 'Journal', required=True, select=1),
'blocked': fields.boolean('Litigation', help="You can check this box to mark the entry line as a litigation with the associated partner"),
- 'partner_id': fields.many2one('res.partner', 'Partner Ref.'),
+ 'partner_id': fields.many2one('res.partner', 'Partner'),
'date_maturity': fields.date('Maturity date', help="This field is used for payable and receivable entries. You can put the limit date for the payment of this entry line."),
'date': fields.related('move_id','date', string='Effective date', type='date', required=True,
store={
@@ -381,7 +381,7 @@ class account_move_line(osv.osv):
'state': fields.selection([('draft','Draft'), ('valid','Valid')], 'State', readonly=True,
help='When new move line is created the state will be \'Draft\'.\n* When all the payments are done it will be in \'Valid\' state.'),
'tax_code_id': fields.many2one('account.tax.code', 'Tax Account', help="The Account can either be a base tax code or tax code account."),
- 'tax_amount': fields.float('Tax/Base Amount', digits=(16,int(tools.config['price_accuracy'])), select=True, help="If the Tax account is tax code account, this field will contain the taxed amount.If the tax account is base tax code,\
+ 'tax_amount': fields.float('Tax/Base Amount', digits=(16,int(tools.config['price_accuracy'])), select=True, help="If the Tax account is a tax code account, this field will contain the taxed amount.If the tax account is base tax code,\
this field will contain the basic amount(without tax)."),
'invoice': fields.function(_invoice, method=True, string='Invoice',
type='many2one', relation='account.invoice', fnct_search=_invoice_search),
diff --git a/addons/account/partner.py b/addons/account/partner.py
index e5b81110c93..00707a13163 100644
--- a/addons/account/partner.py
+++ b/addons/account/partner.py
@@ -171,7 +171,7 @@ class res_partner(osv.osv):
string="Fiscal Position",
method=True,
view_load=True,
- help="The fiscal position will determine taxes and the accounts used for the the partner.",
+ help="The fiscal position will determine taxes and the accounts used for the partner.",
),
'property_payment_term': fields.property(
'account.payment.term',
diff --git a/addons/account/project/project.py b/addons/account/project/project.py
index 51431ee1be1..0f4a87053ed 100644
--- a/addons/account/project/project.py
+++ b/addons/account/project/project.py
@@ -271,7 +271,7 @@ class account_analytic_journal(osv.osv):
'name' : fields.char('Journal name', size=64, required=True),
'code' : fields.char('Journal code', size=8),
'active' : fields.boolean('Active'),
- 'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True, help="Gives the type of the analytic journal. When a document (eg: an invoice) needs to create analytic entries, Open ERP will look for a matching journal of the same type."),
+ 'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True, help="Gives the type of the analytic journal. When it needs for a document (eg: an invoice) to create analytic entries, Open ERP will look for a matching journal of the same type."),
'line_ids' : fields.one2many('account.analytic.line', 'journal_id', 'Lines'),
'company_id': fields.many2one('res.company', 'Company', required=True),
}
diff --git a/addons/auction/auction.py b/addons/auction/auction.py
index 29ce8b30421..da5a2998997 100644
--- a/addons/auction/auction.py
+++ b/addons/auction/auction.py
@@ -1236,7 +1236,7 @@ class report_attendance(osv.osv):
#_rec_name='date'
_columns = {
'name': fields.date('Date', readonly=True,select=1),
- 'employee_id' : fields.many2one('hr.employee', 'Employee', select=1, readonly=True),
+ 'employee_id' : fields.many2one('hr.employee', "Employee's Name", select=1, readonly=True),
'total_attendance': fields.float('Total', readonly=True),
}
def init(self, cr):
diff --git a/addons/crm/crm_config.py b/addons/crm/crm_config.py
index 51e84fce759..0e141ac60d9 100644
--- a/addons/crm/crm_config.py
+++ b/addons/crm/crm_config.py
@@ -71,7 +71,7 @@ class crm_cases(osv.osv):
'category2_id': fields.many2one('crm.case.category2', 'Category Name', domain="[('section_id','=',section_id)]"),
'duration': fields.float('Duration'),
'case_id': fields.many2one('crm.case', 'Related Case'),
- 'partner_name': fields.char('Employee Name', size=64),
+ 'partner_name': fields.char("Employee's Name", size=64),
'partner_name2': fields.char('Employee Email', size=64),
'partner_phone': fields.char('Phone', size=32),
'partner_mobile': fields.char('Mobile', size=32),
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index 896a2047eda..f20ae9be4e8 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -119,7 +119,7 @@ class hr_employee(osv.osv):
_description = "Employee"
_columns = {
- 'name' : fields.char("Employee", size=128, required=True),
+ 'name' : fields.char("Employee's Name", size=128, required=True),
'active' : fields.boolean('Active'),
'company_id': fields.many2one('res.company', 'Company'),
'user_id' : fields.many2one('res.users', 'Related User'),
diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py
index 07223487dc5..d712ae3e428 100644
--- a/addons/hr_attendance/hr_attendance.py
+++ b/addons/hr_attendance/hr_attendance.py
@@ -50,7 +50,7 @@ class hr_attendance(osv.osv):
'name' : fields.datetime('Date', required=True),
'action' : fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out'),('action','Action')], 'Action', required=True),
'action_desc' : fields.many2one("hr.action.reason", "Action reason", domain="[('action_type', '=', action)]"),
- 'employee_id' : fields.many2one('hr.employee', 'Employee', required=True, select=True),
+ 'employee_id' : fields.many2one('hr.employee', "Employee's Name", required=True, select=True),
}
_defaults = {
'name' : lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
diff --git a/addons/hr_contract/hr_contract.py b/addons/hr_contract/hr_contract.py
index afd2d7bafe4..63353648553 100644
--- a/addons/hr_contract/hr_contract.py
+++ b/addons/hr_contract/hr_contract.py
@@ -81,7 +81,7 @@ class hr_contract(osv.osv):
_description = 'Contract'
_columns = {
'name' : fields.char('Contract Name', size=30, required=True),
- 'employee_id' : fields.many2one('hr.employee', 'Employee', required=True),
+ 'employee_id' : fields.many2one('hr.employee', "Employee's Name", required=True),
'function' : fields.many2one('res.partner.function', 'Function'),
'date_start' : fields.date('Start Date', required=True),
'date_end' : fields.date('End Date'),
diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index 5cc7c1236ab..7cd3d4b24c0 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -58,7 +58,7 @@ class hr_expense_expense(osv.osv):
'ref': fields.char('Reference', size=32),
'date': fields.date('Date'),
'journal_id': fields.many2one('account.journal', 'Force Journal'),
- 'employee_id': fields.many2one('hr.employee', 'Employee', required=True),
+ 'employee_id': fields.many2one('hr.employee', "Employee's Name", required=True),
'user_id': fields.many2one('res.users', 'User', required=True),
'date_confirm': fields.date('Date Confirmed'),
'date_valid': fields.date('Date Validated'),
diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py
index 06f8ebbc2e0..9f24fae015d 100644
--- a/addons/hr_holidays/hr.py
+++ b/addons/hr_holidays/hr.py
@@ -102,7 +102,7 @@ class hr_holidays_per_user(osv.osv):
return result
_columns = {
- 'employee_id': fields.many2one('hr.employee', 'Employee',required=True),
+ '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),
@@ -143,7 +143,7 @@ class hr_holidays(osv.osv):
'user_id':fields.many2one('res.users', 'User', states={'draft':[('readonly',False)]}, select=True, readonly=True),
'date_to' : fields.datetime('End Date', readonly=True, states={'draft':[('readonly',False)]}),
'holiday_status_id' : fields.many2one("hr.holidays.status", "Leave Type", required=True,readonly=True, states={'draft':[('readonly',False)]}),
- 'employee_id' : fields.many2one('hr.employee', 'Employee', select=True, invisible=False, readonly=True, states={'draft':[('readonly',False)]}, help='Leave Manager can let this field empty if this leave request/allocation is for every employee'),
+ 'employee_id' : fields.many2one('hr.employee', "Employee's Name", select=True, invisible=False, readonly=True, states={'draft':[('readonly',False)]}, help='Leave Manager can let this field empty if this leave request/allocation is for every employee'),
'manager_id' : fields.many2one('hr.employee', 'Leave Manager', invisible=False, readonly=True, help='This area is automaticly filled by the user who validate the leave'),
'notes' : fields.text('Notes',readonly=True, states={'draft':[('readonly',False)]}),
'number_of_days': fields.float('Number of Days', readonly=True, states={'draft':[('readonly',False)]}),
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index 182d8843b8c..453076cdccf 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -28,7 +28,7 @@ class hr_timesheet_invoice_factor(osv.osv):
_description = "Invoice rate"
_columns = {
'name': fields.char('Internal name', size=128, required=True),
- 'customer_name': fields.char('Visible name', size=128),
+ 'customer_name': fields.char('Name', size=128),
'factor': fields.float('Discount (%)', required=True),
}
_defaults = {
@@ -59,7 +59,7 @@ class account_analytic_account(osv.osv):
'amount_invoiced': fields.function(_invoiced_calc, method=True, string='Invoiced Amount',
help="Total invoiced"),
'to_invoice': fields.many2one('hr_timesheet_invoice.factor','Reinvoice Costs',
- help="Check this field if you plan to automatically generate invoices based " \
+ help="Fill this field if you plan to automatically generate invoices based " \
"on the costs in this analytic account: timesheets, expenses, ..." \
"You can configure an automatic invoice rate on analytic accounts."),
}
@@ -73,7 +73,7 @@ class account_analytic_line(osv.osv):
_inherit = 'account.analytic.line'
_columns = {
'invoice_id': fields.many2one('account.invoice', 'Invoice'),
- 'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Invoicing'),
+ 'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Type of Invoicing'),
}
def unlink(self, cursor, user, ids, context=None):
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index dd6df6ff4ff..390663992e8 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -48,12 +48,12 @@ class mrp_workcenter(osv.osv):
'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="The normal working time of the workcenter."),
'note': fields.text('Description', help="Description of the workcenter. Explain here what's a cycle according to this workcenter."),
- 'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operation this workcenter can do in parallel. If this workcenter represent a team of 5 workers, the capacity per cycle is 5."),
+ 'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operations this workcenter can do in parallel. If this workcenter represents a team of 5 workers, the capacity per cycle is 5."),
'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."),
'time_start': fields.float('Time before prod.', help="Time in hours for the setup."),
'time_stop': fields.float('Time after prod.', help="Time in hours for the cleaning."),
- 'time_efficiency': fields.float('Time Efficiency', help="Factor to adjust the work center cycle and before and after production durations"),
+ 'time_efficiency': fields.float('Efficiency factor', help="Factor to adjust the work center cycle and before and after production durations"),
'costs_hour': fields.float('Cost per hour'),
'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','<>','view')],
@@ -127,7 +127,7 @@ class mrp_routing_workcenter(osv.osv):
'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True),
'name': fields.char('Name', size=64, required=True),
'sequence': fields.integer('Sequence'),
- 'cycle_nbr': fields.float('Number of Cycle', required=True,
+ 'cycle_nbr': fields.float('Number of Cycles', required=True,
help="Time in hours for doing one cycle."),
'hour_nbr': fields.float('Number of Hours', required=True, help="Cost per hour"),
'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True, ondelete='cascade',
@@ -143,7 +143,7 @@ mrp_routing_workcenter()
class mrp_bom(osv.osv):
_name = 'mrp.bom'
- _description = 'Bill of Material'
+ _description = 'Bills of Material'
def _child_compute(self, cr, uid, ids, name, arg, context={}):
result = {}
for bom in self.browse(cr, uid, ids, context=context):
@@ -196,7 +196,7 @@ class mrp_bom(osv.osv):
'product_efficiency': fields.float('Product Efficiency', required=True, help="Material efficiency. A factor of 0.9 means a loss of 10% in the production."),
'bom_lines': fields.one2many('mrp.bom', 'bom_id', 'BoM Lines'),
'bom_id': fields.many2one('mrp.bom', 'Parent BoM', ondelete='cascade', select=True),
- 'routing_id': fields.many2one('mrp.routing', 'Routing', help="The list of operations (list of workcenters) to produce the finished product. The routing is mainly used to compute workcenter costs during operations and to plan futur loads on workcenters based on production plannification."),
+ 'routing_id': fields.many2one('mrp.routing', 'Routing', help="The list of operations (list of workcenters) to produce the finished product. The routing is mainly used to compute workcenter costs during operations and to plan future loads on workcenters based on production planning."),
'property_ids': fields.many2many('mrp.property', 'mrp_bom_property_rel', 'bom_id','property_id', 'Properties'),
'revision_ids': fields.one2many('mrp.bom.revision', 'bom_id', 'BoM Revisions'),
'revision_type': fields.selection([('numeric','numeric indices'),('alpha','alphabetical indices')], 'Index type'),
@@ -417,7 +417,7 @@ class mrp_production(osv.osv):
'product_uos': fields.many2one('product.uom', 'Product UoS', states={'draft':[('readonly',False)]}, readonly=True),
'location_src_id': fields.many2one('stock.location', 'Raw Materials Location', required=True,
- help="Location where the system will look for products used in raw materials."),
+ help="Location where the system will look for components."),
'location_dest_id': fields.many2one('stock.location', 'Finished Products Location', required=True,
help="Location where the system will stock the finished products."),
@@ -431,7 +431,7 @@ class mrp_production(osv.osv):
'routing_id': fields.many2one('mrp.routing', string='Routing', on_delete='set null', help="The list of operations (list of workcenters) to produce the finished product. The routing is mainly used to compute workcenter costs during operations and to plan futur loads on workcenters based on production plannification."),
'picking_id': fields.many2one('stock.picking', 'Picking list', readonly=True,
- help="This is the internal picking list of the raw material needed for the production plan"),
+ help="This is the internal picking list that brings the finished product to the production plan"),
'move_prod_id': fields.many2one('stock.move', 'Move product', readonly=True),
'move_lines': fields.many2many('stock.move', 'mrp_production_move_ids', 'production_id', 'move_id', 'Products Consummed'),
@@ -758,8 +758,8 @@ class mrp_production_workcenter_line(osv.osv):
_columns = {
'name': fields.char('Work Order', size=64, required=True),
'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True),
- 'cycle': fields.float('Nbr of cycle', digits=(16,2)),
- 'hour': fields.float('Nbr of hour', digits=(16,2)),
+ 'cycle': fields.float('Nbr of cycles', digits=(16,2)),
+ 'hour': fields.float('Nbr of hours', digits=(16,2)),
'sequence': fields.integer('Sequence', required=True),
'production_id': fields.many2one('mrp.production', 'Production Order', select=True, ondelete='cascade'),
}
diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py
index edc57750169..5cd7193f69c 100644
--- a/addons/mrp_operations/mrp_operations.py
+++ b/addons/mrp_operations/mrp_operations.py
@@ -75,11 +75,11 @@ class mrp_production_workcenter_line(osv.osv):
'date_planned_end': fields.function(_get_date_end, method=True, string='End Date', type='datetime'),
'date_start': fields.datetime('Start Date'),
'date_finnished': fields.datetime('End Date'),
- 'delay': fields.float('Working Hours',help="This is delay between operation start and stop in this workcenter",readonly=True),
+ 'delay': fields.float('Working Hours',help="This is lead time between operation start and stop in this workcenter",readonly=True),
'production_state':fields.related('production_id','state',
type='selection',
selection=[('draft','Draft'),('picking_except', 'Picking Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')],
- string='Prod.State', readonly=True),
+ string='Production State', readonly=True),
'product':fields.related('production_id','product_id',type='many2one',relation='product.product',string='Product',
readonly=True),
'qty':fields.related('production_id','product_qty',type='float',string='Qty',readonly=True),
diff --git a/addons/product/partner.py b/addons/product/partner.py
index d708022e6be..4efdd2b0430 100644
--- a/addons/product/partner.py
+++ b/addons/product/partner.py
@@ -34,8 +34,7 @@ class res_partner(osv.osv):
string="Sale Pricelist",
method=True,
view_load=True,
- help="This pricelist will be used, instead of the default one, \
- for sales to the current partner"),
+ help="This pricelist will be used, instead of the default one, for sales to the current partner"),
}
res_partner()
diff --git a/addons/product/product.py b/addons/product/product.py
index ad2b4ca0330..78d88926aa1 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -169,7 +169,7 @@ class product_ul(osv.osv):
_description = "Shipping Unit"
_columns = {
'name' : fields.char('Name', size=64,select=True, required=True, translate=True),
- 'type' : fields.selection([('unit','Unit'),('pack','Pack'),('box', 'Box'), ('palet', 'Pallet')], 'Type', required=True),
+ 'type' : fields.selection([('unit','Unit'),('pack','Pack'),('box', 'Box'), ('pallet', 'Pallet')], 'Type', required=True),
}
product_ul()
@@ -248,12 +248,12 @@ class product_template(osv.osv):
'type': fields.selection([('product','Stockable Product'),('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Will change the way requisitions are processed. Consumables are stockable products with infinite stock, or for use when you have no inventory management in the system."),
'supply_method': fields.selection([('produce','Produce'),('buy','Buy')], 'Supply method', required=True, help="Produce will generate production order or tasks, according to the product type. Purchase will trigger purchase orders when requested."),
'sale_delay': fields.float('Customer Lead Time', help="This is the average time between the confirmation of the customer order and the delivery of the finished products. It's the time you promise to your customers."),
- 'produce_delay': fields.float('Manufacturing Lead Time', help="Average time to produce this product. This is only for the production order and, if it is a multi-level bill of material, it's only for the level of this product. Different delays will be summed for all levels and purchase orders."),
+ 'produce_delay': fields.float('Manufacturing Lead Time', help="Average time to produce this product. This is only for the production order and, if it is a multi-level bill of material, it's only for the level of this product. Different lead times will be summed for all levels and purchase orders."),
'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Requisition Method', required=True, help="'Make to Stock': When needed, take from the stock or wait until re-supplying. 'Make to Order': When needed, purchase or produce for the requisition request."),
'rental': fields.boolean('Can be Rent'),
'categ_id': fields.many2one('product.category','Category', required=True, change_default=True),
'list_price': fields.float('Sale Price', digits=(16, int(config['price_accuracy'])), help="Base price for computing the customer price. Sometimes called the catalog price."),
- 'standard_price': fields.float('Cost Price', required=True, digits=(16, int(config['price_accuracy'])), help="The cost of the product for accounting stock valuation. It can serves as a base price for supplier price."),
+ 'standard_price': fields.float('Cost Price', required=True, digits=(16, int(config['price_accuracy'])), help="Product's cost for accounting stock valuation. It is the base price for the supplier price."),
'volume': fields.float('Volume', help="The volume in m3."),
'weight': fields.float('Gross weight', help="The gross weight in Kg."),
'weight_net': fields.float('Net weight', help="The net weight in Kg."),
@@ -264,9 +264,9 @@ class product_template(osv.osv):
'purchase_ok': fields.boolean('Can be Purchased', help="Determine if the product is visible in the list of products within a selection from a purchase order line."),
'state': fields.selection([('',''),('draft', 'In Development'),('sellable','In Production'),('end','End of Lifecycle'),('obsolete','Obsolete')], 'State', help="Tells the user if he can use the product or not."),
'uom_id': fields.many2one('product.uom', 'Default UoM', required=True, help="Default Unit of Measure used for all stock operation."),
- 'uom_po_id': fields.many2one('product.uom', 'Purchase UoM', required=True, help="Default Unit of Measure used for purchase orders. It must in the same category than the default unit of measure."),
+ 'uom_po_id': fields.many2one('product.uom', 'Purchase UoM', required=True, help="Default Unit of Measure used for purchase orders. It must be in the same category than the default unit of measure."),
'uos_id' : fields.many2one('product.uom', 'Unit of Sale',
- help='Used by companies that manages two unit of measure: invoicing and inventory management. For example, in food industries, you will manage a stock of ham but invoice in Kg. Keep empty to use the default UOM.'),
+ help='Used by companies that manage two units of measure: invoicing and inventory management. For example, in food industries, you will manage a stock of ham but invoice in Kg. Keep empty to use the default UOM.'),
'uos_coeff': fields.float('UOM -> UOS Coeff', digits=(16,4),
help='Coefficient to convert UOM to UOS\n'
' uom = uos * coeff'),
@@ -569,18 +569,18 @@ class product_packaging(osv.osv):
'sequence': fields.integer('Sequence'),
'name' : fields.char('Description', size=64),
'qty' : fields.float('Quantity by Package',
- help="The total number of products you can put by palet or box."),
+ help="The total number of products you can put by pallet or box."),
'ul' : fields.many2one('product.ul', 'Type of Package', required=True),
'ul_qty' : fields.integer('Package by layer'),
- 'rows' : fields.integer('Number of Layer', required=True,
- help='The number of layer on a palet or box'),
+ 'rows' : fields.integer('Number of Layers', required=True,
+ help='The number of layers on a pallet or box'),
'product_id' : fields.many2one('product.product', 'Product', select=1, ondelete='cascade', required=True),
'ean' : fields.char('EAN', size=14,
help="The EAN code of the package unit."),
'code' : fields.char('Code', size=14,
help="The code of the transport unit."),
'weight': fields.float('Total Package Weight',
- help='The weight of a full of products palet or box.'),
+ help='The weight of a full package, pallet or box.'),
'weight_ul': fields.float('Empty Package Weight',
help='The weight of the empty UL'),
'height': fields.float('Height', help='The height of the package'),
@@ -627,12 +627,12 @@ class product_supplierinfo(osv.osv):
_description = "Information about a product supplier"
_columns = {
'name' : fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade', help="Supplier of this product"),
- 'product_name': fields.char('Partner Product Name', size=128, help="Name of the product for this partner, will be used when printing a request for quotation. Keep empty to use the internal one."),
- 'product_code': fields.char('Partner Product Code', size=64, help="Code of the product for this partner, will be used when printing a request for quotation. Keep empty to use the internal one."),
+ 'product_name': fields.char('Partner Product Name', size=128, help="This partner's product name will be used when printing a request for quotation. Keep empty to use the internal one."),
+ 'product_code': fields.char('Partner Product Code', size=64, help="This partner's product code will be used when printing a request for quotation. Keep empty to use the internal one."),
'sequence' : fields.integer('Priority'),
- 'qty' : fields.float('Minimal Quantity', required=True, help="The minimal quantity to purchase for this supplier, expressed in the default unit of measure."),
+ 'qty' : fields.float('Minimal Quantity', required=True, help="The minimal quantity to purchase to this supplier, expressed in the default unit of measure."),
'product_id' : fields.many2one('product.template', 'Product', required=True, ondelete='cascade', select=True),
- 'delay' : fields.integer('Delivery Delay', required=True, help="Delay in days between the confirmation of the purchase order and the reception of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning."),
+ 'delay' : fields.integer('Delivery Lead Time', required=True, help="Lead time in days between the confirmation of the purchase order and the reception of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning."),
'pricelist_ids': fields.one2many('pricelist.partnerinfo', 'suppinfo_id', 'Supplier Pricelist'),
'company_id':fields.many2one('res.company','Company'),
}
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 464421b5be7..f217c7d9a13 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -163,7 +163,7 @@ class purchase_order(osv.osv):
'pricelist_id':fields.many2one('product.pricelist', 'Pricelist', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."),
- 'state': fields.selection([('draft', 'Request for Quotation'), ('wait', 'Waiting'), ('confirmed', 'Waiting Supplier Ack'), ('approved', 'Approved'),('except_picking', 'Shipping Exception'), ('except_invoice', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Order State', readonly=True, help="The state of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' state. Then the order has to be confirmed by the user, the state switch to 'Confirmed'. Then the supplier must confirm the order to change the state to 'Approved'. When the purchase order is paid and received, the state becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the state becomes in exception.", select=True),
+ 'state': fields.selection([('draft', 'Request for Quotation'), ('wait', 'Waiting'), ('confirmed', 'Waiting Supplier Ack'), ('approved', 'Approved'),('except_picking', 'Shipping Exception'), ('except_invoice', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, help="The state of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' state. Then the order has to be confirmed by the user, the state switch to 'Confirmed'. Then the supplier must confirm the order to change the state to 'Approved'. When the purchase order is paid and received, the state becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the state becomes in exception.", select=True),
'order_line': fields.one2many('purchase.order.line', 'order_id', 'Order Lines', states={'approved':[('readonly',True)]}),
'validator' : fields.many2one('res.users', 'Validated by', readonly=True),
'notes': fields.text('Notes'),
@@ -176,7 +176,7 @@ class purchase_order(osv.osv):
'invoice_method': fields.selection([('manual','Manual'),('order','From Order'),('picking','From Picking')], 'Invoicing Control', required=True,
help="From Order: a draft invoice will be pre-generated based on the purchase order. The accountant " \
"will just have to validate this invoice for control.\n" \
- "From Picking: a draft invoice will be pre-genearted based on validated receptions.\n" \
+ "From Picking: a draft invoice will be pre-generated based on validated receptions.\n" \
"Manual: no invoice will be pre-generated. The accountant will have to encode manually."
),
'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Planned Date', type='datetime', help="This is computed as the minimum scheduled date of all purchase order lines' products."),
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 1be4b4a2477..55b0504c3a9 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -202,7 +202,7 @@ class sale_order(osv.osv):
'user_id': fields.many2one('res.users', 'Salesman', states={'draft': [('readonly', False)]}, select=True),
'partner_id': fields.many2one('res.partner', 'Customer', readonly=True, states={'draft': [('readonly', False)]}, required=True, change_default=True, select=True),
'partner_invoice_id': fields.many2one('res.partner.address', 'Invoice Address', readonly=True, required=True, states={'draft': [('readonly', False)]}),
- 'partner_order_id': fields.many2one('res.partner.address', 'Ordering Contact', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="The name and address of the contact that requested the order or quotation."),
+ 'partner_order_id': fields.many2one('res.partner.address', 'Ordering Contact', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="The name and address of the contact who requested the order or quotation."),
'partner_shipping_id': fields.many2one('res.partner.address', 'Shipping Address', readonly=True, required=True, states={'draft': [('readonly', False)]}),
'incoterm': fields.selection(_incoterm_get, 'Incoterm', size=3),
diff --git a/addons/stock/product.py b/addons/stock/product.py
index 5c42cdbdab2..eb7389c216e 100644
--- a/addons/stock/product.py
+++ b/addons/stock/product.py
@@ -164,13 +164,13 @@ class product_product(osv.osv):
return res
_columns = {
- 'qty_available': fields.function(_product_available, method=True, type='float', string='Real Stock', help="Current quantities of products in selected locations or all internal if none have been selected.", multi='qty_available'),
- 'virtual_available': fields.function(_product_available, method=True, type='float', string='Virtual Stock', help="Future stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming.", multi='qty_available'),
+ 'qty_available': fields.function(_product_available, method=True, type='float', string='Real Stock', help="Current quantity of products in selected locations or all internal if none have been selected.", multi='qty_available'),
+ 'virtual_available': fields.function(_product_available, method=True, type='float', string='Virtual Stock', help="Future stock for this product according to the selected locations or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming.", multi='qty_available'),
'incoming_qty': fields.function(_product_available, method=True, type='float', string='Incoming', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected.", multi='qty_available'),
'outgoing_qty': fields.function(_product_available, method=True, type='float', string='Outgoing', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected.", multi='qty_available'),
'track_production': fields.boolean('Track Production Lots' , help="Force to use a Production Lot during production order"),
- 'track_incoming': fields.boolean('Track Incomming Lots', help="Force to use a Production Lot during receptions"),
- 'track_outgoing': fields.boolean('Track Outging Lots', help="Force to use a Production Lot during deliveries"),
+ 'track_incoming': fields.boolean('Track Incoming Lots', help="Forces to use a tracking lot during receptions"),
+ 'track_outgoing': fields.boolean('Track Outgoing Lots', help="Forces to use a tracking lot during deliveries"),
'location_id': fields.dummy(string='Location', relation='stock.location', type='many2one', domain=[('usage','=','internal')]),
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index c6a4d51cbcb..540c4ff61af 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -149,12 +149,12 @@ class stock_location(osv.osv):
[('auto', 'Automatic Move'), ('manual', 'Manual Operation'), ('transparent', 'Automatic No Step Added')],
'Automatic Move',
required=True,
- help="This is used only if you selected a chained location type.\n" \
+ help="This is used only if you select a chained location type.\n" \
"The 'Automatic Move' value will create a stock move after the current one that will be "\
"validated automatically. With 'Manual Operation', the stock move has to be validated "\
"by a worker. With 'Automatic No Step Added', the location is replaced in the original move."
),
- 'chained_delay': fields.integer('Chained Delay (days)'),
+ 'chained_delay': fields.integer('Chained lead time (days)'),
'address_id': fields.many2one('res.partner.address', 'Location Address'),
'icon': fields.selection(tools.icons, 'Icon', size=64),
@@ -337,7 +337,7 @@ class stock_tracking(osv.osv):
return sequence + str(self.checksum(sequence))
_columns = {
- 'name': fields.char('Tracking', size=64, required=True),
+ 'name': fields.char('Tracking ID', size=64, required=True),
'active': fields.boolean('Active'),
'serial': fields.char('Reference', size=64),
'move_ids': fields.one2many('stock.move', 'tracking_id', 'Moves Tracked'),
From 1e1c996161e99e22265e07b388e3aca111e272d1 Mon Sep 17 00:00:00 2001
From: "RGA(OpenERP)" <>
Date: Mon, 21 Dec 2009 16:33:05 +0530
Subject: [PATCH 045/123] [REF] HR_attendance : Code optimized for sign in and
out
bzr revid: jvo@tinyerp.com-20091221110305-jvrdec4s2cfu69qt
---
addons/hr_attendance/hr_attendance.py | 47 ++++++++-----------
addons/hr_attendance/wizard/sign_in_out.py | 26 +++++++---
addons/hr_timesheet/wizard/sign_in_out.py | 6 +--
.../hr_timesheet_sheet/hr_timesheet_sheet.py | 4 +-
4 files changed, 43 insertions(+), 40 deletions(-)
diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py
index 07223487dc5..9309b40961a 100644
--- a/addons/hr_attendance/hr_attendance.py
+++ b/addons/hr_attendance/hr_attendance.py
@@ -106,43 +106,34 @@ class hr_employee(osv.osv):
'state': fields.function(_state, method=True, type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Attendance'),
}
- def sign_change(self, cr, uid, ids, context={}, dt=False):
- for emp in self.browse(cr, uid, ids):
- if not self._action_check(cr, uid, emp.id, dt, context):
- raise osv.except_osv(_('Warning'), _('You tried to sign with a date anterior to another event !\nTry to contact the administrator to correct attendances.'))
- res = {'action':'action', 'employee_id':emp.id}
- if dt:
- res['name'] = dt
- att_id = self.pool.get('hr.attendance').create(cr, uid, res, context=context)
- return True
-
- def sign_out(self, cr, uid, ids, context={}, dt=False, *args):
- id = False
- for emp in self.browse(cr, uid, ids):
- if not self._action_check(cr, uid, emp.id, dt, context):
- raise osv.except_osv(_('Warning'), _('You tried to sign out with a date anterior to another event !\nTry to contact the administrator to correct attendances.'))
- res = {'action':'sign_out', 'employee_id':emp.id}
- if dt:
- res['name'] = dt
- att_id = self.pool.get('hr.attendance').create(cr, uid, res, context=context)
- id = att_id
- return id
-
def _action_check(self, cr, uid, emp_id, dt=False,context={}):
cr.execute('select max(name) from hr_attendance where employee_id=%s', (emp_id,))
res = cr.fetchone()
return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))
- def sign_in(self, cr, uid, ids, context={}, dt=False, *args):
+ def attendance_action_change(self, cr, uid, ids, type='action', context={}, dt=False, *args):
id = False
- for emp in self.browse(cr, uid, ids):
- if not self._action_check(cr, uid, emp.id, dt, context):
- raise osv.except_osv(_('Warning'), _('You tried to sign in with a date anterior to another event !\nTry to contact the administrator to correct attendances.'))
- res = {'action':'sign_in', 'employee_id':emp.id}
+ warning_sign = 'sign'
+
+ if type == 'sign_in':
+ warning_sign = "Sign In"
+ elif type == 'sign_out':
+ warning_sign = "Sign Out"
+
+ for emp in self.read(cr, uid, ids, ['id'], context=context):
+ if not self._action_check(cr, uid, emp['id'], dt, context):
+ raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the administrator to correct attendances.')%(warning_sign,))
+
+ res = {'action' : type, 'employee_id' : emp['id']}
+
if dt:
res['name'] = dt
+
id = self.pool.get('hr.attendance').create(cr, uid, res, context=context)
- return id
+
+ if type != 'action':
+ return id
+ return True
hr_employee()
diff --git a/addons/hr_attendance/wizard/sign_in_out.py b/addons/hr_attendance/wizard/sign_in_out.py
index 3d1d364b43a..9b318d8a6f7 100644
--- a/addons/hr_attendance/wizard/sign_in_out.py
+++ b/addons/hr_attendance/wizard/sign_in_out.py
@@ -68,7 +68,7 @@ def _sign_in(self, cr, uid, data, context):
service = netsvc.LocalService('object_proxy')
emp_id = data['form']['emp_id']
if 'last_time' in data['form'] :
- if data['form']['last_time'] > time.strftime('%Y-%m-%d'):
+ if data['form']['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
raise wizard.except_wizard(_('UserError'), _('The sign-out date must be in the past'))
return {'success': False}
service.execute(cr.dbname, uid, 'hr.attendance', 'create', {
@@ -77,7 +77,7 @@ def _sign_in(self, cr, uid, data, context):
'employee_id': emp_id
})
try:
- success = service.execute(cr.dbname, uid, 'hr.employee', 'sign_in', [emp_id])
+ success = service.execute(cr.dbname, uid, 'hr.employee', 'attendance_action_change', [emp_id], 'sign_in')
except:
raise wizard.except_wizard(_('UserError'), _('A sign-in must be right after a sign-out !'))
return {'success': success}
@@ -86,12 +86,12 @@ def _sign_out(self, cr, uid, data, context):
service = netsvc.LocalService('object_proxy')
emp_id = data['form']['emp_id']
if 'last_time' in data['form'] :
- if data['form']['last_time'] > time.strftime('%Y-%m-%d'):
+ if data['form']['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
raise wizard.except_wizard(_('UserError'), _('The Sign-in date must be in the past'))
return {'success': False}
service.execute(cr.dbname, uid, 'hr.attendance', 'create', {'name':data['form']['last_time'], 'action':'sign_in', 'employee_id':emp_id})
try:
- success = service.execute(cr.dbname, uid, 'hr.employee', 'sign_out', [emp_id])
+ success = service.execute(cr.dbname, uid, 'hr.employee', 'attendance_action_change', [emp_id], 'sign_out')
except:
raise wizard.except_wizard(_('UserError'), _('A sign-out must be right after a sign-in !'))
@@ -99,7 +99,7 @@ def _sign_out(self, cr, uid, data, context):
so_ask_form ='''
'''
@@ -122,7 +122,7 @@ def _si_check(self, cr, uid, data, context):
si_ask_form ='''
'''
@@ -132,14 +132,22 @@ si_ask_fields = {
'last_time' : {'string' : "Your last sign in", 'type' : 'datetime', 'required' : True},
}
+so_wo_si_form = '''
+'''
+
def _so_check(self, cr, uid, data, context):
states = {True : 'so', False: 'so_ask_si'}
service = netsvc.LocalService('object_proxy')
emp_id = data['form']['emp_id']
- att_id = service.execute(cr.dbname, uid, 'hr.attendance', 'search', [('employee_id', '=', emp_id)], limit=1, order='name desc')
+ att_id = service.execute(cr.dbname, uid, 'hr.attendance', 'search', [('employee_id', '=', emp_id),('action','!=','action')], limit=1, order='name desc')
last_att = service.execute(cr.dbname, uid, 'hr.attendance', 'read', att_id)
if last_att:
last_att = last_att[0]
+
+ if not att_id and not last_att:
+ return 'so_wo_si'
cond = last_att and last_att['action'] == 'sign_in'
return states[cond]
@@ -173,6 +181,10 @@ class wiz_si_so(wizard.interface):
'actions' : [_sign_out],
'result' : {'type' : 'state', 'state':'end'}
},
+ 'so_wo_si' : {
+ 'actions' : [],
+ 'result' : {'type' : 'form', 'arch' : so_wo_si_form, 'fields' : {}, 'state' : [('end', 'Ok')] }
+ },
}
wiz_si_so('hr.si_so')
diff --git a/addons/hr_timesheet/wizard/sign_in_out.py b/addons/hr_timesheet/wizard/sign_in_out.py
index 4abf337a475..69be06a4b88 100644
--- a/addons/hr_timesheet/wizard/sign_in_out.py
+++ b/addons/hr_timesheet/wizard/sign_in_out.py
@@ -91,7 +91,7 @@ def _sign_in_result(self, cr, uid, data, context):
emp_id = data['form']['emp_id']
from osv.osv import except_osv
try:
- success = emp_obj.sign_in(cr, uid, [emp_id], dt=data['form']['date'] or False)
+ success = emp_obj.attendance_action_change(cr, uid, [emp_id], type = 'sign_in' ,dt=data['form']['date'] or False)
except except_osv, e:
raise wizard.except_wizard(e.name, e.value)
return {}
@@ -118,14 +118,14 @@ def _write(self, cr, uid, data, emp_id, context):
def _sign_out_result_end(self, cr, uid, data, context):
emp_obj = pooler.get_pool(cr.dbname).get('hr.employee')
emp_id = data['form']['emp_id']
- emp_obj.sign_out(cr, uid, [emp_id], dt=data['form']['date'])
+ emp_obj.attendance_action_change(cr, uid, [emp_id], type='sign_out',dt=data['form']['date'])
_write(self, cr, uid, data, emp_id, context)
return {}
def _sign_out_result(self, cr, uid, data, context):
emp_obj = pooler.get_pool(cr.dbname).get('hr.employee')
emp_id = data['form']['emp_id']
- emp_obj.sign_change(cr, uid, [emp_id], dt=data['form']['date'])
+ emp_obj.attendance_action_change(cr, uid, [emp_id], type='action',dt=data['form']['date'])
_write(self, cr, uid, data, emp_id, context)
return {}
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
index 4eff8d63800..7d23e1340cb 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
@@ -202,7 +202,7 @@ class hr_timesheet_sheet(osv.osv):
emp_obj = self.pool.get('hr.employee')
emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)])
context['sheet_id']=ids[0]
- success = emp_obj.sign_in(cr, uid, emp_id, context=context)
+ success = emp_obj.attendance_action_change(cr, uid, emp_id, type='sign_in', context=context,)
return True
def sign_out(self, cr, uid, ids, context):
@@ -211,7 +211,7 @@ class hr_timesheet_sheet(osv.osv):
emp_obj = self.pool.get('hr.employee')
emp_id = emp_obj.search(cr, uid, [('user_id', '=', uid)])
context['sheet_id']=ids[0]
- success = emp_obj.sign_out(cr, uid, emp_id, context=context)
+ success = emp_obj.attendance_action_change(cr, uid, emp_id, type='sign_out', context=context,)
return True
_columns = {
From fe9ae08777060fb8473b8fda6f0c3398e73e2cfd Mon Sep 17 00:00:00 2001
From: vir-openerp <>
Date: Mon, 21 Dec 2009 17:26:44 +0530
Subject: [PATCH 046/123] [FIX]: report_task: month field problem
bzr revid: uco@tinyerp.co.in-20091221115644-j019xuhmq6wwjzzs
---
addons/report_task/report_task.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/addons/report_task/report_task.py b/addons/report_task/report_task.py
index 110226f627e..05c14aa9879 100644
--- a/addons/report_task/report_task.py
+++ b/addons/report_task/report_task.py
@@ -133,7 +133,7 @@ class report_timesheet_task_user(osv.osv):
return result
_columns = {
- 'name': fields.char('Year',size=64,required=False, readonly=True),
+ 'name': fields.date('Month',readonly=True),
'user_id': fields.many2one('res.users', 'User',readonly=True),
'timesheet_hrs': fields.function(get_hrs_timesheet, method=True, string="Timesheet Hours"),
'task_hrs': fields.function(_get_task_hours, method=True, string="Task Hours"),
@@ -154,7 +154,7 @@ class report_timesheet_task_user(osv.osv):
union
select to_char(h.name,'YYYY-MM-01') as name,
to_char(h.name,'MM') as m_id
- from hr_timesheet_sheet_sheet_day h) as month) """)
+ from hr_timesheet_sheet_sheet_day h) as months) """)
report_timesheet_task_user()
From 10c3b2da7d1a1239233e825c52c4a365a5ed6f43 Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Mon, 21 Dec 2009 17:51:32 +0530
Subject: [PATCH 047/123] [IMP]: Generalization of tooltips: Added tooltips for
active field
bzr revid: uco@tinyerp.co.in-20091221122132-hkesf2dy48lpdvum
---
addons/account/account.py | 10 +++++-----
addons/account/project/project.py | 4 ++--
addons/account_report/account.py | 2 +-
addons/auction/auction.py | 2 +-
addons/base_contact/base_contact.py | 2 +-
addons/base_report_creator/base_report_creator.py | 2 +-
addons/caldav/common.py | 2 +-
addons/crm/crm.py | 8 ++++----
addons/delivery/delivery.py | 4 ++--
addons/document/document.py | 2 +-
addons/hr/hr.py | 2 +-
addons/hr_holidays/hr.py | 4 ++--
addons/mrp/mrp.py | 8 ++++----
addons/process/process.py | 2 +-
addons/product/pricelist.py | 2 +-
addons/product/product.py | 4 ++--
addons/project/project.py | 4 ++--
addons/sale_journal/sale_journal.py | 2 +-
addons/scrum/scrum.py | 2 +-
addons/stock/stock.py | 8 ++++----
addons/subscription/subscription.py | 4 ++--
21 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index 967eeff9279..7b63197cbb4 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -37,7 +37,7 @@ class account_payment_term(osv.osv):
_description = "Payment Term"
_columns = {
'name': fields.char('Payment Term', size=64, translate=True, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the payment term without removing it."),
'note': fields.text('Description', translate=True),
'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'),
}
@@ -292,7 +292,7 @@ class account_account(osv.osv):
'note': fields.text('Note'),
'company_currency_id': fields.function(_get_company_currency, method=True, type='many2one', relation='res.currency', string='Company Currency'),
'company_id': fields.many2one('res.company', 'Company', required=True),
- 'active': fields.boolean('Active', select=2),
+ 'active': fields.boolean('Active', select=2, help="If the active field is set to true, it will allow you to hide the account without removing it."),
'parent_left': fields.integer('Parent Left', select=1),
'parent_right': fields.integer('Parent Right', select=1),
@@ -467,7 +467,7 @@ class account_journal(osv.osv):
'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view'), ('code', '<>', 'closed')]),
'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view'), ('type', '<>', 'closed')]),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the journal without removing it."),
'view_id': fields.many2one('account.journal.view', 'View', required=True, help="Gives the view used when writing or browsing entries in this journal. The view tells Open ERP which fields should be visible, required or readonly and in which order. You can create your own view for a faster encoding in each journal."),
'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]"),
'default_debit_account_id': fields.many2one('account.account', 'Default Debit Account', domain="[('type','!=','view')]"),
@@ -676,7 +676,7 @@ class account_journal_period(osv.osv):
'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"),
'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"),
'icon': fields.function(_icon_get, method=True, string='Icon', type='char', size=32),
- 'active': fields.boolean('Active', required=True),
+ 'active': fields.boolean('Active', required=True, help="If the active field is set to true, it will allow you to hide the journal period without removing it."),
'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'State', required=True, readonly=True,
help='When journal period is created. The state is \'Draft\'. If a report is printed it comes to \'Printed\' state. When all transactions are done, it comes in \'Done\' state.'),
'fiscalyear_id': fields.related('period_id', 'fiscalyear_id', string='Fiscal Year', type='many2one', relation='account.fiscalyear'),
@@ -1240,7 +1240,7 @@ class account_tax(osv.osv):
'name': fields.char('Tax Name', size=64, required=True, translate=True, help="This name will be displayed on reports"),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the tax lines from the lowest sequences to the higher ones. The order is important if you have a tax with several tax children. In this case, the evaluation order is important."),
'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the tax without removing it."),
'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'),('balance','Balance')], 'Tax Type', required=True,
help="The computation method for the tax amount."),
'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True,
diff --git a/addons/account/project/project.py b/addons/account/project/project.py
index 0f4a87053ed..cba2fecd40a 100644
--- a/addons/account/project/project.py
+++ b/addons/account/project/project.py
@@ -171,7 +171,7 @@ class account_analytic_account(osv.osv):
'name' : fields.char('Account Name', size=64, required=True),
'complete_name': fields.function(_complete_name_calc, method=True, type='char', string='Full Account Name'),
'code' : fields.char('Account Code', size=24),
- 'active' : fields.boolean('Active'),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the analytic account without removing it."),
'type': fields.selection([('view','View'), ('normal','Normal')], 'Account Type'),
'description' : fields.text('Description'),
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),
@@ -270,7 +270,7 @@ class account_analytic_journal(osv.osv):
_columns = {
'name' : fields.char('Journal name', size=64, required=True),
'code' : fields.char('Journal code', size=8),
- 'active' : fields.boolean('Active'),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the analytic journal without removing it."),
'type': fields.selection([('sale','Sale'), ('purchase','Purchase'), ('cash','Cash'), ('general','General'), ('situation','Situation')], 'Type', size=32, required=True, help="Gives the type of the analytic journal. When it needs for a document (eg: an invoice) to create analytic entries, Open ERP will look for a matching journal of the same type."),
'line_ids' : fields.one2many('account.analytic.line', 'journal_id', 'Lines'),
'company_id': fields.many2one('res.company', 'Company', required=True),
diff --git a/addons/account_report/account.py b/addons/account_report/account.py
index d34eeb620d5..bbea35d7c38 100644
--- a/addons/account_report/account.py
+++ b/addons/account_report/account.py
@@ -153,7 +153,7 @@ class account_report(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the account report without removing it."),
'sequence': fields.integer('Sequence'),
'code': fields.char('Code', size=64, required=True),
'type': fields.selection([
diff --git a/addons/auction/auction.py b/addons/auction/auction.py
index da5a2998997..f90bf254515 100644
--- a/addons/auction/auction.py
+++ b/addons/auction/auction.py
@@ -170,7 +170,7 @@ class auction_lot_category(osv.osv):
_columns = {
'name': fields.char('Category Name', required=True, size=64),
'priority': fields.float('Priority'),
- 'active' : fields.boolean('Active'),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the auction lot category without removing it."),
'aie_categ' : fields.selection([('41',"Unclassifieds"),
('2',"Antiques"),
('42',"Antique/African Arts"),
diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py
index 55da58224df..ceaa35aaddd 100644
--- a/addons/base_contact/base_contact.py
+++ b/addons/base_contact/base_contact.py
@@ -49,7 +49,7 @@ class res_partner_contact(osv.osv):
'job_ids':fields.one2many('res.partner.job','contact_id','Functions and Addresses'),
'country_id':fields.many2one('res.country','Nationality'),
'birthdate':fields.date('Birth Date'),
- 'active' : fields.boolean('Active'),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the partner contact without removing it."),
'partner_id':fields.related('job_ids','address_id','partner_id',type='many2one', relation='res.partner', string='Main Employer'),
'function_id':fields.related('job_ids','function_id',type='many2one', relation='res.partner.function', string='Main Function'),
'job_id':fields.related('job_ids',type='many2one', relation='res.partner.job', string='Main Job'),
diff --git a/addons/base_report_creator/base_report_creator.py b/addons/base_report_creator/base_report_creator.py
index 326f09cfe90..2652fbf2a82 100644
--- a/addons/base_report_creator/base_report_creator.py
+++ b/addons/base_report_creator/base_report_creator.py
@@ -305,7 +305,7 @@ class report_creator(osv.osv):
_columns = {
'name': fields.char('Report Name',size=64, required=True),
'type': fields.selection([('list','Rows And Columns Report'),], 'Report Type',required=True),#('sum','Summation Report')
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the report without removing it."),
'view_type1': fields.selection([('form','Form'),('tree','Tree'),('graph','Graph'),('calendar','Calendar')], 'First View', required=True),
'view_type2': fields.selection([('','/'),('form','Form'),('tree','Tree'),('graph','Graph'),('calendar','Calendar')], 'Second View'),
'view_type3': fields.selection([('','/'),('form','Form'),('tree','Tree'),('graph','Graph'),('calendar','Calendar')], 'Third View'),
diff --git a/addons/caldav/common.py b/addons/caldav/common.py
index c3e08fc878d..334c35d20fb 100644
--- a/addons/caldav/common.py
+++ b/addons/caldav/common.py
@@ -109,7 +109,7 @@ class crm_caldav_alarm(osv.osv):
'duration': fields.integer('Duration'),
'repeat': fields.integer('Repeat'), # TODO
'attach': fields.binary('Attachment'),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the event alarm information without removing it."),
}
_defaults = {
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 44988520898..9e56d4cf1cc 100755
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -67,7 +67,7 @@ class crm_case_section(osv.osv):
_columns = {
'name': fields.char('Case Section',size=64, required=True, translate=True),
'code': fields.char('Section Code',size=8),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the case section without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
'sequence': fields.integer('Sequence'),
'user_id': fields.many2one('res.users', 'Responsible User'),
@@ -219,7 +219,7 @@ class crm_email_gateway_server(osv.osv):
'server_type': fields.selection([("pop","POP"),("imap","Imap")],"Type of Server", required=True, help="Type of Email gateway Server"),
'port': fields.integer("Port" , help="Port Of Email gateway Server. If port is omitted, the standard POP3 port (110) is used for POP EMail Server and the standard IMAP4 port (143) is used for IMAP Sever."),
'ssl': fields.boolean('SSL',help ="Use Secure Authentication"),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the email gateway server without removing it."),
}
_defaults = {
'server_type':lambda * a:'pop',
@@ -369,7 +369,7 @@ class crm_case_rule(osv.osv):
_description = "Case Rule"
_columns = {
'name': fields.char('Rule Name',size=64, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the case rule without removing it."),
'sequence': fields.integer('Sequence'),
'trg_state_from': fields.selection([('',''),('escalate','Escalate')]+AVAILABLE_STATES, 'Case State', size=16),
@@ -491,7 +491,7 @@ class crm_case(osv.osv):
'id': fields.integer('ID', readonly=True),
'name': fields.char('Description',size=64,required=True),
'priority': fields.selection(AVAILABLE_PRIORITIES, 'Priority'),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the case without removing it."),
'description': fields.text('Your action'),
'section_id': fields.many2one('crm.case.section', 'Section', required=True, select=True, help='Section to which Case belongs to. Define Responsible user and Email account for mail gateway.'),
'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id)]", help='Category related to the section.Subdivide the CRM cases independently or section-wise.'),
diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py
index b05dfb7fcdf..6ef39d6e8b9 100644
--- a/addons/delivery/delivery.py
+++ b/addons/delivery/delivery.py
@@ -50,7 +50,7 @@ class delivery_carrier(osv.osv):
'product_id': fields.many2one('product.product', 'Delivery Product', required=True),
'grids_id': fields.one2many('delivery.grid', 'carrier_id', 'Delivery Grids'),
'price' : fields.function(get_price, method=True,string='Price'),
- 'active': fields.boolean('Active')
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the delivery carrier without removing it.")
}
_defaults = {
'active': lambda *args:1
@@ -86,7 +86,7 @@ class delivery_grid(osv.osv):
'zip_from': fields.char('Start Zip', size=12),
'zip_to': fields.char('To Zip', size=12),
'line_ids': fields.one2many('delivery.grid.line', 'grid_id', 'Grid Line'),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the delivery grid without removing it."),
}
_defaults = {
'active': lambda *a: 1,
diff --git a/addons/document/document.py b/addons/document/document.py
index cd3d667f8bf..41318e43c14 100644
--- a/addons/document/document.py
+++ b/addons/document/document.py
@@ -434,7 +434,7 @@ class document_directory_content_type(osv.osv):
_columns = {
'name': fields.char('Content Type', size=64, required=True),
'code': fields.char('Extension', size=4),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the directory content type without removing it."),
}
_defaults = {
'active': lambda *args: 1
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index f20ae9be4e8..d5bb603bdfb 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -120,7 +120,7 @@ class hr_employee(osv.osv):
_columns = {
'name' : fields.char("Employee's Name", size=128, required=True),
- 'active' : fields.boolean('Active'),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the employee record without removing it."),
'company_id': fields.many2one('res.company', 'Company'),
'user_id' : fields.many2one('res.users', 'Related User'),
diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py
index 9f24fae015d..d2a492390b9 100644
--- a/addons/hr_holidays/hr.py
+++ b/addons/hr_holidays/hr.py
@@ -70,7 +70,7 @@ class hr_holidays_status(osv.osv):
'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.'),
'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'),
+ '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."),
'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'),
@@ -107,7 +107,7 @@ class hr_holidays_per_user(osv.osv):
'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'),
+ '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')
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 390663992e8..db0fa5dfa86 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -42,7 +42,7 @@ class mrp_workcenter(osv.osv):
_description = 'Work Center'
_columns = {
'name': fields.char('Work Center Name', size=64, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the work center without removing it."),
'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool')], 'Type', required=True),
'code': fields.char('Code', size=16),
'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="The normal working time of the workcenter."),
@@ -103,7 +103,7 @@ class mrp_routing(osv.osv):
_description = 'Routing'
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the routing without removing it."),
'code': fields.char('Code', size=8),
'note': fields.text('Description'),
@@ -174,7 +174,7 @@ class mrp_bom(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
'code': fields.char('Code', size=16),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the bills of material without removing it."),
'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True, help=
"Use a phantom bill of material in raw materials lines that have to be " \
"automatically computed in on eproduction order and not one per level." \
@@ -1193,7 +1193,7 @@ class stock_warehouse_orderpoint(osv.osv):
_description = "Orderpoint minimum rule"
_columns = {
'name': fields.char('Name', size=32, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."),
'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True),
'location_id': fields.many2one('stock.location', 'Location', required=True),
diff --git a/addons/process/process.py b/addons/process/process.py
index 62483fb6e65..23f54e54168 100644
--- a/addons/process/process.py
+++ b/addons/process/process.py
@@ -48,7 +48,7 @@ class process_process(osv.osv):
_description = "Process"
_columns = {
'name': fields.char('Name', size=30,required=True, translate=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the process without removing it."),
'model_id': fields.many2one('ir.model', 'Object', ondelete='set null'),
'note': fields.text('Notes', translate=True),
'node_ids': fields.one2many('process.node', 'process_id', 'Nodes')
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index 450582edf5d..58f1dd97a70 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -96,7 +96,7 @@ class product_pricelist(osv.osv):
_description = "Pricelist"
_columns = {
'name': fields.char('Pricelist Name',size=64, required=True, translate=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the pricelist without removing it."),
'type': fields.selection(_pricelist_type_get, 'Pricelist Type', required=True),
'version_id': fields.one2many('product.pricelist.version', 'pricelist_id', 'Pricelist Versions'),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
diff --git a/addons/product/product.py b/addons/product/product.py
index 78d88926aa1..4ec4535f3bb 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -91,7 +91,7 @@ class product_uom(osv.osv):
'factor_inv_data': fields.float('Factor', digits=(12, 6)),
'rounding': fields.float('Rounding Precision', digits=(16, 3), required=True,
help="The computed quantity will be a multiple of this value. Use 1.0 for products that can not be split."),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the unit of measure without removing it."),
}
_defaults = {
@@ -438,7 +438,7 @@ class product_product(osv.osv):
'code': fields.function(_product_code, method=True, type='char', string='Code'),
'partner_ref' : fields.function(_product_partner_ref, method=True, type='char', string='Customer ref'),
'default_code' : fields.char('Code', size=64),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the product without removing it."),
'variants': fields.char('Variants', size=64),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True),
'ean13': fields.char('EAN13', size=13),
diff --git a/addons/project/project.py b/addons/project/project.py
index f4452a5fbf0..a2ff54cd5d7 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -92,7 +92,7 @@ class project(osv.osv):
_columns = {
'name': fields.char("Project Name", size=128, required=True),
'complete_name': fields.function(_complete_name, method=True, string="Project Name", type='char', size=128),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the project without removing it."),
'category_id': fields.many2one('account.analytic.account','Analytic Account', help="Link this project to an analytic account if you need financial management on projects. It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc."),
'priority': fields.integer('Sequence'),
'manager': fields.many2one('res.users', 'Project Manager'),
@@ -276,7 +276,7 @@ class task(osv.osv):
return super(task, self).copy_data(cr, uid, id, default, context)
_columns = {
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the task without removing it."),
'name': fields.char('Task summary', size=128, required=True),
'description': fields.text('Description'),
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Importance'),
diff --git a/addons/sale_journal/sale_journal.py b/addons/sale_journal/sale_journal.py
index 5d7199d57ad..cdba7d031ee 100644
--- a/addons/sale_journal/sale_journal.py
+++ b/addons/sale_journal/sale_journal.py
@@ -28,7 +28,7 @@ class sale_journal_invoice_type(osv.osv):
_description = 'Invoice Types'
_columns = {
'name': fields.char('Invoice Type', size=64, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the invoice type without removing it."),
'note': fields.text('Note'),
'invoicing_method': fields.selection([('simple','Non grouped'),('grouped','Grouped')], 'Invoicing method', required=True),
}
diff --git a/addons/scrum/scrum.py b/addons/scrum/scrum.py
index 3e880986038..842a2a01395 100644
--- a/addons/scrum/scrum.py
+++ b/addons/scrum/scrum.py
@@ -159,7 +159,7 @@ class scrum_product_backlog(osv.osv):
_columns = {
'name' : fields.char('Feature', size=64, required=True),
'note' : fields.text('Note'),
- 'active' : fields.boolean('Active'),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the product backlog without removing it."),
'project_id': fields.many2one('scrum.project', 'Scrum Project', required=True, domain=[('scrum','=',1)]),
'user_id': fields.many2one('res.users', 'User'),
'sprint_id': fields.many2one('scrum.sprint', 'Sprint'),
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 540c4ff61af..b3f16e84121 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -37,7 +37,7 @@ class stock_incoterms(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True,help="Incoterms are series of sales terms.They are used to divide transaction costs and responsibilities between buyer and seller and reflect state-of-the-art transportation practices."),
'code': fields.char('Code', size=3, required=True,help="code for Incoterms"),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the incoterms without removing it."),
}
_defaults = {
'active': lambda *a: True,
@@ -129,7 +129,7 @@ class stock_location(osv.osv):
_columns = {
'name': fields.char('Location Name', size=64, required=True, translate=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the stock location without removing it."),
'usage': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production')], 'Location Type', required=True),
'allocation_method': fields.selection([('fifo', 'FIFO'), ('lifo', 'LIFO'), ('nearest', 'Nearest')], 'Allocation Method', required=True),
@@ -338,7 +338,7 @@ class stock_tracking(osv.osv):
_columns = {
'name': fields.char('Tracking ID', size=64, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the tracking lots without removing it."),
'serial': fields.char('Reference', size=64),
'move_ids': fields.one2many('stock.move', 'tracking_id', 'Moves Tracked'),
'date': fields.datetime('Date Created', required=True),
@@ -440,7 +440,7 @@ class stock_picking(osv.osv):
'origin': fields.char('Origin Reference', size=64),
'backorder_id': fields.many2one('stock.picking', 'Back Order'),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('delivery', 'Delivery')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the picking without removing it."),
'note': fields.text('Notes'),
'location_id': fields.many2one('stock.location', 'Location', help="Keep empty if you produce at the location where the finished products are needed." \
diff --git a/addons/subscription/subscription.py b/addons/subscription/subscription.py
index 62c26a5390f..dc07453959c 100644
--- a/addons/subscription/subscription.py
+++ b/addons/subscription/subscription.py
@@ -32,7 +32,7 @@ class subscription_document(osv.osv):
_description = "Subscription document"
_columns = {
'name': fields.char('Name', size=60, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the subscription document without removing it."),
'model': fields.many2one('ir.model', 'Object', required=True),
'field_ids': fields.one2many('subscription.document.fields', 'document_id', 'Fields')
}
@@ -68,7 +68,7 @@ class subscription_subscription(osv.osv):
_description = "Subscription"
_columns = {
'name': fields.char('Name', size=60, required=True),
- 'active': fields.boolean('Active'),
+ 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the subscription without removing it."),
'partner_id': fields.many2one('res.partner', 'Partner'),
'notes': fields.text('Notes'),
'user_id': fields.many2one('res.users', 'User', required=True),
From 8d3fb81f4e8c5d2565c9e9b864dde152c987d886 Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Mon, 21 Dec 2009 18:44:12 +0530
Subject: [PATCH 048/123] [IMP]: Generalization of tooltips: Added tooltips for
sequence field
bzr revid: uco@tinyerp.co.in-20091221131412-xv3u9m8556xkyg6t
---
addons/account/account.py | 2 +-
addons/account/account_bank_statement.py | 2 +-
addons/account/invoice.py | 2 +-
addons/account_analytic_default/account_analytic_default.py | 2 +-
addons/account_budget/crossovered_budget.py | 2 +-
addons/account_followup/followup.py | 2 +-
addons/account_invoice_layout/account_invoice_layout.py | 2 +-
addons/account_report/account.py | 2 +-
addons/account_reporting/account.py | 2 +-
addons/base_report_creator/base_report_creator.py | 2 +-
addons/board/board.py | 2 +-
addons/crm/crm.py | 4 ++--
addons/crm/crm_config.py | 2 +-
addons/delivery/delivery.py | 2 +-
addons/document/document.py | 2 +-
addons/hr_expense/hr_expense.py | 2 +-
addons/mrp/mrp.py | 6 +++---
addons/product/pricelist.py | 2 +-
addons/product/product.py | 6 +++---
addons/project/project.py | 2 +-
addons/project_gtd/project_gtd.py | 4 ++--
addons/report_task/report_task.py | 2 +-
addons/sale/sale.py | 2 +-
addons/scrum/scrum.py | 2 +-
24 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index 7b63197cbb4..bd78d192c81 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -448,7 +448,7 @@ class account_journal_column(osv.osv):
'name': fields.char('Column Name', size=64, required=True),
'field': fields.selection(_col_get, 'Field Name', method=True, required=True, size=32),
'view_id': fields.many2one('account.journal.view', 'Journal View', select=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order to journal column."),
'required': fields.boolean('Required'),
'readonly': fields.boolean('Readonly'),
}
diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index 393d424a585..1ebc3623f9b 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -591,7 +591,7 @@ class account_bank_statement_line(osv.osv):
'note': fields.text('Notes'),
'reconcile_amount': fields.function(_reconcile_amount,
string='Amount reconciled', method=True, type='float'),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bank statement line."),
}
_defaults = {
'name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement.line'),
diff --git a/addons/account/invoice.py b/addons/account/invoice.py
index 8ad957e6453..425f5a78b50 100644
--- a/addons/account/invoice.py
+++ b/addons/account/invoice.py
@@ -1306,7 +1306,7 @@ class account_invoice_tax(osv.osv):
'base': fields.float('Base', digits=(16,int(config['price_accuracy']))),
'amount': fields.float('Amount', digits=(16,int(config['price_accuracy']))),
'manual': fields.boolean('Manual'),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of invoice tax."),
'base_code_id': fields.many2one('account.tax.code', 'Base Code', help="The account basis of the tax declaration."),
'base_amount': fields.float('Base Code Amount', digits=(16,int(config['price_accuracy']))),
diff --git a/addons/account_analytic_default/account_analytic_default.py b/addons/account_analytic_default/account_analytic_default.py
index ad73ad0d403..cec8acaaaa0 100644
--- a/addons/account_analytic_default/account_analytic_default.py
+++ b/addons/account_analytic_default/account_analytic_default.py
@@ -29,7 +29,7 @@ class account_analytic_default(osv.osv):
_rec_name = 'analytic_id'
_order = 'sequence'
_columns = {
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of analytic distribution."),
'analytic_id': fields.many2one('account.analytic.account', 'Analytic Account'),
'product_id': fields.many2one('product.product', 'Product', ondelete='cascade'),
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='cascade'),
diff --git a/addons/account_budget/crossovered_budget.py b/addons/account_budget/crossovered_budget.py
index b350b15e9f3..fd319cd9262 100644
--- a/addons/account_budget/crossovered_budget.py
+++ b/addons/account_budget/crossovered_budget.py
@@ -45,7 +45,7 @@ class account_budget_post(osv.osv):
'account_ids': fields.many2many('account.account', 'account_budget_rel', 'budget_id', 'account_id', 'Accounts'),
'crossovered_budget_line': fields.one2many('crossovered.budget.lines', 'general_budget_id', 'Budget Lines'),
'company_id': fields.many2one('res.company', 'Company', required=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of budgetary position."),
}
_defaults = {
'sequence': lambda *a: 1,
diff --git a/addons/account_followup/followup.py b/addons/account_followup/followup.py
index d6f6a170d26..cdef39b9414 100644
--- a/addons/account_followup/followup.py
+++ b/addons/account_followup/followup.py
@@ -37,7 +37,7 @@ class followup_line(osv.osv):
_description = 'Follow-Ups Criteria'
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of follow-up lines."),
'delay': fields.integer('Days of delay'),
'start': fields.selection([('days','Net Days'),('end_of_month','End of Month')], 'Type of Term', size=64, required=True),
'followup_id': fields.many2one('account_followup.followup', 'Follow Ups', required=True, ondelete="cascade"),
diff --git a/addons/account_invoice_layout/account_invoice_layout.py b/addons/account_invoice_layout/account_invoice_layout.py
index 0e0c68cb15a..e6e7590a00a 100644
--- a/addons/account_invoice_layout/account_invoice_layout.py
+++ b/addons/account_invoice_layout/account_invoice_layout.py
@@ -159,7 +159,7 @@ class account_invoice_line(osv.osv):
('line','Separator Line'),
('break','Page Break'),]
,'Type', select=True, required=True),
- 'sequence': fields.integer('Sequence Number'),
+ 'sequence': fields.integer('Sequence Number', help="Gives the sequence order when displaying a list of invoice lines."),
'functional_field': fields.function(_fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='char', fnct_search=None, obj=None, method=True, store=False, string="Source Account"),
}
diff --git a/addons/account_report/account.py b/addons/account_report/account.py
index bbea35d7c38..c4be180043e 100644
--- a/addons/account_report/account.py
+++ b/addons/account_report/account.py
@@ -154,7 +154,7 @@ class account_report(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the account report without removing it."),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of account reports."),
'code': fields.char('Code', size=64, required=True),
'type': fields.selection([
('fiscal', 'Fiscal Statement'),
diff --git a/addons/account_reporting/account.py b/addons/account_reporting/account.py
index 89513923070..df915ad1601 100644
--- a/addons/account_reporting/account.py
+++ b/addons/account_reporting/account.py
@@ -84,7 +84,7 @@ class account_report_bs(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of account reporting for balance sheet."),
'code': fields.char('Code', size=64, required=True),
'account_id': fields.many2many('account.account', 'account_report_rel', 'report_id', 'account_id', 'Accounts'),
'note': fields.text('Note'),
diff --git a/addons/base_report_creator/base_report_creator.py b/addons/base_report_creator/base_report_creator.py
index 2652fbf2a82..57ddd4f1045 100644
--- a/addons/base_report_creator/base_report_creator.py
+++ b/addons/base_report_creator/base_report_creator.py
@@ -378,7 +378,7 @@ class report_creator_field(osv.osv):
_rec_name = 'field_id'
_order = "sequence,id"
_columns = {
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of fields."),
'field_id': fields.many2one('ir.model.fields', 'Field'),
'report_id': fields.many2one('base_report_creator.report','Report', on_delete='cascade'),
'group_method': fields.selection([('group','Grouped'),('sum','Sum'),('min','Minimum'),('count','Count'),('max','Maximum'),('avg','Average')], 'Grouping Method', required=True),
diff --git a/addons/board/board.py b/addons/board/board.py
index 6238da69a46..107477e8daf 100644
--- a/addons/board/board.py
+++ b/addons/board/board.py
@@ -116,7 +116,7 @@ class board_line(osv.osv):
_order = 'position,sequence'
_columns = {
'name': fields.char('Title', size=64, required=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of board lines."),
'height': fields.integer('Height'),
'width': fields.integer('Width'),
'board_id': fields.many2one('board.board', 'Dashboard', required=True, ondelete='cascade'),
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 9e56d4cf1cc..5c6731359f4 100755
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -69,7 +69,7 @@ class crm_case_section(osv.osv):
'code': fields.char('Section Code',size=8),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the case section without removing it."),
'allow_unlink': fields.boolean('Allow Delete', help="Allows to delete non draft cases"),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case sections."),
'user_id': fields.many2one('res.users', 'Responsible User'),
'reply_to': fields.char('Reply-To', size=64, help="The email address put in the 'Reply-To' of all emails sent by Open ERP about cases in this section"),
'parent_id': fields.many2one('crm.case.section', 'Parent Section'),
@@ -370,7 +370,7 @@ class crm_case_rule(osv.osv):
_columns = {
'name': fields.char('Rule Name',size=64, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the case rule without removing it."),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case rules."),
'trg_state_from': fields.selection([('',''),('escalate','Escalate')]+AVAILABLE_STATES, 'Case State', size=16),
'trg_state_to': fields.selection([('',''),('escalate','Escalate')]+AVAILABLE_STATES, 'Button Pressed', size=16),
diff --git a/addons/crm/crm_config.py b/addons/crm/crm_config.py
index 0e141ac60d9..e3e64de994d 100644
--- a/addons/crm/crm_config.py
+++ b/addons/crm/crm_config.py
@@ -55,7 +55,7 @@ class crm_case_stage(osv.osv):
_columns = {
'name': fields.char('Stage Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Case Section'),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
}
_defaults = {
'sequence': lambda *args: 1
diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py
index 6ef39d6e8b9..ebdabcd5097 100644
--- a/addons/delivery/delivery.py
+++ b/addons/delivery/delivery.py
@@ -79,7 +79,7 @@ class delivery_grid(osv.osv):
_description = "Delivery Grid"
_columns = {
'name': fields.char('Grid Name', size=64, required=True),
- 'sequence': fields.integer('Sequence', size=64, required=True),
+ 'sequence': fields.integer('Sequence', size=64, required=True, help="Gives the sequence order when displaying a list of delivery grid."),
'carrier_id': fields.many2one('delivery.carrier', 'Carrier', required=True, ondelete='cascade'),
'country_ids': fields.many2many('res.country', 'delivery_grid_country_rel', 'grid_id', 'country_id', 'Countries'),
'state_ids': fields.many2many('res.country.state', 'delivery_grid_state_rel', 'grid_id', 'state_id', 'States'),
diff --git a/addons/document/document.py b/addons/document/document.py
index 41318e43c14..68ebe36086d 100644
--- a/addons/document/document.py
+++ b/addons/document/document.py
@@ -451,7 +451,7 @@ class document_directory_content(osv.osv):
return res
_columns = {
'name': fields.char('Content Name', size=64, required=True),
- 'sequence': fields.integer('Sequence', size=16),
+ 'sequence': fields.integer('Sequence', size=16, help="Gives the sequence order when displaying a list of directory contents."),
'suffix': fields.char('Suffix', size=16),
'report_id': fields.many2one('ir.actions.report.xml', 'Report'),
'extension': fields.selection(_extension_get, 'Document Type', required=True, size=4),
diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index 7cd3d4b24c0..9ffdad9c55f 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -205,7 +205,7 @@ class hr_expense_line(osv.osv):
'description': fields.text('Description'),
'analytic_account': fields.many2one('account.analytic.account','Analytic account'),
'ref': fields.char('Reference', size=32),
- 'sequence' : fields.integer('Sequence'),
+ 'sequence' : fields.integer('Sequence', help="Gives the sequence order when displaying a list of expense lines."),
}
_defaults = {
'unit_quantity': lambda *a: 1,
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index db0fa5dfa86..d6a49c1dd55 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -126,7 +126,7 @@ class mrp_routing_workcenter(osv.osv):
_columns = {
'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True),
'name': fields.char('Name', size=64, required=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of routing workcenters."),
'cycle_nbr': fields.float('Number of Cycles', required=True,
help="Time in hours for doing one cycle."),
'hour_nbr': fields.float('Number of Hours', required=True, help="Cost per hour"),
@@ -185,7 +185,7 @@ class mrp_bom(osv.osv):
'method': fields.function(_compute_type, string='Method', method=True, type='selection', selection=[('',''),('stock','On Stock'),('order','On Order'),('set','Set / Pack')]),
'date_start': fields.date('Valid From', help="Validity of this BoM or component. Keep empty if it's always valid."),
'date_stop': fields.date('Valid Until', help="Validity of this BoM or component. Keep empty if it's always valid."),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bills of material."),
'position': fields.char('Internal Ref.', size=64, help="Reference to a position in an external plan."),
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_uos_qty': fields.float('Product UOS Qty'),
@@ -760,7 +760,7 @@ class mrp_production_workcenter_line(osv.osv):
'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True),
'cycle': fields.float('Nbr of cycles', digits=(16,2)),
'hour': fields.float('Nbr of hours', digits=(16,2)),
- 'sequence': fields.integer('Sequence', required=True),
+ 'sequence': fields.integer('Sequence', required=True, help="Gives the sequence order when displaying a list of work orders."),
'production_id': fields.many2one('mrp.production', 'Production Order', select=True, ondelete='cascade'),
}
_defaults = {
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index 58f1dd97a70..6b5b4444263 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -351,7 +351,7 @@ class product_pricelist_item(osv.osv):
'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Set a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
'min_quantity': fields.integer('Min. Quantity', required=True, help="The rule only applies if the partner buys/sells more than this quantity."),
- 'sequence': fields.integer('Sequence', required=True),
+ 'sequence': fields.integer('Sequence', required=True, help="Gives the sequence order when displaying a list of pricelist items."),
'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1, help="The mode for computing the price for this rule."),
'base_pricelist_id': fields.many2one('product.pricelist', 'If Other Pricelist'),
diff --git a/addons/product/product.py b/addons/product/product.py
index 4ec4535f3bb..37194c1a241 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -202,7 +202,7 @@ class product_category(osv.osv):
'complete_name': fields.function(_name_get_fnc, method=True, type="char", string='Name'),
'parent_id': fields.many2one('product.category','Parent Category', select=True),
'child_id': fields.one2many('product.category', 'parent_id', string='Child Categories'),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."),
}
_order = "sequence"
def _check_recursion(self, cr, uid, ids):
@@ -566,7 +566,7 @@ class product_packaging(osv.osv):
_description = "Packaging"
_rec_name = 'ean'
_columns = {
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of packaging."),
'name' : fields.char('Description', size=64),
'qty' : fields.float('Quantity by Package',
help="The total number of products you can put by pallet or box."),
@@ -629,7 +629,7 @@ class product_supplierinfo(osv.osv):
'name' : fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade', help="Supplier of this product"),
'product_name': fields.char('Partner Product Name', size=128, help="This partner's product name will be used when printing a request for quotation. Keep empty to use the internal one."),
'product_code': fields.char('Partner Product Code', size=64, help="This partner's product code will be used when printing a request for quotation. Keep empty to use the internal one."),
- 'sequence' : fields.integer('Priority'),
+ 'sequence' : fields.integer('Priority', help="Assigns the priority to the list of product supplier."),
'qty' : fields.float('Minimal Quantity', required=True, help="The minimal quantity to purchase to this supplier, expressed in the default unit of measure."),
'product_id' : fields.many2one('product.template', 'Product', required=True, ondelete='cascade', select=True),
'delay' : fields.integer('Delivery Lead Time', required=True, help="Lead time in days between the confirmation of the purchase order and the reception of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning."),
diff --git a/addons/project/project.py b/addons/project/project.py
index a2ff54cd5d7..b7ce724373e 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -280,7 +280,7 @@ class task(osv.osv):
'name': fields.char('Task summary', size=128, required=True),
'description': fields.text('Description'),
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Importance'),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of tasks."),
'type': fields.many2one('project.task.type', 'Type'),
'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
help='If the task is created the state \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
diff --git a/addons/project_gtd/project_gtd.py b/addons/project_gtd/project_gtd.py
index 871f6775102..b7f5dbecfe2 100644
--- a/addons/project_gtd/project_gtd.py
+++ b/addons/project_gtd/project_gtd.py
@@ -35,7 +35,7 @@ class project_gtd_context(osv.osv):
_description = "Contexts"
_columns = {
'name': fields.char('Context', size=64, required=True, select=1),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of contexts."),
'project_default_id': fields.many2one('project.project', 'Default Project', required=True),
}
_defaults = {
@@ -51,7 +51,7 @@ class project_gtd_timebox(osv.osv):
_order = "sequence"
_columns = {
'name': fields.char('Timebox', size=64, required=True, select=1),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of timebox."),
'icon': fields.selection(tools.icons, 'Icon', size=64),
}
diff --git a/addons/report_task/report_task.py b/addons/report_task/report_task.py
index 05c14aa9879..342d2f5c4ea 100644
--- a/addons/report_task/report_task.py
+++ b/addons/report_task/report_task.py
@@ -68,7 +68,7 @@ class report_closed_task(osv.osv):
_description = "Closed Task Report"
_auto = False
_columns = {
- 'sequence': fields.integer('Sequence', readonly=True),
+ 'sequence': fields.integer('Sequence', readonly=True, help="Gives the sequence order when displaying a list of closed task reports."),
'name': fields.char('Task summary', size=128, readonly=True),
'project_id': fields.many2one('project.project', 'Project', readonly=True),
'user_id': fields.many2one('res.users', 'Assigned to', readonly=True),
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 55b0504c3a9..92ff5325982 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -752,7 +752,7 @@ class sale_order_line(osv.osv):
_columns = {
'order_id': fields.many2one('sale.order', 'Order Ref', required=True, ondelete='cascade', select=True),
'name': fields.char('Description', size=256, required=True, select=True),
- 'sequence': fields.integer('Sequence'),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale order lines."),
'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer"),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
'invoice_lines': fields.many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
diff --git a/addons/scrum/scrum.py b/addons/scrum/scrum.py
index 842a2a01395..ed14304e080 100644
--- a/addons/scrum/scrum.py
+++ b/addons/scrum/scrum.py
@@ -163,7 +163,7 @@ class scrum_product_backlog(osv.osv):
'project_id': fields.many2one('scrum.project', 'Scrum Project', required=True, domain=[('scrum','=',1)]),
'user_id': fields.many2one('res.users', 'User'),
'sprint_id': fields.many2one('scrum.sprint', 'Sprint'),
- 'sequence' : fields.integer('Sequence'),
+ 'sequence' : fields.integer('Sequence', help="Gives the sequence order when displaying a list of product backlog."),
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Priority'),
'tasks_id': fields.one2many('scrum.task', 'product_backlog_id', 'Tasks Details'),
'state': fields.selection([('draft','Draft'),('open','Open'),('done','Done')], 'State', required=True),
From f50f8d71b8b1f357f67b646e997ed6e7b784069e Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Mon, 21 Dec 2009 19:06:04 +0530
Subject: [PATCH 049/123] [IMP]: Caldav: Improvement for importing project task
with duration propery
bzr revid: rpa@tinyerp.com-20091221133604-ot8dez1yevae71hp
---
addons/caldav/calendar.py | 4 +++-
addons/caldav/common.py | 2 +-
addons/project_calendar/project_calendar.py | 11 ++++++++---
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index 6ec234a6f4b..7800c773112 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -126,6 +126,8 @@ class CalDAV(object):
elif map_type == 'datetime' and data[map_field]:
vevent.add(field).value = datetime.strptime(data[map_field], \
"%Y-%m-%d %H:%M:%S")
+ elif map_type == "timedelta":
+ vevent.add(field).value = timedelta(hours=data[map_field])
if self.__attribute__.get(field).has_key('mapping'):
for key1, val1 in self.ical_get(field, 'mapping').items():
if val1 == data[map_field]:
@@ -151,7 +153,7 @@ class CalDAV(object):
if cal_data.name.lower() in self.__attribute__:
self.ical_set(cal_data.name.lower(), cal_data.value, 'value')
vals = map_data(cr, uid, self)
- if vals : res.append(vals)
+ if vals: res.append(vals)
self.ical_reset('value')
return res
diff --git a/addons/caldav/common.py b/addons/caldav/common.py
index c3e08fc878d..46192c6a0e6 100644
--- a/addons/caldav/common.py
+++ b/addons/caldav/common.py
@@ -204,7 +204,7 @@ virtual_report_spool()
class virtual_wizard(web_services.wizard):
def exp_execute(self, db, uid, wiz_id, datas, action='init', context=None):
if wiz_id not in self.wiz_uid:
- # TODO : To Check why need it
+ # TODO: To Check why need it
if wiz_id == 1:
wiz_name ='base_setup.base_setup'
if wiz_id == 2:
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
index 593a3825c03..82ae10ff4f7 100644
--- a/addons/project_calendar/project_calendar.py
+++ b/addons/project_calendar/project_calendar.py
@@ -66,7 +66,7 @@ class project_task(osv.osv):
'description': {'field': 'description', 'type': 'text'},
# 'dtstamp': {'field': 'field', 'type': 'text'},
'dtstart': {'field': 'date_start', 'type': 'datetime'},
- 'duration': {'field': 'planned_hours', 'type': 'int'},
+ 'duration': {'field': 'planned_hours', 'type': 'timedelta'},
'due': {'field': 'date_deadline', 'type': 'datetime'},
# 'geo': {'field': 'field', 'type': 'text'},
# 'last-mod ': {'field': 'field', 'type': 'text'},
@@ -112,9 +112,14 @@ class project_task(osv.osv):
vals = todo_obj.import_ical(cr, uid, file_content)
for val in vals:
- if not val.has_key('duration'):
- # 'Compute duration'
+ obj_tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode_id
+ if not val.has_key('planned_hours'):
+ # 'Compute duration' in days
val['planned_hours'] = 16
+ else:
+ # Convert timedelta into Project time unit
+ val['planned_hours'] = (val['planned_hours'].seconds/float(86400) + \
+ val['planned_hours'].days) * obj_tm.factor
val.pop('id')
task_id = self.create(cr, uid, val)
return {'count': len(vals)}
From cb304bf0c8f58ad2a0b539b73d63d0ac594510e7 Mon Sep 17 00:00:00 2001
From: Launchpad Code Hosting
Date: Tue, 22 Dec 2009 04:35:45 +0000
Subject: [PATCH 050/123] Launchpad automatic translations update.
bzr revid: codehost@crowberry-20091222043545-p615u32x9nsnpzoq
---
bin/addons/base/i18n/ro.po | 9 ++++-----
debian/po/ro.po | 4 ++--
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/bin/addons/base/i18n/ro.po b/bin/addons/base/i18n/ro.po
index 4065135be01..86a03652760 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-09 10:13+0000\n"
-"PO-Revision-Date: 2009-12-20 16:39+0000\n"
+"PO-Revision-Date: 2009-12-21 06:09+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: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -414,7 +414,7 @@ msgid "Country Name"
msgstr "Nume tara"
#. module: base
-#: model:res.country,name:base.co
+#: model:res.country,name:base.coreturn
msgid "Colombia"
msgstr ""
@@ -994,8 +994,7 @@ msgstr ""
#. module: base
#: code:addons/base/ir/ir_model.py:0
#, python-format
-msgid ""
-"Model %s Does not Exist !"
+msgid "Model %s Does not Exist !"
msgstr ""
#. module: base
diff --git a/debian/po/ro.po b/debian/po/ro.po
index e24cc887fd6..ce52d54d6f7 100644
--- a/debian/po/ro.po
+++ b/debian/po/ro.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
-"PO-Revision-Date: 2009-12-20 09:24+0000\n"
+"PO-Revision-Date: 2009-12-21 06:11+0000\n"
"Last-Translator: Valentin Caragea \n"
"Language-Team: Romanian \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. Type: string
From 881fcc79c2fcd3604ab0f85e2b4eccb824d15448 Mon Sep 17 00:00:00 2001
From: Launchpad Code Hosting
Date: Tue, 22 Dec 2009 04:36:08 +0000
Subject: [PATCH 051/123] Launchpad automatic translations update.
bzr revid: codehost@crowberry-20091222043608-tsh8urt1672jd3wm
---
addons/account_analytic_default/i18n/hr.po | 2 +-
addons/document/i18n/cs.po | 44 +++++-----
addons/document/i18n/hr.po | 2 +-
addons/document_ics/i18n/hr.po | 2 +-
addons/document_webdav/i18n/hr.po | 2 +-
addons/google_map/i18n/hr.po | 2 +-
addons/mrp_subproduct/i18n/zh_CN.po | 6 +-
addons/product/i18n/ar.po | 20 ++---
addons/purchase/i18n/zh_CN.po | 64 +++++++-------
addons/report_crm/i18n/zh_CN.po | 64 +++++++-------
addons/report_intrastat/i18n/zh_CN.po | 80 +++++++++---------
addons/report_mrp/i18n/zh_CN.po | 16 ++--
addons/sale/i18n/ar.po | 64 +++++++-------
addons/sale/i18n/zh_CN.po | 98 +++++++++++-----------
14 files changed, 234 insertions(+), 232 deletions(-)
diff --git a/addons/account_analytic_default/i18n/hr.po b/addons/account_analytic_default/i18n/hr.po
index 9356d0d43ee..742694ede8f 100644
--- a/addons/account_analytic_default/i18n/hr.po
+++ b/addons/account_analytic_default/i18n/hr.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_analytic_default
diff --git a/addons/document/i18n/cs.po b/addons/document/i18n/cs.po
index 0064b70d8e4..f7cdccd295b 100644
--- a/addons/document/i18n/cs.po
+++ b/addons/document/i18n/cs.po
@@ -7,29 +7,29 @@ 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 07:32+0000\n"
+"PO-Revision-Date: 2009-12-21 14:04+0000\n"
"Last-Translator: Kuvaly \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: 2009-12-16 05:25+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document
#: field:document.directory,create_date:0
msgid "Date Created"
-msgstr ""
+msgstr "Datum vytvoření"
#. module: document
#: field:document.directory,ressource_id:0
msgid "Resource ID"
-msgstr ""
+msgstr "ID zdroje"
#. module: document
#: field:document.directory.content,include_name:0
msgid "Include Record Name"
-msgstr ""
+msgstr "Obsažené jméno záznamu"
#. module: document
#: constraint:ir.model:0
@@ -61,7 +61,7 @@ msgstr "Náhled"
#. module: document
#: field:ir.attachment,store_method:0
msgid "Storing Method"
-msgstr ""
+msgstr "Způsob skladování"
#. module: document
#: model:ir.actions.act_window,name:document.action_config_auto_directory
@@ -71,7 +71,7 @@ msgstr ""
#. module: document
#: field:ir.attachment,file_size:0
msgid "File Size"
-msgstr ""
+msgstr "Velikost souboru"
#. module: document
#: help:document.directory.content,include_name:0
@@ -83,12 +83,12 @@ msgstr ""
#. module: document
#: selection:document.directory,type:0
msgid "Other Resources"
-msgstr ""
+msgstr "Jiné zdroje"
#. module: document
#: field:document.directory,ressource_parent_type_id:0
msgid "Parent Model"
-msgstr ""
+msgstr "Nadřazený model"
#. module: document
#: view:document.configuration.wizard:0
@@ -103,7 +103,7 @@ msgstr "Příloha"
#. module: document
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "Špatný název modelu v definici akce"
#. module: document
#: selection:document.directory,type:0
@@ -113,7 +113,7 @@ msgstr ""
#. module: document
#: model:ir.model,name:document.model_document_directory_content_type
msgid "Directory Content Type"
-msgstr ""
+msgstr "Typ obsahu adresáře"
#. module: document
#: help:document.directory,domain:0
@@ -131,40 +131,40 @@ msgstr ""
#. module: document
#: field:document.directory,type:0
msgid "Type"
-msgstr ""
+msgstr "Typ"
#. module: document
#: model:ir.actions.act_window,name:document.action_document_directory_tree
#: model:ir.ui.menu,name:document.menu_document_directories_tree
msgid "Directorie's Structure"
-msgstr ""
+msgstr "Struktura adresářů"
#. module: document
#: field:document.directory,parent_id:0
msgid "Parent Item"
-msgstr ""
+msgstr "Nadřazená položka"
#. module: document
#: view:ir.attachment:0
msgid "File Information"
-msgstr ""
+msgstr "Informace souboru"
#. module: document
#: field:document.directory,file_ids:0
#: view:ir.attachment:0
msgid "Files"
-msgstr ""
+msgstr "Soubory"
#. module: document
#: field:ir.attachment,store_fname:0
msgid "Stored Filename"
-msgstr ""
+msgstr "Skladované jméno souboru"
#. module: document
#: field:document.directory,write_uid:0
#: field:ir.attachment,write_uid:0
msgid "Last Modification User"
-msgstr ""
+msgstr "Poslední upravující uživatel"
#. module: document
#: view:document.configuration.wizard:0
@@ -179,7 +179,7 @@ msgstr "Stromová struktura"
#. module: document
#: field:ir.attachment,title:0
msgid "Resource Title"
-msgstr ""
+msgstr "Titulek zdroje"
#. module: document
#: model:ir.actions.todo,note:document.config_auto_directory
@@ -191,7 +191,7 @@ msgstr ""
#. module: document
#: model:ir.model,name:document.model_document_directory_content
msgid "Directory Content"
-msgstr ""
+msgstr "Obsah adresáře"
#. module: document
#: help:document.directory,ressource_parent_type_id:0
@@ -213,13 +213,13 @@ msgstr "Odkaz"
#. module: document
#: view:document.directory:0
msgid "Directory Type"
-msgstr ""
+msgstr "Typ adresáře"
#. module: document
#: field:document.directory,group_ids:0
#: field:ir.attachment,group_ids:0
msgid "Groups"
-msgstr ""
+msgstr "Skupiny"
#. module: document
#: field:document.directory.content,report_id:0
diff --git a/addons/document/i18n/hr.po b/addons/document/i18n/hr.po
index 4c4dfd7b52c..5850975e095 100644
--- a/addons/document/i18n/hr.po
+++ b/addons/document/i18n/hr.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document
diff --git a/addons/document_ics/i18n/hr.po b/addons/document_ics/i18n/hr.po
index 545d4866ceb..02ac4ad862e 100644
--- a/addons/document_ics/i18n/hr.po
+++ b/addons/document_ics/i18n/hr.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document_ics
diff --git a/addons/document_webdav/i18n/hr.po b/addons/document_webdav/i18n/hr.po
index c2766b9ba68..82ea8b5d2ac 100644
--- a/addons/document_webdav/i18n/hr.po
+++ b/addons/document_webdav/i18n/hr.po
@@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: document_webdav_old
diff --git a/addons/google_map/i18n/hr.po b/addons/google_map/i18n/hr.po
index c1edeb483bb..983b38ce23c 100644
--- a/addons/google_map/i18n/hr.po
+++ b/addons/google_map/i18n/hr.po
@@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: google_map
diff --git a/addons/mrp_subproduct/i18n/zh_CN.po b/addons/mrp_subproduct/i18n/zh_CN.po
index a6c45746ca5..f8c2ef3273b 100644
--- a/addons/mrp_subproduct/i18n/zh_CN.po
+++ b/addons/mrp_subproduct/i18n/zh_CN.po
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.6\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-12-16 04:36+0000\n"
+"PO-Revision-Date: 2009-12-21 08:02+0000\n"
"Last-Translator: Joshua Jan \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: 2009-12-17 04:44+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: mrp_subproduct
@@ -70,7 +70,7 @@ msgstr "子产品"
#. module: mrp_subproduct
#: selection:mrp.subproduct,subproduct_type:0
msgid "Variable"
-msgstr "可变"
+msgstr "可变的"
#. module: mrp_subproduct
#: field:mrp.bom,sub_products:0
diff --git a/addons/product/i18n/ar.po b/addons/product/i18n/ar.po
index 97522de2c4c..b28ef3ea37b 100644
--- a/addons/product/i18n/ar.po
+++ b/addons/product/i18n/ar.po
@@ -7,24 +7,24 @@ 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-12-20 15:50+0000\n"
-"Last-Translator: Hend Awad \n"
+"PO-Revision-Date: 2009-12-21 11:00+0000\n"
+"Last-Translator: hamada_away \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: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: product
#: view:product.pricelist.item:0
msgid "Max. Margin"
-msgstr ""
+msgstr "كحد أقصى. الهامش"
#. module: product
#: view:product.pricelist.item:0
msgid "Base Price"
-msgstr ""
+msgstr "قاعده الاسعار"
#. module: product
#: help:product.template,standard_price:0
@@ -36,7 +36,7 @@ msgstr ""
#. module: product
#: selection:product.template,type:0
msgid "Service"
-msgstr ""
+msgstr "الخدمة"
#. module: product
#: help:product.template,purchase_ok:0
@@ -48,7 +48,7 @@ msgstr ""
#. module: product
#: help:product.supplierinfo,name:0
msgid "Supplier of this product"
-msgstr ""
+msgstr "المورد لهذا المنتج"
#. module: product
#: model:product.template,name:product.product_product_ram512_product_template
@@ -70,7 +70,7 @@ msgstr ""
#. module: product
#: field:product.template,weight_net:0
msgid "Net weight"
-msgstr ""
+msgstr "الوزن الصافي"
#. module: product
#: help:product.product,incoming_qty:0
@@ -164,12 +164,12 @@ msgstr "الشركة"
#. module: product
#: field:product.template,rental:0
msgid "Rentable Product"
-msgstr ""
+msgstr "المنتج للإيجار"
#. module: product
#: field:product.product,lst_price:0
msgid "List Price"
-msgstr ""
+msgstr "قائمة الأسعار"
#. module: product
#: model:ir.actions.act_window,name:product.product_price_type_action
diff --git a/addons/purchase/i18n/zh_CN.po b/addons/purchase/i18n/zh_CN.po
index d224e34c91c..69c9c5d743f 100644
--- a/addons/purchase/i18n/zh_CN.po
+++ b/addons/purchase/i18n/zh_CN.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-12-21 04:01+0000\n"
+"PO-Revision-Date: 2009-12-21 06:56+0000\n"
"Last-Translator: Jeroen Vet \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: 2009-12-21 04:43+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: purchase
@@ -559,17 +559,17 @@ msgstr "该文件已创建日期"
#. module: purchase
#: view:purchase.order:0
msgid "Delivery & Invoices"
-msgstr "运输与发票"
+msgstr "递送与发票"
#. module: purchase
#: field:purchase.order,date_order:0
msgid "Date"
-msgstr "时间"
+msgstr "日期"
#. module: purchase
#: help:purchase.order,origin:0
msgid "Reference of the document that generated this purchase order request."
-msgstr ""
+msgstr "生成该采购报价请求的单据编号"
#. module: purchase
#: rml:purchase.order:0
@@ -579,7 +579,7 @@ msgstr "电话:"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_purchaseinvoice0
msgid "After Purchase order , Create invoice."
-msgstr ""
+msgstr "在采购订单后创建发票"
#. module: purchase
#: field:purchase.order.line,date_planned:0
@@ -589,7 +589,7 @@ msgstr "计划日期"
#. module: purchase
#: rml:purchase.order:0
msgid "Our Order Reference"
-msgstr ""
+msgstr "我方的采购订单编号"
#. module: purchase
#: rml:purchase.quotation:0
@@ -604,7 +604,7 @@ msgstr "计算"
#. module: purchase
#: constraint:product.pricelist.version:0
msgid "You cannot have 2 pricelist versions that overlap!"
-msgstr "您不能同时具有两个重叠的价格表版本。"
+msgstr "你不能有两个重复的价格表版本!"
#. module: purchase
#: view:purchase.order:0
@@ -614,7 +614,7 @@ msgstr "取消采购订单"
#. module: purchase
#: model:process.transition,name:purchase.process_transition_createpackinglist0
msgid "Create Packing list"
-msgstr ""
+msgstr "创建分拣单"
#. module: purchase
#: rml:purchase.order:0
@@ -624,17 +624,17 @@ msgstr "总计:"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_createpackinglist0
msgid "When purchase order is approved , it creates its packing list."
-msgstr "当采购订单批准以后将创建装箱单。"
+msgstr "当采购订单批准以后将创建分拣单。"
#. module: purchase
#: view:purchase.order.line:0
msgid "History"
-msgstr "历史记录"
+msgstr "历史"
#. module: purchase
#: field:purchase.order,state:0
msgid "Order Status"
-msgstr "订单状态"
+msgstr "采购订单状态"
#. module: purchase
#: field:purchase.order.line,price_subtotal:0
@@ -660,7 +660,7 @@ msgstr "财务状况"
#. module: purchase
#: rml:purchase.order:0
msgid "Request for Quotation N°"
-msgstr ""
+msgstr "报价请求编号:"
#. module: purchase
#: field:purchase.order,invoice_id:0
@@ -682,7 +682,7 @@ msgstr "采购属性"
#. module: purchase
#: field:purchase.order.line,order_id:0
msgid "Order Ref"
-msgstr "订单参照"
+msgstr "采购订单编号"
#. module: purchase
#: model:ir.actions.act_window,name:purchase.purchase_form_action
@@ -694,7 +694,7 @@ msgstr "采购订单"
#: wizard_view:purchase.order.merge,init:0
#: wizard_button:purchase.order.merge,init,merge:0
msgid "Merge orders"
-msgstr "合并订单"
+msgstr "合并采购订单"
#. module: purchase
#: constraint:ir.model:0
@@ -712,28 +712,28 @@ msgstr "新建采购订单"
#: field:purchase.order,shipped:0
#: field:purchase.order,shipped_rate:0
msgid "Received"
-msgstr "已接收"
+msgstr "已收货"
#. module: purchase
#: model:ir.actions.report.xml,name:purchase.report_purchase_quotation
#: selection:purchase.order,state:0
msgid "Request for Quotation"
-msgstr "询价"
+msgstr "报价请求"
#. module: purchase
#: model:process.node,name:purchase.process_node_packinginvoice0
msgid "Out Packing"
-msgstr "发出包装"
+msgstr "发货分拣单"
#. module: purchase
#: model:process.node,note:purchase.process_node_productrecept0
msgid "Control invoices on receptions"
-msgstr "接收时控制发票"
+msgstr "接收时核对发票"
#. module: purchase
#: rml:purchase.order:0
msgid "Date Req."
-msgstr ""
+msgstr "要求日期"
#. module: purchase
#: field:purchase.order,date_approve:0
@@ -746,8 +746,8 @@ msgid ""
"Module for purchase management\n"
" Request for quotation, Create Supplier Invoice, Print Order..."
msgstr ""
-"采购模块管理:\n"
-" 询价请求、创建供应商发票和打印订单等等"
+"采购管理模块\\n\n"
+" 报价请求,创建供应商发票,打印采购订单。。"
#. module: purchase
#: field:purchase.order.line,product_id:0
@@ -764,7 +764,7 @@ msgstr "说明"
#. module: purchase
#: model:process.transition,name:purchase.process_transition_productrecept0
msgid "Product recept invoice"
-msgstr ""
+msgstr "货品接收的发票"
#. module: purchase
#: rml:purchase.quotation:0
@@ -805,12 +805,12 @@ msgstr "采购发票"
#. module: purchase
#: rml:purchase.order:0
msgid "Your Order Reference"
-msgstr ""
+msgstr "您的订单编号"
#. module: purchase
#: rml:purchase.order:0
msgid "Purchase Order Confirmation N°"
-msgstr ""
+msgstr "采购订单确认编号"
#. module: purchase
#: view:purchase.order:0
@@ -825,13 +825,13 @@ msgstr "订货日期"
#. module: purchase
#: view:purchase.order:0
msgid "Purchase Control"
-msgstr "采购控制"
+msgstr "采购管理"
#. module: purchase
#: model:ir.actions.act_window,name:purchase.purchase_form_action2
#: model:ir.ui.menu,name:purchase.menu_purchase_order_draft
msgid "Request For Quotations"
-msgstr ""
+msgstr "报价请求"
#. module: purchase
#: field:purchase.order,invoice_method:0
@@ -841,17 +841,17 @@ msgstr "开票方式"
#. module: purchase
#: model:process.transition.action,name:purchase.process_transition_action_approvingpurchaseorder0
msgid "Approve"
-msgstr "核准"
+msgstr "批准"
#. module: purchase
#: model:process.node,name:purchase.process_node_approvepurchaseorder0
msgid "Approved Purchase"
-msgstr "以批准的采购"
+msgstr "已批准采购"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_packinginvoice0
msgid "From Packing list, Create invoice."
-msgstr "从装箱单创建发票"
+msgstr "从分拣单创建发票"
#. module: purchase
#: field:purchase.order,amount_total:0
@@ -861,7 +861,7 @@ msgstr "总计"
#. module: purchase
#: wizard_view:purchase.order.merge,init:0
msgid "Are you sure you want to merge these orders ?"
-msgstr "你确定要合并此订单马?"
+msgstr "你确定要合并此订单吗?"
#. module: purchase
#: model:process.transition,name:purchase.process_transition_approvingpurchaseorder0
@@ -871,7 +871,7 @@ msgstr "正在批准采购订单"
#. module: purchase
#: model:process.transition,note:purchase.process_transition_invoicefrompurchase0
msgid "After approved purchase order , it comes into the supplier invoice"
-msgstr "当采购订单批准以后将进入供应商发票"
+msgstr "采购订单审批通过后创建供应商发票"
#. module: purchase
#: view:purchase.order.line:0
diff --git a/addons/report_crm/i18n/zh_CN.po b/addons/report_crm/i18n/zh_CN.po
index a905f0b7737..4a6bc9248b2 100644
--- a/addons/report_crm/i18n/zh_CN.po
+++ b/addons/report_crm/i18n/zh_CN.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-01-30 13:24+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-21 12:46+0000\n"
+"Last-Translator: Silence \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: 2009-12-16 05:09+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_crm
#: field:report.crm.case.categ,categ_id:0
msgid "Category"
-msgstr ""
+msgstr "分类"
#. module: report_crm
#: field:report.crm.case.categ,probability:0
@@ -30,12 +30,12 @@ msgstr ""
#. module: report_crm
#: field:report.crm.case.service.dashboard,planned_revenue:0
msgid "Planned Revenue"
-msgstr ""
+msgstr "计划收入"
#. module: report_crm
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "在行动定义中的模式名称无效"
#. module: report_crm
#: model:ir.model,name:report_crm.model_report_crm_case_categ
@@ -47,28 +47,28 @@ msgstr ""
#: field:report.crm.case.section,section_id:0
#: field:report.crm.case.user,section_id:0
msgid "Section"
-msgstr ""
+msgstr "案例分部"
#. module: report_crm
#: field:report.crm.case.service.dashboard,user_id:0
msgid "Responsible"
-msgstr ""
+msgstr "负责人"
#. module: report_crm
#: field:report.crm.case.section,perc_done:0
msgid "%Done"
-msgstr ""
+msgstr "%完成"
#. module: report_crm
#: field:report.crm.case.service.dashboard,planned_cost:0
msgid "Planned Costs"
-msgstr ""
+msgstr "计划成本"
#. module: report_crm
#: field:report.crm.case.section,nbr_cases:0
#: field:report.crm.case.user,nbr:0
msgid "# of Cases"
-msgstr ""
+msgstr "# 案例"
#. module: report_crm
#: model:ir.module.module,shortdesc:report_crm.module_meta_information
@@ -92,14 +92,14 @@ msgstr ""
#: selection:report.crm.case.service.dashboard,state:0
#: selection:report.crm.case.user,state:0
msgid "Draft"
-msgstr ""
+msgstr "草稿"
#. module: report_crm
#: selection:report.crm.case.categ,state:0
#: selection:report.crm.case.service.dashboard,state:0
#: selection:report.crm.case.user,state:0
msgid "Closed"
-msgstr ""
+msgstr "已关闭"
#. module: report_crm
#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_categ_tree_month
@@ -116,7 +116,7 @@ msgstr "所有月份"
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
-msgstr ""
+msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
#. module: report_crm
#: field:report.crm.case.categ,amount_revenue_prob:0
@@ -129,7 +129,7 @@ msgstr ""
#: selection:report.crm.case.service.dashboard,state:0
#: selection:report.crm.case.user,state:0
msgid "Pending"
-msgstr ""
+msgstr "未决定的"
#. module: report_crm
#: field:report.crm.case.section,avg_answers:0
@@ -141,12 +141,12 @@ msgstr ""
#: field:report.crm.case.service.dashboard,state:0
#: field:report.crm.case.user,state:0
msgid "Status"
-msgstr ""
+msgstr "状态"
#. module: report_crm
#: field:report.crm.case.service.dashboard,name:0
msgid "Description"
-msgstr ""
+msgstr "说明"
#. module: report_crm
#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_user_tree_month
@@ -167,7 +167,7 @@ msgstr "报表"
#. module: report_crm
#: view:report.crm.case.service.dashboard:0
msgid "Planned costs"
-msgstr ""
+msgstr "计划费用"
#. module: report_crm
#: model:ir.actions.act_window,name:report_crm.action_view_closed_crm_case_dashboard
@@ -183,7 +183,7 @@ msgstr ""
#. module: report_crm
#: field:report.crm.case.user,user_id:0
msgid "User"
-msgstr ""
+msgstr "用户"
#. module: report_crm
#: model:ir.actions.act_window,name:report_crm.act_crm_case_section_2_report_crm_case_categ
@@ -193,7 +193,7 @@ msgstr ""
#. module: report_crm
#: field:report.crm.case.service.dashboard,date:0
msgid "Date"
-msgstr ""
+msgstr "日期"
#. module: report_crm
#: model:ir.actions.act_window,name:report_crm.action_report_crm_case_user_tree_month_my
@@ -214,7 +214,7 @@ msgstr ""
#. module: report_crm
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "无效XML视图结构!"
#. module: report_crm
#: model:ir.model,name:report_crm.model_report_crm_case_service_dashboard
@@ -227,13 +227,13 @@ msgstr ""
#: view:report.crm.case.categ:0
#: view:report.crm.case.user:0
msgid "Cases by User and Section"
-msgstr ""
+msgstr "用户和部门项目"
#. module: report_crm
#: model:ir.actions.act_window,name:report_crm.act_crm_case_categ_2_report_crm_case_categ
#: model:ir.actions.act_window,name:report_crm.act_res_users_2_report_crm_case_user
msgid "Monthly cases"
-msgstr ""
+msgstr "每月项目"
#. module: report_crm
#: field:report.crm.case.categ,amount_revenue:0
@@ -249,12 +249,12 @@ msgstr ""
#. module: report_crm
#: field:report.crm.case.service.dashboard,priority:0
msgid "Priority"
-msgstr ""
+msgstr "优先级"
#. module: report_crm
#: field:report.crm.case.section,perc_cancel:0
msgid "%Cancel"
-msgstr ""
+msgstr "%取消"
#. module: report_crm
#: field:report.crm.case.section,delay_close:0
@@ -284,24 +284,24 @@ msgstr ""
#: field:report.crm.case.section,name:0
#: field:report.crm.case.user,name:0
msgid "Month"
-msgstr ""
+msgstr "月"
#. module: report_crm
#: selection:report.crm.case.categ,state:0
#: selection:report.crm.case.service.dashboard,state:0
#: selection:report.crm.case.user,state:0
msgid "Canceled"
-msgstr ""
+msgstr "已取消"
#. module: report_crm
#: field:report.crm.case.service.dashboard,create_date:0
msgid "Create Date"
-msgstr ""
+msgstr "创建时间"
#. module: report_crm
#: field:report.crm.case.service.dashboard,date_deadline:0
msgid "Deadline"
-msgstr ""
+msgstr "截止日期"
#. module: report_crm
#: model:ir.model,name:report_crm.model_report_crm_case_user
@@ -311,7 +311,7 @@ msgstr ""
#. module: report_crm
#: field:report.crm.case.service.dashboard,partner_id:0
msgid "Partner"
-msgstr ""
+msgstr "业务伙伴"
#. module: report_crm
#: model:ir.module.module,description:report_crm.module_meta_information
@@ -325,9 +325,9 @@ msgstr ""
#: selection:report.crm.case.service.dashboard,state:0
#: selection:report.crm.case.user,state:0
msgid "Open"
-msgstr ""
+msgstr "打开"
#. module: report_crm
#: view:report.crm.case.service.dashboard:0
msgid "Planned revenue"
-msgstr ""
+msgstr "计划收入"
diff --git a/addons/report_intrastat/i18n/zh_CN.po b/addons/report_intrastat/i18n/zh_CN.po
index 430c83b74a8..6f42dc91e68 100644
--- a/addons/report_intrastat/i18n/zh_CN.po
+++ b/addons/report_intrastat/i18n/zh_CN.po
@@ -7,56 +7,56 @@ 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-01-30 13:29+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-21 12:25+0000\n"
+"Last-Translator: Silence \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: 2009-12-16 05:14+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_intrastat
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
-msgstr ""
+msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Canceled Invoice"
-msgstr ""
+msgstr "已取消发票"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Disc. (%)"
-msgstr ""
+msgstr "折扣(%)"
#. module: report_intrastat
#: model:ir.actions.act_window,name:report_intrastat.action_report_intrastat_tree
#: model:ir.ui.menu,name:report_intrastat.menu_report_intrastat
msgid "Intrastat (this month)"
-msgstr ""
+msgstr "内部统计(本月)"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Supplier Invoice"
-msgstr ""
+msgstr "供应商发票"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Unit Price"
-msgstr ""
+msgstr "单价"
#. module: report_intrastat
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "在行动定义中的模式名称无效"
#. module: report_intrastat
#: field:report.intrastat,name:0
msgid "Period"
-msgstr ""
+msgstr "时段"
#. module: report_intrastat
#: model:ir.ui.menu,name:report_intrastat.next_id_90
@@ -66,17 +66,17 @@ msgstr "所有月份"
#. module: report_intrastat
#: selection:report.intrastat,type:0
msgid "Import"
-msgstr ""
+msgstr "导入"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "VAT :"
-msgstr ""
+msgstr "增值税:"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Document"
-msgstr ""
+msgstr "文件"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
@@ -86,18 +86,18 @@ msgstr ""
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Taxes:"
-msgstr ""
+msgstr "税:"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
#: field:report.intrastat.code,description:0
msgid "Description"
-msgstr ""
+msgstr "说明"
#. module: report_intrastat
#: field:report.intrastat,type:0
msgid "Type"
-msgstr ""
+msgstr "类型"
#. module: report_intrastat
#: model:ir.actions.report.xml,name:report_intrastat.invoice_intrastat_id
@@ -107,17 +107,17 @@ msgstr ""
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Invoice Date"
-msgstr ""
+msgstr "发票日期"
#. module: report_intrastat
#: model:ir.module.module,shortdesc:report_intrastat.module_meta_information
msgid "Intrastat Reporting - Reporting"
-msgstr ""
+msgstr "内部统计报告-报告"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Tel. :"
-msgstr ""
+msgstr "电话:"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
@@ -127,7 +127,7 @@ msgstr ""
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Quantity"
-msgstr ""
+msgstr "数量"
#. module: report_intrastat
#: model:ir.ui.menu,name:report_intrastat.next_id_89
@@ -137,7 +137,7 @@ msgstr "本月"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Partner Ref."
-msgstr ""
+msgstr "业务伙伴参照"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
@@ -147,32 +147,32 @@ msgstr ""
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Refund"
-msgstr ""
+msgstr "退款"
#. module: report_intrastat
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "无效XML视图结构!"
#. module: report_intrastat
#: model:ir.model,name:report_intrastat.model_report_intrastat
msgid "Intrastat report"
-msgstr ""
+msgstr "内部统计报告"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Invoice"
-msgstr ""
+msgstr "发票"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Taxes"
-msgstr ""
+msgstr "税款"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Amount"
-msgstr ""
+msgstr "总计"
#. module: report_intrastat
#: view:report.intrastat:0
@@ -182,19 +182,19 @@ msgstr ""
#. module: report_intrastat
#: field:report.intrastat,value:0
msgid "Value"
-msgstr ""
+msgstr "数值"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
#: model:ir.actions.act_window,name:report_intrastat.action_report_intrastat_tree_all
#: model:ir.ui.menu,name:report_intrastat.menu_report_intrastat_all
msgid "Intrastat"
-msgstr ""
+msgstr "内部统计"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Draft Invoice"
-msgstr ""
+msgstr "发票草稿"
#. module: report_intrastat
#: field:report.intrastat,supply_units:0
@@ -212,13 +212,13 @@ msgstr ""
#. module: report_intrastat
#: field:report.intrastat,ref:0
msgid "Origin"
-msgstr ""
+msgstr "来源"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
#: field:report.intrastat,weight:0
msgid "Weight"
-msgstr ""
+msgstr "重量"
#. module: report_intrastat
#: field:res.country,intrastat:0
@@ -228,32 +228,32 @@ msgstr ""
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Tax"
-msgstr ""
+msgstr "税目"
#. module: report_intrastat
#: field:report.intrastat,code:0
msgid "Country code"
-msgstr ""
+msgstr "国家代码"
#. module: report_intrastat
#: field:report.intrastat,currency_id:0
msgid "Currency"
-msgstr ""
+msgstr "货币"
#. module: report_intrastat
#: selection:report.intrastat,type:0
msgid "Export"
-msgstr ""
+msgstr "导出"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Fax :"
-msgstr ""
+msgstr "传真:"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Supplier Refund"
-msgstr ""
+msgstr "供应商退款"
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
@@ -263,7 +263,7 @@ msgstr ""
#. module: report_intrastat
#: rml:account.invoice.intrastat:0
msgid "Price"
-msgstr ""
+msgstr "价格"
#. module: report_intrastat
#: model:ir.actions.act_window,name:report_intrastat.action_report_intrastat_code_tree
diff --git a/addons/report_mrp/i18n/zh_CN.po b/addons/report_mrp/i18n/zh_CN.po
index 101c1e50e13..71996bc95b9 100644
--- a/addons/report_mrp/i18n/zh_CN.po
+++ b/addons/report_mrp/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-08-28 16:01+0000\n"
-"PO-Revision-Date: 2009-01-30 13:24+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
+"PO-Revision-Date: 2009-12-21 12:50+0000\n"
+"Last-Translator: Silence \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: 2009-12-16 05:22+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: report_mrp
@@ -25,7 +25,7 @@ msgstr "周"
#. module: report_mrp
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
-msgstr ""
+msgstr "无效XML视图结构!"
#. module: report_mrp
#: model:ir.ui.menu,name:report_mrp.next_id_77
@@ -36,7 +36,7 @@ msgstr "报表"
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
-msgstr ""
+msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
#. module: report_mrp
#: view:report.workcenter.load:0
@@ -61,7 +61,7 @@ msgstr "库存数量"
#. module: report_mrp
#: field:report.workcenter.load,cycle:0
msgid "Nbr of cycle"
-msgstr "周期数"
+msgstr "循环数"
#. module: report_mrp
#: field:report.workcenter.load,hour:0
@@ -88,13 +88,13 @@ msgstr "周库存变动表"
#. module: report_mrp
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "在行动定义中的模式名称无效"
#. module: report_mrp
#: model:ir.model,name:report_mrp.model_report_mrp_inout
#: view:report.mrp.inout:0
msgid "Stock value variation"
-msgstr ""
+msgstr "存货价值变更"
#. module: report_mrp
#: view:report.workcenter.load:0
diff --git a/addons/sale/i18n/ar.po b/addons/sale/i18n/ar.po
index 0cb6025c91a..5111e13f0eb 100644
--- a/addons/sale/i18n/ar.po
+++ b/addons/sale/i18n/ar.po
@@ -7,34 +7,34 @@ 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:26+0000\n"
-"Last-Translator: <>\n"
+"PO-Revision-Date: 2009-12-21 12:54+0000\n"
+"Last-Translator: hamada_away \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: 2009-12-16 05:14+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:35+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: sale
#: selection:sale.order,picking_policy:0
msgid "Partial Delivery"
-msgstr ""
+msgstr "التسليم الجزئي"
#. module: sale
#: view:sale.order:0
msgid "Recreate Procurement"
-msgstr ""
+msgstr "إعادة الشراء"
#. module: sale
#: model:process.transition,name:sale.process_transition_confirmquotation0
msgid "Confirm Quotation"
-msgstr ""
+msgstr "تأكيد تسعيرة"
#. module: sale
#: model:process.node,name:sale.process_node_deliveryorder0
msgid "Delivery Order"
-msgstr ""
+msgstr "أجل التسليم"
#. module: sale
#: field:sale.order.line,address_allotment_id:0
@@ -44,7 +44,7 @@ msgstr ""
#. module: sale
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
-msgstr ""
+msgstr "اسم النموذج غير صالح في تعريف العمل."
#. module: sale
#: selection:sale.order,state:0
@@ -61,18 +61,18 @@ msgstr ""
#. module: sale
#: selection:sale.order.line,type:0
msgid "from stock"
-msgstr ""
+msgstr "من المخزن"
#. module: sale
#: field:sale.config.picking_policy,step:0
msgid "Steps To Deliver a Sale Order"
-msgstr ""
+msgstr "خطوات لتقديم طلب للبيع"
#. module: sale
#: wizard_field:sale.advance_payment_inv,init,qtty:0
#: rml:sale.order:0
msgid "Quantity"
-msgstr ""
+msgstr "الكمية"
#. module: sale
#: wizard_view:sale.advance_payment_inv,create:0
@@ -83,7 +83,7 @@ msgstr ""
#: view:sale.order:0
#: view:sale.order.line:0
msgid "Automatic Declaration"
-msgstr ""
+msgstr "اعلان تلقائى"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_line_tree3
@@ -99,7 +99,7 @@ msgstr ""
#. module: sale
#: selection:sale.order,state:0
msgid "Invoice Exception"
-msgstr ""
+msgstr "فاتورة استثناء"
#. module: sale
#: help:sale.order,picking_ids:0
@@ -120,17 +120,17 @@ msgstr ""
#. module: sale
#: model:process.transition.action,name:sale.process_transition_action_validate0
msgid "Validate"
-msgstr ""
+msgstr "تحقق"
#. module: sale
#: view:sale.order:0
msgid "Make Invoice"
-msgstr ""
+msgstr "عمل فاتوره"
#. module: sale
#: field:sale.order.line,price_subtotal:0
msgid "Subtotal"
-msgstr ""
+msgstr "المجموع"
#. module: sale
#: model:process.transition,note:sale.process_transition_confirmquotation0
@@ -143,12 +143,12 @@ msgstr ""
#: model:process.transition.action,name:sale.process_transition_action_cancelorder0
#: view:sale.order:0
msgid "Cancel Order"
-msgstr ""
+msgstr "الغاء اﻻمر"
#. module: sale
#: field:sale.order.line,move_ids:0
msgid "Inventory Moves"
-msgstr ""
+msgstr "نقل المخزون"
#. module: sale
#: view:sale.order.line:0
@@ -161,23 +161,23 @@ msgstr ""
#: view:sale.order.line:0
#: field:sale.order.line,notes:0
msgid "Notes"
-msgstr ""
+msgstr "ملاحظات"
#. module: sale
#: model:process.transition,name:sale.process_transition_invoiceafterdelivery0
msgid "Invoice after delivery"
-msgstr ""
+msgstr "الفاتورة بعد التسليم"
#. module: sale
#: field:sale.order,amount_tax:0
#: field:sale.order.line,tax_id:0
msgid "Taxes"
-msgstr ""
+msgstr "الضرائب"
#. module: sale
#: rml:sale.order:0
msgid "Net Total :"
-msgstr ""
+msgstr "المجموع الصافي"
#. module: sale
#: field:sale.order,order_policy:0
@@ -188,7 +188,7 @@ msgstr ""
#: selection:sale.order,state:0
#: selection:sale.order.line,state:0
msgid "Cancelled"
-msgstr ""
+msgstr "الغاء"
#. module: sale
#: selection:sale.order,state:0
@@ -198,12 +198,12 @@ msgstr ""
#. module: sale
#: field:sale.order,amount_total:0
msgid "Total"
-msgstr ""
+msgstr "المجموع"
#. module: sale
#: field:sale.order,origin:0
msgid "Origin"
-msgstr ""
+msgstr "الأصل"
#. module: sale
#: field:sale.order,partner_invoice_id:0
@@ -218,7 +218,7 @@ msgstr ""
#. module: sale
#: view:sale.order:0
msgid "Reference"
-msgstr ""
+msgstr "المرجع"
#. module: sale
#: selection:sale.config.picking_policy,picking_policy:0
@@ -244,22 +244,22 @@ msgstr ""
#. module: sale
#: field:sale.order.line,type:0
msgid "Procure Method"
-msgstr ""
+msgstr "أسلوب الشراء"
#. module: sale
#: view:sale.order:0
msgid "Extra Info"
-msgstr ""
+msgstr "معلومات إضافية"
#. module: sale
#: rml:sale.order:0
msgid "Fax :"
-msgstr ""
+msgstr "الفاكس"
#. module: sale
#: field:sale.order.line,price_net:0
msgid "Net Price"
-msgstr ""
+msgstr "السعر الصافي"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_tree9
@@ -284,7 +284,7 @@ msgstr ""
#. module: sale
#: selection:sale.order.line,state:0
msgid "Confirmed"
-msgstr ""
+msgstr "مؤكد"
#. module: sale
#: field:sale.shop,payment_default_id:0
@@ -300,7 +300,7 @@ msgstr ""
#. module: sale
#: model:process.transition.action,name:sale.process_transition_action_confirm0
msgid "Confirm"
-msgstr ""
+msgstr "تأكيد"
#. module: sale
#: field:sale.order,partner_shipping_id:0
diff --git a/addons/sale/i18n/zh_CN.po b/addons/sale/i18n/zh_CN.po
index c29241e4951..8d3532a5081 100644
--- a/addons/sale/i18n/zh_CN.po
+++ b/addons/sale/i18n/zh_CN.po
@@ -7,39 +7,39 @@ 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-12-03 13:25+0000\n"
-"Last-Translator: Wei \"oldrev\" Li \n"
+"PO-Revision-Date: 2009-12-21 09:19+0000\n"
+"Last-Translator: Jeroen Vet \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: 2009-12-16 05:14+0000\n"
+"X-Launchpad-Export-Date: 2009-12-22 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: sale
#: selection:sale.order,picking_policy:0
msgid "Partial Delivery"
-msgstr ""
+msgstr "分批出货"
#. module: sale
#: view:sale.order:0
msgid "Recreate Procurement"
-msgstr "重建需求分析"
+msgstr "重建需求单"
#. module: sale
#: model:process.transition,name:sale.process_transition_confirmquotation0
msgid "Confirm Quotation"
-msgstr "确认报价"
+msgstr "确认报价单"
#. module: sale
#: model:process.node,name:sale.process_node_deliveryorder0
msgid "Delivery Order"
-msgstr "交货单"
+msgstr "送货单"
#. module: sale
#: field:sale.order.line,address_allotment_id:0
msgid "Allotment Partner"
-msgstr ""
+msgstr "分配业务伙伴"
#. module: sale
#: constraint:ir.actions.act_window:0
@@ -49,24 +49,24 @@ msgstr "操作定义中使用了无效的模式名称。"
#. module: sale
#: selection:sale.order,state:0
msgid "Waiting Schedule"
-msgstr "等待安排"
+msgstr "等待日程"
#. module: sale
#: help:sale.order,picking_policy:0
msgid ""
"If you don't have enough stock available to deliver all at once, do you "
"accept partial shipments or not?"
-msgstr ""
+msgstr "如果您没有足够的库存可以一次运输所有货物,您是否可以接受分批出货?"
#. module: sale
#: selection:sale.order.line,type:0
msgid "from stock"
-msgstr "来自库存"
+msgstr "备货"
#. module: sale
#: field:sale.config.picking_policy,step:0
msgid "Steps To Deliver a Sale Order"
-msgstr ""
+msgstr "完成销售订单的步骤"
#. module: sale
#: wizard_field:sale.advance_payment_inv,init,qtty:0
@@ -83,13 +83,13 @@ msgstr "您的发票已成功创建!"
#: view:sale.order:0
#: view:sale.order.line:0
msgid "Automatic Declaration"
-msgstr "一般说明"
+msgstr "自动申报"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_line_tree3
#: model:ir.ui.menu,name:sale.menu_action_order_line_tree3
msgid "Uninvoiced and Delivered Lines"
-msgstr "未开票运货明细"
+msgstr "未开票及交货明细"
#. module: sale
#: view:sale.order:0
@@ -105,12 +105,12 @@ msgstr "发票例外项"
#: help:sale.order,picking_ids:0
msgid ""
"This is the list of picking list that have been generated for this invoice"
-msgstr ""
+msgstr "此是该发票生成的运货清单."
#. module: sale
#: model:process.node,note:sale.process_node_deliveryorder0
msgid "Delivery, from the warehouse to the customer."
-msgstr "发货,从仓库到客户。"
+msgstr "送货,从仓库到客户"
#. module: sale
#: model:ir.model,name:sale.model_sale_config_picking_policy
@@ -125,7 +125,7 @@ msgstr "审核"
#. module: sale
#: view:sale.order:0
msgid "Make Invoice"
-msgstr "生成发票"
+msgstr "制作发票"
#. module: sale
#: field:sale.order.line,price_subtotal:0
@@ -137,7 +137,7 @@ msgstr "小计"
msgid ""
"Whenever confirm button is clicked, the draft state is moved to manual. that "
"is, quotation is moved to sale order."
-msgstr ""
+msgstr "当点击确认按钮草稿状态将转到手动.报价单转到销售订单."
#. module: sale
#: model:process.transition.action,name:sale.process_transition_action_cancelorder0
@@ -148,12 +148,12 @@ msgstr "取消订单"
#. module: sale
#: field:sale.order.line,move_ids:0
msgid "Inventory Moves"
-msgstr "库存变动"
+msgstr "库存调拨"
#. module: sale
#: view:sale.order.line:0
msgid "Manual Designation"
-msgstr "手工指定"
+msgstr "手动指定"
#. module: sale
#: view:sale.order:0
@@ -166,13 +166,13 @@ msgstr "注解"
#. module: sale
#: model:process.transition,name:sale.process_transition_invoiceafterdelivery0
msgid "Invoice after delivery"
-msgstr ""
+msgstr "送货后开发票"
#. module: sale
#: field:sale.order,amount_tax:0
#: field:sale.order.line,tax_id:0
msgid "Taxes"
-msgstr "?"
+msgstr "税款"
#. module: sale
#: rml:sale.order:0
@@ -228,7 +228,7 @@ msgstr ""
#. module: sale
#: model:process.transition,note:sale.process_transition_saleprocurement0
msgid "Procurement is created after confirmation of sale order."
-msgstr ""
+msgstr "所有一起"
#. module: sale
#: field:sale.order,project_id:0
@@ -244,7 +244,7 @@ msgstr "增值税:"
#. module: sale
#: field:sale.order.line,type:0
msgid "Procure Method"
-msgstr "采购方法"
+msgstr "获得方式"
#. module: sale
#: view:sale.order:0
@@ -270,7 +270,7 @@ msgstr "我的处理中订单"
#. module: sale
#: field:sale.order.line,product_uos_qty:0
msgid "Quantity (UoS)"
-msgstr ""
+msgstr "数量(销售单位)"
#. module: sale
#: help:sale.order,invoice_quantity:0
@@ -280,6 +280,8 @@ msgid ""
"choose if you invoice based on ordered or shipped quantities. If the product "
"is a service, shipped quantities means hours spent on the associated tasks."
msgstr ""
+"\"销售订单将自动创建发票提议(发票草稿).订单和送货数量可能不一致.你必须选择发票基按已订购数量或送货数量。如果该产品是一种服务,发货量是相关的任务所花"
+"费的小时数。"
#. module: sale
#: selection:sale.order.line,state:0
@@ -315,13 +317,13 @@ msgstr "已运数量"
#. module: sale
#: selection:sale.config.picking_policy,order_policy:0
msgid "Invoice Based on Sales Orders"
-msgstr ""
+msgstr "发票基于销售订单"
#. module: sale
#: model:ir.model,name:sale.model_sale_shop
#: view:sale.shop:0
msgid "Sale Shop"
-msgstr "销售点"
+msgstr "销售商店"
#. module: sale
#: field:sale.shop,warehouse_id:0
@@ -331,7 +333,7 @@ msgstr "仓库"
#. module: sale
#: rml:sale.order:0
msgid "Order N°"
-msgstr "单号"
+msgstr "订单号"
#. module: sale
#: field:sale.order,order_line:0
@@ -354,7 +356,7 @@ msgstr "发票明细"
#. module: sale
#: model:process.transition.action,name:sale.process_transition_action_forceassignation0
msgid "Force Assignation"
-msgstr "强制指定"
+msgstr "强制分配"
#. module: sale
#: view:sale.order:0
@@ -366,7 +368,7 @@ msgstr "未完税金额"
msgid ""
"Packing list is created when 'Assign' is being clicked after confirming the "
"sale order. This transaction moves the sale order to packing list."
-msgstr ""
+msgstr "确认销售订单后点击‘分配’时创建发货分拣清单.销售订单转到发货分拣单"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_tree8
@@ -384,17 +386,17 @@ msgstr "货运地址:"
msgid ""
"When you select Shipping Ploicy = 'Automatic Invoice after delivery' , it "
"will automatic create after delivery."
-msgstr ""
+msgstr "当你选择交货方式=‘送货后自动产生发票’.送货后将自动创建发票."
#. module: sale
#: selection:sale.order,picking_policy:0
msgid "Complete Delivery"
-msgstr ""
+msgstr "一次性出货"
#. module: sale
#: view:sale.order:0
msgid "Manual Description"
-msgstr "详细说明"
+msgstr "手动添加描述"
#. module: sale
#: field:sale.order.line,product_uom_qty:0
@@ -406,7 +408,7 @@ msgstr "数量(计量单位)"
#: model:ir.ui.menu,name:sale.menu_action_order_line_tree1
#: view:sale.order.line:0
msgid "Sales Order Lines"
-msgstr "销售单细目"
+msgstr "销售订单明细"
#. module: sale
#: selection:sale.order,invoice_quantity:0
@@ -416,12 +418,12 @@ msgstr "已订数量"
#. module: sale
#: model:process.node,name:sale.process_node_saleorderprocurement0
msgid "Sale Order Procurement"
-msgstr ""
+msgstr "销售订单需求单"
#. module: sale
#: model:process.transition,name:sale.process_transition_packing0
msgid "Packing"
-msgstr "挑选"
+msgstr "分拣单"
#. module: sale
#: rml:sale.order:0
@@ -436,7 +438,7 @@ msgstr "审核订单"
#. module: sale
#: field:sale.order,name:0
msgid "Order Reference"
-msgstr ""
+msgstr "订单编号"
#. module: sale
#: selection:sale.order,state:0
@@ -459,7 +461,7 @@ msgstr "设置"
#. module: sale
#: selection:sale.order,order_policy:0
msgid "Invoice on Order After Delivery"
-msgstr ""
+msgstr "送货后按订单开发票"
#. module: sale
#: constraint:ir.ui.view:0
@@ -469,12 +471,12 @@ msgstr "无效的 XML 视图结构"
#. module: sale
#: field:sale.order,picking_ids:0
msgid "Related Packing"
-msgstr ""
+msgstr "相关的分拣单"
#. module: sale
#: field:sale.shop,payment_account_id:0
msgid "Payment Accounts"
-msgstr ""
+msgstr "付款科目"
#. module: sale
#: constraint:product.template:0
@@ -484,7 +486,7 @@ msgstr "错误:销售单位必须和计量单位在不同的分类。"
#. module: sale
#: field:sale.order,client_order_ref:0
msgid "Customer Ref"
-msgstr ""
+msgstr "客户引用"
#. module: sale
#: view:sale.order:0
@@ -495,12 +497,12 @@ msgstr "销售订单"
#: model:process.node,name:sale.process_node_saleprocurement0
#: field:sale.order.line,procurement_id:0
msgid "Procurement"
-msgstr "请料单"
+msgstr "需求单"
#. module: sale
#: view:sale.shop:0
msgid "Payment accounts"
-msgstr "账号付款"
+msgstr "付款账目"
#. module: sale
#: wizard_button:sale.advance_payment_inv,create,end:0
@@ -511,13 +513,13 @@ msgstr "关闭"
#: model:process.node,name:sale.process_node_invoice0
#: model:process.node,name:sale.process_node_invoiceafterdelivery0
msgid "Draft Invoice"
-msgstr "发票草稿"
+msgstr "草稿发票"
#. module: sale
#: wizard_field:sale.order.line.make_invoice,init,grouped:0
#: wizard_field:sale.order.make_invoice,init,grouped:0
msgid "Group the invoices"
-msgstr "发票分类"
+msgstr "集中发票成组"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_tree5
@@ -528,12 +530,12 @@ msgstr "所有报价单"
#. module: sale
#: field:sale.order.line,discount:0
msgid "Discount (%)"
-msgstr "折扣(%)"
+msgstr "降价 (%)"
#. module: sale
#: model:process.node,note:sale.process_node_invoice0
msgid "Draft customer invoice, to be reviewed by accountant."
-msgstr ""
+msgstr "会计人员即将审查的客户发票草稿"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_tree3
@@ -544,7 +546,7 @@ msgstr "要开票的销售订单"
#. module: sale
#: model:process.node,note:sale.process_node_saleorderprocurement0
msgid "Procurement for each line"
-msgstr ""
+msgstr "每订单行的需求单"
#. module: sale
#: model:ir.actions.act_window,name:sale.action_order_tree10
From 5a4e8b8092ffd3d1178985d9965836d4a90fe36d Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Tue, 22 Dec 2009 12:15:51 +0530
Subject: [PATCH 052/123] [IMP]: Generalization of tooltips: Improved tooltips
for all fields.
bzr revid: uco@tinyerp.co.in-20091222064551-k6g299rk9ly1oyg3
---
addons/account/account.py | 4 ++--
addons/account/invoice.py | 2 +-
addons/account_payment/payment.py | 2 +-
addons/crm/crm.py | 2 +-
addons/crm/crm_config.py | 4 ++--
addons/document_ics/document_ics_config_wizard.py | 4 ++--
addons/hr_expense/hr_expense.py | 2 +-
addons/l10n_be/wizard/partner_vat_listing.py | 2 +-
addons/l10n_be/wizard/wizard_vat_intra.py | 4 ++--
addons/l10n_ch/dta.py | 10 +++++-----
addons/l10n_ch/wizard/journal_config.py | 2 +-
addons/mrp/mrp.py | 2 +-
addons/mrp_repair/mrp_repair.py | 2 +-
addons/product/pricelist.py | 6 +++---
addons/product/product.py | 2 +-
addons/product_margin/product_margin.py | 4 ++--
addons/profile_manufacturing/profile_manufacturing.py | 8 ++++----
addons/profile_service/profile_service.py | 4 ++--
addons/stock/product.py | 4 ++--
addons/stock/stock.py | 6 +++---
20 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index bd78d192c81..d88c6219ec4 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -1880,7 +1880,7 @@ class account_add_tmpl_wizard(osv.osv_memory):
return False
_columns = {
- 'cparent_id':fields.many2one('account.account', 'Parent target', help="Create an account with the selected template under this existing parent.", required=True),
+ 'cparent_id':fields.many2one('account.account', 'Parent target', help="Creates an account with the selected template under this existing parent.", required=True),
}
_defaults = {
'cparent_id': _get_def_cparent,
@@ -2001,7 +2001,7 @@ class account_tax_template(osv.osv):
'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'),
'account_paid_id':fields.many2one('account.account.template', 'Refund Tax Account'),
'parent_id':fields.many2one('account.tax.template', 'Parent Tax Account', select=True),
- 'child_depend':fields.boolean('Tax on Children', help="Indicate if the tax computation is based on the value computed for the computation of child taxes or based on the total amount."),
+ 'child_depend':fields.boolean('Tax on Children', help="Indicates if the tax computation is based on the value computed for the computation of child taxes or based on the total amount."),
'python_compute':fields.text('Python Code'),
'python_compute_inv':fields.text('Python Code (reverse)'),
'python_applicable':fields.text('Python Code'),
diff --git a/addons/account/invoice.py b/addons/account/invoice.py
index 425f5a78b50..4e91fca92a4 100644
--- a/addons/account/invoice.py
+++ b/addons/account/invoice.py
@@ -264,7 +264,7 @@ class account_invoice(osv.osv):
'invoice_line': fields.one2many('account.invoice.line', 'invoice_id', 'Invoice Lines', readonly=True, states={'draft':[('readonly',False)]}),
'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}),
- 'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True, help="Link to the automatically generated Ledger Postings."),
+ 'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True, help="Links to the automatically generated Ledger Postings."),
'amount_untaxed': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])),string='Untaxed',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
diff --git a/addons/account_payment/payment.py b/addons/account_payment/payment.py
index 8d46db771f4..f03fda163c9 100644
--- a/addons/account_payment/payment.py
+++ b/addons/account_payment/payment.py
@@ -31,7 +31,7 @@ class payment_type(osv.osv):
_description= 'Payment type'
_columns= {
'name': fields.char('Name', size=64, required=True,help='Payment Type'),
- 'code': fields.char('Code', size=64, required=True,help='Specify the Code for Payment Type'),
+ 'code': fields.char('Code', size=64, required=True,help='Specifies the Code for Payment Type'),
'suitable_bank_types': fields.many2many('res.partner.bank.type',
'bank_type_payment_type_rel',
'pay_type_id','bank_type_id',
diff --git a/addons/crm/crm.py b/addons/crm/crm.py
index 5c6731359f4..3c488d760ae 100755
--- a/addons/crm/crm.py
+++ b/addons/crm/crm.py
@@ -75,7 +75,7 @@ class crm_case_section(osv.osv):
'parent_id': fields.many2one('crm.case.section', 'Parent Section'),
'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Sections'),
"gateway_ids" : fields.one2many("crm.email.gateway",'section_id',"Email Gateways"),
- 'calendar' : fields.boolean('Calendar', help='Allow to show calendar'),
+ 'calendar' : fields.boolean('Calendar', help='Allows to show calendar'),
}
_defaults = {
'active': lambda *a: 1,
diff --git a/addons/crm/crm_config.py b/addons/crm/crm_config.py
index e3e64de994d..e6bae0281c3 100644
--- a/addons/crm/crm_config.py
+++ b/addons/crm/crm_config.py
@@ -123,13 +123,13 @@ class crm_menu_config_wizard(osv.osv_memory):
'meeting': fields.boolean('Calendar of Meetings', help="Manages the calendar of meetings of the users."),
'lead': fields.boolean('Leads', help="Allows you to track and manage leads which are pre-sales requests or contacts, the very first contact with a customer request."),
'opportunity': fields.boolean('Business Opportunities', help="Tracks identified business opportunities for your sales pipeline."),
- 'jobs': fields.boolean('Jobs Hiring Process', help="Help you to organise the jobs hiring process: evaluation, meetings, email integration..."),
+ 'jobs': fields.boolean('Jobs Hiring Process', help="Helps you to organise the jobs hiring process: evaluation, meetings, email integration..."),
'document_ics': fields.boolean('Shared Calendar', help=" Will allow you to synchronise your Open ERP calendars with your phone, outlook, Sunbird, ical, ..."),
'bugs': fields.boolean('Bug Tracking', help="Used by companies to track bugs and support requests on software"),
'helpdesk': fields.boolean('Helpdesk', help="Manages an Helpdesk service."),
'fund': fields.boolean('Fund Raising Operations', help="This may help associations in their fund raising process and tracking."),
'claims': fields.boolean('Claims', help="Manages the supplier and customers claims, including your corrective or preventive actions."),
- 'phonecall': fields.boolean('Phone Calls', help="Help you to encode the result of a phone call or to plan a list of phone calls to process."),
+ 'phonecall': fields.boolean('Phone Calls', help="Helps you to encode the result of a phone call or to plan a list of phone calls to process."),
}
_defaults = {
'meeting': lambda *args: True,
diff --git a/addons/document_ics/document_ics_config_wizard.py b/addons/document_ics/document_ics_config_wizard.py
index ea6bef3d842..30b959e1c20 100644
--- a/addons/document_ics/document_ics_config_wizard.py
+++ b/addons/document_ics/document_ics_config_wizard.py
@@ -55,13 +55,13 @@ class document_ics_crm_wizard(osv.osv_memory):
'meeting' : fields.boolean('Calendar of Meetings', help="Manages the calendar of meetings of the users."),
'lead' : fields.boolean('Leads', help="Allows you to track and manage leads which are pre-sales requests or contacts, the very first contact with a customer request."),
'opportunity' : fields.boolean('Business Opportunities', help="Tracks identified business opportunities for your sales pipeline."),
- 'jobs' : fields.boolean('Jobs Hiring Process', help="Help you to organise the jobs hiring process: evaluation, meetings, email integration..."),
+ 'jobs' : fields.boolean('Jobs Hiring Process', help="Helps you to organise the jobs hiring process: evaluation, meetings, email integration..."),
'document_ics':fields.boolean('Shared Calendar', help=" Will allow you to synchronise your Open ERP calendars with your phone, outlook, Sunbird, ical, ..."),
'bugs' : fields.boolean('Bug Tracking', help="Used by companies to track bugs and support requests on software"),
'helpdesk': fields.boolean('Helpdesk', help="Manages an Helpdesk service."),
'fund' : fields.boolean('Fund Raising Operations', help="This may help associations in their fund raising process and tracking."),
'claims' : fields.boolean('Claims', help="Manages the supplier and customers claims, including your corrective or preventive actions."),
- 'phonecall' : fields.boolean('Phone Calls', help="Help you to encode the result of a phone call or to plan a list of phone calls to process."),
+ 'phonecall' : fields.boolean('Phone Calls', help="Helps you to encode the result of a phone call or to plan a list of phone calls to process."),
}
_defaults = {
'meeting': lambda *args: True,
diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index 9ffdad9c55f..4c2ca16ce0c 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -176,7 +176,7 @@ class product_product(osv.osv):
_inherit = "product.product"
_columns = {
- 'hr_expense_ok': fields.boolean('Can be Expensed', help="Determine if the product can be visible in the list of product within a selection from an HR expense sheet line."),
+ 'hr_expense_ok': fields.boolean('Can be Expensed', help="Determines if the product can be visible in the list of product within a selection from an HR expense sheet line."),
}
product_product()
diff --git a/addons/l10n_be/wizard/partner_vat_listing.py b/addons/l10n_be/wizard/partner_vat_listing.py
index 359f39e5ebe..6369537ec62 100644
--- a/addons/l10n_be/wizard/partner_vat_listing.py
+++ b/addons/l10n_be/wizard/partner_vat_listing.py
@@ -52,7 +52,7 @@ form = """
-
+
"""
fields = {
diff --git a/addons/l10n_be/wizard/wizard_vat_intra.py b/addons/l10n_be/wizard/wizard_vat_intra.py
index 0ac1ad3d9e9..b79c35be612 100644
--- a/addons/l10n_be/wizard/wizard_vat_intra.py
+++ b/addons/l10n_be/wizard/wizard_vat_intra.py
@@ -35,9 +35,9 @@ form_intra = """
-
+
-
+
diff --git a/addons/l10n_ch/dta.py b/addons/l10n_ch/dta.py
index c5f4dd6d031..2778acc14bd 100755
--- a/addons/l10n_ch/dta.py
+++ b/addons/l10n_ch/dta.py
@@ -45,13 +45,13 @@ class account_dta(osv.osv):
'dta_line_ids': fields.one2many('account.dta.line','dta_id','DTA lines', readonly=True),
## textual notes
'note': fields.text('Creation log', readonly=True,
- help="display the problem during dta generation"),
+ help="Displays the problem during dta generation"),
### bank how will execute DTA order
'bank': fields.many2one('res.partner.bank','Bank', readonly=True,select=True,
- help="bank how will execute DTA order"),
+ help="Bank how will execute DTA order"),
### date of DTA order generation
'date': fields.date('Creation Date', readonly=True,select=True,
- help="date of DTA order generation"),
+ help="Date of DTA order generation"),
### user how generate the DTA order
'user_id': fields.many2one('res.users','User', readonly=True, select=True),
}
@@ -76,10 +76,10 @@ class account_dta_line(osv.osv):
'cashdisc_date' : fields.date('Cash Discount date'),
### amount effectively paied on this line
'amount_to_pay' : fields.float('Amount to pay',
- help="amount effectively paid"),
+ help="Amount effectively paid"),
### amount that was on the supplier invoice
'amount_invoice': fields.float('Invoiced Amount',
- help="amount to pay base on the supplier invoice"),
+ help="Amount to pay base on the supplier invoice"),
### Cash discount amount
'amount_cashdisc': fields.float('Cash Discount Amount'),
### Linke to the main dta order
diff --git a/addons/l10n_ch/wizard/journal_config.py b/addons/l10n_ch/wizard/journal_config.py
index 51368536f84..38422913e9c 100755
--- a/addons/l10n_ch/wizard/journal_config.py
+++ b/addons/l10n_ch/wizard/journal_config.py
@@ -82,7 +82,7 @@ class Journal(osv.osv):
'account.journal',
'Journal to set',
readonly=True,
- help="the currenty edited account journal"
+ help="The currenty edited account journal"
),
'default_credit_account_id': fields.many2one(
'account.account', 'Default Credit Account',
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index d6a49c1dd55..84930f1ae69 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -131,7 +131,7 @@ class mrp_routing_workcenter(osv.osv):
help="Time in hours for doing one cycle."),
'hour_nbr': fields.float('Number of Hours', required=True, help="Cost per hour"),
'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True, ondelete='cascade',
- help="routing indicates all the workcenters used, for how long and/or cycles." \
+ help="Routing indicates all the workcenters used, for how long and/or cycles." \
"If Routing is indicated then,the third tab of a production order (workcenters) will be automatically pre-completed."),
'note': fields.text('Description')
}
diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py
index fca6bc76232..51dd47aaf13 100644
--- a/addons/mrp_repair/mrp_repair.py
+++ b/addons/mrp_repair/mrp_repair.py
@@ -91,7 +91,7 @@ class mrp_repair(osv.osv):
'location_id': fields.many2one('stock.location', 'Current Location', required=True, select=True, readonly=True, states={'draft':[('readonly',False)]}),
'location_dest_id': fields.many2one('stock.location', 'Delivery Location', readonly=True, states={'draft':[('readonly',False)]}),
'move_id': fields.many2one('stock.move', 'Move',required=True, domain="[('product_id','=',product_id)]", readonly=True, states={'draft':[('readonly',False)]}),
- 'guarantee_limit': fields.date('Guarantee limit', help="The garantee limit is computed as: last move date + warranty defined on selected product. If the current date is below the garantee limit, each operation and fee you will add will be set as 'not to invoiced' by default. Note that you can change manually afterwards."),
+ 'guarantee_limit': fields.date('Guarantee limit', help="The guarantee limit is computed as: last move date + warranty defined on selected product. If the current date is below the guarantee limit, each operation and fee you will add will be set as 'not to invoiced' by default. Note that you can change manually afterwards."),
'operations' : fields.one2many('mrp.repair.line', 'repair_id', 'Operation Lines', readonly=True, states={'draft':[('readonly',False)]}),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', help='The pricelist comes from the selected partner, by default.'),
'partner_invoice_id':fields.many2one('res.partner.address', 'Invoicing Address', domain="[('partner_id','=',partner_id)]"),
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index 6b5b4444263..0849ee85dcd 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -346,9 +346,9 @@ class product_pricelist_item(osv.osv):
_columns = {
'name': fields.char('Rule Name', size=64, help="Explicit rule name for this pricelist line."),
'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True),
- 'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Set a template if this rule only apply to a template of product. Keep empty for all products"),
- 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Set a product if this rule only apply to one product. Keep empty for all products"),
- 'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Set a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
+ 'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Sets a template if this rule only apply to a template of product. Keep empty for all products"),
+ 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Sets a product if this rule only apply to one product. Keep empty for all products"),
+ 'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Sets a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
'min_quantity': fields.integer('Min. Quantity', required=True, help="The rule only applies if the partner buys/sells more than this quantity."),
'sequence': fields.integer('Sequence', required=True, help="Gives the sequence order when displaying a list of pricelist items."),
diff --git a/addons/product/product.py b/addons/product/product.py
index 37194c1a241..b6ee402077f 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -260,7 +260,7 @@ class product_template(osv.osv):
'cost_method': fields.selection([('standard','Standard Price'), ('average','Average Price')], 'Costing Method', required=True,
help="Standard Price: the cost price is fixed and recomputed periodically (usually at the end of the year), Average Price: the cost price is recomputed at each reception of products."),
'warranty': fields.float('Warranty (months)'),
- 'sale_ok': fields.boolean('Can be sold', help="Determine if the product can be visible in the list of product within a selection from a sale order line."),
+ 'sale_ok': fields.boolean('Can be sold', help="Determines if the product can be visible in the list of product within a selection from a sale order line."),
'purchase_ok': fields.boolean('Can be Purchased', help="Determine if the product is visible in the list of products within a selection from a purchase order line."),
'state': fields.selection([('',''),('draft', 'In Development'),('sellable','In Production'),('end','End of Lifecycle'),('obsolete','Obsolete')], 'State', help="Tells the user if he can use the product or not."),
'uom_id': fields.many2one('product.uom', 'Default UoM', required=True, help="Default Unit of Measure used for all stock operation."),
diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py
index 226fee378fb..d35a60773c5 100644
--- a/addons/product_margin/product_margin.py
+++ b/addons/product_margin/product_margin.py
@@ -104,14 +104,14 @@ class product_product(osv.osv):
'purchase_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='purchase',help="Avg. Price in Supplier Invoices "),
'sale_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='sale',help="Sum of Quantity in Customer Invoices"),
'purchase_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='purchase',help="Sum of Quantity in Supplier Invoices"),
- 'sales_gap' : fields.function(_product_margin, method=True, type='float', string='Sales Gap', multi='sale',help="Excepted Sale - Turn Over"),
+ 'sales_gap' : fields.function(_product_margin, method=True, type='float', string='Sales Gap', multi='sale',help="Expected Sale - Turn Over"),
'purchase_gap' : fields.function(_product_margin, method=True, type='float', string='Purchase Gap', multi='purchase',help="Normal Cost - Total Cost"),
'turnover' : fields.function(_product_margin, method=True, type='float', string='Turnover' ,multi='sale',help="Sum of Multification of Invoice price and quantity of Customer Invoices"),
'total_cost' : fields.function(_product_margin, method=True, type='float', string='Total Cost', multi='purchase',help="Sum of Multification of Invoice price and quantity of Supplier Invoices "),
'sale_expected' : fields.function(_product_margin, method=True, type='float', string='Expected Sale', multi='sale',help="Sum of Multification of Sale Catalog price and quantity of Customer Invoices"),
'normal_cost' : fields.function(_product_margin, method=True, type='float', string='Normal Cost', multi='purchase',help="Sum of Multification of Cost price and quantity of Supplier Invoices"),
'total_margin' : fields.function(_product_margin, method=True, type='float', string='Total Margin', multi='total',help="Turnorder - Total Cost"),
- 'expected_margin' : fields.function(_product_margin, method=True, type='float', string='Expected Margin', multi='total',help="Excepted Sale - Normal Cost"),
+ 'expected_margin' : fields.function(_product_margin, method=True, type='float', string='Expected Margin', multi='total',help="Expected Sale - Normal Cost"),
'total_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Total Margin (%)', multi='margin',help="Total margin * 100 / Turnover"),
'expected_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Expected Margin (%)', multi='margin',help="Expected margin * 100 / Expected Sale"),
}
diff --git a/addons/profile_manufacturing/profile_manufacturing.py b/addons/profile_manufacturing/profile_manufacturing.py
index 991e405bafb..2905cee8ac4 100644
--- a/addons/profile_manufacturing/profile_manufacturing.py
+++ b/addons/profile_manufacturing/profile_manufacturing.py
@@ -33,13 +33,13 @@ class profile_manufacturing_config_install_modules_wizard(osv.osv_memory):
"efficiently priorities in requisitions."
),
'sale_margin':fields.boolean('Margins on Sales Order',
- help="Display margins on the sale order form."),
+ help="Displays margins on the sale order form."),
'sale_crm':fields.boolean('CRM and Calendars',
help="This installs the customer relationship features like: "\
"leads and opportunities tracking, shared calendar, jobs "\
"tracking, bug tracker, and so on."),
'sale_journal':fields.boolean('Manage by Journals',
- help="This module allows you to manage your " \
+ help="This module allows you to manage your " \
"sales, invoicing and picking by journals. You can define "\
"journals for trucks, salesman, departments, invoicing date "\
"delivery period, etc."
@@ -69,11 +69,11 @@ class profile_manufacturing_config_install_modules_wizard(osv.osv_memory):
'mrp_subproduct': fields.boolean('Mrp Sub Product',
help="This module allows you to add sub poducts in mrp bom."),
'warning': fields.boolean('Warning',
- help="Able you to set warnings on products and partners."),
+ help="Makes you able to set warnings on products and partners."),
'board_document':fields.boolean('Document Management',
help= "The Document Management System of Open ERP allows you to store, browse, automatically index, search and preview all kind of documents (internal documents, printed reports, calendar system). It opens an FTP access for the users to easily browse association's document."),
'mrp_repair': fields.boolean('Repair',
- help="Allow to manage product repairs. Handle the guarantee limit date and the invoicing of products and services."),
+ help="Allows to manage product repairs. Handle the guarantee limit date and the invoicing of products and services."),
}
def action_cancel(self,cr,uid,ids,conect=None):
diff --git a/addons/profile_service/profile_service.py b/addons/profile_service/profile_service.py
index 48236901d90..a3c1a981d62 100644
--- a/addons/profile_service/profile_service.py
+++ b/addons/profile_service/profile_service.py
@@ -27,7 +27,7 @@ class profile_service_config_install_modules_wizard(osv.osv_memory):
_rec_name = 'crm_configuration'
_columns = {
'crm_configuration':fields.boolean('CRM & Calendars', help="This installs the customer relationship features like: leads and opportunities tracking, shared calendar, jobs tracking, bug tracker, and so on."),
- 'project_timesheet':fields.boolean('Timesheets', help="Timesheets allows you to track time and costs spent on different projects, represented by analytic accounts."),
+ 'project_timesheet':fields.boolean('Timesheets', help="Allows you to track time and costs spent on different projects, represented by analytic accounts."),
'hr_timesheet_invoice':fields.boolean('Invoice on Timesheets', help="There are different invoicing methods in OpenERP: from sale orders, from shipping, ... Install this module if you plan to invoice your customers based on time spent on projects."),
'hr_holidays':fields.boolean('Holidays Management', help="Tracks the full holidays management process, from the employee's request to the global planning."),
'hr_expense':fields.boolean('Expenses Tracking', help="Tracks the personal expenses process, from the employee expense encoding, to the reimbursement of the employee up to the reinvoicing to the final customer."),
@@ -44,7 +44,7 @@ class profile_service_config_install_modules_wizard(osv.osv_memory):
help="This module allows you to manage a Portal system."),
'wiki': fields.boolean('Wiki',
help="An integrated wiki content management system. This is really "\
- "usefull to manage FAQ, quality manuals, etc.")
+ "useful to manage FAQ, quality manuals, etc.")
}
def action_cancel(self,cr,uid,ids,conect=None):
return {
diff --git a/addons/stock/product.py b/addons/stock/product.py
index eb7389c216e..edf3d021159 100644
--- a/addons/stock/product.py
+++ b/addons/stock/product.py
@@ -164,11 +164,11 @@ class product_product(osv.osv):
return res
_columns = {
- 'qty_available': fields.function(_product_available, method=True, type='float', string='Real Stock', help="Current quantity of products in selected locations or all internal if none have been selected.", multi='qty_available'),
+ 'qty_available': fields.function(_product_available, method=True, type='float', string='Real Stock', help="Current quantities of products in selected locations or all internal if none have been selected.", multi='qty_available'),
'virtual_available': fields.function(_product_available, method=True, type='float', string='Virtual Stock', help="Future stock for this product according to the selected locations or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming.", multi='qty_available'),
'incoming_qty': fields.function(_product_available, method=True, type='float', string='Incoming', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected.", multi='qty_available'),
'outgoing_qty': fields.function(_product_available, method=True, type='float', string='Outgoing', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected.", multi='qty_available'),
- 'track_production': fields.boolean('Track Production Lots' , help="Force to use a Production Lot during production order"),
+ 'track_production': fields.boolean('Track Production Lots' , help="Forces to use a Production Lot during production order"),
'track_incoming': fields.boolean('Track Incoming Lots', help="Forces to use a tracking lot during receptions"),
'track_outgoing': fields.boolean('Track Outgoing Lots', help="Forces to use a tracking lot during deliveries"),
'location_id': fields.dummy(string='Location', relation='stock.location', type='many2one', domain=[('usage','=','internal')]),
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index b3f16e84121..b81edbc300f 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -36,7 +36,7 @@ class stock_incoterms(osv.osv):
_description = "Incoterms"
_columns = {
'name': fields.char('Name', size=64, required=True,help="Incoterms are series of sales terms.They are used to divide transaction costs and responsibilities between buyer and seller and reflect state-of-the-art transportation practices."),
- 'code': fields.char('Code', size=3, required=True,help="code for Incoterms"),
+ 'code': fields.char('Code', size=3, required=True,help="Code for Incoterms"),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the incoterms without removing it."),
}
_defaults = {
@@ -978,9 +978,9 @@ class stock_move(osv.osv):
'product_uos': fields.many2one('product.uom', 'Product UOS'),
'product_packaging': fields.many2one('product.packaging', 'Packaging', help="It specifies attributes of packaging like type, quantity of packaging,etc."),
- 'location_id': fields.many2one('stock.location', 'Source Location', required=True, select=True, help="Set a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations."),
+ 'location_id': fields.many2one('stock.location', 'Source Location', required=True, select=True, help="Sets a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations."),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, select=True, help="Location where the system will stock the finished products."),
- 'address_id': fields.many2one('res.partner.address', 'Dest. Address', help="Adress where goods are to be delivered"),
+ 'address_id': fields.many2one('res.partner.address', 'Dest. Address', help="Address where goods are to be delivered"),
'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', help="Production lot is used to put a serial number on the production"),
'tracking_id': fields.many2one('stock.tracking', 'Tracking Lot', select=True, help="Tracking lot is the code that will be put on the logistical unit/pallet"),
From 170211cba381fe12bf2874518b20c7753191534e Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Tue, 22 Dec 2009 13:57:58 +0530
Subject: [PATCH 053/123] [IMP]: Tooltips improvements: Typo errors remaining
improvements
bzr revid: uco@tinyerp.co.in-20091222082758-pv16moqjdfm3q070
---
addons/account/wizard/wizard_account_chart.py | 2 +-
addons/account/wizard/wizard_statement_from_invoice.py | 2 +-
addons/account_report/account_view.xml | 2 +-
addons/mrp_operations/mrp_operations_view.xml | 2 +-
addons/product/product_view.xml | 2 +-
addons/stock/stock_view.xml | 8 ++++----
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/addons/account/wizard/wizard_account_chart.py b/addons/account/wizard/wizard_account_chart.py
index 75f58711ccc..b4fc40ab01a 100644
--- a/addons/account/wizard/wizard_account_chart.py
+++ b/addons/account/wizard/wizard_account_chart.py
@@ -35,7 +35,7 @@ class wizard_account_chart(wizard.interface):
'string': 'Fiscal year',
'type': 'many2one',
'relation': 'account.fiscalyear',
- 'help': 'Keep empty for all open fiscal year',
+ 'help': 'Keep empty for all open fiscal years',
},
'target_move': {
'string': 'Target Moves',
diff --git a/addons/account/wizard/wizard_statement_from_invoice.py b/addons/account/wizard/wizard_statement_from_invoice.py
index 8b5aa431a30..be4a01c94c4 100644
--- a/addons/account/wizard/wizard_statement_from_invoice.py
+++ b/addons/account/wizard/wizard_statement_from_invoice.py
@@ -41,7 +41,7 @@ FIELDS = {
START_FIELD = {
'date': {'string': 'Date payment', 'type': 'date','required':True, 'default': lambda *a: time.strftime('%Y-%m-%d')},
- 'journal_id': {'string': 'Journal', 'type': 'many2many', 'relation': 'account.journal', 'domain': '[("type","in",["sale","purchase","cash"])]', 'help': 'This field allow you to choose the accounting journals you want for filtering the invoices. If you left this field empty, it will search on all sale, purchase and cash journals.'},
+ 'journal_id': {'string': 'Journal', 'type': 'many2many', 'relation': 'account.journal', 'domain': '[("type","in",["sale","purchase","cash"])]', 'help': 'This field allows you to choose the accounting journals you want for filtering the invoices. If you left this field empty, it will search on all sale, purchase and cash journals.'},
}
START_FORM = '''
diff --git a/addons/account_report/account_view.xml b/addons/account_report/account_view.xml
index ce2b629f030..ff144d6f0c2 100644
--- a/addons/account_report/account_view.xml
+++ b/addons/account_report/account_view.xml
@@ -41,7 +41,7 @@
-
+
diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml
index 29a20321dfc..48261c19912 100644
--- a/addons/mrp_operations/mrp_operations_view.xml
+++ b/addons/mrp_operations/mrp_operations_view.xml
@@ -206,7 +206,7 @@
- Operations Code
+ Operation Codes
ir.actions.act_window
mrp_operations.operation.code
form
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index fe0a3035a61..b6349757b4b 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -128,7 +128,7 @@
-
+
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 1f78d3dffeb..d66f05672b6 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -349,7 +349,7 @@
-
+
@@ -576,7 +576,7 @@
-
+
@@ -692,7 +692,7 @@
-
+
@@ -851,7 +851,7 @@
-
+
From c1d66e1ac53492e4ea87dde6edc9639f015e2f67 Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Tue, 22 Dec 2009 15:08:41 +0530
Subject: [PATCH 054/123] [IMP]: Generalization of tooltips: Added tooltips for
'origin' fields, renamed 'Ref' to 'Reference', Added same tooltips for same
fields of 'account & account template' and 'tax & tax templates'
bzr revid: uco@tinyerp.co.in-20091222093841-2uamhp6w0wkmcnk0
---
addons/account/account.py | 28 +++++++++++--------
addons/account/account_analytic_line.py | 2 +-
addons/account/account_bank_statement.py | 2 +-
addons/account/account_move_line.py | 2 +-
addons/account/invoice.py | 2 +-
.../wizard/wizard_crossovered_analytic.py | 2 +-
addons/account_voucher/voucher.py | 2 +-
addons/mrp/mrp.py | 6 ++--
addons/mrp_repair/mrp_repair.py | 6 ++--
addons/point_of_sale/pos.py | 4 +--
addons/purchase/purchase.py | 4 +--
addons/report_account/report_receivable.py | 2 +-
addons/sale/sale.py | 6 ++--
addons/stock/stock.py | 4 +--
14 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index d88c6219ec4..7bb0e7622d4 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -275,9 +275,13 @@ class account_account(osv.osv):
('consolidation', 'Consolidation'),
('other', 'Others'),
('closed', 'Closed'),
- ], 'Internal Type', required=True,),
-
- 'user_type': fields.many2one('account.account.type', 'Account Type', required=True),
+ ], 'Internal Type', required=True, help="This type is used to differentiate types with "\
+ "special effects in Open ERP: view can not have entries, consolidation are accounts that "\
+ "can have children accounts for multi-company consolidations, payable/receivable are for "\
+ "partners accounts (for debit/credit computations), closed for depreciated accounts."),
+ 'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
+ help="These types are defined according to your country. The type contains more information "\
+ "about the account and its specificities."),
'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade'),
'child_parent_ids': fields.one2many('account.account','parent_id','Children'),
'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
@@ -762,7 +766,7 @@ class account_move(osv.osv):
_columns = {
'name': fields.char('Number', size=64, required=True),
- 'ref': fields.char('Ref', size=64),
+ 'ref': fields.char('Reference', size=64),
'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
'state': fields.selection([('draft','Draft'), ('posted','Posted')], 'State', required=True, readonly=True,
@@ -1526,7 +1530,7 @@ class account_model(osv.osv):
_description = "Account Model"
_columns = {
'name': fields.char('Model Name', size=64, required=True, help="This is a model for recurring accounting entries"),
- 'ref': fields.char('Ref', size=64),
+ 'ref': fields.char('Reference', size=64),
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'lines_id': fields.one2many('account.model.line', 'model_id', 'Model Entries'),
'legend' :fields.text('Legend',readonly=True,size=100),
@@ -1586,7 +1590,7 @@ class account_model_line(osv.osv):
'model_id': fields.many2one('account.model', 'Model', required=True, ondelete="cascade", select=True),
- 'ref': fields.char('Ref.', size=16),
+ 'ref': fields.char('Reference', size=16),
'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency."),
'currency_id': fields.many2one('res.currency', 'Currency'),
@@ -1615,7 +1619,7 @@ class account_subscription(osv.osv):
_description = "Account Subscription"
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'ref': fields.char('Ref', size=16),
+ 'ref': fields.char('Reference', size=16),
'model_id': fields.many2one('account.model', 'Model', required=True),
'date_start': fields.date('Start Date', required=True),
@@ -1806,10 +1810,10 @@ class account_account_template(osv.osv):
('consolidation','Consolidation'),
('other','Others'),
('closed','Closed'),
- ], 'Internal Type', required=True,help="This type is used to differenciate types with "\
+ ], 'Internal Type', required=True,help="This type is used to differentiate types with "\
"special effects in Open ERP: view can not have entries, consolidation are accounts that "\
"can have children accounts for multi-company consolidations, payable/receivable are for "\
- "partners accounts (for debit/credit computations), closed for deprecated accounts."),
+ "partners accounts (for debit/credit computations), closed for depreciated accounts."),
'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
help="These types are defined according to your country. The type contains more information "\
"about the account and its specificities."),
@@ -1994,14 +1998,14 @@ class account_tax_template(osv.osv):
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
'name': fields.char('Tax Name', size=64, required=True),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the taxes lines from lower sequences to higher ones. The order is important if you have a tax that has several tax children. In this case, the evaluation order is important."),
- 'amount': fields.float('Amount', required=True, digits=(14,4)),
+ 'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."),
'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code')], 'Tax Type', required=True),
- 'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True),
+ 'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True, help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'),
'account_paid_id':fields.many2one('account.account.template', 'Refund Tax Account'),
'parent_id':fields.many2one('account.tax.template', 'Parent Tax Account', select=True),
- 'child_depend':fields.boolean('Tax on Children', help="Indicates if the tax computation is based on the value computed for the computation of child taxes or based on the total amount."),
+ 'child_depend':fields.boolean('Tax on Children', help="Set if the tax computation is based on the computation of child taxes rather than on the total amount."),
'python_compute':fields.text('Python Code'),
'python_compute_inv':fields.text('Python Code (reverse)'),
'python_applicable':fields.text('Python Code'),
diff --git a/addons/account/account_analytic_line.py b/addons/account/account_analytic_line.py
index 0b723b4c9e4..7c872669d8c 100644
--- a/addons/account/account_analytic_line.py
+++ b/addons/account/account_analytic_line.py
@@ -42,7 +42,7 @@ class account_analytic_line(osv.osv):
'journal_id' : fields.many2one('account.analytic.journal', 'Analytic Journal', required=True, ondelete='cascade', select=True),
'code' : fields.char('Code', size=8),
'user_id' : fields.many2one('res.users', 'User',),
- 'ref': fields.char('Ref.', size=32),
+ 'ref': fields.char('Reference', size=32),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d'),
diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py
index 1ebc3623f9b..096f33b2496 100644
--- a/addons/account/account_bank_statement.py
+++ b/addons/account/account_bank_statement.py
@@ -587,7 +587,7 @@ class account_bank_statement_line(osv.osv):
'move_ids': fields.many2many('account.move',
'account_bank_statement_line_move_rel', 'move_id','statement_id',
'Moves'),
- 'ref': fields.char('Ref.', size=32),
+ 'ref': fields.char('Reference', size=32),
'note': fields.text('Notes'),
'reconcile_amount': fields.function(_reconcile_amount,
string='Amount reconciled', method=True, type='float'),
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index f0639b9af0d..dacca142274 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -357,7 +357,7 @@ class account_move_line(osv.osv):
'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2),
'move_id': fields.many2one('account.move', 'Move', ondelete="cascade", states={'valid':[('readonly',True)]}, help="The move of this entry line.", select=2),
- 'ref': fields.char('Ref.', size=32),
+ 'ref': fields.char('Reference', size=32),
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1),
'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2),
diff --git a/addons/account/invoice.py b/addons/account/invoice.py
index 4e91fca92a4..76ab9a63182 100644
--- a/addons/account/invoice.py
+++ b/addons/account/invoice.py
@@ -1075,7 +1075,7 @@ class account_invoice_line(osv.osv):
_columns = {
'name': fields.char('Description', size=256, required=True),
'origin': fields.char('Origin', size=256, help="Reference of the document that produced this invoice."),
- 'invoice_id': fields.many2one('account.invoice', 'Invoice Ref', ondelete='cascade', select=True),
+ 'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='cascade', select=True),
'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'),
'product_id': fields.many2one('product.product', 'Product', ondelete='set null'),
'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."),
diff --git a/addons/account_analytic_plans/wizard/wizard_crossovered_analytic.py b/addons/account_analytic_plans/wizard/wizard_crossovered_analytic.py
index d36f684bab4..58effcce3db 100644
--- a/addons/account_analytic_plans/wizard/wizard_crossovered_analytic.py
+++ b/addons/account_analytic_plans/wizard/wizard_crossovered_analytic.py
@@ -38,7 +38,7 @@ fields = {
'date1': {'string':'Start Date', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-01-01')},
'date2': {'string':'End Date', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-%m-%d')},
'journal_ids': {'string':'Analytic Journal', 'type':'many2many', 'relation':'account.analytic.journal'},
- 'ref' :{'string':'Analytic Account Ref.', 'type':'many2one', 'relation':'account.analytic.account','required':True},
+ 'ref' :{'string':'Analytic Account Reference', 'type':'many2one', 'relation':'account.analytic.account','required':True},
'empty_line': {'string':'Dont show empty lines', 'type':'boolean', 'default': lambda *a:False},
}
diff --git a/addons/account_voucher/voucher.py b/addons/account_voucher/voucher.py
index b9c223dcb0a..459611aca43 100755
--- a/addons/account_voucher/voucher.py
+++ b/addons/account_voucher/voucher.py
@@ -487,7 +487,7 @@ class VoucherLine(osv.osv):
'partner_id': fields.many2one('res.partner', 'Partner', change_default=True),
'amount':fields.float('Amount'),
'type':fields.selection([('dr','Debit'),('cr','Credit')], 'Type'),
- 'ref':fields.char('Ref.', size=32),
+ 'ref':fields.char('Reference', size=32),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account')
}
_defaults = {
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 84930f1ae69..12790a5d42b 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -186,7 +186,7 @@ class mrp_bom(osv.osv):
'date_start': fields.date('Valid From', help="Validity of this BoM or component. Keep empty if it's always valid."),
'date_stop': fields.date('Valid Until', help="Validity of this BoM or component. Keep empty if it's always valid."),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bills of material."),
- 'position': fields.char('Internal Ref.', size=64, help="Reference to a position in an external plan."),
+ 'position': fields.char('Internal Reference', size=64, help="Reference to a position in an external plan."),
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_uos_qty': fields.float('Product UOS Qty'),
'product_uos': fields.many2one('product.uom', 'Product UOS', help="Product UOS (Unit of Sale) is the unit of measurement for the invoicing and promotion of stock."),
@@ -407,7 +407,7 @@ class mrp_production(osv.osv):
_columns = {
'name': fields.char('Reference', size=64, required=True),
- 'origin': fields.char('Origin', size=64),
+ 'origin': fields.char('Origin', size=64, help="Reference of the document that generated this production order request."),
'priority': fields.selection([('0','Not urgent'),('1','Normal'),('2','Urgent'),('3','Very Urgent')], 'Priority'),
'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type','<>','service')]),
@@ -445,7 +445,7 @@ class mrp_production(osv.osv):
'cycle_total': fields.function(_production_calc, method=True, type='float', string='Total Cycles', multi='workorder'),
'sale_name': fields.function(_sale_name_calc, method=True, type='char', string='Sale Name'),
- 'sale_ref': fields.function(_sale_ref_calc, method=True, type='char', string='Sale Ref'),
+ 'sale_ref': fields.function(_sale_ref_calc, method=True, type='char', string='Sale Reference'),
'company_id': fields.many2one('res.company','Company',required=True),
}
_defaults = {
diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py
index 51dd47aaf13..7ad80e3de22 100644
--- a/addons/mrp_repair/mrp_repair.py
+++ b/addons/mrp_repair/mrp_repair.py
@@ -73,7 +73,7 @@ class mrp_repair(osv.osv):
return res
_columns = {
- 'name' : fields.char('Repair Ref',size=24, required=True),
+ 'name' : fields.char('Repair Reference',size=24, required=True),
'product_id': fields.many2one('product.product', string='Product to Repair', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'partner_id' : fields.many2one('res.partner', 'Partner', select=True, help='This field allow you to choose the parner that will be invoiced and delivered'),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', domain="[('partner_id','=',partner_id)]"),
@@ -489,7 +489,7 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
_columns = {
'name' : fields.char('Description',size=64,required=True),
- 'repair_id': fields.many2one('mrp.repair', 'Repair Order Ref',ondelete='cascade', select=True),
+ 'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference',ondelete='cascade', select=True),
'type': fields.selection([('add','Add'),('remove','Remove')],'Type', required=True),
'to_invoice': fields.boolean('To Invoice'),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok','=',True)], required=True),
@@ -555,7 +555,7 @@ class mrp_repair_fee(osv.osv, ProductChangeMixin):
return res
_columns = {
- 'repair_id': fields.many2one('mrp.repair', 'Repair Order Ref', required=True, ondelete='cascade', select=True),
+ 'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference', required=True, ondelete='cascade', select=True),
'name': fields.char('Description', size=64, select=True,required=True),
'product_id': fields.many2one('product.product', 'Product'),
'product_uom_qty': fields.float('Quantity', digits=(16,2), required=True),
diff --git a/addons/point_of_sale/pos.py b/addons/point_of_sale/pos.py
index 4cf8ef4ec56..156c42e25f6 100644
--- a/addons/point_of_sale/pos.py
+++ b/addons/point_of_sale/pos.py
@@ -826,7 +826,7 @@ class pos_order_line(osv.osv):
'qty': fields.float('Quantity'),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal'),
'discount': fields.float('Discount (%)', digits=(16, 2)),
- 'order_id': fields.many2one('pos.order', 'Order Ref', ondelete='cascade'),
+ 'order_id': fields.many2one('pos.order', 'Order Reference', ondelete='cascade'),
'create_date': fields.datetime('Creation Date', readonly=True),
}
@@ -922,7 +922,7 @@ class pos_payment(osv.osv):
_columns = {
'name': fields.char('Description', size=64),
- 'order_id': fields.many2one('pos.order', 'Order Ref', required=True, ondelete='cascade'),
+ 'order_id': fields.many2one('pos.order', 'Order Reference', required=True, ondelete='cascade'),
'journal_id': fields.many2one('account.journal', "Journal", required=True),
'payment_id': fields.many2one('account.payment.term','Payment Term', select=True),
'payment_nb': fields.char('Piece Number', size=32),
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index f217c7d9a13..f16ea80f540 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -148,7 +148,7 @@ class purchase_order(osv.osv):
'origin': fields.char('Origin', size=64,
help="Reference of the document that generated this purchase order request."
),
- 'partner_ref': fields.char('Supplier Ref.', size=64),
+ 'partner_ref': fields.char('Supplier Reference', size=64),
'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, help="Date on which this document has been created."),
'date_approve':fields.date('Date Approved', readonly=1),
'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, change_default=True),
@@ -454,7 +454,7 @@ class purchase_order_line(osv.osv):
'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy']))),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits=(16, int(config['price_accuracy']))),
'notes': fields.text('Notes'),
- 'order_id': fields.many2one('purchase.order', 'Order Ref', select=True, required=True, ondelete='cascade'),
+ 'order_id': fields.many2one('purchase.order', 'Order Reference', select=True, required=True, ondelete='cascade'),
'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account',),
'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company',store=True)
}
diff --git a/addons/report_account/report_receivable.py b/addons/report_account/report_receivable.py
index 8d106193cf7..b8e3cf22f67 100644
--- a/addons/report_account/report_receivable.py
+++ b/addons/report_account/report_receivable.py
@@ -179,7 +179,7 @@ class report_invoice_created(osv.osv):
('paid','Done'),
('cancel','Cancelled')
],'State', readonly=True),
- 'origin': fields.char('Origin', size=64, readonly=True),
+ 'origin': fields.char('Origin', size=64, readonly=True, help="Reference of the document that generated this invoice report."),
'create_date' : fields.datetime('Create Date', readonly=True)
}
_order = 'create_date'
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 92ff5325982..3b77bf8eb88 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -184,8 +184,8 @@ class sale_order(osv.osv):
_columns = {
'name': fields.char('Order Reference', size=64, required=True, select=True),
'shop_id': fields.many2one('sale.shop', 'Shop', required=True, readonly=True, states={'draft': [('readonly', False)]}),
- 'origin': fields.char('Origin', size=64),
- 'client_order_ref': fields.char('Customer Ref', size=64),
+ 'origin': fields.char('Origin', size=64, help="Reference of the document that generated this sale order request."),
+ 'client_order_ref': fields.char('Customer Reference', size=64),
'state': fields.selection([
('draft', 'Quotation'),
@@ -750,7 +750,7 @@ class sale_order_line(osv.osv):
_name = 'sale.order.line'
_description = 'Sale Order line'
_columns = {
- 'order_id': fields.many2one('sale.order', 'Order Ref', required=True, ondelete='cascade', select=True),
+ 'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True),
'name': fields.char('Description', size=256, required=True, select=True),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale order lines."),
'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer"),
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index b81edbc300f..dbd8c0c743e 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -437,7 +437,7 @@ class stock_picking(osv.osv):
_columns = {
'name': fields.char('Reference', size=64, select=True),
- 'origin': fields.char('Origin Reference', size=64),
+ 'origin': fields.char('Origin', size=64, help="Reference of the document that produced this picking."),
'backorder_id': fields.many2one('stock.picking', 'Back Order'),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('delivery', 'Delivery')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the picking without removing it."),
@@ -883,7 +883,7 @@ class stock_production_lot(osv.osv):
_columns = {
'name': fields.char('Serial', size=64, required=True),
- 'ref': fields.char('Internal Ref', size=64),
+ 'ref': fields.char('Internal Reference', size=64),
'product_id': fields.many2one('product.product', 'Product', required=True),
'date': fields.datetime('Created Date', required=True),
'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Available", select="2"),
From 6eb9fc83e08350d69e19f63ebabdb3184f116e2a Mon Sep 17 00:00:00 2001
From: "Jay (Open ERP)"
Date: Tue, 22 Dec 2009 17:08:41 +0530
Subject: [PATCH 055/123] [REV/FIX] Reverted bad commit for report_task module
lp bug: https://launchpad.net/bugs/499060 fixed
bzr revid: jvo@tinyerp.com-20091222113841-8yoa0d9iemw5no8e
---
addons/report_task/report_task.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/report_task/report_task.py b/addons/report_task/report_task.py
index 110226f627e..15dfab6b1ea 100644
--- a/addons/report_task/report_task.py
+++ b/addons/report_task/report_task.py
@@ -154,7 +154,7 @@ class report_timesheet_task_user(osv.osv):
union
select to_char(h.name,'YYYY-MM-01') as name,
to_char(h.name,'MM') as m_id
- from hr_timesheet_sheet_sheet_day h) as month) """)
+ from hr_timesheet_sheet_sheet_day h) as months) """)
report_timesheet_task_user()
From 18f41e53a78d420de8a7af1890633b9b96ddf23b Mon Sep 17 00:00:00 2001
From: Christophe Chauvet
Date: Tue, 22 Dec 2009 12:43:50 +0100
Subject: [PATCH 056/123] [IMP] Change try/except by if to test when field is
not a relation
bzr revid: christophe.chauvet@syleam.fr-20091222114350-x94m7ts7uwcadsnc
---
bin/osv/fields.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 50b7a233b3b..2cbba931a47 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -901,27 +901,25 @@ class property(function):
else:
res[int(prop.res_id.split(',')[1])] = prop.value or ''
- try:
+ if self._obj:
obj = obj.pool.get(self._obj)
-
+
to_check = res.values()
if default_val and default_val not in to_check:
to_check += [default_val]
existing_ids = obj.search(cr, uid, [('id', 'in', to_check)])
-
+
for id, res_id in res.items():
if res_id not in existing_ids:
cr.execute('DELETE FROM ir_property WHERE value=%s', ((obj._name+','+str(res_id)),))
res[id] = default_val
-
+
names = dict(obj.name_get(cr, uid, existing_ids, context))
for r in res.keys():
if res[r] and res[r] in names:
res[r] = (res[r], names[res[r]])
else:
res[r] = False
- except:
- pass
return res
def _field_get(self, cr, uid, model_name, prop):
From 2bc631a28da4c403a2b74121ed825c3a42790d55 Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Tue, 22 Dec 2009 18:38:10 +0530
Subject: [PATCH 057/123] [IMP,ADD]: Missing or to clarify tooltips: Added and
Improved tooltips for some fields.
bzr revid: uco@tinyerp.co.in-20091222130810-12crvqp29ckoxzsj
---
addons/account/account.py | 7 ++++++-
addons/hr/hr.py | 2 +-
addons/hr_timesheet/hr_timesheet.py | 2 +-
addons/mrp/mrp.py | 11 ++++-------
addons/product/product.py | 2 +-
addons/stock/stock.py | 2 +-
6 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index 7bb0e7622d4..47cf0c93f4b 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -465,7 +465,12 @@ class account_journal(osv.osv):
_columns = {
'name': fields.char('Journal Name', size=64, required=True, translate=True),
'code': fields.char('Code', size=16),
- 'type': fields.selection([('sale', 'Sale'), ('purchase', 'Purchase'), ('cash', 'Cash'), ('general', 'General'), ('situation', 'Situation')], 'Type', size=32, required=True),
+ 'type': fields.selection([('sale', 'Sale'), ('purchase', 'Purchase'), ('cash', 'Cash'), ('general', 'General'), ('situation', 'Situation')], 'Type', size=32, required=True,
+ help="Select 'Sale' for Sale journal to be used at the time of making invoice."\
+ " Select 'Purchase' for Purchase Journal to be used at the time of approving purchase order."\
+ " Select 'Cash' to be used at the time of making payment."\
+ " Select 'General' to be used at the time of stock input/output."\
+ " Select 'Situation' to be used at the time of making vouchers."),
'refund_journal': fields.boolean('Refund Journal'),
'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view'), ('code', '<>', 'closed')]),
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index d5bb603bdfb..d25ac4e1717 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -126,7 +126,7 @@ class hr_employee(osv.osv):
'country_id' : fields.many2one('res.country', 'Nationality'),
'birthday' : fields.date("Birthday"),
- 'ssnid': fields.char('SSN No', size=32),
+ 'ssnid': fields.char('SSN No', size=32, help='Social Security Number'),
'sinid': fields.char('SIN No', size=32),
'otherid': fields.char('Other ID', size=32),
'gender': fields.selection([('',''),('male','Male'),('female','Female')], 'Gender'),
diff --git a/addons/hr_timesheet/hr_timesheet.py b/addons/hr_timesheet/hr_timesheet.py
index 652814b6e02..61dfba9914b 100644
--- a/addons/hr_timesheet/hr_timesheet.py
+++ b/addons/hr_timesheet/hr_timesheet.py
@@ -29,7 +29,7 @@ class hr_employee(osv.osv):
_name = "hr.employee"
_inherit = "hr.employee"
_columns = {
- 'product_id': fields.many2one('product.product', 'Product'),
+ 'product_id': fields.many2one('product.product', 'Product', help="Specifies employee's designation as a product with type 'service'."),
'journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal')
}
hr_employee()
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 12790a5d42b..860a765a448 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -175,13 +175,10 @@ class mrp_bom(osv.osv):
'name': fields.char('Name', size=64, required=True),
'code': fields.char('Code', size=16),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the bills of material without removing it."),
- 'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True, help=
- "Use a phantom bill of material in raw materials lines that have to be " \
- "automatically computed in on eproduction order and not one per level." \
- "If you put \"Phantom/Set\" at the root level of a bill of material " \
- "it is considered as a set or pack: the products are replaced by the components " \
- "between the sale order to the picking without going through the production order." \
- "The normal BoM will generate one production order per BoM level."),
+ 'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True,
+ help= "If a sub-product is used in several products, it can be useful to create its own BoM."\
+ "Though if you don't want separated production orders for this sub-product, select Set/Phantom as BoM type."\
+ "If a Phantom BoM is used for a root product, it will be sold and shipped as a set of components, instead of being produced."),
'method': fields.function(_compute_type, string='Method', method=True, type='selection', selection=[('',''),('stock','On Stock'),('order','On Order'),('set','Set / Pack')]),
'date_start': fields.date('Valid From', help="Validity of this BoM or component. Keep empty if it's always valid."),
'date_stop': fields.date('Valid Until', help="Validity of this BoM or component. Keep empty if it's always valid."),
diff --git a/addons/product/product.py b/addons/product/product.py
index b6ee402077f..7a1ddf7c727 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -571,7 +571,7 @@ class product_packaging(osv.osv):
'qty' : fields.float('Quantity by Package',
help="The total number of products you can put by pallet or box."),
'ul' : fields.many2one('product.ul', 'Type of Package', required=True),
- 'ul_qty' : fields.integer('Package by layer'),
+ 'ul_qty' : fields.integer('Package by layer', help='The number of packages by layer'),
'rows' : fields.integer('Number of Layers', required=True,
help='The number of layers on a pallet or box'),
'product_id' : fields.many2one('product.product', 'Product', select=1, ondelete='cascade', required=True),
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index dbd8c0c743e..0b2aaa90b18 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -438,7 +438,7 @@ class stock_picking(osv.osv):
_columns = {
'name': fields.char('Reference', size=64, select=True),
'origin': fields.char('Origin', size=64, help="Reference of the document that produced this picking."),
- 'backorder_id': fields.many2one('stock.picking', 'Back Order'),
+ 'backorder_id': fields.many2one('stock.picking', 'Back Order', help="If the picking is splitted then the picking id in available state of move for this picking is stored in Backorder."),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('delivery', 'Delivery')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the picking without removing it."),
'note': fields.text('Notes'),
From 312ce4d690cb19938ec91345b2ae60f97dcb0456 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Tue, 22 Dec 2009 18:44:25 +0530
Subject: [PATCH 058/123] [IMP]: Caldav+crm+project_calendar , Implemented
exdates for Event and tasks
bzr revid: rpa@tinyerp.com-20091222131425-8wxl8xv01wznl56v
---
addons/caldav/calendar.py | 22 +++++++---
addons/crm/crm_caldav_view.xml | 23 +++++++---
addons/crm/crm_calendar.py | 43 +++++++++----------
addons/project_calendar/project_calendar.py | 31 +++++++------
.../project_calendar_view.xml | 18 ++++++--
5 files changed, 86 insertions(+), 51 deletions(-)
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index 7800c773112..2e671ddedf1 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -69,14 +69,17 @@ class CalDAV(object):
__attribute__ = {
}
def get_recurrent_dates(self, rrulestring, exdate, startdate=None):
- todate = parser.parse
+ def todate(date):
+ val = parser.parse(''.join((re.compile('\d')).findall(date)) + 'Z')
+ return val
+
if not startdate:
startdate = datetime.now()
else:
- startdate = todate(''.join((re.compile('\d')).findall(startdate)) + 'Z')
+ startdate = todate(startdate)
rset1 = rrulestr(rrulestring, dtstart=startdate, forceset=True)
for date in exdate:
- datetime_obj = datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
+ datetime_obj = todate(date)
rset1._exdate.append(datetime_obj)
re_dates = rset1._iter()
recurrent_dates = map(lambda x:x.strftime('%Y-%m-%d %H:%M:%S'), re_dates)
@@ -93,9 +96,12 @@ class CalDAV(object):
valtype = self.__attribute__.get(name).get('type', None)
if type == 'value':
if valtype and valtype=='datetime' and val:
- val = val.strftime('%Y-%m-%d %H:%M:%S')
+ if isinstance(val, list):
+ val = ','.join(map(lambda x: x.strftime('%Y-%m-%d %H:%M:%S'), val))
+ else:
+ val = val.strftime('%Y-%m-%d %H:%M:%S')
if valtype and valtype=='integer' and val:
- val = int(val)
+ val = int(val)
return val
else:
return self.__attribute__.get(name, None)
@@ -124,8 +130,10 @@ class CalDAV(object):
if map_type == "text":
vevent.add(field).value = str(data[map_field])
elif map_type == 'datetime' and data[map_field]:
- vevent.add(field).value = datetime.strptime(data[map_field], \
- "%Y-%m-%d %H:%M:%S")
+ if field in ('exdate'):
+ vevent.add(field).value = [parser.parse(data[map_field])]
+ else:
+ vevent.add(field).value = parser.parse(data[map_field])
elif map_type == "timedelta":
vevent.add(field).value = timedelta(hours=data[map_field])
if self.__attribute__.get(field).has_key('mapping'):
diff --git a/addons/crm/crm_caldav_view.xml b/addons/crm/crm_caldav_view.xml
index eefa9cd280f..a68970c3bf5 100644
--- a/addons/crm/crm_caldav_view.xml
+++ b/addons/crm/crm_caldav_view.xml
@@ -98,12 +98,23 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_calendar.py b/addons/crm/crm_calendar.py
index 4ce6b6038e5..98fef31c6e9 100644
--- a/addons/crm/crm_calendar.py
+++ b/addons/crm/crm_calendar.py
@@ -19,18 +19,13 @@
#
##############################################################################
-from osv import fields, osv
-from time import strftime
-import time
-import base64
-import vobject
from dateutil.rrule import *
-from dateutil import parser
+from osv import fields, osv
import datetime
-from time import strftime
-from pytz import timezone
+import base64
+import re
+import time
import tools
-from service import web_services
def caldevIDs2readIDs(caldev_ID = None):
if caldev_ID:
@@ -68,8 +63,8 @@ class crm_case(osv.osv):
# 'categories' : {'field':None , 'sub-field':'name', 'type':'text'}, # keep none for now
'comment' : None,
'contact' : None,
- 'exdate' : None,
- 'exrule' : None,
+ 'exdate' : {'field':'exdate', 'type':'datetime'},
+ 'exrule' : {'field':'exrule', 'type':'text'},
'rstatus' : None,
'related' : None,
'resources' : None,
@@ -100,10 +95,10 @@ class crm_case(osv.osv):
def _get_rdates(self, cr, uid, ids, name, arg, context=None):
res = {}
context.update({'read':True})
- for case in self.read(cr, uid, ids, ['date', 'rrule'], context=context):
+ for case in self.read(cr, uid, ids, ['date', 'rrule', 'exdate', 'exrule'], context=context):
if case['rrule']:
- rule = case['rrule'].split('\n')[0]
- exdate = case['rrule'].split('\n')[1:]
+ rule = case['rrule']
+ exdate = case['exdate'] and case['exdate'].split(',') or []
event_obj = self.pool.get('caldav.event')
res[case['id']] = str(event_obj.get_recurrent_dates(str(rule), exdate, case['date']))
return res
@@ -116,6 +111,10 @@ class crm_case(osv.osv):
'freebusy' : fields.text('FreeBusy'),
'transparent' : fields.selection([('OPAQUE', 'OPAQUE'), ('TRANSPARENT', 'TRANSPARENT')], 'Trensparent'),
'caldav_url' : fields.char('Caldav URL', size=34),
+ 'exdate' : fields.text('Exception Date/Times', help="This property defines the list\
+ of date/time exceptions for arecurring calendar component."),
+ 'exrule' : fields.text('Exception Rule', help="defines a rule or repeating pattern\
+ for anexception to a recurrence set"),
'rrule' : fields.text('Recurrent Rule'),
'rdates' : fields.function(_get_rdates, method=True, string='Recurrent Dates', \
store=True, type='text'),
@@ -134,7 +133,7 @@ class crm_case(osv.osv):
def run_scheduler(self, cr, uid, automatic=False, use_new_cursor=False, \
context=None):
if not context:
- context={}
+ context = {}
cr.execute('select c.id as id, c.date as date, alarm.id as alarm_id, alarm.name as name,\
alarm.trigger_interval, alarm.trigger_duration, alarm.trigger_related, \
alarm.trigger_occurs from crm_case c \
@@ -196,7 +195,7 @@ class crm_case(osv.osv):
file_content = base64.decodestring(data['form']['file_path'])
event_obj = self.pool.get('caldav.event')
event_obj.__attribute__.update(self.__attribute__)
-
+
attendee_obj = self.pool.get('caldav.attendee')
crm_attendee = self.pool.get('crm.caldav.attendee')
attendee_obj.__attribute__.update(crm_attendee.__attribute__)
@@ -236,8 +235,7 @@ class crm_case(osv.osv):
select = map(lambda x:caldevIDs2readIDs(x), select)
return super(crm_case, self).browse(cr, uid, select, context, list_class, fields_process)
- def read(self, cr, uid, ids, fields=None, context={},
- load='_classic_read'):
+ def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
""" logic for recurrent event
example : 123-20091111170822"""
if context and context.has_key('read'):
@@ -269,7 +267,6 @@ class crm_case(osv.osv):
result.remove(val)
for rdate in rdates:
- import re
idval = (re.compile('\d')).findall(rdate)
val['date'] = rdate
id = str(val['id']).split('-')[0]
@@ -287,10 +284,12 @@ class crm_case(osv.osv):
if len(str(id).split('-')) > 1:
date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
- for record in self.read(cr, uid, [caldevIDs2readIDs(id)], ['date', 'rdates', 'rrule']):
+ for record in self.read(cr, uid, [caldevIDs2readIDs(id)], \
+ ['date', 'rdates', 'rrule', 'exdate']):
+ exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
+ ''.join((re.compile('\d')).findall(date_new)) + 'Z'
if record['date'] == date_new:
- self.write(cr, uid, [caldevIDs2readIDs(id)], \
- {'rrule' : record['rrule'] +"\n" + str(date_new)})
+ self.write(cr, uid, [caldevIDs2readIDs(id)], {'exdate' : exdate})
else:
return super(crm_case, self).unlink(cr, uid, ids)
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
index 82ae10ff4f7..8e7b3852bec 100644
--- a/addons/project_calendar/project_calendar.py
+++ b/addons/project_calendar/project_calendar.py
@@ -23,6 +23,8 @@ from datetime import datetime
from osv import fields, osv
from service import web_services
import base64
+import time
+import re
def caldevIDs2readIDs(caldev_ID = None):
if caldev_ID:
@@ -36,12 +38,12 @@ class project_task(osv.osv):
def _get_rdates(self, cr, uid, ids, name, arg, context=None):
res = {}
context.update({'read':True})
- for task in self.read(cr, uid, ids, ['date_start', 'rrule'], context=context):
+ for task in self.read(cr, uid, ids, ['date_start', 'rrule', 'exdate', 'exrule'], context=context):
if task['rrule']:
- rule = task['rrule'].split('\n')[0]
+ rule = task['rrule']
if rule.upper().find('COUNT') < 0: # Temp fix, needs review
rule += ';COUNT=5'
- exdate = task['rrule'].split('\n')[1:]
+ exdate = task['exdate'] and task['exdate'].split(',') or []
todo_obj = self.pool.get('caldav.todo')
res[task['id']] = str(todo_obj.get_recurrent_dates(str(rule), exdate, task['date_start']))
return res
@@ -51,9 +53,13 @@ class project_task(osv.osv):
('CONFIDENTIAL', 'CONFIDENTIAL')], 'Class'),
'location': fields.text('Location'),
'rrule': fields.text('Recurrent Rule'),
+ 'exdate' : fields.text('Exception Date/Times', help="This property defines the list\
+ of date/time exceptions for arecurring calendar component."),
+ 'exrule' : fields.text('Exception Rule', help="defines a rule or repeating pattern\
+ for anexception to a recurrence set"),
'rdates': fields.function(_get_rdates, method=True, string='Recurrent Dates', \
store=True, type='text'),
- 'attendee_ids': fields.many2many('crm.caldav.attendee', 'crm_attendee_rel', 'case_id', \
+ 'attendee_ids': fields.many2many('crm.caldav.attendee', 'task_attendee_rel', 'case_id', \
'attendee_id', 'Attendees'),
'alarm_id': fields.many2one('crm.caldav.alarm', 'Alarm'),
'caldav_url': fields.char('Caldav URL', size=34),
@@ -87,8 +93,8 @@ class project_task(osv.osv):
# 'categories': {'field': 'type', 'type': 'text'}, # Needs review
'comment': {'field': 'notes', 'type': 'text'},
# 'contact': {'field': 'field', 'type': 'text'},
-# 'exdate': {'field': 'field', 'type': 'text'},
-# 'exrule': {'field': 'field', 'type': 'text'},
+ 'exdate' : {'field':'exdate', 'type':'datetime'},
+ 'exrule' : {'field':'exrule', 'type':'text'},
# 'rstatus': {'field': 'field', 'type': 'text'},
# 'related': {'field': 'field', 'type': 'text'},
# 'resources': {'field': 'field', 'type': 'text'},
@@ -143,8 +149,8 @@ class project_task(osv.osv):
return caendar_val
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
- """ logic for recurrent task
- example : 123-20091111170822""", ids, fields, context
+ """ Logic for recurrent task
+ example : 123-20091111170822"""
if context and context.has_key('read'):
return super(project_task, self).read(cr, uid, ids, fields, context, load)
if not type(ids) == list :
@@ -173,7 +179,6 @@ class project_task(osv.osv):
result.remove(val)
for rdate in rdates:
- import re
idval = (re.compile('\d')).findall(rdate)
val['date_start'] = rdate
id = str(val['id']).split('-')[0]
@@ -210,10 +215,12 @@ class project_task(osv.osv):
if len(str(id).split('-')) > 1:
date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
- for record in self.read(cr, uid, [caldevIDs2readIDs(id)], ['date_start', 'rdates', 'rrule']):
+ for record in self.read(cr, uid, [caldevIDs2readIDs(id)], \
+ ['date', 'rdates', 'rrule', 'exdate']):
+ exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
+ ''.join((re.compile('\d')).findall(date_new)) + 'Z'
if record['date_start'] == date_new:
- self.write(cr, uid, [caldevIDs2readIDs(id)], \
- {'rrule' : record['rrule'] +"\n" + str(date_new)})
+ self.write(cr, uid, [caldevIDs2readIDs(id)], {'exdate' : exdate})
else:
return super(project_task, self).unlink(cr, uid, ids)
diff --git a/addons/project_calendar/project_calendar_view.xml b/addons/project_calendar/project_calendar_view.xml
index 826d0788b04..6ed99321b13 100644
--- a/addons/project_calendar/project_calendar_view.xml
+++ b/addons/project_calendar/project_calendar_view.xml
@@ -109,10 +109,20 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From c3aaa3a6735f4bf7f584cb4d987ca35596344c33 Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Tue, 22 Dec 2009 18:47:41 +0530
Subject: [PATCH 059/123] [REF]: To receive button must be checked by default.
(Bug# 493714)
bzr revid: uco@tinyerp.co.in-20091222131741-1dqryh2n2i5gnyii
---
addons/stock/stock_view.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index d66f05672b6..04e79821368 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -1259,7 +1259,7 @@
-
+
From 306d196cbdb34c52c3ef3a93cc33f861fd677676 Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Tue, 22 Dec 2009 17:27:03 +0100
Subject: [PATCH 060/123] [IMP] Improved description of project_mrp module
bzr revid: odo@openerp.com-20091222162703-fvufgrtdtbqpv0ja
---
addons/project_mrp/__terp__.py | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/addons/project_mrp/__terp__.py b/addons/project_mrp/__terp__.py
index ed8c9e74e51..2f43d28a681 100644
--- a/addons/project_mrp/__terp__.py
+++ b/addons/project_mrp/__terp__.py
@@ -21,15 +21,29 @@
{
- 'name': 'Project Management - MRP and Sale Integration',
+ 'name': 'Procurement and Project Management integration',
'version': '1.0',
'category': 'Generic Modules/Projects & Services',
'description': """
-This module is used to automatically create tasks based on different
-procurements: sales order, manufacturing order, ...
+This module creates a link between procurement orders
+containing "service" lines and project management tasks.
+
+When installed, this module will automatically create a new task
+for each procurement order line, when the corresponding product
+meets the following characteristics:
+ * Type = Service
+ * Procurement method (Order fulfillment) = MTO (make to order)
+ * Supply/Procurement method = Produce
+
+The new task is created outside of any existing project, but
+can be added to a project manually.
+
+When the project task is completed or cancelled, the workflow of the corresponding
+procurement line is updated accordingly.
+
+This module is useful to be able to invoice services based on tasks
+automatically created via sale orders.
-It is mainly used to invoices services based on tasks automatically
-created by sales orders.
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
From a1516b79727d1219a33591dd82abc5b219901404 Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Tue, 22 Dec 2009 18:31:48 +0100
Subject: [PATCH 061/123] [IMP] Improved description of mrp_jit module
bzr revid: odo@openerp.com-20091222173148-etyj05cqddxx5byn
---
addons/mrp_jit/__terp__.py | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/addons/mrp_jit/__terp__.py b/addons/mrp_jit/__terp__.py
index b0f3028f6e2..1d894a84c30 100644
--- a/addons/mrp_jit/__terp__.py
+++ b/addons/mrp_jit/__terp__.py
@@ -25,15 +25,23 @@
'version': '1.0',
'category': 'Generic Modules/Production',
'description': """
- This module allows Just In Time computation of all procurement.
-
- If you install this module, you will not have to run the schedulers anymore.
- Each document is computed in real time. Note that this module can slow down your
- system a little bit.
+ This module allows Just In Time computation of procurement orders.
+ If you install this module, you will not have to run the procurement scheduler
+ manually anymore, or wait for it to execute.
+ Each procurement order (resulting from a sale order, for instance) will be computed
+ when confirmed, without waiting for the procurement scheduler to run.
+
+ Warning: this does not take into account minimum stock rules (order points), which still
+ require to run the appropriate scheduler, or wait for it to run nightly.
+
+ Note that the procurement computation can be resource-intensive, so you may
+ want to be careful with this, depending on your mrp configuration and system
+ usage.
It may also increase your stock size because products are reserved as soon
- as possible. In that case, you can not use priorities any more on the different
- picking.
+ as possible. In that case, you can not use priorities any more.
+
+
""",
'author': 'Tiny',
'depends': ['mrp', 'sale'],
From 1e96d81e13d509461069d20a819194579b1d9ae0 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 18:34:09 +0100
Subject: [PATCH 062/123] merge
bzr revid: fp@tinyerp.com-20091222173409-ybwzoq7zbsphj26a
---
bin/addons/base/res/partner/partner.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py
index 99fd490a27f..39190d4df33 100644
--- a/bin/addons/base/res/partner/partner.py
+++ b/bin/addons/base/res/partner/partner.py
@@ -277,13 +277,12 @@ res_partner()
class res_partner_address(osv.osv):
_description ='Partner Addresses'
_name = 'res.partner.address'
- _order = 'id'
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', select=True, help="Keep empty for a private address, not related to partner."),
'type': fields.selection( [ ('default','Default'),('invoice','Invoice'), ('delivery','Delivery'), ('contact','Contact'), ('other','Other') ],'Address Type', help="Used to select automatically the right address according to the context in sales and purchases documents."),
'function': fields.many2one('res.partner.function', 'Function'),
'title': fields.selection(_contact_title_get, 'Title', size=32),
- 'name': fields.char('Contact Name', size=64),
+ 'name': fields.char('Contact Name', size=64, select=1),
'street': fields.char('Street', size=128),
'street2': fields.char('Street2', size=128),
'zip': fields.char('Zip', change_default=True, size=24),
From 583aeef94c4d3ae3c3771757e9c7a8feae99a406 Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Tue, 22 Dec 2009 19:23:25 +0100
Subject: [PATCH 063/123] [FIX] Corrected tooltip on quantity field in product
supplier info (uses purchase UoM, not default one)
bzr revid: odo@openerp.com-20091222182325-hyiidmwh0ytry2rx
---
addons/product/i18n/fr.po | 4 ++--
addons/product/i18n/nl.po | 4 ++--
addons/product/product.py | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/addons/product/i18n/fr.po b/addons/product/i18n/fr.po
index d6f107598c6..aaa1dcef76f 100644
--- a/addons/product/i18n/fr.po
+++ b/addons/product/i18n/fr.po
@@ -105,11 +105,11 @@ msgstr "Intervention senior sur site"
#. module: product
#: help:product.supplierinfo,qty:0
msgid ""
-"The minimal quantity to purchase for this supplier, expressed in the default "
+"The minimal quantity to purchase for this supplier, expressed in the purchase "
"unit of measure."
msgstr ""
"La quantité minimum d'achat pour ce fournisseur, exprimée dans l'unité de "
-"mesure par défaut"
+"mesure d'achat"
#. module: product
#: field:product.template,weight_net:0
diff --git a/addons/product/i18n/nl.po b/addons/product/i18n/nl.po
index f7b0ef41818..cbfa83f3fb4 100644
--- a/addons/product/i18n/nl.po
+++ b/addons/product/i18n/nl.po
@@ -67,11 +67,11 @@ msgstr "Onsite Senior Intervention"
#. module: product
#: help:product.supplierinfo,qty:0
msgid ""
-"The minimal quantity to purchase for this supplier, expressed in the default "
+"The minimal quantity to purchase for this supplier, expressed in the purchase "
"unit of measure."
msgstr ""
"Het minimale aantal om in te kopen voor deze leverancier, uitgedrukt in de "
-"standaard meeteenheid."
+"inkoop-meeteenheid."
#. module: product
#: field:product.template,weight_net:0
diff --git a/addons/product/product.py b/addons/product/product.py
index ad2b4ca0330..2de5612c44d 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -630,7 +630,7 @@ class product_supplierinfo(osv.osv):
'product_name': fields.char('Partner Product Name', size=128, help="Name of the product for this partner, will be used when printing a request for quotation. Keep empty to use the internal one."),
'product_code': fields.char('Partner Product Code', size=64, help="Code of the product for this partner, will be used when printing a request for quotation. Keep empty to use the internal one."),
'sequence' : fields.integer('Priority'),
- 'qty' : fields.float('Minimal Quantity', required=True, help="The minimal quantity to purchase for this supplier, expressed in the default unit of measure."),
+ 'qty' : fields.float('Minimal Quantity', required=True, help="The minimal quantity to purchase for this supplier, expressed in the purchase unit of measure."),
'product_id' : fields.many2one('product.template', 'Product', required=True, ondelete='cascade', select=True),
'delay' : fields.integer('Delivery Delay', required=True, help="Delay in days between the confirmation of the purchase order and the reception of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning."),
'pricelist_ids': fields.one2many('pricelist.partnerinfo', 'suppinfo_id', 'Supplier Pricelist'),
From 4e56ee5d95f99908c86b5860b2a45b9c3e56b5c0 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 19:59:36 +0100
Subject: [PATCH 064/123] [FIX] multi-company on products
bzr revid: fp@tinyerp.com-20091222185936-147z4634by47frw1
---
addons/product/product.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/addons/product/product.py b/addons/product/product.py
index ad2b4ca0330..21f041864bb 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -446,7 +446,6 @@ class product_product(osv.osv):
'price_extra': fields.float('Variant Price Extra', digits=(16, int(config['price_accuracy']))),
'price_margin': fields.float('Variant Price Margin', digits=(16, int(config['price_accuracy']))),
'pricelist_id': fields.dummy(string='Pricelist',relation='product.pricelist', type='many2one'),
-# 'company_id': fields.many2one('res.company', 'Company'),
}
def onchange_uom(self, cursor, user, ids, uom_id,uom_po_id):
From eb665f6e1d5f7b280c8ca52711692aed0c5aed11 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 20:01:58 +0100
Subject: [PATCH 065/123] [FIX] improve multi-company and rule system
bzr revid: fp@tinyerp.com-20091222190158-lwknqi2vcgj1e94d
---
bin/addons/base/ir/ir_rule.py | 69 +++++------------------------------
bin/osv/expression.py | 4 +-
bin/osv/fields.py | 8 ++--
bin/osv/orm.py | 50 +++++++++----------------
4 files changed, 32 insertions(+), 99 deletions(-)
diff --git a/bin/addons/base/ir/ir_rule.py b/bin/addons/base/ir/ir_rule.py
index 20ceb737601..f096d53a93d 100644
--- a/bin/addons/base/ir/ir_rule.py
+++ b/bin/addons/base/ir/ir_rule.py
@@ -137,10 +137,9 @@ class ir_rule(osv.osv):
if not (field_id or operator or operand):
return {}
- def domain_get(self, cr, uid, model_name):
- # root user above constraint
+ def domain_get2(self, cr, uid, model_name):
if uid == 1:
- return '', []
+ return []
cr.execute("""SELECT r.id FROM
ir_rule r
@@ -152,64 +151,14 @@ class ir_rule(osv.osv):
JOIN res_groups_users_rel u_rel ON (g_rel.group_id = u_rel.gid)
WHERE u_rel.uid = %s) OR g.global)""", (model_name, uid))
ids = map(lambda x:x[0], cr.fetchall())
- if not ids:
- return '', []
- obj = self.pool.get(model_name)
- add = []
- add_str = []
- sub = []
- sub_str = []
- clause={}
- clause_global={}
+ dom = []
for rule in self.browse(cr, uid, ids):
- dom = rule.domain
- if rule.rule_group['global']:
- clause_global.setdefault(rule.rule_group.id, [])
- clause_global[rule.rule_group.id].append(obj._where_calc(cr, uid, dom, active_test=False))
- else:
- clause.setdefault(rule.rule_group.id, [])
- clause[rule.rule_group.id].append(obj._where_calc(cr, uid, dom, active_test=False))
-
- def _query(clause, test):
- query = ''
- val = []
- for g in clause.values():
- if not g:
- continue
- if len(query):
- query += ' '+test+' '
- query += '('
- first = True
- for c in g:
- if not first:
- query += ' AND '
- first = False
- query += '('
- first2 = True
- for clause in c[0]:
- if not first2:
- query += ' AND '
- first2 = False
- query += clause
- query += ')'
- val += c[1]
- query += ')'
- return query, val
-
- query, val = _query(clause, 'OR')
- query_global, val_global = _query(clause_global, 'OR')
- if query_global:
- if query:
- query = '('+query+') OR '+query_global
- val.extend(val_global)
- else:
- query = query_global
- val = val_global
-
-
- if query:
- query = '('+query+')'
- return query, val
+ dom += rule.domain
+ return dom
+ def domain_get(self, cr, uid, model_name):
+ dom = self.domain_get2(cr, uid, model_name)
+ d1,d2,tables = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
+ return ' and '.join(d1), d2, tables
domain_get = tools.cache()(domain_get)
def unlink(self, cr, uid, ids, context=None):
diff --git a/bin/osv/expression.py b/bin/osv/expression.py
index d1fdfedf464..6dbe600fe0c 100644
--- a/bin/osv/expression.py
+++ b/bin/osv/expression.py
@@ -115,14 +115,14 @@ class expression(object):
main_table = table
fargs = left.split('.', 1)
index = i
- if left in table._inherit_fields:
+ if fargs[0] in table._inherit_fields:
while True:
field = main_table._columns.get(fargs[0], False)
if field:
working_table = main_table
self.__tables[i] = working_table
break
- working_table = main_table.pool.get(main_table._inherit_fields[left][0])
+ working_table = main_table.pool.get(main_table._inherit_fields[fargs[0]][0])
if working_table not in self.__tables.values():
self.__joins.append(('%s.%s=%s.%s' % (working_table._table, 'id', main_table._table, main_table._inherits[working_table._name]), working_table._table))
self.__tables[index] = working_table
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index d86c48bdc1a..a8cf6e85b8d 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -506,12 +506,12 @@ class many2many(_column):
limit_str = self._limit is not None and ' limit %d' % self._limit or ''
obj = obj.pool.get(self._obj)
- d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
+ d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
if d1:
d1 = ' and ' + d1
cr.execute('SELECT '+self._rel+'.'+self._id2+','+self._rel+'.'+self._id1+' \
- FROM '+self._rel+' , '+obj._table+' \
+ FROM '+self._rel+' , '+(','.join(tables))+' \
WHERE '+self._rel+'.'+self._id1+' = ANY (%s) \
AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+d1
+limit_str+' order by '+obj._table+'.'+obj._order+' offset %s',
@@ -544,10 +544,10 @@ class many2many(_column):
cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%s', (id,))
elif act[0] == 6:
- d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
+ d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
if d1:
d1 = ' and ' + d1
- cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+obj._table+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
+ cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
for act_nbr in act[2]:
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s, %s)', (id, act_nbr))
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index f15b452d5b2..d445e966bc9 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -2343,7 +2343,6 @@ class orm(orm_template):
select = map(lambda x: isinstance(x,dict) and x['id'] or x, select)
result = self._read_flat(cr, user, select, fields, context, load)
-
for r in result:
for key, v in r.items():
if v == None:
@@ -2361,8 +2360,7 @@ class orm(orm_template):
id_exist = cr.fetchone()
if not id_exist:
cr.execute('update "'+self._table+'" set "'+key+'"=NULL where "%s"=%s' %(key,''.join("'"+str(v)+"'")))
- r[key] = ''
-
+ r[key] = ''
if isinstance(ids, (int, long, dict)):
return result and result[0] or False
return result
@@ -2377,7 +2375,7 @@ class orm(orm_template):
fields_to_read = self._columns.keys()
# construct a clause for the rules :
- d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name)
+ d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, user, self._name)
# all inherited fields + all non inherited fields for which the attribute whose name is in load is True
fields_pre = [f for f in fields_to_read if
@@ -2392,7 +2390,7 @@ class orm(orm_template):
return "date_trunc('second', %s) as %s" % (f, f)
if f == self.CONCURRENCY_CHECK_FIELD:
if self._log_access:
- return "COALESCE(write_date, create_date, now())::timestamp AS %s" % (f,)
+ return "COALESCE(%s.write_date, %s.create_date, now())::timestamp AS %s" % (self._table, self._table, f,)
return "now()::timestamp AS %s" % (f,)
if isinstance(self._columns[f], fields.binary) and context.get('bin_size', False):
return 'length("%s") as "%s"' % (f, f)
@@ -2401,8 +2399,8 @@ class orm(orm_template):
for i in range(0, len(ids), cr.IN_MAX):
sub_ids = ids[i:i+cr.IN_MAX]
if d1:
- cr.execute('SELECT %s FROM \"%s\" WHERE id = ANY (%%s) AND %s ORDER BY %s' % \
- (','.join(fields_pre2 + ['id']), self._table, d1,
+ cr.execute('SELECT %s FROM %s WHERE %s.id = ANY (%%s) AND %s ORDER BY %s' % \
+ (','.join(fields_pre2 + [self._table + '.id']), ','.join(tables), self._table, d1,
self._order),[sub_ids,]+d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
@@ -2588,7 +2586,7 @@ class orm(orm_template):
# ids2 = [x[self._inherits[key]] for x in res]
# self.pool.get(key).unlink(cr, uid, ids2)
- d1, d2 = self.pool.get('ir.rule').domain_get(cr, uid, self._name)
+ d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name)
if d1:
d1 = ' AND '+d1
@@ -2596,19 +2594,15 @@ class orm(orm_template):
sub_ids = ids[i:i+cr.IN_MAX]
str_d = string.join(('%s',)*len(sub_ids), ',')
if d1:
- cr.execute('SELECT id FROM "'+self._table+'" ' \
- 'WHERE id IN ('+str_d+')'+d1, sub_ids+d2)
+ cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \
+ 'WHERE '+self._table+'.id IN ('+str_d+')'+d1, sub_ids+d2)
if not cr.rowcount == len(sub_ids):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule (Document type: %s).') % \
self._description)
- if d1:
- cr.execute('delete from "'+self._table+'" ' \
- 'where id in ('+str_d+')'+d1, sub_ids+d2)
- else:
- cr.execute('delete from "'+self._table+'" ' \
- 'where id in ('+str_d+')', sub_ids)
+ cr.execute('delete from '+self._table+' ' \
+ 'where id in ('+str_d+')', sub_ids)
for order, object, store_ids, fields in result_store:
if object<>self._name:
@@ -2708,7 +2702,7 @@ class orm(orm_template):
if len(upd0):
- d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name)
+ d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name)
if d1:
d1 = ' and '+d1
@@ -2716,8 +2710,8 @@ class orm(orm_template):
sub_ids = ids[i:i+cr.IN_MAX]
ids_str = string.join(map(str, sub_ids), ',')
if d1:
- cr.execute('SELECT id FROM "'+self._table+'" ' \
- 'WHERE id IN ('+ids_str+')'+d1, d2)
+ cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \
+ 'WHERE '+self._table+'.id IN ('+ids_str+')'+d1, d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule (Document type: %s).') % \
@@ -2728,12 +2722,8 @@ class orm(orm_template):
raise except_orm(_('AccessError'),
_('You try to write on an record that doesn\'t exist ' \
'(Document type: %s).') % self._description)
- if d1:
- cr.execute('update "'+self._table+'" set '+string.join(upd0, ',')+' ' \
- 'where id in ('+ids_str+')'+d1, upd1+ d2)
- else:
- cr.execute('update "'+self._table+'" set '+string.join(upd0, ',')+' ' \
- 'where id in ('+ids_str+')', upd1)
+ cr.execute('update '+self._table+' set '+string.join(upd0, ',')+' ' \
+ 'where id in ('+ids_str+')', upd1)
if totranslate:
# TODO: optimize
@@ -3161,8 +3151,8 @@ class orm(orm_template):
if not context:
context = {}
# compute the where, order by, limit and offset clauses
- (qu1, qu2, tables) = self._where_calc(cr, user, args, context=context)
-
+ dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name)
+ (qu1, qu2, tables) = self._where_calc(cr, user, args+dom, context=context)
if len(qu1):
qu1 = ' where '+string.join(qu1, ' and ')
else:
@@ -3176,12 +3166,6 @@ class orm(orm_template):
offset_str = offset and ' offset %d' % offset or ''
- # construct a clause for the rules :
- d1, d2 = self.pool.get('ir.rule').domain_get(cr, user, self._name)
- if d1:
- qu1 = qu1 and qu1+' and '+d1 or ' where '+d1
- qu2 += d2
-
if count:
cr.execute('select count(%s.id) from ' % self._table +
','.join(tables) +qu1 + limit_str + offset_str, qu2)
From 3cc2c44407ae116512016416b0847f9a01e33e2f Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 20:07:37 +0100
Subject: [PATCH 066/123] [IMP] multi-company fields
bzr revid: fp@tinyerp.com-20091222190737-gyye9ubuk5vrq8dj
---
addons/product/product.py | 4 ++--
addons/purchase/purchase.py | 4 ++--
addons/sale/sale.py | 4 ++--
addons/stock/stock.py | 16 ++++++++--------
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/addons/product/product.py b/addons/product/product.py
index 4ba7a5e8d1b..8fd23b5be9c 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -276,7 +276,7 @@ class product_template(osv.osv):
'loc_rack': fields.char('Rack', size=16),
'loc_row': fields.char('Row', size=16),
'loc_case': fields.char('Case', size=16),
- 'company_id': fields.many2one('res.company', 'Company'),
+ 'company_id': fields.many2one('res.company', 'Company',select=1),
}
def _get_uom_id(self, cr, uid, *args):
@@ -633,7 +633,7 @@ class product_supplierinfo(osv.osv):
'product_id' : fields.many2one('product.template', 'Product', required=True, ondelete='cascade', select=True),
'delay' : fields.integer('Delivery Delay', required=True, help="Delay in days between the confirmation of the purchase order and the reception of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning."),
'pricelist_ids': fields.one2many('pricelist.partnerinfo', 'suppinfo_id', 'Supplier Pricelist'),
- 'company_id':fields.many2one('res.company','Company'),
+ 'company_id':fields.many2one('res.company','Company',select=1),
}
_defaults = {
'qty': lambda *a: 0.0,
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 464421b5be7..3316b2f6d68 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -195,7 +195,7 @@ class purchase_order(osv.osv):
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'),
'product_id': fields.related('order_line','product_id', type='many2one', relation='product.product', string='Product'),
'create_uid': fields.many2one('res.users', 'Responsible'),
- 'company_id': fields.many2one('res.company','Company',required=True),
+ 'company_id': fields.many2one('res.company','Company',required=True,select=1),
}
_defaults = {
'date_order': lambda *a: time.strftime('%Y-%m-%d'),
@@ -456,7 +456,7 @@ class purchase_order_line(osv.osv):
'notes': fields.text('Notes'),
'order_id': fields.many2one('purchase.order', 'Order Ref', select=True, required=True, ondelete='cascade'),
'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account',),
- 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company',store=True)
+ 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company')
}
_defaults = {
'product_qty': lambda *a: 1.0
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 1be4b4a2477..c5a09c37f2b 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -254,7 +254,7 @@ class sale_order(osv.osv):
'invoice_quantity': fields.selection([('order', 'Ordered Quantities'), ('procurement', 'Shipped Quantities')], 'Invoice on', help="The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks.", required=True),
'payment_term': fields.many2one('account.payment.term', 'Payment Term'),
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'),
- 'company_id': fields.many2one('res.company','Company'),
+ 'company_id': fields.many2one('res.company','Company',select=1),
}
_defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'sale.order', c),
@@ -778,7 +778,7 @@ class sale_order_line(osv.osv):
'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled'), ('exception', 'Exception')], 'State', required=True, readonly=True),
'order_partner_id': fields.related('order_id', 'partner_id', type='many2one', relation='res.partner', string='Customer'),
'salesman_id':fields.related('order_id','user_id',type='many2one',relation='res.users',string='Salesman'),
- 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company',store=True),
+ 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company'),
}
_order = 'sequence, id'
_defaults = {
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index c6a4d51cbcb..0bdcb682db7 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -167,7 +167,7 @@ class stock_location(osv.osv):
'parent_right': fields.integer('Right Parent', select=1),
'stock_real_value': fields.function(_product_value, method=True, type='float', string='Real Stock Value', multi="stock"),
'stock_virtual_value': fields.function(_product_value, method=True, type='float', string='Virtual Stock Value', multi="stock"),
- 'company_id': fields.many2one('res.company', 'Company', required=True),
+ 'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
}
_defaults = {
'active': lambda *a: 1,
@@ -474,7 +474,7 @@ class stock_picking(osv.osv):
("2binvoiced", "To Be Invoiced"),
("none", "Not from Picking")], "Invoice Status",
select=True, required=True, readonly=True, states={'draft': [('readonly', False)]}),
- 'company_id': fields.many2one('res.company', 'Company', required=True),
+ 'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
}
_defaults = {
'name': lambda self, cr, uid, context: '/',
@@ -888,7 +888,7 @@ class stock_production_lot(osv.osv):
'date': fields.datetime('Created Date', required=True),
'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Available", select="2"),
'revisions': fields.one2many('stock.production.lot.revision', 'lot_id', 'Revisions'),
- 'company_id': fields.many2one('res.company','Company'),
+ 'company_id': fields.many2one('res.company','Company',select=1),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
@@ -912,7 +912,7 @@ class stock_production_lot_revision(osv.osv):
'indice': fields.char('Revision', size=16),
'author_id': fields.many2one('res.users', 'Author'),
'lot_id': fields.many2one('stock.production.lot', 'Production lot', select=True, ondelete='cascade'),
- 'company_id': fields.related('lot_id','company_id',type='many2one',relation='res.company',string='Company',store=True),
+ 'company_id': fields.related('lot_id','company_id',type='many2one',relation='res.company',string='Company'),
}
_defaults = {
@@ -1000,7 +1000,7 @@ class stock_move(osv.osv):
\nThe state is \'Waiting\' if the move is waiting for another one.'),
'price_unit': fields.float('Unit Price',
digits=(16, int(config['price_accuracy']))),
- 'company_id': fields.many2one('res.company', 'Company', required=True),
+ 'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
'partner_id': fields.related('picking_id','address_id','partner_id',type='many2one', relation="res.partner", string="Partner"),
'backorder_id': fields.related('picking_id','backorder_id',type='many2one', relation="stock.picking", string="Back Orders"),
'origin': fields.related('picking_id','origin',type='char', size=64, relation="stock.picking", string="Origin"),
@@ -1387,7 +1387,7 @@ class stock_inventory(osv.osv):
'inventory_line_id': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', readonly=True, states={'draft': [('readonly', False)]}),
'move_ids': fields.many2many('stock.move', 'stock_inventory_move_rel', 'inventory_id', 'move_id', 'Created Moves'),
'state': fields.selection( (('draft', 'Draft'), ('done', 'Done'), ('cancel','Cancelled')), 'State', readonly=True),
- 'company_id': fields.many2one('res.company','Company',required=True),
+ 'company_id': fields.many2one('res.company','Company',required=True,select=1),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
@@ -1460,7 +1460,7 @@ class stock_inventory_line(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_qty': fields.float('Quantity'),
- 'company_id': fields.related('inventory_id','company_id',type='many2one',relation='res.company',string='Company',store=True)
+ 'company_id': fields.related('inventory_id','company_id',type='many2one',relation='res.company',string='Company')
}
def on_change_product_id(self, cr, uid, ids, location_id, product, uom=False):
@@ -1485,7 +1485,7 @@ class stock_warehouse(osv.osv):
_columns = {
'name': fields.char('Name', size=60, required=True),
# 'partner_id': fields.many2one('res.partner', 'Owner'),
- 'company_id': fields.many2one('res.company','Company',required=True),
+ 'company_id': fields.many2one('res.company','Company',required=True,select=1),
'partner_address_id': fields.many2one('res.partner.address', 'Owner Address'),
'lot_input_id': fields.many2one('stock.location', 'Location Input', required=True),
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True),
From cb32d72dfa134e57c88742612c6c85bd13ee5797 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 21:56:00 +0100
Subject: [PATCH 067/123] [FIX] rule and multi-company
bzr revid: fp@tinyerp.com-20091222205600-3h0fow08pndm7y0f
---
bin/addons/base/ir/ir_rule.py | 7 +++---
bin/addons/base/res/partner/partner.py | 2 +-
bin/osv/expression.py | 30 ++++++++++++--------------
bin/osv/fields.py | 8 +++----
bin/osv/orm.py | 22 +++++++++++--------
5 files changed, 36 insertions(+), 33 deletions(-)
diff --git a/bin/addons/base/ir/ir_rule.py b/bin/addons/base/ir/ir_rule.py
index f096d53a93d..02b87a4a77f 100644
--- a/bin/addons/base/ir/ir_rule.py
+++ b/bin/addons/base/ir/ir_rule.py
@@ -137,7 +137,7 @@ class ir_rule(osv.osv):
if not (field_id or operator or operand):
return {}
- def domain_get2(self, cr, uid, model_name):
+ def domain_get2(self, cr, uid, model_name, context={}):
if uid == 1:
return []
@@ -155,8 +155,9 @@ class ir_rule(osv.osv):
for rule in self.browse(cr, uid, ids):
dom += rule.domain
return dom
- def domain_get(self, cr, uid, model_name):
- dom = self.domain_get2(cr, uid, model_name)
+
+ def domain_get(self, cr, uid, model_name, context={}):
+ dom = self.domain_get2(cr, uid, model_name, context=context)
d1,d2,tables = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
return ' and '.join(d1), d2, tables
domain_get = tools.cache()(domain_get)
diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py
index 39190d4df33..765eb86f686 100644
--- a/bin/addons/base/res/partner/partner.py
+++ b/bin/addons/base/res/partner/partner.py
@@ -151,7 +151,7 @@ class res_partner(osv.osv):
'supplier': fields.boolean('Supplier', help="Check this box if the partner is a supplier. If it's not checked, purchase people will not see it when encoding a purchase order."),
'city':fields.related('address','city',type='char', string='City'),
'country':fields.related('address','country_id',type='many2one', relation='res.country', string='Country'),
- 'company_id': fields.many2one('res.company', 'Company'),
+ 'company_id': fields.many2one('res.company', 'Company',select=1),
}
def _default_category(self, cr, uid, context={}):
diff --git a/bin/osv/expression.py b/bin/osv/expression.py
index 6dbe600fe0c..9b4b01d3fe9 100644
--- a/bin/osv/expression.py
+++ b/bin/osv/expression.py
@@ -145,25 +145,23 @@ class expression(object):
if field._type in ['many2many','one2many']:
right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context)
right1 = table.search(cr, uid, [(fargs[0],'in', right)], context=context)
- self.__exp[i] = ('id', 'in', right1)
-
+ self.__exp[i] = ('id', 'in', right1)
continue
- if field._properties:
+ if field._properties and not field.store:
# this is a function field
- if not field.store:
- if not field._fnct_search:
- # the function field doesn't provide a search function and doesn't store
- # values in the database, so we must ignore it : we generate a dummy leaf
- self.__exp[i] = self.__DUMMY_LEAF
- else:
- subexp = field.search(cr, uid, table, left, [self.__exp[i]])
- # we assume that the expression is valid
- # we create a dummy leaf for forcing the parsing of the resulting expression
- self.__exp[i] = '&'
- self.__exp.insert(i + 1, self.__DUMMY_LEAF)
- for j, se in enumerate(subexp):
- self.__exp.insert(i + 2 + j, se)
+ if not field._fnct_search:
+ # the function field doesn't provide a search function and doesn't store
+ # values in the database, so we must ignore it : we generate a dummy leaf
+ self.__exp[i] = self.__DUMMY_LEAF
+ else:
+ subexp = field.search(cr, uid, table, left, [self.__exp[i]])
+ # we assume that the expression is valid
+ # we create a dummy leaf for forcing the parsing of the resulting expression
+ self.__exp[i] = '&'
+ self.__exp.insert(i + 1, self.__DUMMY_LEAF)
+ for j, se in enumerate(subexp):
+ self.__exp.insert(i + 2 + j, se)
# else, the value of the field is store in the database, so we search on it
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index a8cf6e85b8d..8ecdd8eb407 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -506,7 +506,7 @@ class many2many(_column):
limit_str = self._limit is not None and ' limit %d' % self._limit or ''
obj = obj.pool.get(self._obj)
- d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
+ d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
d1 = ' and ' + d1
@@ -544,7 +544,7 @@ class many2many(_column):
cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%s', (id,))
elif act[0] == 6:
- d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
+ d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
d1 = ' and ' + d1
cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
@@ -741,7 +741,8 @@ class related(function):
if not ids: return {}
relation = obj._name
res = {}.fromkeys(ids, False)
- objlst = obj.browse(cr, uid, ids)
+
+ objlst = obj.browse(cr, uid, ids, context=context)
for data in objlst:
if not data:
continue
@@ -778,7 +779,6 @@ class related(function):
if res[r]:
res[r] = [x.id for x in res[r]]
-
return res
def __init__(self, *arg, **args):
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index d445e966bc9..ae27dcece2d 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -2375,7 +2375,7 @@ class orm(orm_template):
fields_to_read = self._columns.keys()
# construct a clause for the rules :
- d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, user, self._name)
+ d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
# all inherited fields + all non inherited fields for which the attribute whose name is in load is True
fields_pre = [f for f in fields_to_read if
@@ -2404,7 +2404,7 @@ class orm(orm_template):
self._order),[sub_ids,]+d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
- _('You try to bypass an access rule (Document type: %s).') % self._description)
+ _('You try to bypass an access rule while reading (Document type: %s).') % self._description)
else:
cr.execute('SELECT %s FROM \"%s\" WHERE id = ANY (%%s) ORDER BY %s' % \
(','.join(fields_pre2 + ['id']), self._table,
@@ -2586,7 +2586,7 @@ class orm(orm_template):
# ids2 = [x[self._inherits[key]] for x in res]
# self.pool.get(key).unlink(cr, uid, ids2)
- d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name)
+ d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, context=context)
if d1:
d1 = ' AND '+d1
@@ -2702,7 +2702,7 @@ class orm(orm_template):
if len(upd0):
- d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name)
+ d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
if d1:
d1 = ' and '+d1
@@ -2714,7 +2714,7 @@ class orm(orm_template):
'WHERE '+self._table+'.id IN ('+ids_str+')'+d1, d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
- _('You try to bypass an access rule (Document type: %s).') % \
+ _('You try to bypass an access rule while writing (Document type: %s).') % \
self._description)
else:
cr.execute('SELECT id FROM "'+self._table+'" WHERE id IN ('+ids_str+')')
@@ -3016,7 +3016,9 @@ class orm(orm_template):
continue
result.setdefault(fncts[fnct][0], {})
- ids2 = fncts[fnct][2](self,cr, uid, ids, context)
+
+ # uid == 1 for accessing objects having rules defined on store fields
+ ids2 = fncts[fnct][2](self,cr, 1, ids, context)
for id in filter(None, ids2):
result[fncts[fnct][0]].setdefault(id, [])
result[fncts[fnct][0]][id].append(fnct)
@@ -3065,7 +3067,8 @@ class orm(orm_template):
for key in keys:
val = todo[key]
if key:
- result = self._columns[val[0]].get(cr, self, ids, val, uid, context=context)
+ # uid == 1 for accessing objects having rules defined on store fields
+ result = self._columns[val[0]].get(cr, self, ids, val, 1, context=context)
for id,value in result.items():
if field_flag:
for f in value.keys():
@@ -3089,7 +3092,8 @@ class orm(orm_template):
else:
for f in val:
- result = self._columns[f].get(cr, self, ids, f, uid, context=context)
+ # uid == 1 for accessing objects having rules defined on store fields
+ result = self._columns[f].get(cr, self, ids, f, 1, context=context)
for r in result.keys():
if field_flag:
if r in field_dict.keys():
@@ -3151,7 +3155,7 @@ class orm(orm_template):
if not context:
context = {}
# compute the where, order by, limit and offset clauses
- dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name)
+ dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name, context=context)
(qu1, qu2, tables) = self._where_calc(cr, user, args+dom, context=context)
if len(qu1):
qu1 = ' where '+string.join(qu1, ' and ')
From 320e418660c1acb4f8777406f2945f810d725bcb Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 21:56:33 +0100
Subject: [PATCH 068/123] [FIX] added store=True on sale.order
bzr revid: fp@tinyerp.com-20091222205633-xzthswfavntuphky
---
addons/sale/sale.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index c5a09c37f2b..c81c6180d87 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -778,7 +778,7 @@ class sale_order_line(osv.osv):
'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled'), ('exception', 'Exception')], 'State', required=True, readonly=True),
'order_partner_id': fields.related('order_id', 'partner_id', type='many2one', relation='res.partner', string='Customer'),
'salesman_id':fields.related('order_id','user_id',type='many2one',relation='res.users',string='Salesman'),
- 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company'),
+ 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company',store=True),
}
_order = 'sequence, id'
_defaults = {
From 89be98debf3ff15b80dfc4231c7d2831e47c1da7 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:20:36 +0100
Subject: [PATCH 069/123] [FIX] multi company, speed improvement
bzr revid: fp@tinyerp.com-20091222212036-oeekt3f06k5j0ize
---
bin/addons/base/ir/ir_rule.py | 10 +++-------
bin/osv/orm.py | 22 +++++++++++++++-------
bin/sql_db.py | 1 -
3 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/bin/addons/base/ir/ir_rule.py b/bin/addons/base/ir/ir_rule.py
index 02b87a4a77f..6cd547c3d9f 100644
--- a/bin/addons/base/ir/ir_rule.py
+++ b/bin/addons/base/ir/ir_rule.py
@@ -137,9 +137,9 @@ class ir_rule(osv.osv):
if not (field_id or operator or operand):
return {}
- def domain_get2(self, cr, uid, model_name, context={}):
+ def domain_get(self, cr, uid, model_name, context={}):
if uid == 1:
- return []
+ return [], [], []
cr.execute("""SELECT r.id FROM
ir_rule r
@@ -154,12 +154,8 @@ class ir_rule(osv.osv):
dom = []
for rule in self.browse(cr, uid, ids):
dom += rule.domain
- return dom
-
- def domain_get(self, cr, uid, model_name, context={}):
- dom = self.domain_get2(cr, uid, model_name, context=context)
d1,d2,tables = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
- return ' and '.join(d1), d2, tables
+ return d1, d2, tables
domain_get = tools.cache()(domain_get)
def unlink(self, cr, uid, ids, context=None):
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index ae27dcece2d..94d8c23a045 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -2400,7 +2400,7 @@ class orm(orm_template):
sub_ids = ids[i:i+cr.IN_MAX]
if d1:
cr.execute('SELECT %s FROM %s WHERE %s.id = ANY (%%s) AND %s ORDER BY %s' % \
- (','.join(fields_pre2 + [self._table + '.id']), ','.join(tables), self._table, d1,
+ (','.join(fields_pre2 + [self._table + '.id']), ','.join(tables), self._table, ' and '.join(d1),
self._order),[sub_ids,]+d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
@@ -2588,14 +2588,14 @@ class orm(orm_template):
d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, context=context)
if d1:
- d1 = ' AND '+d1
+ d1 = ' AND '+' and '.join(d1)
for i in range(0, len(ids), cr.IN_MAX):
sub_ids = ids[i:i+cr.IN_MAX]
str_d = string.join(('%s',)*len(sub_ids), ',')
if d1:
cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \
- 'WHERE '+self._table+'.id IN ('+str_d+')'+d1, sub_ids+d2)
+ 'WHERE '+self._table+'.id IN ('+str_d+')'+' and '.join(d1), sub_ids+d2)
if not cr.rowcount == len(sub_ids):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule (Document type: %s).') % \
@@ -2704,14 +2704,14 @@ class orm(orm_template):
d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
if d1:
- d1 = ' and '+d1
+ d1 = ' and '+' and '.join(d1)
for i in range(0, len(ids), cr.IN_MAX):
sub_ids = ids[i:i+cr.IN_MAX]
ids_str = string.join(map(str, sub_ids), ',')
if d1:
cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \
- 'WHERE '+self._table+'.id IN ('+ids_str+')'+d1, d2)
+ 'WHERE '+self._table+'.id IN ('+ids_str+')'+' and '.join(d1), d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule while writing (Document type: %s).') % \
@@ -3155,13 +3155,21 @@ class orm(orm_template):
if not context:
context = {}
# compute the where, order by, limit and offset clauses
- dom = self.pool.get('ir.rule').domain_get2(cr, user, self._name, context=context)
- (qu1, qu2, tables) = self._where_calc(cr, user, args+dom, context=context)
+ (qu1, qu2, tables) = self._where_calc(cr, user, args, context=context)
+ dom = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
+ print '***', dom, qu1,qu2,tables
+ qu1 = qu1 + dom[0]
+ qu2 = qu2 + dom[1]
+ for t in dom[2]:
+ if t not in tables:
+ tables.append(t)
+
if len(qu1):
qu1 = ' where '+string.join(qu1, ' and ')
else:
qu1 = ''
+
if order:
self._check_qorder(order)
order_by = order or self._order
diff --git a/bin/sql_db.py b/bin/sql_db.py
index a84547b0b7c..b4ce8347f43 100644
--- a/bin/sql_db.py
+++ b/bin/sql_db.py
@@ -82,7 +82,6 @@ class Cursor(object):
self.sql_into_log = {}
self.sql_log = False
self.sql_log_count = 0
-
self.__closed = True # avoid the call of close() (by __del__) if an exception
# is raised by any of the following initialisations
self._pool = pool
From 99fe46f0cbcdce71bb9ce2bc0429a3c76cab7774 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:22:43 +0100
Subject: [PATCH 070/123] [FIX] multi company, speed improvement
bzr revid: fp@tinyerp.com-20091222212243-jptdo5hwmj3pah54
---
bin/osv/fields.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 8ecdd8eb407..432f5cde680 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -508,7 +508,7 @@ class many2many(_column):
d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
- d1 = ' and ' + d1
+ d1 = ' and ' + ' and '.join(d1)
cr.execute('SELECT '+self._rel+'.'+self._id2+','+self._rel+'.'+self._id1+' \
FROM '+self._rel+' , '+(','.join(tables))+' \
@@ -546,7 +546,7 @@ class many2many(_column):
d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
- d1 = ' and ' + d1
+ d1 = ' and ' + ' and '.join(d1)
cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
for act_nbr in act[2]:
From ac61176c3e4a6c3582993065963a00325084407e Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:24:26 +0100
Subject: [PATCH 071/123] [FIX] multi company, speed improvement
bzr revid: fp@tinyerp.com-20091222212426-z7gmxxj356hgjvvh
---
bin/osv/fields.py | 3 +++
bin/osv/orm.py | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 432f5cde680..2c7378ea6a1 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -509,6 +509,7 @@ class many2many(_column):
d1, d2, tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
d1 = ' and ' + ' and '.join(d1)
+ else: d1 = ''
cr.execute('SELECT '+self._rel+'.'+self._id2+','+self._rel+'.'+self._id1+' \
FROM '+self._rel+' , '+(','.join(tables))+' \
@@ -547,6 +548,8 @@ class many2many(_column):
d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
if d1:
d1 = ' and ' + ' and '.join(d1)
+ else:
+ d1 = ''
cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
for act_nbr in act[2]:
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 94d8c23a045..9d8313eebf0 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -3157,7 +3157,6 @@ class orm(orm_template):
# compute the where, order by, limit and offset clauses
(qu1, qu2, tables) = self._where_calc(cr, user, args, context=context)
dom = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
- print '***', dom, qu1,qu2,tables
qu1 = qu1 + dom[0]
qu2 = qu2 + dom[1]
for t in dom[2]:
From 03624bd6e002e856f60595eb663cc366f00b5f43 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:28:07 +0100
Subject: [PATCH 072/123] [FIX] bugfix
bzr revid: fp@tinyerp.com-20091222212807-2p2q39aaqvnihldo
---
bin/addons/base/ir/ir_rule.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/addons/base/ir/ir_rule.py b/bin/addons/base/ir/ir_rule.py
index 6cd547c3d9f..99ba68168b9 100644
--- a/bin/addons/base/ir/ir_rule.py
+++ b/bin/addons/base/ir/ir_rule.py
@@ -139,7 +139,7 @@ class ir_rule(osv.osv):
def domain_get(self, cr, uid, model_name, context={}):
if uid == 1:
- return [], [], []
+ return [], [], ['"'+self.pool.get(model_name)._table+'"']
cr.execute("""SELECT r.id FROM
ir_rule r
From 2066752cd337d55e8862acbb15a39dc95e67f310 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:33:25 +0100
Subject: [PATCH 073/123] [FIX] fix
bzr revid: fp@tinyerp.com-20091222213325-ar920r2repylm27c
---
bin/osv/orm.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 9d8313eebf0..8a1bc6ab877 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -2595,7 +2595,7 @@ class orm(orm_template):
str_d = string.join(('%s',)*len(sub_ids), ',')
if d1:
cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \
- 'WHERE '+self._table+'.id IN ('+str_d+')'+' and '.join(d1), sub_ids+d2)
+ 'WHERE '+self._table+'.id IN ('+str_d+')'+d1, sub_ids+d2)
if not cr.rowcount == len(sub_ids):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule (Document type: %s).') % \
@@ -2703,6 +2703,7 @@ class orm(orm_template):
if len(upd0):
d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
+ print d1,d2
if d1:
d1 = ' and '+' and '.join(d1)
@@ -2711,7 +2712,7 @@ class orm(orm_template):
ids_str = string.join(map(str, sub_ids), ',')
if d1:
cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \
- 'WHERE '+self._table+'.id IN ('+ids_str+')'+' and '.join(d1), d2)
+ 'WHERE '+self._table+'.id IN ('+ids_str+')'+d1, d2)
if not cr.rowcount == len({}.fromkeys(sub_ids)):
raise except_orm(_('AccessError'),
_('You try to bypass an access rule while writing (Document type: %s).') % \
From d3b9efd21a394fb4dea0279727775b3e474361af Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:36:56 +0100
Subject: [PATCH 074/123] [FIX] removed print statement
bzr revid: fp@tinyerp.com-20091222213656-c1scjz1yyglhup8u
---
bin/osv/orm.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index 8a1bc6ab877..f1c36026c32 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -2703,7 +2703,6 @@ class orm(orm_template):
if len(upd0):
d1, d2,tables = self.pool.get('ir.rule').domain_get(cr, user, self._name, context=context)
- print d1,d2
if d1:
d1 = ' and '+' and '.join(d1)
From a05e83688113ab49dc7ed5e1d50113c26a0b5b06 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 22:40:21 +0100
Subject: [PATCH 075/123] [FIX] put store=True on company_id related
bzr revid: fp@tinyerp.com-20091222214021-7dkq442rwzbt04qx
---
addons/account/account.py | 1 -
addons/product/product_view.xml | 1 -
addons/stock/stock.py | 4 ++--
3 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/addons/account/account.py b/addons/account/account.py
index 549f257b124..e044b292ee1 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -479,7 +479,6 @@ class account_journal(osv.osv):
'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
'entry_posted': fields.boolean('Skip \'Draft\' State for Created Entries', help='Check this box if you don\'t want new account moves to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation.'),
- #'company_id': fields.related('default_credit_account_id','company_id',type='many2one', relation="res.company", string="Company",store=True),
'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
'invoice_sequence_id': fields.many2one('ir.sequence', 'Invoice Sequence', \
help="The sequence used for invoice numbers in this journal."),
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index fe0a3035a61..81a7cfb7c90 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -43,7 +43,6 @@
-
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 0bdcb682db7..e1ee06ec3ce 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -912,7 +912,7 @@ class stock_production_lot_revision(osv.osv):
'indice': fields.char('Revision', size=16),
'author_id': fields.many2one('res.users', 'Author'),
'lot_id': fields.many2one('stock.production.lot', 'Production lot', select=True, ondelete='cascade'),
- 'company_id': fields.related('lot_id','company_id',type='many2one',relation='res.company',string='Company'),
+ 'company_id': fields.related('lot_id','company_id',type='many2one',relation='res.company',string='Company',store=True),
}
_defaults = {
@@ -1460,7 +1460,7 @@ class stock_inventory_line(osv.osv):
'product_id': fields.many2one('product.product', 'Product', required=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_qty': fields.float('Quantity'),
- 'company_id': fields.related('inventory_id','company_id',type='many2one',relation='res.company',string='Company')
+ 'company_id': fields.related('inventory_id','company_id',type='many2one',relation='res.company',string='Company',store=True)
}
def on_change_product_id(self, cr, uid, ids, location_id, product, uom=False):
From e4656b1f76749a864be39d5842f290de72729d21 Mon Sep 17 00:00:00 2001
From: Fabien Pinckaers
Date: Tue, 22 Dec 2009 23:49:51 +0100
Subject: [PATCH 076/123] [FIX] for sebastien syleam
bzr revid: fp@tinyerp.com-20091222224951-nxox7h4vdc9c5qzn
---
addons/account_tax_include/invoice_tax_incl.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/account_tax_include/invoice_tax_incl.py b/addons/account_tax_include/invoice_tax_incl.py
index dde3bed2566..ec0309aa2f4 100644
--- a/addons/account_tax_include/invoice_tax_incl.py
+++ b/addons/account_tax_include/invoice_tax_incl.py
@@ -170,7 +170,7 @@ class account_invoice_tax(osv.osv):
val={}
val['invoice_id'] = inv.id
val['name'] = tax['name']
- val['amount'] = cur_obj.round(cr, uid, cur, tax['amount'])
+ val['amount'] = tax['amount']
val['manual'] = False
val['sequence'] = tax['sequence']
val['base'] = tax['price_unit'] * line['quantity']
From d8f91951f91d69be8ea121634205ef1bb7ff6eb8 Mon Sep 17 00:00:00 2001
From: "Nch (OpenERP)" <>
Date: Wed, 23 Dec 2009 11:10:05 +0530
Subject: [PATCH 077/123] [FIX] quality_integration_server: if db exits, first
drop db on create db command
bzr revid: hmo@tinyerp.com-20091223054005-b70d4cupfeomi1ht
---
.../base_quality_interrogation.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/bin/addons/quality_integration_server/base_quality_interrogation.py b/bin/addons/quality_integration_server/base_quality_interrogation.py
index 8806ff0e2b9..96c04e72ca6 100755
--- a/bin/addons/quality_integration_server/base_quality_interrogation.py
+++ b/bin/addons/quality_integration_server/base_quality_interrogation.py
@@ -171,9 +171,10 @@ def create_db(uri, dbname, user='admin', pwd='admin', lang='en_US'):
wiz_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
login_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/common')
db_list = execute(conn, 'list')
- if dbname not in db_list:
- id = execute(conn,'create',admin_passwd, dbname, True, lang)
- wait(id,uri)
+ if dbname in db_list:
+ drop_db(uri, dbname)
+ id = execute(conn,'create',admin_passwd, dbname, True, lang)
+ wait(id,uri)
uid = login_conn.login(dbname, user, pwd)
wiz_id = execute(wiz_conn,'create', dbname, uid, user, 'base_setup.base_setup')
From 7b898aabfc0b3f2d1ccdf9796cd7eb6c084a4d19 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Wed, 23 Dec 2009 11:17:42 +0530
Subject: [PATCH 078/123] [REF]: crm, project_calendar: Removed function to get
ID and used function imported from caldav module
bzr revid: rpa@tinyerp.com-20091223054742-0q9t7f2qlwp7etbt
---
addons/crm/crm_calendar.py | 34 +++++++++------------
addons/project_calendar/project_calendar.py | 25 ++++++---------
2 files changed, 25 insertions(+), 34 deletions(-)
diff --git a/addons/crm/crm_calendar.py b/addons/crm/crm_calendar.py
index 98fef31c6e9..849dc93d3b7 100644
--- a/addons/crm/crm_calendar.py
+++ b/addons/crm/crm_calendar.py
@@ -19,6 +19,7 @@
#
##############################################################################
+from caldav import common
from dateutil.rrule import *
from osv import fields, osv
import datetime
@@ -27,13 +28,6 @@ import re
import time
import tools
-def caldevIDs2readIDs(caldev_ID = None):
- if caldev_ID:
- if isinstance(caldev_ID, str):
- return int(caldev_ID.split('-')[0])
- return caldev_ID
-
-
class crm_case(osv.osv):
_name = 'crm.case'
_inherit = 'crm.case'
@@ -60,7 +54,7 @@ class crm_case(osv.osv):
# 'attach' : {'field':'attachment_ids', 'sub-field':'datas', 'type':'list'},
'attendee' : {'field':'attendees', 'type':'many2many', 'object' : 'crm.caldav.attendee'},
# 'categories' : {'field':'categ_id', 'sub-field':'name'},
-# 'categories' : {'field':None , 'sub-field':'name', 'type':'text'}, # keep none for now
+# 'categories' : {'field':None , 'sub-field':'name', 'type':'text'},
'comment' : None,
'contact' : None,
'exdate' : {'field':'exdate', 'type':'datetime'},
@@ -109,7 +103,8 @@ class crm_case(osv.osv):
'location' : fields.function(_get_location, method=True, store=True, \
string='Location', type='text'),
'freebusy' : fields.text('FreeBusy'),
- 'transparent' : fields.selection([('OPAQUE', 'OPAQUE'), ('TRANSPARENT', 'TRANSPARENT')], 'Trensparent'),
+ 'transparent' : fields.selection([('TRANSPARENT', 'TRANSPARENT'), \
+ ('OPAQUE', 'OPAQUE')], 'Trensparent'),
'caldav_url' : fields.char('Caldav URL', size=34),
'exdate' : fields.text('Exception Date/Times', help="This property defines the list\
of date/time exceptions for arecurring calendar component."),
@@ -222,17 +217,17 @@ class crm_case(osv.osv):
def write(self, cr, uid, ids, vals, context=None):
new_ids = []
for id in ids:
- id = caldevIDs2readIDs(id)
+ id = common.caldevIDs2readIDs(id)
if not id in new_ids:
new_ids.append(id)
if 'case_id' in vals :
- vals['case_id'] = caldevIDs2readIDs(vals['case_id'])
+ vals['case_id'] = common.caldevIDs2readIDs(vals['case_id'])
res = super(crm_case, self).write(cr, uid, new_ids, vals, context=context)
return res
def browse(self, cr, uid, select, context=None, list_class=None, fields_process={}):
if not isinstance(select, list): select = [select]
- select = map(lambda x:caldevIDs2readIDs(x), select)
+ select = map(lambda x:common.caldevIDs2readIDs(x), select)
return super(crm_case, self).browse(cr, uid, select, context, list_class, fields_process)
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
@@ -243,10 +238,10 @@ class crm_case(osv.osv):
load=load)
if not type(ids) == list :
# Called from code
- return super(crm_case, self).read(cr, uid, caldevIDs2readIDs(ids), fields=fields, \
- context=context, load=load)
+ return super(crm_case, self).read(cr, uid, common.caldevIDs2readIDs(ids), \
+ fields=fields, context=context, load=load)
else:
- ids = map(lambda x:caldevIDs2readIDs(x), ids)
+ ids = map(lambda x:common.caldevIDs2readIDs(x), ids)
res = super(crm_case, self).read(cr, uid, ids, fields=fields, context=context, load=load)
read_ids = ",".join([str(x) for x in ids])
if not read_ids:
@@ -276,7 +271,8 @@ class crm_case(osv.osv):
return result
def copy(self, cr, uid, id, default=None, context={}):
- return super(crm_case, self).copy(cr, uid, caldevIDs2readIDs(id), default, context)
+ return super(crm_case, self).copy(cr, uid, common.caldevIDs2readIDs(id), \
+ default, context)
def unlink(self, cr, uid, ids, context=None):
#TODO: Change RRULE
@@ -284,18 +280,18 @@ class crm_case(osv.osv):
if len(str(id).split('-')) > 1:
date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
- for record in self.read(cr, uid, [caldevIDs2readIDs(id)], \
+ for record in self.read(cr, uid, [common.caldevIDs2readIDs(id)], \
['date', 'rdates', 'rrule', 'exdate']):
exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
''.join((re.compile('\d')).findall(date_new)) + 'Z'
if record['date'] == date_new:
- self.write(cr, uid, [caldevIDs2readIDs(id)], {'exdate' : exdate})
+ self.write(cr, uid, [common.caldevIDs2readIDs(id)], {'exdate' : exdate})
else:
return super(crm_case, self).unlink(cr, uid, ids)
def create(self, cr, uid, vals, context={}):
if 'case_id' in vals:
- vals['case_id'] = caldevIDs2readIDs(vals['case_id'])
+ vals['case_id'] = common.caldevIDs2readIDs(vals['case_id'])
return super(crm_case, self).create(cr, uid, vals, context)
crm_case()
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
index 8e7b3852bec..df4785b66f2 100644
--- a/addons/project_calendar/project_calendar.py
+++ b/addons/project_calendar/project_calendar.py
@@ -19,18 +19,13 @@
#
##############################################################################
+from caldav import common
from datetime import datetime
from osv import fields, osv
from service import web_services
import base64
-import time
import re
-
-def caldevIDs2readIDs(caldev_ID = None):
- if caldev_ID:
- if isinstance(caldev_ID, str):
- return int(caldev_ID.split('-')[0])
- return caldev_ID
+import time
class project_task(osv.osv):
_inherit = "project.task"
@@ -155,10 +150,10 @@ class project_task(osv.osv):
return super(project_task, self).read(cr, uid, ids, fields, context, load)
if not type(ids) == list :
# Called from code
- return super(project_task, self).read(cr, uid, caldevIDs2readIDs(ids),\
+ return super(project_task, self).read(cr, uid, common.caldevIDs2readIDs(ids),\
fields=fields, context=context, load=load)
else:
- ids = map(lambda x:caldevIDs2readIDs(x), ids)
+ ids = map(lambda x:common.caldevIDs2readIDs(x), ids)
res = super(project_task, self).read(cr, uid, ids, fields=fields, context=context, load=load)
read_ids = ",".join([str(x) for x in ids])
if not read_ids:
@@ -195,7 +190,7 @@ class project_task(osv.osv):
def write(self, cr, uid, ids, vals, context=None):
new_ids = []
for id in ids:
- id = caldevIDs2readIDs(id)
+ id = common.caldevIDs2readIDs(id)
if not id in new_ids:
new_ids.append(id)
res = super(project_task, self).write(cr, uid, new_ids, vals, context=context)
@@ -203,11 +198,11 @@ class project_task(osv.osv):
def browse(self, cr, uid, select, context=None, list_class=None, fields_process={}):
if not isinstance(select, list): select = [select]
- select = map(lambda x:caldevIDs2readIDs(x), select)
+ select = map(lambda x:common.caldevIDs2readIDs(x), select)
return super(project_task, self).browse(cr, uid, select, context, list_class, fields_process)
def copy(self, cr, uid, id, default=None, context={}):
- return super(project_task, self).copy(cr, uid, caldevIDs2readIDs(id), default, context)
+ return super(project_task, self).copy(cr, uid, common.caldevIDs2readIDs(id), default, context)
def unlink(self, cr, uid, ids, context=None):
#TODO: Change RRULE
@@ -215,18 +210,18 @@ class project_task(osv.osv):
if len(str(id).split('-')) > 1:
date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
- for record in self.read(cr, uid, [caldevIDs2readIDs(id)], \
+ for record in self.read(cr, uid, [common.caldevIDs2readIDs(id)], \
['date', 'rdates', 'rrule', 'exdate']):
exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
''.join((re.compile('\d')).findall(date_new)) + 'Z'
if record['date_start'] == date_new:
- self.write(cr, uid, [caldevIDs2readIDs(id)], {'exdate' : exdate})
+ self.write(cr, uid, [common.caldevIDs2readIDs(id)], {'exdate' : exdate})
else:
return super(project_task, self).unlink(cr, uid, ids)
def create(self, cr, uid, vals, context={}):
if 'case_id' in vals:
- vals['case_id'] = caldevIDs2readIDs(vals['case_id'])
+ vals['case_id'] = common.caldevIDs2readIDs(vals['case_id'])
return super(project_task, self).create(cr, uid, vals, context)
project_task()
From 125cccc07e9c1acecb75d90e922fcd3d3fdce0d4 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Wed, 23 Dec 2009 11:32:37 +0530
Subject: [PATCH 079/123] [IMP]: crm, project_calendar: Improvement in export
wizard, Added field name for file name
bzr revid: rpa@tinyerp.com-20091223060237-y0f572eyoud1vi0q
---
addons/crm/wizard/wizard_cal_export.py | 17 ++++++++++-----
.../wizard/wizard_cal_export.py | 21 ++++++++++++-------
2 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/addons/crm/wizard/wizard_cal_export.py b/addons/crm/wizard/wizard_cal_export.py
index 08e9de56945..a166e55f292 100644
--- a/addons/crm/wizard/wizard_cal_export.py
+++ b/addons/crm/wizard/wizard_cal_export.py
@@ -27,23 +27,30 @@ import pooler
class crm_cal_export_wizard(wizard.interface):
form1 = '''
'''
form1_fields = {
'file_path': {
- 'string': 'Select ICS file',
+ 'string': 'Save ICS file',
'type': 'binary',
'required' : True,
'filters' : '*.ics'
- }
+ },
+ 'name': {
+ 'string': 'File name',
+ 'type': 'char',
+ 'size': 34,
+ 'required': True,
+ 'help': 'Save in .ics format'},
}
def _process_export_ics(self, cr, uid, data, context):
case_obj = pooler.get_pool(cr.dbname).get('crm.case')
calendar = case_obj.export_cal(cr, uid, data['ids'], context)
- return {'file_path': base64.encodestring(calendar)}
+ return {'file_path': base64.encodestring(calendar), \
+ 'name': 'OpenERP Events.ics'}
states = {
'init': {
diff --git a/addons/project_calendar/wizard/wizard_cal_export.py b/addons/project_calendar/wizard/wizard_cal_export.py
index 430654d90f6..d8e70ca83fc 100644
--- a/addons/project_calendar/wizard/wizard_cal_export.py
+++ b/addons/project_calendar/wizard/wizard_cal_export.py
@@ -27,23 +27,30 @@ import pooler
class project_cal_export_wizard(wizard.interface):
form1 = '''
'''
form1_fields = {
'file_path': {
- 'string': 'Select ICS file',
+ 'string': 'Save ICS file',
'type': 'binary',
- 'required': True,
- 'filters': '*.ics'
- }
+ 'required' : True,
+ 'filters' : '*.ics'
+ },
+ 'name': {
+ 'string': 'File name',
+ 'type': 'char',
+ 'size': 34,
+ 'required': True,
+ 'help': 'Save in .ics format'},
}
def _process_export_ics(self, cr, uid, data, context):
task_obj = pooler.get_pool(cr.dbname).get('project.task')
calendar = task_obj.export_cal(cr, uid, data['ids'], context)
- return {'file_path': base64.encodestring(calendar)}
+ return {'file_path': base64.encodestring(calendar), \
+ 'name': 'OpenERP Tasks.ics'}
states = {
'init': {
From f0d67e836949113e0bab499ab731494af5c5ba5f Mon Sep 17 00:00:00 2001
From: "Jay (Open ERP)"
Date: Wed, 23 Dec 2009 12:16:55 +0530
Subject: [PATCH 080/123] [FIX] Integer widget : improvements when functional
integer field returns big value
lp bug: https://launchpad.net/bugs/416821 fixed
bzr revid: jvo@tinyerp.com-20091223064655-ssk404pl46271rdj
---
bin/osv/fields.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 2c7378ea6a1..f56f700596c 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -679,6 +679,10 @@ class function(_column):
if self._type == 'binary' and context.get('bin_size', False):
# convert the data returned by the function with the size of that data...
res = dict(map( get_nice_size, res.items()))
+ if self._type == "integer":
+ for r in res.keys():
+ # Converting value into string so that it does not affect XML-RPC Limits
+ res[r] = str(res[r])
return res
get_memory = get
From 1502dc1224a4b3b859dde011bcf6ed8834ebf606 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Wed, 23 Dec 2009 12:30:48 +0530
Subject: [PATCH 081/123] [IMP]: crm, project_calendar: Improvement in read
method for providing virtual id in event/task , Fixed problem of unlink
event/task without rrule
bzr revid: rpa@tinyerp.com-20091223070048-fj59ktb5odiz0byh
---
addons/crm/crm_calendar.py | 23 ++++++++++++++++----
addons/project_calendar/project_calendar.py | 24 ++++++++++++++++-----
2 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/addons/crm/crm_calendar.py b/addons/crm/crm_calendar.py
index 849dc93d3b7..ad2979abcf2 100644
--- a/addons/crm/crm_calendar.py
+++ b/addons/crm/crm_calendar.py
@@ -242,6 +242,7 @@ class crm_case(osv.osv):
fields=fields, context=context, load=load)
else:
ids = map(lambda x:common.caldevIDs2readIDs(x), ids)
+ fields.append('date')
res = super(crm_case, self).read(cr, uid, ids, fields=fields, context=context, load=load)
read_ids = ",".join([str(x) for x in ids])
if not read_ids:
@@ -250,6 +251,11 @@ class crm_case(osv.osv):
rrules = filter(lambda x: not x['rrule']==None, cr.dictfetchall())
rdates = []
if not rrules:
+ for ress in res:
+ strdate = ''.join((re.compile('\d')).findall(ress['date']))
+ idval = str(ress['id']) + '-' + strdate
+ idval = str(common.caldevIDs2readIDs(ress['id'])) + '-' + strdate
+ ress['id'] = idval
return res
result = res + []
for data in rrules:
@@ -260,6 +266,11 @@ class crm_case(osv.osv):
val = res_temp
if rdates:
result.remove(val)
+ else:
+ strdate = ''.join((re.compile('\d')).findall(res_temp['date']))
+ idval = str(res_temp['id']) + '-' + strdate
+ idval = str(common.caldevIDs2readIDs(res_temp['id'])) + '-' + strdate
+ res_temp['id'] = idval
for rdate in rdates:
idval = (re.compile('\d')).findall(rdate)
@@ -282,10 +293,14 @@ class crm_case(osv.osv):
time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
for record in self.read(cr, uid, [common.caldevIDs2readIDs(id)], \
['date', 'rdates', 'rrule', 'exdate']):
- exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
- ''.join((re.compile('\d')).findall(date_new)) + 'Z'
- if record['date'] == date_new:
- self.write(cr, uid, [common.caldevIDs2readIDs(id)], {'exdate' : exdate})
+ if record['rrule']:
+ exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
+ ''.join((re.compile('\d')).findall(date_new)) + 'Z'
+ if record['date'] == date_new:
+ self.write(cr, uid, [common.caldevIDs2readIDs(id)], {'exdate' : exdate})
+ else:
+ ids = map(lambda x:common.caldevIDs2readIDs(x), ids)
+ return super(crm_case, self).unlink(cr, uid, common.caldevIDs2readIDs(ids))
else:
return super(crm_case, self).unlink(cr, uid, ids)
diff --git a/addons/project_calendar/project_calendar.py b/addons/project_calendar/project_calendar.py
index df4785b66f2..c25cb2aaed9 100644
--- a/addons/project_calendar/project_calendar.py
+++ b/addons/project_calendar/project_calendar.py
@@ -154,6 +154,7 @@ class project_task(osv.osv):
fields=fields, context=context, load=load)
else:
ids = map(lambda x:common.caldevIDs2readIDs(x), ids)
+ fields.append('date_start')
res = super(project_task, self).read(cr, uid, ids, fields=fields, context=context, load=load)
read_ids = ",".join([str(x) for x in ids])
if not read_ids:
@@ -162,6 +163,11 @@ class project_task(osv.osv):
rrules = filter(lambda x: not x['rrule']==None, cr.dictfetchall())
rdates = []
if not rrules:
+ for ress in res:
+ strdate = ''.join((re.compile('\d')).findall(ress['date_start']))
+ idval = str(ress['id']) + '-' + strdate
+ idval = str(common.caldevIDs2readIDs(ress['id'])) + '-' + strdate
+ ress['id'] = idval
return res
result = res + []
for data in rrules:
@@ -172,7 +178,11 @@ class project_task(osv.osv):
val = res_temp
if rdates:
result.remove(val)
-
+ else:
+ strdate = ''.join((re.compile('\d')).findall(res_temp['date_start']))
+ idval = str(res_temp['id']) + '-' + strdate
+ res_temp['id'] = idval
+
for rdate in rdates:
idval = (re.compile('\d')).findall(rdate)
val['date_start'] = rdate
@@ -212,10 +222,14 @@ class project_task(osv.osv):
time.strptime(str(str(id).split('-')[1]), "%Y%m%d%H%M%S"))
for record in self.read(cr, uid, [common.caldevIDs2readIDs(id)], \
['date', 'rdates', 'rrule', 'exdate']):
- exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
- ''.join((re.compile('\d')).findall(date_new)) + 'Z'
- if record['date_start'] == date_new:
- self.write(cr, uid, [common.caldevIDs2readIDs(id)], {'exdate' : exdate})
+ if record['rrule']:
+ exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
+ ''.join((re.compile('\d')).findall(date_new)) + 'Z'
+ if record['date_start'] == date_new:
+ self.write(cr, uid, [common.caldevIDs2readIDs(id)], {'exdate' : exdate})
+ else:
+ ids = map(lambda x:common.caldevIDs2readIDs(x), ids)
+ return super(project_task, self).unlink(cr, uid, ids)
else:
return super(project_task, self).unlink(cr, uid, ids)
From 1b1772e2048b99c56b0cc973a0fe436544daced3 Mon Sep 17 00:00:00 2001
From: "rpa (Open ERP)"
Date: Wed, 23 Dec 2009 15:24:04 +0530
Subject: [PATCH 082/123] [IMP]: Caldav: Improvement in code, added help text
in attendee and alarm object
bzr revid: rpa@tinyerp.com-20091223095404-ihojnyyrhfh2pcxc
---
addons/caldav/calendar.py | 23 ++++++----------
addons/caldav/common.py | 55 ++++++++++++++++++++++++---------------
2 files changed, 42 insertions(+), 36 deletions(-)
diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py
index 2e671ddedf1..f0a2eaec2b6 100644
--- a/addons/caldav/calendar.py
+++ b/addons/caldav/calendar.py
@@ -22,12 +22,8 @@
from datetime import datetime, timedelta
from dateutil import parser
from dateutil.rrule import *
-from osv import fields, osv
-from pytz import timezone
-from time import strftime
-import base64
+from osv import osv
import re
-import time
import vobject
# O-1 Optional and can come only once
@@ -81,13 +77,12 @@ class CalDAV(object):
for date in exdate:
datetime_obj = todate(date)
rset1._exdate.append(datetime_obj)
- re_dates = rset1._iter()
- recurrent_dates = map(lambda x:x.strftime('%Y-%m-%d %H:%M:%S'), re_dates)
- return recurrent_dates
+ re_dates = map(lambda x:x.strftime('%Y-%m-%d %H:%M:%S'), rset1._iter())
+ return re_dates
def ical_set(self, name, value, type):
if name in self.__attribute__ and self.__attribute__[name]:
- self.__attribute__[name][type] = value
+ self.__attribute__[name][type] = value
return True
def ical_get(self, name, type):
@@ -104,7 +99,7 @@ class CalDAV(object):
val = int(val)
return val
else:
- return self.__attribute__.get(name, None)
+ return self.__attribute__.get(name, None)
def ical_reset(self, type):
for name in self.__attribute__:
@@ -297,10 +292,8 @@ class Timezone(CalDAV):
'tzid': None, # Use: R-1, Type: Text, Specifies the text value that uniquely identifies the "VTIMEZONE" calendar component.
'last-mod': None, # Use: O-1, Type: DATE-TIME, Specifies the date and time that the information associated with the calendar component was last revised in the calendar store.
'tzurl': None, # Use: O-1, Type: URI, Provides a means for a VTIMEZONE component to point to a network location that can be used to retrieve an up-to-date version of itself.
- 'standardc': # Use: R-n,
- {'tzprop': None, }, # Use: R-1,
- 'daylightc': # Use: R-n, Type: Text,
- {'tzprop': None, }, # Use: R-1,
+ 'standardc': {'tzprop': None}, # Use: R-1,
+ 'daylightc': {'tzprop': None}, # Use: R-1,
'x-prop': None, # Use: O-n, Type: Text,
}
@@ -419,4 +412,4 @@ class Attendee(CalDAV, osv.osv_memory):
Attendee()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/caldav/common.py b/addons/caldav/common.py
index cbf9bedecd4..c5dae055561 100644
--- a/addons/caldav/common.py
+++ b/addons/caldav/common.py
@@ -51,22 +51,29 @@ class crm_caldav_attendee(osv.osv):
_columns = {
'cutype': fields.selection([('INDIVIDUAL', 'INDIVIDUAL'), ('GROUP', 'GROUP'), \
('RESOURCE', 'RESOURCE'), ('ROOM', 'ROOM'), \
- ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE'),
- 'member': fields.char('Member', size=124),
+ ('UNKNOWN', 'UNKNOWN') ], 'CUTYPE', \
+ help="Specify the type of calendar user"),
+ 'member': fields.char('Member', size=124, help="Indicate the groups that the attendee belongs to"),
'role': fields.selection([ ('REQ-PARTICIPANT', 'REQ-PARTICIPANT'), \
('CHAIR', 'CHAIR'), ('OPT-PARTICIPANT', 'OPT-PARTICIPANT'), \
- ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE'),
- 'partstat': fields.selection([('NEEDS-ACTION', 'NEEDS-ACTION'), \
- ('ACCEPTED', 'ACCEPTED'), ('DECLINED', 'DECLINED'), \
- ('TENTATIVE', 'TENTATIVE'), \
- ('DELEGATED', 'DELEGATED')], 'PARTSTAT'),
- 'rsvp': fields.boolean('RSVP'),
- 'delegated_to': fields.char('DELEGATED-TO', size=124),
- 'delegated_from': fields.char('DELEGATED-FROM', size=124),
- 'sent_by': fields.char('SENT-BY', size=124),
- 'cn': fields.char('CN', size=124),
- 'dir': fields.char('DIR', size=124),
- 'language': fields.char('LANGUAGE', size=124),
+ ('NON-PARTICIPANT', 'NON-PARTICIPANT')], 'ROLE', \
+ help='Participation role for the calendar user'),
+ 'partstat': fields.selection([('TENTATIVE', 'TENTATIVE'),
+ ('NEEDS-ACTION', 'NEEDS-ACTION'),
+ ('ACCEPTED', 'ACCEPTED'),
+ ('DECLINED', 'DECLINED'),
+ ('DELEGATED', 'DELEGATED')], 'PARTSTAT', \
+ help="Status of the attendee's participation"),
+ 'rsvp': fields.boolean('RSVP', help="Indicats whether the favor of a reply is requested"),
+ 'delegated_to': fields.char('DELEGATED-TO', size=124, \
+ help="The calendar users that the original request was delegated to"),
+ 'delegated_from': fields.char('DELEGATED-FROM', size=124, \
+ help="Indicates whom the request was delegated from"),
+ 'sent_by': fields.char('SENT-BY', size=124, \
+ help="Specify the calendar user that is acting on behalf of the calendar user"),
+ 'cn': fields.char('CN', size=124, help="The common or displayable name to be associated with the calendar user"),
+ 'dir': fields.char('DIR', size=124, help="Reference to the URI that points to the directory information corresponding to the attendee."),
+ 'language': fields.char('LANGUAGE', size=124, help="To specify the language for text values in a property or property parameter."),
}
_defaults = {
'cn': lambda *x: 'MAILTO:',
@@ -93,22 +100,28 @@ class crm_caldav_alarm(osv.osv):
}
_columns = {
- 'name': fields.char('Summary', size=124),
+ 'name': fields.char('Summary', size=124, help="""Contains the text to be used as the message subject for EMAIL
+or contains the text to be used for DISPLAY"""),
'action': fields.selection([('AUDIO', 'AUDIO'), ('DISPLAY', 'DISPLAY'), \
- ('PROCEDURE', 'PROCEDURE'), ('EMAIL', 'EMAIL') ], 'Action', required=True),
- 'description': fields.text('Description'),
+ ('PROCEDURE', 'PROCEDURE'), ('EMAIL', 'EMAIL') ], 'Action', \
+ required=True, help="Defines the action to be invoked when an alarm is triggered"),
+ 'description': fields.text('Description', help='Provides a more complete description of the calendar component, than that provided by the "SUMMARY" property'),
'attendee_ids': fields.many2many('crm.caldav.attendee', 'alarm_attendee_rel', \
'alarm_id', 'attendee_id', 'Attendees'),
'trigger_occurs': fields.selection([('BEFORE', 'BEFORE'), ('AFTER', 'AFTER')], \
'Trigger time', required=True),
'trigger_interval': fields.selection([('MINUTES', 'MINUTES'), ('HOURS', 'HOURS'), \
- ('DAYS', 'DAYS')], 'Trugger duration', required=True),
+ ('DAYS', 'DAYS')], 'Trigger duration', required=True),
'trigger_duration': fields.integer('TIme', required=True),
'trigger_related': fields.selection([('start', 'The event starts'), ('end', \
'The event ends')], 'Trigger Occures at', required=True),
- 'duration': fields.integer('Duration'),
+ 'duration': fields.integer('Duration', help="""Duration' and 'Repeat' \
+are both optional, but if one occurs, so MUST the other"""),
'repeat': fields.integer('Repeat'), # TODO
- 'attach': fields.binary('Attachment'),
+ 'attach': fields.binary('Attachment', help="""* Points to a sound resource, which is rendered when the alarm is triggered for AUDIO,
+* File which is intended to be sent as message attachments for EMAIL,
+* Points to a procedure resource, which is invoked when the alarm is triggered for PROCEDURE.
+"""),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the event alarm information without removing it."),
}
@@ -214,7 +227,7 @@ class virtual_wizard(web_services.wizard):
if 'id' in datas:
datas['id'] = caldevIDs2readIDs(datas['id'])
for id in datas['ids']:
- new_ids.append(caldevIDs2readIDs(id))
+ new_ids.append(caldevIDs2readIDs(id))
datas['ids'] = new_ids
res=super(virtual_wizard, self).exp_execute(db, uid, wiz_id, datas, action, context)
return res
From 6c70671d2d469e2553e46114838008a47cd1094f Mon Sep 17 00:00:00 2001
From: "uco (OpenERP)"
Date: Wed, 23 Dec 2009 16:39:21 +0530
Subject: [PATCH 083/123] [REF]: Removed 'My cases by section' menu from
report_crm view.
bzr revid: uco@tinyerp.co.in-20091223110921-p2p9n1x58evwc5pu
---
addons/report_crm/report_crm_view.xml | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/addons/report_crm/report_crm_view.xml b/addons/report_crm/report_crm_view.xml
index d406d9ab454..ef7306f3b5b 100644
--- a/addons/report_crm/report_crm_view.xml
+++ b/addons/report_crm/report_crm_view.xml
@@ -62,6 +62,8 @@
+
+
@@ -88,16 +90,6 @@
-
- My cases by section
- report.crm.case.user
- form
- tree,graph
- [('user_id','=',uid)]
-
-
-
-
From 54d968371ab3b304db225eab4b01a6392698c0aa Mon Sep 17 00:00:00 2001
From: "GPA(OpenERP)" <>
Date: Wed, 23 Dec 2009 16:44:43 +0530
Subject: [PATCH 084/123] [FIX] Pricelist : Correction in price_get() to
achieve proper price.
lp bug: https://launchpad.net/bugs/438144 fixed
bzr revid: jvo@tinyerp.com-20091223111443-id4ef38w1j6b9cgg
---
addons/product/pricelist.py | 102 +++++++++++++++++++-----------------
1 file changed, 54 insertions(+), 48 deletions(-)
diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py
index 0849ee85dcd..93800e0e973 100644
--- a/addons/product/pricelist.py
+++ b/addons/product/pricelist.py
@@ -193,58 +193,64 @@ class product_pricelist(osv.osv):
'AND price_version_id = %s '
'AND (min_quantity IS NULL OR min_quantity <= %s) '
'AND i.price_version_id = v.id AND v.pricelist_id = pl.id '
- 'ORDER BY sequence LIMIT 1',
+ 'ORDER BY sequence',
(tmpl_id, prod_id, plversion['id'], qty))
- res = cr.dictfetchone()
- if res:
- if res['base'] == -1:
- if not res['base_pricelist_id']:
+ res1 = cr.dictfetchall()
+
+ for res in res1:
+ if res:
+ if res['base'] == -1:
+ if not res['base_pricelist_id']:
+ price = 0.0
+ else:
+ price_tmp = self.price_get(cr, uid,
+ [res['base_pricelist_id']], prod_id,
+ qty)[res['base_pricelist_id']]
+ ptype_src = self.browse(cr, uid,
+ res['base_pricelist_id']).currency_id.id
+ price = currency_obj.compute(cr, uid, ptype_src,
+ res['currency_id'], price_tmp, round=False)
+ break
+ elif res['base'] == -2:
+ where = []
+ if partner:
+ where = [('name', '=', partner) ]
+ sinfo = supplierinfo_obj.search(cr, uid,
+ [('product_id', '=', tmpl_id)] + where)
price = 0.0
+ if sinfo:
+ cr.execute('SELECT * ' \
+ 'FROM pricelist_partnerinfo ' \
+ 'WHERE suppinfo_id IN (' + \
+ ','.join(map(str, sinfo)) + ') ' \
+ 'AND min_quantity <= %s ' \
+ 'ORDER BY min_quantity DESC LIMIT 1', (qty,))
+ res2 = cr.dictfetchone()
+ if res2:
+ price = res2['price']
+ break
else:
- price_tmp = self.price_get(cr, uid,
- [res['base_pricelist_id']], prod_id,
- qty)[res['base_pricelist_id']]
- ptype_src = self.browse(cr, uid,
- res['base_pricelist_id']).currency_id.id
- price = currency_obj.compute(cr, uid, ptype_src,
- res['currency_id'], price_tmp, round=False)
- elif res['base'] == -2:
- where = []
- if partner:
- where = [('name', '=', partner) ]
- sinfo = supplierinfo_obj.search(cr, uid,
- [('product_id', '=', tmpl_id)] + where)
- price = 0.0
- if sinfo:
- cr.execute('SELECT * ' \
- 'FROM pricelist_partnerinfo ' \
- 'WHERE suppinfo_id IN (' + \
- ','.join(map(str, sinfo)) + ') ' \
- 'AND min_quantity <= %s ' \
- 'ORDER BY min_quantity DESC LIMIT 1', (qty,))
- res2 = cr.dictfetchone()
- if res2:
- price = res2['price']
+ price_type = price_type_obj.browse(cr, uid, int(res['base']))
+ price = currency_obj.compute(cr, uid,
+ price_type.currency_id.id, res['currency_id'],
+ product_obj.price_get(cr, uid, [prod_id],
+ price_type.field)[prod_id], round=False)
+
+ if price:
+ price_limit = price
+
+ price = price * (1.0+(res['price_discount'] or 0.0))
+ price = rounding(price, res['price_round'])
+ price += (res['price_surcharge'] or 0.0)
+ if res['price_min_margin']:
+ price = max(price, price_limit+res['price_min_margin'])
+ if res['price_max_margin']:
+ price = min(price, price_limit+res['price_max_margin'])
+ break
else:
- price_type = price_type_obj.browse(cr, uid, int(res['base']))
- price = currency_obj.compute(cr, uid,
- price_type.currency_id.id, res['currency_id'],
- product_obj.price_get(cr, uid, [prod_id],
- price_type.field)[prod_id], round=False)
-
- price_limit = price
-
- price = price * (1.0+(res['price_discount'] or 0.0))
- price = rounding(price, res['price_round'])
- price += (res['price_surcharge'] or 0.0)
- if res['price_min_margin']:
- price = max(price, price_limit+res['price_min_margin'])
- if res['price_max_margin']:
- price = min(price, price_limit+res['price_max_margin'])
- else:
- # False means no valid line found ! But we may not raise an
- # exception here because it breaks the search
- price = False
+ # False means no valid line found ! But we may not raise an
+ # exception here because it breaks the search
+ price = False
result[id] = price
if context and ('uom' in context):
product = product_obj.browse(cr, uid, prod_id)
From e32b5e6225b6b0205adc70a7f9dade13b48cd85e Mon Sep 17 00:00:00 2001
From: "mra (Open ERP)"
Date: Wed, 23 Dec 2009 16:51:15 +0530
Subject: [PATCH 085/123] [REM] launchpad translation: remove addons folder
with dm,account_budget_crossover,
association_vertical,hr_timesheet_project,invoice_payment_tab,report_stock,
stock_back_order, base_module_doc_rst modules translaiton files
bzr revid: mra@tinyerp.com-20091223112115-4izid9qkgzh8lffh
---
.../account_budget_crossover/i18n/bg.po | 314 --
.../account_budget_crossover/i18n/ca.po | 315 --
.../account_budget_crossover/i18n/de.po | 317 --
.../account_budget_crossover/i18n/el.po | 314 --
.../account_budget_crossover/i18n/es.po | 318 --
.../account_budget_crossover/i18n/es_AR.po | 314 --
.../account_budget_crossover/i18n/et.po | 313 --
.../account_budget_crossover/i18n/fi.po | 312 --
.../account_budget_crossover/i18n/fr.po | 317 --
.../account_budget_crossover/i18n/gl.po | 315 --
.../account_budget_crossover/i18n/hr.po | 313 --
.../account_budget_crossover/i18n/it.po | 314 --
.../account_budget_crossover/i18n/ko.po | 312 --
.../account_budget_crossover/i18n/lt.po | 312 --
.../account_budget_crossover/i18n/nl.po | 316 --
.../account_budget_crossover/i18n/pl.po | 314 --
.../account_budget_crossover/i18n/pt.po | 314 --
.../account_budget_crossover/i18n/pt_BR.po | 313 --
.../account_budget_crossover/i18n/ro.po | 314 --
.../account_budget_crossover/i18n/ru.po | 314 --
.../account_budget_crossover/i18n/sl.po | 313 --
.../account_budget_crossover/i18n/uk.po | 313 --
.../account_budget_crossover/i18n/zh_TW.po | 312 --
addons/addons/association_vertical/i18n/ca.po | 70 -
addons/addons/association_vertical/i18n/da.po | 69 -
addons/addons/association_vertical/i18n/de.po | 72 -
addons/addons/association_vertical/i18n/el.po | 69 -
addons/addons/association_vertical/i18n/es.po | 73 -
.../addons/association_vertical/i18n/es_AR.po | 69 -
addons/addons/association_vertical/i18n/et.po | 69 -
addons/addons/association_vertical/i18n/fr.po | 72 -
addons/addons/association_vertical/i18n/gl.po | 69 -
addons/addons/association_vertical/i18n/hr.po | 69 -
addons/addons/association_vertical/i18n/hu.po | 69 -
addons/addons/association_vertical/i18n/it.po | 69 -
addons/addons/association_vertical/i18n/ko.po | 69 -
addons/addons/association_vertical/i18n/nl.po | 72 -
addons/addons/association_vertical/i18n/pl.po | 69 -
addons/addons/association_vertical/i18n/pt.po | 69 -
.../addons/association_vertical/i18n/pt_BR.po | 69 -
addons/addons/association_vertical/i18n/ro.po | 69 -
addons/addons/association_vertical/i18n/ru.po | 69 -
addons/addons/association_vertical/i18n/sl.po | 69 -
addons/addons/base_module_doc_rst/i18n/ar.po | 57 -
addons/addons/base_module_doc_rst/i18n/bg.po | 57 -
addons/addons/base_module_doc_rst/i18n/bs.po | 57 -
addons/addons/base_module_doc_rst/i18n/ca.po | 58 -
addons/addons/base_module_doc_rst/i18n/cs.po | 57 -
addons/addons/base_module_doc_rst/i18n/de.po | 57 -
addons/addons/base_module_doc_rst/i18n/el.po | 58 -
addons/addons/base_module_doc_rst/i18n/es.po | 58 -
.../addons/base_module_doc_rst/i18n/es_AR.po | 57 -
addons/addons/base_module_doc_rst/i18n/et.po | 57 -
addons/addons/base_module_doc_rst/i18n/fi.po | 58 -
addons/addons/base_module_doc_rst/i18n/fr.po | 57 -
addons/addons/base_module_doc_rst/i18n/gl.po | 59 -
addons/addons/base_module_doc_rst/i18n/hr.po | 57 -
addons/addons/base_module_doc_rst/i18n/hu.po | 57 -
addons/addons/base_module_doc_rst/i18n/it.po | 57 -
addons/addons/base_module_doc_rst/i18n/ko.po | 58 -
addons/addons/base_module_doc_rst/i18n/lt.po | 57 -
addons/addons/base_module_doc_rst/i18n/nl.po | 57 -
.../addons/base_module_doc_rst/i18n/nl_BE.po | 57 -
addons/addons/base_module_doc_rst/i18n/pl.po | 57 -
addons/addons/base_module_doc_rst/i18n/pt.po | 57 -
.../addons/base_module_doc_rst/i18n/pt_BR.po | 57 -
addons/addons/base_module_doc_rst/i18n/ro.po | 57 -
addons/addons/base_module_doc_rst/i18n/ru.po | 57 -
addons/addons/base_module_doc_rst/i18n/sk.po | 58 -
addons/addons/base_module_doc_rst/i18n/sl.po | 60 -
addons/addons/base_module_doc_rst/i18n/sr.po | 58 -
addons/addons/base_module_doc_rst/i18n/sv.po | 57 -
addons/addons/base_module_doc_rst/i18n/tlh.po | 57 -
addons/addons/base_module_doc_rst/i18n/tr.po | 57 -
addons/addons/base_module_doc_rst/i18n/uk.po | 57 -
addons/addons/base_module_doc_rst/i18n/ur.po | 60 -
.../addons/base_module_doc_rst/i18n/zh_CN.po | 57 -
.../addons/base_module_doc_rst/i18n/zh_TW.po | 57 -
addons/addons/dm/i18n/ca.po | 4417 ----------------
addons/addons/dm/i18n/de.po | 4391 ----------------
addons/addons/dm/i18n/es.po | 4461 ----------------
addons/addons/dm/i18n/et.po | 4394 ----------------
addons/addons/dm/i18n/fi.po | 4469 ----------------
addons/addons/dm/i18n/fr.po | 4479 -----------------
addons/addons/dm/i18n/hr.po | 4410 ----------------
addons/addons/dm/i18n/it.po | 4399 ----------------
addons/addons/dm/i18n/ko.po | 4397 ----------------
addons/addons/dm/i18n/lt.po | 4401 ----------------
addons/addons/dm/i18n/pl.po | 4391 ----------------
addons/addons/dm/i18n/pt.po | 4427 ----------------
addons/addons/dm/i18n/pt_BR.po | 4393 ----------------
addons/addons/dm/i18n/ru.po | 4402 ----------------
addons/addons/dm/i18n/sl.po | 4391 ----------------
addons/addons/dm/i18n/uk.po | 4391 ----------------
addons/addons/dm/i18n/zh_CN.po | 4391 ----------------
addons/addons/hr_timesheet_project/i18n/ca.po | 89 -
addons/addons/hr_timesheet_project/i18n/de.po | 91 -
addons/addons/hr_timesheet_project/i18n/es.po | 92 -
.../addons/hr_timesheet_project/i18n/es_AR.po | 88 -
addons/addons/hr_timesheet_project/i18n/et.po | 88 -
addons/addons/hr_timesheet_project/i18n/fi.po | 88 -
addons/addons/hr_timesheet_project/i18n/fr.po | 92 -
addons/addons/hr_timesheet_project/i18n/gl.po | 89 -
addons/addons/hr_timesheet_project/i18n/it.po | 88 -
addons/addons/hr_timesheet_project/i18n/ko.po | 88 -
addons/addons/hr_timesheet_project/i18n/lv.po | 88 -
addons/addons/hr_timesheet_project/i18n/nl.po | 91 -
addons/addons/hr_timesheet_project/i18n/pl.po | 88 -
addons/addons/hr_timesheet_project/i18n/pt.po | 88 -
.../addons/hr_timesheet_project/i18n/pt_BR.po | 88 -
addons/addons/hr_timesheet_project/i18n/ru.po | 88 -
addons/addons/hr_timesheet_project/i18n/sl.po | 88 -
.../addons/hr_timesheet_project/i18n/zh_CN.po | 88 -
addons/addons/invoice_payment_tab/i18n/bg.po | 33 -
addons/addons/invoice_payment_tab/i18n/ca.po | 34 -
addons/addons/invoice_payment_tab/i18n/cs.po | 33 -
addons/addons/invoice_payment_tab/i18n/da.po | 33 -
addons/addons/invoice_payment_tab/i18n/de.po | 36 -
addons/addons/invoice_payment_tab/i18n/el.po | 33 -
addons/addons/invoice_payment_tab/i18n/es.po | 37 -
.../addons/invoice_payment_tab/i18n/es_AR.po | 33 -
addons/addons/invoice_payment_tab/i18n/et.po | 33 -
addons/addons/invoice_payment_tab/i18n/fr.po | 36 -
addons/addons/invoice_payment_tab/i18n/gl.po | 33 -
addons/addons/invoice_payment_tab/i18n/hu.po | 33 -
addons/addons/invoice_payment_tab/i18n/it.po | 33 -
addons/addons/invoice_payment_tab/i18n/ko.po | 33 -
addons/addons/invoice_payment_tab/i18n/lt.po | 33 -
addons/addons/invoice_payment_tab/i18n/nl.po | 36 -
addons/addons/invoice_payment_tab/i18n/oc.po | 33 -
addons/addons/invoice_payment_tab/i18n/pl.po | 33 -
addons/addons/invoice_payment_tab/i18n/pt.po | 33 -
.../addons/invoice_payment_tab/i18n/pt_BR.po | 33 -
addons/addons/invoice_payment_tab/i18n/ro.po | 33 -
addons/addons/invoice_payment_tab/i18n/ru.po | 33 -
addons/addons/invoice_payment_tab/i18n/sk.po | 33 -
addons/addons/invoice_payment_tab/i18n/sl.po | 33 -
addons/addons/invoice_payment_tab/i18n/tr.po | 33 -
addons/addons/invoice_payment_tab/i18n/uk.po | 33 -
addons/addons/report_stock/i18n/ca.po | 80 -
addons/addons/report_stock/i18n/da.po | 77 -
addons/addons/report_stock/i18n/de.po | 82 -
addons/addons/report_stock/i18n/es.po | 83 -
addons/addons/report_stock/i18n/es_AR.po | 79 -
addons/addons/report_stock/i18n/et.po | 78 -
addons/addons/report_stock/i18n/fr.po | 82 -
addons/addons/report_stock/i18n/gl.po | 80 -
addons/addons/report_stock/i18n/it.po | 78 -
addons/addons/report_stock/i18n/ko.po | 77 -
addons/addons/report_stock/i18n/nl.po | 80 -
addons/addons/report_stock/i18n/pl.po | 79 -
addons/addons/report_stock/i18n/pt.po | 78 -
addons/addons/report_stock/i18n/pt_BR.po | 78 -
addons/addons/report_stock/i18n/ro.po | 79 -
addons/addons/report_stock/i18n/ru.po | 79 -
addons/addons/report_stock/i18n/sl.po | 78 -
addons/addons/report_stock/i18n/uk.po | 78 -
addons/addons/report_stock/i18n/zh_CN.po | 77 -
addons/addons/stock_back_order/i18n/bg.po | 75 -
addons/addons/stock_back_order/i18n/ca.po | 76 -
addons/addons/stock_back_order/i18n/da.po | 75 -
addons/addons/stock_back_order/i18n/de.po | 75 -
addons/addons/stock_back_order/i18n/es.po | 76 -
addons/addons/stock_back_order/i18n/et.po | 75 -
addons/addons/stock_back_order/i18n/fr.po | 75 -
addons/addons/stock_back_order/i18n/hr.po | 75 -
addons/addons/stock_back_order/i18n/it.po | 75 -
addons/addons/stock_back_order/i18n/ko.po | 75 -
addons/addons/stock_back_order/i18n/pl.po | 75 -
addons/addons/stock_back_order/i18n/pt.po | 75 -
addons/addons/stock_back_order/i18n/pt_BR.po | 75 -
addons/addons/stock_back_order/i18n/ru.po | 75 -
addons/addons/stock_back_order/i18n/sl.po | 75 -
173 files changed, 90732 deletions(-)
delete mode 100644 addons/addons/account_budget_crossover/i18n/bg.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/ca.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/de.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/el.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/es.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/es_AR.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/et.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/fi.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/fr.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/gl.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/hr.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/it.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/ko.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/lt.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/nl.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/pl.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/pt.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/pt_BR.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/ro.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/ru.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/sl.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/uk.po
delete mode 100644 addons/addons/account_budget_crossover/i18n/zh_TW.po
delete mode 100644 addons/addons/association_vertical/i18n/ca.po
delete mode 100644 addons/addons/association_vertical/i18n/da.po
delete mode 100644 addons/addons/association_vertical/i18n/de.po
delete mode 100644 addons/addons/association_vertical/i18n/el.po
delete mode 100644 addons/addons/association_vertical/i18n/es.po
delete mode 100644 addons/addons/association_vertical/i18n/es_AR.po
delete mode 100644 addons/addons/association_vertical/i18n/et.po
delete mode 100644 addons/addons/association_vertical/i18n/fr.po
delete mode 100644 addons/addons/association_vertical/i18n/gl.po
delete mode 100644 addons/addons/association_vertical/i18n/hr.po
delete mode 100644 addons/addons/association_vertical/i18n/hu.po
delete mode 100644 addons/addons/association_vertical/i18n/it.po
delete mode 100644 addons/addons/association_vertical/i18n/ko.po
delete mode 100644 addons/addons/association_vertical/i18n/nl.po
delete mode 100644 addons/addons/association_vertical/i18n/pl.po
delete mode 100644 addons/addons/association_vertical/i18n/pt.po
delete mode 100644 addons/addons/association_vertical/i18n/pt_BR.po
delete mode 100644 addons/addons/association_vertical/i18n/ro.po
delete mode 100644 addons/addons/association_vertical/i18n/ru.po
delete mode 100644 addons/addons/association_vertical/i18n/sl.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/ar.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/bg.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/bs.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/ca.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/cs.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/de.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/el.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/es.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/es_AR.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/et.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/fi.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/fr.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/gl.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/hr.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/hu.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/it.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/ko.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/lt.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/nl.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/nl_BE.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/pl.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/pt.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/pt_BR.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/ro.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/ru.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/sk.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/sl.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/sr.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/sv.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/tlh.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/tr.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/uk.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/ur.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/zh_CN.po
delete mode 100644 addons/addons/base_module_doc_rst/i18n/zh_TW.po
delete mode 100644 addons/addons/dm/i18n/ca.po
delete mode 100644 addons/addons/dm/i18n/de.po
delete mode 100644 addons/addons/dm/i18n/es.po
delete mode 100644 addons/addons/dm/i18n/et.po
delete mode 100644 addons/addons/dm/i18n/fi.po
delete mode 100644 addons/addons/dm/i18n/fr.po
delete mode 100644 addons/addons/dm/i18n/hr.po
delete mode 100644 addons/addons/dm/i18n/it.po
delete mode 100644 addons/addons/dm/i18n/ko.po
delete mode 100644 addons/addons/dm/i18n/lt.po
delete mode 100644 addons/addons/dm/i18n/pl.po
delete mode 100644 addons/addons/dm/i18n/pt.po
delete mode 100644 addons/addons/dm/i18n/pt_BR.po
delete mode 100644 addons/addons/dm/i18n/ru.po
delete mode 100644 addons/addons/dm/i18n/sl.po
delete mode 100644 addons/addons/dm/i18n/uk.po
delete mode 100644 addons/addons/dm/i18n/zh_CN.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/ca.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/de.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/es.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/es_AR.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/et.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/fi.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/fr.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/gl.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/it.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/ko.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/lv.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/nl.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/pl.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/pt.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/pt_BR.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/ru.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/sl.po
delete mode 100644 addons/addons/hr_timesheet_project/i18n/zh_CN.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/bg.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/ca.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/cs.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/da.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/de.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/el.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/es.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/es_AR.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/et.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/fr.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/gl.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/hu.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/it.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/ko.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/lt.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/nl.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/oc.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/pl.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/pt.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/pt_BR.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/ro.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/ru.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/sk.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/sl.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/tr.po
delete mode 100644 addons/addons/invoice_payment_tab/i18n/uk.po
delete mode 100644 addons/addons/report_stock/i18n/ca.po
delete mode 100644 addons/addons/report_stock/i18n/da.po
delete mode 100644 addons/addons/report_stock/i18n/de.po
delete mode 100644 addons/addons/report_stock/i18n/es.po
delete mode 100644 addons/addons/report_stock/i18n/es_AR.po
delete mode 100644 addons/addons/report_stock/i18n/et.po
delete mode 100644 addons/addons/report_stock/i18n/fr.po
delete mode 100644 addons/addons/report_stock/i18n/gl.po
delete mode 100644 addons/addons/report_stock/i18n/it.po
delete mode 100644 addons/addons/report_stock/i18n/ko.po
delete mode 100644 addons/addons/report_stock/i18n/nl.po
delete mode 100644 addons/addons/report_stock/i18n/pl.po
delete mode 100644 addons/addons/report_stock/i18n/pt.po
delete mode 100644 addons/addons/report_stock/i18n/pt_BR.po
delete mode 100644 addons/addons/report_stock/i18n/ro.po
delete mode 100644 addons/addons/report_stock/i18n/ru.po
delete mode 100644 addons/addons/report_stock/i18n/sl.po
delete mode 100644 addons/addons/report_stock/i18n/uk.po
delete mode 100644 addons/addons/report_stock/i18n/zh_CN.po
delete mode 100644 addons/addons/stock_back_order/i18n/bg.po
delete mode 100644 addons/addons/stock_back_order/i18n/ca.po
delete mode 100644 addons/addons/stock_back_order/i18n/da.po
delete mode 100644 addons/addons/stock_back_order/i18n/de.po
delete mode 100644 addons/addons/stock_back_order/i18n/es.po
delete mode 100644 addons/addons/stock_back_order/i18n/et.po
delete mode 100644 addons/addons/stock_back_order/i18n/fr.po
delete mode 100644 addons/addons/stock_back_order/i18n/hr.po
delete mode 100644 addons/addons/stock_back_order/i18n/it.po
delete mode 100644 addons/addons/stock_back_order/i18n/ko.po
delete mode 100644 addons/addons/stock_back_order/i18n/pl.po
delete mode 100644 addons/addons/stock_back_order/i18n/pt.po
delete mode 100644 addons/addons/stock_back_order/i18n/pt_BR.po
delete mode 100644 addons/addons/stock_back_order/i18n/ru.po
delete mode 100644 addons/addons/stock_back_order/i18n/sl.po
diff --git a/addons/addons/account_budget_crossover/i18n/bg.po b/addons/addons/account_budget_crossover/i18n/bg.po
deleted file mode 100644
index 2c15f0a3419..00000000000
--- a/addons/addons/account_budget_crossover/i18n/bg.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Bulgarian translation for openobject-addons
-# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 16:31+0000\n"
-"Last-Translator: lem0na \n"
-"Language-Team: Bulgarian \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Отговорен потребител"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Потвърдено"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Името на обекта трябва да започва с \"x_\" и да не съдържа никакви специални "
-"символи!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Отпечатано в:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Потвърждение"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Проверка на потребител"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Отпратка към аналитична сметка"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Валута:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Чернова"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "на"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Печат на бюджети"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Печат"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Процент"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Проверен"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Кръстосани бюджетни линии"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Име"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Състояние"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Описание"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Аналитична сметка :"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Отпратка към бюджет"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "до"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Планирано количество"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Записи"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Потвърждаване"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Избери опция"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Практическо количество"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Крайна дата"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "Невалиден XML за преглед на архитектурата"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Теоритично количество"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Общо:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Отказано"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Отпратка към главен бюджет"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Редове"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Бюджет"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Избор на дати на период"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Дата на плащане"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Бюджети"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Край на периода"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Кръстосан бюджет"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Старт на периода"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Печат на обобщение на бюджети"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Код"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Теоритично количество"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Буджет :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Готово"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Редове на бюджет"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Откажи"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Общо планирана сума"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Начална дата"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Аналитичен от"
diff --git a/addons/addons/account_budget_crossover/i18n/ca.po b/addons/addons/account_budget_crossover/i18n/ca.po
deleted file mode 100644
index 612014f5867..00000000000
--- a/addons/addons/account_budget_crossover/i18n/ca.po
+++ /dev/null
@@ -1,315 +0,0 @@
-# Catalan translation for openobject-addons
-# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 13:20+0000\n"
-"Last-Translator: Jordi Esteve - http://www.zikzakmedia.com "
-"\n"
-"Language-Team: Catalan \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Usuari responsable"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmada"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"El nom de l'objecte ha de començar amb x_ i no contenir cap caràcter "
-"especial !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Imprès el:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirma"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Usuari validat"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Ref. compte analític"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Moneda:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Esborrany"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "a les"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimeix pressupostos"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Imprimeix"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Percentatge"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validat"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Línies de pressupost creuat"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nom"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Estat"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descripció"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Compte analític:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Ref. pressupost"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "fins"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Import previst"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Assentaments"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validar"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Selecciona opcions"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Import real"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Data final"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML invàlid per a la definició de la vista!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Import teòric"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Cancel·lat"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Ref. pressupost principal"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Línies"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Pressupost"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Seleccioni dates del període"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data de pagament"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Pressuposts"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Fi del període"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Pressupost creuat"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Inici del període"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimeix resum de pressupostos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Codi"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Import teòric"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Pressupost:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Realitzat"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Línies de pressupost"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Cancel·la"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Import total previst"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data inicial"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Anàlisi des de"
diff --git a/addons/addons/account_budget_crossover/i18n/de.po b/addons/addons/account_budget_crossover/i18n/de.po
deleted file mode 100644
index 68a82a37ff8..00000000000
--- a/addons/addons/account_budget_crossover/i18n/de.po
+++ /dev/null
@@ -1,317 +0,0 @@
-# Translation of OpenERP Server.
-# This file containt the translation of the following modules:
-# * account_budget_crossover
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: OpenERP Server 4.3.0Report-Msgid-Bugs-To: "
-"support@openerp.comPOT-Creation-Date: 2008-09-10 15:03:49+0000PO-Revision-"
-"Date: 2008-09-10 15:03:49+0000Last-Translator: <>Language-Team: MIME-"
-"Version: 1.0Content-Type: text/plain; charset=UTF-8Content-Transfer-"
-"Encoding: Plural-Forms:\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 14:11+0000\n"
-"Last-Translator: Ferdinand-chricar \n"
-"Language-Team: LANGUAGE \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Verantwortlicher Benutzer"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Bestätigt"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Der Objekt Name muss mit einem x_ starten und darf keine Sonderzeichen "
-"beinhalten"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Druck am:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Bestätige"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Validiere Benutzer"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Analysekonto Ref."
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Währung:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Entwurf"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "von"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Druck Budgets..."
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Drucke"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Prozentsatz"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Bestätigt"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Übergeleitete Budget Zeilen"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Bezeichnung"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Status"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Beschreibung"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Analytisches Konto"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Budget Ref."
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "bis"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Geplanter Betrag"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Buchungen"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validiere"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Wähe Optionen"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "geeigneter Betrag"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Enddatum:"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "Fehlerhafter xml code für diese Ansicht!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Planwert"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Gesamt:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Abgebrochen"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Haupt BUdget Ref."
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Positionen"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Budget"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Wähle Perioden"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Zahldatum"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Budgets"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Periodenende:"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Übergeleitetes Budget"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Startdatum"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Drucke Zusammenfassung des Budgets"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Kurzbez."
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Sollwert"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Budget:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Erledigt"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Budget Positionen"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Abbruch"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Gesamter geplanter Betrag"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Start Datum"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analyse vom"
diff --git a/addons/addons/account_budget_crossover/i18n/el.po b/addons/addons/account_budget_crossover/i18n/el.po
deleted file mode 100644
index 20c478b02a8..00000000000
--- a/addons/addons/account_budget_crossover/i18n/el.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Greek translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 15:28+0000\n"
-"Last-Translator: Makis Nicolaou \n"
-"Language-Team: Greek \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Υπεύθυνος Χρήστης"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Επιβεβαιωμένο"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Το όνομα του αντικειμένου θα πρέπει να ξεκινάει με x_ και να μην περιέχει "
-"ειδικούς χαρακτήρες!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Εκτυπωμένο στίς:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Επιβεβαίωση"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Επικύρωση Χρήστη"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Σχ. Αναλυτικού Λογαριασμού"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Νόμισμα:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Πρόχειρο"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "στο"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Εκτύπωση Προϋπολογισμών"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Εκτύπωση"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Ποσοστό"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Επικυρωμένο"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Διασταυρωμένες Γραμμές Προϋπολογισμών"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Όνομα"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Κατάσταση"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Περιγραφή"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Αναλυτικός Λογαριασμός :"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Σχ. Προϋπολογισμού"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "σε"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Μελετημένο Ποσό"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Εγγραφές"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Επικύρωση"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Επιλογή Ρυθμίσεων"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Πρακτικό Ποσό"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Ημερομηνία Λήξης"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "Άκυρο XML για Αρχιτεκτονική Όψης!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Θεωρητικό Ποσό"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Σύνολο:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Ακυρωμένο"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Σχ. Κύριου Προϋπολογισμού"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Γραμμές"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Προϋπολογισμός"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Επιλογή Ημερομηνιών Περιόδου"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Ημερομηνία Πληρωμής"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Προϋπολογισμοί"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Τέλος περιόδου"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Διασταυρωμένοι Προϋπολογισμοί"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Έναρξη Περιόδου"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Εκτύπωση Περιλήψεων Προϋπολογισμών"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Κώδικας"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Θεωρητικό Ποσό"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Προϋπολογισμός :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Εκπληρωμένο"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Γραμμές Προϋπολογισμού"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Άκυρο"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Συνολικό Μελετηθέν Ποσό"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Ημερομηνία Έναρξης"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Ανάλυση απο"
diff --git a/addons/addons/account_budget_crossover/i18n/es.po b/addons/addons/account_budget_crossover/i18n/es.po
deleted file mode 100644
index 6d36058ad4c..00000000000
--- a/addons/addons/account_budget_crossover/i18n/es.po
+++ /dev/null
@@ -1,318 +0,0 @@
-# Translation of OpenERP Server.
-# This file containt the translation of the following modules:
-# * account_budget_crossover
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: OpenERP Server 4.3.0Report-Msgid-Bugs-To: "
-"support@openerp.comPOT-Creation-Date: 2008-09-10 15:05:00+0000PO-Revision-"
-"Date: 2008-09-10 15:05:00+0000Last-Translator: <>Language-Team: MIME-"
-"Version: 1.0Content-Type: text/plain; charset=UTF-8Content-Transfer-"
-"Encoding: Plural-Forms:\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 16:27+0000\n"
-"Last-Translator: Jordi Esteve - http://www.zikzakmedia.com "
-"\n"
-"Language-Team: LANGUAGE \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Usuario responsable"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmada"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"¡El nombre del objeto debe empezar con x_ y no contener ningún carácter "
-"especial!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Impreso el:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmar"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Usuario validado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Ref. cuenta analítica"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Moneda:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Borrador"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "a las"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimir presupuestos"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Imprimir"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Porcentaje"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Líneas de presupuesto cruzado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nombre"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Estado"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descripción"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Cuenta analítica:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Ref. presupuesto"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "hasta"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Importe previsto"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Asientos"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Seleccionar opciones"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Importe real"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Fecha final"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "¡XML inválido para la definición de la vista!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Importe teórico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Cancelado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Ref. presupuesto principal"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Líneas"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Presupuesto"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Seleccione fechas del período"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Fecha de pago"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Presupuestos"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Fin del período"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Presupuesto cruzado"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Inicio del período"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimir resumen de presupuestos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Importe teórico"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Presupuesto:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Realizado"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Líneas de presupuesto"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Importe total previsto"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Fecha inicial"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Análisis desde"
diff --git a/addons/addons/account_budget_crossover/i18n/es_AR.po b/addons/addons/account_budget_crossover/i18n/es_AR.po
deleted file mode 100644
index 998465d42f0..00000000000
--- a/addons/addons/account_budget_crossover/i18n/es_AR.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Spanish (Argentina) translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-15 18:12+0000\n"
-"Last-Translator: Silvana Herrera \n"
-"Language-Team: Spanish (Argentina) \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Usuario responsable"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmado"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"¡El nombre del objeto debe empezar con x_ y no contener ningún caracter "
-"especial!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Impreso en:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmar"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Validar usuario"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Referencia cuenta analítica"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Moneda:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Borrador"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "en"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimir presupuestos"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Imprimir"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Porcentaje"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Líneas de presupuesto cruzado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nombre"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Estado"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descripción"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Cuenta analítica:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Referencia de presupuesto"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "hasta"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Importe previsto"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Asientos"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validar"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Seleccionar opciones"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Importe real"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Fecha de fin"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML inválido para la definición de la vista!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Importe teórico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Cancelado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Referencia del presupuesto principal"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Líneas"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Presupuesto"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Seleccione fechas del período"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Fecha de pago"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Presupuestos"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Fin del período"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Presupuesto cruzado"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Inicio del período"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimir resumen de presupuestos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Importe teórico"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Presupuesto :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Realizado"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Líneas de presupuesto"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Importe total previsto"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Fecha de inicio"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Análisis desde"
diff --git a/addons/addons/account_budget_crossover/i18n/et.po b/addons/addons/account_budget_crossover/i18n/et.po
deleted file mode 100644
index 92d9860bdda..00000000000
--- a/addons/addons/account_budget_crossover/i18n/et.po
+++ /dev/null
@@ -1,313 +0,0 @@
-# Estonian translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 12:41+0000\n"
-"Last-Translator: Ahti Hinnov \n"
-"Language-Team: Estonian \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Vastutav kasutaja"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Kinnitatud"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Objekti nimi peab algama x_'ga ja ei tohi sisaldada ühtegi erisümbolit !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Prinditud:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Kinnita"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Valideeriv kasutaja"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Analüütilise konto viit"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Valuuta:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Mustand"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "kell"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Prindi eelarved"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Prindi"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Protsent"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Valideeritud"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Ühendatud eelarveread"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nimi"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Olek"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Kirjeldus"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Analüütiline konto:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Eelarve viit"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "kuni"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Planeeritud summa"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Kirjeid"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Valideeri"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Vali suvandid"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Praktiline summa"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Lõppkuupäev"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "Vigane vaate arhitektuuri XML!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Teoreetiline summa"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Kokku:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Tühistatud"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Põhieelarve viit"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Read"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Eelarve"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Vali kuupäevade periood"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Maksmise kuupäev"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Eelarved"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Perioodi lõpp"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Ühendatud eelarve"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Perioodi algus"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Prindi eelarvete kokkuvõte"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Kood"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Teoreetiline summa"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Eelarve:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Tehtud"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Eelarveread"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Tühista"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Kogu planeeritud summa"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Alguskuupäev"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analüüs alates"
diff --git a/addons/addons/account_budget_crossover/i18n/fi.po b/addons/addons/account_budget_crossover/i18n/fi.po
deleted file mode 100644
index 447551f0f18..00000000000
--- a/addons/addons/account_budget_crossover/i18n/fi.po
+++ /dev/null
@@ -1,312 +0,0 @@
-# Finnish translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-11-12 08:07+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: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr ""
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr ""
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr ""
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr ""
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr ""
diff --git a/addons/addons/account_budget_crossover/i18n/fr.po b/addons/addons/account_budget_crossover/i18n/fr.po
deleted file mode 100644
index 4756155196e..00000000000
--- a/addons/addons/account_budget_crossover/i18n/fr.po
+++ /dev/null
@@ -1,317 +0,0 @@
-# Translation of OpenERP Server.
-# This file containt the translation of the following modules:
-# * account_budget_crossover
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: OpenERP Server 4.3.0Report-Msgid-Bugs-To: "
-"support@openerp.comPOT-Creation-Date: 2008-09-10 15:05:34+0000PO-Revision-"
-"Date: 2008-09-10 15:05:34+0000Last-Translator: <>Language-Team: MIME-"
-"Version: 1.0Content-Type: text/plain; charset=UTF-8Content-Transfer-"
-"Encoding: Plural-Forms:\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 16:34+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
-"Language-Team: LANGUAGE \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Utilisateur Responsable"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmé"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Le nom de l'objet doit commencer avec x_ et ne pas contenir de charactères "
-"spéciaux !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Imprimé à :"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmer"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Valider l'utilisateur"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Réf. du Compte Analytique"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Devise"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Brouillon"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "à"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimer les Budgets"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Imprimer"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Pourcentage"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validé"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Lignes de budget"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nom"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "État"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Description"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Compte Analytique :"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Réf. du Budget"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "au"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Montant Plannifié"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Écritures"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Valider"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Sélectionnez les Options"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Montant en Pratique"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Date de fin"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML non valide pour l'architecture de la vue"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Montant Théorique"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Annulé"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Réf; du Budget Principal"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Lignes"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Budget"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Sélectionnez la Période de Date"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Date de Paiement"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Budgets"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Fin de la période"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Début de la période"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimer le Résumé des Budgets"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Code"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Montant Théorique"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Budget :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Terminé"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Lignes de Budget"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Annuler"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Montant Total Planifié"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Date de début"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analyse de"
diff --git a/addons/addons/account_budget_crossover/i18n/gl.po b/addons/addons/account_budget_crossover/i18n/gl.po
deleted file mode 100644
index 743661d8f11..00000000000
--- a/addons/addons/account_budget_crossover/i18n/gl.po
+++ /dev/null
@@ -1,315 +0,0 @@
-# translation of account-budget-crossover-es.po to Galego
-# Translation of OpenERP Server.
-# This file containt the translation of the following modules:
-# * account_budget_crossover
-#
-# Frco. Javier Rial Rodríguez , 2009.
-msgid ""
-msgstr ""
-"Project-Id-Version: account-budget-crossover-es\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 14:49+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
-"Language-Team: Galego \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Usuario responsábel"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmada"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"¡O nome do obxecto debe comezar con x_ y e non conter ningún carácter "
-"especial!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Impreso o:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmar"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Usuario validado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Ref. conta analítica"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Moeda:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Borrador"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "ás"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimir presupostos"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Imprimir"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Porcentaxe"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Líñas de presuposto cruzado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nome"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Estado"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descrición"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Conta analítica:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Ref. presuposto"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "ata"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Importe previsto"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Asentos"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Seleccionar opcións"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Importe real"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Data final"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "¡XML non válido para a definición da vista!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Importe teórico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Cancelado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Ref. presuposto principal"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Liñas"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Presuposto"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Seleccione datas do período"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data de pago"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Presupostos"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Remate do período"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Presuposto cruzado"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Comezo do período"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimir resumen de presupuestos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Importe teórico"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Presuposto:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Realizado"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Liñas de presuposto"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Importe total previsto"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data inicial"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Análise desde"
diff --git a/addons/addons/account_budget_crossover/i18n/hr.po b/addons/addons/account_budget_crossover/i18n/hr.po
deleted file mode 100644
index d82462d47e7..00000000000
--- a/addons/addons/account_budget_crossover/i18n/hr.po
+++ /dev/null
@@ -1,313 +0,0 @@
-# Croatian translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 12:31+0000\n"
-"Last-Translator: Ivica Perić \n"
-"Language-Team: Croatian
\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Odgovorni korisnik"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Potvrđeno"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Naziv objekta mora počinjati sa x_ i ne smije sadržavati specijalne znakove!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Ispisano na:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Potvrdi"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Potvrdi korisnika"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Vezani analitički račun"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Valuta:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "U pripremi"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "na"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Ispis proračuna"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Ispis"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Postotak"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Potvrđeno"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Retci proračuna koje se križaju"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Naziv"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Stanje"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Opis"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Analitički račun:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Vezani proračun"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "do"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Planirani iznos"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Stavke"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Potvrdi"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Odaberite opcije"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Stvarni iznos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Završni datum"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "Neispravan XML za arhitekturu prikaza!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Teoretski iznos"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Ukupno:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Otkazano"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Vezni glavni proračun"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Retci"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Proračun"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Odaberi razdoblje datuma"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Datum plaćanja"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Proračuni"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Kraj razdoblja"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Križani proračun"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Početak razdoblja"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Ispis sume proračuna"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Šifra"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Teoretski iznos"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Proračun :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Završeno"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Retci proračuna"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Odustani"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Ukupni planirani iznos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Početni datum"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analiza od"
diff --git a/addons/addons/account_budget_crossover/i18n/it.po b/addons/addons/account_budget_crossover/i18n/it.po
deleted file mode 100644
index 5f2f6ec4f33..00000000000
--- a/addons/addons/account_budget_crossover/i18n/it.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Italian translation for openobject-addons
-# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 16:33+0000\n"
-"Last-Translator: michele \n"
-"Language-Team: Italian \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Utente responsabile"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confermato"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Il nome dell'oggetto deve iniziare per x_ e non deve contenere caratteri "
-"speciali!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Stampato a:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Conferma"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Convalida utente"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Rif. contabilità analitico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Valuta:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Bozza"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "a"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Stampa Budgets"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Stampa"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Percentuale"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Convalidato"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nome"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Stato"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descrizione"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Contabilità Analitica:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Rif Budget"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "a"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "importo pianificato"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Movimenti"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Convalida"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Seleziona le opzioni"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Data di fine"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Importo teorico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Totale:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Annullato"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Rif. Budget principale"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Righe"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Budget"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Seleziona il periodo"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data pagamento"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Budgets"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Fine Periodo"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Inizio periodo"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Stampa indice dei budgets"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Codice"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Importo teorico"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Budget:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Fatto"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Righe budget"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Annulla"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Importo totale pianificato"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data di inizio"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analisi da"
diff --git a/addons/addons/account_budget_crossover/i18n/ko.po b/addons/addons/account_budget_crossover/i18n/ko.po
deleted file mode 100644
index 8a925b5e607..00000000000
--- a/addons/addons/account_budget_crossover/i18n/ko.po
+++ /dev/null
@@ -1,312 +0,0 @@
-# Korean translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 16:32+0000\n"
-"Last-Translator: ekodaq \n"
-"Language-Team: Korean \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "책임 사용자"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "확정됨"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr "오브젝트 이름은 x_로 시작해야 하며, 특수 문자를 포함하면 안 됩니다 !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "인쇄 장소:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "확정"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "사용자 인증"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "분석 계정 참조"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "통화:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "초안"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "예산 인쇄"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "인쇄"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "퍼센트"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "검증됨"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "크로스오버 예산 라인"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "이름"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "상태"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "설명"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "분석 계정:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "예산 참조"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "계획된 금액"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "엔트리"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "검증"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "선택 옵션"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "실질 금액"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "종료일"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "유효하지 않은 뷰 아키텍처를 위한 XML !"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "이론적 금액"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "합계:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "취소됨"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "마스터 예산 참조"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "라인"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "예산"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "날짜와 기간 선택"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "결제된 날짜"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "예산"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "회기말"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "크로스오버 예산"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "기간 시작"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "예산 요약 인쇄"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "코드"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "이론적 금액"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "예산:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "완료"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "예산 라인"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "취소"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "총 계획 금액"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "시작 날짜"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "분석 출처"
diff --git a/addons/addons/account_budget_crossover/i18n/lt.po b/addons/addons/account_budget_crossover/i18n/lt.po
deleted file mode 100644
index d2ae461d3ef..00000000000
--- a/addons/addons/account_budget_crossover/i18n/lt.po
+++ /dev/null
@@ -1,312 +0,0 @@
-# Lithuanian translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 13:54+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
-"Language-Team: Lithuanian \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Patvirtinta"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr ""
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Pavirtinti"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Valiuta:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Juodraštis"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "iki"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Spausdinti"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Pavadinimas"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Būsena"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Aprašas"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "iki"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Įrašai"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Patvirtinti"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Pabaigos data"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Iš viso:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Nutrauktas"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Eilutės"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Biudžetas"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr ""
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Periodo pabaiga"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Periodo pradžia"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Kodas"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr ""
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Atlikta"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Atšaukti"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr ""
diff --git a/addons/addons/account_budget_crossover/i18n/nl.po b/addons/addons/account_budget_crossover/i18n/nl.po
deleted file mode 100644
index 568bf556e67..00000000000
--- a/addons/addons/account_budget_crossover/i18n/nl.po
+++ /dev/null
@@ -1,316 +0,0 @@
-# Translation of OpenERP Server.
-# This file containt the translation of the following modules:
-# * account_budget_crossover
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: OpenERP Server 4.3.0Report-Msgid-Bugs-To: "
-"support@openerp.comPOT-Creation-Date: 2008-09-10 15:07:19+0000PO-Revision-"
-"Date: 2008-09-10 15:07:19+0000Last-Translator: <>Language-Team: MIME-"
-"Version: 1.0Content-Type: text/plain; charset=UTF-8Content-Transfer-"
-"Encoding: Plural-Forms:\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-10-07 08:24+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
-"Language-Team: LANGUAGE \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Verantwoordelijke gebruiker"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Bevestigd"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"De objectnaam moet beginnen met x_ en mag geen speciale tekens bevatten!"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Afgedrukt op:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Bevestigen"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Gebruiker valideren"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Kostenplaats ref."
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Valuta:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Concept"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "op"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Budgetten afdrukken"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Afdrukken"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Percentage"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Gevalideerd"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Overgehevelde budgetregels"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Naam"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Status"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Omschrijving"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Kostenplaats:"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Budget ref."
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "naar"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Begroot bedrag"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Boekingen"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Valideren"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Kies opties"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Werkelijk bedrag"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Einddatum"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "Ongeldige XML voor weergave!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Theoretisch bedrag"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Totaal:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Geannuleerd"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Hoofdbudget ref."
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Regels"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Budget"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Kies datums periode"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Betalingsdatum"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Budgetten"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Einde van periode"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Overgeheveld budget"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Begin van periode"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Samenvatting van budgetten afdrukken"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Code"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Theoretisch bedrag"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Budget :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Gereed"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Budgetregels"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Annuleren"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Totaal begroot bedrag"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Begindatum"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analyse vanaf"
diff --git a/addons/addons/account_budget_crossover/i18n/pl.po b/addons/addons/account_budget_crossover/i18n/pl.po
deleted file mode 100644
index f5f0f734a8f..00000000000
--- a/addons/addons/account_budget_crossover/i18n/pl.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Polish translation for openobject-addons
-# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-11-17 09:22+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
-"Language-Team: Polish \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Użytkownik odpowiedzialny"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Potwierdzone"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Nazwa obiektu musi zaczynać się od x_ oraz nie może zawierać znaków "
-"specjalnych !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Drukowane na:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Potwierdź"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Waluta:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Projekt"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "na"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Drukuj budżety"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Drukuj"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Procentowo"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Zatwierdzony"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr ""
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nazwisko"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Status"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Opis"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Konto analityczne :"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "do"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Planowana kwota"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Zapisy"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Zatwierdź"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Opcje selekcji"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Kwota w praktyce"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Data końcowa"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML niewłaściwy dla tej architektury wyświetlania!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Kwota teoretyczna"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Suma:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Anulowano"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr ""
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Pozycje"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Budżet"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Wybierz daty okresu"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data zapłaty"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Budżety"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Koniec okresu"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr ""
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Początek okresu"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Drukuj podsumowanie budżetów"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Kod"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Kwota teoretyczna"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Budżet :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Wykonano"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Pozycje budżetu"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Anuluj"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Suma planowanych kwot"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data początkowa"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analiza od"
diff --git a/addons/addons/account_budget_crossover/i18n/pt.po b/addons/addons/account_budget_crossover/i18n/pt.po
deleted file mode 100644
index a30af715251..00000000000
--- a/addons/addons/account_budget_crossover/i18n/pt.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Portuguese translation for openobject-addons
-# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-11-29 00:15+0000\n"
-"Last-Translator: Paulino \n"
-"Language-Team: Portuguese \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Utilizador responsável"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmado"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"O nome do Objecto deve começar com x_ e não pode conter nenhum caractere "
-"especial !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Impresso em:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmar"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Validar utilizador"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Referençia da conta analítica"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Divisa"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Rascunho"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "às"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimir orçamentos"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Imprimir"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Percentagem"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Linhas de orçamentos cruzados"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nome"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Estado"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descrição"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Conta analítica"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Referencia de orçamento"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "para"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Quantidade planeada"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Movimentos"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validar"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Seleccione as opções"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Quantidade prática"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Data final"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML inválido para a arquitectura da vista"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Valor teórico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Cancelado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Referência do orçamento mestre"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Linhas"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Orçamento"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Seleccione o período de datas"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data do pagamento"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Orçamentos"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Fim do período"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Orçamento ultrapassado"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Início do período"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimir resumo do orçamento"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Valor teórico"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Orçamento:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Concluído"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Linhas do orçamento"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Montante total planeado."
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data de Início"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Análise de"
diff --git a/addons/addons/account_budget_crossover/i18n/pt_BR.po b/addons/addons/account_budget_crossover/i18n/pt_BR.po
deleted file mode 100644
index 95df26ef4ec..00000000000
--- a/addons/addons/account_budget_crossover/i18n/pt_BR.po
+++ /dev/null
@@ -1,313 +0,0 @@
-# Brazilian Portuguese translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 13:59+0000\n"
-"Last-Translator: Pedro_Maschio \n"
-"Language-Team: Brazilian Portuguese \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Usuário Responsável"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmado"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"O nome do Objeto deve começar com x_ e não deve conter carcateres especiais !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Impresso em:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmar"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Validar o Usuário"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Ref Conta Analítica"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Moeda:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Provisório"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "em"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Imprimir Orçamentos"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "imprimir"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Porcentagem"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validado"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "linhas do Orçamento Cruzado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nome"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Posição"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descrição"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Conta Analítica"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Ref Orçamento"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "para"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Valor Planejado"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "lançamentos"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validar"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Selecionar Opções"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Valor Prático"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Data Final"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML inválido para Visão Arquitetura!"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Valor Teórico"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Cancelado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Ref Orçamento Master"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Linhas"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Orçamento"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Selecionar as Datas do Período"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data do pagamento"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Orçamentos"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Final do período"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Orçamento Cruzado"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Início do período"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Imprimir Resumo dos Orçamentos"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Valor Teórico"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Or';çamento:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Completado"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Linhas do Orçamento"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Valor Total Planejado"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data de Início"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Análise de"
diff --git a/addons/addons/account_budget_crossover/i18n/ro.po b/addons/addons/account_budget_crossover/i18n/ro.po
deleted file mode 100644
index 2b81f5fd6a2..00000000000
--- a/addons/addons/account_budget_crossover/i18n/ro.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Romanian translation for openobject-addons
-# Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2009.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-11-17 09:22+0000\n"
-"Last-Translator: Fabien (Open ERP) \n"
-"Language-Team: Romanian \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2009-12-16 05:14+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,creating_user_id:0
-msgid "Responsible User"
-msgstr "Responsabil"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Confirmed"
-msgstr "Confirmat"
-
-#. module: account_budget_crossover
-#: constraint:ir.model:0
-msgid ""
-"The Object name must start with x_ and not contain any special character !"
-msgstr ""
-"Numele obiectului trebuie să înceapă cu x_ şi să nu conţină nici un caracter "
-"special !"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Printed at:"
-msgstr "Tipărit la:"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Confirm"
-msgstr "Confirmare"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,validating_user_id:0
-msgid "Validate User"
-msgstr "Validare utilizator"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,analytic_account_id:0
-msgid "Analytic Account Ref"
-msgstr "Ref. cont analitic"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Currency:"
-msgstr "Monedă:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Draft"
-msgstr "Ciornă"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "at"
-msgstr "la"
-
-#. module: account_budget_crossover
-#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
-#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
-#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
-msgid "Print Budgets"
-msgstr "Tipărire bugete"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,report:0
-#: wizard_button:wizard.crossovered.budget,init,report:0
-#: wizard_button:wizard.crossovered.budget.summary,init,report:0
-msgid "Print"
-msgstr "Tipărire"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,percentage:0
-msgid "Percentage"
-msgstr "Procentaj"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Validated"
-msgstr "Validat"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
-msgid "Crossovered Budget Lines"
-msgstr "Diviziuni bugetare încrucişate"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,name:0
-msgid "Name"
-msgstr "Nume"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,state:0
-msgid "Status"
-msgstr "Stare"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "%"
-msgstr "%"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Description"
-msgstr "Descriere"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-msgid "Analytic Account :"
-msgstr "Cont analitic :"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,crossovered_budget_id:0
-msgid "Budget Ref"
-msgstr "Ref. buget"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "to"
-msgstr "la"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,planned_amount:0
-msgid "Planned Amount"
-msgstr "Suma planificată"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
-msgid "Entries"
-msgstr "Înregistrări"
-
-#. module: account_budget_crossover
-#: view:crossovered.budget:0
-msgid "Validate"
-msgstr "Validare"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.crossovered.budget,init:0
-#: wizard_view:wizard.crossovered.budget.summary,init:0
-msgid "Select Options"
-msgstr "Selectează opţiuni"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-#: field:crossovered.budget.lines,practical_amount:0
-msgid "Practical Amount"
-msgstr "Sumă acceptabilă"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_to:0
-#: field:crossovered.budget.lines,date_to:0
-msgid "End Date"
-msgstr "Dată de finalizare"
-
-#. module: account_budget_crossover
-#: constraint:ir.ui.view:0
-msgid "Invalid XML for View Architecture!"
-msgstr "XML invalid pentru arhitectura afișării !"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,theoritical_amount:0
-msgid "Theoritical Amount"
-msgstr "Suma teoretică"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Total:"
-msgstr "Total:"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-msgid "Cancelled"
-msgstr "Anulat"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,general_budget_id:0
-msgid "Master Budget Ref"
-msgstr "Referinţă buget principal"
-
-#. module: account_budget_crossover
-#: view:account.analytic.account:0
-msgid "Lines"
-msgstr "Linii"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
-#: view:crossovered.budget:0
-msgid "Budget"
-msgstr "Buget"
-
-#. module: account_budget_crossover
-#: wizard_view:wizard.analytic.account.budget.report,init:0
-msgid "Select Dates Period"
-msgstr "Selectează perioada"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget.lines,paid_date:0
-msgid "Paid Date"
-msgstr "Data plăţii"
-
-#. module: account_budget_crossover
-#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
-msgid "Budgets"
-msgstr "Bugete"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
-#: wizard_field:wizard.crossovered.budget,init,date_to:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
-msgid "End of period"
-msgstr "Sfărşitul perioadei"
-
-#. module: account_budget_crossover
-#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
-msgid "Crossovered Budget"
-msgstr "Buget încrucişat"
-
-#. module: account_budget_crossover
-#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
-#: wizard_field:wizard.crossovered.budget,init,date_from:0
-#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
-msgid "Start of period"
-msgstr "Începutul perioadei"
-
-#. module: account_budget_crossover
-#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
-msgid "Print Summary of Budgets"
-msgstr "Tipărire sumar bugete"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,code:0
-msgid "Code"
-msgstr "Cod"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Theoretical Amount"
-msgstr "Suma teoretică"
-
-#. module: account_budget_crossover
-#: rml:crossovered.budget.report:0
-msgid "Budget :"
-msgstr "Buget :"
-
-#. module: account_budget_crossover
-#: selection:crossovered.budget,state:0
-#: view:crossovered.budget:0
-msgid "Done"
-msgstr "Gata"
-
-#. module: account_budget_crossover
-#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
-#: field:account.analytic.account,crossovered_budget_line:0
-#: field:account.budget.post,crossovered_budget_line:0
-#: field:crossovered.budget,crossovered_budget_line:0
-#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
-#: view:crossovered.budget:0
-#: view:account.analytic.account:0
-#: view:crossovered.budget.lines:0
-msgid "Budget Lines"
-msgstr "Linii buget"
-
-#. module: account_budget_crossover
-#: wizard_button:wizard.analytic.account.budget.report,init,end:0
-#: wizard_button:wizard.crossovered.budget,init,end:0
-#: wizard_button:wizard.crossovered.budget.summary,init,end:0
-#: view:crossovered.budget:0
-msgid "Cancel"
-msgstr "Renunțare"
-
-#. module: account_budget_crossover
-#: field:account.budget.post.dotation,tot_planned:0
-msgid "Total Planned Amount"
-msgstr "Suma totală planificată"
-
-#. module: account_budget_crossover
-#: field:crossovered.budget,date_from:0
-#: field:crossovered.budget.lines,date_from:0
-msgid "Start Date"
-msgstr "Data de început"
-
-#. module: account_budget_crossover
-#: rml:account.analytic.account.budget:0
-#: rml:crossovered.budget.report:0
-msgid "Analysis from"
-msgstr "Analiză de la"
diff --git a/addons/addons/account_budget_crossover/i18n/ru.po b/addons/addons/account_budget_crossover/i18n/ru.po
deleted file mode 100644
index 7f6628302e3..00000000000
--- a/addons/addons/account_budget_crossover/i18n/ru.po
+++ /dev/null
@@ -1,314 +0,0 @@
-# Russian translation for openobject-addons
-# Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2008.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2008-09-05 16:26+0000\n"
-"PO-Revision-Date: 2009-09-08 13:54+0000\n"
-"Last-Translator: Sergei Kostigoff \n"
-"Language-Team: Russian