From d47800d1b66b5ca3eb7ba841e496ae8f99f5d23f Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sat, 2 Jun 2012 18:25:23 +0200 Subject: [PATCH 01/49] ir.attachment move methods bzr revid: al@openerp.com-20120602162523-0zp9bzd6cqu8qgis --- openerp/addons/base/ir/ir_attachment.py | 104 ++++++++++++------------ 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 4978378f22a..9f8814430b8 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -26,6 +26,58 @@ from osv.orm import except_orm import tools class ir_attachment(osv.osv): + def _name_get_resname(self, cr, uid, ids, object, method, context): + data = {} + for attachment in self.browse(cr, uid, ids, context=context): + model_object = attachment.res_model + res_id = attachment.res_id + if model_object and res_id: + model_pool = self.pool.get(model_object) + res = model_pool.name_get(cr,uid,[res_id],context) + res_name = res and res[0][1] or False + if res_name: + field = self._columns.get('res_name',False) + if field and len(res_name) > field.size: + res_name = res_name[:field.size-3] + '...' + data[attachment.id] = res_name + else: + data[attachment.id] = False + return data + + _name = 'ir.attachment' + _columns = { + 'name': fields.char('Attachment Name',size=256, required=True), + 'datas': fields.binary('Data'), + 'datas_fname': fields.char('File Name',size=256), + 'description': fields.text('Description'), + 'res_name': fields.function(_name_get_resname, type='char', size=128, + string='Resource Name', store=True), + 'res_model': fields.char('Resource Object',size=64, readonly=True, + help="The database object this attachment will be attached to"), + 'res_id': fields.integer('Resource ID', readonly=True, + help="The record id this is attached to"), + 'url': fields.char('Url', size=512, oldname="link"), + 'type': fields.selection( + [ ('url','URL'), ('binary','Binary'), ], + 'Type', help="Binary File or external URL", required=True, change_default=True), + + 'create_date': fields.datetime('Date Created', readonly=True), + 'create_uid': fields.many2one('res.users', 'Owner', readonly=True), + 'company_id': fields.many2one('res.company', 'Company', change_default=True), + } + + _defaults = { + 'type': 'binary', + 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c), + } + + def _auto_init(self, cr, context=None): + super(ir_attachment, self)._auto_init(cr, context) + cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('ir_attachment_res_idx',)) + if not cr.fetchone(): + cr.execute('CREATE INDEX ir_attachment_res_idx ON ir_attachment (res_model, res_id)') + cr.commit() + def check(self, cr, uid, ids, mode, context=None, values=None): """Restricts the access to an ir.attachment, according to referred model In the 'document' module, it is overriden to relax this hard rule, since @@ -120,58 +172,6 @@ class ir_attachment(osv.osv): return self.pool.get('ir.actions.act_window').for_xml_id( cr, uid, 'base', 'action_attachment', context=context) - def _name_get_resname(self, cr, uid, ids, object, method, context): - data = {} - for attachment in self.browse(cr, uid, ids, context=context): - model_object = attachment.res_model - res_id = attachment.res_id - if model_object and res_id: - model_pool = self.pool.get(model_object) - res = model_pool.name_get(cr,uid,[res_id],context) - res_name = res and res[0][1] or False - if res_name: - field = self._columns.get('res_name',False) - if field and len(res_name) > field.size: - res_name = res_name[:field.size-3] + '...' - data[attachment.id] = res_name - else: - data[attachment.id] = False - return data - - _name = 'ir.attachment' - _columns = { - 'name': fields.char('Attachment Name',size=256, required=True), - 'datas': fields.binary('Data'), - 'datas_fname': fields.char('File Name',size=256), - 'description': fields.text('Description'), - 'res_name': fields.function(_name_get_resname, type='char', size=128, - string='Resource Name', store=True), - 'res_model': fields.char('Resource Object',size=64, readonly=True, - help="The database object this attachment will be attached to"), - 'res_id': fields.integer('Resource ID', readonly=True, - help="The record id this is attached to"), - 'url': fields.char('Url', size=512, oldname="link"), - 'type': fields.selection( - [ ('url','URL'), ('binary','Binary'), ], - 'Type', help="Binary File or external URL", required=True, change_default=True), - - 'create_date': fields.datetime('Date Created', readonly=True), - 'create_uid': fields.many2one('res.users', 'Owner', readonly=True), - 'company_id': fields.many2one('res.company', 'Company', change_default=True), - } - - _defaults = { - 'type': 'binary', - 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c), - } - - def _auto_init(self, cr, context=None): - super(ir_attachment, self)._auto_init(cr, context) - cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('ir_attachment_res_idx',)) - if not cr.fetchone(): - cr.execute('CREATE INDEX ir_attachment_res_idx ON ir_attachment (res_model, res_id)') - cr.commit() - ir_attachment() From 30ce97d206a92897df6fe4856fe148b01c587d46 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 7 Jun 2012 23:35:37 +0200 Subject: [PATCH 02/49] [IMP] ir_attachment external storage bzr revid: al@openerp.com-20120607213537-ajm4dihfkco8wssl --- openerp/addons/base/ir/ir_attachment.py | 117 +++++++++++++++++++++--- 1 file changed, 105 insertions(+), 12 deletions(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 9f8814430b8..dc3ea5faf87 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -26,6 +26,19 @@ from osv.orm import except_orm import tools class ir_attachment(osv.osv): + """Attachments are used to link binary files or url to any openerp document. + + External attachment storage + --------------------------- + + The 'data' function field (_data_get,data_set) is implemented using + _file_read, _file_write and _file_delete which can be overridden to + implement other storage engines, shuch methods should check for other + location pseudo uri (example: hdfs://hadoppserver) + + The default implementation is the file:dirname location that stores files + on the local filesystem using name based on their sha1 hash + """ def _name_get_resname(self, cr, uid, ids, object, method, context): data = {} for attachment in self.browse(cr, uid, ids, context=context): @@ -44,26 +57,106 @@ class ir_attachment(osv.osv): data[attachment.id] = False return data + # 'data' field implementation + def _full_path(self, cr, uid, location, path) + # location = 'file:filestore' + assert location.startswith('file:'), "Unhandled filestore location %s" % location + location = location[5:] + + # sanitize location name and path + location = re.sub('[.]','',location) + location = path.strip('/\\') + + path = re.sub('[.]','',path) + path = path.strip('/\\') + return os.path.join(tools.config['root_path'], location, cr.dbname, path) + + def _file_read(self, cr, uid, location, fname, bin_size=False) + full_path = self._full_path(cr, uid, location, fname) + r = '' + try: + if bin_size: + r = os.path.filesize(full_path) + else: + r = open(full_path).read().encode('base64') + except IOError: + _logger.error("_read_file reading %s",full_path) + return r + + def _file_write(self, cr, uid, location, value): + bin_value = value.decode('base64') + fname = hashlib.sha1(bin_value).hexdigest() + # scatter files across 1024 dirs + # we use '/' in the db (even on windows) + fname = fname[:3] + '/' + fname + full_path = self._full_path(cr, uid, location, fname) + try: + dirname = os.path.dirname(full_path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + open(full_path,'wb').write(bin_value) + except IOError: + _logger.error("_file_write writing %s",full_path) + return fname + + def _file_delete(self, cr, uid, location, fname, threshold=1): + count = self.search(cr, 1, [('store_fname','=',fname)], count=True) + if count <= threshold: + full_path = self._full_path(cr, uid, location, fname) + try: + os.unlink(full_path) + except IOError: + _logger.error("_file_delete could not unlink %s",full_path) + + def _data_get(self, cr, uid, ids, name, arg, context=None): + if context is None: + context = {} + result = {} + location = self.pool.get('ir.config_parameter').get_param('ir_attachment.location') + bin_size = context.get('bin_size', False) + for i in self.browse(cr, uid, ids, context=context): + if location and i.store_fname: + result[i.id] = self._file_read(cr, uid, location, i.store_fname, bin_size) + else: + result[i.id] = i.db_datas + return result + + def _data_set(self, cr, uid, id, name, value, arg, context=None): + if not value: + return True + if context is None: + context = {} + result = {} + location = self.pool.get('ir.config_parameter').get_param('ir_attachment.location') + bin_size = context.get('bin_size', False) + if path: + i = self.browse(cr, uid, id, context=context) + if i.store_fname: + self._file_delete(cr, uid, location, i.store_fname) + fname = self._file_write(cr, uid, location, value) + self.write(cr, uid, [id], {'store_fname': fname}, context=context) + else: + self.write(cr, uid, [id], {'db_datas': value}, context=context) + return True + _name = 'ir.attachment' _columns = { 'name': fields.char('Attachment Name',size=256, required=True), - 'datas': fields.binary('Data'), 'datas_fname': fields.char('File Name',size=256), 'description': fields.text('Description'), - 'res_name': fields.function(_name_get_resname, type='char', size=128, - string='Resource Name', store=True), - 'res_model': fields.char('Resource Object',size=64, readonly=True, - help="The database object this attachment will be attached to"), - 'res_id': fields.integer('Resource ID', readonly=True, - help="The record id this is attached to"), - 'url': fields.char('Url', size=512, oldname="link"), - 'type': fields.selection( - [ ('url','URL'), ('binary','Binary'), ], - 'Type', help="Binary File or external URL", required=True, change_default=True), - + 'res_name': fields.function(_name_get_resname, type='char', size=128, string='Resource Name', store=True), + 'res_model': fields.char('Resource Model',size=64, readonly=True, help="The database object this attachment will be attached to"), + 'res_id': fields.integer('Resource ID', readonly=True, help="The record id this is attached to"), 'create_date': fields.datetime('Date Created', readonly=True), 'create_uid': fields.many2one('res.users', 'Owner', readonly=True), 'company_id': fields.many2one('res.company', 'Company', change_default=True), + 'type': fields.selection( [ ('url','URL'), ('binary','Binary'), ], + 'Type', help="Binary File or URL", required=True, change_default=True), + 'url': fields.char('Url', size=1024), + # al: For the moment I keepi those shitty field names for backward compatibility with document + 'datas': fields.function(_data_get, fnct_inv=_data_set, string='File Content', type="binary", nodrop=True), + 'store_fname': fields.char('Stored Filename', size=256), + 'db_datas': fields.binary('Database Data'), } _defaults = { From 9c8aa2cb967a0ffd3d468604672e4ee2020fc558 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 8 Jun 2012 01:28:03 +0200 Subject: [PATCH 03/49] remove unsed cruft bzr revid: al@openerp.com-20120607232803-5263vpe6io9hm5h2 --- addons/document/README.txt | 8 ---- addons/document/__openerp__.py | 4 +- addons/document/board_document_demo.xml | 17 ------- addons/document/custom_report.xml | 6 --- addons/document/custom_view.xml | 14 ------ addons/document/dict_tools.py | 59 ------------------------- addons/document/document_demo.xml | 1 - 7 files changed, 3 insertions(+), 106 deletions(-) delete mode 100644 addons/document/README.txt delete mode 100644 addons/document/board_document_demo.xml delete mode 100644 addons/document/custom_report.xml delete mode 100644 addons/document/custom_view.xml delete mode 100644 addons/document/dict_tools.py diff --git a/addons/document/README.txt b/addons/document/README.txt deleted file mode 100644 index 34887026aeb..00000000000 --- a/addons/document/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -To be done: ------------ - -* Test to not create several times the same file / directory - -> May be put a sql_constraints uniq on several files - -> test through remove or put - -* Retest everything diff --git a/addons/document/__openerp__.py b/addons/document/__openerp__.py index d8e42703efc..f518dac9903 100644 --- a/addons/document/__openerp__.py +++ b/addons/document/__openerp__.py @@ -55,7 +55,9 @@ ATTENTION: 'report/document_report_view.xml', 'board_document_view.xml', ], - 'demo_xml': [ 'document_demo.xml','board_document_demo.xml'], + 'demo_xml': [ + 'document_demo.xml', + ], 'test': [ 'test/document_test2.yml', ], diff --git a/addons/document/board_document_demo.xml b/addons/document/board_document_demo.xml deleted file mode 100644 index 672fb5cb268..00000000000 --- a/addons/document/board_document_demo.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - diff --git a/addons/document/custom_report.xml b/addons/document/custom_report.xml deleted file mode 100644 index ebfe70e4c50..00000000000 --- a/addons/document/custom_report.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/addons/document/custom_view.xml b/addons/document/custom_view.xml deleted file mode 100644 index 45c4b337d99..00000000000 --- a/addons/document/custom_view.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - grcompta - - - - grcomptaadmin - - - - - - diff --git a/addons/document/dict_tools.py b/addons/document/dict_tools.py deleted file mode 100644 index e117b429f83..00000000000 --- a/addons/document/dict_tools.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright P. Christeas 2008-2010 -# Copyright 2010 OpenERP SA. http://www.openerp.com -# -# This program is Free Software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; version 2 of the License. -# -# 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 Lesser General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -############################################################################### - - -def dict_merge(*dicts): - """ Return a dict with all values of dicts - """ - res = {} - for d in dicts: - res.update(d) - return res - -def dict_merge2(*dicts): - """ Return a dict with all values of dicts. - If some key appears twice and contains iterable objects, the values - are merged (instead of overwritten). - """ - res = {} - for d in dicts: - for k in d.keys(): - if k in res and isinstance(res[k], (list, tuple)): - res[k] = res[k] + d[k] - elif k in res and isinstance(res[k], dict): - res[k].update(d[k]) - else: - res[k] = d[k] - return res - -def dict_filter(srcdic, keys, res=None): - ''' Return a copy of srcdic that has only keys set. - If any of keys are missing from srcdic, the result won't have them, - either. - @param res If given, result will be updated there, instead of a new dict. - ''' - if res is None: - res = {} - for k in keys: - if k in srcdic: - res[k] = srcdic[k] - return res - -#eof - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/document_demo.xml b/addons/document/document_demo.xml index b94048ec13c..fda125afb95 100644 --- a/addons/document/document_demo.xml +++ b/addons/document/document_demo.xml @@ -4,6 +4,5 @@ - From 098b40c759c18d57152a81e578a5df7d8843ab0e Mon Sep 17 00:00:00 2001 From: ThinkOpen Solutions Date: Tue, 24 Jul 2012 16:15:21 +0100 Subject: [PATCH 04/49] added l10n_pt bzr revid: trunk@thinkopensolutions.com-20120724151521-4grkrzkmogrqejk7 --- addons/l10n_pt/__init__.py | 22 + addons/l10n_pt/__openerp__.py | 48 + addons/l10n_pt/account_chart.xml | 3957 ++++++++++++++++++ addons/l10n_pt/account_chart_template.xml | 22 + addons/l10n_pt/account_tax_code_template.xml | 23 + addons/l10n_pt/account_taxes.xml | 38 + addons/l10n_pt/account_types.xml | 75 + addons/l10n_pt/fiscal_position_templates.xml | 23 + addons/l10n_pt/i18n/pt.po | 27 + addons/l10n_pt/l10n_chart_pt_wizard.xml | 16 + 10 files changed, 4251 insertions(+) create mode 100644 addons/l10n_pt/__init__.py create mode 100644 addons/l10n_pt/__openerp__.py create mode 100644 addons/l10n_pt/account_chart.xml create mode 100644 addons/l10n_pt/account_chart_template.xml create mode 100644 addons/l10n_pt/account_tax_code_template.xml create mode 100644 addons/l10n_pt/account_taxes.xml create mode 100644 addons/l10n_pt/account_types.xml create mode 100644 addons/l10n_pt/fiscal_position_templates.xml create mode 100644 addons/l10n_pt/i18n/pt.po create mode 100644 addons/l10n_pt/l10n_chart_pt_wizard.xml diff --git a/addons/l10n_pt/__init__.py b/addons/l10n_pt/__init__.py new file mode 100644 index 00000000000..673024708f5 --- /dev/null +++ b/addons/l10n_pt/__init__.py @@ -0,0 +1,22 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012 Thinkopen Solutions, Lda. All Rights Reserved +# http://www.thinkopensolutions.com. +# $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 . +# +############################################################################## diff --git a/addons/l10n_pt/__openerp__.py b/addons/l10n_pt/__openerp__.py new file mode 100644 index 00000000000..03e3b0e9baa --- /dev/null +++ b/addons/l10n_pt/__openerp__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012 Thinkopen Solutions, Lda. All Rights Reserved +# http://www.thinkopensolutions.com. +# $Id$ +# +# 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': 'Portugal - Chart of Accounts', + 'version': '0.011', + 'author': 'ThinkOpen Solutions', + 'website': 'http://www.thinkopensolutions.com/', + 'category': 'Localization/Account Charts', + 'description': 'Plano de contas SNC para Portugal', + 'depends': ['base', + 'base_vat', + 'account', + 'account_chart', + ], + 'init_xml': [], + 'update_xml': ['account_types.xml', + 'account_chart.xml', + 'account_tax_code_template.xml', + 'account_chart_template.xml', + 'fiscal_position_templates.xml', + 'account_taxes.xml', + 'l10n_chart_pt_wizard.xml', + ], + 'demo_xml': [], + 'installable': True, +} + diff --git a/addons/l10n_pt/account_chart.xml b/addons/l10n_pt/account_chart.xml new file mode 100644 index 00000000000..eaf322ab1b8 --- /dev/null +++ b/addons/l10n_pt/account_chart.xml @@ -0,0 +1,3957 @@ + + + + + + SNC Portugal + 0 + view + + + + + 1 + Meios financeiros líquidos + + view + + + + + 11 + Caixa + + other + + + + + 12 + Depósitos à ordem + + other + + + + + 13 + Outros depósitos bancários + + other + + + + + 14 + Outros instrumentos financeiros + + view + + + + + 141 + Derivados + + view + + + + + 1411 + Potencialmente favoráveis + + other + + + + + 1412 + Potencialmente desfavoráveis + + other + + + + + 142 + Instrumentos financeiros detidos para negociação + + view + + + + + 1421 + Activos financeiros + + other + + + + + 1422 + Passivos financeiros + + other + + + + + 143 + Outros activos e passivos financeiros + + view + + + + + 1431 + Outros activos financeiros + + other + + + + + 1432 + Outros passivos financeiros + + other + + + + + 2 + Contas a receber e a pagar + + view + + + + + 21 + Clientes + + view + + + + + 211 + Clientes c/c + + view + + + + + 2111 + Clientes gerais + + receivable + + + + + 2112 + Clientes empresa mãe + + receivable + + + + + 2113 + Clientes empresas subsidiárias + + receivable + + + + + 2114 + Clientes empresas associadas + + receivable + + + + + 2115 + Clientes empreendimentos conjuntos + + receivable + + + + + 2116 + Clientes outras partes relacionadas + + receivable + + + + + 212 + Clientes títulos a receber + + view + + + + + 2121 + Clientes gerais + + receivable + + + + + 2122 + Clientes empresa mãe + + receivable + + + + + 2123 + Clientes empresas subsidiárias + + receivable + + + + + 2124 + Clientes empresas associadas + + receivable + + + + + 2125 + Clientes empreendimentos conjuntos + + receivable + + + + + 2126 + Clientes outras partes relacionadas + + receivable + + + + + 218 + Adiantamentos de clientes + + receivable + + + + + 219 + Perdas por imparidade acumuladas + + receivable + + + + + 22 + Fornecedores + + view + + + + + 221 + Fornecedores c/c + + view + + + + + 2211 + Fornecedores gerais + + payable + + + + + 2212 + Fornecedores empresa mãe + + payable + + + + + 2213 + Fornecedores empresas subsidiárias + + payable + + + + + 2214 + Fornecedores empresas associadas + + payable + + + + + 2215 + Fornecedores empreendimentos conjuntos + + payable + + + + + 2216 + Fornecedores outras partes relacionadas + + payable + + + + + 222 + Fornecedores títulos a pagar + + view + + + + + 2221 + Fornecedores gerais + + payable + + + + + 2222 + Fornecedores empresa mãe + + payable + + + + + 2223 + Fornecedores empresas subsidiárias + + payable + + + + + 2224 + Fornecedores empresas associadas + + payable + + + + + 2225 + Fornecedores empreendimentos conjuntos + + payable + + + + + 2226 + Fornecedores outras partes relacionadas + + payable + + + + + 225 + Facturas em recepção e conferência + + other + + + + + 228 + Adiantamentos a fornecedores + + view + + + + + 229 + Perdas por imparidade acumuladas + + other + + + + + 23 + Pessoal + + view + + + + + 231 + Remunerações a pagar + + view + + + + + 2311 + Aos órgãos sociais + + other + + + + + 2312 + Ao pessoal + + other + + + + + 232 + Adiantamentos + + view + + + + + 2321 + Aos órgãos sociais + + other + + + + + 2322 + Ao pessoal + + other + + + + + 237 + Cauções + + view + + + + + 2371 + Dos órgãos sociais + + other + + + + + 2372 + Do pessoal + + other + + + + + 238 + Outras operações + + view + + + + + 2381 + Com os órgãos sociais + + other + + + + + 2382 + Com o pessoal + + view + + + + + 239 + Perdas por imparidade acumuladas + + other + + + + + 24 + Estado e outros entes públicos + + view + + + + + 241 + Imposto sobre o rendimento + + view + + + + + 242 + Retenção de impostos sobre rendimentos + + view + + + + + 243 + Imposto sobre o valor acrescentado + + view + + + + + 2431 + Iva suportado + + other + + + + + 2432 + Iva dedutível + + other + + + + + 2433 + Iva liquidado + + other + + + + + 2434 + Iva regularizações + + other + + + + + 2435 + Iva apuramento + + other + + + + + 2436 + Iva a pagar + + other + + + + + 2437 + Iva a recuperar + + other + + + + + 2438 + Iva reembolsos pedidos + + other + + + + + 2439 + Iva liquidações oficiosas + + other + + + + + 244 + Outros impostos + + other + + + + + 245 + Contribuições para a segurança social + + other + + + + + 246 + Tributos das autarquias locais + + other + + + + + 248 + Outras tributações + + other + + + + + 25 + Financiamentos obtidos + + view + + + + + 251 + Instituições de crédito e sociedades financeiras + + view + + + + + 2511 + Empréstimos bancários + + other + + + + + 2512 + Descobertos bancários + + other + + + + + 2513 + Locações financeiras + + other + + + + + 252 + Mercado de valores mobiliários + + view + + + + + 2521 + Empréstimos por obrigações + + other + + + + + 253 + Participantes de capital + + view + + + + + 2531 + Empresa mãe suprimentos e outros mútuos + + other + + + + + 2532 + Outros participantes suprimentos e outros mútuos + + other + + + + + 254 + Subsidiárias, associadas e empreendimentos conjuntos + + other + + + + + 258 + Outros financiadores + + other + + + + + 26 + Accionistas/sócios + + view + + + + + 261 + Accionistas c. subscrição + + other + + + + + 262 + Quotas não liberadas + + other + + + + + 263 + Adiantamentos por conta de lucros + + other + + + + + 264 + Resultados atribuídos + + other + + + + + 265 + Lucros disponíveis + + other + + + + + 266 + Empréstimos concedidos empresa mãe + + other + + + + + 268 + Outras operações + + other + + + + + 269 + Perdas por imparidade acumuladas + + other + + + + + 27 + Outras contas a receber e a pagar + + view + + + + + 271 + Fornecedores de investimentos + + view + + + + + 2711 + Fornecedores de investimentos contas gerais + + other + + + + + 2712 + Facturas em recepção e conferência + + other + + + + + 2713 + Adiantamentos a fornecedores de investimentos + + other + + + + + 272 + Devedores e credores por acréscimos + + view + + + + + 2721 + Devedores por acréscimo de rendimentos + + other + + + + + 2722 + Credores por acréscimos de gastos + + other + + + + + 273 + Benefícios pós emprego + + other + + + + + 274 + Impostos diferidos + + view + + + + + 2741 + Activos por impostos diferidos + + other + + + + + 2742 + Passivos por impostos diferidos + + other + + + + + 275 + Credores por subscrições não liberadas + + other + + + + + 276 + Adiantamentos por conta de vendas + + other + + + + + 278 + Outros devedores e credores + + other + + + + + 279 + Perdas por imparidade acumuladas + + other + + + + + 28 + Diferimentos + + view + + + + + 281 + Gastos a reconhecer + + other + + + + + 282 + Rendimentos a reconhecer + + other + + + + + 29 + Provisões + + view + + + + + 291 + Impostos + + other + + + + + 292 + Garantias a clientes + + other + + + + + 293 + Processos judiciais em curso + + other + + + + + 294 + Acidentes de trabalho e doenças profissionais + + other + + + + + 295 + Matérias ambientais + + other + + + + + 296 + Contratos onerosos + + other + + + + + 297 + Reestruturação + + other + + + + + 298 + Outras provisões + + other + + + + + 3 + Inventários e activos biológicos + + view + + + + + 31 + Compras + + view + + + + + 311 + Mercadorias + + other + + + + + 312 + Matérias primas, subsidiárias e de consumo + + other + + + + + 313 + Activos biológicos + + other + + + + + 317 + Devoluções de compras + + other + + + + + 318 + Descontos e abatimentos em compras + + other + + + + + 32 + Mercadorias + + view + + + + + 325 + Mercadorias em trânsito + + other + + + + + 326 + Mercadorias em poder de terceiros + + other + + + + + 329 + Perdas por imparidade acumuladas + + other + + + + + 33 + Matérias primas, subsidiárias e de consumo + + view + + + + + 331 + Matérias primas + + other + + + + + 332 + Matérias subsidiárias + + other + + + + + 333 + Embalagens + + other + + + + + 334 + Materiais diversos + + other + + + + + 335 + Matérias em trânsito + + other + + + + + 339 + Perdas por imparidade acumuladas + + other + + + + + 34 + Produtos acabados e intermédios + + view + + + + + 346 + Produtos em poder de terceiros + + other + + + + + 349 + Perdas por imparidade acumuladas + + other + + + + + 35 + Subprodutos, desperdícios, resíduos e refugos + + view + + + + + 351 + Subprodutos + + other + + + + + 352 + Desperdícios, resíduos e refugos + + other + + + + + 359 + Perdas por imparidade acumuladas + + other + + + + + 36 + Produtos e trabalhos em curso + + other + + + + + 37 + Activos biológicos + + view + + + + + 371 + Consumíveis + + view + + + + + 3711 + Animais + + other + + + + + 3712 + Plantas + + other + + + + + 372 + De produção + + view + + + + + 3721 + Animais + + other + + + + + 3722 + Plantas + + other + + + + + 38 + Reclassificação e regular. de invent. e activos biológ. + + view + + + + + 382 + Mercadorias + + other + + + + + 383 + Matérias primas, subsidiárias e de consumo + + other + + + + + 384 + Produtos acabados e intermédios + + other + + + + + 385 + Subprodutos, desperdícios, resíduos e refugos + + other + + + + + 386 + Produtos e trabalhos em curso + + other + + + + + 387 + Activos biológicos + + other + + + + + 39 + Adiantamentos por conta de compras + + other + + + + + 4 + Investimentos + + view + + + + + 41 + Investimentos financeiros + + view + + + + + 411 + Investimentos em subsidiárias + + view + + + + + 4111 + Participações de capital método da equiv. patrimonial + + other + + + + + 4112 + Participações de capital outros métodos + + other + + + + + 4113 + Empréstimos concedidos + + other + + + + + 412 + Investimentos em associadas + + view + + + + + 4121 + Participações de capital método da equiv. patrimonial + + other + + + + + 4122 + Participações de capital outros métodos + + other + + + + + 4123 + Empréstimos concedidos + + other + + + + + 413 + Investimentos em entidades conjuntamente controladas + + view + + + + + 4131 + Participações de capital método da equiv. patrimonial + + other + + + + + 4132 + Participações de capital outros métodos + + other + + + + + 4133 + Empréstimos concedidos + + other + + + + + 414 + Investimentos noutras empresas + + view + + + + + 4141 + Participações de capital + + other + + + + + 4142 + Empréstimos concedidos + + other + + + + + 415 + Outros investimentos financeiros + + view + + + + + 4151 + Detidos até à maturidade + + other + + + + + 4158 + Acções da sgm (6500x1,00) + + other + + + + + 419 + Perdas por imparidade acumuladas + + other + + + + + 42 + Propriedades de investimento + + view + + + + + 421 + Terrenos e recursos naturais + + other + + + + + 422 + Edifícios e outras construções + + other + + + + + 426 + Outras propriedades de investimento + + other + + + + + 428 + Depreciações acumuladas + + other + + + + + 429 + Perdas por imparidade acumuladas + + other + + + + + 43 + Activo fixos tangíveis + + view + + + + + 431 + Terrenos e recursos naturais + + other + + + + + 432 + Edifícios e outras construções + + other + + + + + 433 + Equipamento básico + + other + + + + + 434 + Equipamento de transporte + + other + + + + + 435 + Equipamento administrativo + + other + + + + + 436 + Equipamentos biológicos + + other + + + + + 437 + Outros activos fixos tangíveis + + other + + + + + 438 + Depreciações acumuladas + + other + + + + + 439 + Perdas por imparidade acumuladas + + other + + + + + 44 + Activos intangíveis + + view + + + + + 441 + Goodwill + + other + + + + + 442 + Projectos de desenvolvimento + + other + + + + + 443 + Programas de computador + + other + + + + + 444 + Propriedade industrial + + other + + + + + 446 + Outros activos intangíveis + + other + + + + + 448 + Depreciações acumuladas + + other + + + + + 449 + Perdas por imparidade acumuladas + + other + + + + + 45 + Investimentos em curso + + view + + + + + 451 + Investimentos financeiros em curso + + other + + + + + 452 + Propriedades de investimento em curso + + other + + + + + 453 + Activos fixos tangíveis em curso + + other + + + + + 454 + Activos intangíveis em curso + + other + + + + + 455 + Adiantamentos por conta de investimentos + + other + + + + + 459 + Perdas por imparidade acumuladas + + other + + + + + 46 + Activos não correntes detidos para venda + + view + + + + + 469 + Perdas por imparidade acumuladas + + other + + + + + 5 + Capital, reservas e resultados transitados + + view + + + + + 51 + Capital + + other + + + + + 52 + Acções (quotas) próprias + + view + + + + + 521 + Valor nominal + + other + + + + + 522 + Descontos e prémios + + other + + + + + 53 + Outros instrumentos de capital próprio + + other + + + + + 54 + Prémios de emissão + + other + + + + + 55 + Reservas + + view + + + + + 551 + Reservas legais + + other + + + + + 552 + Outras reservas + + other + + + + + 56 + Resultados transitados + + other + + + + + 57 + Ajustamentos em activos financeiros + + view + + + + + 571 + Relacionados com o método da equivalência patrimonial + + view + + + + + 5711 + Ajustamentos de transição + + other + + + + + 5712 + Lucros não atribuídos + + other + + + + + 5713 + Decorrentes de outras variações nos capitais próprios d + + other + + + + + 579 + Outros + + other + + + + + 58 + Excedentes de revalor. de activos fixos tangíveis e int + + view + + + + + 581 + Reavaliações decorrentes de diplomas legais + + view + + + + + 5811 + Antes de imposto sobre o rendimento + + other + + + + + 5812 + Impostos diferidos + + other + + + + + 589 + Outros excedentes + + view + + + + + 5891 + Antes de imposto sobre o rendimento + + other + + + + + 5892 + Impostos diferidos + + other + + + + + 59 + Outras variações no capital próprio + + view + + + + + 591 + Diferenças de conversão de demonstrações financeiras + + other + + + + + 592 + Ajustamentos por impostos diferidos + + other + + + + + 593 + Subsídios + + other + + + + + 594 + Doações + + other + + + + + 599 + Outras + + other + + + + + 6 + Gastos + + view + + + + + 61 + Custo das mercadorias vendidas e matérias consumidas + + view + + + + + 611 + Mercadorias + + other + + + + + 612 + Matérias primas, subsidiárias e de consumo + + other + + + + + 613 + Activos biológicos (compras) + + other + + + + + 62 + Fornecimentos e serviços externos + + view + + + + + 621 + Subcontratos + + other + + + + + 622 + Trabalhos especializados + + view + + + + + 6221 + Trabalhos especializados + + other + + + + + 6222 + Publicidade e propaganda + + other + + + + + 6223 + Vigilância e segurança + + other + + + + + 6224 + Honorários + + other + + + + + 6225 + Comissões + + other + + + + + 6226 + Conservação e reparação + + other + + + + + 6228 + Outros + + other + + + + + 623 + Materiais + + view + + + + + 6231 + Ferramentas e utensílios de desgaste rápido + + other + + + + + 6232 + Livros de documentação técnica + + other + + + + + 6233 + Material de escritório + + other + + + + + 6234 + Artigos de oferta + + other + + + + + 6238 + Outros + + other + + + + + 624 + Energia e fluídos + + view + + + + + 6241 + Electricidade + + other + + + + + 6242 + Combustíveis + + other + + + + + 6243 + Água + + other + + + + + 6248 + Outros + + other + + + + + 625 + Deslocações, estadas e transportes + + view + + + + + 6251 + Deslocações e estadas + + other + + + + + 6252 + Transporte de pessoal + + other + + + + + 6253 + Transportes de mercadorias + + other + + + + + 6258 + Outros + + other + + + + + 626 + Serviços diversos + + view + + + + + 6261 + Rendas e alugueres + + other + + + + + 6262 + Comunicação + + other + + + + + 6263 + Seguros + + other + + + + + 6264 + Royalties + + other + + + + + 6265 + Contencioso e notariado + + other + + + + + 6266 + Despesas de representação + + other + + + + + 6267 + Limpeza, higiene e conforto + + other + + + + + 6268 + Outros serviços + + other + + + + + 63 + Gastos com o pessoal + + view + + + + + 631 + Remunerações dos órgãos sociais + + other + + + + + 632 + Remunerações do pessoal + + other + + + + + 633 + Benefícios pós emprego + + view + + + + + 6331 + Prémios para pensões + + other + + + + + 6332 + Outros benefícios + + other + + + + + 634 + Indemnizações + + other + + + + + 635 + Encargos sobre remunerações + + other + + + + + 636 + Seguros de acidentes no trabalho e doenças profissionais + + other + + + + + 637 + Gastos de acção social + + other + + + + + 638 + Outros gastos com o pessoal + + other + + + + + 64 + Gastos de depreciação e de amortização + + view + + + + + 641 + Propriedades de investimento + + other + + + + + 642 + Activos fixos tangíveis + + other + + + + + 643 + Activos intangíveis + + other + + + + + 65 + Perdas por imparidade + + view + + + + + 651 + Em dívidas a receber + + view + + + + + 6511 + Clientes + + other + + + + + 6512 + Outros devedores + + other + + + + + 652 + Em inventários + + other + + + + + 653 + Em investimentos financeiros + + other + + + + + 654 + Em propriedades de investimento + + other + + + + + 655 + Em activos fixos tangíveis + + other + + + + + 656 + Em activos intangíveis + + other + + + + + 657 + Em investimentos em curso + + other + + + + + 658 + Em activos não correntes detidos para venda + + other + + + + + 66 + Perdas por reduções de justo valor + + view + + + + + 661 + Em instrumentos financeiros + + other + + + + + 662 + Em investimentos financeiros + + other + + + + + 663 + Em propriedades de investimento + + other + + + + + 664 + Em activos biológicos + + other + + + + + 67 + Provisões do período + + view + + + + + 671 + Impostos + + other + + + + + 672 + Garantias a clientes + + other + + + + + 673 + Processos judiciais em curso + + other + + + + + 674 + Acidentes de trabalho e doenças profissionais + + other + + + + + 675 + Matérias ambientais + + other + + + + + 676 + Contratos onerosos + + other + + + + + 677 + Reestruturação + + other + + + + + 678 + Outras provisões + + other + + + + + 68 + Outros gastos e perdas + + view + + + + + 681 + Impostos + + view + + + + + 6811 + Impostos directos + + other + + + + + 6812 + Impostos indirectos + + other + + + + + 6813 + Taxas + + other + + + + + 682 + Descontos de pronto pagamento concedidos + + other + + + + + 683 + Dívidas incobráveis + + other + + + + + 684 + Perdas em inventários + + view + + + + + 6841 + Sinistros + + other + + + + + 6842 + Quebras + + other + + + + + 6848 + Outras perdas + + other + + + + + 685 + Gastos e perdas em subsid. , assoc. e empreend. conjuntos + + view + + + + + 6851 + Cobertura de prejuízos + + other + + + + + 6852 + Aplicação do método da equivalência patrimonial + + other + + + + + 6853 + Alienações + + other + + + + + 6858 + Outros gastos e perdas + + other + + + + + 686 + Gastos e perdas nos restantes investimentos financeiros + + view + + + + + 6861 + Cobertura de prejuízos + + other + + + + + 6862 + Alienações + + other + + + + + 6868 + Outros gastos e perdas + + other + + + + + 687 + Gastos e perdas em investimentos não financeiros + + view + + + + + 6871 + Alienações + + other + + + + + 6872 + Sinistros + + other + + + + + 6873 + Abates + + other + + + + + 6874 + Gastos em propriedades de investimento + + other + + + + + 6878 + Outros gastos e perdas + + other + + + + + 688 + Outros + + view + + + + + 6881 + Correcções relativas a períodos anteriores + + other + + + + + 6882 + Donativos + + other + + + + + 6883 + Quotizações + + other + + + + + 6884 + Ofertas e amostras de inventários + + other + + + + + 6885 + Insuficiência da estimativa para impostos + + other + + + + + 6886 + Perdas em instrumentos financeiros + + other + + + + + 6888 + Outros não especificados + + other + + + + + 69 + Gastos e perdas de financiamento + + view + + + + + 691 + Juros suportados + + view + + + + + 6911 + Juros de financiamento obtidos + + other + + + + + 6918 + Outros juros + + other + + + + + 692 + Diferenças de câmbio desfavoráveis + + view + + + + + 6921 + Relativos a financiamentos obtidos + + other + + + + + 6928 + Outras + + other + + + + + 698 + Outros gastos e perdas de financiamento + + view + + + + + 6981 + Relativos a financiamentos obtidos + + other + + + + + 6988 + Outros + + other + + + + + 7 + Rendimentos + + view + + + + + 71 + Vendas + + view + + + + + 711 + Mercadoria + + other + + + + + 712 + Produtos acabados e intermédios + + other + + + + + 713 + Subprodutos, desperdícios, resíduos e refugos + + other + + + + + 714 + Activos biológicos + + other + + + + + 716 + Iva das vendas com imposto incluído + + other + + + + + 717 + Devoluções de vendas + + other + + + + + 718 + Descontos e abatimentos em vendas + + other + + + + + 72 + Prestações de serviços + + view + + + + + 721 + Serviço a + + other + + + + + 722 + Serviço b + + other + + + + + 725 + Serviços secundários + + other + + + + + 726 + Iva dos serviços com imposto incluído + + other + + + + + 728 + Descontos e abatimentos + + other + + + + + 73 + Variações nos inventários da produção + + view + + + + + 731 + Produtos acabados e intermédios + + other + + + + + 732 + Subprodutos, desperdícios, resíduos e refugos + + other + + + + + 733 + Produtos e trabalhos em curso + + other + + + + + 734 + Activos biológicos + + other + + + + + 74 + Trabalhos para a própria entidade + + view + + + + + 741 + Activos fixos tangíveis + + other + + + + + 742 + Activos intangíveis + + other + + + + + 743 + Propriedades de investimento + + other + + + + + 744 + Activos por gastos diferidos + + other + + + + + 75 + Subsídios à exploração + + view + + + + + 751 + Subsídios do estado e outros entes públicos + + other + + + + + 752 + Subsídios de outras entidades + + other + + + + + 76 + Reversões + + view + + + + + 761 + De depreciações e de amortizações + + view + + + + + 7611 + Propriedades de investimento + + other + + + + + 7612 + Activos fixos tangíveis + + other + + + + + 7613 + Activos intangíveis + + other + + + + + 762 + De perdas por imparidade + + view + + + + + 7621 + Em dívidas a receber + + view + + + + + 76211 + Clientes + + other + + + + + 76212 + Outros devedores + + other + + + + + 7622 + Em inventários + + other + + + + + 7623 + Em investimentos financeiros + + other + + + + + 7624 + Em propriedades de investimento + + other + + + + + 7625 + Em activos fixos tangíveis + + other + + + + + 7626 + Em activos intangíveis + + other + + + + + 7627 + Em investimentos em curso + + other + + + + + 7628 + Em activos não correntes detidos para venda + + other + + + + + 763 + De provisões + + view + + + + + 7631 + Impostos + + other + + + + + 7632 + Garantias a clientes + + other + + + + + 7633 + Processos judiciais em curso + + other + + + + + 7634 + Acidentes no trabalho e doenças profissionais + + other + + + + + 7635 + Matérias ambientais + + other + + + + + 7636 + Contratos onerosos + + other + + + + + 7637 + Reestruturação + + other + + + + + 7638 + Outras provisões + + other + + + + + 77 + Ganhos por aumentos de justo valor + + view + + + + + 771 + Em instrumentos financeiros + + other + + + + + 772 + Em investimentos financeiros + + other + + + + + 773 + Em propriedades de investimento + + other + + + + + 774 + Em activos biológicos + + other + + + + + 78 + Outros rendimentos e ganhos + + view + + + + + 781 + Rendimentos suplementares + + view + + + + + 7811 + Serviços sociais + + other + + + + + 7812 + Aluguer de equipamento + + other + + + + + 7813 + Estudos, projectos e assistência tecnológica + + other + + + + + 7814 + Royalties + + other + + + + + 7815 + Desempenho de cargos sociais noutras empresas + + other + + + + + 7816 + Outros rendimentos suplementares + + other + + + + + 782 + Descontos de pronto pagamento obtidos + + view + + + + + 783 + Recuperação de dívidas a receber + + other + + + + + 784 + Ganhos em inventários + + view + + + + + 7841 + Sinistros + + other + + + + + 7842 + Sobras + + other + + + + + 7848 + Outros ganhos + + other + + + + + 785 + Rendimentos e ganhos em subsidiárias, associadas e empr + + view + + + + + 7851 + Aplicação do método da equivalência patrimonial + + other + + + + + 7852 + Alienações + + other + + + + + 7858 + Outros rendimentos e ganhos + + other + + + + + 786 + Rendimentos e ganhos nos restantes activos financeiros + + view + + + + + 7861 + Diferenças de câmbio favoráveis + + other + + + + + 7862 + Alienações + + other + + + + + 7868 + Outros rendimentos e ganhos + + other + + + + + 787 + Rendimentos e ganhos em investimentos não financeiros + + view + + + + + 7871 + Alienações + + other + + + + + 7872 + Sinistros + + other + + + + + 7873 + Rendas e outros rendimentos em propriedades de investimento + + other + + + + + 7878 + Outros rendimentos e ganhos + + other + + + + + 788 + Outros + + view + + + + + 7881 + Correcções relativas a períodos anteriores + + other + + + + + 7882 + Excesso da estimativa para impostos + + other + + + + + 7883 + Imputação de subsídios para investimentos + + other + + + + + 7884 + Ganhos em outros instrumentos financeiros + + other + + + + + 7885 + Restituição de impostos + + other + + + + + 7888 + Outros não especificados + + other + + + + + 79 + Juros, dividendos e outros rendimentos similares + + view + + + + + 791 + Juros obtidos + + view + + + + + 7911 + De depósitos + + other + + + + + 7912 + De outras aplicações de meios financeiros líquidos + + other + + + + + 7913 + De financiamentos concedidos a associadas e emp. conjun + + other + + + + + 7914 + De financiamentos concedidos a subsidiárias + + other + + + + + 7915 + De financiamentos obtidos + + other + + + + + 7918 + De outros financiamentos obtidos + + other + + + + + 792 + Dividendos obtidos + + view + + + + + 7921 + De aplicações de meios financeiros líquidos + + other + + + + + 7922 + De associadas e empreendimentos conjuntos + + other + + + + + 7923 + De subsidiárias + + other + + + + + 7928 + Outras + + other + + + + + 798 + Outros rendimentos similares + + other + + + + + 8 + Resultados + + view + + + + + 81 + Resultado líquido do período + + view + + + + + 811 + Resultado antes de impostos + + other + + + + + 812 + Impostos sobre o rendimento do período + + view + + + + + 8121 + Imposto estimado para o período + + other + + + + + 8122 + Imposto diferido + + other + + + + + 818 + Resultado líquido + + other + + + + + 89 + Dividendos antecipados + + other + + + + + diff --git a/addons/l10n_pt/account_chart_template.xml b/addons/l10n_pt/account_chart_template.xml new file mode 100644 index 00000000000..25ddc500def --- /dev/null +++ b/addons/l10n_pt/account_chart_template.xml @@ -0,0 +1,22 @@ + + + + + + + + Portugal - Template do Plano de Contas SNC + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/l10n_pt/account_tax_code_template.xml b/addons/l10n_pt/account_tax_code_template.xml new file mode 100644 index 00000000000..5172dc6d0a8 --- /dev/null +++ b/addons/l10n_pt/account_tax_code_template.xml @@ -0,0 +1,23 @@ + + + + + + TP + Tax Paid + Tax Paid + + + + + + TP21 + TP21 + TP21 + + + + + + + diff --git a/addons/l10n_pt/account_taxes.xml b/addons/l10n_pt/account_taxes.xml new file mode 100644 index 00000000000..0f26057cc65 --- /dev/null +++ b/addons/l10n_pt/account_taxes.xml @@ -0,0 +1,38 @@ + + + + + + + IVA23 + IVA23 + 0.230000 + percent + + + + + IVA13 + IVA13 + 0.130000 + percent + + + + + IVA6 + IVA6 + 0.060000 + percent + + + + + IVA0 + IVA0 + 0.000000 + percent + + + + diff --git a/addons/l10n_pt/account_types.xml b/addons/l10n_pt/account_types.xml new file mode 100644 index 00000000000..4b8fbbb4514 --- /dev/null +++ b/addons/l10n_pt/account_types.xml @@ -0,0 +1,75 @@ + + + + + + Vista + view + none + + + + A Receber + receivable + income + unreconciled + + + + A Pagar + payable + expense + unreconciled + + + + Receitas + income + income + none + + + + Despesa + expense + expense + none + + + + Impostos + tax + expense + unreconciled + + + + Caixa + cash + asset + balance + + + + Activo + asset + asset + balance + + + + Passivo + equity + liability + balance + + + + Capital e Resultados + liability + liability + balance + + + + diff --git a/addons/l10n_pt/fiscal_position_templates.xml b/addons/l10n_pt/fiscal_position_templates.xml new file mode 100644 index 00000000000..176811d4ae5 --- /dev/null +++ b/addons/l10n_pt/fiscal_position_templates.xml @@ -0,0 +1,23 @@ + + + + + + + + Portugal + + + + + Europa + + + + + Extra-comunitário + + + + + diff --git a/addons/l10n_pt/i18n/pt.po b/addons/l10n_pt/i18n/pt.po new file mode 100644 index 00000000000..0aecddba0ab --- /dev/null +++ b/addons/l10n_pt/i18n/pt.po @@ -0,0 +1,27 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * l10n_pt +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.0.2\n" +"Report-Msgid-Bugs-To: support@openerp.com\n" +"POT-Creation-Date: 2011-10-17 11:13+0000\n" +"PO-Revision-Date: 2011-10-17 11:13+0000\n" +"Last-Translator: Thinkopen Solutions.>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_pt +#: model:ir.module.module,description:l10n_pt.module_meta_information +msgid "TODO: Descrever função" +msgstr "TODO: Descrever função" + +#. module: l10n_pt +#: model:ir.module.module,shortdesc:l10n_pt.module_meta_information +msgid "Portuguese Localization" +msgstr "Portugal - SNC Chart of Account" + diff --git a/addons/l10n_pt/l10n_chart_pt_wizard.xml b/addons/l10n_pt/l10n_chart_pt_wizard.xml new file mode 100644 index 00000000000..3f3cfd33a4c --- /dev/null +++ b/addons/l10n_pt/l10n_chart_pt_wizard.xml @@ -0,0 +1,16 @@ + + + + + + Generate Chart of Accounts for l10n_pt + Generate Chart of Accounts from a Chart Template. Please let the nuber to 0 for Portuguese charts. + This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial + Accounts/Generate Chart of Accounts from a Chart Template. + + automatic + + open + + + \ No newline at end of file From 0eee4e49bb09507443265064de6e7f06670f6f1e Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 8 Aug 2012 10:49:20 +0200 Subject: [PATCH 05/49] [ADD] l10n_it: purchase taxes included in the price bzr revid: leonardo.pistone@domsense.com-20120808084920-0tsjlx652an02lgk --- addons/l10n_it/data/account.tax.template.csv | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/l10n_it/data/account.tax.template.csv b/addons/l10n_it/data/account.tax.template.csv index 36c4f99db79..9ce6f02c7f5 100644 --- a/addons/l10n_it/data/account.tax.template.csv +++ b/addons/l10n_it/data/account.tax.template.csv @@ -41,11 +41,17 @@ id,description,chart_template_id:id,name,sequence,amount,parent_id:id,child_depe 00a,00a,l10n_it_chart_template_generic,Esente IVA (debito),,0,,False,percent,2601,2601,sale,template_impcode_riscossa_0,template_ivacode_riscossa_0,template_impcode_riscossa_0,template_ivacode_riscossa_0,-1,-1,False,, 00b,00b,l10n_it_chart_template_generic,Esente IVA (credito),,0,,False,percent,1601,1601,purchase,template_impcode_pagata_0,template_ivacode_pagata_0,template_impcode_pagata_0,template_ivacode_pagata_0,,,False,-1,-1 21a INC,21a INC,l10n_it_chart_template_generic,Iva al 21% (debito) INC,,0.21,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_21,l10n_it.template_ivacode_riscossa_21,l10n_it.template_impcode_riscossa_21,l10n_it.template_ivacode_riscossa_21,-1,-1,True,, +21b INC,21b INC,l10n_it_chart_template_generic,Iva al 21% (credito) INC,,0.21,,False,percent,1601,1601,purchase,template_impcode_pagata_21,template_ivacode_pagata_21,template_impcode_pagata_21,template_ivacode_pagata_21,,,True,-1,-1 20a INC,20a INC,l10n_it_chart_template_generic,Iva al 20% (debito) INC,,0.2,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_20,l10n_it.template_ivacode_riscossa_20,l10n_it.template_impcode_riscossa_20,l10n_it.template_ivacode_riscossa_20,-1,-1,True,, +20b INC,20b INC,l10n_it_chart_template_generic,Iva al 20% (credito) INC,,0.2,,False,percent,1601,1601,purchase,template_impcode_pagata_20,template_ivacode_pagata_20,template_impcode_pagata_20,template_ivacode_pagata_20,,,True,-1,-1 10a INC,10a INC,l10n_it_chart_template_generic,Iva al 10% (debito) INC,,0.1,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_10,l10n_it.template_ivacode_riscossa_10,l10n_it.template_impcode_riscossa_10,l10n_it.template_ivacode_riscossa_10,-1,-1,True,, +10b INC,10b INC,l10n_it_chart_template_generic,Iva al 10% (credito) INC,,0.1,,False,percent,1601,1601,purchase,template_impcode_pagata_10,template_ivacode_pagata_10,template_impcode_pagata_10,template_ivacode_pagata_10,,,True,-1,-1 12a INC,12a INC,l10n_it_chart_template_generic,Iva 12% (debito) INC,,0.12,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_12,l10n_it.template_ivacode_riscossa_12,l10n_it.template_impcode_riscossa_12,l10n_it.template_ivacode_riscossa_12,-1,-1,True,, +12b INC,12b INC,l10n_it_chart_template_generic,Iva 12% (credito) INC,,0.12,,False,percent,1601,1601,purchase,template_impcode_pagata_12,template_ivacode_pagata_12,template_impcode_pagata_12,template_ivacode_pagata_12,,,True,-1,-1 22a INC,22a INC,l10n_it_chart_template_generic,Iva 2% (debito) INC,,0.02,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_2,l10n_it.template_ivacode_riscossa_2,l10n_it.template_impcode_riscossa_2,l10n_it.template_ivacode_riscossa_2,-1,-1,True,, +22b INC,22b INC,l10n_it_chart_template_generic,Iva 2% (credito) INC,,0.02,,False,percent,1601,1601,purchase,template_impcode_pagata_2,template_ivacode_pagata_2,template_impcode_pagata_2,template_ivacode_pagata_2,,,True,-1,-1 4a INC,4a INC,l10n_it_chart_template_generic,Iva 4% (debito) INC,,0.04,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_4,l10n_it.template_ivacode_riscossa_4,l10n_it.template_impcode_riscossa_4,l10n_it.template_ivacode_riscossa_4,-1,-1,True,, +4b INC,4b INC,l10n_it_chart_template_generic,Iva 4% (credito) INC,,0.04,,False,percent,1601,1601,purchase,template_impcode_pagata_4,template_ivacode_pagata_4,template_impcode_pagata_4,template_ivacode_pagata_4,,,True,-1,-1 00a INC,00a INC,l10n_it_chart_template_generic,Esente IVA (debito) INC,,0,,False,percent,l10n_it.2601,l10n_it.2601,sale,l10n_it.template_impcode_riscossa_0,l10n_it.template_ivacode_riscossa_0,l10n_it.template_impcode_riscossa_0,l10n_it.template_ivacode_riscossa_0,-1,-1,True,, 2110,2110,l10n_it_chart_template_generic,Iva al 21% detraibile 10%,,0.21,,True,percent,,,purchase,template_impcode_pagata_21det10,,template_impcode_pagata_21det10,,,,False,-1,-1 2110a,2110a,l10n_it_chart_template_generic,Iva al 21% detraibile 10% (D),2,0,2110,False,balance,1601,1601,purchase,,template_ivacode_pagata_21det10,,template_ivacode_pagata_21det10,,,False,, From 2f774e42b55504d6f15ed91efa777c75c975e11a Mon Sep 17 00:00:00 2001 From: Cubic ERP Date: Wed, 14 Nov 2012 11:49:46 -0500 Subject: [PATCH 06/49] [ADD] l10n_bo bzr revid: info@cubicerp.com-20121114164946-zry0w8fyn4vhjvqf --- addons/l10n_bo/__init__.py | 32 +++ addons/l10n_bo/__openerp__.py | 52 +++++ addons/l10n_bo/account_tax.xml | 50 +++++ addons/l10n_bo/account_tax_code.xml | 94 +++++++++ addons/l10n_bo/i18n/es.po | 72 +++++++ addons/l10n_bo/i18n/es_BO.po | 53 +++++ addons/l10n_bo/i18n/l10n_bo.pot | 35 ++++ addons/l10n_bo/l10n_bo_chart.xml | 257 +++++++++++++++++++++++++ addons/l10n_bo/l10n_bo_wizard.xml | 10 + addons/l10n_bo/static/src/img/icon.png | Bin 0 -> 1846 bytes 10 files changed, 655 insertions(+) create mode 100644 addons/l10n_bo/__init__.py create mode 100644 addons/l10n_bo/__openerp__.py create mode 100644 addons/l10n_bo/account_tax.xml create mode 100644 addons/l10n_bo/account_tax_code.xml create mode 100644 addons/l10n_bo/i18n/es.po create mode 100644 addons/l10n_bo/i18n/es_BO.po create mode 100644 addons/l10n_bo/i18n/l10n_bo.pot create mode 100644 addons/l10n_bo/l10n_bo_chart.xml create mode 100644 addons/l10n_bo/l10n_bo_wizard.xml create mode 100644 addons/l10n_bo/static/src/img/icon.png diff --git a/addons/l10n_bo/__init__.py b/addons/l10n_bo/__init__.py new file mode 100644 index 00000000000..92da5dbf966 --- /dev/null +++ b/addons/l10n_bo/__init__.py @@ -0,0 +1,32 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (c) 2011 Cubic ERP - Teradata SAC. (http://cubicerp.com). +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# 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 2 +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_bo/__openerp__.py b/addons/l10n_bo/__openerp__.py new file mode 100644 index 00000000000..d55777d198f --- /dev/null +++ b/addons/l10n_bo/__openerp__.py @@ -0,0 +1,52 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012 Cubic ERP - Teradata SAC (). +# +# 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": "Bolivia Localization Chart Account", + "version": "1.0", + "description": """ +Bolivian accounting chart and tax localization. + +Plan contable boliviano e impuestos de acuerdo a disposiciones vigentes + + """, + "author": "Cubic ERP", + "website": "http://cubicERP.com", + "category": "Localization/Account Charts", + "depends": [ + "account_chart", + ], + "data":[ + "account_tax_code.xml", + "l10n_bo_chart.xml", + "account_tax.xml", + "l10n_bo_wizard.xml", + ], + "demo_xml": [ + ], + "update_xml": [ + ], + "active": False, + "installable": True, + "certificate" : "", + 'images': ['images/config_chart_l10n_bo.jpeg','images/l10n_bo_chart.jpeg'], + +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_bo/account_tax.xml b/addons/l10n_bo/account_tax.xml new file mode 100644 index 00000000000..6c0ca68c4ba --- /dev/null +++ b/addons/l10n_bo/account_tax.xml @@ -0,0 +1,50 @@ + + + + + + + IVA 13% Venta + 0.130000 + percent + sale + 1 + + + + + + + + + + IVA 13% Compra + 0.130000 + percent + purchase + 1 + + + + + + + + + + + IT 3% + 0.30000 + percent + sale + 0 + + + + + + + + + + diff --git a/addons/l10n_bo/account_tax_code.xml b/addons/l10n_bo/account_tax_code.xml new file mode 100644 index 00000000000..9b3fa8cf6e3 --- /dev/null +++ b/addons/l10n_bo/account_tax_code.xml @@ -0,0 +1,94 @@ + + + + + + Bolivia Impuestos + + + Base Imponible + + + + Base Imponible - Ventas + + + + Impuesto al Valor Agregado con IVA + + + + Ventas NO Gravadas (Exoneradas) + + + + Ventas Gravadas Fuera de Ámbito + + + + Base Imponible - Compras + + + + Compras Gravadas con IVA + + + + Compras NO Gravadas (Exoneradas) + + + + Compras Gravadas Fuera de Ámbito + + + + + Impuesto al Valor Agregado (IVA) Total a Pagar + + + + Impuesto Pagado + + + + Impuesto Pagado IVA + + -1 + + + Impuesto Pagado de Exonerados al IVA + + -1 + + + Impuesto Pagado Fuera de Ámbito + + -1 + + + Impuesto Cobrado + + + + Impuesto Cobrado IVA + + + + Impuesto Cobrado de Exonerados al IVA + + + + Impuesto Cobrado Fuera de Ámbito + + + + + Impuesto a las Transacciones IT (3%) + + + + Impuesto a las Utilidades de la Empresa IUE (25%) + + + + diff --git a/addons/l10n_bo/i18n/es.po b/addons/l10n_bo/i18n/es.po new file mode 100644 index 00000000000..9d12c53b71c --- /dev/null +++ b/addons/l10n_bo/i18n/es.po @@ -0,0 +1,72 @@ +# Spanish translation for openobject-addons +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-11 11:15+0000\n" +"PO-Revision-Date: 2011-01-10 13:46+0000\n" +"Last-Translator: Yury Tello \n" +"Language-Team: Spanish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-01-15 05:56+0000\n" +"X-Generator: Launchpad (build 12177)\n" + +#. module: l10n_ar +#: model:ir.module.module,description:l10n_ar.module_meta_information +msgid "" +"\n" +" Bolivian Accounting : chart of Account\n" +" " +msgstr "" +"\n" +" Contabilidad Peruana : Plan de cuentas\n" +" " + +#. module: l10n_bo +#: model:ir.module.module,shortdesc:l10n_bo.module_meta_information +msgid "Bolivian Chart of Account" +msgstr "Plan de cuentas de Boliviana" + +#. module: l10n_bo +#: model:ir.actions.todo,note:l10n_bo.config_call_account_template_in_minimal +msgid "" +"Generate Chart of Accounts from a Chart Template. You will be asked to pass " +"the name of the company, the chart template to follow, the no. of digits to " +"generate the code for your accounts and Bank account, currency to create " +"Journals. Thus,the pure copy of chart Template is generated.\n" +"\tThis is the same wizard that runs from Financial " +"Management/Configuration/Financial Accounting/Financial Accounts/Generate " +"Chart of Accounts from a Chart Template." +msgstr "" +"Generar el plan contable a partir de una plantilla de plan contable. Se le " +"pedirá el nombre de la compañia, la plantilla de plan contable a utilizar, " +"el número de dígitos para generar el código de las cuentas y de la cuenta " +"bancaria, la moneda para crear los diarios. Así pues, se genere una copia " +"exacta de la plantilla de plan contable.\n" +"\tEste es el mismo asistente que se ejecuta desde Contabilidad y finanzas / " +"Configuración / Contabilidad financiera / Cuentas financieras / Generar el " +"plan contable a partir de una plantilla de plan contable." + +#~ msgid "Liability" +#~ msgstr "Pasivo" + +#~ msgid "Asset" +#~ msgstr "Activo" + +#~ msgid "Closed" +#~ msgstr "Cerrado" + +#~ msgid "Income" +#~ msgstr "Ingreso" + +#~ msgid "Expense" +#~ msgstr "Gasto" + +#~ msgid "View" +#~ msgstr "Vista" diff --git a/addons/l10n_bo/i18n/es_BO.po b/addons/l10n_bo/i18n/es_BO.po new file mode 100644 index 00000000000..5dc0ecb42be --- /dev/null +++ b/addons/l10n_bo/i18n/es_BO.po @@ -0,0 +1,53 @@ +# Spanish (Paraguay) translation for openobject-addons +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-11 11:15+0000\n" +"PO-Revision-Date: 2011-03-21 16:23+0000\n" +"Last-Translator: FULL NAME \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-03-22 04:36+0000\n" +"X-Generator: Launchpad (build 12559)\n" + +#. module: l10n_bo +#: model:ir.module.module,description:l10n_bo.module_meta_information +msgid "" +"\n" +" Bolivian Accounting : chart of Account\n" +" " +msgstr "" +"\n" +" Contabilidad boliviana : Plan de cuentas\n" +" " + +#. module: l10n_ar +#: model:ir.module.module,shortdesc:l10n_ar.module_meta_information +msgid "Bolivian Chart of Account" +msgstr "Plan de cuentas de Bolivia" + +#. module: l10n_ar +#: model:ir.actions.todo,note:l10n_ar.config_call_account_template_in_minimal +msgid "" +"Generate Chart of Accounts from a Chart Template. You will be asked to pass " +"the name of the company, the chart template to follow, the no. of digits to " +"generate the code for your accounts and Bank account, currency to create " +"Journals. Thus,the pure copy of chart Template is generated.\n" +"\tThis is the same wizard that runs from Financial " +"Management/Configuration/Financial Accounting/Financial Accounts/Generate " +"Chart of Accounts from a Chart Template." +msgstr "" +"Generar el plan contable a partir de una plantilla de plan contable. Se le " +"pedirá el nombre de la compañía, la plantilla de plan contable a utilizar, " +"el número de dígitos para generar el código de las cuentas y de la cuenta " +"bancaria, la moneda para crear los diarios. Así pues, se genere una copia " +"exacta de la plantilla de plan contable.\n" +"\tEste es el mismo asistente que se ejecuta desde Contabilidad y finanzas / " +"Configuración / Contabilidad financiera / Cuentas financieras / Generar el " +"plan contable a partir de una plantilla de plan contable." diff --git a/addons/l10n_bo/i18n/l10n_bo.pot b/addons/l10n_bo/i18n/l10n_bo.pot new file mode 100644 index 00000000000..8d117342eea --- /dev/null +++ b/addons/l10n_bo/i18n/l10n_bo.pot @@ -0,0 +1,35 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * l10n_ar +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.1.0-rc1\n" +"Report-Msgid-Bugs-To: soporte@cubicerp.com\n" +"POT-Creation-Date: 2011-01-11 11:15:31+0000\n" +"PO-Revision-Date: 2011-01-11 11:15:31+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_ar +#: model:ir.module.module,description:l10n_ar.module_meta_information +msgid "\n" +" Argentinian Accounting : chart of Account\n" +" " +msgstr "" + +#. module: l10n_ar +#: model:ir.module.module,shortdesc:l10n_ar.module_meta_information +msgid "Argentinian Chart of Account" +msgstr "" + +#. module: l10n_ar +#: model:ir.actions.todo,note:l10n_ar.config_call_account_template_in_minimal +msgid "Generate Chart of Accounts from a Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated.\n" +" This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template." +msgstr "" + diff --git a/addons/l10n_bo/l10n_bo_chart.xml b/addons/l10n_bo/l10n_bo_chart.xml new file mode 100644 index 00000000000..dc9e9598909 --- /dev/null +++ b/addons/l10n_bo/l10n_bo_chart.xml @@ -0,0 +1,257 @@ + + + + + + + noneviewVistanone + + balanceBG_ACC_10Caja y Bancosasset + detailBG_ACC_20Inversiones al Valor Razonable y Disponibleasset + unreconciledBG_ACC_30Créditos o Exigiblesasset + unreconciledBG_ACC_50Otros Créditosasset + balanceBG_ACC_60Bienes de Cambio o Realizablezasset + + detailBG_ACN_10Otros Creditos no Corrientesasset + detailBG_ACN_40Inversiones Permanentesasset + balanceBG_ACN_50Bienes de Usoasset + + unreconciledBG_PAC_10Deudas Bancarias y Financierasliability + unreconciledBG_PAC_20Cuentas por Pagarliability + unreconciledBG_PAC_35Deudas del Personal e Instituciones de Seguridad Socialliability + unreconciledBG_PAC_40Deudas Fiscalesliability + unreconciledBG_PAC_45Otros Pasivosliability + + unreconciledBG_PAN_10Deudas Bancarias y Financieras a Largo Plazoliability + unreconciledBG_PAN_20Otros Pasivos a Largo Plazoliability + unreconciledBG_PAN_40Previsiones y Provisionesliability + + balanceBG_PTN_10Patrimonio o Capital Contableliability + + noneEGP_FU_010Ventas de Mercaderia en Generalincome + noneEGP_FU_030Costo de Ventas de Mercaderíasexpense + noneEGP_FU_040Gastos de Administraciónexpense + noneEGP_FU_050Gastos de Distribución o Ventasexpense + unreconciledEGP_FU_060Ingresos Financierosincome + noneEGP_FU_070Gastos Financierosexpense + noneEGP_FU_080Otros Ingresosincome + noneEGP_FU_090Otros Gastosexpense + noneEGP_FU_120Tributosexpense + noneEGP_FU_160Ganancia (Pérdida) Neta del Ejercicioincome + + noneEGP_NA_010Compras de Bienes de Usonone + + noneORDCuentas de Ordennone + + noneNCLASIFICADOCuentas No Clasificadasnone + + + + + Bolivia + pcge + + view + + + Cuentas Patrimoniales + .1.BG + + + view + + + ACTIVO1view + Caja y Bancos11view + Caja y Bancos - Caja111view + Caja y bancos - Caja / efectivo en BOB111.001liquidity + Caja y Bancos - Moneda Extranjera112view + Caja y bancos - Caja / efectivo USD112.001liquidity + Caja y Bancos - Fondos fijos113view + Caja y ...- Fondos fijos / caja chica 01 BOB113.001liquidity + Caja y Bancos - Cuentas Corrientes114view + Caja y Bancos.../ BCO. CTA CTE BOB114.001liquidity + Caja y bancos - Valores a Depositar 115other + Caja y bancos - Recaudaciones a Depositar 116other + Créditos fiscal IVA12view + Créditos fiscal IVA / Deudores por Ventas121receivable1 + Créditos fiscal IVA / Deudores Morosos122receivable1 + Créditos fiscal IVA / Deudores en Gestión Judicial123receivable + Créditos fiscal IVA / Deudores Varios124receivable + Créditos fiscal IVA / (-) Previsión para Ds. Incobrables125receivable1 + Otros Créditos13view + Otros Créditos / Préstamos otorgados131receivable + Otros Créditos / Anticipos a Proveedores132receivable + Otros Créditos / Anticipo de Impuestos133receivable + Otros Créditos / Anticipo al Personal134receivable + Otros Créditos / Alquileres Pagados por Adelantado135receivable + Otros Créditos / Intereses Pagados por Adelantado136receivable + Otros Créditos / Accionistas137receivable + Otros Créditos / (-) Previsión para Descuentos138receivable + Otros Créditos / (-) Intereses (+) a Devengar139receivable + Inversiones14view + Inversiones / Acciones Transitorias141other + Inversiones / Acciones Permanentes142other + Inversiones / Títulos Públicos143other + Inversiones / (-) Previsión para Devalorización de Acciones144other + Bienes de Cambio o Realizables15view + Bienes de Cambio - Mercaderías151view + Bienes de Cambio - Existencia de Mercaderías / Categoria de productos 01151.01other + Bienes de Cambio - Mercaderías en Tránsito152other + Materias primas153other + Productos en Curso de Elaboración154other + Productos Elaborados155other + Materiales Varios 156other + (-) Desvalorización de Existencias157other + Bienes de Uso16view + Bienes de Uso / Inmuebles161other + Bienes de Uso / Maquinaria162other + Bienes de Uso / Equipos163other + Bienes de Uso / Vehículos164other + Bienes de Uso / (-) Depreciación Acumulada Bienes de Uso165other + Bienes Intangibles17view + Bienes Intangibles / Marcas de Fábrica171other + Bienes Intangibles / Concesiones y Franquicias172other + Bienes Intangibles / Patentes de Invención173other + Bienes Intangibles / (-) Amortización Acumulada174other + PASIVO2view + Deudas Comerciales21view + Deudas Comerciales / Proveedores211payable1 + Deudas Comerciales / Anticipos de Clientes212payable1 + Deudas Comerciales / (-) Intereses a Devengar por Compras al Crédito213payable1 + Deudas Bancarias y Financieras22view + Deudas Bancarias y Financieras / Adelantos en Cuenta Corriente221payable + Deudas Bancarias y Financieras / Prestamos222payable + Deudas Bancarias y Financieras / Obligaciones a Pagar223payable + Deudas Bancarias y Financieras / Intereses a Pagar224payable + Deudas Bancarias y Financieras / Letras de Cambio Emitidos225payable + Deudas Fiscales23view + Deudas Fiscales / IVA a Pagar231other + Deudas Fiscales / Impuesto a las Transacciones IT a Pagar232other + Deudas Fiscales / Impuesto a las Utilidades de Empresas IUE a Pagar233other + Deudas Sociales24view + Deudas Sociales / Sueldos a Pagar241payable + Deudas Sociales / Cargas Sociales a Pagar242payable + Deudas Sociales / Provisión para Sueldo Anual Complementario243payable + Deudas Sociales / Retenciones a Depositar244payable + Otras Deudas25view + Otras Deudas / Acreedores Varios251payable + Otras Deudas / Dividendos a Pagar252payable + Otras Deudas / Cobros por Adelantado253payable + Otras Deudas / Honorarios Directores y Síndicos a Pagar254payable + Previsiones26view + Previsiones / Previsión Indemnización por Despidos261payable + Previsiones / Previsión para juicios Pendientes262payable + Previsiones / Previsión para Garantías por Service263payable + PATRIMONIO NETO3view + Capital Social31view + Capital social / Capital Suscripto311other + Capital social / Acciones en Circulación312other + Capital social / Dividendos a Distribuir en Acciones313other + Capital social / (-) Descuento de Emisión de Acciones314other + Aportes No Capitalizados32view + Aportes No Capitalizados / Primas de Emsión321other + Aportes No Capitalizados / Aportes Irrevocables Futura Suscripción de Acciones322other + Ajustes al Patrimonio33view + Ajustes al Patrimonio / Revaluo Técnico de Bienes de Uso331other + Ganancias Reservadas34view + Reserva Legal341other + Reserva Estatutaria342other + Reserva Facultativa343other + Reserva para Renovación de Bienes de Uso344other + Resultados No Asignados35view + Resultados Acumulados351other + Resultados Acumulados del Ejercicio Anterior352other + Ganancias y Pérdidas del Ejercicio353other + Resultado del Ejercicio354other + + + Cuentas de Resultado + .2.GP + + + view + + + RESULTADOS POSITIVOS4view + Resultados Positivos Ordinarios41view + Ventas411view + Ventas - Categoria de productos 01411.01other + Intereses gananados, obtenidos, percibidos412other + Alquileres gananados, obtenidos, percibidos413other + Comisiones gananados, obtenidos, percibidos414other + Descuentos gananados, obtenidos, percibidos415other + Renta de Títulos Públicos416other + Honorarios gananados, obtenidos, percibidos417other + Ganancia Venta de Acciones418other + Resultados Positivos Extraordinarios42view + Recupero de Rezagos421other + Recupero de Deudores Incobrables422other + Ganancia Venta de Bienes de Uso423other + Donaciones obtenidas, ganandas, percibidas424other + Ganancia Venta Inversiones Permanentes425other + RESULTADOS NEGATIVOS5view + Resultados Negativos Ordinarios51view + Costo de Mercaderías Vendidas511view + Costo de Mercaderías Vendidas - Categoria de productos 01511.01other + Gastos en Depreciación de Bienes de Uso512other + Gastos en Amortización513other + Gastos en Sueldos y Jormales514other + Gastos en Cargas Sociales515other + Gastos en Impuestos516other + Gastos Bancarios517other + Gastos en Servicios Públicos518other + Gastos de Publicidad y Propaganda519other + Resultados Negativos Extraordinarios52view + Gastos en Siniestros521other + Donaciones Cedidas, Otorgadas522other + Pérdida Venta Bienes de Uso523other + + + Cuentas de Movimiento + .3.CC + + + view + + + Compras61view + Compras - Categoria de productos 0161.01other + Costos de Producción62other + Gastos de Administración63other + Gastos de Comercialización64other + + + Cuentas de Orden + .4.CO + + + view + + + CUENTAS DE ORDEN DEUDORAS71view + Mercaderias Recibidas en Consignación711other + Depósito de Valores Recibos en Garantía712other + Garantias Otorgadas713other + Documentos Descontados714other + Documentos Endosados715other + CUENTAS DE ORDEN ACREEDORAS72view + Comitente por Mercaderias Recibidas en Consignación721other + Acreedor por Garantías Otorgadas722other + Acreedor por Documentos Descontados723other + + + Bolivia - Plan de Cuentas + + + + + + + + + + + + + diff --git a/addons/l10n_bo/l10n_bo_wizard.xml b/addons/l10n_bo/l10n_bo_wizard.xml new file mode 100644 index 00000000000..4de61247b90 --- /dev/null +++ b/addons/l10n_bo/l10n_bo_wizard.xml @@ -0,0 +1,10 @@ + + + + + + open + + + + diff --git a/addons/l10n_bo/static/src/img/icon.png b/addons/l10n_bo/static/src/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..aaf8ad438b211291933b328ebeb5c6b6799d8a34 GIT binary patch literal 1846 zcmbtUX*8P&7k(4XtG1?^iY1hat&F8~q>@PVtCld0U8|Oq`ASiW2}4OITAhlR8bjOB zYMg4-HiWU0NGv5IRZDdQwUxG%ptUruU^p{B=bW$Sd_SIh&;4=ld7gWpa~ZB=2PJt8 zc>n;ENRIaI+nK(D-Qad?BLoToV3%I#@#C(fYQ=7k@ke`<>A|a(kSZyNm&JACuG5_$XIV0i(wR_WJhLeOI#9@F`yJ;HzWgh z#2-`wgA#|<_|+tj8^$Fh$HbX-_(20P%xkhKF38ZM-EZ}?&}Q7`E$(f=h`lW(wC1k5 zSL*H3^7}n{x3UV6*{oA({Z#|bG6SWvWYbJx_dc^0m57dDU6+K`fiIUem!4bif|f$>&~o?1_jMZDk`EH)ZuT0_ zsg&*JfOw85*t{-~BBLhAn)Hf9HR=XuR+aq{7}GOpo)KMlcnfZJFLq_#|Js@L+=7O0 z>*0(slQqv~263=vMRUoyg2HYf1^xh&WPI*Vg2rpRtrY)4qmI3Gpis*8kAY*b#J;FP zg;VQcv4;~i)hhc|_2+&SppOp5hU}|)q)K1(mQ;(royjZ`c!W*_PP91DN^&T7qrKmx zj0&sH<~)U>Gycmf?4G8}(uvh&oFZ6vKNe$^kNn_#Iy|zx_}FmyT^~1v4a*!{K!)H@ zMANO-Y;ED5#<&OSLZnki->kt8Wx(amP;%I_R##CoY`tPb- z(|orATqiq<_ebR!qQ?+KsvT4{Z-ELyJgUHm?#=IZZo#(ffyu{2U{#Et(~MS^IWDoD zNG#d)gVc^@lD?%KaDaYI;|@rJ8D}cB6g*zG{PNTc-y-)hb@gV{7Ka`W^>iEK(BVl>VF!i(^{uMIuOU5V4Gud}5b>F;<{#r_7$ zfvm!5?$W&6TDRhc7FUfbUln$$Ceif$F0~_Yeegaw*x~skrId>F8Oh6f>~1aS5UrpK zxVkaWL`bJ-1_3A!0+WW+c zJoR30xBnGzd`~{9H11F9E|t?m>=O1NxumXoOaB)RH&nWhsPw!xvi`oF+sb^X*L+R) z=FG9N_2v_Cqlys=zVC;qp?+v(ZEr3w~&43mx(?=bo@n>31a(g$VEB&dk~ya4!29D0!{q9({QO(za@>Cta~UDa$lJ9ne(TuD zy;bjSBJ@>z4VD7Jm>i5bPpbTQ;B1@hAU~aH_UTVLgpacTWaudRR1*LK7@+feh$0XP z+@vf_y`)^_D@%|7L2B9vQ3GBAn&U7FpdNCxS>YTIB@>mT$_FOE35nVE5GDS5|9=~^ z2>suURZQq{h0Gnd6o(vKjp@It zBx|re6D5#1SrS>cm<`Z8`70ebAxXhb*5V_}@xvzvLSAk@taoyGZQ=Tk5V%Xoj*|2^ z|7v)7a;{Tn!5#cC+YYo_;BUcxcHvc`{?8SD5%GVH1{|=<(GD0q>zqA=f7f$fc|-wS z>pwp%5!zmj-Kw_kFcK%kik)(cN7Jo>e;e$KPN+$Ze6Q|do9=UeZ82eMO1jdvoFU7XK!q=7^(HEVDwLeX0h`3K1z=>(_-z>s|JXo=rslXpH+cq{pIzhHC J|IfLre*wi6NK60# literal 0 HcmV?d00001 From be4047ff1b26331d4f9a49bfee2d29c011e4407b Mon Sep 17 00:00:00 2001 From: "Hiral Patel (OpenERP)" Date: Fri, 23 Nov 2012 17:47:45 +0530 Subject: [PATCH 07/49] [IMP] The bounce effect is too fast everywhere, slow it down a little bit bzr revid: hip@tinyerp.com-20121123121745-rmi0wnmzmfq6nx9z --- addons/web/static/src/js/view_form.js | 4 ++-- addons/web/static/src/js/view_list.js | 2 +- addons/web_kanban/static/src/js/kanban.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 7170bdcec72..c2b47d01a34 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -204,7 +204,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.$el.find(".oe_form_group_row,.oe_form_field,label").on('click', function (e) { if(self.get("actual_mode") == "view") { var $button = self.options.$buttons.find(".oe_form_button_edit"); - $button.css('box-sizing', 'content-box').effect('bounce', {distance: 18, times: 5}, 150); + $button.css('box-sizing', 'content-box').effect('bounce', {distance: 18, times: 5}, 250); e.stopPropagation(); instance.web.bus.trigger('click', e); } @@ -213,7 +213,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.$el.find(".oe_form_field_status:not(.oe_form_status_clickable)").on('click', function (e) { if((self.get("actual_mode") == "view")) { var $button = self.$el.find(".oe_highlight:not(.oe_form_invisible)").css({'float':'left','clear':'none'}); - $button.effect('bounce', {distance:18, times: 5}, 150); + $button.effect('bounce', {distance:18, times: 5}, 250); e.stopPropagation(); } }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 55e3c17b494..fc5df164102 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -829,7 +829,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi ); var create_nocontent = this.$buttons; this.$el.find('.oe_view_nocontent').click(function() { - create_nocontent.effect('bounce', {distance: 18, times: 5}, 150); + create_nocontent.effect('bounce', {distance: 18, times: 5}, 250); }); } }); diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index cd1ea74983f..ce581f526e4 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -50,7 +50,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ this._super.apply(this, arguments); this.$el.on('click', '.oe_kanban_dummy_cell', function() { if (self.$buttons) { - self.$buttons.find('.oe_kanban_add_column').effect('bounce', {distance: 18, times: 5}, 150); + self.$buttons.find('.oe_kanban_add_column').effect('bounce', {distance: 18, times: 5}, 250); } }); }, @@ -468,7 +468,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ ); var create_nocontent = this.$buttons; this.$el.find('.oe_view_nocontent').click(function() { - create_nocontent.effect('bounce', {distance: 18, times: 5}, 150); + create_nocontent.effect('bounce', {distance: 18, times: 5}, 250); }); }, @@ -612,7 +612,7 @@ instance.web_kanban.KanbanGroup = instance.web.Widget.extend({ this.$records.click(function (ev) { if (ev.target == ev.currentTarget) { if (!self.state.folded) { - add_btn.effect('bounce', {distance: 18, times: 5}, 150); + add_btn.effect('bounce', {distance: 18, times: 5}, 250); } } }); From f09b67d560393165f12ebbf68eb21a8fd955db20 Mon Sep 17 00:00:00 2001 From: Tejas Tank Date: Wed, 28 Nov 2012 19:02:22 +0500 Subject: [PATCH 08/49] [IMP] Fixed tag issue rendering. bzr revid: tta@openerp.com-20121128140222-y8pijs2rtx3htgv4 --- addons/web_kanban/static/src/css/kanban.css | 3 +++ addons/web_kanban/static/src/js/kanban.js | 11 ++++++----- addons/web_kanban/static/src/xml/web_kanban.xml | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index 9b74462ee13..6e5edf61bc5 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -109,6 +109,9 @@ .openerp .oe_kanban_view .oe_kanban_column { height: 100%; } +.openerp .oe_kanban_view .oe_kanban_column .oe_kanban_column_cards{ + height: 100%; +} .openerp .oe_kanban_view .oe_kanban_aggregates { padding: 0; margin: 0px; diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 9484c6ed38b..eaded30efaa 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -319,7 +319,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ this.compute_groups_width(); if (this.group_by) { // Kanban cards drag'n'drop - var $columns = this.$el.find('.oe_kanban_column'); + var $columns = this.$el.find('.oe_kanban_column .oe_kanban_column_cards'); $columns.sortable({ handle : '.oe_kanban_draghandle', start: function(event, ui) { @@ -368,8 +368,8 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ stop: function(event, ui) { var stop_index = ui.item.index(); if (start_index !== stop_index) { - var $start_column = $('.oe_kanban_groups_records .oe_kanban_column').eq(start_index); - var $stop_column = $('.oe_kanban_groups_records .oe_kanban_column').eq(stop_index); + var $start_column = $('.oe_kanban_groups_records .oe_kanban_column .oe_kanban_column_cards').eq(start_index); + var $stop_column = $('.oe_kanban_groups_records .oe_kanban_column .oe_kanban_column_cards').eq(stop_index); var method = (start_index > stop_index) ? 'insertBefore' : 'insertAfter'; $start_column[method]($stop_column); var tmp_group = self.groups.splice(start_index, 1)[0]; @@ -657,14 +657,15 @@ instance.web_kanban.KanbanGroup = instance.web.Widget.extend({ var self = this; var $list_header = this.$records.find('.oe_kanban_group_list_header'); var $show_more = this.$records.find('.oe_kanban_show_more'); + var $cards = this.$records.find('.oe_kanban_column_cards'); _.each(records, function(record) { var rec = new instance.web_kanban.KanbanRecord(self, record); if (!prepend) { - rec.insertBefore($show_more); + rec.appendTo($cards); self.records.push(rec); } else { - rec.insertAfter($list_header); + rec.prependTo($cards); self.records.unshift(rec); } }); diff --git a/addons/web_kanban/static/src/xml/web_kanban.xml b/addons/web_kanban/static/src/xml/web_kanban.xml index 2bef63a5730..115e6d4466b 100644 --- a/addons/web_kanban/static/src/xml/web_kanban.xml +++ b/addons/web_kanban/static/src/xml/web_kanban.xml @@ -68,6 +68,7 @@
+
From 4fcb917d394ec28577ae742a9a78d199528e2c11 Mon Sep 17 00:00:00 2001 From: Tejas Tank Date: Thu, 6 Dec 2012 16:15:43 +0500 Subject: [PATCH 09/49] [FIX] Corrected bounce effect. bzr revid: tta@openerp.com-20121206111543-rm3irpfsx8fp58x4 --- addons/web_kanban/static/src/js/kanban.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 6073fd55819..ca57c97ef34 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -610,7 +610,7 @@ instance.web_kanban.KanbanGroup = instance.web.Widget.extend({ this.$has_been_started.resolve(); var add_btn = this.$el.find('.oe_kanban_add'); add_btn.tipsy({delayIn: 500, delayOut: 1000}); - this.$records.click(function (ev) { + this.$records.find(".oe_kanban_column_cards").click(function (ev) { if (ev.target == ev.currentTarget) { if (!self.state.folded) { add_btn.effect('bounce', {distance: 18, times: 5}, 250); From addd89fb4f1b8aefeb81a6e0381d0921ac3af807 Mon Sep 17 00:00:00 2001 From: Tejas Tank Date: Thu, 6 Dec 2012 18:30:35 +0500 Subject: [PATCH 10/49] [FIX] Kanban column dragging issue. bzr revid: tta@openerp.com-20121206133035-tigtaa18gpwj0le1 --- addons/web_kanban/static/src/js/kanban.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index ca57c97ef34..5fabe2519d7 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -369,8 +369,8 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ stop: function(event, ui) { var stop_index = ui.item.index(); if (start_index !== stop_index) { - var $start_column = $('.oe_kanban_groups_records .oe_kanban_column .oe_kanban_column_cards').eq(start_index); - var $stop_column = $('.oe_kanban_groups_records .oe_kanban_column .oe_kanban_column_cards').eq(stop_index); + var $start_column = $('.oe_kanban_groups_records .oe_kanban_column ').eq(start_index); + var $stop_column = $('.oe_kanban_groups_records .oe_kanban_column ').eq(stop_index); var method = (start_index > stop_index) ? 'insertBefore' : 'insertAfter'; $start_column[method]($stop_column); var tmp_group = self.groups.splice(start_index, 1)[0]; From 4a1c6ae2284d9df01c77f342107e11edd1cbe9bf Mon Sep 17 00:00:00 2001 From: "fclementi@camptocamp.com" <> Date: Fri, 7 Dec 2012 16:51:56 +0100 Subject: [PATCH 11/49] [FIX] l10n_fr : shorten taxe codes due to new invoices layout, reverse VAT correction, remove reconcile=true on vat accounts, remamed some taxes to match legal terms bzr revid: fclementi@camptocamp.com-20121207155156-c54b2q7kjx5azdmc --- addons/l10n_fr/fr_tax.xml | 156 ++++++++++------------ addons/l10n_fr/plan_comptable_general.xml | 13 -- 2 files changed, 68 insertions(+), 101 deletions(-) diff --git a/addons/l10n_fr/fr_tax.xml b/addons/l10n_fr/fr_tax.xml index 36c5feb47b6..d03ee4520f0 100644 --- a/addons/l10n_fr/fr_tax.xml +++ b/addons/l10n_fr/fr_tax.xml @@ -11,7 +11,7 @@ TVA collectée (vente) 19,6% - TVA-VT-19.6 + 19.6 percent @@ -33,7 +33,7 @@ TVA collectée (vente) 8,5% - TVA-VT-8.5 + 8.5 percent @@ -55,7 +55,7 @@ TVA collectée (vente) 7,0% - TVA-VT-7.0 + 7.0 percent @@ -77,7 +77,7 @@ TVA collectée (vente) 5,5% - TVA-VT-5.5 + 5.5 percent @@ -99,7 +99,7 @@ TVA collectée (vente) 2,1% - TVA-VT-2.1 + 2.1 percent @@ -122,8 +122,8 @@ - TVA acquittée (achat) 19,6% - TVA-HA-19.6 + TVA déductible (achat) 19,6% + ACH-19.6 percent @@ -144,8 +144,8 @@ - TVA acquittée (achat) 8,5% - TVA-HA-8.5 + TVA déductible (achat) 8,5% + ACH-8.5 percent @@ -166,8 +166,8 @@ - TVA acquittée (achat) 7,0% - TVA-HA-7.0 + TVA déductible (achat) 7,0% + ACH-7.0 percent @@ -188,8 +188,8 @@ - TVA acquittée (achat) 5,5% - TVA-HA-5.5 + TVA déductible (achat) 5,5% + ACH-5.5 percent @@ -210,8 +210,8 @@ - TVA acquittée (achat) 2,1% - TVA-HA-2.1 + TVA déductible (achat) 2,1% + ACH-2.1 percent @@ -232,10 +232,10 @@ - + - TVA acquittée (achat) 19,6% inclue - TVA-HA-19.6-inclue + TVA déductible (achat) 19,6% TTC + ACH-19.6-TTC percent @@ -255,10 +255,10 @@ purchase - + - TVA acquittée (achat) 8,5% inclue - TVA-HA-8.5-inclue + TVA déductible (achat) 8,5% TTC + ACH-8.5-TTC percent @@ -278,10 +278,10 @@ purchase - + - TVA acquittée (achat) 7,0% inclue - TVA-HA-7.0-inclue + TVA déductible (achat) 7,0% TTC + ACH-7.0-TTC percent @@ -301,10 +301,10 @@ purchase - + - TVA acquittée (achat) 5,5% inclue - TVA-HA-5.5-inclue + TVA déductible (achat) 5,5% TTC + ACH-5.5-TTC percent @@ -324,10 +324,10 @@ purchase - + - TVA acquittée (achat) 2,1% inclue - TVA-HA-2.1-inclue + TVA déductible (achat) 2,1% TTC + ACH-2.1-TTC percent @@ -349,11 +349,11 @@ - + - TVA immobilisation (achat) 19,6% - TVA-immo-19.6 + TVA déd./immobilisation (achat) 19,6% + IMMO-19.6 percent @@ -374,8 +374,8 @@ - TVA immobilisation (achat) 8,5% - TVA-immo-8.5 + TVA déd./immobilisation (achat) 8,5% + IMMO-8.5 percent @@ -396,8 +396,8 @@ - TVA immobilisation (achat) 7,0% - TVA-immo-7.0 + TVA déd./immobilisation (achat) 7,0% + IMMO-7.0 percent @@ -418,8 +418,8 @@ - TVA immobilisation (achat) 5,5% - TVA-immo-5.5 + TVA déd./immobilisation (achat) 5,5% + IMMO-5.5 percent @@ -440,8 +440,8 @@ - TVA immobilisation (achat) 2,1% - TVA-immo-2.1 + TVA déd./immobilisation (achat) 2,1% + IMMO-2.1 percent @@ -464,8 +464,8 @@ - TVA due intracommunautaire (achat) 19,6% - TVA-HA_UE_due-19.6 + TVA due s/ acq. intracommunautaire (achat) 19,6% + ACH_UE_due-19.6 percent @@ -486,8 +486,8 @@ - TVA due intracommunautaire (achat) 8,5% - TVA-HA_UE_due-8.5 + TVA due s/ acq. intracommunautaire (achat) 8,5% + ACH_UE_due-8.5 percent @@ -508,8 +508,8 @@ - TVA due intracommunautaire (achat) 7,0% - TVA-HA_UE_due-7.0 + TVA due s/ acq. intracommunautaire (achat) 7,0% + ACH_UE_due-7.0 percent @@ -530,8 +530,8 @@ - TVA due intracommunautaire (achat) 5,5% - TVA-HA_UE_due-5.5 + TVA due s/ acq. intracommunautaire (achat) 5,5% + ACH_UE_due-5.5 percent @@ -552,8 +552,8 @@ - TVA due intracommunautaire (achat) 2,1% - TVA-HA_UE_due-2.1 + TVA due s/ acq. intracommunautaire (achat) 2,1% + ACH_UE_due-2.1 percent @@ -576,20 +576,16 @@ - TVA déductible intracommunautaire (achat) 19,6% - TVA-HA_UE_déduc-19.6 + TVA déd. s/ acq. intracommunautaire (achat) 19,6% + ACH_UE_ded.-19.6 percent - - - - @@ -598,20 +594,16 @@ - TVA déductible intracommunautaire (achat) 8,5% - TVA-HA_UE_déduc-8.5 + TVA déd. s/ acq. intracommunautaire (achat) 8,5% + ACH_UE_ded.-8.5 percent - - - - @@ -620,20 +612,16 @@ - TVA déductible intracommunautaire (achat) 7,0% - TVA-HA_UE_déduc-7.0 + TVA déd. s/ acq. intracommunautaire (achat) 7,0% + ACH_UE_ded.-7.0 percent - - - - @@ -642,20 +630,16 @@ - TVA déductible intracommunautaire (achat) 5,5% - TVA-HA_UE_déduc-5.5 + TVA déd. s/ acq. intracommunautaire (achat) 5,5% + ACH_UE_ded.-5.5 percent - - - - @@ -664,20 +648,16 @@ - TVA déductible intracommunautaire (achat) 2,1% - TVA-HA_UE_déduc-2.1 + TVA déd. s/ acq. intracommunautaire (achat) 2,1% + ACH_UE_ded.-2.1 percent - - - - @@ -689,7 +669,7 @@ TVA 0% autres opérations non imposables (vente) - TVA-VT-autre-0 + EXO-0 percent @@ -707,7 +687,7 @@ TVA 0% export (vente) - TVA-export-0 + EXPORT-0 percent @@ -725,7 +705,7 @@ TVA 0% livraisons intracommunautaires (vente) - TVA-VT-UE-0 + UE-0 percent @@ -743,7 +723,7 @@ TVA 0% import (achat) - TVA-import-0 + IMPORT-0 percent @@ -796,7 +776,7 @@ - + @@ -880,7 +860,7 @@ - + @@ -1056,7 +1036,7 @@ - + diff --git a/addons/l10n_fr/plan_comptable_general.xml b/addons/l10n_fr/plan_comptable_general.xml index 268f4bd6336..c68e0a88a4c 100644 --- a/addons/l10n_fr/plan_comptable_general.xml +++ b/addons/l10n_fr/plan_comptable_general.xml @@ -3581,7 +3581,6 @@ view - @@ -3590,7 +3589,6 @@ other - @@ -3599,7 +3597,6 @@ other - @@ -3608,7 +3605,6 @@ other - @@ -3644,7 +3640,6 @@ view - @@ -3653,7 +3648,6 @@ other - @@ -3671,7 +3665,6 @@ other - @@ -3680,7 +3673,6 @@ other - @@ -3717,7 +3709,6 @@ view - @@ -3726,7 +3717,6 @@ other - @@ -3735,7 +3725,6 @@ other - @@ -3744,7 +3733,6 @@ other - @@ -3762,7 +3750,6 @@ view - From b6cb0014b7b219ac30549640b836d45c84815595 Mon Sep 17 00:00:00 2001 From: Tejas Tank Date: Mon, 10 Dec 2012 11:24:44 +0500 Subject: [PATCH 12/49] [FIX] Hide quick create box when drag and drop. bzr revid: tta@openerp.com-20121210062444-n4ll8y9yoy5sabia --- addons/web_kanban/static/src/js/kanban.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 5fabe2519d7..a25e13820d5 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -364,6 +364,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ scroll: false, start: function(event, ui) { start_index = ui.item.index(); + self.$('.oe_kanban_quick_create').css({ visibility: 'hidden' }); self.$('.oe_kanban_record').css({ visibility: 'hidden' }); }, stop: function(event, ui) { @@ -382,6 +383,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ } }); } + self.$('.oe_kanban_quick_create').css({ visibility: 'visible' }); self.$('.oe_kanban_record').css({ visibility: 'visible' }); } }); From 15e8533aa42cc11967d6e537c1a6f9a484e7a7d8 Mon Sep 17 00:00:00 2001 From: Tejas Tank Date: Mon, 10 Dec 2012 15:22:59 +0500 Subject: [PATCH 13/49] [FIX] Merged jquery selector and removed space from selector. bzr revid: tta@openerp.com-20121210102259-y6bz503v9ucvgpcr --- addons/web_kanban/static/src/js/kanban.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index a25e13820d5..b58f5024620 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -364,14 +364,13 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ scroll: false, start: function(event, ui) { start_index = ui.item.index(); - self.$('.oe_kanban_quick_create').css({ visibility: 'hidden' }); - self.$('.oe_kanban_record').css({ visibility: 'hidden' }); + self.$('.oe_kanban_record, .oe_kanban_quick_create').css({ visibility: 'hidden' }); }, stop: function(event, ui) { var stop_index = ui.item.index(); if (start_index !== stop_index) { - var $start_column = $('.oe_kanban_groups_records .oe_kanban_column ').eq(start_index); - var $stop_column = $('.oe_kanban_groups_records .oe_kanban_column ').eq(stop_index); + var $start_column = $('.oe_kanban_groups_records .oe_kanban_column').eq(start_index); + var $stop_column = $('.oe_kanban_groups_records .oe_kanban_column').eq(stop_index); var method = (start_index > stop_index) ? 'insertBefore' : 'insertAfter'; $start_column[method]($stop_column); var tmp_group = self.groups.splice(start_index, 1)[0]; @@ -383,8 +382,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ } }); } - self.$('.oe_kanban_quick_create').css({ visibility: 'visible' }); - self.$('.oe_kanban_record').css({ visibility: 'visible' }); + self.$('.oe_kanban_record, .oe_kanban_quick_create').css({ visibility: 'visible' }); } }); } From eb599370e85ff139853fc9423166448a81e56954 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Wed, 12 Dec 2012 21:58:58 +0100 Subject: [PATCH 14/49] [FIX] l10n_nl: incorrect configuration of taxes for handling refunds lp bug: https://launchpad.net/bugs/1026760 fixed bzr revid: stefan@therp.nl-20121212205858-qpn3fua9krh28m7m --- addons/l10n_nl/account_chart_netherlands.xml | 106 +++++++++++++++---- 1 file changed, 88 insertions(+), 18 deletions(-) diff --git a/addons/l10n_nl/account_chart_netherlands.xml b/addons/l10n_nl/account_chart_netherlands.xml index 2235dd49ec9..516c88bdcf9 100644 --- a/addons/l10n_nl/account_chart_netherlands.xml +++ b/addons/l10n_nl/account_chart_netherlands.xml @@ -4140,9 +4140,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale @@ -4153,11 +4155,13 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale @@ -4168,11 +4172,13 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale @@ -4184,11 +4190,13 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale @@ -4201,9 +4209,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4214,9 +4224,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4227,23 +4239,27 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase - 15 + 15 BTW af te dragen verlegd (verkopen) 0% BTW verlegd percent - + + + purchase @@ -4254,9 +4270,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4268,9 +4286,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4281,9 +4301,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4294,9 +4316,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4308,9 +4332,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4321,9 +4347,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + purchase @@ -4338,6 +4366,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4351,6 +4381,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4364,6 +4396,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4375,6 +4409,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4388,6 +4424,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4401,6 +4439,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4413,6 +4453,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4426,6 +4468,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4439,6 +4483,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge 99 + + purchase @@ -4450,9 +4496,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale @@ -4463,9 +4511,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale @@ -4481,6 +4531,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4494,6 +4546,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge 99 + + purchase @@ -4507,6 +4561,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge 99 + + purchase @@ -4519,6 +4575,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4532,6 +4590,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4545,6 +4605,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4557,6 +4619,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase @@ -4569,6 +4633,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase 99 @@ -4582,6 +4648,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + + purchase 99 @@ -4594,9 +4662,11 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge percent - + + + sale From 6ee638f8fd838ebe0cae7187a6fbd97b2ee9f02d Mon Sep 17 00:00:00 2001 From: Fekete Mihai Date: Thu, 13 Dec 2012 09:37:44 +0200 Subject: [PATCH 15/49] Update the l10n_ro module providing the last chart of account and tax template. bzr revid: office@erpsystems.ro-20121213073744-g0dh73t3q3q1rn2a --- addons/l10n_ro/__init__.py | 8 +- addons/l10n_ro/__openerp__.py | 26 +- addons/l10n_ro/account_chart.xml | 1755 ++++++++++-------- addons/l10n_ro/account_tax.xml | 136 -- addons/l10n_ro/account_tax_code.xml | 134 -- addons/l10n_ro/account_tax_code_template.xml | 186 ++ addons/l10n_ro/account_tax_template.xml | 170 ++ addons/l10n_ro/i18n/ar.po | 132 -- addons/l10n_ro/i18n/ca.po | 146 -- addons/l10n_ro/i18n/da.po | 118 -- addons/l10n_ro/i18n/es.po | 146 -- addons/l10n_ro/i18n/es_CR.po | 147 -- addons/l10n_ro/i18n/es_MX.po | 67 - addons/l10n_ro/i18n/es_PY.po | 146 -- addons/l10n_ro/i18n/es_VE.po | 67 - addons/l10n_ro/i18n/gl.po | 145 -- addons/l10n_ro/i18n/it.po | 146 -- addons/l10n_ro/i18n/l10n_ro.pot | 117 -- addons/l10n_ro/i18n/pt.po | 118 -- addons/l10n_ro/i18n/pt_BR.po | 145 -- addons/l10n_ro/i18n/ro.po | 146 -- addons/l10n_ro/i18n/sr@latin.po | 146 -- addons/l10n_ro/i18n/tr.po | 135 -- addons/l10n_ro/partner_view.xml | 23 +- addons/l10n_ro/res_partner.py | 7 +- 25 files changed, 1362 insertions(+), 3150 deletions(-) delete mode 100644 addons/l10n_ro/account_tax.xml delete mode 100644 addons/l10n_ro/account_tax_code.xml create mode 100644 addons/l10n_ro/account_tax_code_template.xml create mode 100644 addons/l10n_ro/account_tax_template.xml delete mode 100644 addons/l10n_ro/i18n/ar.po delete mode 100644 addons/l10n_ro/i18n/ca.po delete mode 100644 addons/l10n_ro/i18n/da.po delete mode 100644 addons/l10n_ro/i18n/es.po delete mode 100644 addons/l10n_ro/i18n/es_CR.po delete mode 100644 addons/l10n_ro/i18n/es_MX.po delete mode 100644 addons/l10n_ro/i18n/es_PY.po delete mode 100644 addons/l10n_ro/i18n/es_VE.po delete mode 100644 addons/l10n_ro/i18n/gl.po delete mode 100644 addons/l10n_ro/i18n/it.po delete mode 100644 addons/l10n_ro/i18n/l10n_ro.pot delete mode 100644 addons/l10n_ro/i18n/pt.po delete mode 100644 addons/l10n_ro/i18n/pt_BR.po delete mode 100644 addons/l10n_ro/i18n/ro.po delete mode 100644 addons/l10n_ro/i18n/sr@latin.po delete mode 100644 addons/l10n_ro/i18n/tr.po mode change 100644 => 100755 addons/l10n_ro/res_partner.py diff --git a/addons/l10n_ro/__init__.py b/addons/l10n_ro/__init__.py index 81d74690925..15aa903aea9 100644 --- a/addons/l10n_ro/__init__.py +++ b/addons/l10n_ro/__init__.py @@ -2,8 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2009 Fil System (). All Rights Reserved -# $Id$ +# Copyright (C) 2012 TOTAL PC SYSTEMS (). 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 @@ -19,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## -import res_partner -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: +import res_partner + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_ro/__openerp__.py b/addons/l10n_ro/__openerp__.py index 8026d49c3db..e8bc9b869ad 100644 --- a/addons/l10n_ro/__openerp__.py +++ b/addons/l10n_ro/__openerp__.py @@ -2,8 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2009 (). All Rights Reserved -# $Id$ +# Copyright (C) 2012 (). 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 @@ -20,23 +19,22 @@ # ############################################################################## { - 'name' : 'Romania - Accounting', - 'version' : '1.1', - 'author' : 'filsys', - 'website': 'http://www.filsystem.ro', - 'category' : 'Localization/Account Charts', - 'depends' : ['account_chart', 'base_vat'], - 'description': """ + "name" : "Romania - Accounting", + "version" : "1.0", + "author" : "TOTAL PC SYSTEMS", + "website": "http://www.erpsystems.ro", + "category" : "Localization/Account Charts", + "depends" : ['account','account_chart','base_vat'], + "description": """ This is the module to manage the accounting chart, VAT structure and Registration Number for Romania in OpenERP. ================================================================================================================ Romanian accounting chart and localization. """, - 'demo' : [], - 'data' : ['partner_view.xml','account_tax_code.xml','account_chart.xml','account_tax.xml','l10n_chart_ro_wizard.xml'], - 'auto_install': False, - 'installable': True, - 'images': ['images/config_chart_l10n_ro.jpeg','images/l10n_ro_chart.jpeg'], + "demo_xml" : [], + "update_xml" : ['partner_view.xml','account_tax_code_template.xml','account_chart.xml','account_tax_template.xml','l10n_chart_ro_wizard.xml'], + "auto_install": False, + "installable": True, } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_ro/account_chart.xml b/addons/l10n_ro/account_chart.xml index 28347d64090..1e0a9b749f7 100644 --- a/addons/l10n_ro/account_chart.xml +++ b/addons/l10n_ro/account_chart.xml @@ -1,116 +1,47 @@ - + - - - - Receivable - receivable - unreconciled - + + + + Active + active + balance + - - Stocks - stocks - balance - + + Passive + passive + balance + - - Payable - payable - unreconciled - - - - View - view - none - - - - Income - income - none - - - - Expense - expense - none - - - - Tax - tax - unreconciled - - - - Cash - cash - balance - - - - Asset - asset - balance - - - - Equity - equity - liability - balance - - - - Liability - liability - balance - - - - Provisions - provision - balance - - - - Immobilization - immobilization - balance - - - - - + + Bifunctional + bifunctional + balance + + + Special special none - - - Commitment - commitment - balance - - - + + Plan de conturi general 0 view - + Conturi financiare Clasele 1-7 view - + @@ -118,7 +49,7 @@ Conturi in afara bilantului Clasele 8-9 view - + @@ -126,7 +57,7 @@ Conturi de bilant Clasele 1-5 view - + @@ -134,9 +65,8 @@ Conturi de capitaluri Clasa 1 view - + Capitaluri proprii, alte fonduri proprii, imprumuturi si datorii asimilate - @@ -144,7 +74,7 @@ Capital si rezerve 10 view - + @@ -152,7 +82,7 @@ Capital 101 view - + in functie de forma juridica a entitatii se inscrie: capital social, patrimoniul regiei,etc. @@ -161,7 +91,7 @@ Capital subscris nevarsat 1011 other - + @@ -169,7 +99,7 @@ Capital subscris varsat 1012 other - + @@ -177,7 +107,7 @@ Patrimoniul regiei 1015 other - + @@ -185,8 +115,7 @@ Patrimoniul public 1016 other - - + @@ -194,8 +123,7 @@ Prime de capital 104 view - - + @@ -203,7 +131,7 @@ Prime de emisiune 1041 other - + @@ -211,7 +139,7 @@ Prime de fuziune/divizare 1042 other - + @@ -219,7 +147,7 @@ Prime de aport 1043 other - + @@ -227,7 +155,7 @@ Prime de conversie a obligatiunilor in actiuni 1044 other - + @@ -235,8 +163,7 @@ Rezerve din reevaluare 105 other - - + @@ -244,8 +171,7 @@ Rezerve 106 view - - + @@ -253,8 +179,7 @@ Rezerve legale 1061 other - - + @@ -262,8 +187,7 @@ Rezerve statutare sau contractuale 1063 other - - + @@ -271,7 +195,7 @@ Rezerve de valoare justa 1064 other - + Acest cont apare numai in situatiile financiare anuale consolidate @@ -280,17 +204,23 @@ Rezerve reprezentand surplusul realizat din rezerve din reevaluare 1065 other - - + + + Rezerve din diferente de curs valutar in relatie cu investitia neta intr-o entitate straina + 1067 + other + + + + Alte rezerve 1068 other - - + @@ -298,34 +228,33 @@ Rezerve din conversie 107 other - + Acest cont apare numai in situatiile financiare anuale consolidate - Interese minoritare + Interese care nu controleaza 108 view - + Acest cont apare numai in situatiile financiare anuale consolidate - - Interese minoritare - rezultatul exercitiului financiar + Interese care nu controleaza - rezultatul exercitiului financiar 1081 other - + - Interese minoritare - alte capitaluri proprii + Interese care nu controleaza - alte capitaluri proprii 1082 other - + @@ -333,8 +262,7 @@ Actiuni proprii 109 view - - + @@ -342,7 +270,7 @@ Actiuni proprii detinute pe termen scurt 1091 other - + @@ -350,7 +278,7 @@ Actiuni proprii detinute pe termen lung 1092 other - + @@ -358,8 +286,7 @@ REZULTATUL REPORTAT 11 view - - + @@ -367,17 +294,15 @@ Rezultatul reportat 117 view - - + - Rezultatul reportat reprezentand profitul nerepartizat sau pierderea neacoperitã + Rezultatul reportat reprezentand profitul nerepartizat sau pierderea neacoperita 1171 other - - + @@ -385,7 +310,7 @@ Rezultatul reportat provenit din adoptarea pentru prima data a IAS, mai puþin IAS 29 1172 other - + Acest cont apare doar la agentii economici care au aplicat Reglementarile contabile aprobate prin OMFP nr. 94/2001 si panã la inchiderea soldului acestui cont @@ -394,8 +319,7 @@ Rezultatul reportat provenit din corectarea erorilor contabile 1174 other - - + @@ -403,18 +327,16 @@ Rezultatul reportat provenit din trecerea la aplicarea Reglementarilor contabile conforme cu Directiva a patra a Comunitatilor Economice Europene 1176 other - - + - REZULTATUL EXERCItIULUI FINANCIAR + REZULTATUL EXERCITIULUI FINANCIAR 12 view - - + @@ -422,7 +344,7 @@ Profit sau pierdere 121 other - + @@ -430,80 +352,31 @@ Repartizarea profitului 129 other - + - - SUBVENtII PENTRU INVESTItII - 13 - view - - - - - - Subventii guvernamentale pentru investitii - 131 - other - - - - - - - imprumuturi nerambursabile cu caracter de subventii pentru investitii - 132 - other - - - - - - Donatii pentru investitii - 133 - other - - - - - - Plusuri de inventar de natura imobilizarilor - 134 - other - - - - - - Alte sume primite cu caracter de subventii pentru investitii - 138 - other - - - - - CasTIGURI SAU PIERDERI LEGATE DE EMITEREA,RaSCUMP.,VaNZAREA,CEDAREA CU TITLU GRATUIT SAU ANULAREA INSTRUM.DE CAPITALURI PROPRII + CASTIGURI SAU PIERDERI LEGATE DE EMITEREA,RASCUMPARAREA,VANZAREA,CEDAREA CU TITLU GRATUIT SAU ANULAREA INSTRUM.DE CAPITALURI PROPRII 14 view - + - Castiguri + Castiguri legate de vanzarea sau anularea instrumentelor de capitaluri proprii. 141 other - + - Pierderi + Pierderi legate de emiterea, rascumpararea, vanzarea, cedarea cu titlu gratuit sau anularea instrumentelor de capitaluri proprii. 149 other - + @@ -512,7 +385,7 @@ PROVIZIOANE 15 view - + @@ -520,7 +393,7 @@ Provizioane 151 view - + @@ -528,7 +401,7 @@ Provizioane pentru litigii 1511 other - + @@ -536,7 +409,7 @@ Provizioane pentru garantii acordate clientilor 1512 other - + @@ -544,7 +417,7 @@ Provizioane pentru dezafectare imobilizari corporale si alte actiuni legate de acestea 1513 other - + Acest cont apare doar la agentii economici care au aplicat Reglementarile contabile aprobate prin OMFP nr. 94/2001 si pana la scoaterea din evidenta a imobilizarilor corporale in valoarea carora au fost incluse aceste provizioane. Ca urmare, aceste provizioane nu se mai pot constitui in baza prezentelor reglementari. @@ -553,7 +426,7 @@ Provizioane pentru restructurare 1514 other - + @@ -561,7 +434,7 @@ Provizioane pentru pensii si obligatii similare 1515 other - + @@ -569,7 +442,7 @@ Provizioane pentru impozite 1516 other - + @@ -577,47 +450,47 @@ Alte provizioane 1518 other - + - imprumuturi si datorii asimilate + IMPRUMUTURI SI DATORII ASIMILATE 16 view - + - imprumuturi din emisiuni de obligatiuni + Imprumuturi din emisiuni de obligatiuni 161 view - + - imprumuturi externe din emisiuni de obligatiuni garantate de stat + Imprumuturi externe din emisiuni de obligatiuni garantate de stat 1614 other - + - imprumuturi externe din emisiuni de obligatiuni garantate de banci + Imprumuturi externe din emisiuni de obligatiuni garantate de banci 1615 other - + - imprumuturi interne din emisiuni de obligatiuni garantate de stat + Imprumuturi interne din emisiuni de obligatiuni garantate de stat 1617 other - + @@ -625,7 +498,7 @@ Alte imprumuturi din emisiuni de obligatiuni 1618 other - + @@ -633,7 +506,7 @@ Credite bancare pe termen lung 162 view - + @@ -641,7 +514,7 @@ Credite bancare pe termen lung 1621 other - + @@ -649,7 +522,7 @@ Credite bancare pe termen lung nerambursate la scadenta 1622 other - + @@ -657,7 +530,7 @@ Credite externe guvernamentale 1623 other - + @@ -665,7 +538,7 @@ Credite bancare externe garantate de stat 1624 other - + @@ -673,7 +546,7 @@ Credite bancare externe garantate de banci 1625 other - + @@ -681,7 +554,7 @@ Credite de la trezoreria statului 1626 other - + @@ -689,7 +562,7 @@ Credite bancare interne garantate de stat 1627 other - + @@ -697,8 +570,7 @@ Datorii care privesc imobilizarile financiare 166 view - - + @@ -706,8 +578,7 @@ Datorii fata de entitatile afiliate 1661 other - - + @@ -715,8 +586,7 @@ Datorii fata de entitatile de care compania este legata prin interese de participare 1663 other - - + @@ -724,8 +594,7 @@ Alte imprumuturi si datorii asimilate 167 other - - + @@ -733,8 +602,7 @@ Dobanzi aferente imprumuturilor si datoriilor asimilate 168 view - - + @@ -742,8 +610,7 @@ Dobanzi aferente imprumuturilor din emisiunile de obligatiuni 1681 other - - + @@ -751,8 +618,7 @@ Dobanzi aferente creditelor bancare pe termen lung 1682 other - - + @@ -760,8 +626,7 @@ Dobanzi aferente datoriilor fata de entitatile afiliate 1685 other - - + @@ -769,7 +634,7 @@ Dobanzi aferente datoriilor fata de entitatile de care compania este legata prin interese de participare 1686 other - + @@ -777,7 +642,7 @@ Dobanzi aferente altor imprumuturi si datorii asimilate 1687 other - + @@ -785,24 +650,24 @@ Prime privind rambursarea obligatiunilor 169 other - + - CONTURI DE IMOBILIZaRI + CONTURI DE IMOBILIZARI Clasa 2 view - + Imobilizari necorporale, corporale, financiare, amortizari - IMOBILIZaRI NECORPORALE + IMOBILIZARI NECORPORALE 20 view - + @@ -810,7 +675,7 @@ Cheltuieli de constituire 201 other - + @@ -818,7 +683,7 @@ Cheltuieli de dezvoltare 203 other - + @@ -826,7 +691,7 @@ Concesiuni, brevete, licente, marci comerciale, drepturi si active similare 205 other - + @@ -834,7 +699,7 @@ Fond comercial 207 view - + @@ -842,27 +707,34 @@ Fond comercial pozitiv 2071 other - + Acest cont apare, de regula, in situatiile financiare anuale consolidate - + Fond comercial negativ - 2072 + 2075 other Acest cont apare numai in situatiile financiare anuale consolidate - + + + Alte imobilizari necorporale + 208 + other + + + + - IMOBILIZaRI CORPORALE + IMOBILIZARI CORPORALE 21 view - + Atunci cand valoarea de achizitie depaseste 1800 RON - @@ -870,7 +742,7 @@ Terenuri si amenajari de terenuri 211 view - + @@ -878,8 +750,7 @@ Terenuri 2111 other - - + @@ -887,8 +758,7 @@ Amenajari de terenuri 2112 other - - + @@ -896,7 +766,7 @@ Constructii 212 other - + @@ -904,7 +774,7 @@ Instalatii tehnice, mijloace de transport, animale si plantatii 213 view - + @@ -912,7 +782,7 @@ Echipamente tehnologice (masini, utilaje si instalatii de lucru) 2131 other - + @@ -920,15 +790,15 @@ Aparate si instalatii de masurare, control si reglare 2132 other - + - Mijloace detransport + Mijloace de transport 2133 other - + @@ -936,7 +806,7 @@ Animale si plantatii 2134 other - + @@ -944,16 +814,39 @@ Mobilier, aparatura birotica, echipamente de protectie a valorilor umane si materiale si alte active corporale 214 other - + + + IMOBILIZARI CORPORALE IN CURS DE APROVIZIONARE + 22 + view + + + + + + Instalatii tehnice, mijloace de transport, animale si plantatii in curs de aprovizionare + 223 + other + + + + + + Mobilier, aparatura birotica, echipamente de protectie a valorilor umane si materiale si alte active corporale in curs de aprovizionare + 224 + other + + + + - IMOBILIZaRI iN CURS + IMOBILIZARI IN CURS SI AVANSURI PENTRU IMOBILIZARI 23 view - - + @@ -961,7 +854,7 @@ Imobilizari corporale in curs de executie 231 other - + @@ -969,7 +862,7 @@ Avansuri acordate pentru imobilizari corporale 232 other - + @@ -977,7 +870,7 @@ Imobilizari necorporale in curs de executie 233 other - + @@ -985,15 +878,15 @@ Avansuri acordate pentru imobilizari necorporale 234 other - + - IMOBILIZaRI FINANCIARE + IMOBILIZARI FINANCIARE 26 view - + @@ -1001,7 +894,7 @@ Actiuni detinute la entitatile afiliate 261 other - + @@ -1009,7 +902,7 @@ Interse de participare 263 other - + @@ -1017,7 +910,7 @@ Titluri puse in echivalenta 264 other - + Acest cont apare numai in situatiile financiare anuale consolidate @@ -1026,7 +919,7 @@ Alte titluri imobilizate 265 other - + @@ -1034,7 +927,7 @@ Creante imobilizate 267 view - + @@ -1042,7 +935,7 @@ Sume datorate de entitatile afiliate 2671 other - + @@ -1050,7 +943,7 @@ Dobanda aferenta sumelor datorate de entitatile afiliate 2672 other - + @@ -1058,7 +951,7 @@ Creante legate de interesele de participare 2673 other - + @@ -1066,15 +959,15 @@ Dobanda aferenta creantelor legate de interesele de participare 2674 other - + - imprumuturi acordate pe termen lung + Imprumuturi acordate pe termen lung 2675 other - + @@ -1082,7 +975,7 @@ Dobanda aferenta imprumuturilor acordate pe termen lung 2676 other - + @@ -1090,15 +983,15 @@ Alte creante imobilizate 2678 other - + - Varsaminte de efectuat pentru imobilizari financiare + Dobânzi aferente altor creante imobilizate 2679 other - + @@ -1106,7 +999,7 @@ Varsaminte de efectuat pentru imobilizari financiare 269 view - + @@ -1114,7 +1007,7 @@ Varsaminte de efectuat privind actiunile detinute la entitatile afiliate 2691 other - + @@ -1122,7 +1015,7 @@ Varsaminte de efectuat privind interesele de participare 2692 other - + @@ -1130,15 +1023,15 @@ Varsaminte de efectuat pentru alte imobilizari financiare 2693 other - + - AMORTIZaRI PRIVIND IMOBILIZaRILE + AMORTIZARI PRIVIND IMOBILIZARILE 28 view - + @@ -1146,7 +1039,7 @@ Amortizari privind amortizarile necorporale 280 view - + @@ -1154,7 +1047,7 @@ Amortizarea cheltuielilor de constituire 2801 other - + @@ -1162,7 +1055,7 @@ Amortizarea cheltuielilor de dezvoltare 2803 other - + @@ -1170,7 +1063,7 @@ Amortizarea concesiunilor, brevetelor, licentelor, marcilor comerciale, drepturilor si activelor similare 2805 other - + @@ -1178,7 +1071,7 @@ Amortizarea fondului comercial 2807 other - + Acest cont apare, de regula, in situatiile financiare anuale consolidate @@ -1187,7 +1080,7 @@ Amortizarea altor imobilizari necorporale 2808 other - + @@ -1195,7 +1088,7 @@ Amortizari privind imobilizarile corporale 281 view - + @@ -1203,7 +1096,7 @@ Amortizarea amenajarilor de terenuri 2811 other - + @@ -1211,7 +1104,7 @@ Amortizarea constructiilor 2812 other - + @@ -1219,7 +1112,7 @@ Amortizarea instalatiilor, mijloacelor de transport, animalelor si plantatiilor 2813 other - + @@ -1227,15 +1120,15 @@ Amortizarea altor imobilizari corporale 2814 other - + - AJUSTaRI PENTRU DEPRECIEREA SAU PIERDEREA DE VALOARE A IMOBILIZaRILOR + AJUSTARI PENTRU DEPRECIEREA SAU PIERDEREA DE VALOARE A IMOBILIZARILOR 29 view - + @@ -1243,7 +1136,7 @@ Ajustari pentru deprecierea imobilizarilor necorporale 290 view - + @@ -1251,7 +1144,7 @@ Ajustari pentru deprecierea cheltuielilor de dezvoltare 2903 other - + @@ -1259,7 +1152,7 @@ Ajustari pentru deprecierea concesiunilor, brevetelor, licentelor, marcilor comerciale, drepturilor si activelor similare 2905 other - + @@ -1267,7 +1160,7 @@ Ajustari pentru deprecierea fondului comercial 2907 other - + @@ -1275,7 +1168,7 @@ Ajustari pentru deprecierea altor imobilizari necorporale 2908 other - + @@ -1283,8 +1176,7 @@ Ajustari pentru deprecierea imobilizarilor corporale 291 view - - + @@ -1292,8 +1184,7 @@ Ajustari pentru deprecierea terenurilor si amenajarilor de terenuri 2911 other - - + @@ -1301,7 +1192,7 @@ Ajustari pentru deprecierea constructiilor 2912 other - + @@ -1309,7 +1200,7 @@ Ajustari pentru deprecierea instalatiilor, mijloacelor de transport, animalelor si plantatiilor 2913 other - + @@ -1317,7 +1208,7 @@ Ajustari pentru deprecierea altor imobilizari corporale 2914 other - + @@ -1325,7 +1216,7 @@ Ajustari pentru deprecierea imobilizarilor in curs de executie 293 view - + @@ -1333,7 +1224,7 @@ Ajustari pentru deprecierea imobilizarilor corporale in curs de executie 2931 other - + @@ -1341,7 +1232,7 @@ Ajustari pentru deprecierea imobilizarilor necorporale in curs de executie 2933 other - + @@ -1349,7 +1240,7 @@ Ajustari pentru pierderea de valoare a imobilizarilor financiare 296 view - + @@ -1357,7 +1248,7 @@ Ajustari pentru pierderea de valoare a actiunilor detinute la entitatile afiliate 2961 other - + @@ -1365,7 +1256,7 @@ Ajustari pentru pierderea de valoare a intereselor de participare 2962 other - + @@ -1373,7 +1264,7 @@ Ajustari pentru pierderea de valoare a altor titluri imobilizate 2963 other - + @@ -1381,7 +1272,7 @@ Ajustari pentru pierderea de valoare a sumelor datorate entitatilor afiliate 2964 other - + @@ -1389,7 +1280,7 @@ Ajustari pentru pierderea de valoare a creantelor legate de interesele de participare 2965 other - + @@ -1397,7 +1288,7 @@ Ajustari pentru pierderea de valoare a imprumuturilor pe termen lung 2966 other - + @@ -1405,23 +1296,23 @@ Ajustari pentru pierderea de valoare a altor creante imobilizate 2968 other - + - CONTURI DE STOCURI sI PRODUCtIE iN CURS DE EXECUtIE + CONTURI DE STOCURI SI PRODUCTIE IN CURS DE EXECUTIE Clasa 3 view - + - STOCURI DE MATERII PRIME sI MATERIALE + STOCURI DE MATERII PRIME SI MATERIALE 30 view - + @@ -1429,7 +1320,7 @@ Materii prime 301 other - + @@ -1437,7 +1328,7 @@ Materiale consumabile 302 view - + @@ -1445,7 +1336,7 @@ Materiale auxiliare 3021 other - + @@ -1453,15 +1344,15 @@ Combustibili 3022 other - + - Materiale auxiliare + Materiale pentru ambalat 3023 other - + @@ -1469,7 +1360,7 @@ Piese de schimb 3024 other - + @@ -1477,7 +1368,7 @@ Seminte si materiale de plantat 3025 other - + @@ -1485,7 +1376,7 @@ Furaje 3026 other - + @@ -1493,7 +1384,7 @@ Alte materiale consumabile 3028 other - + @@ -1501,7 +1392,7 @@ Materiale de natura obiectelor de inventar 303 other - + @@ -1509,15 +1400,71 @@ Diferente de pret la materii prime si materiale 308 other - + + + STOCURI IN CURS DE APROVIZIONARE + 32 + view + + + + + + Materii prime in curs de aprovizionare + 321 + other + + + + + + Materiale consumabile in curs de aprovizionare + 322 + other + + + + + + Materiale de natura obiectelor de inventar in curs de aprovizionare + 323 + other + + + + + + Animale in curs de aprovizionare + 326 + other + + + + + + Marfuri in curs de aprovizionare + 327 + other + + + + + + Ambalaje in curs de aprovizionare + 328 + other + + + + - PRODUCtIA iN CURS DE EXECUtIE + PRODUCTIA IN CURS DE EXECUTIE 33 view - + @@ -1525,15 +1472,15 @@ Produse in curs de executie 331 other - + - Lucrari si servicii in curs de executie + Servicii in curs de executie 332 other - + @@ -1541,7 +1488,7 @@ PRODUSE 34 view - + @@ -1549,7 +1496,7 @@ Semifabricate 341 other - + @@ -1557,7 +1504,7 @@ Produse finite 345 other - + @@ -1565,7 +1512,7 @@ Produse reziduale 346 other - + @@ -1573,15 +1520,15 @@ Diferente de pret la produse 348 other - + - STOCURI AFLATE LA TERtI + STOCURI AFLATE LA TERTI 35 view - + @@ -1589,7 +1536,7 @@ Materii si materiale aflate la terti 351 other - + @@ -1597,7 +1544,7 @@ Produse aflate la terti 354 other - + @@ -1605,7 +1552,7 @@ Animale aflate la terti 356 other - + @@ -1613,7 +1560,7 @@ Marfuri aflate la terti 357 other - + @@ -1621,7 +1568,7 @@ Ambalaje aflate la terti 358 other - + @@ -1629,7 +1576,7 @@ ANIMALE 36 view - + @@ -1637,7 +1584,7 @@ Animale si pasari 361 other - + @@ -1645,15 +1592,15 @@ Diferente de pret la animale si pasari 368 other - + - MaRFURI + MARFURI 37 view - + @@ -1661,7 +1608,7 @@ Marfuri 371 other - + @@ -1669,7 +1616,7 @@ Diferente de pret la marfuri 378 other - + @@ -1677,7 +1624,7 @@ AMBALAJE 38 view - + @@ -1685,7 +1632,7 @@ Ambalaje 381 other - + @@ -1693,15 +1640,15 @@ Diferente de pret la ambalaje 388 other - + - AJUSTaRI PENTRU DEPRECIEREA STOCURILOR sI PRODUCtIEI iN CURS DE EXECUtIE + AJUSTARI PENTRU DEPRECIEREA STOCURILOR SI PRODUCTIEI IN CURS DE EXECUTIE 39 view - + @@ -1709,7 +1656,7 @@ Ajustari pentru deprecierea materiilor prime 391 other - + @@ -1717,7 +1664,7 @@ Ajustari pentru deprecierea materialelor 392 view - + @@ -1725,7 +1672,7 @@ Ajustari pentru deprecierea materialelor consumabile 3921 other - + @@ -1733,7 +1680,7 @@ Ajustari pentru deprecierea materialelor de natura obiectelor de inventar 3922 other - + @@ -1741,7 +1688,7 @@ Ajustari pentru deprecierea productiei in curs de executie 393 other - + @@ -1749,7 +1696,7 @@ Ajustari pentru deprecierea produselor 394 view - + @@ -1757,7 +1704,7 @@ Ajustari pentru deprecierea semifabricatelor 3941 other - + @@ -1765,7 +1712,7 @@ Ajustari pentru deprecierea produselor finite 3945 other - + @@ -1773,7 +1720,7 @@ Ajustari pentru deprecierea produselor reziduale 3946 other - + @@ -1781,7 +1728,7 @@ Ajustari pentru deprecierea stocurilor aflate la terti 395 view - + @@ -1789,7 +1736,7 @@ Ajustari pentru deprecierea materiilor prime si materialelor aflate la terti 3951 other - + @@ -1797,7 +1744,7 @@ Ajustari pentru deprecierea semifabricatelor aflate la terti 3952 other - + @@ -1805,7 +1752,7 @@ Ajustari pentru deprecierea produselor finite aflate la terti 3953 other - + @@ -1813,7 +1760,7 @@ Ajustari pentru deprecierea produselor reziduale aflate la terti 3954 other - + @@ -1821,7 +1768,7 @@ Ajustari pentru deprecierea animalelor aflate la terti 3956 other - + @@ -1829,7 +1776,7 @@ Ajustari pentru deprecierea marfurilor aflate la terti 3957 other - + @@ -1837,15 +1784,23 @@ Ajustari pentru deprecierea ambalajelor aflate la terti 3958 other - + + + Ajustari pentru deprecierea animalelor + 396 + other + + + + Ajustari pentru deprecierea marfurilor 397 other - + @@ -1853,61 +1808,41 @@ Ajustari pentru deprecierea ambalajelor 398 other - + - CONTURI DE TERtI + CONTURI DE TERTI Clasa 4 view - + - FURNIZORI sI CONTURI ASIMILATE + FURNIZORI SI CONTURI ASIMILATE 40 view - + - + Furnizori 401 - view - + payable + - - - Furnizori cumparari de bunuri si prestari de servicii - 4011 - payable - - - - - - - - Furnizori - Contracte civile - 4012 - payable - - - - - Efecte de platit 403 payable - + @@ -1916,7 +1851,7 @@ Furnizori de imobilizari 404 payable - + @@ -1925,7 +1860,7 @@ Efecte de platit pentru imobilizari 405 payable - + @@ -1934,7 +1869,7 @@ Furnizori - facturi nesosite 408 payable - + @@ -1943,7 +1878,7 @@ Furnizori - debitori 409 view - + @@ -1952,25 +1887,25 @@ Furnizori - debitori pentru cumparari de bunuri de natura stocurilor 4091 other - + - Furnizori - debitori pentru prestari de servicii si executari de lucrari + Furnizori - debitori pentru prestari de servicii 4092 other - + - CLIENtI sI CONTURI ASIMILATE + CLIENTI SI CONTURI ASIMILATE 41 view - + @@ -1979,16 +1914,16 @@ Clienti 411 view - + - Clienti - Vanzari de bunuri sau prestari de servicii + Clienti 4111 receivable - + @@ -1997,7 +1932,7 @@ Clienti incerti sau in litigiu 4118 receivable - + @@ -2006,7 +1941,7 @@ Efecte de primit de la clienti 413 receivable - + @@ -2015,7 +1950,7 @@ Clienti - facturi de intocmit 418 receivable - + @@ -2024,24 +1959,24 @@ Clienti creditori 419 other - + - PERSONAL sI CONTURI ASIMILATE + PERSONAL SI CONTURI ASIMILATE 42 view - + Personal - salarii datorate 421 - view - + other + @@ -2050,7 +1985,7 @@ Personal - ajutoare materiale datorate 423 other - + @@ -2059,7 +1994,7 @@ Prime privind participarea personalului la profit 424 other - + Se utilizeaza atunci cand exista baza legala pentru acordarea acestora @@ -2069,17 +2004,16 @@ Avansuri acordate personalului 425 receivable - - + - Drepturi de personal neridicatelte creante + Drepturi de personal neridicate 426 other - + @@ -2088,7 +2022,7 @@ Retineri din salarii datorate tertilor 427 other - + @@ -2097,7 +2031,7 @@ Alte datorii si creante in legatura cu personalul 428 view - + @@ -2106,7 +2040,7 @@ Alte datorii in legatura cu personalul 4281 other - + @@ -2115,16 +2049,16 @@ Alte creante in legatura cu personalul 4282 receivable - + - ASIGURaRI SOCIALE, PROTECtIE SOCIALa sI CONTURI ASIMILATE + ASIGURARI SOCIALE, PROTECTIE SOCIALA SI CONTURI ASIMILATE 43 view - + @@ -2132,7 +2066,7 @@ Asigurari sociale 431 view - + @@ -2141,7 +2075,7 @@ Contributia unitatii la asigurarile sociale 4311 other - + @@ -2150,16 +2084,16 @@ Contributia personalului la asigurarile sociale 4312 other - + - Contributia unitatii pentru asigurarile sociale de sanatate + Contributia angajatorului pentru asigurarile sociale de sanatate 4313 other - + @@ -2168,7 +2102,7 @@ Contributia angajatilor pentru asigurarile sociale de sanatate 4314 other - + @@ -2177,7 +2111,7 @@ Contributia angajatorilor la fondul pentru concedii si indemnizatii 4315 other - + @@ -2186,7 +2120,7 @@ Contributia angajatorilor la fondul de asigurare pentru accidente de munca si boli profesionale 4316 other - + @@ -2196,7 +2130,7 @@ Ajutor de somaj 437 view - + @@ -2205,7 +2139,7 @@ Contributia unitatii la fondul de somaj 4371 other - + @@ -2214,7 +2148,7 @@ Contributia personalului la fondul de somaj 4372 other - + @@ -2223,7 +2157,7 @@ Contributia unitatii la fondul de garantare pentru plata creantelor salariale 4373 other - + @@ -2232,7 +2166,7 @@ Alte datorii si creante sociale 438 view - + @@ -2241,7 +2175,7 @@ Alte datorii sociale 4381 other - + @@ -2250,7 +2184,7 @@ Alte creante sociale 4382 receivable - + @@ -2259,7 +2193,7 @@ BUGETUL STATULUI, FONDURI SPECIALE sI CONTURI ASIMILATE 44 view - + @@ -2267,7 +2201,7 @@ Impozitul pe profit 441 view - + @@ -2276,7 +2210,7 @@ Impozitul pe profit 4411 other - + @@ -2285,7 +2219,7 @@ Impozitul pe venit 4418 other - + @@ -2294,7 +2228,7 @@ Taxa pe valoarea adaugata 442 view - + @@ -2303,7 +2237,7 @@ TVA de plata 4423 other - + @@ -2312,7 +2246,7 @@ TVA de recuperat 4424 other - + @@ -2321,7 +2255,7 @@ TVA deductibila 4426 other - + @@ -2330,7 +2264,7 @@ TVA colectata 4427 other - + @@ -2338,25 +2272,25 @@ TVA neexigibila 4428 other - + - Impozitul pe vanituri de natura salariilor + Impozitul pe venituri de natura salariilor 444 other - + - c + Subventii 445 view - + @@ -2365,16 +2299,16 @@ Subventii guvernamentale 4451 receivable - + - imprumuturi nerambursabile cu caracter de subventii + Imprumuturi nerambursabile cu caracter de subventii 4452 receivable - + @@ -2383,7 +2317,7 @@ Alte sume primite cu caracter de subventii 4458 receivable - + @@ -2392,7 +2326,7 @@ Alte impozite,taxe si varsaminte asimilate 446 other - + @@ -2401,7 +2335,7 @@ Fonduri speciale - taxe si varsaminte asimilate 447 other - + @@ -2410,7 +2344,7 @@ Alte datorii si creante cu bugetul statului 448 view - + @@ -2419,7 +2353,7 @@ Alte datorii fata de bugetul statului 4481 other - + @@ -2428,16 +2362,16 @@ Alte creante privind bugetul statului 4482 other - + - GRUP sI ACtIONARI / ASOCIAtI + GRUP SI ACTIONARI / ASOCIATI 45 view - + @@ -2445,7 +2379,7 @@ Decontari intre entitatile afiliate 451 view - + @@ -2453,8 +2387,8 @@ Decontari intre entitatile afiliate 4511 - receivable - + other + @@ -2462,8 +2396,8 @@ Dobanzi aferente decontarilor intre entitatile afiliate 4518 - receivable - + other + @@ -2472,7 +2406,7 @@ Decontari privind interesele de participare 453 view - + @@ -2480,8 +2414,8 @@ Decontari privind interesele de participare 4531 - receivable - + other + @@ -2489,8 +2423,8 @@ Dobanzi aferente decontarilor privind interesele de participare 4538 - receivable - + other + @@ -2499,7 +2433,7 @@ Sume datorate actionarilor/asociatilor 455 view - + @@ -2508,7 +2442,7 @@ Actionari/asociati - conturi curente 4551 receivable - + @@ -2517,7 +2451,7 @@ Actionari/asociati dobanzi la conturi curente receivable 4558 - + @@ -2525,8 +2459,8 @@ Decontari cu actionarii/asociatii privind capitalul 456 - receivable - + other + @@ -2535,7 +2469,7 @@ Dividende de plata 457 other - + @@ -2544,7 +2478,7 @@ Decontari din operatii in participare 458 view - + @@ -2553,7 +2487,7 @@ Decontari din operatii in participare - activ 4581 receivable - + @@ -2562,16 +2496,16 @@ Decontari din operatii in participare - pasiv 4582 receivable - + - DEBITORI sI CREDITORI DIVERsI + DEBITORI SI CREDITORI DIVERSI 46 view - + @@ -2579,7 +2513,7 @@ Debitori diversi 461 receivable - + @@ -2588,16 +2522,16 @@ Creditori diversi 462 other - + - CONTURI DE REGULARIZARE sI ASIMILATE + CONTURI DE REGULARIZARE SI ASIMILATE 47 view - + @@ -2605,7 +2539,7 @@ Cheltuieli integistrate in avans 471 receivable - + @@ -2614,7 +2548,7 @@ Venituri inregistrate in avans 472 other - + @@ -2622,25 +2556,78 @@ Decontari din operatiuni in curs de clarificare 473 - receivable - + other + + + + Subventii pentru investitii + 475 + view + + + + + + Subventii guvernamentale pentru investitii + 4751 + other + + + + + + + Imprumuturi nerambursabile cu caracter de subventii pentru investitii + 4752 + other + + + + + + + Donatii pentru investitii + 4753 + other + + + + + + + Plusuri de inventar de natura imobilizarilor + 4754 + other + + + + + + + Alte sume primite cu caracter de subventii pentru investitii + 4758 + other + + + + - DECONTaRI iN CADRUL UNITatII + DECONTARI IN CADRUL UNITATII 48 view - + - + Decontari intre unitati si subunitati 481 - receivable - + other + @@ -2648,18 +2635,18 @@ Decontari intre subunitati 482 - receivable - + other + - AJUSTaRI PENTRU DEPRECIEREA CREANtELOR + AJUSTARI PENTRU DEPRECIEREA CREANTELOR 49 view - + @@ -2667,7 +2654,7 @@ Ajustari pentru deprecierea creantelor - clienti 491 other - + @@ -2676,7 +2663,7 @@ Ajustari pentru deprecierea creantelor - decontari in cadrul grupului si cu actionarii/asociatii 495 other - + @@ -2685,7 +2672,7 @@ Ajustari pentru deprecierea creantelor - debitori diversi 496 receivable - + @@ -2694,15 +2681,15 @@ CONTURI DE TREZORERIE Clasa 5 view - + - INVESTItII PE TERMEN SCURT + INVESTITII PE TERMEN SCURT 50 view - + @@ -2710,7 +2697,7 @@ Actiuni detinute la entitatile afiliate 501 other - + @@ -2718,7 +2705,7 @@ Obligatiuni emise si rascumparate 505 other - + @@ -2726,7 +2713,7 @@ Obligatiuni 506 other - + @@ -2734,7 +2721,7 @@ Alte investitii pe termen scurt si creante asimilate 508 view - + @@ -2742,7 +2729,7 @@ Alte titluri de plasament 5081 other - + @@ -2750,7 +2737,7 @@ Dobanzi la obligatiuni si alte titluri de plasament 5088 other - + @@ -2758,7 +2745,7 @@ Varsaminte de efctuat pentru investitiile pe termen scurt 509 view - + @@ -2766,7 +2753,7 @@ Varsaminte de efctuat pentru actiunile detinute la institutiile afiliate 5091 other - + @@ -2774,7 +2761,7 @@ Varsaminte de efctuat pentru alte investitii pe termen scurt 5092 other - + @@ -2782,7 +2769,7 @@ CONTURI LA BANCI 51 view - + @@ -2790,7 +2777,7 @@ Valori de incasat 511 view - + @@ -2798,8 +2785,7 @@ Cecuri de incasat 5112 other - - + @@ -2807,7 +2793,7 @@ Efecte de incasat 5113 other - + @@ -2815,7 +2801,7 @@ Efecte remise spre scontare 5114 other - + @@ -2823,7 +2809,7 @@ Conturi curente la banci 512 view - + Se creeaza cate un cont pentru fiecare cont bancar @@ -2832,8 +2818,8 @@ Conturi la banci in lei 5121 - other - + view + @@ -2842,7 +2828,7 @@ Conturi la banci in valuta 5124 other - + @@ -2850,7 +2836,7 @@ Sume in curs de decontare 5125 other - + @@ -2858,7 +2844,7 @@ Dobanzi 518 view - + @@ -2866,8 +2852,7 @@ Dobanzi de platit 5186 other - - + @@ -2875,7 +2860,7 @@ Dobanzi de incasat 5187 other - + @@ -2883,7 +2868,7 @@ Credite bancare pe termen scurt 519 view - + @@ -2891,7 +2876,7 @@ Credite bancare pe termen scurt 5191 other - + @@ -2899,7 +2884,7 @@ Credite bancare pe termen scurt nerambursate la scadenta 5192 other - + @@ -2907,7 +2892,7 @@ Credite externe guvernamentale 5193 other - + @@ -2915,7 +2900,7 @@ Credite externe garantate de stat 5194 other - + @@ -2923,7 +2908,7 @@ Credite externe garantate de banci 5195 other - + @@ -2931,7 +2916,7 @@ Credite de la trezoreria statului 5196 other - + @@ -2939,7 +2924,7 @@ Credite interne garantate de stat 5197 other - + @@ -2947,7 +2932,7 @@ Dobanzi aferente creditelor pe termen scurt 5198 other - + @@ -2955,7 +2940,7 @@ CASA 53 view - + @@ -2963,7 +2948,7 @@ Casa 531 view - + @@ -2971,7 +2956,7 @@ Casa in lei 5311 other - + @@ -2979,7 +2964,7 @@ Casa in valuta 5314 other - + @@ -2987,7 +2972,7 @@ Alte valori 532 view - + @@ -2995,7 +2980,7 @@ Timbre fiscale si postale 5321 other - + @@ -3003,7 +2988,7 @@ Bilete de tratament si odihna 5322 other - + @@ -3011,7 +2996,7 @@ Tichete si bilete de calatorie 5323 other - + @@ -3019,7 +3004,7 @@ Alte valori 5328 other - + @@ -3027,7 +3012,7 @@ ACREDITIVE 54 view - + @@ -3035,7 +3020,7 @@ Acreditive 541 view - + @@ -3043,7 +3028,7 @@ Acreditive in lei 5411 other - + @@ -3051,7 +3036,7 @@ Acreditive in valuta 5412 other - + @@ -3059,7 +3044,7 @@ Avansuri de trezorerie 542 other - + in acest cont vor fi evidentiate si sumele acordate prin sistemul de carduri @@ -3068,7 +3053,7 @@ VIRAMENTE INTERNE 58 view - + @@ -3077,16 +3062,16 @@ Viramente interne 581 other - + - AJUSTaRI PENTRU PIERDEREA DE VALOARE A CONTURILOR DE TREZORERIE + AJUSTARI PENTRU PIERDEREA DE VALOARE A CONTURILOR DE TREZORERIE 59 view - + @@ -3094,7 +3079,7 @@ Ajustari pentru pierderea de valoare a actiunilor detinute la entitatile afiliate 591 other - + @@ -3102,7 +3087,7 @@ Ajustari pentru pierderea de valoare a obligatiunilor emise si recuperate 595 other - + @@ -3110,7 +3095,7 @@ Ajustari pentru pierderea de valoare a obligatiunilor 596 other - + @@ -3118,7 +3103,7 @@ Ajustari pentru pierderea de valoare a altor invesitii pe termen scurt si creante asimilate 598 other - + @@ -3126,7 +3111,7 @@ Conturile de venituri si cheltuieli Clasele 6 si 7 view - + @@ -3134,7 +3119,7 @@ CONTURI DE CHELTUIELI Clasa 6 view - + @@ -3142,15 +3127,15 @@ CHELTUIELI PRIVIND STOCURILE 60 view - + - Venituri din subventii de exploatareCheltuieli cu materiile prime + Cheltuieli cu materiile prime 601 other - + @@ -3158,7 +3143,7 @@ Cheltuieli cu materialele consumabile 602 view - + @@ -3166,7 +3151,7 @@ Cheltuieli cu materiale auxiliare 6021 other - + @@ -3174,7 +3159,7 @@ Cheltuieli privind combustibilul 6022 other - + @@ -3182,7 +3167,7 @@ Cheltuieli privind materialele pentru ambalat 6023 other - + @@ -3190,7 +3175,7 @@ Cheltuieli privind piesele de schimb 6024 other - + @@ -3198,7 +3183,7 @@ Cheltuieli privind semintele si materialele de plantat 6025 other - + @@ -3206,7 +3191,7 @@ Cheltuieli privind furajele 6026 other - + @@ -3214,7 +3199,7 @@ Cheltuieli privind alte materiale consumabile 6028 other - + @@ -3222,7 +3207,7 @@ Cheltuieli privind materialele de natura obiectelor de inventar 603 other - + @@ -3230,7 +3215,7 @@ Cheltuieli privind materialele nestocate 604 other - + @@ -3238,7 +3223,7 @@ Cheltuieli privind energia si apa 605 other - + @@ -3246,7 +3231,7 @@ Cheltuieli privind animalele si pasarile 606 other - + @@ -3254,7 +3239,7 @@ Cheltuieli privind marfurile 607 other - + @@ -3262,15 +3247,23 @@ Cheltuieli privind ambalajele 608 other - + - + + + Reduceri comerciale primite + 609 + other + + + + - CHELTUIELI CU LUCRaRIRE sI SERVICIILE EXECUTATE DE TERtI + CHELTUIELI CU LUCRARIRE SI SERVICIILE EXECUTATE DE TERTI 61 view - + @@ -3278,7 +3271,7 @@ Cheltuieli cu intretinerile si reparatiile 611 other - + @@ -3286,7 +3279,7 @@ Cheltuieli cu redeventele, locatiile de gestiune si chiriile 612 other - + @@ -3294,7 +3287,7 @@ Cheltuieli cu primele de asigurare 613 other - + @@ -3302,15 +3295,15 @@ Cheltuieli cu studiile si cercetarile 614 other - + - CHELTUIELI CU ALTE SERVICII EXECUTATE DE TERtI + CHELTUIELI CU ALTE SERVICII EXECUTATE DE TERTI 62 view - + @@ -3318,7 +3311,7 @@ Cheltuieli cu colaboratorii 621 other - + @@ -3327,7 +3320,7 @@ Cheltuieli privind comisioanele si onorariile 622 other - + @@ -3335,7 +3328,7 @@ Cheltuieli de protocol, reclama si publicitate 623 other - + @@ -3343,7 +3336,7 @@ Cheltuieli cu transportul de bunuri si personal 624 other - + @@ -3351,7 +3344,7 @@ Cheltuieli cu deplasari, detasari si transferari 625 other - + @@ -3359,7 +3352,7 @@ Cheltuieli postale si taxe de telecomunicatii 626 other - + @@ -3367,7 +3360,7 @@ Cheltuieli cu serviciile bancare si asimilate 627 other - + @@ -3375,7 +3368,7 @@ Alte cheltuieli cu serviciile executate de terti 628 other - + @@ -3383,7 +3376,7 @@ Cheltuieli cu alte impozite, taxe si varsaminte asimilate 63 view - + @@ -3391,7 +3384,7 @@ Cheltuieli cu alte impozite, taxe si varsaminte asimilate 635 other - + @@ -3399,7 +3392,7 @@ CHELTUIELI CU PERSONALUL 64 view - + @@ -3407,7 +3400,7 @@ Cheltuieli cu salariile personalului 641 other - + @@ -3415,15 +3408,31 @@ Cheltuieli cu tichetele de masa acordate salariatilor 642 other - + + + Cheltuieli cu primele reprezentand participarea personalului la profit + 643 + other + + + + + + Cheltuieli cu renumerarea in instrumente de capitaluri proprii + 644 + other + + + + Cheltuieli privind asigurarile si protectia sociala 645 view - + @@ -3431,7 +3440,7 @@ Contributia unitatii la asigurarile sociale 6451 other - + @@ -3439,7 +3448,7 @@ Contributia unitatii pentru ajutorul de somaj 6452 other - + @@ -3447,7 +3456,7 @@ Contributia angajatorului pentru asigurarile sociale de sanatate 6453 other - + @@ -3455,7 +3464,7 @@ Contributia unitatii la fondul de garantare 6454 other - + @@ -3463,15 +3472,31 @@ Contributia unitatii la fondul de concedii medicale 6455 other - + + + Contributia unitatii la schemele de pensii facultative + 6456 + other + + + + + + Contributia unitatii la primele de asigurare voluntara de sanatate + 6457 + other + + + + Alte cheltuieli privind asigurarile si protectia sociala 6458 other - + @@ -3479,15 +3504,23 @@ Alte cheltuieli de exploatare 65 view - + + + Cheltuieli cu protectia mediului inconjurator + 652 + other + + + + Pierderi din creante si debitori diversi 654 other - + @@ -3495,7 +3528,7 @@ Alte cheltuieli de exploatare 658 view - + @@ -3503,7 +3536,7 @@ Despagubiri, amenzi si penalitati 6581 other - + @@ -3511,7 +3544,7 @@ Donatii si subventii acordate 6582 other - + @@ -3519,7 +3552,7 @@ Cheltuieli privind activele cedate si alte operatii de capital 6583 other - + @@ -3527,16 +3560,15 @@ Alte cheltuieli de exploatare 6588 other - + - CHELTUIELI FINANCIARE 66 view - + @@ -3544,16 +3576,15 @@ Pierderi din creante legate de participatii 663 other - + - Cheltuieli privind investitiile financiare cedate 664 view - + @@ -3561,7 +3592,7 @@ Cheltuieli privind imobilizarile financiare cedate 6641 other - + @@ -3569,7 +3600,7 @@ Pierderi din investitiile pe termen scurt cedate 6642 other - + @@ -3577,7 +3608,7 @@ Cheltuieli din diferente de curs valutar 665 other - + @@ -3585,7 +3616,7 @@ Cheltuieli privind dobanzile 666 other - + @@ -3593,7 +3624,7 @@ Cheltuieli privind sconturile acordate 667 other - + @@ -3601,7 +3632,7 @@ Alte cheltuieli financiare 668 other - + @@ -3609,7 +3640,7 @@ CHELTUIELI EXTRAORDINARE 67 view - + @@ -3617,15 +3648,15 @@ Cheltuieli privind calamitatile si alte evenimente extraordinare 671 other - + - CHELTUIELI CU AMORTIZaRILE, PROVIZIOANELE sI AJUSTaRILE PENTRU DEPRECIERE SAU PIERDERE DE VALOARE + CHELTUIELI CU AMORTIZARILE, PROVIZIOANELE SI AJUSTARILE PENTRU DEPRECIERE SAU PIERDERE DE VALOARE 68 view - + @@ -3633,15 +3664,15 @@ Cheltuieli de exploatare privind amortizarile, provizioanele si ajustarile pentru depreciere 681 view - + - Alte cheltuieli cu serviciile executate de tertiCheltuieli de exploatare privind amortizarea imobilizarilor + Cheltuieli de exploatare privind amortizarea imobilizarilor 6811 other - + @@ -3649,7 +3680,7 @@ Cheltuieli de exploatare privind provizioanele 6812 other - + @@ -3657,7 +3688,7 @@ Cheltuieli de exploatare privind ajustarile pentru deprecierea imobilizarilor 6813 other - + @@ -3665,7 +3696,7 @@ Cheltuieli de exploatare privind ajustarile pentru deprecierea activelor circulante 6814 other - + @@ -3673,7 +3704,7 @@ Cheltuieli financiare privind amortizarile si ajustarile pentru pierdere de valoare 686 view - + @@ -3681,7 +3712,7 @@ Cheltuieli financiare privind ajustarile pentru pierderea de valoare a imobilizarilor financiare 6863 other - + @@ -3689,7 +3720,7 @@ Cheltuieli financiare privind ajustarile pentru pierderea de valoare a activelor circulante 6864 other - + @@ -3697,15 +3728,15 @@ Cheltuieli financiare privind amortizarea primelor de rambursare a obligatiunilor 6868 other - + - CHELTUIELI CU IMPOZITUL PE PROFIT sI ALTE IMPOZITE + CHELTUIELI CU IMPOZITUL PE PROFIT SI ALTE IMPOZITE 69 view - + @@ -3713,7 +3744,7 @@ Impozitul pe profit 691 other - + @@ -3721,7 +3752,7 @@ Cheltuieli cu impozitul pe venit si cu alte impozite care nu apar in elementele de mai sus 698 other - + Se utilizeaza conform reglementarilor legale @@ -3730,15 +3761,15 @@ CONTURI DE VENITURI Clasa 7 view - + - CIFRA DE AFACERI NETa + CIFRA DE AFACERI NETA 70 view - + @@ -3746,7 +3777,7 @@ Venituri din vanzarea produselor finite 701 other - + @@ -3754,7 +3785,7 @@ Venituri din vanzarea semifabricatelor 702 other - + @@ -3762,7 +3793,7 @@ Venituri din vanzarea produselor reziduale 703 other - + @@ -3770,7 +3801,7 @@ Venituri din lucrari executate si servicii prestate 704 other - + @@ -3778,7 +3809,7 @@ Venituri din studii si cercetari 705 other - + @@ -3786,7 +3817,7 @@ Venituri din redevente, locatii de gestiune si chirii 706 other - + @@ -3794,7 +3825,7 @@ Venituri din vanzarea marfurilor 707 other - + 707-607 = adaosul comercial @@ -3803,23 +3834,39 @@ Venituri din activitati diverse 708 other - + + + + + + Reduceri comerciale acordate + 709 + other + - Variatia stocurilor + Venituri aferente costului productiei in curs de executie 71 view - + - Variatia stocurilor + Venituri aferente costurilor stocurilor de produse 711 other - + + + + + + Venituri aferente costurilor serviciilor in curs de executie + 712 + other + @@ -3827,7 +3874,7 @@ Venituri din productia de imobilizari 72 view - + @@ -3835,7 +3882,7 @@ Venituri din productia de imobilizari necorporale 721 other - + @@ -3843,15 +3890,15 @@ Venituri din productia de imobilizari corporale 722 other - + - VENITURI DIN SUBVENtII DE EXPLOATARE + VENITURI DIN SUBVENTII DE EXPLOATARE 74 view - + @@ -3859,7 +3906,7 @@ Venituri din subventii de exploatare 741 view - + @@ -3867,7 +3914,7 @@ Venituri din subventii de exploatare aferente cifrei de afaceri 7411 other - + Se ia in calcul la determinarea cifrei de afaceri @@ -3876,7 +3923,7 @@ Venituri din subventii de exploatare pentru materii prime si materiale consumabile 7412 other - + @@ -3884,7 +3931,7 @@ Venituri din subventii de exploatare pentru alte cheltuieli externe 7413 other - + @@ -3892,7 +3939,7 @@ Venituri din subventii de exploatare pentru plata personalului 7414 other - + @@ -3900,7 +3947,7 @@ Venituri din subventii de exploatare pentru asigurari si protectie sociala 7415 other - + @@ -3908,7 +3955,7 @@ Venituri din subventii de exploatare pentru alte cheltuieli de exploatare 7416 other - + @@ -3916,7 +3963,7 @@ Venituri din subventii de exploatare aferente altor venituri 7417 other - + @@ -3924,7 +3971,7 @@ Venituri din subventii de exploatare pentru dobanda datorata 7418 other - + @@ -3932,7 +3979,7 @@ ALTE VENITURI DIN EXPLOATARE 75 view - + @@ -3940,7 +3987,7 @@ Venituri din creante reactivate si debitori diversi 754 other - + @@ -3948,7 +3995,7 @@ Alte venituri din exploatare 758 view - + @@ -3956,7 +4003,7 @@ Venituri din despagubiri, amenzi si penalitati 7581 other - + @@ -3964,7 +4011,7 @@ Venituri din donatii si subventii primite 7582 other - + @@ -3972,7 +4019,7 @@ Venituri din vanzarea activelor si alte operatii de capital 7583 other - + @@ -3980,7 +4027,7 @@ Venituri din subventii pentru investitii 7584 other - + @@ -3988,7 +4035,7 @@ Alte venituri din exploatare 7588 other - + @@ -3996,7 +4043,7 @@ VENITURI FINANCIARE 76 view - + @@ -4004,7 +4051,7 @@ Venituri din imobilizari financiare 761 view - + @@ -4012,7 +4059,7 @@ Venituri din actiuni detinute la entitatile afiliate 7611 other - + @@ -4020,7 +4067,7 @@ Venituri din interese de participare 7613 other - + @@ -4028,7 +4075,7 @@ Venituri din investitii financiare pe termen scurt 762 other - + @@ -4036,7 +4083,7 @@ Venituri din creante imobilizate 763 other - + @@ -4044,7 +4091,7 @@ Venituri din investitii financiare cedate 764 view - + @@ -4052,7 +4099,7 @@ Venituri din imobilizari financiare cedate 7641 other - + @@ -4060,7 +4107,7 @@ Castiguri din investitii pe termen scurt cedate 7642 other - + @@ -4068,7 +4115,7 @@ Venituri din diferente de curs valutar 765 other - + @@ -4076,7 +4123,7 @@ Venituri din dobanzi 766 other - + @@ -4084,7 +4131,7 @@ Venituri din sconturi obtinute 767 other - + (contrepartie 667) @@ -4093,7 +4140,7 @@ Alte venituri financiare 768 other - + @@ -4101,7 +4148,7 @@ VENITURI EXTRAORDINARE 77 view - + @@ -4109,15 +4156,15 @@ Venituri din subventii pentru evenimente extraordinare si altele similare 771 other - + - VENITURI DIN PROVIZIOANE sI AJUSTaRI PENTRU DEPRECIERE SAU PIERDERE DE VALOARE + VENITURI DIN PROVIZIOANE SI AJUSTARI PENTRU DEPRECIERE SAU PIERDERE DE VALOARE 78 view - + @@ -4125,7 +4172,7 @@ Venituri din provizioane si ajustari pentru depreciere privind activitatea de exploatare 781 view - + @@ -4133,7 +4180,7 @@ Venituri din provizioane 7812 other - + @@ -4141,7 +4188,7 @@ Venituri din ajustari pentru deprecierea imobilizarilor 7813 other - + @@ -4149,7 +4196,7 @@ Venituri din ajustari pentru deprecierea activelor circulante 7814 other - + @@ -4158,7 +4205,7 @@ 7815 other Acest cont apare numai in situatiile anuale consolidate - + @@ -4166,7 +4213,7 @@ Venituri financiare din ajustari pentru pierdere de valoare 786 view - + @@ -4174,7 +4221,7 @@ Venituri financiare din ajustari pentru pierderea de valoare a imobilizarilor financiare 7863 other - + @@ -4182,7 +4229,7 @@ Venituri financiare din ajustari pentru pierderea de valoare a activelor circulante 7864 other - + @@ -4190,7 +4237,7 @@ CONTURI SPECIALE Clasa 8 view - + @@ -4198,7 +4245,7 @@ CONTURI IN AFARA BILANTULUI 80 view - + @@ -4206,7 +4253,7 @@ Angajamente acordate 801 view - + @@ -4214,7 +4261,7 @@ Giruri si garantii acordate 8011 other - + @@ -4222,7 +4269,7 @@ Alte angajamente acordate 8018 other - + @@ -4230,7 +4277,7 @@ Angajamente primite 802 view - + @@ -4238,7 +4285,7 @@ Giruri si garantii primite 8021 other - + @@ -4246,7 +4293,7 @@ Alte angajamente primite 8028 other - + @@ -4254,7 +4301,7 @@ Alte conturi in afara bilantului 803 view - + @@ -4315,18 +4362,26 @@ - Alte valori in afara bilantului + Bunuri publice primite in administrare, concesiune si cu chirie 8038 other + + Alte valori in afara bilantului + 8039 + other + + + + Amortizarea aferenta gradului de neutilizare a mijloacelor fixe 804 view - + @@ -4342,7 +4397,7 @@ Dobanzi aferente contractelor de leasing si altor contracte asimilate, neajunse la scadenta 805 view - + @@ -4362,11 +4417,35 @@ + + Certificate de emisii de gaze cu efect de sera + 806 + other + + + + + + Active contingente + 807 + other + + + + + + Datorii contingente + 808 + other + + + + Bilant 89 view - + @@ -4385,18 +4464,130 @@ + + + CONTURI DE GESTIUNE + Clasa 9 + view + + + + + + DECONTARI INTERNE + 90 + view + + + + + + Decontari interne privind cheltuielile + 901 + other + + + - - - Romania - Chart of Accounts - - - - - - - - - + + Decontari interne privind productia obtinuta + 902 + other + + + + + + Decontari interne privind diferentele de pret + 903 + other + + + + + + CONTURI DE CALCULATIE + 92 + view + + + + + + Cheltuielile activitatii de baza + 921 + other + + + + + + Cheltuielile activitatilor auxiliare + 922 + other + + + + + + Cheltuieli indirecte de productie + 923 + other + + + + + + Cheltuieli generale de administratie + 924 + other + + + + + + Cheltuieli de desfacere + 925 + other + + + + + + COSTUL PRODUCTIEI + 93 + view + + + + + + Costul productiei obtinute + 931 + other + + + + + + Costul productiei de executie + 933 + other + + + + + + + Romania - Chart of Accounts + + + + + + + + + diff --git a/addons/l10n_ro/account_tax.xml b/addons/l10n_ro/account_tax.xml deleted file mode 100644 index 22c2478110f..00000000000 --- a/addons/l10n_ro/account_tax.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - TVA colectat 0% - 0.000000 - percent - - - - 1.00 - - 1.00 - - -1.00 - - -1.00 - - - - TVA colectat 5% - 0.090000 - percent - - - - - - - -1.00 - -1.00 - 1.00 - 1.00 - - - - TVA colectat 9% - 0.090000 - percent - - - - - - - -1.00 - -1.00 - 1.00 - 1.00 - - - - TVA colectat 19% - 0.190000 - percent - - - - - - - -1.00 - -1.00 - 1.00 - 1.00 - - - - - TVA deductibil 0% - 0.000000 - percent - - - - 1.00 - - 1.00 - - -1.00 - - -1.00 - - - - TVA deductibil 5% - 0.090000 - percent - - - - - - - -1.00 - -1.00 - 1.00 - 1.00 - - - - TVA deductibil 9% - 0.090000 - percent - - - - - - - -1.00 - -1.00 - 1.00 - 1.00 - - - - TVA deductibil 19% - 0.190000 - percent - - - - - - - -1.00 - -1.00 - 1.00 - 1.00 - - - - - diff --git a/addons/l10n_ro/account_tax_code.xml b/addons/l10n_ro/account_tax_code.xml deleted file mode 100644 index 247c70b5f06..00000000000 --- a/addons/l10n_ro/account_tax_code.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - - -# -# Tax Code Template Configuration -# - - Decont TVA - - - - TVA COLECTATA - b) - - - - - TVA 19% - TVA colectata 19% - - - - TVA 9% - TVA colectata 9% - - - - TVA 5% - TVA colectata 5% - - - - - TVA Taxare inversa - TVA - - - - - TVA 0% - TVA colectata 0% - - - - - BAZA TVA COLECTAT - a) - - - - Baza TVA 19% - TVA colectata 19%(Baza) - - - - Baza TVA 9% - TVA colectata 9%(Baza) - - - - Baza TVA 5% - TVA colectata 5%(Baza) - - - - - Baza TVA Taxare inversa - Baza - - - - - Baza TVA 0% - TVA colectata 0%(Baza) - - - - - - TVA DEDUCTIBILA - d) - - - - TVA 19% - TVA deductibila 19% - - - - TVA 9% - TVA deductibila 9% - - - - TVA 5% - TVA deductibila 5% - - - - - TVA 0% - TVA deductibila 0% - - - - BAZA TVA DEDUCTIBIL - c) - - - - Baza TVA 19% - TVA deductibila 19%(Baza) - - - - Baza TVA 9% - TVA deductibila 9%(Baza) - - - - Baza TVA 5% - TVA deductibila 5%(Baza) - - - - - Baza TVA 0% - TVA deductibila 0%(Baza) - - - - - diff --git a/addons/l10n_ro/account_tax_code_template.xml b/addons/l10n_ro/account_tax_code_template.xml new file mode 100644 index 00000000000..21b99b02e28 --- /dev/null +++ b/addons/l10n_ro/account_tax_code_template.xml @@ -0,0 +1,186 @@ + + + + +# +# Tax Code Template Configuration +# + + Decont TVA + + + + TVA COLECTATA + b) + + + + + TVA 24% + TVA colectata 24% + + + + TVA 19% + TVA colectata 19% + + + + TVA 9% + TVA colectata 9% + + + + TVA 5% + TVA colectata 5% + + + + + TVA Taxare inversa + TVA + + + + + TVA 0% + TVA colectata 0% + + + + + BAZA TVA COLECTAT + a) + + + + Baza TVA 24% + TVA colectata 24%(Baza) + + + + Baza TVA 19% + TVA colectata 19%(Baza) + + + + Baza TVA 9% + TVA colectata 9%(Baza) + + + + Baza TVA 5% + TVA colectata 5%(Baza) + + + + + Baza TVA Taxare inversa + Baza + + + + + Baza TVA 0% + TVA colectata 0%(Baza) + + + + + + TVA DEDUCTIBILA + d) + + + + TVA 24% + TVA deductibila 24% + + + + TVA 19% + TVA deductibila 19% + + + + TVA 9% + TVA deductibila 9% + + + + TVA 5% + TVA deductibila 5% + + + + + TVA 0% + TVA deductibila 0% + + + + BAZA TVA DEDUCTIBIL + c) + + + + Baza TVA 24% + TVA deductibila 24%(Baza) + + + + Baza TVA 19% + TVA deductibila 19%(Baza) + + + + Baza TVA 9% + TVA deductibila 9%(Baza) + + + + Baza TVA 5% + TVA deductibila 5%(Baza) + + + + + Baza TVA 0% + TVA deductibila 0%(Baza) + + + + + BAZA TVA NEEXIGIBIL + e) + + + + Baza TVA neexigibil - colectat + TVA neexigibil - colectat (Baza) + + + + Baza TVA neexigibil - deductibil + TVA neexigibil - deductibil (Baza) + + + + TVA NEEXIGIBIL + f) + + + + TVA neexigibil - colectat + TVA neexigibil - colectat + + + + TVA neexigibil - deductibil + TVA neexigibil - deductibil + + + + + + diff --git a/addons/l10n_ro/account_tax_template.xml b/addons/l10n_ro/account_tax_template.xml new file mode 100644 index 00000000000..cfb6c6aca1a --- /dev/null +++ b/addons/l10n_ro/account_tax_template.xml @@ -0,0 +1,170 @@ + + + + + + TVA colectat 0% + 0.000000 + percent + + + + 1.00 + + 1.00 + + -1.00 + + -1.00 + + + + TVA colectat 5% + 0.050000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + TVA colectat 9% + 0.090000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + TVA colectat 19% + 0.190000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + + TVA colectat 24% + 0.240000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + + TVA deductibil 0% + 0.000000 + percent + + + + 1.00 + + 1.00 + + -1.00 + + -1.00 + + + + TVA deductibil 5% + 0.050000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + TVA deductibil 9% + 0.090000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + TVA deductibil 19% + 0.190000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + + TVA deductibil 24% + 0.240000 + percent + + + + + + + -1.00 + -1.00 + 1.00 + 1.00 + + + + + diff --git a/addons/l10n_ro/i18n/ar.po b/addons/l10n_ro/i18n/ar.po deleted file mode 100644 index 7773868c897..00000000000 --- a/addons/l10n_ro/i18n/ar.po +++ /dev/null @@ -1,132 +0,0 @@ -# Arabic translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-01-10 21:54+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Arabic \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "الدائنون" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "خطأ ! لا يمكنك إنشاء أعضاء مرتبطين و متداخلين." - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "الأسهم" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "الدخل" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "ضريبة" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "نقدي" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "الخصوم" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "مدفوعات" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "أصل" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "عرض" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "الأسهم" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "شريك" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "مصروف" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "خاص" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "إعداد شجرة الحسابات من قالب. ستم سؤالك عن اسم المنشأة، القالب المتبع، و " -#~ "إعداد أكواد الحسابات و البنوك، بالإضافة إلي يوميات العملة. و لذلك سيكون هناك " -#~ "قالب جديد. \n" -#~ "\tهذه لإعداد الحسابات." diff --git a/addons/l10n_ro/i18n/ca.po b/addons/l10n_ro/i18n/ca.po deleted file mode 100644 index 1bb4a6ea94f..00000000000 --- a/addons/l10n_ro/i18n/ca.po +++ /dev/null @@ -1,146 +0,0 @@ -# Catalan translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-02-15 15:37+0000\n" -"Last-Translator: FULL NAME \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: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Empresa" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Nombre de registre al Registre de Comerç" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Genera el pla de comptes des d'una plantilla de pla. Se us demanarà el nom " -#~ "de l'empresa, la plantilla de pla a seguir, i el número de dígits per " -#~ "generar el codi dels vostres comptes, compte bancari, i divisa per crear els " -#~ "vostres diaris. Per tant, es genera una còpia directa de la plantilla del " -#~ "pla de comptes.\n" -#~ "\t Aquest és el mateix assistent que s'executa des de " -#~ "Comptabilitat/Configuració/Comptabilitat financera/Comptes financers/Genera " -#~ "pla comptable des d'una plantilla de pla comptable." - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Aquest és el mòdul que gestiona el pla comptable, estructura d'Impostos i " -#~ "número de Registre per a Romania amb OpenERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Romania - Pla comptable" diff --git a/addons/l10n_ro/i18n/da.po b/addons/l10n_ro/i18n/da.po deleted file mode 100644 index 89b6fa62b38..00000000000 --- a/addons/l10n_ro/i18n/da.po +++ /dev/null @@ -1,118 +0,0 @@ -# Danish translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-01-27 09:01+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Danish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "" diff --git a/addons/l10n_ro/i18n/es.po b/addons/l10n_ro/i18n/es.po deleted file mode 100644 index 0c6e92c9019..00000000000 --- a/addons/l10n_ro/i18n/es.po +++ /dev/null @@ -1,146 +0,0 @@ -# Spanish translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-02-15 15:37+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Spanish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Empresa" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Número de registro en el Registro de Comercio" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Este es el módulo que gestiona el plan contable, estructura de Impuestos y " -#~ "Número de Registro para Rumanía en Open ERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Rumanía - Plan Contable" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Generar Plan Contable a partir de una plantilla de Plan. Se le preguntará " -#~ "por el nombre de la compañía, la plantilla de plan contable a seguir, el no. " -#~ "de dígitos para generar el código de sus cuentas y la cuenta bancaria, la " -#~ "divisa para crear Diarios. Por lo tanto, la copia exacta de la plantilla de " -#~ "plan contable será generada.\n" -#~ "Este es el mismo asistente que se ejecuta desde Gestión " -#~ "Financiera/Configuración/Contabilidad Financiera/Contabilidad " -#~ "Financiera/Generar Plan Contable a partir de una Plantilla de Plan." diff --git a/addons/l10n_ro/i18n/es_CR.po b/addons/l10n_ro/i18n/es_CR.po deleted file mode 100644 index b692c7b474d..00000000000 --- a/addons/l10n_ro/i18n/es_CR.po +++ /dev/null @@ -1,147 +0,0 @@ -# Spanish translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-02-17 19:37+0000\n" -"Last-Translator: Freddy Gonzalez \n" -"Language-Team: Spanish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" -"Language: es\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "A cobrar" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "Inmobilización" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "¡Error! No puede crear miembros asociados recursivamente." - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "Provisiones" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "Stocks" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "Ingreso" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "Impuesto" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "Compromiso" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "Efectivo" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "Responsabilidad" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "A pagar" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "Activo" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "Vista" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "Equidad" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Empresa" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "Gastos" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "Especial" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Número de registro en el Registro de Comercio" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Generar Plan Contable a partir de una plantilla de Plan. Se le preguntará " -#~ "por el nombre de la compañía, la plantilla de plan contable a seguir, el no. " -#~ "de dígitos para generar el código de sus cuentas y la cuenta bancaria, la " -#~ "divisa para crear Diarios. Por lo tanto, la copia exacta de la plantilla de " -#~ "plan contable será generada.\n" -#~ "Este es el mismo asistente que se ejecuta desde Gestión " -#~ "Financiera/Configuración/Contabilidad Financiera/Contabilidad " -#~ "Financiera/Generar Plan Contable a partir de una Plantilla de Plan." - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Este es el módulo que gestiona el plan contable, estructura de Impuestos y " -#~ "Número de Registro para Rumanía en Open ERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Rumanía - Plan Contable" diff --git a/addons/l10n_ro/i18n/es_MX.po b/addons/l10n_ro/i18n/es_MX.po deleted file mode 100644 index ac016c5ddf7..00000000000 --- a/addons/l10n_ro/i18n/es_MX.po +++ /dev/null @@ -1,67 +0,0 @@ -# Spanish translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2011-01-07 06:16+0000\n" -"PO-Revision-Date: 2011-02-15 15:37+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Spanish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-05 05:59+0000\n" -"X-Generator: Launchpad (build 13830)\n" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Número de registro en el Registro de Comercio" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:ir.actions.todo,note:l10n_ro.config_call_account_template_ro -msgid "" -"Generate Chart of Accounts from a Chart Template. You will be asked to pass " -"the name of the company, the chart template to follow, the no. of digits to " -"generate the code for your accounts and Bank account, currency to create " -"Journals. Thus,the pure copy of chart Template is generated.\n" -"\tThis is the same wizard that runs from Financial " -"Management/Configuration/Financial Accounting/Financial Accounts/Generate " -"Chart of Accounts from a Chart Template." -msgstr "" -"Generar Plan Contable a partir de una plantilla de Plan. Se le preguntará " -"por el nombre de la compañía, la plantilla de plan contable a seguir, el no. " -"de dígitos para generar el código de sus cuentas y la cuenta bancaria, la " -"divisa para crear Diarios. Por lo tanto, la copia exacta de la plantilla de " -"plan contable será generada.\n" -"Este es el mismo asistente que se ejecuta desde Gestión " -"Financiera/Configuración/Contabilidad Financiera/Contabilidad " -"Financiera/Generar Plan Contable a partir de una Plantilla de Plan." - -#. module: l10n_ro -#: model:ir.module.module,shortdesc:l10n_ro.module_meta_information -msgid "Romania - Chart of Accounts" -msgstr "Rumanía - Plan Contable" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Empresa" - -#. module: l10n_ro -#: model:ir.module.module,description:l10n_ro.module_meta_information -msgid "" -"This is the module to manage the accounting chart, VAT structure and " -"Registration Number for Romania in Open ERP." -msgstr "" -"Este es el módulo que gestiona el plan contable, estructura de Impuestos y " -"Número de Registro para Rumanía en Open ERP." diff --git a/addons/l10n_ro/i18n/es_PY.po b/addons/l10n_ro/i18n/es_PY.po deleted file mode 100644 index 16ce09305fc..00000000000 --- a/addons/l10n_ro/i18n/es_PY.po +++ /dev/null @@ -1,146 +0,0 @@ -# Spanish (Paraguay) translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-03-21 16:30+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Spanish (Paraguay) \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Socio" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Número de registro en el Registro de Comercio" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Este es el módulo que gestiona el plan contable, estructura de Impuestos y " -#~ "Número de Registro para Rumanía en Open ERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Rumanía - Plan Contable" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Generar el plan contable a partir de una plantilla de plan contable. Se le " -#~ "pedirá el nombre de la compañía, la plantilla de plan contable a utilizar, " -#~ "el número de dígitos para generar el código de las cuentas y de la cuenta " -#~ "bancaria, la moneda para crear los diarios. Así pues, se genere una copia " -#~ "exacta de la plantilla de plan contable.\n" -#~ "\tEste es el mismo asistente que se ejecuta desde Contabilidad y finanzas / " -#~ "Configuración / Contabilidad financiera / Cuentas financieras / Generar el " -#~ "plan contable a partir de una plantilla de plan contable." diff --git a/addons/l10n_ro/i18n/es_VE.po b/addons/l10n_ro/i18n/es_VE.po deleted file mode 100644 index ac016c5ddf7..00000000000 --- a/addons/l10n_ro/i18n/es_VE.po +++ /dev/null @@ -1,67 +0,0 @@ -# Spanish translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2011-01-07 06:16+0000\n" -"PO-Revision-Date: 2011-02-15 15:37+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Spanish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-05 05:59+0000\n" -"X-Generator: Launchpad (build 13830)\n" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Número de registro en el Registro de Comercio" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:ir.actions.todo,note:l10n_ro.config_call_account_template_ro -msgid "" -"Generate Chart of Accounts from a Chart Template. You will be asked to pass " -"the name of the company, the chart template to follow, the no. of digits to " -"generate the code for your accounts and Bank account, currency to create " -"Journals. Thus,the pure copy of chart Template is generated.\n" -"\tThis is the same wizard that runs from Financial " -"Management/Configuration/Financial Accounting/Financial Accounts/Generate " -"Chart of Accounts from a Chart Template." -msgstr "" -"Generar Plan Contable a partir de una plantilla de Plan. Se le preguntará " -"por el nombre de la compañía, la plantilla de plan contable a seguir, el no. " -"de dígitos para generar el código de sus cuentas y la cuenta bancaria, la " -"divisa para crear Diarios. Por lo tanto, la copia exacta de la plantilla de " -"plan contable será generada.\n" -"Este es el mismo asistente que se ejecuta desde Gestión " -"Financiera/Configuración/Contabilidad Financiera/Contabilidad " -"Financiera/Generar Plan Contable a partir de una Plantilla de Plan." - -#. module: l10n_ro -#: model:ir.module.module,shortdesc:l10n_ro.module_meta_information -msgid "Romania - Chart of Accounts" -msgstr "Rumanía - Plan Contable" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Empresa" - -#. module: l10n_ro -#: model:ir.module.module,description:l10n_ro.module_meta_information -msgid "" -"This is the module to manage the accounting chart, VAT structure and " -"Registration Number for Romania in Open ERP." -msgstr "" -"Este es el módulo que gestiona el plan contable, estructura de Impuestos y " -"Número de Registro para Rumanía en Open ERP." diff --git a/addons/l10n_ro/i18n/gl.po b/addons/l10n_ro/i18n/gl.po deleted file mode 100644 index d6535bd4509..00000000000 --- a/addons/l10n_ro/i18n/gl.po +++ /dev/null @@ -1,145 +0,0 @@ -# Galician translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-03-02 23:31+0000\n" -"Last-Translator: FULL NAME \n" -"Language-Team: Galician \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Socio" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Número de rexistro no Rexistro de Comercio" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Este é o módulo que xestiona o plan contable, a estrutura dos Impostos e o " -#~ "Número de Rexistro para Romanía no Open ERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Romanía - Plan contable" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Xerar o Plan Contable a partir dun modelo de Plan. Pediráselle o nome da " -#~ "compañía, o modelo do plan contable a seguir, o número de díxitos para xerar " -#~ "o código das súas contas e a conta bancaria, a divisa para crear Diarios. " -#~ "Deste xeito xerarase a copia exacta do modelo do plan contable. Este é o " -#~ "mesmo asistente que se executa desde Xestión " -#~ "financeira/Configuración/Contabilidade financeira/Contabilidade " -#~ "financeira/Xerar Plan Contable a partir dun modelo de plan." diff --git a/addons/l10n_ro/i18n/it.po b/addons/l10n_ro/i18n/it.po deleted file mode 100644 index 6bee2ebd638..00000000000 --- a/addons/l10n_ro/i18n/it.po +++ /dev/null @@ -1,146 +0,0 @@ -# Italian translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-02-15 15:37+0000\n" -"Last-Translator: FULL NAME \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: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Partner" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Numero di registrazione alla Camera di Commercio" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Questo è il modulo per gestire il piano dei conti, la partita IVA e il " -#~ "numero di registrazione per la Romania in OpenERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Romania - Piano dei conti" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Genera il Piano dei Conti da un Modello. Vi verrà richiesto di passare il " -#~ "nome dell'azienda, il modello da seguire, il numero di decimali per generare " -#~ "il codice dei tuoi conti e, per il conto della Banca, la valuta per creare " -#~ "il Libro Giornale. Così una copia vergine del Piano dei Conti, derivatante " -#~ "dal modello, viene generata.\n" -#~ "\tQuesto è la stessa procedura automatica che viene lanciata da: Gestione " -#~ "Finanziaria / Configurazione / Contabilità / Conti finanziari / Genera il " -#~ "Piano dei conti da un modello." diff --git a/addons/l10n_ro/i18n/l10n_ro.pot b/addons/l10n_ro/i18n/l10n_ro.pot deleted file mode 100644 index 12fc3f8b5f8..00000000000 --- a/addons/l10n_ro/i18n/l10n_ro.pot +++ /dev/null @@ -1,117 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * l10n_ro -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0alpha\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-11-24 02:53+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "" - diff --git a/addons/l10n_ro/i18n/pt.po b/addons/l10n_ro/i18n/pt.po deleted file mode 100644 index d86aac0c2ac..00000000000 --- a/addons/l10n_ro/i18n/pt.po +++ /dev/null @@ -1,118 +0,0 @@ -# Portuguese translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-04-23 14:56+0000\n" -"Last-Translator: FULL NAME \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: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "Recebível" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "Erro! Não pode criar membros recursivos." - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "Provisões" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "Stocks" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "Imposto" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "Dinheiro" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "Pagável" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "Vista" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Parceiro" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "Despesas" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "Especial" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "" diff --git a/addons/l10n_ro/i18n/pt_BR.po b/addons/l10n_ro/i18n/pt_BR.po deleted file mode 100644 index a1cfa91235a..00000000000 --- a/addons/l10n_ro/i18n/pt_BR.po +++ /dev/null @@ -1,145 +0,0 @@ -# Brazilian Portuguese translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-03-10 23:17+0000\n" -"Last-Translator: Emerson \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: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Partner" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Registration number at the Registry of Commerce" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Romania - Chart of Accounts" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." diff --git a/addons/l10n_ro/i18n/ro.po b/addons/l10n_ro/i18n/ro.po deleted file mode 100644 index 3d17e010d2f..00000000000 --- a/addons/l10n_ro/i18n/ro.po +++ /dev/null @@ -1,146 +0,0 @@ -# Romanian translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-02-15 15:37+0000\n" -"Last-Translator: FULL NAME \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: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "Incasari" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "Imobilizare" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "Eroare ! Nu puteti crea membri asociati recursiv." - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "Provizii" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "Stocuri" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "Venit" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "Taxa" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "Angajament" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "Numerar" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "Raspundere" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "Plati" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "Active" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "Vizualizeaza" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "Capital" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Partener" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "Cheltuieli" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "Special" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Numarul de inregistrare la Registrul Comertului" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Acesta este modulul pentru gestionarea planului de conturi, structura TVA-" -#~ "ului si Numărul de Inregistrare pentru Romania in OpenERP." - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Romania - Plan de Conturi" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Genereaza Planul de Conturi dintr-un Sablon. Vi se va cere sa specificati " -#~ "numele companiei, sablonul de urmat, numarul de cifre pentru generarea " -#~ "codului pentru conturile dumneavoastra si Contul bancar, moneda pentru " -#~ "crearea Jurnalelor. Astfel, este generata copia Sablonului planului de " -#~ "conturi.\n" -#~ "\t Acesta este acelasi asistent care ruleaza din Managementul " -#~ "Financiar/Configurare/Contabilitate Financiara/Conturi Financiare/Genereaza " -#~ "Plan de Conturi dintr-un Sablon de planuri." diff --git a/addons/l10n_ro/i18n/sr@latin.po b/addons/l10n_ro/i18n/sr@latin.po deleted file mode 100644 index 059fb12f2b0..00000000000 --- a/addons/l10n_ro/i18n/sr@latin.po +++ /dev/null @@ -1,146 +0,0 @@ -# Serbian Latin translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2011-10-13 14:55+0000\n" -"Last-Translator: Milan Milosevic \n" -"Language-Team: Serbian Latin \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "NRC" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "Partner" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "Registracioni broj pri Trgovinskom registru" - -#~ msgid "" -#~ "This is the module to manage the accounting chart, VAT structure and " -#~ "Registration Number for Romania in Open ERP." -#~ msgstr "" -#~ "Ovo je model za sređivanje računskih tabela, VAT strukture i Registracioni " -#~ "broj za Rumuniju u OPenERP-u" - -#~ msgid "Romania - Chart of Accounts" -#~ msgstr "Rumunija - računske tabele" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Generiše tabelu računâ iz šablona tabelâ. Bićete upitani za ime kompanije, " -#~ "šablon tabelâ koji ćete pratiti, broj cifara za generisanje koda za Vaše " -#~ "naloge i bankovni račun, valuta za pravljenje dnevnika. Na taj način se " -#~ "generiše čista kopija šablona tabelâ.\n" -#~ "\n" -#~ "\tTo je isti setup wizard koji se pokreće iz Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." diff --git a/addons/l10n_ro/i18n/tr.po b/addons/l10n_ro/i18n/tr.po deleted file mode 100644 index 028e41591b7..00000000000 --- a/addons/l10n_ro/i18n/tr.po +++ /dev/null @@ -1,135 +0,0 @@ -# Turkish translation for openobject-addons -# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 -# This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: openobject-addons\n" -"Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-01-25 17:26+0000\n" -"Last-Translator: Ahmet Altınışık \n" -"Language-Team: Turkish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-25 06:31+0000\n" -"X-Generator: Launchpad (build 16293)\n" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_receivable -msgid "Receivable" -msgstr "Alacak" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_immobilization -msgid "Immobilization" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error ! You cannot create recursive associated members." -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_provision -msgid "Provisions" -msgstr "" - -#. module: l10n_ro -#: field:res.partner,nrc:0 -msgid "NRC" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_stocks -msgid "Stocks" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_income -msgid "Income" -msgstr "Gelir" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_tax -msgid "Tax" -msgstr "Vergi" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_commitment -msgid "Commitment" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_cash -msgid "Cash" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_liability -msgid "Liability" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_payable -msgid "Payable" -msgstr "" - -#. module: l10n_ro -#: constraint:res.partner:0 -msgid "Error: Invalid ean code" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_asset -msgid "Asset" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_view -msgid "View" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_equity -msgid "Equity" -msgstr "" - -#. module: l10n_ro -#: model:ir.model,name:l10n_ro.model_res_partner -msgid "Partner" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_expense -msgid "Expense" -msgstr "" - -#. module: l10n_ro -#: model:account.account.type,name:l10n_ro.account_type_special -msgid "Special" -msgstr "" - -#. module: l10n_ro -#: help:res.partner,nrc:0 -msgid "Registration number at the Registry of Commerce" -msgstr "" - -#~ msgid "" -#~ "Generate Chart of Accounts from a Chart Template. You will be asked to pass " -#~ "the name of the company, the chart template to follow, the no. of digits to " -#~ "generate the code for your accounts and Bank account, currency to create " -#~ "Journals. Thus,the pure copy of chart Template is generated.\n" -#~ "\tThis is the same wizard that runs from Financial " -#~ "Management/Configuration/Financial Accounting/Financial Accounts/Generate " -#~ "Chart of Accounts from a Chart Template." -#~ msgstr "" -#~ "Bir Tablo Şablonundan bir Hesap Tablosu oluşturun. Firma adını girmeniz, " -#~ "hesaplarınızın ve banka hesaplarınızın kodlarının oluşturulması için rakam " -#~ "sayısını, yevmiyeleri oluşturmak için para birimini girmeniz istenecektir. " -#~ "Böylece sade bir hesap planı oluşturumuş olur.\n" -#~ "\t Bu sihirbaz, Mali Yönetim/Yapılandırma/Mali Muhasebe/Mali Hesaplar/Tablo " -#~ "Şablonundan Hesap planı Oluşturma menüsünden çalıştırılan sihirbaz ile " -#~ "aynıdır." diff --git a/addons/l10n_ro/partner_view.xml b/addons/l10n_ro/partner_view.xml index b3549e5f5a8..c03d5c9a1a6 100644 --- a/addons/l10n_ro/partner_view.xml +++ b/addons/l10n_ro/partner_view.xml @@ -1,15 +1,16 @@ - - - res.partner.form.ro - - res.partner - - - + + + res.partner.form.ro + + res.partner + + + - - - + + + diff --git a/addons/l10n_ro/res_partner.py b/addons/l10n_ro/res_partner.py old mode 100644 new mode 100755 index 009aa76b62f..decdad124a2 --- a/addons/l10n_ro/res_partner.py +++ b/addons/l10n_ro/res_partner.py @@ -3,8 +3,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2009 (). All Rights Reserved -# $Id$ +# Copyright (C) 2012 (). 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 @@ -29,6 +28,10 @@ class res_partner(osv.osv): _columns = { 'nrc' : fields.char('NRC', size=16, help='Registration number at the Registry of Commerce'), } + _sql_constraints = [ + ('vat_uniq', 'unique (vat)', 'The vat of the partner must be unique !'), + ('nrc_uniq', 'unique (nrc)', 'The code of the partner must be unique !') + ] res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 807c949030d8b672e7a3da1ed2819d8886c92710 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Dec 2012 13:25:55 +0100 Subject: [PATCH 16/49] minor fixes bzr revid: al@openerp.com-20121216122555-frwadjd247zidw7o --- openerp/addons/base/ir/ir_attachment.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 0a4ec979103..644cec10bf0 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -99,9 +99,9 @@ class ir_attachment(osv.osv): _logger.error("_file_write writing %s",full_path) return fname - def _file_delete(self, cr, uid, location, fname, threshold=1): + def _file_delete(self, cr, uid, location, fname): count = self.search(cr, 1, [('store_fname','=',fname)], count=True) - if count <= threshold: + if count <= 1: full_path = self._full_path(cr, uid, location, fname) try: os.unlink(full_path) @@ -122,14 +122,13 @@ class ir_attachment(osv.osv): return result def _data_set(self, cr, uid, id, name, value, arg, context=None): + # We dont handle setting data to null if not value: return True if context is None: context = {} - result = {} location = self.pool.get('ir.config_parameter').get_param('ir_attachment.location') - bin_size = context.get('bin_size', False) - if path: + if location: i = self.browse(cr, uid, id, context=context) if i.store_fname: self._file_delete(cr, uid, location, i.store_fname) From 2569587c905bcdb01dd6f62b996e979626992851 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Dec 2012 18:38:56 +0100 Subject: [PATCH 17/49] Simplify openerp testing, deprecated redondant test declaration, we feed all tests.* modules to unittest2.TestLoader.loadTestsFromModule(module) bzr revid: al@openerp.com-20121216173856-euntlfi80uzutkp0 --- openerp/addons/base/__openerp__.py | 5 - openerp/addons/base/ir/ir_attachment.py | 10 +- openerp/addons/base/test/base_test.xml | 14 --- openerp/addons/base/test/test_ir_cron.py | 116 ------------------ openerp/addons/base/test/test_ir_cron.yml | 61 --------- openerp/addons/base/tests/__init__.py | 14 +-- .../addons/base/tests/test_ir_attachment.py | 16 +++ openerp/modules/module.py | 97 +++------------ openerp/tests/__init__.py | 36 ++---- 9 files changed, 58 insertions(+), 311 deletions(-) delete mode 100644 openerp/addons/base/test/base_test.xml delete mode 100644 openerp/addons/base/test/test_ir_cron.py delete mode 100644 openerp/addons/base/test/test_ir_cron.yml create mode 100644 openerp/addons/base/tests/test_ir_attachment.py diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index b4473434cdf..d400b28a729 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -93,16 +93,11 @@ The kernel of OpenERP, needed for all installation. 'res/res_partner_image_demo.xml', ], 'test': [ - 'test/base_test.xml', 'test/base_test.yml', 'test/test_context.xml', 'test/bug_lp541545.xml', 'test/test_osv_expression.yml', 'test/test_ir_rule.yml', # <-- These tests modify/add/delete ir_rules. - # Commented because this takes some time. - # This must be (un)commented with the corresponding import statement - # in test/__init__.py. - # 'test/test_ir_cron.yml', # <-- These tests perform a roolback. ], 'installable': True, 'auto_install': True, diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 644cec10bf0..4b9a721e7b5 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -112,13 +112,13 @@ class ir_attachment(osv.osv): if context is None: context = {} result = {} - location = self.pool.get('ir.config_parameter').get_param('ir_attachment.location') + location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location') bin_size = context.get('bin_size', False) - for i in self.browse(cr, uid, ids, context=context): - if location and i.store_fname: + for attach in self.browse(cr, uid, ids, context=context): + if location and attach.store_fname: result[i.id] = self._file_read(cr, uid, location, i.store_fname, bin_size) else: - result[i.id] = i.db_datas + result[i.id] = attach.db_datas return result def _data_set(self, cr, uid, id, name, value, arg, context=None): @@ -127,7 +127,7 @@ class ir_attachment(osv.osv): return True if context is None: context = {} - location = self.pool.get('ir.config_parameter').get_param('ir_attachment.location') + location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location') if location: i = self.browse(cr, uid, id, context=context) if i.store_fname: diff --git a/openerp/addons/base/test/base_test.xml b/openerp/addons/base/test/base_test.xml deleted file mode 100644 index 27bcabfc8f9..00000000000 --- a/openerp/addons/base/test/base_test.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - ASUSTeK - - - - \ No newline at end of file diff --git a/openerp/addons/base/test/test_ir_cron.py b/openerp/addons/base/test/test_ir_cron.py deleted file mode 100644 index 6ef79ac3a78..00000000000 --- a/openerp/addons/base/test/test_ir_cron.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2011-TODAY OpenERP S.A. -# -# 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 -from datetime import datetime -from dateutil.relativedelta import relativedelta - -import openerp - -JOB = { - 'function': u'_0_seconds', - 'interval_type': u'minutes', - 'user_id': 1, - 'name': u'test', - 'args': False, - 'numbercall': 1, - 'nextcall': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), - 'priority': 5, - 'doall': True, - 'active': True, - 'interval_number': 1, - 'model': u'ir.cron' -} - -class test_ir_cron(openerp.osv.osv.osv): - """ Add a few handy methods to test cron jobs scheduling. """ - _inherit = "ir.cron" - - def _0_seconds(a, b, c): - print ">>> _0_seconds" - - def _20_seconds(self, cr, uid): - print ">>> in _20_seconds" - time.sleep(20) - print ">>> out _20_seconds" - - def _80_seconds(self, cr, uid): - print ">>> in _80_seconds" - time.sleep(80) - print ">>> out _80_seconds" - - def test_0(self, cr, uid): - now = datetime.now() - t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') - t2 = (now + relativedelta(minutes=1, seconds=5)).strftime('%Y-%m-%d %H:%M:%S') - t3 = (now + relativedelta(minutes=1, seconds=10)).strftime('%Y-%m-%d %H:%M:%S') - self.create(cr, uid, dict(JOB, name='test_0 _20_seconds A', function='_20_seconds', nextcall=t1)) - self.create(cr, uid, dict(JOB, name='test_0 _20_seconds B', function='_20_seconds', nextcall=t2)) - self.create(cr, uid, dict(JOB, name='test_0 _20_seconds C', function='_20_seconds', nextcall=t3)) - - def test_1(self, cr, uid): - now = datetime.now() - t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') - self.create(cr, uid, dict(JOB, name='test_1 _20_seconds * 3', function='_20_seconds', nextcall=t1, numbercall=3)) - - def test_2(self, cr, uid): - now = datetime.now() - t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') - self.create(cr, uid, dict(JOB, name='test_2 _80_seconds * 2', function='_80_seconds', nextcall=t1, numbercall=2)) - - def test_3(self, cr, uid): - now = datetime.now() - t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') - t2 = (now + relativedelta(minutes=1, seconds=5)).strftime('%Y-%m-%d %H:%M:%S') - t3 = (now + relativedelta(minutes=1, seconds=10)).strftime('%Y-%m-%d %H:%M:%S') - self.create(cr, uid, dict(JOB, name='test_3 _80_seconds A', function='_80_seconds', nextcall=t1)) - self.create(cr, uid, dict(JOB, name='test_3 _20_seconds B', function='_20_seconds', nextcall=t2)) - self.create(cr, uid, dict(JOB, name='test_3 _20_seconds C', function='_20_seconds', nextcall=t3)) - - # This test assumes 4 cron threads. - def test_00(self, cr, uid): - self.test_00_set = set() - now = datetime.now() - t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') - t2 = (now + relativedelta(minutes=1, seconds=5)).strftime('%Y-%m-%d %H:%M:%S') - t3 = (now + relativedelta(minutes=1, seconds=10)).strftime('%Y-%m-%d %H:%M:%S') - self.create(cr, uid, dict(JOB, name='test_00 _20_seconds_A', function='_20_seconds_A', nextcall=t1)) - self.create(cr, uid, dict(JOB, name='test_00 _20_seconds_B', function='_20_seconds_B', nextcall=t2)) - self.create(cr, uid, dict(JOB, name='test_00 _20_seconds_C', function='_20_seconds_C', nextcall=t3)) - - def _expect(self, cr, uid, to_add, to_sleep, to_expect_in, to_expect_out): - assert self.test_00_set == to_expect_in - self.test_00_set.add(to_add) - time.sleep(to_sleep) - self.test_00_set.discard(to_add) - assert self.test_00_set == to_expect_out - - def _20_seconds_A(self, cr, uid): - self._expect(cr, uid, 'A', 20, set(), set(['B', 'C'])) - - def _20_seconds_B(self, cr, uid): - self._expect(cr, uid, 'B', 20, set('A'), set('C')) - - def _20_seconds_C(self, cr, uid): - self._expect(cr, uid, 'C', 20, set(['A', 'B']), set()) - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/addons/base/test/test_ir_cron.yml b/openerp/addons/base/test/test_ir_cron.yml deleted file mode 100644 index 16d648e1c30..00000000000 --- a/openerp/addons/base/test/test_ir_cron.yml +++ /dev/null @@ -1,61 +0,0 @@ -- - Test the cron jobs scheduling. -- - Disable the existing cron jobs if any during the tests. -- - !python {model: ir.cron }: | - # For this test to work, as it involves multiple database cursors, - # we have to commit changes. But YAML tests must be rollbacked, so - # the final database state is left untouched. So we have to be a bit - # ugly here: use our own cursor, commit, and clean after ourselves. - # We also pass around some ids using setattr/delattr, and we have to - # rollback the previous tests otherwise we won't be able to touch the - # db. - # Well, this should probably be a standalone, or regular unit test, - # instead of using the YAML infrastructure. - cr.rollback() - our_cr = self.pool.db.cursor() - try: - ids = self.search(our_cr, uid, [], {}) - setattr(self, 'saved_ids', ids) - self.write(our_cr, uid, ids, {'active': False}, {}) - our_cr.commit() - finally: - our_cr.close() -- - Three concurrent jobs started with a slight time gap. Assume 4 cron threads. - This will take about 2 minutes. -- - !python {model: ir.cron }: | - # Pretend initialization is already done. We the use a try/finally - # to reset _init correctly. - self.pool._init = False - our_cr = self.pool.db.cursor() - try: - self.test_00(our_cr, uid) # this will commit using the passed cursor - import openerp.cron - openerp.cron._thread_slots = 4 - # Wake up this db as soon as the master cron thread starts. - openerp.cron.schedule_wakeup(1, self.pool.db.dbname) - # Pretend to be the master thread, for 4 iterations. - openerp.cron.runner_body() - openerp.cron.runner_body() - openerp.cron.runner_body() - openerp.cron.runner_body() - finally: - self.pool._init = True - our_cr.close() -- - Clean after ourselves. -- - !python {model: ir.cron }: | - our_cr = self.pool.db.cursor() - try: - ids = [x for x in self.search(our_cr, uid, ['|', ('active', '=', True), ('active', '=', False)], {}) if x not in self.saved_ids] - self.unlink(our_cr, uid, ids, {}) - ids = self.saved_ids - delattr(self, 'saved_ids') - self.write(our_cr, uid, ids, {'active': True}, {}) - our_cr.commit() - finally: - our_cr.close() diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py index 70f9a932d01..1d60f1a60a8 100644 --- a/openerp/addons/base/tests/__init__.py +++ b/openerp/addons/base/tests/__init__.py @@ -1,9 +1,7 @@ -import test_base, test_expression, test_search, test_ir_values, test_menu +#import test_base +#import test_expression +import test_ir_attachment +#import test_ir_values +#import test_menu +#import test_search -checks = [ - test_base, - test_expression, - test_search, - test_ir_values, - test_menu, -] diff --git a/openerp/addons/base/tests/test_ir_attachment.py b/openerp/addons/base/tests/test_ir_attachment.py new file mode 100644 index 00000000000..fa04a4f967c --- /dev/null +++ b/openerp/addons/base/tests/test_ir_attachment.py @@ -0,0 +1,16 @@ +import unittest2 + +import openerp.tests.common as common + +class test_ir_attachment(common.TransactionCase): + + def test_00_attachment_flow(self): + + registry, cr, uid = self.registry, self.cr, self.uid + + ira = registry('ir.attachment') + d = ira.create(cr, uid, {'name': 'a1', 'datas':'blob1'}) + + #name_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%')], order="name asc") + #self.assertEqual([a, ab, b, c], name_asc, "Search with 'NAME ASC' order failed.") + diff --git a/openerp/modules/module.py b/openerp/modules/module.py index bb4ff481fb9..aefab86796e 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -456,15 +456,9 @@ def get_modules_with_version(): continue return res -def get_test_modules(module, submodule, explode): - """ - Return a list of submodules containing tests. - `submodule` can be: - - None - - the name of a submodule - - '__fast_suite__' - - '__sanity_checks__' - """ +def get_test_modules(module): + """ Return a list of module for the addons potentialy containing tests to + feed unittest2.TestLoader.loadTestsFromModule() """ # Turn command-line module, submodule into importable names. if module is None: pass @@ -472,74 +466,21 @@ def get_test_modules(module, submodule, explode): module = 'openerp.tests' else: module = 'openerp.addons.' + module + '.tests' - # Try to import the module try: __import__(module) except Exception, e: - if explode: - print 'Can not `import %s`.' % module - import logging - logging.exception('') - sys.exit(1) - else: - if str(e) == 'No module named tests': - # It seems the module has no `tests` sub-module, no problem. - pass - else: - _logger.exception('Can not `import %s`.', module) - return [] + # If module has no `tests` sub-module, no problem. + if str(e) != 'No module named tests': + _logger.exception('Can not `import %s`.', module) + return [] - # Discover available test sub-modules. - m = sys.modules[module] - submodule_names = sorted([x for x in dir(m) \ - if x.startswith('test_') and \ - isinstance(getattr(m, x), types.ModuleType)]) - submodules = [getattr(m, x) for x in submodule_names] - - def show_submodules_and_exit(): - if submodule_names: - print 'Available submodules are:' - for x in submodule_names: - print ' ', x - sys.exit(1) - - if submodule is None: - # Use auto-discovered sub-modules. - ms = submodules - elif submodule == '__fast_suite__': - # Obtain the explicit test sub-modules list. - ms = getattr(sys.modules[module], 'fast_suite', None) - # `suite` was used before the 6.1 release instead of `fast_suite`. - ms = ms if ms else getattr(sys.modules[module], 'suite', None) - if ms is None: - if explode: - print 'The module `%s` has no defined test suite.' % (module,) - show_submodules_and_exit() - else: - ms = [] - elif submodule == '__sanity_checks__': - ms = getattr(sys.modules[module], 'checks', None) - if ms is None: - if explode: - print 'The module `%s` has no defined sanity checks.' % (module,) - show_submodules_and_exit() - else: - ms = [] - else: - # Pick the command-line-specified test sub-module. - m = getattr(sys.modules[module], submodule, None) - ms = [m] - - if m is None: - if explode: - print 'The module `%s` has no submodule named `%s`.' % \ - (module, submodule) - show_submodules_and_exit() - else: - ms = [] - - return ms + # include submodules too + result = [] + for name in sys.modules: + if name.startswith(module): + result.append(sys.modules[name]) + return result def run_unit_tests(module_name): """ @@ -547,14 +488,9 @@ def run_unit_tests(module_name): Return None if no test was found. """ import unittest2 - ms = get_test_modules(module_name, '__fast_suite__', explode=False) - # TODO: No need to try again if the above call failed because of e.g. a syntax error. - ms.extend(get_test_modules(module_name, '__sanity_checks__', explode=False)) - suite = unittest2.TestSuite() - for m in ms: - suite.addTests(unittest2.TestLoader().loadTestsFromModule(m)) + ms = get_test_modules(module_name) if ms: - _logger.log(logging.TEST, 'module %s: executing %s `fast_suite` and/or `checks` sub-modules', module_name, len(ms)) + _logger.log(logging.TEST, 'module %s: running test.', module_name) # Use a custom stream object to log the test executions. class MyStream(object): def __init__(self): @@ -570,6 +506,9 @@ def run_unit_tests(module_name): c = '` ' + c first = False _logger.log(logging.TEST, c) + suite = unittest2.TestSuite() + for m in ms: + suite.addTests(unittest2.TestLoader().loadTestsFromModule(m)) result = unittest2.TextTestRunner(verbosity=2, stream=MyStream()).run(suite) if result.wasSuccessful(): return True diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index 92a40ab306c..38569464bbe 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -8,28 +8,18 @@ Tests can be explicitely added to the `fast_suite` or `checks` lists or not. See the :ref:`test-framework` section in the :ref:`features` list. """ -from . import test_expression, test_mail, test_ir_sequence, test_orm, \ - test_fields, test_basecase, \ - test_view_validation, test_uninstall, test_misc, test_db_cursor, \ - test_osv, test_translate -from . import test_ir_filters - -fast_suite = [ - test_ir_sequence, - test_ir_filters -] - -checks = [ - test_expression, - test_mail, - test_db_cursor, - test_orm, - test_fields, - test_basecase, - test_view_validation, - test_misc, - test_osv, - test_translate, -] +#import test_basecase +#import test_db_cursor +#import test_expression +#import test_fields +#import test_ir_filters +#import test_ir_sequence +#import test_mail +#import test_misc +#import test_orm +#import test_osv +#import test_translate +#import test_uninstall +#import test_view_validation # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 70aa2c995a53208a9e4aabf85f0c9ee210c61506 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Dec 2012 20:03:17 +0100 Subject: [PATCH 18/49] filestore testcase and fix bugs bzr revid: al@openerp.com-20121216190317-xoz0jij2cfk0c2zk --- openerp/addons/base/ir/ir_attachment.py | 23 +++-- openerp/addons/base/tests/__init__.py | 10 +-- .../addons/base/tests/test_ir_attachment.py | 87 +++++++++++++++++-- openerp/tests/__init__.py | 26 +++--- 4 files changed, 114 insertions(+), 32 deletions(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 4b9a721e7b5..f9502b7a288 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -19,7 +19,10 @@ # ############################################################################## +import hashlib import itertools +import os +import re from osv import fields,osv from osv.orm import except_orm @@ -65,7 +68,7 @@ class ir_attachment(osv.osv): # sanitize location name and path location = re.sub('[.]','',location) - location = path.strip('/\\') + location = location.strip('/\\') path = re.sub('[.]','',path) path = path.strip('/\\') @@ -106,6 +109,7 @@ class ir_attachment(osv.osv): try: os.unlink(full_path) except IOError: + # Harmless and needed for race conditions _logger.error("_file_delete could not unlink %s",full_path) def _data_get(self, cr, uid, ids, name, arg, context=None): @@ -113,12 +117,12 @@ class ir_attachment(osv.osv): context = {} result = {} location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location') - bin_size = context.get('bin_size', False) + bin_size = context.get('bin_size') for attach in self.browse(cr, uid, ids, context=context): if location and attach.store_fname: - result[i.id] = self._file_read(cr, uid, location, i.store_fname, bin_size) + result[attach.id] = self._file_read(cr, uid, location, attach.store_fname, bin_size) else: - result[i.id] = attach.db_datas + result[attach.id] = attach.db_datas return result def _data_set(self, cr, uid, id, name, value, arg, context=None): @@ -129,9 +133,9 @@ class ir_attachment(osv.osv): context = {} location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location') if location: - i = self.browse(cr, uid, id, context=context) - if i.store_fname: - self._file_delete(cr, uid, location, i.store_fname) + attach = self.browse(cr, uid, id, context=context) + if attach.store_fname: + self._file_delete(cr, uid, location, attach.store_fname) fname = self._file_write(cr, uid, location, value) self.write(cr, uid, [id], {'store_fname': fname}, context=context) else: @@ -263,6 +267,11 @@ class ir_attachment(osv.osv): def unlink(self, cr, uid, ids, context=None): self.check(cr, uid, ids, 'unlink', context=context) + location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location') + if location: + for attach in self.browse(cr, uid, ids, context=context): + if attach.store_fname: + self._file_delete(cr, uid, location, attach.store_fname) return super(ir_attachment, self).unlink(cr, uid, ids, context) def create(self, cr, uid, values, context=None): diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py index 1d60f1a60a8..4a586a8a971 100644 --- a/openerp/addons/base/tests/__init__.py +++ b/openerp/addons/base/tests/__init__.py @@ -1,7 +1,7 @@ -#import test_base -#import test_expression +import test_base +import test_expression import test_ir_attachment -#import test_ir_values -#import test_menu -#import test_search +import test_ir_values +import test_menu +import test_search diff --git a/openerp/addons/base/tests/test_ir_attachment.py b/openerp/addons/base/tests/test_ir_attachment.py index fa04a4f967c..4d96ec42b28 100644 --- a/openerp/addons/base/tests/test_ir_attachment.py +++ b/openerp/addons/base/tests/test_ir_attachment.py @@ -1,16 +1,89 @@ +import hashlib +import os + import unittest2 -import openerp.tests.common as common +import openerp +import openerp.tests.common -class test_ir_attachment(common.TransactionCase): +class test_ir_attachment(openerp.tests.common.TransactionCase): def test_00_attachment_flow(self): - registry, cr, uid = self.registry, self.cr, self.uid - + root_path = openerp.tools.config['root_path'] ira = registry('ir.attachment') - d = ira.create(cr, uid, {'name': 'a1', 'datas':'blob1'}) - #name_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%')], order="name asc") - #self.assertEqual([a, ab, b, c], name_asc, "Search with 'NAME ASC' order failed.") + # Blob1 + blob1 = 'blob1' + blob1_b64 = blob1.encode('base64') + blob1_hash = hashlib.sha1(blob1).hexdigest() + blob1_fname = blob1_hash[:3] + '/' + blob1_hash + + # Blob2 + blob2 = 'blob2' + blob2_b64 = blob2.encode('base64') + blob2_hash = hashlib.sha1(blob2).hexdigest() + blob2_fname = blob2_hash[:3] + '/' + blob2_hash + + # 'ir_attachment.location' is undefined test database storage + a1 = ira.create(cr, uid, {'name': 'a1', 'datas': blob1_b64}) + a1_read = ira.read(cr, uid, [a1], ['datas']) + self.assertEqual(a1_read[0]['datas'], blob1_b64) + + cr.execute("select id,db_datas from ir_attachment where id = %s", (a1,) ) + a1_db_datas = str(cr.fetchall()[0][1]) + self.assertEqual(a1_db_datas, blob1_b64) + + # define a location for filestore + registry('ir.config_parameter').set_param(cr, uid, 'ir_attachment.location', 'file:///filestore') + + # Test file storage + a2 = ira.create(cr, uid, {'name': 'a2', 'datas': blob1_b64}) + a2_read = ira.read(cr, uid, [a2], ['datas']) + self.assertEqual(a2_read[0]['datas'], blob1_b64) + + cr.execute("select id,store_fname from ir_attachment where id = %s", (a2,) ) + a2_store_fname = cr.fetchall()[0][1] + self.assertEqual(a2_store_fname, blob1_fname) + + a2_fn = os.path.join(root_path, 'filestore', cr.dbname, blob1_hash[:3], blob1_hash) + fc = file(a2_fn).read() + self.assertEqual(fc, blob1) + + # create a3 with same blob + a3 = ira.create(cr, uid, {'name': 'a3', 'datas': blob1_b64}) + a3_read = ira.read(cr, uid, [a3], ['datas']) + self.assertEqual(a3_read[0]['datas'], blob1_b64) + + cr.execute("select id,store_fname from ir_attachment where id = %s", (a3,) ) + a3_store_fname = cr.fetchall()[0][1] + self.assertEqual(a3_store_fname, a2_store_fname) + + # create a4 blob2 + a4 = ira.create(cr, uid, {'name': 'a4', 'datas': blob2_b64}) + a4_read = ira.read(cr, uid, [a4], ['datas']) + self.assertEqual(a4_read[0]['datas'], blob2_b64) + + a4_fn = os.path.join(root_path, 'filestore', cr.dbname, blob2_hash[:3], blob2_hash) + self.assertTrue(os.path.isfile(a4_fn)) + + # delete a3 but file stays + ira.unlink(cr, uid, [a3]) + self.assertTrue(os.path.isfile(a2_fn)) + + # delete a2 it is unlinked + ira.unlink(cr, uid, [a2]) + self.assertFalse(os.path.isfile(a2_fn)) + + # update a4 blob2 by blob1 + ira.write(cr, uid, [a4], {'datas': blob1_b64}) + a4_read = ira.read(cr, uid, [a4], ['datas']) + self.assertEqual(a4_read[0]['datas'], blob1_b64) + + # file of a4 disapear and a2 reappear + self.assertFalse(os.path.isfile(a4_fn)) + self.assertTrue(os.path.isfile(a2_fn)) + + # everybody applause + diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index 38569464bbe..327b8715125 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -8,18 +8,18 @@ Tests can be explicitely added to the `fast_suite` or `checks` lists or not. See the :ref:`test-framework` section in the :ref:`features` list. """ -#import test_basecase -#import test_db_cursor -#import test_expression -#import test_fields -#import test_ir_filters -#import test_ir_sequence -#import test_mail -#import test_misc -#import test_orm -#import test_osv -#import test_translate -#import test_uninstall -#import test_view_validation +import test_basecase +import test_db_cursor +import test_expression +import test_fields +import test_ir_filters +import test_ir_sequence +import test_mail +import test_misc +import test_orm +import test_osv +import test_translate +import test_uninstall +import test_view_validation # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 9568552636d866b2c558cfc800e9ede902482001 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Dec 2012 20:39:32 +0100 Subject: [PATCH 19/49] revert test change will be moved to an other branch bzr revid: al@openerp.com-20121216193932-foluon7b5bqqvrib --- openerp/addons/base/tests/__init__.py | 8 +++ openerp/modules/module.py | 97 ++++++++++++++++++++++----- openerp/tests/__init__.py | 18 +++++ 3 files changed, 105 insertions(+), 18 deletions(-) diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py index 4a586a8a971..d891bc06fda 100644 --- a/openerp/addons/base/tests/__init__.py +++ b/openerp/addons/base/tests/__init__.py @@ -5,3 +5,11 @@ import test_ir_values import test_menu import test_search +checks = [ + test_base, + test_expression, + test_ir_attachment, + test_ir_values, + test_menu, + test_search, +] diff --git a/openerp/modules/module.py b/openerp/modules/module.py index aefab86796e..bb4ff481fb9 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -456,9 +456,15 @@ def get_modules_with_version(): continue return res -def get_test_modules(module): - """ Return a list of module for the addons potentialy containing tests to - feed unittest2.TestLoader.loadTestsFromModule() """ +def get_test_modules(module, submodule, explode): + """ + Return a list of submodules containing tests. + `submodule` can be: + - None + - the name of a submodule + - '__fast_suite__' + - '__sanity_checks__' + """ # Turn command-line module, submodule into importable names. if module is None: pass @@ -466,21 +472,74 @@ def get_test_modules(module): module = 'openerp.tests' else: module = 'openerp.addons.' + module + '.tests' + # Try to import the module try: __import__(module) except Exception, e: - # If module has no `tests` sub-module, no problem. - if str(e) != 'No module named tests': - _logger.exception('Can not `import %s`.', module) - return [] + if explode: + print 'Can not `import %s`.' % module + import logging + logging.exception('') + sys.exit(1) + else: + if str(e) == 'No module named tests': + # It seems the module has no `tests` sub-module, no problem. + pass + else: + _logger.exception('Can not `import %s`.', module) + return [] - # include submodules too - result = [] - for name in sys.modules: - if name.startswith(module): - result.append(sys.modules[name]) - return result + # Discover available test sub-modules. + m = sys.modules[module] + submodule_names = sorted([x for x in dir(m) \ + if x.startswith('test_') and \ + isinstance(getattr(m, x), types.ModuleType)]) + submodules = [getattr(m, x) for x in submodule_names] + + def show_submodules_and_exit(): + if submodule_names: + print 'Available submodules are:' + for x in submodule_names: + print ' ', x + sys.exit(1) + + if submodule is None: + # Use auto-discovered sub-modules. + ms = submodules + elif submodule == '__fast_suite__': + # Obtain the explicit test sub-modules list. + ms = getattr(sys.modules[module], 'fast_suite', None) + # `suite` was used before the 6.1 release instead of `fast_suite`. + ms = ms if ms else getattr(sys.modules[module], 'suite', None) + if ms is None: + if explode: + print 'The module `%s` has no defined test suite.' % (module,) + show_submodules_and_exit() + else: + ms = [] + elif submodule == '__sanity_checks__': + ms = getattr(sys.modules[module], 'checks', None) + if ms is None: + if explode: + print 'The module `%s` has no defined sanity checks.' % (module,) + show_submodules_and_exit() + else: + ms = [] + else: + # Pick the command-line-specified test sub-module. + m = getattr(sys.modules[module], submodule, None) + ms = [m] + + if m is None: + if explode: + print 'The module `%s` has no submodule named `%s`.' % \ + (module, submodule) + show_submodules_and_exit() + else: + ms = [] + + return ms def run_unit_tests(module_name): """ @@ -488,9 +547,14 @@ def run_unit_tests(module_name): Return None if no test was found. """ import unittest2 - ms = get_test_modules(module_name) + ms = get_test_modules(module_name, '__fast_suite__', explode=False) + # TODO: No need to try again if the above call failed because of e.g. a syntax error. + ms.extend(get_test_modules(module_name, '__sanity_checks__', explode=False)) + suite = unittest2.TestSuite() + for m in ms: + suite.addTests(unittest2.TestLoader().loadTestsFromModule(m)) if ms: - _logger.log(logging.TEST, 'module %s: running test.', module_name) + _logger.log(logging.TEST, 'module %s: executing %s `fast_suite` and/or `checks` sub-modules', module_name, len(ms)) # Use a custom stream object to log the test executions. class MyStream(object): def __init__(self): @@ -506,9 +570,6 @@ def run_unit_tests(module_name): c = '` ' + c first = False _logger.log(logging.TEST, c) - suite = unittest2.TestSuite() - for m in ms: - suite.addTests(unittest2.TestLoader().loadTestsFromModule(m)) result = unittest2.TextTestRunner(verbosity=2, stream=MyStream()).run(suite) if result.wasSuccessful(): return True diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index 327b8715125..07232bff5dc 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -22,4 +22,22 @@ import test_translate import test_uninstall import test_view_validation +fast_suite = [ + test_ir_sequence, + test_ir_filters +] + +checks = [ + test_expression, + test_mail, + test_db_cursor, + test_orm, + test_fields, + test_basecase, + test_view_validation, + test_misc, + test_osv, + test_translate, +] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 893f34555fe084b42c9f4223263f84fb6f85640d Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Dec 2012 21:47:37 +0100 Subject: [PATCH 20/49] remove more cruft bzr revid: al@openerp.com-20121216204737-4mfsbp0v6s0g799j --- addons/document/__openerp__.py | 2 +- addons/document/document.py | 87 +--------------------------------- 2 files changed, 2 insertions(+), 87 deletions(-) diff --git a/addons/document/__openerp__.py b/addons/document/__openerp__.py index e3354efff0c..7e46ece47b5 100644 --- a/addons/document/__openerp__.py +++ b/addons/document/__openerp__.py @@ -55,7 +55,7 @@ ATTENTION: 'report/document_report_view.xml', 'board_document_view.xml', ], - 'demo': [ 'document_demo.xml','board_document_demo.xml'], + 'demo': [ 'document_demo.xml' ], 'test': ['test/document_test2.yml'], 'js': ['static/src/js/document.js'], 'installable': True, diff --git a/addons/document/document.py b/addons/document/document.py index 37a0219d143..aeb5f97754a 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -62,9 +62,7 @@ class document_file(osv.osv): if ids is not None: raise NotImplementedError("Ids are just there by convention, please do not use it.") - cr.execute("UPDATE ir_attachment " \ - "SET parent_id = %s, db_datas = decode(encode(db_datas,'escape'), 'base64') " \ - "WHERE parent_id IS NULL", (parent_id,)) + cr.execute("UPDATE ir_attachment SET parent_id = %s WHERE parent_id IS NULL", (parent_id,)) cr.execute("UPDATE ir_attachment SET file_size=length(db_datas) WHERE file_size = 0 and type = 'binary'") @@ -72,67 +70,17 @@ class document_file(osv.osv): return True - def _get_filestore(self, cr): - return os.path.join(DMS_ROOT_PATH, cr.dbname) - - def _data_get(self, cr, uid, ids, name, arg, context=None): - if context is None: - context = {} - fbrl = self.browse(cr, uid, ids, context=context) - nctx = nodes.get_node_context(cr, uid, context={}) - # nctx will /not/ inherit the caller's context. Most of - # it would be useless, anyway (like active_id, active_model, - # bin_size etc.) - result = {} - 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, arg, context=None): - if not value: - return True - 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 = { # Columns from ir.attachment: - 'create_date': fields.datetime('Date Created', readonly=True), - 'create_uid': fields.many2one('res.users', 'Creator', readonly=True), 'write_date': fields.datetime('Date Modified', readonly=True), 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True), - 'res_model': fields.char('Attached Model', size=64, readonly=True, change_default=True), - 'res_id': fields.integer('Attached ID', readonly=True), - - # 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'), - 'datas': fields.function(_data_get, fnct_inv=_data_set, string='File Content', type="binary", nodrop=True), - # Fields of document: 'user_id': fields.many2one('res.users', 'Owner', select=1), - # 'group_ids': fields.many2many('res.groups', 'document_group_rel', 'item_id', 'group_id', 'Groups'), - # the directory id now is mandatory. It can still be computed automatically. 'parent_id': fields.many2one('document.directory', 'Directory', select=1, required=True, change_default=True), 'index_content': fields.text('Indexed Content'), 'partner_id':fields.many2one('res.partner', 'Partner', select=1), 'file_size': fields.integer('File Size', required=True), 'file_type': fields.char('Content Type', size=128), - - # fields used for file storage - 'store_fname': fields.char('Stored Filename', size=200), } _order = "id desc" @@ -185,7 +133,6 @@ class document_file(osv.osv): ids.remove(doc_id) return len(ids) if count else ids - def copy(self, cr, uid, id, default=None, context=None): if not default: default = {} @@ -282,36 +229,4 @@ class document_file(osv.osv): return bro.partner_id.id return False - def unlink(self, cr, uid, ids, context=None): - 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 - ids = self.search(cr, uid, [('id','in',ids)]) - for f in self.browse(cr, uid, ids, context=context): - # TODO: update the node cache - par = f.parent_id - storage_id = None - while par: - if par.storage_id: - storage_id = par.storage_id - break - par = par.parent_id - #assert storage_id, "Strange, found file #%s w/o storage!" % f.id #TOCHECK: after run yml, it's fail - if storage_id: - r = stor.prepare_unlink(cr, uid, storage_id, f) - if r: - unres.append(r) - else: - self.loggerdoc.warning("Unlinking attachment #%s %s that has no storage.", - f.id, f.name) - res = super(document_file, self).unlink(cr, uid, ids, context) - stor.do_unlink(cr, uid, unres) - return res - -document_file() - - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 0adc138bdc95de0f5d1e6e41d7ce5281fe5c1f33 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Dec 2012 23:50:00 +0100 Subject: [PATCH 21/49] remove more cruft, really ugly storage engine code bzr revid: al@openerp.com-20121216225000-44oitkilkkx8u29u --- addons/document/__openerp__.py | 8 - addons/document/board_document_view.xml | 41 -- addons/document/document_storage.py | 540 +----------------------- addons/document/nodes.py | 1 - 4 files changed, 16 insertions(+), 574 deletions(-) delete mode 100644 addons/document/board_document_view.xml diff --git a/addons/document/__openerp__.py b/addons/document/__openerp__.py index 7e46ece47b5..3e75c7d15e3 100644 --- a/addons/document/__openerp__.py +++ b/addons/document/__openerp__.py @@ -27,7 +27,6 @@ 'description': """ This is a complete document management system. ============================================== - * User Authentication * Document Indexation:- .pptx and .docx files are not supported in Windows platform. * Dashboard for Document that includes: @@ -35,13 +34,6 @@ This is a complete document management system. * Files by Resource Type (graph) * Files by Partner (graph) * Files Size by Month (graph) - -ATTENTION: ----------- - - When you install this module in a running company that have already PDF - files stored into the database, you will lose them all. - - After installing this module PDF's are no longer stored into the database, - but in the servers rootpad like /server/bin/filestore. """, 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', diff --git a/addons/document/board_document_view.xml b/addons/document/board_document_view.xml deleted file mode 100644 index 986b054383f..00000000000 --- a/addons/document/board_document_view.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - board.document.manager.form - board.board - -
- - - - - - - - -
-
-
- - - - Knowledge - board.board - form - form - - - - - -
-
diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py index a4b37b126b2..9ad70497b2b 100644 --- a/addons/document/document_storage.py +++ b/addons/document/document_storage.py @@ -38,8 +38,6 @@ import pooler import nodes from content_index import cntIndex _logger = logging.getLogger(__name__) -DMS_ROOT_PATH = tools.config.get('document_path', os.path.join(tools.config.get('root_path'), 'filestore')) - """ The algorithm of data storage @@ -68,103 +66,8 @@ 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 nodefd_file(nodes.node_descriptor): - """ A descriptor to a real file - - Inheriting directly from file doesn't work, since file exports - some read-only attributes (like 'name') that we don't like. - """ - def __init__(self, parent, path, mode): - nodes.node_descriptor.__init__(self, parent) - self.__file = open(path, mode) - if mode.endswith('b'): - mode = mode[:-1] - self.mode = mode - self._size = os.stat(path).st_size - - for attr in ('closed', 'read', 'write', 'seek', 'tell', 'next'): - setattr(self,attr, getattr(self.__file, attr)) - - def size(self): - return self._size - - def __iter__(self): - return self - - def close(self): - # TODO: locking in init, close() - fname = self.__file.name - self.__file.close() - - if self.mode in ('w', 'w+', 'r+'): - par = self._get_parent() - cr = pooler.get_db(par.context.dbname).cursor() - icont = '' - mime = '' - filename = par.path - if isinstance(filename, (tuple, list)): - filename = '/'.join(filename) - - try: - mime, icont = cntIndex.doIndex(None, filename=filename, - content_type=None, realfname=fname) - except Exception: - _logger.debug('Cannot index file:', exc_info=True) - pass - - try: - icont_u = ustr(icont) - except UnicodeError: - icont_u = '' - - try: - fsize = os.stat(fname).st_size - cr.execute("UPDATE ir_attachment " \ - " SET index_content = %s, file_type = %s, " \ - " file_size = %s " \ - " WHERE id = %s", - (icont_u, mime, fsize, par.file_id)) - par.content_length = fsize - par.content_type = mime - cr.commit() - cr.close() - except Exception: - _logger.warning('Cannot save file indexed content:', exc_info=True) - - elif self.mode in ('a', 'a+' ): - try: - par = self._get_parent() - cr = pooler.get_db(par.context.dbname).cursor() - fsize = os.stat(fname).st_size - cr.execute("UPDATE ir_attachment SET file_size = %s " \ - " WHERE id = %s", - (fsize, par.file_id)) - par.content_length = fsize - cr.commit() - cr.close() - except Exception: - _logger.warning('Cannot save file appended content:', exc_info=True) - - - class nodefd_db(StringIO, nodes.node_descriptor): """ A descriptor to db data """ @@ -175,9 +78,7 @@ class nodefd_db(StringIO, nodes.node_descriptor): mode = mode[:-1] if mode in ('r', 'r+'): - cr = ira_browse._cr # reuse the cursor of the browse object, just now - cr.execute('SELECT db_datas FROM ir_attachment WHERE id = %s',(ira_browse.id,)) - data = cr.fetchone()[0] + data = ira_browse.datas if data: self._size = len(data) StringIO.__init__(self, data) @@ -244,85 +145,6 @@ class nodefd_db(StringIO, nodes.node_descriptor): cr.close() StringIO.close(self) -class nodefd_db64(StringIO, nodes.node_descriptor): - """ A descriptor to db data, base64 (the old way) - - It stores the data in base64 encoding at the db. Not optimal, but - the transparent compression of Postgres will save the day. - """ - def __init__(self, parent, ira_browse, mode): - nodes.node_descriptor.__init__(self, parent) - self._size = 0L - if mode.endswith('b'): - mode = mode[:-1] - - if mode in ('r', 'r+'): - data = base64.decodestring(ira_browse.db_datas) - if data: - self._size = len(data) - StringIO.__init__(self, data) - elif mode in ('w', 'w+'): - StringIO.__init__(self, None) - # at write, we start at 0 (= overwrite), but have the original - # data available, in case of a seek() - elif mode == 'a': - StringIO.__init__(self, None) - else: - _logger.error("Incorrect mode %s is specified.", mode) - raise IOError(errno.EINVAL, "Invalid file mode.") - self.mode = mode - - def size(self): - return self._size - - def close(self): - # we now open a *separate* cursor, to update the data. - # FIXME: this may be improved, for concurrency handling - par = self._get_parent() - # uid = par.context.uid - cr = pooler.get_db(par.context.dbname).cursor() - try: - if self.mode in ('w', 'w+', 'r+'): - data = self.getvalue() - icont = '' - mime = '' - filename = par.path - if isinstance(filename, (tuple, list)): - filename = '/'.join(filename) - - try: - mime, icont = cntIndex.doIndex(data, filename=filename, - content_type=None, realfname=None) - except Exception: - self.logger.debug('Cannot index file:', exc_info=True) - pass - - try: - icont_u = ustr(icont) - except UnicodeError: - icont_u = '' - - cr.execute('UPDATE ir_attachment SET db_datas = %s::bytea, file_size=%s, ' \ - 'index_content = %s, file_type = %s ' \ - 'WHERE id = %s', - (base64.encodestring(data), len(data), icont_u, mime, par.file_id)) - elif self.mode == 'a': - data = self.getvalue() - # Yes, we're obviously using the wrong representation for storing our - # data as base64-in-bytea - cr.execute("UPDATE ir_attachment " \ - "SET db_datas = encode( (COALESCE(decode(encode(db_datas,'escape'),'base64'),'') || decode(%s, 'base64')),'base64')::bytea , " \ - " file_size = COALESCE(file_size, 0) + %s " \ - " WHERE id = %s", - (base64.encodestring(data), len(data), par.file_id)) - cr.commit() - except Exception: - _logger.exception('Cannot update db file #%d for close.', par.file_id) - raise - finally: - cr.close() - StringIO.close(self) - class document_storage(osv.osv): """ The primary object for data storage. Each instance of this object is a storage media, in which our application @@ -346,72 +168,12 @@ class document_storage(osv.osv): 'user_id': fields.many2one('res.users', 'Owner'), 'group_ids': fields.many2many('res.groups', 'document_storage_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'),], '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"), 'readonly': fields.boolean('Read Only', help="If set, media is for reading only"), } - def _get_rootpath(self, cr, uid, context=None): - return os.path.join(DMS_ROOT_PATH, 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_random_fname(self, path): - flag = None - # 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() - return os.path.join(flag, filename) - - def __prepare_realpath(self, cr, file_node, ira, store_path, do_create=True): - """ Cleanup path for realstore, create dirs if needed - - @param file_node the node - @param ira ir.attachment browse of the file_node - @param store_path the path of the parent storage object, list - @param do_create create the directories, if needed - - @return tuple(path "/var/filestore/real/dir/", npath ['dir','fname.ext'] ) - """ - file_node.fix_ppath(cr, ira) - npath = file_node.full_path() or [] - # npath may contain empty elements, for root directory etc. - npath = filter(lambda x: x is not None, npath) - - # if self._debug: - # self._logger.debug('Npath: %s', npath) - for n in npath: - if n == '..': - raise ValueError("Invalid '..' element in path.") - for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?',): - if ch in n: - raise ValueError("Invalid char %s in path %s." %(ch, n)) - dpath = [store_path,] - dpath += npath[:-1] - path = os.path.join(*dpath) - if not os.path.isdir(path): - _logger.debug("Create dirs: %s", path) - os.makedirs(path) - return path, npath 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 @@ -419,14 +181,16 @@ class document_storage(osv.osv): (ir.attachment) """ boo = self.browse(cr, uid, id, context=context) - if not boo.online: - raise IOError(errno.EREMOTE, 'Medium offline.') - 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) + data = ira.datas + if data: + out = data.decode('base64') + else: + out = '' + return out def get_file(self, cr, uid, id, file_node, mode, context=None): """ Return a file-like object for the contents of some node @@ -434,100 +198,9 @@ class document_storage(osv.osv): if context is None: context = {} boo = self.browse(cr, uid, id, context=context) - if not boo.online: - raise IOError(errno.EREMOTE, 'Medium offline.') - - if boo.readonly and mode not in ('r', 'rb'): - raise IOError(errno.EPERM, "Readonly medium.") ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - 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 mode in ('r','r+'): - if ira.file_size: - _logger.warning( "ir.attachment #%d does not have a filename, but is at filestore. This should get fixed." % ira.id) - raise IOError(errno.ENOENT, 'No file can be located.') - else: - store_fname = self.__get_random_fname(boo.path) - cr.execute('UPDATE ir_attachment SET store_fname = %s WHERE id = %s', - (store_fname, ira.id)) - fpath = os.path.join(boo.path, store_fname) - else: - fpath = os.path.join(boo.path, ira.store_fname) - return nodefd_file(file_node, path=fpath, mode=mode) - - elif boo.type == 'db': - # TODO: we need a better api for large files - return nodefd_db(file_node, ira_browse=ira, mode=mode) - - elif boo.type == 'db64': - return nodefd_db64(file_node, ira_browse=ira, mode=mode) - - elif boo.type == 'realstore': - path, npath = self.__prepare_realpath(cr, file_node, ira, boo.path, - do_create = (mode[0] in ('w','a')) ) - fpath = os.path.join(path, npath[-1]) - if (not os.path.exists(fpath)) and mode[0] == 'r': - raise IOError("File not found: %s." % fpath) - elif mode[0] in ('w', 'a') and not ira.store_fname: - store_fname = os.path.join(*npath) - cr.execute('UPDATE ir_attachment SET store_fname = %s WHERE id = %s', - (store_fname, ira.id)) - return nodefd_file(file_node, path=fpath, mode=mode) - - elif boo.type == 'virtual': - raise ValueError('Virtual storage does not support static file(s).') - - else: - raise TypeError("No %s storage." % boo.type) - - def __get_data_3(self, cr, uid, boo, ira, context): - 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: - _logger.warning( "ir.attachment #%d does not have a filename, but is at filestore. This should get fixed." % ira.id) - return None - fpath = os.path.join(boo.path, ira.store_fname) - return file(fpath, 'rb').read() - elif boo.type == 'db64': - # 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 == 'db': - # We do an explicit query, to avoid type transformations. - cr.execute('SELECT db_datas FROM ir_attachment WHERE id = %s', (ira.id,)) - res = cr.fetchone() - if res: - return res[0] - else: - return '' - elif boo.type == 'realstore': - 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: - _logger.warning("ir.attachment #%d does not have a filename, trying the name." %ira.id) - # sfname = ira.name - fpath = os.path.join(boo.path,ira.store_fname or ira.name) - if os.path.exists(fpath): - return file(fpath,'rb').read() - elif not ira.store_fname: - return None - else: - raise IOError(errno.ENOENT, "File not found: %s." % fpath) - - elif boo.type == 'virtual': - raise ValueError('Virtual storage does not support static file(s).') - - else: - raise TypeError("No %s storage!" % boo.type) + return nodefd_db(file_node, ira_browse=ira, mode=mode) def set_data(self, cr, uid, id, file_node, data, context=None, fil_obj=None): """ store the data. @@ -540,68 +213,11 @@ class document_storage(osv.osv): else: ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - if not boo.online: - raise IOError(errno.EREMOTE, 'Medium offline.') - - if boo.readonly: - raise IOError(errno.EPERM, "Readonly medium.") - _logger.debug( "Store data for ir.attachment #%d." % ira.id) store_fname = None fname = None - if boo.type == 'filestore': - path = boo.path - try: - store_fname = self.__get_random_fname(path) - fname = os.path.join(path, store_fname) - fp = open(fname, 'wb') - try: - fp.write(data) - finally: - fp.close() - _logger.debug( "Saved data to %s." % fname) - filesize = len(data) # os.stat(fname).st_size - - # TODO Here, an old file would be left hanging. - - except Exception, e: - _logger.warning( "Cannot save data to %s.", path, exc_info=True) - raise except_orm(_('Error!'), str(e)) - elif boo.type == 'db': - filesize = len(data) - # will that work for huge data? - out = psycopg2.Binary(data) - cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s', - (out, file_node.file_id)) - elif boo.type == 'db64': - filesize = len(data) - # will that work for huge data? - out = base64.encodestring(data) - cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s', - (out, file_node.file_id)) - elif boo.type == 'realstore': - try: - path, npath = self.__prepare_realpath(cr, file_node, ira, boo.path, do_create=True) - fname = os.path.join(path, npath[-1]) - fp = open(fname,'wb') - try: - fp.write(data) - finally: - fp.close() - _logger.debug("Saved data to %s.", fname) - filesize = len(data) # os.stat(fname).st_size - store_fname = os.path.join(*npath) - # TODO Here, an old file would be left hanging. - except Exception,e : - _logger.warning("Cannot save data.", exc_info=True) - raise except_orm(_('Error!'), str(e)) - - elif boo.type == 'virtual': - raise ValueError('Virtual storage does not support static file(s).') - - else: - raise TypeError("No %s storage!" % boo.type) - + filesize = len(data) + self.pool.get('ir.attachment').write(cr, uid, [file_node.file_id], {'datas': data.encode('base64')}, context=context) # 2nd phase: store the metadata try: icont = '' @@ -609,22 +225,18 @@ class document_storage(osv.osv): if not mime: mime = "" try: - mime, icont = cntIndex.doIndex(data, ira.datas_fname, - ira.file_type or None, fname) + mime, icont = cntIndex.doIndex(data, ira.datas_fname, ira.file_type or None, fname) except Exception: _logger.debug('Cannot index file.', exc_info=True) pass - try: icont_u = ustr(icont) except UnicodeError: icont_u = '' - # 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, icont_u, mime, file_node.file_id)) + cr.execute('UPDATE ir_attachment SET file_size = %s, index_content = %s, file_type = %s WHERE id = %s', (filesize, icont_u, mime, file_node.file_id)) file_node.content_length = filesize file_node.content_type = mime return True @@ -637,40 +249,9 @@ class document_storage(osv.osv): 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 IOError(errno.EREMOTE, 'Medium offline.') - - if storage_bo.readonly: - raise IOError(errno.EPERM, "Readonly medium.") - - 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 in ('db', 'db64'): - return None - elif storage_bo.type == 'realstore': - fname = fil_bo.store_fname - if not fname: - return None - path = storage_bo.path - return ( storage_bo.id, 'file', os.path.join(path, fname)) - else: - raise TypeError("No %s storage!" % storage_bo.type) + pass def do_unlink(self, cr, uid, unres): - for id, ktype, fname in unres: - if ktype == 'file': - try: - os.unlink(fname) - except Exception: - _logger.warning("Cannot remove file %s, please remove it manually.", fname, exc_info=True) - else: - _logger.warning("Unlink unknown key %s." % ktype) - return True def simple_rename(self, cr, uid, file_node, new_name, context=None): @@ -680,38 +261,8 @@ class document_storage(osv.osv): @return the dict of values that can safely be be stored in the db. """ - sbro = self.browse(cr, uid, file_node.storage_id, context=context) - assert sbro, "The file #%d didn't provide storage" % file_node.file_id - - if not sbro.online: - raise IOError(errno.EREMOTE, 'Medium offline.') - - if sbro.readonly: - raise IOError(errno.EPERM, "Readonly medium.") - - if sbro.type in ('filestore', 'db', 'db64'): - # nothing to do for a rename, allow to change the db field - return { 'name': new_name, 'datas_fname': new_name } - elif sbro.type == 'realstore': - ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - - path, npath = self.__prepare_realpath(cr, file_node, ira, sbro.path, do_create=False) - fname = ira.store_fname - - if not fname: - _logger.warning("Trying to rename a non-stored file.") - if fname != os.path.join(*npath): - _logger.warning("Inconsistency to realstore: %s != %s." , fname, repr(npath)) - - oldpath = os.path.join(path, npath[-1]) - newpath = os.path.join(path, new_name) - os.rename(oldpath, newpath) - store_path = npath[:-1] - store_path.append(new_name) - store_fname = os.path.join(*store_path) - return { 'name': new_name, 'datas_fname': new_name, 'store_fname': store_fname } - else: - raise TypeError("No %s storage!" % sbro.type) + # nothing to do for a rename, allow to change the db field + return { 'name': new_name, 'datas_fname': new_name } def simple_move(self, cr, uid, file_node, ndir_bro, context=None): """ A preparation for a file move. @@ -722,65 +273,6 @@ class document_storage(osv.osv): file should move to. @return the dict of values that can safely be be stored in the db. """ - sbro = self.browse(cr, uid, file_node.storage_id, context=context) - assert sbro, "The file #%d didn't provide storage" % file_node.file_id - - if not sbro.online: - raise IOError(errno.EREMOTE, 'Medium offline.') - - if sbro.readonly: - raise IOError(errno.EPERM, "Readonly medium.") - - par = ndir_bro - psto = None - while par: - if par.storage_id: - psto = par.storage_id.id - break - par = par.parent_id - if file_node.storage_id != psto: - _logger.debug('Cannot move file %r from %r to %r.', file_node, file_node.parent, ndir_bro.name) - raise NotImplementedError('Cannot move file(s) between storage media.') - - if sbro.type in ('filestore', 'db', 'db64'): - # nothing to do for a rename, allow to change the db field - return { 'parent_id': ndir_bro.id } - elif sbro.type == 'realstore': - ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - - path, opath = self.__prepare_realpath(cr, file_node, ira, sbro.path, do_create=False) - fname = ira.store_fname - - if not fname: - _logger.warning("Trying to rename a non-stored file.") - if fname != os.path.join(*opath): - _logger.warning("Inconsistency to realstore: %s != %s." , fname, repr(opath)) - - oldpath = os.path.join(path, opath[-1]) - - npath = [sbro.path,] + (ndir_bro.get_full_path() or []) - npath = filter(lambda x: x is not None, npath) - newdir = os.path.join(*npath) - if not os.path.isdir(newdir): - _logger.debug("Must create dir %s.", newdir) - os.makedirs(newdir) - npath.append(opath[-1]) - newpath = os.path.join(*npath) - - _logger.debug("Going to move %s from %s to %s.", opath[-1], oldpath, newpath) - shutil.move(oldpath, newpath) - - store_path = npath[1:] + [opath[-1],] - store_fname = os.path.join(*store_path) - - return { 'store_fname': store_fname } - else: - raise TypeError("No %s storage." % sbro.type) - - -document_storage() - - -#eof + return { 'parent_id': ndir_bro.id } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/nodes.py b/addons/document/nodes.py index aeb2e64fc97..1b4afd31a65 100644 --- a/addons/document/nodes.py +++ b/addons/document/nodes.py @@ -134,7 +134,6 @@ class node_context(object): return self.node_file_class(fbro.name, parent, self, fbro) - class node_descriptor(object): """A file-like interface to the data contents of a node. From fde832955ab4155087893db31aeb9ac3aa7c4466 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 02:16:01 +0100 Subject: [PATCH 22/49] add file_size bzr revid: al@openerp.com-20121217011601-utt2a0zweaq2c0bt --- openerp/addons/base/ir/ir_attachment.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index f9502b7a288..014a56380bc 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -132,14 +132,15 @@ class ir_attachment(osv.osv): if context is None: context = {} location = self.pool.get('ir.config_parameter').get_param(cr, uid, 'ir_attachment.location') + file_size = len(value.decode('base64')) if location: attach = self.browse(cr, uid, id, context=context) if attach.store_fname: self._file_delete(cr, uid, location, attach.store_fname) fname = self._file_write(cr, uid, location, value) - self.write(cr, uid, [id], {'store_fname': fname}, context=context) + super(ir_attachment, self).write(cr, uid, [id], {'store_fname': fname, 'file_size': file_size}, context=context) else: - self.write(cr, uid, [id], {'db_datas': value}, context=context) + super(ir_attachment, self).write(cr, uid, [id], {'db_datas': value, 'file_size': file_size}, context=context) return True _name = 'ir.attachment' @@ -156,14 +157,16 @@ class ir_attachment(osv.osv): 'type': fields.selection( [ ('url','URL'), ('binary','Binary'), ], 'Type', help="Binary File or URL", required=True, change_default=True), 'url': fields.char('Url', size=1024), - # al: For the moment I keepi those shitty field names for backward compatibility with document + # al: We keep shitty field names for backward compatibility with document 'datas': fields.function(_data_get, fnct_inv=_data_set, string='File Content', type="binary", nodrop=True), 'store_fname': fields.char('Stored Filename', size=256), 'db_datas': fields.binary('Database Data'), + 'file_size': fields.integer('File Size'), } _defaults = { 'type': 'binary', + 'file_size': 0, 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c), } @@ -259,6 +262,8 @@ class ir_attachment(osv.osv): def write(self, cr, uid, ids, vals, context=None): self.check(cr, uid, ids, 'write', context=context, values=vals) + if 'file_size' in vals: + del vals['file_size'] return super(ir_attachment, self).write(cr, uid, ids, vals, context) def copy(self, cr, uid, id, default=None, context=None): @@ -276,14 +281,13 @@ class ir_attachment(osv.osv): def create(self, cr, uid, values, context=None): self.check(cr, uid, [], mode='create', context=context, values=values) + if 'file_size' in values: + del values['file_size'] return super(ir_attachment, self).create(cr, uid, values, context) def action_get(self, cr, uid, context=None): return self.pool.get('ir.actions.act_window').for_xml_id( cr, uid, 'base', 'action_attachment', context=context) -ir_attachment() - - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 76ce1a297275718ce16044bad6d04a9d3f051e76 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 02:19:58 +0100 Subject: [PATCH 23/49] document partial refactoring and cleanups bzr revid: al@openerp.com-20121217011958-70esu8d6q54fu0zd --- addons/document/__init__.py | 4 - addons/document/__openerp__.py | 3 +- addons/document/directory_content.py | 124 - addons/document/directory_report.py | 64 - addons/document/document.py | 2133 +++++++++++++++-- addons/document/document_data.xml | 12 - addons/document/document_directory.py | 308 --- addons/document/document_storage.py | 278 --- addons/document/document_view.xml | 125 +- addons/document/nodes.py | 1560 ------------ .../document_ftp/ftpserver/abstracted_fs.py | 2 +- 11 files changed, 2015 insertions(+), 2598 deletions(-) delete mode 100644 addons/document/directory_content.py delete mode 100644 addons/document/directory_report.py delete mode 100644 addons/document/document_directory.py delete mode 100644 addons/document/document_storage.py delete mode 100644 addons/document/nodes.py diff --git a/addons/document/__init__.py b/addons/document/__init__.py index 12306b0499b..ab14f808182 100644 --- a/addons/document/__init__.py +++ b/addons/document/__init__.py @@ -21,10 +21,6 @@ import content_index import std_index -import document_storage -import document_directory -import directory_content -import directory_report import document import report import wizard diff --git a/addons/document/__openerp__.py b/addons/document/__openerp__.py index 3e75c7d15e3..501e5566e60 100644 --- a/addons/document/__openerp__.py +++ b/addons/document/__openerp__.py @@ -37,7 +37,7 @@ This is a complete document management system. """, 'author': 'OpenERP SA', 'website': 'http://www.openerp.com', - 'depends': ['process','board', 'knowledge'], + 'depends': ['knowledge'], 'data': [ 'security/document_security.xml', 'document_view.xml', @@ -45,7 +45,6 @@ This is a complete document management system. 'wizard/document_configuration_view.xml', 'security/ir.model.access.csv', 'report/document_report_view.xml', - 'board_document_view.xml', ], 'demo': [ 'document_demo.xml' ], 'test': ['test/document_test2.yml'], diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py deleted file mode 100644 index 5b8ec3ddd93..00000000000 --- a/addons/document/directory_content.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 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 - -import netsvc -# import os -import nodes -# import StringIO - -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=None): - 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 to contain the record name." \ - "\nIf set, the directory will have to be a resource one."), - '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! - model = node.res_model - if content.include_name and not model: - return False - - res2 = [] - tname = '' - if content.include_name: - 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 '') - if tname.find('/'): - tname=tname.replace('/', '_') - act_id = False - if 'dctx_res_id' in node.dctx: - act_id = node.dctx['dctx_res_id'] - elif hasattr(node, 'res_id'): - act_id = node.res_id - else: - act_id = node.context.context.get('res_id',False) - if not nodename: - n = nodes.node_content(tname, node, node.context,content, act_id=act_id) - res2.append( n) - else: - if nodename == tname: - n = nodes.node_content(tname, node, node.context,content, act_id=act_id) - n.fill_fields(cr) - res2.append(n) - return res2 - - 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, 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, context=context) - srv = netsvc.Service._services['report.'+report.report_name] - ctx = node.context.context.copy() - ctx.update(node.dctx) - pdf,pdftype = srv.create(cr, uid, [node.act_id,], {}, context=ctx) - return pdf -document_directory_content() - -#eof -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/directory_report.py b/addons/document/directory_report.py deleted file mode 100644 index 202725a1d3f..00000000000 --- a/addons/document/directory_report.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 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 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 - -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=None): - 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, context=None): - if not len(args): - return [] - assert len(args) == 1 and args[0][1] == '=', 'expression is not what we expect: %r' % args - model_id= args[0][2] - if not model_id: - # a deviation from standard behavior: when searching model_id = False - # we return *all* reports, not just ones with empty model. - # One reason is that 'model' is a required field so far - 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, string='Model Id'), - } - -ir_action_report_xml() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/document.py b/addons/document/document.py index aeb5f97754a..2ae5d55b7ad 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -18,57 +18,33 @@ # along with this program. If not, see . # ############################################################################## - import base64 -from osv import osv, fields -import os - -#from psycopg2 import Binary -#from tools import config -import tools -from tools.translate import _ -import nodes +import errno import logging +import os +import random +import shutil +import string +import time +from StringIO import StringIO + +import openerp +import netsvc +import pooler +import psycopg2 +import tools +import pooler +from content_index import cntIndex +from osv import osv, fields +from osv.orm import except_orm +from tools.misc import ustr +from tools.translate import _ +from tools.safe_eval import safe_eval _logger = logging.getLogger(__name__) -DMS_ROOT_PATH = tools.config.get('document_path', os.path.join(tools.config['root_path'], 'filestore')) - class document_file(osv.osv): _inherit = 'ir.attachment' - _rec_name = 'name' - - def _attach_parent_id(self, cr, uid, ids=None, context=None): - """Migrate ir.attachments to the document module. - - When the 'document' module is loaded on a db that has had plain attachments, - they will need to be attached to some parent folder, and be converted from - base64-in-bytea to raw-in-bytea format. - This function performs the internal migration, once and forever, for these - attachments. It cannot be done through the nominal ORM maintenance code, - because the root folder is only created after the document_data.xml file - is loaded. - It also establishes the parent_id NOT NULL constraint that ir.attachment - should have had (but would have failed if plain attachments contained null - values). - It also updates the File Size for the previously created attachments. - """ - - parent_id = self.pool.get('document.directory')._get_root_directory(cr,uid) - if not parent_id: - _logger.warning("at _attach_parent_id(), still not able to set the parent!") - return False - - if ids is not None: - raise NotImplementedError("Ids are just there by convention, please do not use it.") - - cr.execute("UPDATE ir_attachment SET parent_id = %s WHERE parent_id IS NULL", (parent_id,)) - - cr.execute("UPDATE ir_attachment SET file_size=length(db_datas) WHERE file_size = 0 and type = 'binary'") - - cr.execute("ALTER TABLE ir_attachment ALTER parent_id SET NOT NULL") - - return True _columns = { # Columns from ir.attachment: @@ -76,50 +52,33 @@ class document_file(osv.osv): 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True), # Fields of document: 'user_id': fields.many2one('res.users', 'Owner', select=1), - 'parent_id': fields.many2one('document.directory', 'Directory', select=1, required=True, change_default=True), + 'parent_id': fields.many2one('document.directory', 'Directory', select=1, change_default=True), 'index_content': fields.text('Indexed Content'), 'partner_id':fields.many2one('res.partner', 'Partner', select=1), - 'file_size': fields.integer('File Size', required=True), - 'file_type': fields.char('Content Type', size=128), + 'file_type': fields.char('Content Type'), } _order = "id desc" - 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, - 'parent_id': __get_def_directory, - 'file_size': lambda self, cr, uid, ctx:0, } - _sql_constraints = [ - # filename_uniq is not possible in pure SQL - ] - def onchange_file(self, cr, uid, ids, datas_fname=False, context=None): - res = {'value':{}} - if datas_fname: - res['value'].update({'name': datas_fname}) - return res + _sql_constraints = [ + ('filename_unique', 'unique (name,parent_id)', 'The filename must be unique in a directory !'), + ] def check(self, cr, uid, ids, mode, context=None, values=None): """Check access wrt. res_model, relax the rule of ir.attachment parent - With 'document' installed, everybody will have access to attachments of any resources they can *read*. """ - return super(document_file, self).check(cr, uid, ids, mode='read', - context=context, values=values) + return super(document_file, self).check(cr, uid, ids, mode='read', context=context, values=values) def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): # Grab ids, bypassing 'count' - ids = super(document_file, self).search(cr, uid, args, offset=offset, - limit=limit, order=order, - context=context, count=False) + ids = super(document_file, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False) if not ids: return 0 if count else [] - # Filter out documents that are in directories that the user is not allowed to read. # Must use pure SQL to avoid access rules exceptions (we want to remove the records, # not fail), and the records have been filtered in parent's search() anyway. @@ -141,79 +100,13 @@ class document_file(osv.osv): default.update(name=_("%s (copy)") % (name)) return super(document_file, self).copy(cr, uid, id, default, context=context) - def write(self, cr, uid, ids, vals, context=None): - result = False - if not isinstance(ids, list): - ids = [ids] - res = self.search(cr, uid, [('id', 'in', ids)]) - if not len(res): - return False - - # if nodes call this write(), they must skip the code below - from_node = context and context.get('__from_node', False) - if (('parent_id' in vals) or ('name' in vals)) and not from_node: - # perhaps this file is renaming or changing directory - nctx = nodes.get_node_context(cr,uid,context={}) - dirobj = self.pool.get('document.directory') - if 'parent_id' in vals: - dbro = dirobj.browse(cr, uid, vals['parent_id'], context=context) - dnode = nctx.get_dir_node(cr, dbro) - else: - dbro = None - dnode = None - ids2 = [] - for fbro in self.browse(cr, uid, ids, context=context): - if ('parent_id' not in vals or fbro.parent_id.id == vals['parent_id']) \ - and ('name' not in vals or fbro.name == vals['name']): - ids2.append(fbro.id) - continue - fnode = nctx.get_file_node(cr, fbro) - res = fnode.move_to(cr, dnode or fnode.parent, vals.get('name', fbro.name), fbro, dbro, True) - if isinstance(res, dict): - vals2 = vals.copy() - vals2.update(res) - wid = res.get('id', fbro.id) - result = super(document_file,self).write(cr,uid,wid,vals2,context=context) - # TODO: how to handle/merge several results? - elif res == True: - ids2.append(fbro.id) - elif res == False: - pass - ids = ids2 - if 'file_size' in vals: # only write that field using direct SQL calls - del vals['file_size'] - if ids and vals: - result = super(document_file,self).write(cr, uid, ids, vals, context=context) - return result - def create(self, cr, uid, vals, context=None): if context is None: context = {} vals['parent_id'] = context.get('parent_id', False) or vals.get('parent_id', False) - if not vals['parent_id']: - vals['parent_id'] = self.pool.get('document.directory')._get_root_directory(cr,uid, context) - if not vals.get('res_id', False) and context.get('default_res_id', False): - vals['res_id'] = context.get('default_res_id', False) - if not vals.get('res_model', False) and context.get('default_res_model', False): - vals['res_model'] = context.get('default_res_model', False) - if vals.get('res_id', False) and vals.get('res_model', False) \ - and not vals.get('partner_id', False): - vals['partner_id'] = self.__get_partner_id(cr, uid, \ - vals['res_model'], vals['res_id'], context) - - datas = None - if vals.get('link', False) : - import urllib - datas = base64.encodestring(urllib.urlopen(vals['link']).read()) - else: - datas = vals.get('datas', False) - - if datas: - vals['file_size'] = len(datas) - else: - if vals.get('file_size'): - del vals['file_size'] - + # take partner from uid + if vals.get('res_id', False) and vals.get('res_model', False) and not vals.get('partner_id', False): + vals['partner_id'] = self.__get_partner_id(cr, uid, vals['res_model'], vals['res_id'], context) return super(document_file, self).create(cr, uid, vals, context) def __get_partner_id(self, cr, uid, res_model, res_id, context=None): @@ -229,4 +122,1970 @@ class document_file(osv.osv): return bro.partner_id.id return False +class document_directory(osv.osv): + _name = 'document.directory' + _description = 'Directory' + _order = 'name' + _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'), + 'parent_id': fields.many2one('document.directory', 'Parent Directory', select=1, change_default=True), + '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','Folders per resource'), ], + 'Type', required=True, select=1, change_default=True, + help="Each directory can either have the type Static or be linked to another resource. A static directory, as with Operating Systems, is the classic directory that can contain a set of files. The directories linked to systems resources automatically possess sub-directories for each of resource types defined in the parent directory."), + 'domain': fields.char('Domain', size=128, help="Use a domain if you want to apply an automatic filter on visible resources."), + 'ressource_type_id': fields.many2one('ir.model', 'Resource model', change_default=True, + help="Select an object here and there will be one folder per record of that resource."), + 'resource_field': fields.many2one('ir.model.fields', 'Name field', help='Field to be used as name on resource directories. If empty, the "name" will be used.'), + 'resource_find_all': fields.boolean('Find all resources', + help="If true, all attachments that match this resource will " \ + " be located. If false, only ones that have this as parent." ), + 'ressource_parent_type_id': fields.many2one('ir.model', 'Parent Model', change_default=True, + help="If you put an object here, this directory template will appear bellow all of these objects. " \ + "Such directories are \"attached\" to the specific model or record, just like attachments. " \ + "Don't put a parent directory if you select a parent model."), + 'ressource_id': fields.integer('Resource ID', + help="Along with Parent Model, this ID attaches this folder to a specific record of Parent Model."), + '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'), + 'company_id': fields.many2one('res.company', 'Company', change_default=True), + } + + _defaults = { + 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'document.directory', context=c), + 'user_id': lambda self,cr,uid,ctx: uid, + 'domain': '[]', + 'type': 'directory', + 'ressource_id': 0, + 'resource_find_all': True, + } + _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 name_get(self, cr, uid, ids, context=None): + res = [] + if not self.search(cr,uid,[('id','in',ids)]): + ids = [] + for d in self.browse(cr, uid, ids, context=context): + s = '' + d2 = d + while d2 and d2.parent_id: + s = d2.name + (s and ('/' + s) or '') + d2 = d2.parent_id + res.append((d.id, s or d.name)) + return res + + def get_full_path(self, cr, uid, dir_id, context=None): + """ Return the full path to this directory, in a list, root first + """ + if isinstance(dir_id, (tuple, list)): + assert len(dir_id) == 1 + dir_id = dir_id[0] + + 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 + path = [] + _parent(dir_id, path) + return path + + def _check_recursion(self, cr, uid, ids, context=None): + 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 cannot create recursive directories.', ['parent_id']) + ] + + def onchange_content_id(self, cr, uid, ids, ressource_type_id): + return {} + + 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 + """ + return get_node_context(cr, uid, context).get_uri(cr, uri) + + def get_node_class(self, cr, uid, ids, dbro=None, dynamic=False, context=None): + """Retrieve the class of nodes for this directory + + This function can be overriden by inherited classes ;) + @param dbro The browse object, if caller already has it + """ + if dbro is None: + dbro = self.browse(cr, uid, ids, context=context) + + if dynamic: + return node_res_obj + elif dbro.type == 'directory': + return node_dir + elif dbro.type == 'ressource': + return node_res_dir + else: + raise ValueError("dir node for %s type.", dbro.type) + + def _prepare_context(self, cr, uid, nctx, context=None): + """ Fill nctx with properties for this database + @param nctx instance of nodes.node_context, to be filled + @param context ORM context (dict) for us + + Note that this function is called *without* a list of ids, + it should behave the same for the whole database (based on the + ORM instance of document.directory). + + Some databases may override this and attach properties to the + node_context. See WebDAV, CalDAV. + """ + return + + def get_dir_permissions(self, cr, uid, ids, context=None): + """Check what permission user 'uid' has on directory 'id' + """ + assert len(ids) == 1 + + res = 0 + for pperms in [('read', 5), ('write', 2), ('unlink', 8)]: + try: + self.check_access_rule(cr, uid, ids, pperms[0], context=context) + res |= pperms[1] + except except_orm: + pass + return res + + 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) + """ + return (node_database(context=ncontext), uri) + + 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=_("%s (copy)") % (name)) + return super(document_directory,self).copy(cr, uid, id, default, context=context) + + def _check_duplication(self, cr, uid, vals, ids=None, 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 + # TODO fix algo + 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!')) + newname = vals.get('name',False) + if newname: + for illeg in ('/', '@', '$', '#'): + if illeg in newname: + raise osv.except_osv(_('ValidateError'), _('Directory name contains special characters!')) + return super(document_directory,self).create(cr, uid, vals, context) + +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, ondelete="cascade"), + '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"), + } + +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 + } + +class document_directory_content(osv.osv): + _name = 'document.directory.content' + _description = 'Directory Content' + _order = "sequence" + + def _extension_get(self, cr, uid, context=None): + 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 to contain the record name." \ + "\nIf set, the directory will have to be a resource one."), + '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! + model = node.res_model + if content.include_name and not model: + return False + + res2 = [] + tname = '' + if content.include_name: + 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 '') + if tname.find('/'): + tname=tname.replace('/', '_') + act_id = False + if 'dctx_res_id' in node.dctx: + act_id = node.dctx['dctx_res_id'] + elif hasattr(node, 'res_id'): + act_id = node.res_id + else: + act_id = node.context.context.get('res_id',False) + if not nodename: + n = node_content(tname, node, node.context,content, act_id=act_id) + res2.append( n) + else: + if nodename == tname: + n = node_content(tname, node, node.context,content, act_id=act_id) + n.fill_fields(cr) + res2.append(n) + return res2 + + 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, 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, context=context) + srv = netsvc.Service._services['report.'+report.report_name] + ctx = node.context.context.copy() + ctx.update(node.dctx) + pdf,pdftype = srv.create(cr, uid, [node.act_id,], {}, context=ctx) + return pdf + +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=None): + 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, context=None): + if not len(args): + return [] + assert len(args) == 1 and args[0][1] == '=', 'expression is not what we expect: %r' % args + model_id= args[0][2] + if not model_id: + # a deviation from standard behavior: when searching model_id = False + # we return *all* reports, not just ones with empty model. + # One reason is that 'model' is a required field so far + 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, string='Model Id'), + } + +class document_storage(osv.osv): + """ The primary object for data storage. Deprecated. """ + _name = 'document.storage' + _description = 'Storage Media' + + 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) + """ + boo = self.browse(cr, uid, id, context=context) + if fil_obj: + ira = fil_obj + else: + ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) + data = ira.datas + if data: + out = data.decode('base64') + else: + out = '' + return out + + def get_file(self, cr, uid, id, file_node, mode, context=None): + """ Return a file-like object for the contents of some node + """ + if context is None: + context = {} + boo = self.browse(cr, uid, id, context=context) + + ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) + return nodefd_db(file_node, ira_browse=ira, mode=mode) + + 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). + """ + boo = self.browse(cr, uid, id, context=context) + if fil_obj: + ira = fil_obj + else: + ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) + + _logger.debug( "Store data for ir.attachment #%d." % ira.id) + store_fname = None + fname = None + filesize = len(data) + self.pool.get('ir.attachment').write(cr, uid, [file_node.file_id], {'datas': data.encode('base64')}, context=context) + # 2nd phase: store the metadata + try: + icont = '' + mime = ira.file_type + if not mime: + mime = "" + try: + mime, icont = cntIndex.doIndex(data, ira.datas_fname, ira.file_type or None, fname) + except Exception: + _logger.debug('Cannot index file.', exc_info=True) + pass + try: + icont_u = ustr(icont) + except UnicodeError: + icont_u = '' + # 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 index_content = %s, file_type = %s WHERE id = %s', (filesize, icont_u, mime, file_node.file_id)) + file_node.content_length = filesize + file_node.content_type = mime + return True + except Exception, e : + self._logger.warning("Cannot save data.", exc_info=True) + # 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 _str2time(cre): + """ Convert a string with time representation (from db) into time (float) + + Note: a place to fix if datetime is used in db. + """ + if not cre: + return time.time() + frac = 0.0 + if isinstance(cre, basestring) and '.' in cre: + fdot = cre.find('.') + frac = float(cre[fdot:]) + cre = cre[:fdot] + return time.mktime(time.strptime(cre,'%Y-%m-%d %H:%M:%S')) + frac + +def get_node_context(cr, uid, context): + return node_context(cr, uid, context) + +# +# 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 +# + +class node_context(object): + """ This is the root node, representing access to some particular context + + A context is a set of persistent data, which may influence the structure + of the nodes. All other transient information during a data query should + be passed down with function arguments. + """ + cached_roots = {} + node_file_class = None + + def __init__(self, cr, uid, context=None): + self.dbname = cr.dbname + self.uid = uid + self.context = context + if context is None: + context = {} + context['uid'] = uid + self._dirobj = pooler.get_pool(cr.dbname).get('document.directory') + self.node_file_class = node_file + self.extra_ctx = {} # Extra keys for context, that do _not_ trigger inequality + assert self._dirobj + self._dirobj._prepare_context(cr, uid, self, context=context) + self.rootdir = False #self._dirobj._get_root_directory(cr,uid,context) + + def __eq__(self, other): + if not type(other) == node_context: + return False + if self.dbname != other.dbname: + return False + if self.uid != other.uid: + return False + if self.context != other.context: + return False + if self.rootdir != other.rootdir: + return False + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def get(self, name, default=None): + return self.context.get(name, default) + + 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 + + def get_dir_node(self, cr, dbro): + """Create (or locate) a node for a directory + @param dbro a browse object of document.directory + """ + + fullpath = dbro.get_full_path(context=self.context) + klass = dbro.get_node_class(dbro, context=self.context) + return klass(fullpath, None ,self, dbro) + + def get_file_node(self, cr, fbro): + """ Create or locate a node for a static file + @param fbro a browse object of an ir.attachment + """ + parent = None + if fbro.parent_id: + parent = self.get_dir_node(cr, fbro.parent_id) + + return self.node_file_class(fbro.name, parent, self, fbro) + +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' + DAV_PROPS = None + DAV_M_NS = None + + 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.uidperms = 5 # computed permissions for our uid, in unix bits + self.mimetype = 'application/octet-stream' + self.create_date = None + self.write_date = None + self.unixperms = 0660 + self.uuser = 'user' + self.ugroup = 'group' + self.content_length = 0 + # dynamic context: + self.dctx = {} + if parent: + self.dctx = parent.dctx.copy() + self.displayname = 'Object' + + def __eq__(self, other): + return NotImplemented + + def __ne__(self, other): + return not self.__eq__(other) + + def full_path(self): + """ Return the components of the full path for some + node. + The returned list only contains the names of nodes. + """ + if self.parent: + s = self.parent.full_path() + else: + s = [] + if isinstance(self.path,list): + s+=self.path + elif self.path is None: + s.append('') + else: + s.append(self.path) + return s #map(lambda x: '/' +x, s) + + def __repr__(self): + return "%s@/%s" % (self.our_type, '/'.join(self.full_path())) + + def children(self, cr, domain=None): + print "node_class.children()" + return [] #stub + + def child(self, cr, name, domain=None): + print "node_class.child()" + return None + + def get_uri(self, cr, uri): + duri = uri + ndir = self + while duri: + ndir = ndir.child(cr, duri[0]) + if not ndir: + return False + duri = duri[1:] + return ndir + + 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 open_data(self, cr, mode): + """ Open a node_descriptor object for this node. + + @param the mode of open, eg 'r', 'w', 'a', like file.open() + + This operation may lock the data for this node (and accross + other node hierarchies), until the descriptor is close()d. If + the node is locked, subsequent opens (depending on mode) may + immediately fail with an exception (which?). + For this class, there is no data, so no implementation. Each + child class that has data should override this. + """ + raise TypeError('No data for %s.' % self.type) + + def get_etag(self, cr): + """ Get a tag, unique per object + modification. + + see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """ + return '"%s-%s"' % (self._get_ttag(cr), self._get_wtag(cr)) + + def _get_wtag(self, cr): + """ Return the modification time as a unique, compact string """ + return str(_str2time(self.write_date)).replace('.','') + + 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 NotImplementedError("get_ttag stub()") + + def get_dav_props(self, cr): + """ If this class has special behaviour for GroupDAV etc, export + its capabilities """ + # This fn is placed here rather than WebDAV, because we want the + # baseclass methods to apply to all node subclasses + return self.DAV_PROPS or {} + + def match_dav_eprop(self, cr, match, ns, prop): + res = self.get_dav_eprop(cr, ns, prop) + if res == match: + return True + return False + + def get_dav_eprop(self, cr, ns, prop): + if not self.DAV_M_NS: + return None + + if self.DAV_M_NS.has_key(ns): + prefix = self.DAV_M_NS[ns] + else: + _logger.debug('No namespace: %s ("%s").',ns, prop) + return None + + mname = prefix + "_" + prop.replace('-','_') + + if not hasattr(self, mname): + return None + + try: + m = getattr(self, mname) + r = m(cr) + return r + except AttributeError: + _logger.debug('The property %s is not supported.' % prop, exc_info=True) + return None + + def get_dav_resourcetype(self, cr): + """ Get the DAV resource type. + + Is here because some nodes may exhibit special behaviour, like + CalDAV/GroupDAV collections + """ + raise NotImplementedError + + def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): + """ Move this node to a new parent directory. + @param ndir_node the collection that this node should be moved under + @param new_name a name to rename this node to. If omitted, the old + name is preserved + @param fil_obj, can be None, is the browse object for the file, + if already available. + @param ndir_obj must be the browse object to the new doc.directory + location, where this node should be moved to. + in_write: When called by write(), we shouldn't attempt to write the + object, but instead return the dict of vals (avoid re-entrance). + If false, we should write all data to the object, here, as if the + caller won't do anything after calling move_to() + + Return value: + True: the node is moved, the caller can update other values, too. + False: the node is either removed or fully updated, the caller + must discard the fil_obj, not attempt to write any more to it. + dict: values to write back to the object. *May* contain a new id! + + Depending on src and target storage, implementations of this function + could do various things. + Should also consider node<->content, dir<->dir moves etc. + + Move operations, as instructed from APIs (e.g. request from DAV) could + use this function. + """ + raise NotImplementedError(repr(self)) + + def create_child(self, cr, path, data=None): + """ Create a regular file under this node + """ + _logger.warning("Attempted to create a file under %r, not possible.", self) + raise IOError(errno.EPERM, "Not allowed to create file(s) here.") + + def create_child_collection(self, cr, objname): + """ Create a child collection (directory) under self + """ + _logger.warning("Attempted to create a collection under %r, not possible.", self) + raise IOError(errno.EPERM, "Not allowed to create folder(s) here.") + + def rm(self, cr): + raise NotImplementedError(repr(self)) + + def rmcol(self, cr): + raise NotImplementedError(repr(self)) + + def get_domain(self, cr, filters): + # TODO Document + return [] + + def check_perms(self, perms): + """ Check the permissions of the current node. + + @param perms either an integers of the bits to check, or + a string with the permission letters + + Permissions of nodes are (in a unix way): + 1, x : allow descend into dir + 2, w : allow write into file, or modification to dir + 4, r : allow read of file, or listing of dir contents + 8, u : allow remove (unlink) + """ + + if isinstance(perms, str): + pe2 = 0 + chars = { 'x': 1, 'w': 2, 'r': 4, 'u': 8 } + for c in perms: + pe2 = pe2 | chars[c] + perms = pe2 + elif isinstance(perms, int): + if perms < 0 or perms > 15: + raise ValueError("Invalid permission bits.") + else: + raise ValueError("Invalid permission attribute.") + + return ((self.uidperms & perms) == perms) + +class node_database(node_class): + """ A node representing the database directory + + """ + our_type = 'database' + def __init__(self, path=None, parent=False, context=None): + if path is None: + path = [] + super(node_database,self).__init__(path, parent, context) + self.unixperms = 040750 + self.uidperms = 5 + + def children(self, cr, domain=None): + res = self._child_get(cr, domain=domain) + self._file_get(cr) + return res + + def child(self, cr, name, domain=None): + res = self._child_get(cr, name, domain=None) + if res: + return res[0] + res = self._file_get(cr,name) + if res: + return res[0] + return None + + def _child_get(self, cr, name=False, domain=None): + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + where = [('parent_id','=', False), ('ressource_parent_type_id','=',False)] + if name: + where.append(('name','=',name)) + is_allowed = self.check_perms(1) + else: + is_allowed = self.check_perms(5) + + if not is_allowed: + raise IOError(errno.EPERM, "Permission into directory denied.") + + if domain: + where = where + domain + ids = dirobj.search(cr, uid, where, context=ctx) + res = [] + for dirr in dirobj.browse(cr, uid, ids, context=ctx): + klass = dirr.get_node_class(dirr, context=ctx) + res.append(klass(dirr.name, self, self.context,dirr)) + + return res + + def _file_get(self, cr, nodename=False): + res = [] + return res + + def _get_ttag(self, cr): + return 'db-%s' % cr.dbname + +def mkdosname(company_name, default='noname'): + """ convert a string to a dos-like name""" + if not company_name: + return default + badchars = ' !@#$%^`~*()+={}[];:\'"/?.<>' + n = '' + for c in company_name[:8]: + n += (c in badchars and '_') or c + return n + +def _uid2unixperms(perms, has_owner): + """ Convert the uidperms and the owner flag to full unix bits + """ + res = 0 + if has_owner: + res |= (perms & 0x07) << 6 + res |= (perms & 0x05) << 3 + elif perms & 0x02: + res |= (perms & 0x07) << 6 + res |= (perms & 0x07) << 3 + else: + res |= (perms & 0x07) << 6 + res |= (perms & 0x05) << 3 + res |= 0x05 + return res + +class node_dir(node_database): + our_type = 'collection' + def __init__(self, path, parent, context, dirr, dctx=None): + super(node_dir,self).__init__(path, parent,context) + self.dir_id = dirr and dirr.id or False + #todo: more info from dirr + self.mimetype = 'application/x-directory' + # 'httpd/unix-directory' + self.create_date = dirr and dirr.create_date or False + self.domain = dirr and dirr.domain or [] + self.res_model = dirr and 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 and (dirr.write_date or dirr.create_date) or False + self.content_length = 0 + try: + self.uuser = (dirr.user_id and dirr.user_id.login) or 'nobody' + except Exception: + self.uuser = 'nobody' + self.ugroup = mkdosname(dirr.company_id and dirr.company_id.name, default='nogroup') + self.uidperms = dirr.get_dir_permissions() + self.unixperms = 040000 | _uid2unixperms(self.uidperms, dirr and dirr.user_id) + if dctx: + self.dctx.update(dctx) + dc2 = self.context.context + dc2.update(self.dctx) + dc2['dir_id'] = self.dir_id + self.displayname = dirr and dirr.name or False + if dirr and dirr.dctx_ids: + 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 __eq__(self, other): + if type(self) != type(other): + return False + if not self.context == other.context: + return False + # Two directory nodes, for the same document.directory, may have a + # different context! (dynamic folders) + if self.dctx != other.dctx: + return False + return self.dir_id == other.dir_id + + def get_data(self, cr): + #res = '' + #for child in self.children(cr): + # res += child.get_data(cr) + return None + + def _file_get(self, cr, nodename=False): + res = super(node_dir,self)._file_get(cr, nodename) + + is_allowed = self.check_perms(nodename and 1 or 5) + if not is_allowed: + raise IOError(errno.EPERM, "Permission into directory denied.") + + 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 _child_get(self, cr, name=None, domain=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)) + is_allowed = self.check_perms(1) + else: + is_allowed = self.check_perms(5) + + if not is_allowed: + raise IOError(errno.EPERM, "Permission into directory denied.") + + if not domain: + domain = [] + + where2 = where + domain + [('ressource_parent_type_id','=',False)] + ids = dirobj.search(cr, uid, where2, context=ctx) + res = [] + for dirr in dirobj.browse(cr, uid, ids, context=ctx): + klass = dirr.get_node_class(dirr, context=ctx) + res.append(klass(dirr.name, self, self.context,dirr)) + + # Static directories should never return files with res_model/res_id + # because static dirs are /never/ related to a record. + # In fact, files related to some model and parented by the root dir + # (the default), will NOT be accessible in the node system unless + # a resource folder for that model exists (with resource_find_all=True). + # Having resource attachments in a common folder is bad practice, + # because they would be visible to all users, and their names may be + # the same, conflicting. + where += [('res_model', '=', False)] + fil_obj = dirobj.pool.get('ir.attachment') + ids = fil_obj.search(cr, uid, where, context=ctx) + if ids: + for fil in fil_obj.browse(cr, uid, ids, context=ctx): + klass = self.context.node_file_class + res.append(klass(fil.name, self, self.context, fil)) + return res + + def rmcol(self, cr): + uid = self.context.uid + directory = self.context._dirobj.browse(cr, uid, self.dir_id) + res = False + if not directory: + raise OSError(2, 'Not such file or directory.') + if not self.check_perms('u'): + raise IOError(errno.EPERM,"Permission denied.") + + if directory._table_name=='document.directory': + if self.children(cr): + raise OSError(39, 'Directory not empty.') + res = self.context._dirobj.unlink(cr, uid, [directory.id]) + else: + raise OSError(1, 'Operation is not permitted.') + return res + + def create_child_collection(self, cr, objname): + object2 = False + if not self.check_perms(2): + raise IOError(errno.EPERM,"Permission denied.") + + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + obj = dirobj.browse(cr, uid, self.dir_id) + if obj and (obj.type == 'ressource') and not object2: + raise OSError(1, 'Operation is not permitted.') + + #objname = uri2[-1] + val = { + 'name': objname, + 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False, + 'ressource_id': object2 and object2.id or False, + 'parent_id' : obj and obj.id or False + } + + return dirobj.create(cr, uid, val) + + def create_child(self, cr, path, data=None): + """ API function to create a child file object and node + Return the node_* created + """ + if not self.check_perms(2): + raise IOError(errno.EPERM,"Permission denied.") + + 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) + if data is not None: + fnode.set_data(cr, data, fil) + return fnode + + def _get_ttag(self, cr): + return 'dir-%d' % self.dir_id + + def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): + """ Move directory. This operation is simple, since the present node is + only used for static, simple directories. + Note /may/ be called with ndir_node = None, to rename the document root. + """ + if ndir_node and (ndir_node.context != self.context): + raise NotImplementedError("Cannot move directories between contexts.") + + if (not self.check_perms('u')) or (not ndir_node.check_perms('w')): + raise IOError(errno.EPERM,"Permission denied.") + + dir_obj = self.context._dirobj + if not fil_obj: + dbro = dir_obj.browse(cr, self.context.uid, self.dir_id, context=self.context.context) + else: + dbro = dir_obj + assert dbro.id == self.dir_id + + if not dbro: + raise IndexError("Cannot locate dir %d", self.dir_id) + + if (not self.parent) and ndir_node: + if not dbro.parent_id: + raise IOError(errno.EPERM, "Cannot move the root directory!") + self.parent = self.context.get_dir_node(cr, dbro.parent_id) + assert self.parent + + if self.parent != ndir_node: + _logger.debug('Cannot move dir %r from %r to %r.', self, self.parent, ndir_node) + raise NotImplementedError('Cannot move dir to another dir.') + + ret = {} + if new_name and (new_name != dbro.name): + if ndir_node.child(cr, new_name): + raise IOError(errno.EEXIST, "Destination path already exists.") + ret['name'] = new_name + + del dbro + + if not in_write: + # We have to update the data ourselves + if ret: + ctx = self.context.context.copy() + ctx['__from_node'] = True + dir_obj.write(cr, self.context.uid, [self.dir_id,], ret, ctx) + ret = True + + return ret + +class node_res_dir(node_class): + """ A folder containing dynamic folders + 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' + res_obj_class = None + 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 + try: + self.uuser = (dirr.user_id and dirr.user_id.login) or 'nobody' + except Exception: + self.uuser = 'nobody' + self.ugroup = mkdosname(dirr.company_id and dirr.company_id.name, default='nogroup') + self.uidperms = dirr.get_dir_permissions() + self.unixperms = 040000 | _uid2unixperms(self.uidperms, dirr and dirr.user_id) + self.res_model = dirr.ressource_type_id and dirr.ressource_type_id.model or False + self.resm_id = dirr.ressource_id + self.res_find_all = dirr.resource_find_all + self.namefield = dirr.resource_field.name or 'name' + self.displayname = dirr.name + # 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: + 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 __eq__(self, other): + if type(self) != type(other): + return False + if not self.context == other.context: + return False + # Two nodes, for the same document.directory, may have a + # different context! (dynamic folders) + if self.dctx != other.dctx: + return False + return self.dir_id == other.dir_id + + def children(self, cr, domain=None): + return self._child_get(cr, domain=domain) + + def child(self, cr, name, domain=None): + res = self._child_get(cr, name, domain=domain) + if res: + return res[0] + return None + + def _child_get(self, cr, name=None, domain=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: + return [] + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + ctx.update(self.context.extra_ctx) + where = [] + if self.domain: + app = safe_eval(self.domain, ctx) + if not app: + pass + elif isinstance(app, list): + where.extend(app) + elif isinstance(app, tuple): + where.append(app) + else: + raise RuntimeError("Incorrect domain expr: %s." % self.domain) + if self.resm_id: + where.append(('id','=',self.resm_id)) + + if name: + # The =like character will match underscores against any characters + # including the special ones that couldn't exist in a FTP/DAV request + where.append((self.namefield,'=like',name.replace('\\','\\\\'))) + is_allowed = self.check_perms(1) + else: + is_allowed = self.check_perms(5) + + if not is_allowed: + raise IOError(errno.EPERM,"Permission denied.") + + # 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 = [] + for bo in obj.browse(cr, uid, resids, context=ctx): + if not bo: + continue + res_name = getattr(bo, self.namefield) + if not res_name: + continue + # Yes! we can't do better but skip nameless records. + + # Escape the name for characters not supported in filenames + res_name = res_name.replace('/','_') # any other weird char? + + if name and (res_name != ustr(name)): + # we have matched _ to any character, but we only meant to match + # the special ones. + # Eg. 'a_c' will find 'abc', 'a/c', 'a_c', may only + # return 'a/c' and 'a_c' + continue + + res.append(self.res_obj_class(res_name, self.dir_id, 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 dynamically created folder. + 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, 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 = 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.uidperms = parent.uidperms & 15 + self.unixperms = 040000 | _uid2unixperms(self.uidperms, True) + self.uuser = parent.uuser + self.ugroup = parent.ugroup + self.res_model = res_model + self.domain = parent.domain + self.displayname = path + self.dctx_dict = parent.dctx_dict + if isinstance(parent, node_res_dir): + self.res_find_all = parent.res_find_all + else: + self.res_find_all = False + if res_bo: + self.res_id = res_bo.id + dc2 = self.context.context.copy() + dc2.update(self.dctx) + dc2['res_model'] = res_model + dc2['res_id'] = res_bo.id + dc2['this'] = res_bo + for fld,expr in self.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 __eq__(self, other): + if type(self) != type(other): + return False + if not self.context == other.context: + return False + if not self.res_model == other.res_model: + return False + if not self.res_id == other.res_id: + return False + if self.domain != other.domain: + return False + if self.res_find_all != other.res_find_all: + return False + if self.dctx != other.dctx: + return False + return self.dir_id == other.dir_id + + def children(self, cr, domain=None): + return self._child_get(cr, domain=domain) + self._file_get(cr) + + def child(self, cr, name, domain=None): + res = self._child_get(cr, name, domain=domain) + 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 = [] + is_allowed = self.check_perms((nodename and 1) or 5) + if not is_allowed: + raise IOError(errno.EPERM,"Permission denied.") + + 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_DEPR(self, cr): + # Deprecated! (but document_ics must be cleaned, first) + 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_DEPR(self, cr, ns, prop): + # Deprecated! + if ns != 'http://groupdav.org/' or prop != 'resourcetype': + _logger.warning("Who asks for %s:%s?" % (ns, prop)) + return None + 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): + # TODO: remove relic of GroupDAV + if content.extension == '.ics': # FIXME: call the content class! + return ('vevent-collection','http://groupdav.org/') + return None + + def _child_get(self, cr, name=None, domain=None): + dirobj = self.context._dirobj + + is_allowed = self.check_perms((name and 1) or 5) + if not is_allowed: + raise IOError(errno.EPERM,"Permission denied.") + + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + directory = dirobj.browse(cr, uid, self.dir_id) + obj = dirobj.pool.get(self.res_model) + where = [] + res = [] + if name: + where.append(('name','=',name)) + + # Directory Structure display in tree structure + if self.res_id and directory.ressource_tree: + where1 = [] + if name: + where1.append(('name','=like',name.replace('\\','\\\\'))) + if obj._parent_name in obj.fields_get(cr, uid): + where1.append((obj._parent_name, '=', self.res_id)) + namefield = directory.resource_field.name or 'name' + resids = obj.search(cr, uid, where1, context=ctx) + for bo in obj.browse(cr, uid, resids, context=ctx): + if not bo: + continue + res_name = getattr(bo, namefield) + if not res_name: + continue + res_name = res_name.replace('/', '_') + if name and (res_name != ustr(name)): + continue + # TODO Revise + klass = directory.get_node_class(directory, dynamic=True, context=ctx) + rnode = klass(res_name, dir_id=self.dir_id, parent=self, context=self.context, + res_model=self.res_model, res_bo=bo) + rnode.res_find_all = self.res_find_all + res.append(rnode) + + + where2 = where + [('parent_id','=',self.dir_id) ] + ids = dirobj.search(cr, uid, where2, context=ctx) + bo = obj.browse(cr, uid, self.res_id, context=ctx) + + for dirr in dirobj.browse(cr, uid, ids, context=ctx): + if name and (name != dirr.name): + continue + if dirr.type == 'directory': + klass = dirr.get_node_class(dirr, dynamic=True, context=ctx) + res.append(klass(dirr.name, dirr.id, self, self.context, self.res_model, res_bo = bo, res_id = self.res_id)) + elif dirr.type == 'ressource': + # child resources can be controlled by properly set dctx + klass = dirr.get_node_class(dirr, context=ctx) + res.append(klass(dirr.name,self,self.context, dirr, {'active_id': self.res_id})) # bo? + + fil_obj = dirobj.pool.get('ir.attachment') + if self.res_find_all: + where2 = where + where3 = where2 + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)] + # print "where clause for dir_obj", where3 + ids = fil_obj.search(cr, uid, where3, context=ctx) + if ids: + for fil in fil_obj.browse(cr, uid, ids, context=ctx): + klass = self.context.node_file_class + res.append(klass(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), ('ressource_id','=',self.res_id)] + 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: + klass = dirr.get_node_class(dirr, dynamic=True, context=ctx) + rnode = klass(dirr.name, dirr.id, self, self.context, self.res_model, res_bo = bo, res_id = self.res_id) + rnode.res_find_all = dirr.resource_find_all + res.append(rnode) + if dirr.type == 'ressource': + klass = dirr.get_node_class(dirr, context=ctx) + rnode = klass(dirr.name, self, self.context, dirr, {'active_id': self.res_id}) + rnode.res_find_all = dirr.resource_find_all + res.append(rnode) + return res + + def create_child_collection(self, cr, objname): + dirobj = self.context._dirobj + is_allowed = self.check_perms(2) + if not is_allowed: + raise IOError(errno.EPERM,"Permission denied.") + + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + res_obj = dirobj.pool.get(self.res_model) + + object2 = res_obj.browse(cr, uid, self.res_id) or False + + obj = dirobj.browse(cr, uid, self.dir_id) + if obj and (obj.type == 'ressource') and not object2: + raise OSError(1, 'Operation is not permitted.') + + + val = { + 'name': objname, + 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False, + 'ressource_id': object2 and object2.id or False, + 'parent_id' : False, + 'resource_find_all': False, + } + if (obj and (obj.type in ('directory'))) or not object2: + val['parent_id'] = obj and obj.id or False + + return dirobj.create(cr, uid, val) + + def create_child(self, cr, path, data=None): + """ API function to create a child file object and node + Return the node_* created + """ + is_allowed = self.check_perms(2) + if not is_allowed: + raise IOError(errno.EPERM,"Permission denied.") + + 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, + 'res_model': self.res_model, + 'res_id': self.res_id, + # Datas are not set here + } + if not self.res_find_all: + val['parent_id'] = self.dir_id + + fil_id = fil_obj.create(cr, uid, val, context=ctx) + fil = fil_obj.browse(cr, uid, fil_id, context=ctx) + klass = self.context.node_file_class + fnode = klass(path, self, self.context, fil) + if data is not None: + fnode.set_data(cr, data, fil) + return fnode + + def _get_ttag(self, cr): + return 'rodir-%d-%d' % (self.dir_id, self.res_id) + +node_res_dir.res_obj_class = node_res_obj + +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 = str(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 + + self.uidperms = 14 + if parent: + if not parent.check_perms('x'): + self.uidperms = 0 + elif not parent.check_perms('w'): + self.uidperms = 4 + + try: + self.uuser = (fil.user_id and fil.user_id.login) or 'nobody' + except Exception: + self.uuser = 'nobody' + self.ugroup = mkdosname(fil.company_id and fil.company_id.name, default='nogroup') + + def __eq__(self, other): + if type(self) != type(other): + return False + if not self.context == other.context: + return False + if self.dctx != other.dctx: + return False + return self.file_id == other.file_id + + def open_data(self, cr, mode): + if not self.check_perms(4): + raise IOError(errno.EPERM, "Permission denied.") + + stobj = self.context._dirobj.pool.get('document.storage') + return stobj.get_file(cr, self.context.uid, None, self, mode=mode, context=self.context.context) + + def rm(self, cr): + uid = self.context.uid + if not self.check_perms(8): + raise IOError(errno.EPERM, "Permission denied.") + document_obj = self.context._dirobj.pool.get('ir.attachment') + if self.type in ('collection','database'): + return False + document = document_obj.browse(cr, uid, self.file_id, context=self.context.context) + res = False + if document and document._table_name == 'ir.attachment': + res = document_obj.unlink(cr, uid, [document.id]) + return res + + def fix_ppath(self, cr, fbro): + """Sometimes we may init this w/o path, parent. + This function fills the missing path from the file browse object + + Note: this may be an expensive operation, do on demand. However, + once caching is in, we might want to do that at init time and keep + this object anyway + """ + if self.path or self.parent: + return + assert fbro + uid = self.context.uid + + dirpath = [] + if fbro.parent_id: + dirobj = self.context._dirobj.pool.get('document.directory') + dirpath = dirobj.get_full_path(cr, uid, fbro.parent_id.id, context=self.context.context) + if fbro.datas_fname: + dirpath.append(fbro.datas_fname) + else: + dirpath.append(fbro.name) + + if len(dirpath)>1: + self.path = dirpath + else: + self.path = dirpath[0] + + 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. """ + if not self.check_perms(4): + raise IOError(errno.EPERM, "Permission denied.") + + stobj = self.context._dirobj.pool.get('document.storage') + return stobj.get_data(cr, self.context.uid, None, self,self.context.context, fil_obj) + + def get_data_len(self, cr, fil_obj=None): + bin_size = self.context.context.get('bin_size', False) + if bin_size and not self.content_length: + self.content_length = fil_obj.db_datas + 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. """ + if not self.check_perms(2): + raise IOError(errno.EPERM, "Permission denied.") + + stobj = self.context._dirobj.pool.get('document.storage') + return stobj.set_data(cr, self.context.uid, None, self, data, self.context.context, fil_obj) + + def _get_ttag(self, cr): + return 'file-%d' % self.file_id + + def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): + if ndir_node and ndir_node.context != self.context: + raise NotImplementedError("Cannot move files between contexts.") + + if (not self.check_perms(8)) and ndir_node.check_perms(2): + raise IOError(errno.EPERM, "Permission denied.") + + doc_obj = self.context._dirobj.pool.get('ir.attachment') + if not fil_obj: + dbro = doc_obj.browse(cr, self.context.uid, self.file_id, context=self.context.context) + else: + dbro = fil_obj + assert dbro.id == self.file_id, "%s != %s for %r." % (dbro.id, self.file_id, self) + + if not dbro: + raise IndexError("Cannot locate doc %d.", self.file_id) + + if (not self.parent): + # there *must* be a parent node for this one + self.parent = self.context.get_dir_node(cr, dbro.parent_id) + assert self.parent + + ret = {} + if ndir_node and self.parent != ndir_node: + if not (isinstance(self.parent, node_dir) and isinstance(ndir_node, node_dir)): + _logger.debug('Cannot move file %r from %r to %r.', self, self.parent, ndir_node) + raise NotImplementedError('Cannot move files between dynamic folders.') + + if not ndir_obj: + ndir_obj = self.context._dirobj.browse(cr, self.context.uid, \ + ndir_node.dir_id, context=self.context.context) + + assert ndir_obj.id == ndir_node.dir_id + + r2 = { 'parent_id': ndir_obj.id } + ret.update(r2) + + if new_name and (new_name != dbro.name): + if len(ret): + raise NotImplementedError("Cannot rename and move.") # TODO + r2 = { 'name': new_name, 'datas_fname': new_name } + ret.update(r2) + + del dbro + + if not in_write: + # We have to update the data ourselves + if ret: + ctx = self.context.context.copy() + ctx['__from_node'] = True + doc_obj.write(cr, self.context.uid, [self.file_id,], ret, ctx ) + ret = True + + return ret + +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.unixperms = 0640 + if parent: + self.uidperms = parent.uidperms & 14 + self.uuser = parent.uuser + self.ugroup = parent.ugroup + + 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 = str(res[0][0]) + + def get_data(self, cr, fil_obj=None): + cntobj = self.context._dirobj.pool.get('document.directory.content') + if not self.check_perms(4): + raise IOError(errno.EPERM, "Permission denied.") + + 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 open_data(self, cr, mode): + if mode.endswith('b'): + mode = mode[:-1] + if mode in ('r', 'w'): + cperms = mode[:1] + elif mode in ('r+', 'w+'): + cperms = 'rw' + else: + raise IOError(errno.EINVAL, "Cannot open at mode %s." % mode) + + if not self.check_perms(cperms): + raise IOError(errno.EPERM, "Permission denied.") + + ctx = self.context.context.copy() + ctx.update(self.dctx) + + return nodefd_content(self, cr, mode, ctx) + + def get_data_len(self, cr, fil_obj=None): + # FIXME : here, we actually generate the content twice!! + # we should have cached the generated content, but it is + # not advisable to do keep it in memory, until we have a cache + # expiration logic. + 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') + if not self.check_perms(2): + raise IOError(errno.EPERM, "Permission denied.") + + 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 '') + + def get_dav_resourcetype(self, cr): + return '' + +class node_descriptor(object): + """A file-like interface to the data contents of a node. + + This class is NOT a node, but an /open descriptor/ for some + node. It can hold references to a cursor or a file object, + because the life of a node_descriptor will be the open period + of the data. + It should also take care of locking, with any native mechanism + or using the db. + For the implementation, it would be OK just to wrap around file, + StringIO or similar class. The node_descriptor is only needed to + provide the link to the parent /node/ object. + """ + + def __init__(self, parent): + assert isinstance(parent, node_class) + self.name = parent.displayname + self.__parent = parent + + def _get_parent(self): + return self.__parent + + def open(self, **kwargs): + raise NotImplementedError + + def close(self): + raise NotImplementedError + + def read(self, size=None): + raise NotImplementedError + + def seek(self, offset, whence=None): + raise NotImplementedError + + def tell(self): + raise NotImplementedError + + def write(self, str): + raise NotImplementedError + + def size(self): + raise NotImplementedError + + def __len__(self): + return self.size() + + def __nonzero__(self): + """ Ensure that a node_descriptor will never equal False + + Since we do define __len__ and __iter__ for us, we must avoid + being regarded as non-true objects. + """ + return True + + def next(self, str): + raise NotImplementedError + +class nodefd_content(StringIO, node_descriptor): + """ A descriptor to content nodes + """ + def __init__(self, parent, cr, mode, ctx): + node_descriptor.__init__(self, parent) + self._context=ctx + self._size = 0L + + if mode in ('r', 'r+'): + cntobj = parent.context._dirobj.pool.get('document.directory.content') + data = cntobj.process_read(cr, parent.context.uid, parent, ctx) + if data: + self._size = len(data) + parent.content_length = len(data) + StringIO.__init__(self, data) + elif mode in ('w', 'w+'): + StringIO.__init__(self, None) + # at write, we start at 0 (= overwrite), but have the original + # data available, in case of a seek() + elif mode == 'a': + StringIO.__init__(self, None) + else: + _logger.error("Incorrect mode %s is specified.", mode) + raise IOError(errno.EINVAL, "Invalid file mode.") + self.mode = mode + + def size(self): + return self._size + + def close(self): + # we now open a *separate* cursor, to update the data. + # FIXME: this may be improved, for concurrency handling + if self.mode == 'r': + StringIO.close(self) + return + + par = self._get_parent() + uid = par.context.uid + cr = pooler.get_db(par.context.dbname).cursor() + try: + if self.mode in ('w', 'w+', 'r+'): + data = self.getvalue() + cntobj = par.context._dirobj.pool.get('document.directory.content') + cntobj.process_write(cr, uid, par, data, par.context.context) + elif self.mode == 'a': + raise NotImplementedError + cr.commit() + except Exception: + _logger.exception('Cannot update db content #%d for close.', par.cnt_id) + raise + finally: + cr.close() + StringIO.close(self) + +class nodefd_static(StringIO, node_descriptor): + """ A descriptor to nodes with static data. + """ + def __init__(self, parent, cr, mode, ctx=None): + node_descriptor.__init__(self, parent) + self._context=ctx + self._size = 0L + + if mode in ('r', 'r+'): + data = parent.get_data(cr) + if data: + self._size = len(data) + parent.content_length = len(data) + StringIO.__init__(self, data) + elif mode in ('w', 'w+'): + StringIO.__init__(self, None) + # at write, we start at 0 (= overwrite), but have the original + # data available, in case of a seek() + elif mode == 'a': + StringIO.__init__(self, None) + else: + _logger.error("Incorrect mode %s is specified.", mode) + raise IOError(errno.EINVAL, "Invalid file mode.") + self.mode = mode + + def size(self): + return self._size + + def close(self): + # we now open a *separate* cursor, to update the data. + # FIXME: this may be improved, for concurrency handling + if self.mode == 'r': + StringIO.close(self) + return + + par = self._get_parent() + # uid = par.context.uid + cr = pooler.get_db(par.context.dbname).cursor() + try: + if self.mode in ('w', 'w+', 'r+'): + data = self.getvalue() + par.set_data(cr, data) + elif self.mode == 'a': + raise NotImplementedError + cr.commit() + except Exception: + _logger.exception('Cannot update db content #%d for close.', par.cnt_id) + raise + finally: + cr.close() + StringIO.close(self) + +class nodefd_db(StringIO, node_descriptor): + """ A descriptor to db data + """ + def __init__(self, parent, ira_browse, mode): + node_descriptor.__init__(self, parent) + self._size = 0L + if mode.endswith('b'): + mode = mode[:-1] + + if mode in ('r', 'r+'): + data = ira_browse.datas + print "READ64",data + if data: + data = data.decode('base64') + print "READ",data + self._size = len(data) + StringIO.__init__(self, data) + elif mode in ('w', 'w+'): + StringIO.__init__(self, None) + # at write, we start at 0 (= overwrite), but have the original + # data available, in case of a seek() + elif mode == 'a': + StringIO.__init__(self, None) + else: + _logger.error("Incorrect mode %s is specified.", mode) + raise IOError(errno.EINVAL, "Invalid file mode.") + self.mode = mode + + def size(self): + return self._size + + def close(self): + # we now open a *separate* cursor, to update the data. + # FIXME: this may be improved, for concurrency handling + par = self._get_parent() + # uid = par.context.uid + registry = openerp.modules.registry.RegistryManager.get(par.context.dbname) + with registry.cursor() as cr: + data = self.getvalue().encode('base64') + if self.mode in ('w', 'w+', 'r+'): + registry.get('ir.attachment').write(cr, 1, par.file_id, {'datas': data}) + cr.commit() + StringIO.close(self) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/document_data.xml b/addons/document/document_data.xml index a7bc98de6f3..ca3a2ed7144 100644 --- a/addons/document/document_data.xml +++ b/addons/document/document_data.xml @@ -1,17 +1,9 @@ - - - Database storage - db - - - Documents - 0 @@ -20,7 +12,6 @@ 0 - @@ -101,8 +92,5 @@ 0 - - diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py deleted file mode 100644 index 58492b87222..00000000000 --- a/addons/document/document_directory.py +++ /dev/null @@ -1,308 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 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 logging -import nodes -from tools.translate import _ -_logger = logging.getLogger(__name__) -class document_directory(osv.osv): - _name = 'document.directory' - _description = 'Directory' - _order = 'name' - _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), - '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', change_default=True), - 'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'), - 'parent_id': fields.many2one('document.directory', 'Parent Directory', select=1, change_default=True), - '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','Folders per resource'), - ], - 'Type', required=True, select=1, change_default=True, - help="Each directory can either have the type Static or be linked to another resource. A static directory, as with Operating Systems, is the classic directory that can contain a set of files. The directories linked to systems resources automatically possess sub-directories for each of resource types defined in the parent directory."), - 'ressource_type_id': fields.many2one('ir.model', 'Resource model', change_default=True, - help="Select an object here and there will be one folder per record of that resource."), - 'resource_field': fields.many2one('ir.model.fields', 'Name field', help='Field to be used as name on resource directories. If empty, the "name" will be used.'), - 'resource_find_all': fields.boolean('Find all resources', - help="If true, all attachments that match this resource will " \ - " be located. If false, only ones that have this as parent." ), - 'ressource_parent_type_id': fields.many2one('ir.model', 'Parent Model', change_default=True, - help="If you put an object here, this directory template will appear bellow all of these objects. " \ - "Such directories are \"attached\" to the specific model or record, just like attachments. " \ - "Don't put a parent directory if you select a parent model."), - 'ressource_id': fields.integer('Resource ID', - help="Along with Parent Model, this ID attaches this folder to a specific record of Parent Model."), - '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'), - 'company_id': fields.many2one('res.company', 'Company', change_default=True), - } - - - 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 False - root_id = objid.read(cr, uid, mid, ['res_id'])['res_id'] - return root_id - except Exception: - return False - 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 = { - 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'document.directory', context=c), - 'user_id': lambda self,cr,uid,ctx: uid, - 'domain': '[]', - 'type': 'directory', - 'ressource_id': 0, - 'storage_id': _get_def_storage, # Still, it is bad practice to set it everywhere. - 'resource_find_all': True, - } - _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!'), - ('dir_parented', 'check(parent_id IS NOT NULL OR storage_id IS NOT NULL)', 'Directory must have a parent or a storage.') - ] - def name_get(self, cr, uid, ids, context=None): - res = [] - if not self.search(cr,uid,[('id','in',ids)]): - ids = [] - for d in self.browse(cr, uid, ids, context=context): - s = '' - d2 = d - while d2 and d2.parent_id: - s = d2.name + (s and ('/' + s) or '') - d2 = d2.parent_id - res.append((d.id, s or d.name)) - return res - - def get_full_path(self, cr, uid, dir_id, context=None): - """ Return the full path to this directory, in a list, root first - """ - if isinstance(dir_id, (tuple, list)): - assert len(dir_id) == 1 - dir_id = dir_id[0] - - 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 - path = [] - _parent(dir_id, path) - return path - - def _check_recursion(self, cr, uid, ids, context=None): - 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 cannot create recursive directories.', ['parent_id']) - ] - - def __init__(self, *args, **kwargs): - super(document_directory, self).__init__(*args, **kwargs) - - 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 - """ - - return nodes.get_node_context(cr, uid, context).get_uri(cr, uri) - - def get_node_class(self, cr, uid, ids, dbro=None, dynamic=False, context=None): - """Retrieve the class of nodes for this directory - - This function can be overriden by inherited classes ;) - @param dbro The browse object, if caller already has it - """ - if dbro is None: - dbro = self.browse(cr, uid, ids, context=context) - - if dynamic: - return nodes.node_res_obj - elif dbro.type == 'directory': - return nodes.node_dir - elif dbro.type == 'ressource': - return nodes.node_res_dir - else: - raise ValueError("dir node for %s type.", dbro.type) - - def _prepare_context(self, cr, uid, nctx, context=None): - """ Fill nctx with properties for this database - @param nctx instance of nodes.node_context, to be filled - @param context ORM context (dict) for us - - Note that this function is called *without* a list of ids, - it should behave the same for the whole database (based on the - ORM instance of document.directory). - - Some databases may override this and attach properties to the - node_context. See WebDAV, CalDAV. - """ - return - - def get_dir_permissions(self, cr, uid, ids, context=None): - """Check what permission user 'uid' has on directory 'id' - """ - assert len(ids) == 1 - - res = 0 - for pperms in [('read', 5), ('write', 2), ('unlink', 8)]: - try: - self.check_access_rule(cr, uid, ids, pperms[0], context=context) - res |= pperms[1] - except except_orm: - pass - return res - - 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) - """ - return (nodes.node_database(context=ncontext), uri) - - 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=_("%s (copy)") % (name)) - return super(document_directory,self).copy(cr, uid, id, default, context=context) - - def _check_duplication(self, cr, uid, vals, ids=None, 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 - # TODO fix algo - 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!')) - newname = vals.get('name',False) - if newname: - for illeg in ('/', '@', '$', '#'): - if illeg in newname: - raise osv.except_osv(_('ValidateError'), _('Directory name contains special characters!')) - return super(document_directory,self).create(cr, uid, vals, context) - - # TODO def unlink(... - -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, ondelete="cascade"), - '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() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py deleted file mode 100644 index 9ad70497b2b..00000000000 --- a/addons/document/document_storage.py +++ /dev/null @@ -1,278 +0,0 @@ -# -*- 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 -import errno -import logging -import shutil -from StringIO import StringIO -import psycopg2 -from tools.misc import ustr -from tools.translate import _ -from osv.orm import except_orm -import random -import string -import pooler -import nodes -from content_index import cntIndex -_logger = logging.getLogger(__name__) - -""" 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 need 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). - -""" - -class nodefd_db(StringIO, nodes.node_descriptor): - """ A descriptor to db data - """ - def __init__(self, parent, ira_browse, mode): - nodes.node_descriptor.__init__(self, parent) - self._size = 0L - if mode.endswith('b'): - mode = mode[:-1] - - if mode in ('r', 'r+'): - data = ira_browse.datas - if data: - self._size = len(data) - StringIO.__init__(self, data) - elif mode in ('w', 'w+'): - StringIO.__init__(self, None) - # at write, we start at 0 (= overwrite), but have the original - # data available, in case of a seek() - elif mode == 'a': - StringIO.__init__(self, None) - else: - _logger.error("Incorrect mode %s is specified.", mode) - raise IOError(errno.EINVAL, "Invalid file mode.") - self.mode = mode - - def size(self): - return self._size - - def close(self): - # we now open a *separate* cursor, to update the data. - # FIXME: this may be improved, for concurrency handling - par = self._get_parent() - # uid = par.context.uid - cr = pooler.get_db(par.context.dbname).cursor() - try: - if self.mode in ('w', 'w+', 'r+'): - data = self.getvalue() - icont = '' - mime = '' - filename = par.path - if isinstance(filename, (tuple, list)): - filename = '/'.join(filename) - - try: - mime, icont = cntIndex.doIndex(data, filename=filename, - content_type=None, realfname=None) - except Exception: - _logger.debug('Cannot index file:', exc_info=True) - pass - - try: - icont_u = ustr(icont) - except UnicodeError: - icont_u = '' - - out = psycopg2.Binary(data) - cr.execute("UPDATE ir_attachment " \ - "SET db_datas = %s, file_size=%s, " \ - " index_content= %s, file_type=%s " \ - " WHERE id = %s", - (out, len(data), icont_u, mime, par.file_id)) - elif self.mode == 'a': - data = self.getvalue() - out = psycopg2.Binary(data) - cr.execute("UPDATE ir_attachment " \ - "SET db_datas = COALESCE(db_datas,'') || %s, " \ - " file_size = COALESCE(file_size, 0) + %s " \ - " WHERE id = %s", - (out, len(data), par.file_id)) - cr.commit() - except Exception: - _logger.exception('Cannot update db file #%d for close.', par.file_id) - raise - finally: - cr.close() - StringIO.close(self) - -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 = '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_storage_group_rel', 'item_id', 'group_id', 'Groups'), - 'dir_ids': fields.one2many('document.directory', 'parent_id', 'Directories'), - 'readonly': fields.boolean('Read Only', help="If set, media is for reading only"), - } - - _defaults = { - 'user_id': lambda self, cr, uid, ctx: uid, - } - - 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) - """ - boo = self.browse(cr, uid, id, context=context) - if fil_obj: - ira = fil_obj - else: - ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - data = ira.datas - if data: - out = data.decode('base64') - else: - out = '' - return out - - def get_file(self, cr, uid, id, file_node, mode, context=None): - """ Return a file-like object for the contents of some node - """ - if context is None: - context = {} - boo = self.browse(cr, uid, id, context=context) - - ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - return nodefd_db(file_node, ira_browse=ira, mode=mode) - - 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). - """ - boo = self.browse(cr, uid, id, context=context) - if fil_obj: - ira = fil_obj - else: - ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context) - - _logger.debug( "Store data for ir.attachment #%d." % ira.id) - store_fname = None - fname = None - filesize = len(data) - self.pool.get('ir.attachment').write(cr, uid, [file_node.file_id], {'datas': data.encode('base64')}, context=context) - # 2nd phase: store the metadata - try: - icont = '' - mime = ira.file_type - if not mime: - mime = "" - try: - mime, icont = cntIndex.doIndex(data, ira.datas_fname, ira.file_type or None, fname) - except Exception: - _logger.debug('Cannot index file.', exc_info=True) - pass - try: - icont_u = ustr(icont) - except UnicodeError: - icont_u = '' - # 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 file_size = %s, index_content = %s, file_type = %s WHERE id = %s', (filesize, icont_u, mime, file_node.file_id)) - file_node.content_length = filesize - file_node.content_type = mime - return True - except Exception, e : - self._logger.warning("Cannot save data.", exc_info=True) - # 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. """ - pass - - def do_unlink(self, cr, uid, unres): - return True - - def simple_rename(self, cr, uid, file_node, new_name, context=None): - """ A preparation for a file rename. - It will not affect the database, but merely check and perhaps - rename the realstore file. - - @return the dict of values that can safely be be stored in the db. - """ - # nothing to do for a rename, allow to change the db field - return { 'name': new_name, 'datas_fname': new_name } - - def simple_move(self, cr, uid, file_node, ndir_bro, context=None): - """ A preparation for a file move. - It will not affect the database, but merely check and perhaps - move the realstore file. - - @param ndir_bro a browse object of document.directory, where this - file should move to. - @return the dict of values that can safely be be stored in the db. - """ - return { 'parent_id': ndir_bro.id } - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document/document_view.xml b/addons/document/document_view.xml index 54776c4d36e..4c2456de827 100644 --- a/addons/document/document_view.xml +++ b/addons/document/document_view.xml @@ -3,64 +3,6 @@ - - document.storage - document.storage - -
- - - - - - - - - - -
-
-
- - - document.storage - document.storage - - - - - - - - - - Search View: Document Storage - document.storage - - - - - - - - - - - - Storage Media - ir.actions.act_window - document.storage - form - tree,form - - - - document.directory document.directory @@ -69,7 +11,6 @@ - @@ -153,7 +94,6 @@ - @@ -161,25 +101,23 @@ - Search View: Document Directory - document.directory - - - - - - - - - - - - - - - - - + Search View: Document Directory + document.directory + + + + + + + + + + + + + + + Directories @@ -268,10 +206,7 @@
- - - IR Attachment2 ir.attachment @@ -342,32 +277,6 @@ - - process.node.form - process.node - - - - - - - - - - - - process.process.form - process.process - - - - - - - - - - ). -# -# 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 urlparse -import pooler -from tools.safe_eval import safe_eval - -from tools.misc import ustr -import errno -# import os -import time -import logging - -from StringIO import StringIO - -# -# 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 -# -_logger = logging.getLogger(__name__) - -def _str2time(cre): - """ Convert a string with time representation (from db) into time (float) - - Note: a place to fix if datetime is used in db. - """ - if not cre: - return time.time() - frac = 0.0 - if isinstance(cre, basestring) and '.' in cre: - fdot = cre.find('.') - frac = float(cre[fdot:]) - cre = cre[:fdot] - return time.mktime(time.strptime(cre,'%Y-%m-%d %H:%M:%S')) + frac - -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 - - A context is a set of persistent data, which may influence the structure - of the nodes. All other transient information during a data query should - be passed down with function arguments. - """ - cached_roots = {} - node_file_class = None - - def __init__(self, cr, uid, context=None): - self.dbname = cr.dbname - self.uid = uid - self.context = context - if context is None: - context = {} - context['uid'] = uid - self._dirobj = pooler.get_pool(cr.dbname).get('document.directory') - self.node_file_class = node_file - self.extra_ctx = {} # Extra keys for context, that do _not_ trigger inequality - assert self._dirobj - self._dirobj._prepare_context(cr, uid, self, context=context) - self.rootdir = False #self._dirobj._get_root_directory(cr,uid,context) - - def __eq__(self, other): - if not type(other) == node_context: - return False - if self.dbname != other.dbname: - return False - if self.uid != other.uid: - return False - if self.context != other.context: - return False - if self.rootdir != other.rootdir: - return False - return True - - def __ne__(self, other): - return not self.__eq__(other) - - def get(self, name, default=None): - return self.context.get(name, default) - - 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 - - def get_dir_node(self, cr, dbro): - """Create (or locate) a node for a directory - @param dbro a browse object of document.directory - """ - - fullpath = dbro.get_full_path(context=self.context) - klass = dbro.get_node_class(dbro, context=self.context) - return klass(fullpath, None ,self, dbro) - - def get_file_node(self, cr, fbro): - """ Create or locate a node for a static file - @param fbro a browse object of an ir.attachment - """ - parent = None - if fbro.parent_id: - parent = self.get_dir_node(cr, fbro.parent_id) - - return self.node_file_class(fbro.name, parent, self, fbro) - -class node_descriptor(object): - """A file-like interface to the data contents of a node. - - This class is NOT a node, but an /open descriptor/ for some - node. It can hold references to a cursor or a file object, - because the life of a node_descriptor will be the open period - of the data. - It should also take care of locking, with any native mechanism - or using the db. - For the implementation, it would be OK just to wrap around file, - StringIO or similar class. The node_descriptor is only needed to - provide the link to the parent /node/ object. - """ - - def __init__(self, parent): - assert isinstance(parent, node_class) - self.name = parent.displayname - self.__parent = parent - - def _get_parent(self): - return self.__parent - - def open(self, **kwargs): - raise NotImplementedError - - def close(self): - raise NotImplementedError - - def read(self, size=None): - raise NotImplementedError - - def seek(self, offset, whence=None): - raise NotImplementedError - - def tell(self): - raise NotImplementedError - - def write(self, str): - raise NotImplementedError - - def size(self): - raise NotImplementedError - - def __len__(self): - return self.size() - - def __nonzero__(self): - """ Ensure that a node_descriptor will never equal False - - Since we do define __len__ and __iter__ for us, we must avoid - being regarded as non-true objects. - """ - return True - - def next(self, str): - raise NotImplementedError - -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' - DAV_PROPS = None - DAV_M_NS = None - - 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.uidperms = 5 # computed permissions for our uid, in unix bits - self.mimetype = 'application/octet-stream' - self.create_date = None - self.write_date = None - self.unixperms = 0660 - self.uuser = 'user' - self.ugroup = 'group' - self.content_length = 0 - # dynamic context: - self.dctx = {} - if parent: - self.dctx = parent.dctx.copy() - self.displayname = 'Object' - - def __eq__(self, other): - return NotImplemented - - def __ne__(self, other): - return not self.__eq__(other) - - def full_path(self): - """ Return the components of the full path for some - node. - The returned list only contains the names of nodes. - """ - if self.parent: - s = self.parent.full_path() - else: - s = [] - if isinstance(self.path,list): - s+=self.path - elif self.path is None: - s.append('') - else: - s.append(self.path) - return s #map(lambda x: '/' +x, s) - - def __repr__(self): - return "%s@/%s" % (self.our_type, '/'.join(self.full_path())) - - def children(self, cr, domain=None): - print "node_class.children()" - return [] #stub - - def child(self, cr, name, domain=None): - print "node_class.child()" - return None - - def get_uri(self, cr, uri): - duri = uri - ndir = self - while duri: - ndir = ndir.child(cr, duri[0]) - if not ndir: - return False - duri = duri[1:] - return ndir - - 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 open_data(self, cr, mode): - """ Open a node_descriptor object for this node. - - @param the mode of open, eg 'r', 'w', 'a', like file.open() - - This operation may lock the data for this node (and accross - other node hierarchies), until the descriptor is close()d. If - the node is locked, subsequent opens (depending on mode) may - immediately fail with an exception (which?). - For this class, there is no data, so no implementation. Each - child class that has data should override this. - """ - 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 '"%s-%s"' % (self._get_ttag(cr), self._get_wtag(cr)) - - def _get_wtag(self, cr): - """ Return the modification time as a unique, compact string """ - return str(_str2time(self.write_date)).replace('.','') - - 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 NotImplementedError("get_ttag stub()") - - def get_dav_props(self, cr): - """ If this class has special behaviour for GroupDAV etc, export - its capabilities """ - # This fn is placed here rather than WebDAV, because we want the - # baseclass methods to apply to all node subclasses - return self.DAV_PROPS or {} - - def match_dav_eprop(self, cr, match, ns, prop): - res = self.get_dav_eprop(cr, ns, prop) - if res == match: - return True - return False - - def get_dav_eprop(self, cr, ns, prop): - if not self.DAV_M_NS: - return None - - if self.DAV_M_NS.has_key(ns): - prefix = self.DAV_M_NS[ns] - else: - _logger.debug('No namespace: %s ("%s").',ns, prop) - return None - - mname = prefix + "_" + prop.replace('-','_') - - if not hasattr(self, mname): - return None - - try: - m = getattr(self, mname) - r = m(cr) - return r - except AttributeError: - _logger.debug('The property %s is not supported.' % prop, exc_info=True) - return None - - def get_dav_resourcetype(self, cr): - """ Get the DAV resource type. - - Is here because some nodes may exhibit special behaviour, like - CalDAV/GroupDAV collections - """ - raise NotImplementedError - - def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): - """ Move this node to a new parent directory. - @param ndir_node the collection that this node should be moved under - @param new_name a name to rename this node to. If omitted, the old - name is preserved - @param fil_obj, can be None, is the browse object for the file, - if already available. - @param ndir_obj must be the browse object to the new doc.directory - location, where this node should be moved to. - in_write: When called by write(), we shouldn't attempt to write the - object, but instead return the dict of vals (avoid re-entrance). - If false, we should write all data to the object, here, as if the - caller won't do anything after calling move_to() - - Return value: - True: the node is moved, the caller can update other values, too. - False: the node is either removed or fully updated, the caller - must discard the fil_obj, not attempt to write any more to it. - dict: values to write back to the object. *May* contain a new id! - - Depending on src and target storage, implementations of this function - could do various things. - Should also consider node<->content, dir<->dir moves etc. - - Move operations, as instructed from APIs (e.g. request from DAV) could - use this function. - """ - raise NotImplementedError(repr(self)) - - def create_child(self, cr, path, data=None): - """ Create a regular file under this node - """ - _logger.warning("Attempted to create a file under %r, not possible.", self) - raise IOError(errno.EPERM, "Not allowed to create file(s) here.") - - def create_child_collection(self, cr, objname): - """ Create a child collection (directory) under self - """ - _logger.warning("Attempted to create a collection under %r, not possible.", self) - raise IOError(errno.EPERM, "Not allowed to create folder(s) here.") - - def rm(self, cr): - raise NotImplementedError(repr(self)) - - def rmcol(self, cr): - raise NotImplementedError(repr(self)) - - def get_domain(self, cr, filters): - # TODO Document - return [] - - def check_perms(self, perms): - """ Check the permissions of the current node. - - @param perms either an integers of the bits to check, or - a string with the permission letters - - Permissions of nodes are (in a unix way): - 1, x : allow descend into dir - 2, w : allow write into file, or modification to dir - 4, r : allow read of file, or listing of dir contents - 8, u : allow remove (unlink) - """ - - if isinstance(perms, str): - pe2 = 0 - chars = { 'x': 1, 'w': 2, 'r': 4, 'u': 8 } - for c in perms: - pe2 = pe2 | chars[c] - perms = pe2 - elif isinstance(perms, int): - if perms < 0 or perms > 15: - raise ValueError("Invalid permission bits.") - else: - raise ValueError("Invalid permission attribute.") - - return ((self.uidperms & perms) == perms) - -class node_database(node_class): - """ A node representing the database directory - - """ - our_type = 'database' - def __init__(self, path=None, parent=False, context=None): - if path is None: - path = [] - super(node_database,self).__init__(path, parent, context) - self.unixperms = 040750 - self.uidperms = 5 - - def children(self, cr, domain=None): - res = self._child_get(cr, domain=domain) + self._file_get(cr) - return res - - def child(self, cr, name, domain=None): - res = self._child_get(cr, name, domain=None) - if res: - return res[0] - res = self._file_get(cr,name) - if res: - return res[0] - return None - - def _child_get(self, cr, name=False, domain=None): - dirobj = self.context._dirobj - uid = self.context.uid - ctx = self.context.context.copy() - ctx.update(self.dctx) - where = [('parent_id','=', False), ('ressource_parent_type_id','=',False)] - if name: - where.append(('name','=',name)) - is_allowed = self.check_perms(1) - else: - is_allowed = self.check_perms(5) - - if not is_allowed: - raise IOError(errno.EPERM, "Permission into directory denied.") - - if domain: - where = where + domain - ids = dirobj.search(cr, uid, where, context=ctx) - res = [] - for dirr in dirobj.browse(cr, uid, ids, context=ctx): - klass = dirr.get_node_class(dirr, context=ctx) - res.append(klass(dirr.name, self, self.context,dirr)) - - return res - - def _file_get(self, cr, nodename=False): - res = [] - return res - - def _get_ttag(self, cr): - return 'db-%s' % cr.dbname - -def mkdosname(company_name, default='noname'): - """ convert a string to a dos-like name""" - if not company_name: - return default - badchars = ' !@#$%^`~*()+={}[];:\'"/?.<>' - n = '' - for c in company_name[:8]: - n += (c in badchars and '_') or c - return n - - -def _uid2unixperms(perms, has_owner): - """ Convert the uidperms and the owner flag to full unix bits - """ - res = 0 - if has_owner: - res |= (perms & 0x07) << 6 - res |= (perms & 0x05) << 3 - elif perms & 0x02: - res |= (perms & 0x07) << 6 - res |= (perms & 0x07) << 3 - else: - res |= (perms & 0x07) << 6 - res |= (perms & 0x05) << 3 - res |= 0x05 - return res - -class node_dir(node_database): - our_type = 'collection' - def __init__(self, path, parent, context, dirr, dctx=None): - super(node_dir,self).__init__(path, parent,context) - self.dir_id = dirr and dirr.id or False - #todo: more info from dirr - self.mimetype = 'application/x-directory' - # 'httpd/unix-directory' - self.create_date = dirr and dirr.create_date or False - self.domain = dirr and dirr.domain or [] - self.res_model = dirr and 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 and (dirr.write_date or dirr.create_date) or False - self.content_length = 0 - try: - self.uuser = (dirr.user_id and dirr.user_id.login) or 'nobody' - except Exception: - self.uuser = 'nobody' - self.ugroup = mkdosname(dirr.company_id and dirr.company_id.name, default='nogroup') - self.uidperms = dirr.get_dir_permissions() - self.unixperms = 040000 | _uid2unixperms(self.uidperms, dirr and dirr.user_id) - if dctx: - self.dctx.update(dctx) - dc2 = self.context.context - dc2.update(self.dctx) - dc2['dir_id'] = self.dir_id - self.displayname = dirr and dirr.name or False - if dirr and dirr.dctx_ids: - 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 __eq__(self, other): - if type(self) != type(other): - return False - if not self.context == other.context: - return False - # Two directory nodes, for the same document.directory, may have a - # different context! (dynamic folders) - if self.dctx != other.dctx: - return False - return self.dir_id == other.dir_id - - def get_data(self, cr): - #res = '' - #for child in self.children(cr): - # res += child.get_data(cr) - return None - - def _file_get(self, cr, nodename=False): - res = super(node_dir,self)._file_get(cr, nodename) - - is_allowed = self.check_perms(nodename and 1 or 5) - if not is_allowed: - raise IOError(errno.EPERM, "Permission into directory denied.") - - 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 _child_get(self, cr, name=None, domain=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)) - is_allowed = self.check_perms(1) - else: - is_allowed = self.check_perms(5) - - if not is_allowed: - raise IOError(errno.EPERM, "Permission into directory denied.") - - if not domain: - domain = [] - - where2 = where + domain + [('ressource_parent_type_id','=',False)] - ids = dirobj.search(cr, uid, where2, context=ctx) - res = [] - for dirr in dirobj.browse(cr, uid, ids, context=ctx): - klass = dirr.get_node_class(dirr, context=ctx) - res.append(klass(dirr.name, self, self.context,dirr)) - - # Static directories should never return files with res_model/res_id - # because static dirs are /never/ related to a record. - # In fact, files related to some model and parented by the root dir - # (the default), will NOT be accessible in the node system unless - # a resource folder for that model exists (with resource_find_all=True). - # Having resource attachments in a common folder is bad practice, - # because they would be visible to all users, and their names may be - # the same, conflicting. - where += [('res_model', '=', False)] - fil_obj = dirobj.pool.get('ir.attachment') - ids = fil_obj.search(cr, uid, where, context=ctx) - if ids: - for fil in fil_obj.browse(cr, uid, ids, context=ctx): - klass = self.context.node_file_class - res.append(klass(fil.name, self, self.context, fil)) - return res - - def rmcol(self, cr): - uid = self.context.uid - directory = self.context._dirobj.browse(cr, uid, self.dir_id) - res = False - if not directory: - raise OSError(2, 'Not such file or directory.') - if not self.check_perms('u'): - raise IOError(errno.EPERM,"Permission denied.") - - if directory._table_name=='document.directory': - if self.children(cr): - raise OSError(39, 'Directory not empty.') - res = self.context._dirobj.unlink(cr, uid, [directory.id]) - else: - raise OSError(1, 'Operation is not permitted.') - return res - - def create_child_collection(self, cr, objname): - object2 = False - if not self.check_perms(2): - raise IOError(errno.EPERM,"Permission denied.") - - dirobj = self.context._dirobj - uid = self.context.uid - ctx = self.context.context.copy() - ctx.update(self.dctx) - obj = dirobj.browse(cr, uid, self.dir_id) - if obj and (obj.type == 'ressource') and not object2: - raise OSError(1, 'Operation is not permitted.') - - #objname = uri2[-1] - val = { - 'name': objname, - 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False, - 'ressource_id': object2 and object2.id or False, - 'parent_id' : obj and obj.id or False - } - - return dirobj.create(cr, uid, val) - - def create_child(self, cr, path, data=None): - """ API function to create a child file object and node - Return the node_* created - """ - if not self.check_perms(2): - raise IOError(errno.EPERM,"Permission denied.") - - 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) - if data is not None: - fnode.set_data(cr, data, fil) - return fnode - - def _get_ttag(self, cr): - return 'dir-%d' % self.dir_id - - def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): - """ Move directory. This operation is simple, since the present node is - only used for static, simple directories. - Note /may/ be called with ndir_node = None, to rename the document root. - """ - if ndir_node and (ndir_node.context != self.context): - raise NotImplementedError("Cannot move directories between contexts.") - - if (not self.check_perms('u')) or (not ndir_node.check_perms('w')): - raise IOError(errno.EPERM,"Permission denied.") - - dir_obj = self.context._dirobj - if not fil_obj: - dbro = dir_obj.browse(cr, self.context.uid, self.dir_id, context=self.context.context) - else: - dbro = dir_obj - assert dbro.id == self.dir_id - - if not dbro: - raise IndexError("Cannot locate dir %d", self.dir_id) - - if (not self.parent) and ndir_node: - if not dbro.parent_id: - raise IOError(errno.EPERM, "Cannot move the root directory!") - self.parent = self.context.get_dir_node(cr, dbro.parent_id) - assert self.parent - - if self.parent != ndir_node: - _logger.debug('Cannot move dir %r from %r to %r.', self, self.parent, ndir_node) - raise NotImplementedError('Cannot move dir to another dir.') - - ret = {} - if new_name and (new_name != dbro.name): - if ndir_node.child(cr, new_name): - raise IOError(errno.EEXIST, "Destination path already exists.") - ret['name'] = new_name - - del dbro - - if not in_write: - # We have to update the data ourselves - if ret: - ctx = self.context.context.copy() - ctx['__from_node'] = True - dir_obj.write(cr, self.context.uid, [self.dir_id,], ret, ctx) - ret = True - - return ret - -class node_res_dir(node_class): - """ A folder containing dynamic folders - 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' - res_obj_class = None - 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 - try: - self.uuser = (dirr.user_id and dirr.user_id.login) or 'nobody' - except Exception: - self.uuser = 'nobody' - self.ugroup = mkdosname(dirr.company_id and dirr.company_id.name, default='nogroup') - self.uidperms = dirr.get_dir_permissions() - self.unixperms = 040000 | _uid2unixperms(self.uidperms, dirr and dirr.user_id) - self.res_model = dirr.ressource_type_id and dirr.ressource_type_id.model or False - self.resm_id = dirr.ressource_id - self.res_find_all = dirr.resource_find_all - self.namefield = dirr.resource_field.name or 'name' - self.displayname = dirr.name - # 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: - 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 __eq__(self, other): - if type(self) != type(other): - return False - if not self.context == other.context: - return False - # Two nodes, for the same document.directory, may have a - # different context! (dynamic folders) - if self.dctx != other.dctx: - return False - return self.dir_id == other.dir_id - - def children(self, cr, domain=None): - return self._child_get(cr, domain=domain) - - def child(self, cr, name, domain=None): - res = self._child_get(cr, name, domain=domain) - if res: - return res[0] - return None - - def _child_get(self, cr, name=None, domain=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: - return [] - dirobj = self.context._dirobj - uid = self.context.uid - ctx = self.context.context.copy() - ctx.update(self.dctx) - ctx.update(self.context.extra_ctx) - where = [] - if self.domain: - app = safe_eval(self.domain, ctx) - if not app: - pass - elif isinstance(app, list): - where.extend(app) - elif isinstance(app, tuple): - where.append(app) - else: - raise RuntimeError("Incorrect domain expr: %s." % self.domain) - if self.resm_id: - where.append(('id','=',self.resm_id)) - - if name: - # The =like character will match underscores against any characters - # including the special ones that couldn't exist in a FTP/DAV request - where.append((self.namefield,'=like',name.replace('\\','\\\\'))) - is_allowed = self.check_perms(1) - else: - is_allowed = self.check_perms(5) - - if not is_allowed: - raise IOError(errno.EPERM,"Permission denied.") - - # 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 = [] - for bo in obj.browse(cr, uid, resids, context=ctx): - if not bo: - continue - res_name = getattr(bo, self.namefield) - if not res_name: - continue - # Yes! we can't do better but skip nameless records. - - # Escape the name for characters not supported in filenames - res_name = res_name.replace('/','_') # any other weird char? - - if name and (res_name != ustr(name)): - # we have matched _ to any character, but we only meant to match - # the special ones. - # Eg. 'a_c' will find 'abc', 'a/c', 'a_c', may only - # return 'a/c' and 'a_c' - continue - - res.append(self.res_obj_class(res_name, self.dir_id, 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 dynamically created folder. - 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, 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 = 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.uidperms = parent.uidperms & 15 - self.unixperms = 040000 | _uid2unixperms(self.uidperms, True) - self.uuser = parent.uuser - self.ugroup = parent.ugroup - self.res_model = res_model - self.domain = parent.domain - self.displayname = path - self.dctx_dict = parent.dctx_dict - if isinstance(parent, node_res_dir): - self.res_find_all = parent.res_find_all - else: - self.res_find_all = False - if res_bo: - self.res_id = res_bo.id - dc2 = self.context.context.copy() - dc2.update(self.dctx) - dc2['res_model'] = res_model - dc2['res_id'] = res_bo.id - dc2['this'] = res_bo - for fld,expr in self.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 __eq__(self, other): - if type(self) != type(other): - return False - if not self.context == other.context: - return False - if not self.res_model == other.res_model: - return False - if not self.res_id == other.res_id: - return False - if self.domain != other.domain: - return False - if self.res_find_all != other.res_find_all: - return False - if self.dctx != other.dctx: - return False - return self.dir_id == other.dir_id - - def children(self, cr, domain=None): - return self._child_get(cr, domain=domain) + self._file_get(cr) - - def child(self, cr, name, domain=None): - res = self._child_get(cr, name, domain=domain) - 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 = [] - is_allowed = self.check_perms((nodename and 1) or 5) - if not is_allowed: - raise IOError(errno.EPERM,"Permission denied.") - - 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_DEPR(self, cr): - # Deprecated! (but document_ics must be cleaned, first) - 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_DEPR(self, cr, ns, prop): - # Deprecated! - if ns != 'http://groupdav.org/' or prop != 'resourcetype': - _logger.warning("Who asks for %s:%s?" % (ns, prop)) - return None - 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): - # TODO: remove relic of GroupDAV - if content.extension == '.ics': # FIXME: call the content class! - return ('vevent-collection','http://groupdav.org/') - return None - - def _child_get(self, cr, name=None, domain=None): - dirobj = self.context._dirobj - - is_allowed = self.check_perms((name and 1) or 5) - if not is_allowed: - raise IOError(errno.EPERM,"Permission denied.") - - uid = self.context.uid - ctx = self.context.context.copy() - ctx.update(self.dctx) - directory = dirobj.browse(cr, uid, self.dir_id) - obj = dirobj.pool.get(self.res_model) - where = [] - res = [] - if name: - where.append(('name','=',name)) - - # Directory Structure display in tree structure - if self.res_id and directory.ressource_tree: - where1 = [] - if name: - where1.append(('name','=like',name.replace('\\','\\\\'))) - if obj._parent_name in obj.fields_get(cr, uid): - where1.append((obj._parent_name, '=', self.res_id)) - namefield = directory.resource_field.name or 'name' - resids = obj.search(cr, uid, where1, context=ctx) - for bo in obj.browse(cr, uid, resids, context=ctx): - if not bo: - continue - res_name = getattr(bo, namefield) - if not res_name: - continue - res_name = res_name.replace('/', '_') - if name and (res_name != ustr(name)): - continue - # TODO Revise - klass = directory.get_node_class(directory, dynamic=True, context=ctx) - rnode = klass(res_name, dir_id=self.dir_id, parent=self, context=self.context, - res_model=self.res_model, res_bo=bo) - rnode.res_find_all = self.res_find_all - res.append(rnode) - - - where2 = where + [('parent_id','=',self.dir_id) ] - ids = dirobj.search(cr, uid, where2, context=ctx) - bo = obj.browse(cr, uid, self.res_id, context=ctx) - - for dirr in dirobj.browse(cr, uid, ids, context=ctx): - if name and (name != dirr.name): - continue - if dirr.type == 'directory': - klass = dirr.get_node_class(dirr, dynamic=True, context=ctx) - res.append(klass(dirr.name, dirr.id, self, self.context, self.res_model, res_bo = bo, res_id = self.res_id)) - elif dirr.type == 'ressource': - # child resources can be controlled by properly set dctx - klass = dirr.get_node_class(dirr, context=ctx) - res.append(klass(dirr.name,self,self.context, dirr, {'active_id': self.res_id})) # bo? - - fil_obj = dirobj.pool.get('ir.attachment') - if self.res_find_all: - where2 = where - where3 = where2 + [('res_model', '=', self.res_model), ('res_id','=',self.res_id)] - # print "where clause for dir_obj", where3 - ids = fil_obj.search(cr, uid, where3, context=ctx) - if ids: - for fil in fil_obj.browse(cr, uid, ids, context=ctx): - klass = self.context.node_file_class - res.append(klass(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), ('ressource_id','=',self.res_id)] - 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: - klass = dirr.get_node_class(dirr, dynamic=True, context=ctx) - rnode = klass(dirr.name, dirr.id, self, self.context, self.res_model, res_bo = bo, res_id = self.res_id) - rnode.res_find_all = dirr.resource_find_all - res.append(rnode) - if dirr.type == 'ressource': - klass = dirr.get_node_class(dirr, context=ctx) - rnode = klass(dirr.name, self, self.context, dirr, {'active_id': self.res_id}) - rnode.res_find_all = dirr.resource_find_all - res.append(rnode) - return res - - def create_child_collection(self, cr, objname): - dirobj = self.context._dirobj - is_allowed = self.check_perms(2) - if not is_allowed: - raise IOError(errno.EPERM,"Permission denied.") - - uid = self.context.uid - ctx = self.context.context.copy() - ctx.update(self.dctx) - res_obj = dirobj.pool.get(self.res_model) - - object2 = res_obj.browse(cr, uid, self.res_id) or False - - obj = dirobj.browse(cr, uid, self.dir_id) - if obj and (obj.type == 'ressource') and not object2: - raise OSError(1, 'Operation is not permitted.') - - - val = { - 'name': objname, - 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False, - 'ressource_id': object2 and object2.id or False, - 'parent_id' : False, - 'resource_find_all': False, - } - if (obj and (obj.type in ('directory'))) or not object2: - val['parent_id'] = obj and obj.id or False - - return dirobj.create(cr, uid, val) - - def create_child(self, cr, path, data=None): - """ API function to create a child file object and node - Return the node_* created - """ - is_allowed = self.check_perms(2) - if not is_allowed: - raise IOError(errno.EPERM,"Permission denied.") - - 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, - 'res_model': self.res_model, - 'res_id': self.res_id, - # Datas are not set here - } - if not self.res_find_all: - val['parent_id'] = self.dir_id - - fil_id = fil_obj.create(cr, uid, val, context=ctx) - fil = fil_obj.browse(cr, uid, fil_id, context=ctx) - klass = self.context.node_file_class - fnode = klass(path, self, self.context, fil) - if data is not None: - fnode.set_data(cr, data, fil) - return fnode - - def _get_ttag(self, cr): - return 'rodir-%d-%d' % (self.dir_id, self.res_id) - -node_res_dir.res_obj_class = node_res_obj - -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 = str(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 - - self.uidperms = 14 - if parent: - if not parent.check_perms('x'): - self.uidperms = 0 - elif not parent.check_perms('w'): - self.uidperms = 4 - - try: - self.uuser = (fil.user_id and fil.user_id.login) or 'nobody' - except Exception: - self.uuser = 'nobody' - self.ugroup = mkdosname(fil.company_id and fil.company_id.name, default='nogroup') - - # This only propagates the problem to get_data. Better - # fix those files to point to the root dir. - self.storage_id = None - par = fil.parent_id - while par: - if par.storage_id and par.storage_id.id: - self.storage_id = par.storage_id.id - break - par = par.parent_id - - def __eq__(self, other): - if type(self) != type(other): - return False - if not self.context == other.context: - return False - if self.dctx != other.dctx: - return False - return self.file_id == other.file_id - - def open_data(self, cr, mode): - stor = self.storage_id - assert stor, "No storage for file #%s." % self.file_id - if not self.check_perms(4): - raise IOError(errno.EPERM, "Permission denied.") - - # If storage is not set properly, we are just screwed here, don't - # try to get it from default. - stobj = self.context._dirobj.pool.get('document.storage') - return stobj.get_file(cr, self.context.uid, stor, self, mode=mode, context=self.context.context) - - def rm(self, cr): - uid = self.context.uid - if not self.check_perms(8): - raise IOError(errno.EPERM, "Permission denied.") - document_obj = self.context._dirobj.pool.get('ir.attachment') - if self.type in ('collection','database'): - return False - document = document_obj.browse(cr, uid, self.file_id, context=self.context.context) - res = False - if document and document._table_name == 'ir.attachment': - res = document_obj.unlink(cr, uid, [document.id]) - return res - - def fix_ppath(self, cr, fbro): - """Sometimes we may init this w/o path, parent. - This function fills the missing path from the file browse object - - Note: this may be an expensive operation, do on demand. However, - once caching is in, we might want to do that at init time and keep - this object anyway - """ - if self.path or self.parent: - return - assert fbro - uid = self.context.uid - - dirpath = [] - if fbro.parent_id: - dirobj = self.context._dirobj.pool.get('document.directory') - dirpath = dirobj.get_full_path(cr, uid, fbro.parent_id.id, context=self.context.context) - if fbro.datas_fname: - dirpath.append(fbro.datas_fname) - else: - dirpath.append(fbro.name) - - if len(dirpath)>1: - self.path = dirpath - else: - self.path = dirpath[0] - - 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, "No storage for file #%s" % self.file_id - if not self.check_perms(4): - raise IOError(errno.EPERM, "Permission denied.") - - # If storage is not set properly, we are just screwed here, don't - # try to get it from default. - 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! - bin_size = self.context.context.get('bin_size', False) - if bin_size and not self.content_length: - self.content_length = fil_obj.db_datas - 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, "No storage for file #%s" % self.file_id - if not self.check_perms(2): - raise IOError(errno.EPERM, "Permission denied.") - - 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 - - def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False): - if ndir_node and ndir_node.context != self.context: - raise NotImplementedError("Cannot move files between contexts.") - - if (not self.check_perms(8)) and ndir_node.check_perms(2): - raise IOError(errno.EPERM, "Permission denied.") - - doc_obj = self.context._dirobj.pool.get('ir.attachment') - if not fil_obj: - dbro = doc_obj.browse(cr, self.context.uid, self.file_id, context=self.context.context) - else: - dbro = fil_obj - assert dbro.id == self.file_id, "%s != %s for %r." % (dbro.id, self.file_id, self) - - if not dbro: - raise IndexError("Cannot locate doc %d.", self.file_id) - - if (not self.parent): - # there *must* be a parent node for this one - self.parent = self.context.get_dir_node(cr, dbro.parent_id) - assert self.parent - - ret = {} - if ndir_node and self.parent != ndir_node: - if not (isinstance(self.parent, node_dir) and isinstance(ndir_node, node_dir)): - _logger.debug('Cannot move file %r from %r to %r.', self, self.parent, ndir_node) - raise NotImplementedError('Cannot move files between dynamic folders.') - - if not ndir_obj: - ndir_obj = self.context._dirobj.browse(cr, self.context.uid, \ - ndir_node.dir_id, context=self.context.context) - - assert ndir_obj.id == ndir_node.dir_id - - stobj = self.context._dirobj.pool.get('document.storage') - r2 = stobj.simple_move(cr, self.context.uid, self, ndir_obj, \ - context=self.context.context) - ret.update(r2) - - if new_name and (new_name != dbro.name): - if len(ret): - raise NotImplementedError("Cannot rename and move.") # TODO - stobj = self.context._dirobj.pool.get('document.storage') - r2 = stobj.simple_rename(cr, self.context.uid, self, new_name, self.context.context) - ret.update(r2) - - del dbro - - if not in_write: - # We have to update the data ourselves - if ret: - ctx = self.context.context.copy() - ctx['__from_node'] = True - doc_obj.write(cr, self.context.uid, [self.file_id,], ret, ctx ) - ret = True - - return ret - -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.unixperms = 0640 - if parent: - self.uidperms = parent.uidperms & 14 - self.uuser = parent.uuser - self.ugroup = parent.ugroup - - 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 = str(res[0][0]) - - def get_data(self, cr, fil_obj=None): - cntobj = self.context._dirobj.pool.get('document.directory.content') - if not self.check_perms(4): - raise IOError(errno.EPERM, "Permission denied.") - - 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 open_data(self, cr, mode): - if mode.endswith('b'): - mode = mode[:-1] - if mode in ('r', 'w'): - cperms = mode[:1] - elif mode in ('r+', 'w+'): - cperms = 'rw' - else: - raise IOError(errno.EINVAL, "Cannot open at mode %s." % mode) - - if not self.check_perms(cperms): - raise IOError(errno.EPERM, "Permission denied.") - - ctx = self.context.context.copy() - ctx.update(self.dctx) - - return nodefd_content(self, cr, mode, ctx) - - def get_data_len(self, cr, fil_obj=None): - # FIXME : here, we actually generate the content twice!! - # we should have cached the generated content, but it is - # not advisable to do keep it in memory, until we have a cache - # expiration logic. - 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') - if not self.check_perms(2): - raise IOError(errno.EPERM, "Permission denied.") - - 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 '') - - def get_dav_resourcetype(self, cr): - return '' - -class nodefd_content(StringIO, node_descriptor): - - """ A descriptor to content nodes - """ - def __init__(self, parent, cr, mode, ctx): - node_descriptor.__init__(self, parent) - self._context=ctx - self._size = 0L - - if mode in ('r', 'r+'): - cntobj = parent.context._dirobj.pool.get('document.directory.content') - data = cntobj.process_read(cr, parent.context.uid, parent, ctx) - if data: - self._size = len(data) - parent.content_length = len(data) - StringIO.__init__(self, data) - elif mode in ('w', 'w+'): - StringIO.__init__(self, None) - # at write, we start at 0 (= overwrite), but have the original - # data available, in case of a seek() - elif mode == 'a': - StringIO.__init__(self, None) - else: - _logger.error("Incorrect mode %s is specified.", mode) - raise IOError(errno.EINVAL, "Invalid file mode.") - self.mode = mode - - def size(self): - return self._size - - def close(self): - # we now open a *separate* cursor, to update the data. - # FIXME: this may be improved, for concurrency handling - if self.mode == 'r': - StringIO.close(self) - return - - par = self._get_parent() - uid = par.context.uid - cr = pooler.get_db(par.context.dbname).cursor() - try: - if self.mode in ('w', 'w+', 'r+'): - data = self.getvalue() - cntobj = par.context._dirobj.pool.get('document.directory.content') - cntobj.process_write(cr, uid, par, data, par.context.context) - elif self.mode == 'a': - raise NotImplementedError - cr.commit() - except Exception: - _logger.exception('Cannot update db content #%d for close.', par.cnt_id) - raise - finally: - cr.close() - StringIO.close(self) - -class nodefd_static(StringIO, node_descriptor): - - """ A descriptor to nodes with static data. - """ - def __init__(self, parent, cr, mode, ctx=None): - node_descriptor.__init__(self, parent) - self._context=ctx - self._size = 0L - - if mode in ('r', 'r+'): - data = parent.get_data(cr) - if data: - self._size = len(data) - parent.content_length = len(data) - StringIO.__init__(self, data) - elif mode in ('w', 'w+'): - StringIO.__init__(self, None) - # at write, we start at 0 (= overwrite), but have the original - # data available, in case of a seek() - elif mode == 'a': - StringIO.__init__(self, None) - else: - _logger.error("Incorrect mode %s is specified.", mode) - raise IOError(errno.EINVAL, "Invalid file mode.") - self.mode = mode - - def size(self): - return self._size - - def close(self): - # we now open a *separate* cursor, to update the data. - # FIXME: this may be improved, for concurrency handling - if self.mode == 'r': - StringIO.close(self) - return - - par = self._get_parent() - # uid = par.context.uid - cr = pooler.get_db(par.context.dbname).cursor() - try: - if self.mode in ('w', 'w+', 'r+'): - data = self.getvalue() - par.set_data(cr, data) - elif self.mode == 'a': - raise NotImplementedError - cr.commit() - except Exception: - _logger.exception('Cannot update db content #%d for close.', par.cnt_id) - raise - finally: - cr.close() - StringIO.close(self) - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document_ftp/ftpserver/abstracted_fs.py b/addons/document_ftp/ftpserver/abstracted_fs.py index 326c62f7a92..dd393f1b1e9 100644 --- a/addons/document_ftp/ftpserver/abstracted_fs.py +++ b/addons/document_ftp/ftpserver/abstracted_fs.py @@ -15,7 +15,7 @@ import sql_db from service import security from osv import osv -from document.nodes import get_node_context +from document.document import get_node_context def _get_month_name(month): month=int(month) From 92e8304acb06acf44bccded929bf8d9c2b7c0c81 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 02:45:19 +0100 Subject: [PATCH 24/49] cleanup tests bzr revid: al@openerp.com-20121217014519-fwr5otel8qwlevaz --- addons/document/test/document_test.yml | 3 --- addons/document/test/document_test2.yml | 10 ---------- 2 files changed, 13 deletions(-) diff --git a/addons/document/test/document_test.yml b/addons/document/test/document_test.yml index 5864a223033..a6b938f0e69 100644 --- a/addons/document/test/document_test.yml +++ b/addons/document/test/document_test.yml @@ -5,7 +5,6 @@ - !record {model: 'document.directory', id: dir_partner_label}: name : "Partner Labels" - storage_id : storage_default type : ressource content_ids: - name: "Label" @@ -22,7 +21,6 @@ - !record {model: 'document.directory', id: directory_1}: name : "Directory 1" - storage_id : storage_default type : directory - In order to make a directory hierarchy in OpenERP I will make other static directory "Directory 2" and I put its Parent Item as "Directory 1", @@ -30,7 +28,6 @@ - !record {model: 'document.directory', id: directory_2}: name : "Directory 2" - storage_id : storage_default type : directory parent_id : directory_1 - diff --git a/addons/document/test/document_test2.yml b/addons/document/test/document_test2.yml index be91bfb3644..2ee3cda76a0 100644 --- a/addons/document/test/document_test2.yml +++ b/addons/document/test/document_test2.yml @@ -1,13 +1,3 @@ -- - In order to test the document management I make sure the default installation has some storage. -- - !assert {model: document.storage, id: storage_default }: - - id != False -- - I make sure the default installation has some root directory. -- - !assert {model: document.directory, id: dir_root}: - - storage_id != False - I create a "Testing" folder where all the test data will go. - From 45ce2234577fc5df16c25ebe45a9e4f5597f3213 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 02:56:51 +0100 Subject: [PATCH 25/49] cleanup tests bzr revid: al@openerp.com-20121217015651-qdw4iugzh9ghwv19 --- addons/document/document.py | 2 -- addons/document/test/document_test2.yml | 1 - .../document_ftp/test/document_ftp_test2.yml | 26 +++++++------------ 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/addons/document/document.py b/addons/document/document.py index 2ae5d55b7ad..6c75b60fcfe 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -2055,10 +2055,8 @@ class nodefd_db(StringIO, node_descriptor): if mode in ('r', 'r+'): data = ira_browse.datas - print "READ64",data if data: data = data.decode('base64') - print "READ",data self._size = len(data) StringIO.__init__(self, data) elif mode in ('w', 'w+'): diff --git a/addons/document/test/document_test2.yml b/addons/document/test/document_test2.yml index 2ee3cda76a0..beff61d4d0f 100644 --- a/addons/document/test/document_test2.yml +++ b/addons/document/test/document_test2.yml @@ -32,7 +32,6 @@ !assert {model: ir.attachment, id: file_test2 }: - datas == "YWJjZA==\n" - file_size == 4 - - file_type == 'text/plain' - I rename the attachment. - diff --git a/addons/document_ftp/test/document_ftp_test2.yml b/addons/document_ftp/test/document_ftp_test2.yml index eb86a99407d..ce8e25906d2 100644 --- a/addons/document_ftp/test/document_ftp_test2.yml +++ b/addons/document_ftp/test/document_ftp_test2.yml @@ -235,43 +235,37 @@ - I check that test3.txt is removed. - - I create 200 files through FTP + I create 5 files through FTP - !python {model: ir.attachment}: | from document_ftp import test_easyftp as te from cStringIO import StringIO ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2') fdata = StringIO('abcd') - # TODO speed - for i in range(0, 200): + for i in range(0, 5): fdata.seek(0) ftp.storbinary('STOR test-name%s.txt' %i, fdata) ftp.close() - - I list the 200 files, check speed + I list the 5 files, check speed - !python {model: ir.attachment}: | from document_ftp import test_easyftp as te ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2') - # TODO speed - assert len(ftp.nlst()) >= 200, "We haven't managed to store 200 files!" + assert len(ftp.nlst()) >= 5, "We haven't managed to store 5 files!" - - I read the 200 files, check speed - # TODO + I read the 5 files, check speed - - I move the 200 files to 'Test-Folder2' - # TODO - + I move the 5 files to 'Test-Folder2' - - I delete the 200 files + I delete the 5 files - !python {model: ir.attachment}: | from document_ftp import test_easyftp as te from cStringIO import StringIO ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2') - # TODO speed ftp.delete('test3.txt') - for i in range(0, 200): + for i in range(0, 5): ftp.delete('test-name%s.txt' %i) ftp.close() @@ -282,11 +276,9 @@ from document_ftp import test_easyftp as te from cStringIO import StringIO ftp = te.get_ftp_folder(cr, uid, self, 'Documents') - # TODO speed ftp.delete('test.txt') ftp.delete('test-renamed.txt') - ftp.close() - + ftp.close() - I remove the 'Test-Folder2' - From 25acb93277f1f38fa7d8db4493e42bc48bfde861 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 03:00:13 +0100 Subject: [PATCH 26/49] more fixes bzr revid: al@openerp.com-20121217020013-b0buz0ilza9ole0a --- addons/document/security/ir.model.access.csv | 3 --- addons/document/test/document_test.yml | 2 +- addons/document_webdav/nodes.py | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/addons/document/security/ir.model.access.csv b/addons/document/security/ir.model.access.csv index a82b9acd838..e0513a0640c 100644 --- a/addons/document/security/ir.model.access.csv +++ b/addons/document/security/ir.model.access.csv @@ -6,9 +6,6 @@ access_document_directory_content_all,document.directory.content all,model_docum access_document_directory_content_group_document_manager,document.directory.content document manager,model_document_directory_content,base.group_system,1,1,1,1 access_document_directory_content_type_group_document_manager,document.directory.content.type document manager,model_document_directory_content_type,base.group_system,1,1,1,1 access_document_directory_content_type_group_system,document.directory.content.type group system,model_document_directory_content_type,base.group_user,1,0,0,0 -access_document_storage_group_document_manager,document.storage document manager,model_document_storage,base.group_system,1,1,1,1 -access_document_storage_group_system,document.storage group system,model_document_storage,base.group_user,1,0,0,0 -access_document_storage_group_user,document.storage group user,model_document_storage,base.group_document_user,1,1,1,1 access_ir_attachment_group_user,ir.attachment user,base.model_ir_attachment,base.group_document_user,1,1,1,1 access_ir_attachment_group_system,ir.attachment system,base.model_ir_attachment,base.group_system,1,0,0,0 access_res_partner_group_user,res.partner user,base.model_res_partner,base.group_document_user,1,1,1,0 diff --git a/addons/document/test/document_test.yml b/addons/document/test/document_test.yml index a6b938f0e69..75fa74548d0 100644 --- a/addons/document/test/document_test.yml +++ b/addons/document/test/document_test.yml @@ -17,7 +17,7 @@ id = self.write(cr, uid, [ref("dir_partner_label")], {'ressource_type_id' : ids[0]}, context) - In order to check static directory in OpenERP which is the real directory just like system's local folders, - First I create a directory in OpenERP named "Directory 1" with storage as "Default File storage" and type as "Static Directory" + First I create a directory in OpenERP named "Directory 1" with type as "Static Directory" - !record {model: 'document.directory', id: directory_1}: name : "Directory 1" diff --git a/addons/document_webdav/nodes.py b/addons/document_webdav/nodes.py index a8fedee4fe3..babe10a519e 100644 --- a/addons/document_webdav/nodes.py +++ b/addons/document_webdav/nodes.py @@ -20,7 +20,7 @@ ############################################################################## -from document import nodes +from document import document as nodes from tools.safe_eval import safe_eval as eval import time import urllib From d01868ed74127061c04ffca0f79f72f5e7beb250 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 03:13:23 +0100 Subject: [PATCH 27/49] webdav fixes bzr revid: al@openerp.com-20121217021323-0u771l13oo3hqu7m --- addons/document_webdav/document_webdav.py | 9 ++------- addons/document_webdav/nodes.py | 16 ++++++++++++---- addons/document_webdav/webdav_setup.xml | 6 ------ 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/addons/document_webdav/document_webdav.py b/addons/document_webdav/document_webdav.py index cb1315140a3..e096c2b509c 100644 --- a/addons/document_webdav/document_webdav.py +++ b/addons/document_webdav/document_webdav.py @@ -20,9 +20,10 @@ ############################################################################## from osv import osv, fields -import nodes from tools import config +import nodes + class document_davdir(osv.osv): _inherit = 'document.directory' @@ -64,8 +65,6 @@ class document_davdir(osv.osv): """ return (nodes.node_database(context=ncontext), uri) -document_davdir() - class dav_dir_property(osv.osv): """ Arbitrary WebDAV properties, attached to document.directories. @@ -96,8 +95,6 @@ class dav_dir_property(osv.osv): 'do_subst': False, } -dav_dir_property() - class dav_file_property(osv.osv): """ Arbitrary WebDAV properties, attached to ir.attachments. @@ -126,7 +123,5 @@ class dav_file_property(osv.osv): 'do_subst': False, } -dav_file_property() - #eof # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/document_webdav/nodes.py b/addons/document_webdav/nodes.py index babe10a519e..aab83766514 100644 --- a/addons/document_webdav/nodes.py +++ b/addons/document_webdav/nodes.py @@ -27,10 +27,18 @@ import urllib import uuid from openerp import SUPERUSER_ID -try: - from tools.dict_tools import dict_filter -except ImportError: - from document.dict_tools import dict_filter +def dict_filter(srcdic, keys, res=None): + ''' Return a copy of srcdic that has only keys set. + If any of keys are missing from srcdic, the result won't have them, + either. + @param res If given, result will be updated there, instead of a new dict. + ''' + if res is None: + res = {} + for k in keys: + if k in srcdic: + res[k] = srcdic[k] + return res class node_acl_mixin(object): def _get_dav_owner(self, cr): diff --git a/addons/document_webdav/webdav_setup.xml b/addons/document_webdav/webdav_setup.xml index 6ea894b6a22..d75c416a93e 100644 --- a/addons/document_webdav/webdav_setup.xml +++ b/addons/document_webdav/webdav_setup.xml @@ -14,7 +14,6 @@ - directory principals @@ -27,7 +26,6 @@ - directory groups @@ -39,7 +37,6 @@ - directory resources @@ -52,7 +49,6 @@ - ressource @@ -66,7 +62,6 @@ - ressource @@ -78,7 +73,6 @@ - directory locations From f60cc9ea2cf213bafad8f94571acc2a9dffd4f48 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 03:24:49 +0100 Subject: [PATCH 28/49] webdav fixes for runbot bzr revid: al@openerp.com-20121217022449-veh0s2i5m8bc6bt7 --- addons/document_webdav/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/document_webdav/__init__.py b/addons/document_webdav/__init__.py index 11bbd35f7c3..c62339bdb7b 100644 --- a/addons/document_webdav/__init__.py +++ b/addons/document_webdav/__init__.py @@ -22,10 +22,10 @@ import logging _logger = logging.getLogger(__name__) +import document_webdav try: import webdav import webdav_server - import document_webdav except ImportError: _logger.info('document_webdav disabled please install PyWebDAV from http://code.google.com/p/pywebdav/downloads/detail?name=PyWebDAV-0.9.4.tar.gz&can=2&q=/') From ff7626229a2687ed85271c510ecc017e35634056 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Dec 2012 04:09:13 +0100 Subject: [PATCH 29/49] document fix filtering when parents are nullt bzr revid: al@openerp.com-20121217030913-x50nlq5qf7kuffe3 --- addons/document/document.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/addons/document/document.py b/addons/document/document.py index 6c75b60fcfe..444ddd74781 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -79,17 +79,26 @@ class document_file(osv.osv): ids = super(document_file, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False) if not ids: return 0 if count else [] + # Filter out documents that are in directories that the user is not allowed to read. # Must use pure SQL to avoid access rules exceptions (we want to remove the records, # not fail), and the records have been filtered in parent's search() anyway. - cr.execute('SELECT id, parent_id from "%s" WHERE id in %%s' % self._table, (tuple(ids),)) - doc_pairs = cr.fetchall() - parent_ids = set(zip(*doc_pairs)[1]) + cr.execute('SELECT id, parent_id from ir_attachment WHERE id in %s', (tuple(ids),)) + + # cont a dict of parent -> attach + parents = {} + for attach_id, attach_parent in cr.fetchall(): + parents.setdefault(attach_parent, []).append(attach_id) + parent_ids = parents.keys() + + # filter parents visible_parent_ids = self.pool.get('document.directory').search(cr, uid, [('id', 'in', list(parent_ids))]) - disallowed_parents = parent_ids.difference(visible_parent_ids) - for doc_id, parent_id in doc_pairs: - if parent_id in disallowed_parents: - ids.remove(doc_id) + + # null parents means allowed + ids = parents.get(None,[]) + for parent_id in visible_parent_ids: + ids.extend(parents[parent_id]) + return len(ids) if count else ids def copy(self, cr, uid, id, default=None, context=None): From e7a3b2638ba9fd768b52ce5289c335556098c4ad Mon Sep 17 00:00:00 2001 From: Date: Mon, 17 Dec 2012 11:55:52 +0100 Subject: [PATCH 30/49] [FIX] select the current fiscal year in the financial reports wizards lp bug: https://launchpad.net/bugs/1091171 fixed bzr revid: guewen.baconnier@camptocamp.com-20121217105552-s82nf3t5ttlrvkr0 --- addons/account/wizard/account_report_common.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/account/wizard/account_report_common.py b/addons/account/wizard/account_report_common.py index 2c1448b5e6f..bf579532eab 100644 --- a/addons/account/wizard/account_report_common.py +++ b/addons/account/wizard/account_report_common.py @@ -122,9 +122,11 @@ class account_common_report(osv.osv_memory): now = time.strftime('%Y-%m-%d') company_id = False ids = context.get('active_ids', []) + domain = [('date_start', '<', now), ('date_stop', '>', now)] if ids and context.get('active_model') == 'account.account': company_id = self.pool.get('account.account').browse(cr, uid, ids[0], context=context).company_id.id - fiscalyears = self.pool.get('account.fiscalyear').search(cr, uid, [('date_start', '<', now), ('date_stop', '>', now), ('company_id', '=', company_id)], limit=1) + domain += ('company_id', '=', company_id) + fiscalyears = self.pool.get('account.fiscalyear').search(cr, uid, domain, limit=1) return fiscalyears and fiscalyears[0] or False def _get_all_journal(self, cr, uid, context=None): From 163dceec5787adfd14b4eebe425320c99c680b35 Mon Sep 17 00:00:00 2001 From: "fclementi@camptocamp.com" <> Date: Mon, 17 Dec 2012 17:14:00 +0100 Subject: [PATCH 31/49] [IMP] put sequence 0 on main default taxes (for configuration wizard) bzr revid: fclementi@camptocamp.com-20121217161400-0wxxrsk8d4x0ho8w --- addons/l10n_fr/fr_tax.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/l10n_fr/fr_tax.xml b/addons/l10n_fr/fr_tax.xml index d03ee4520f0..7cd3a36f54a 100644 --- a/addons/l10n_fr/fr_tax.xml +++ b/addons/l10n_fr/fr_tax.xml @@ -26,7 +26,7 @@ - + sale @@ -138,7 +138,7 @@ - + purchase From 68097047e7de56f1cabd953c262d126165849c42 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Tue, 18 Dec 2012 17:37:24 +0100 Subject: [PATCH 32/49] [FIX]_logger instead of self._logger, fix report name bzr revid: dle@openerp.com-20121218163724-08wry3f8tdwz8g23 --- addons/document/document.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/document/document.py b/addons/document/document.py index 437fb9ff28d..99bc4137e62 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -408,12 +408,12 @@ class document_directory_content(osv.osv): res2 = [] tname = '' if content.include_name: - content_name = node.displayname or '' + record_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 '') + if record_name: + tname = (content.prefix or '') + record_name + (content.suffix or '') + (content.extension or '') else: - tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '') + tname = (content.prefix or '') + (content.name or '') + (content.suffix or '') + (content.extension or '') if tname.find('/'): tname=tname.replace('/', '_') act_id = False @@ -556,7 +556,7 @@ class document_storage(osv.osv): file_node.content_type = mime return True except Exception, e : - self._logger.warning("Cannot save data.", exc_info=True) + _logger.warning("Cannot save data.", exc_info=True) # 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)) From a68e84387c67f3909c841e9596717440a5ab0a68 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Tue, 18 Dec 2012 17:53:25 +0100 Subject: [PATCH 33/49] [FIX]Data xml bzr revid: dle@openerp.com-20121218165325-75pq1jxc3vsdwtu2 --- addons/document/document_data.xml | 54 +------------------------------ 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/addons/document/document_data.xml b/addons/document/document_data.xml index ca3a2ed7144..ee4521bfc46 100644 --- a/addons/document/document_data.xml +++ b/addons/document/document_data.xml @@ -22,26 +22,13 @@ application/pdf - - Partners by Category - - ressource - 1 - 0 - - - - - Partners ressource - [('category_id','in',[active_id])] - + 0 - @@ -53,44 +40,5 @@ 0 - - Products - - - 0 - - - - - Sales Order - - - 0 - - - - - All Sales Order - - - 0 - - - - - Quotations - - - 0 - - - - - Projects - - - 0 - - From 6fa12e9458b0caa72b12ce1a5153ce206d905e62 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Tue, 18 Dec 2012 17:58:39 +0100 Subject: [PATCH 34/49] [FIX]remove dctx, from merge https://code.launchpad.net/~numerigraphe/openobject-addons/trunk-document-dctx-noprefix/+merge/92431 bzr revid: dle@openerp.com-20121218165839-mwgb8jl5tgcn9eam --- addons/document/document.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/document/document.py b/addons/document/document.py index 99bc4137e62..52c4984a299 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -341,7 +341,7 @@ class document_directory_dctx(osv.osv): 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 )] + children could have a domain like [('sale_id', = ,s_id )] This system should be used recursively, that is, parent dynamic context will be appended to all children down the tree. """ @@ -349,7 +349,7 @@ class document_directory_dctx(osv.osv): _description = 'Directory Dynamic Context' _columns = { 'dir_id': fields.many2one('document.directory', 'Directory', required=True, ondelete="cascade"), - '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."), + 'field': fields.char('Field', size=20, required=True, select=1, help="The name of the field."), '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"), } @@ -418,7 +418,7 @@ class document_directory_content(osv.osv): tname=tname.replace('/', '_') act_id = False if 'dctx_res_id' in node.dctx: - act_id = node.dctx['dctx_res_id'] + act_id = node.dctx['res_id'] elif hasattr(node, 'res_id'): act_id = node.res_id else: @@ -1010,7 +1010,7 @@ class node_dir(node_database): if dirr and dirr.dctx_ids: for dfld in dirr.dctx_ids: try: - self.dctx['dctx_' + dfld.field] = safe_eval(dfld.expr,dc2) + self.dctx[dfld.field] = safe_eval(dfld.expr,dc2) except Exception,e: print "Cannot eval %s." % dfld.expr print e @@ -1254,7 +1254,7 @@ class node_res_dir(node_class): # 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 + self.dctx_dict[dfld.field] = dfld.expr def __eq__(self, other): if type(self) != type(other): From 31592e96aa99c029c6256b644269038e221aeafc Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 19 Dec 2012 16:12:17 +0100 Subject: [PATCH 35/49] [ADD] Added an openerpBounce jquery plugin bzr revid: fme@openerp.com-20121219151217-bxp1p04gmbccckys --- addons/web/static/src/js/coresetup.js | 5 +++++ addons/web/static/src/js/view_form.js | 4 ++-- addons/web/static/src/js/view_list.js | 2 +- addons/web_kanban/static/src/js/kanban.js | 6 +++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index eac26520301..a8b0510389b 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -477,6 +477,11 @@ $.fn.openerpClass = function(additionalClass) { $(this).addClass('openerp ' + additionalClass); }); }; +$.fn.openerpBounce = function() { + return this.each(function() { + $(this).css('box-sizing', 'content-box').effect('bounce', {distance: 18, times: 5}, 250); + }); +}; /** Jquery extentions */ $.Mutex = (function() { diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 328919144e6..5c76a13ef0d 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -206,7 +206,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.$el.find(".oe_form_group_row,.oe_form_field,label").on('click', function (e) { if(self.get("actual_mode") == "view") { var $button = self.options.$buttons.find(".oe_form_button_edit"); - $button.css('box-sizing', 'content-box').effect('bounce', {distance: 18, times: 5}, 250); + $button.openerpBounce(); e.stopPropagation(); instance.web.bus.trigger('click', e); } @@ -215,7 +215,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.$el.find(".oe_form_field_status:not(.oe_form_status_clickable)").on('click', function (e) { if((self.get("actual_mode") == "view")) { var $button = self.$el.find(".oe_highlight:not(.oe_form_invisible)").css({'float':'left','clear':'none'}); - $button.effect('bounce', {distance:18, times: 5}, 250); + $button.openerpBounce(); e.stopPropagation(); } }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 8420a870eec..4687b3cb2ba 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -833,7 +833,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi ); var create_nocontent = this.$buttons; this.$el.find('.oe_view_nocontent').click(function() { - create_nocontent.effect('bounce', {distance: 18, times: 5}, 250); + create_nocontent.openerpBounce(); }); } }); diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 915fff2f567..71e8336d0eb 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -52,7 +52,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ this._super.apply(this, arguments); this.$el.on('click', '.oe_kanban_dummy_cell', function() { if (self.$buttons) { - self.$buttons.find('.oe_kanban_add_column').effect('bounce', {distance: 18, times: 5}, 250); + self.$buttons.find('.oe_kanban_add_column').openerpBounce(); } }); }, @@ -471,7 +471,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ ); var create_nocontent = this.$buttons; this.$el.find('.oe_view_nocontent').click(function() { - create_nocontent.effect('bounce', {distance: 18, times: 5}, 250); + create_nocontent.openerpBounce(); }); }, @@ -615,7 +615,7 @@ instance.web_kanban.KanbanGroup = instance.web.Widget.extend({ this.$records.find(".oe_kanban_column_cards").click(function (ev) { if (ev.target == ev.currentTarget) { if (!self.state.folded) { - add_btn.effect('bounce', {distance: 18, times: 5}, 250); + add_btn.openerpBounce(); } } }); From bcd4686ad8c86d4bcafe555ef342fb0bc70e87a6 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 19 Dec 2012 16:15:50 +0100 Subject: [PATCH 36/49] [FIX] osv exception message not displayed anymore Reverted part of revid:chs@openerp.com-20121108145001-pswe7r5ss4nzgu00 bzr revid: fme@openerp.com-20121219151550-6lkn996jxdv2r7x2 --- addons/web/static/src/xml/base.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index a3fd74bfb00..885c5f84572 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -40,7 +40,7 @@

- var message = d.error.message ? d.error.message : d.error.data.fault_code; + var message = d.message ? d.message : d.error.data.fault_code; d.html_error = context.engine.tools.html_escape(message) .replace(/\n/g, '
');
From f14a8b9aac07a0cf8c346adf53b856a4c01ec07c Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 19 Dec 2012 16:45:05 +0100 Subject: [PATCH 37/49] [IMP] version_info more info bzr revid: al@openerp.com-20121219154505-lcartslny586t07n --- addons/web/controllers/main.py | 4 +--- addons/web/static/src/xml/base.xml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 0d5194829ad..6d12f8a49fe 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -679,9 +679,7 @@ class WebClient(openerpweb.Controller): @openerpweb.jsonrequest def version_info(self, req): - return { - "version": openerp.release.version - } + return openerp.service.web_services.RPC_VERSION_1 class Proxy(openerpweb.Controller): _cp_path = '/web/proxy' diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 885c5f84572..877a2c183ee 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -412,7 +412,7 @@

Activate the developer mode -

Version

+

Version

Copyright © 2004-TODAY OpenERP SA. All Rights Reserved.
From b33e5309c39df29f3035d6dd7246aca7412dbcf8 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 19 Dec 2012 16:47:17 +0100 Subject: [PATCH 38/49] [IMP] Improved kanban style bzr revid: fme@openerp.com-20121219154717-61fe54e66q6f2rs5 --- addons/web_kanban/static/src/css/kanban.css | 6 ++---- addons/web_kanban/static/src/css/kanban.sass | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index 4d50f73d2cf..325f92b621d 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -1,3 +1,4 @@ +@charset "utf-8"; .openerp .oe_kanban_view { background: white; height: inherit; @@ -108,10 +109,7 @@ padding: 0px; background: white; } -.openerp .oe_kanban_view .oe_kanban_column { - height: 100%; -} -.openerp .oe_kanban_view .oe_kanban_column .oe_kanban_column_cards{ +.openerp .oe_kanban_view .oe_kanban_column, .openerp .oe_kanban_view .oe_kanban_column_cards { height: 100%; } .openerp .oe_kanban_view .oe_kanban_aggregates { diff --git a/addons/web_kanban/static/src/css/kanban.sass b/addons/web_kanban/static/src/css/kanban.sass index 84de3e32842..c115862ef0a 100644 --- a/addons/web_kanban/static/src/css/kanban.sass +++ b/addons/web_kanban/static/src/css/kanban.sass @@ -135,7 +135,7 @@ padding: 0px background: #ffffff - .oe_kanban_column + .oe_kanban_column, .oe_kanban_column_cards height: 100% .oe_kanban_aggregates padding: 0 From 6d49547fb6aafa5c9b5417177dd518b21d7b3f46 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Wed, 19 Dec 2012 17:18:40 +0100 Subject: [PATCH 39/49] [FIX]Remove exception bzr revid: dle@openerp.com-20121219161840-t5jrxrtly1jzm8lh --- addons/document_webdav/webdav_server.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py index f801a56ee97..2c008abe02f 100644 --- a/addons/document_webdav/webdav_server.py +++ b/addons/document_webdav/webdav_server.py @@ -57,6 +57,7 @@ import re import time from string import atoi import addons +import socket # from DAV.constants import DAV_VERSION_1, DAV_VERSION_2 from xml.dom import minidom from redirect import RedirectHTTPHandler @@ -87,6 +88,12 @@ class DAVHandler(DAVRequestHandler, HttpOptions, FixSendError): 'DELETE', 'TRACE', 'REPORT', ] } + def __init__(self, request, client_address, server): + self.request = request + self.client_address = client_address + self.server = server + self.setup() + def get_userinfo(self, user, pw): return False @@ -118,15 +125,9 @@ class DAVHandler(DAVRequestHandler, HttpOptions, FixSendError): return res def setup(self): - DAVRequestHandler.setup(self) self.davpath = '/'+config.get_misc('webdav','vdir','webdav') addr, port = self.server.server_name, self.server.server_port server_proto = getattr(self.server,'proto', 'http').lower() - try: - if hasattr(self.request, 'getsockname'): - addr, port = self.request.getsockname() - except Exception, e: - self.log_error("Cannot calculate own address: %s" , e) # Too early here to use self.headers self.baseuri = "%s://%s:%d/"% (server_proto, addr, port) self.IFACE_CLASS = openerp_dav_handler(self, self.verbose) From 068e93a887cb5dbb008e47252fda82450fbb36e8 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 19 Dec 2012 17:39:39 +0100 Subject: [PATCH 40/49] [ADD] Added 'instance' in kanban box qweb redering context bzr revid: fme@openerp.com-20121219163939-5l0pdjphzeaog9ko --- addons/web_kanban/static/src/js/kanban.js | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 71e8336d0eb..0e90cd5c9ad 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -793,6 +793,7 @@ instance.web_kanban.KanbanRecord = instance.web.Widget.extend({ }, renderElement: function() { this.qweb_context = { + instance: instance, record: this.record, widget: this, read_only_mode: this.view.options.read_only_mode, From 7a627b581062ea55178448480d7ed9f7ee36a6e0 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Wed, 19 Dec 2012 18:00:05 +0100 Subject: [PATCH 41/49] [FIX]Update request missing one argument bzr revid: dle@openerp.com-20121219170005-swdzzhvm2nifye5f --- addons/document/document.py | 3 +-- addons/document_webdav/dav_fs.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/document/document.py b/addons/document/document.py index 52c4984a299..6cb2cabbf38 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -551,7 +551,7 @@ class document_storage(osv.osv): # 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 index_content = %s, file_type = %s WHERE id = %s', (filesize, icont_u, mime, file_node.file_id)) + cr.execute('UPDATE ir_attachment SET file_size = %s, index_content = %s, file_type = %s WHERE id = %s', (filesize, icont_u, mime, file_node.file_id)) file_node.content_length = filesize file_node.content_type = mime return True @@ -1620,7 +1620,6 @@ class node_res_obj(node_class): } if not self.res_find_all: val['parent_id'] = self.dir_id - fil_id = fil_obj.create(cr, uid, val, context=ctx) fil = fil_obj.browse(cr, uid, fil_id, context=ctx) klass = self.context.node_file_class diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 59e93fa3722..9f677400dd8 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -709,7 +709,6 @@ class openerp_dav_handler(dav_interface): if not dir_node: cr.close() raise DAV_NotFound('Parent folder not found.') - newchild = self._try_function(dir_node.create_child, (cr, objname, data), "create %s" % objname, cr=cr) if not newchild: From eabc5b0dde75d176e7abae4be40b68479d9ba294 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Wed, 19 Dec 2012 18:13:08 +0100 Subject: [PATCH 42/49] [FIX]Import failed bzr revid: dle@openerp.com-20121219171308-5sdy52hpyn9gxpv7 --- addons/document_webdav/dav_fs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 9f677400dd8..759d6764b47 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -39,7 +39,10 @@ except ImportError: import openerp from openerp import pooler, sql_db, netsvc from openerp.tools import misc -from openerp.addons.document.dict_tools import dict_merge2 +try: + from tools.dict_tools import dict_merge2 +except ImportError: + from document.dict_tools import dict_merge2 from cache import memoize from webdav import mk_lock_response From f2e50cc6a739eccf1986bdcde53bbd29f36ac253 Mon Sep 17 00:00:00 2001 From: "dle@openerp.com" <> Date: Wed, 19 Dec 2012 18:18:35 +0100 Subject: [PATCH 43/49] [FIX]paste dict_merge2 instead of import bzr revid: dle@openerp.com-20121219171835-p6jsfd3zgq5t41ug --- addons/document_webdav/dav_fs.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 759d6764b47..e5756f5df91 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -39,10 +39,6 @@ except ImportError: import openerp from openerp import pooler, sql_db, netsvc from openerp.tools import misc -try: - from tools.dict_tools import dict_merge2 -except ImportError: - from document.dict_tools import dict_merge2 from cache import memoize from webdav import mk_lock_response @@ -57,6 +53,22 @@ day_names = { 0: 'Mon', 1: 'Tue' , 2: 'Wed', 3: 'Thu', 4: 'Fri', 5: 'Sat', 6: 'S month_names = { 1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec' } +def dict_merge2(*dicts): + """ Return a dict with all values of dicts. + If some key appears twice and contains iterable objects, the values + are merged (instead of overwritten). + """ + res = {} + for d in dicts: + for k in d.keys(): + if k in res and isinstance(res[k], (list, tuple)): + res[k] = res[k] + d[k] + elif k in res and isinstance(res[k], dict): + res[k].update(d[k]) + else: + res[k] = d[k] + return res + class DAV_NotFound2(DAV_NotFound): """404 exception, that accepts our list uris """ From e5a244eea3fe9bf188b5d1b4501d178609ddbfb9 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 19 Dec 2012 18:40:09 +0100 Subject: [PATCH 44/49] [FIX] account move reconciliation: Properly evaluate action context (since evalpocalypse) bzr revid: fme@openerp.com-20121219174009-se5fvfizxh2wmh4x --- addons/account/static/src/js/account_move_reconciliation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/static/src/js/account_move_reconciliation.js b/addons/account/static/src/js/account_move_reconciliation.js index 19c194166e2..dbbfe3cc069 100644 --- a/addons/account/static/src/js/account_move_reconciliation.js +++ b/addons/account/static/src/js/account_move_reconciliation.js @@ -103,7 +103,7 @@ openerp.account = function (instance) { action_id: result[1], context: additional_context }).done(function (result) { - result.context = _.extend(result.context || {}, additional_context); + result.context = instance.web.pyeval.eval('contexts', [result.context, additional_context]); result.flags = result.flags || {}; result.flags.new_window = true; return self.do_action(result, { From 833fcbd7a209066a39e3dfe0dbb12cde856b2a98 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 19 Dec 2012 19:10:03 +0100 Subject: [PATCH 45/49] [FIX] mail: avoid duplicate notifications when receiving inbound mails - disable auto-follow of system user used by mail gateway, when message_process calls message_new (otherwise this user would be a follower of all new records) - avoid matching multiple partners with the same email when looking up partner_id for inbound emails - just 1 partner per email is enough (avoids more duplicates) - delay setting partner_ids on mail_messages posted by the mail gateway, in order to avoid notifying again people who were direct recipient of the message in the first place (should perhaps be improved to only do that for external emails, i.e. emails that are not present in the mail.alias table) bzr revid: odo@openerp.com-20121219181003-xvw5q0dd3t2jtjw9 --- addons/mail/mail_thread.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index e8bfdc1a8fe..ef616c44218 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -268,7 +268,7 @@ class mail_thread(osv.AbstractModel): """ Find partners related to some header fields of the message. """ s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)]) return [partner_id for email in tools.email_split(s) - for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], context=context)] + for partner_id in self.pool.get('res.partner').search(cr, uid, [('email', 'ilike', email)], limit=1, context=context)] def _message_find_user_id(self, cr, uid, message, context=None): from_local_part = tools.email_split(decode(message.get('From')))[0] @@ -431,6 +431,10 @@ class mail_thread(osv.AbstractModel): msg = self.message_parse(cr, uid, msg_txt, save_original=save_original, context=context) if strip_attachments: msg.pop('attachments', None) + + # postpone setting msg.partner_ids after message_post, to avoid double notifications + partner_ids = msg.pop('partner_ids', []) + thread_id = False for model, thread_id, custom_values, user_id in routes: if self._name != model: @@ -440,14 +444,24 @@ class mail_thread(osv.AbstractModel): assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \ "Undeliverable mail with Message-Id %s, model %s does not accept incoming emails" % \ (msg['message_id'], model) + + # disabled subscriptions during message_new/update to avoid having the system user running the + # email gateway become a follower of all inbound messages + nosub_ctx = dict(context, mail_nosubscribe=True) if thread_id and hasattr(model_pool, 'message_update'): - model_pool.message_update(cr, user_id, [thread_id], msg, context=context) + model_pool.message_update(cr, user_id, [thread_id], msg, context=nosub_ctx) else: - thread_id = model_pool.message_new(cr, user_id, msg, custom_values, context=context) + thread_id = model_pool.message_new(cr, user_id, msg, custom_values, context=nosub_ctx) else: assert thread_id == 0, "Posting a message without model should be with a null res_id, to create a private message." model_pool = self.pool.get('mail.thread') - model_pool.message_post_user_api(cr, uid, [thread_id], context=context, content_subtype='html', **msg) + new_msg_id = model_pool.message_post_user_api(cr, uid, [thread_id], context=context, content_subtype='html', **msg) + + if partner_ids: + # postponed after message_post, because this is an external message and we don't want to create + # duplicate emails due to notifications + self.pool.get('mail.message').write(cr, uid, [new_msg_id], {'partner_ids': partner_ids}, context=context) + return thread_id def message_new(self, cr, uid, msg_dict, custom_values=None, context=None): From b0cb29dea2d14eb65abbc3117168709fc2599dcf Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Wed, 19 Dec 2012 19:18:35 +0100 Subject: [PATCH 46/49] [IMP] Adding an extra_email argument to message_post_user_api bzr revid: fp@tinyerp.com-20121219181835-twsoxzlu9x7y3mqr --- addons/mail/mail_thread.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index ef616c44218..48bdef508d0 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -749,7 +749,8 @@ class mail_thread(osv.AbstractModel): return mail_message.create(cr, uid, values, context=context) def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False, - attachment_ids=None, context=None, content_subtype='plaintext', **kwargs): + attachment_ids=None, context=None, content_subtype='plaintext', + extra_email=[], **kwargs): """ Wrapper on message_post, used for user input : - mail gateway - quick reply in Chatter (refer to mail.js), not @@ -761,6 +762,7 @@ class mail_thread(osv.AbstractModel): - type and subtype: comment and mail.mt_comment by default - attachment_ids: supposed not attached to any document; attach them to the related document. Should only be set by Chatter. + - extra_email: [ 'Fabien ', 'al@openerp.com' ] """ ir_attachment = self.pool.get('ir.attachment') mail_message = self.pool.get('mail.message') @@ -769,6 +771,12 @@ class mail_thread(osv.AbstractModel): if content_subtype == 'plaintext': body = tools.plaintext2html(body) + for partner in extra_email: + part_ids = self.pool.get('res.partner').search(cr, uid, [('email', '=', partner)], context=context) + if not part_ids: + part_ids = [self.pool.get('res.partner').name_create(cr, uid, partner, context=context)[0]] + self.message_subscribe(cr, uid, [thread_id], part_ids, context=context) + partner_ids = kwargs.pop('partner_ids', []) if parent_id: parent_message = self.pool.get('mail.message').browse(cr, uid, parent_id, context=context) From adb16fd77918f186941ef634917f2185c01aff8b Mon Sep 17 00:00:00 2001 From: "vta vta@openerp.com" <> Date: Wed, 19 Dec 2012 21:03:39 +0100 Subject: [PATCH 47/49] [FIX] Anonymous group allowed to create mail.message, so anonymous users can submit contact forms which creates a lead bzr revid: vta@openerp.com-20121219200339-42fx8vxw7pzfclxl --- addons/portal_anonymous/security/ir.model.access.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/portal_anonymous/security/ir.model.access.csv b/addons/portal_anonymous/security/ir.model.access.csv index a26b600288d..24c29200230 100644 --- a/addons/portal_anonymous/security/ir.model.access.csv +++ b/addons/portal_anonymous/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_mail_message_portal,mail.message.portal,mail.model_mail_message,portal.group_anonymous,1,0,0,0 +access_mail_message_portal,mail.message.portal,mail.model_mail_message,portal.group_anonymous,1,0,1,0 access_res_partner,res.partner,base.model_res_partner,portal.group_anonymous,1,0,0,0 From 0ed151708ab3a4423e1d6a1ddcfed7e107113a33 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 20 Dec 2012 03:37:21 +0100 Subject: [PATCH 48/49] last fix bzr revid: al@openerp.com-20121220023721-oy7y4czmf3tvmyzl --- openerp/addons/base/ir/ir_attachment.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index b73d8362c58..5f54b4aca8e 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -24,6 +24,7 @@ import itertools import os import re +from openerp import tools from openerp.osv import fields,osv class ir_attachment(osv.osv): @@ -77,7 +78,7 @@ class ir_attachment(osv.osv): r = '' try: if bin_size: - r = os.path.filesize(full_path) + r = os.path.getsize(full_path) else: r = open(full_path).read().encode('base64') except IOError: From 2a1ca8fba20debf2eb771c9bc615a1d85987bdf3 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Thu, 20 Dec 2012 04:43:23 +0000 Subject: [PATCH 49/49] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20121220044323-lda479xp4patic59 --- openerp/addons/base/i18n/en_GB.po | 13 +- openerp/addons/base/i18n/es.po | 1155 ++++++++++++++++++++++++----- openerp/addons/base/i18n/es_EC.po | 45 +- openerp/addons/base/i18n/et.po | 54 +- openerp/addons/base/i18n/hr.po | 10 +- openerp/addons/base/i18n/hu.po | 296 +++++++- openerp/addons/base/i18n/it.po | 2 +- openerp/addons/base/i18n/ro.po | 98 ++- openerp/addons/base/i18n/zh_CN.po | 32 +- 9 files changed, 1429 insertions(+), 276 deletions(-) diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po index e6f7fcdf2a7..5be4080d6a6 100644 --- a/openerp/addons/base/i18n/en_GB.po +++ b/openerp/addons/base/i18n/en_GB.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-17 20:41+0000\n" +"PO-Revision-Date: 2012-12-19 19:54+0000\n" "Last-Translator: David Bowers \n" "Language-Team: English (United Kingdom) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n" -"X-Generator: Launchpad (build 16372)\n" +"X-Launchpad-Export-Date: 2012-12-20 04:42+0000\n" +"X-Generator: Launchpad (build 16378)\n" #. module: base #: model:ir.module.module,description:base.module_account_check_writing @@ -4199,6 +4199,13 @@ msgid "" "invite.\n" "\n" msgstr "" +"\n" +"This module updates memos inside OpenERP when using an external pad\n" +"=====================================================================\n" +"\n" +"Use to update your text memo in real time with a user following that you " +"invite.\n" +"\n" #. module: base #: code:addons/base/module/module.py:609 diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po index 0b0474e092f..9730848f44d 100644 --- a/openerp/addons/base/i18n/es.po +++ b/openerp/addons/base/i18n/es.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-13 16:14+0000\n" -"Last-Translator: Roberto Lizana (trey.es) \n" +"PO-Revision-Date: 2012-12-19 23:24+0000\n" +"Last-Translator: Pedro Manuel Baeza \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: 2012-12-14 05:35+0000\n" -"X-Generator: Launchpad (build 16369)\n" +"X-Launchpad-Export-Date: 2012-12-20 04:42+0000\n" +"X-Generator: Launchpad (build 16378)\n" #. module: base #: model:ir.module.module,description:base.module_account_check_writing @@ -127,6 +127,17 @@ msgid "" " * Product Attributes\n" " " msgstr "" +"\n" +"Módulo que añade fabricantes y atributos en el formulario de producto.\n" +"===========================================================\n" +"\n" +"Puede definir los siguientes campos para un producto:\n" +"-------------------------------------------------\n" +"* Fabricante\n" +"* Nombre del producto del fabricante\n" +"* Código del producto del fabricante\n" +"* Atributos del producto\n" +" " #. module: base #: field:ir.actions.client,params:0 @@ -140,6 +151,9 @@ msgid "" "The module adds google user in res user.\n" "========================================\n" msgstr "" +"\n" +"El módulo añade usuarios Google res.user.\n" +"========================================\n" #. module: base #: help:res.partner,employee:0 @@ -196,6 +210,15 @@ msgid "" "revenue\n" "reports." msgstr "" +"\n" +"Genere facturas desde los gastos y partes de horas.\n" +"========================================================\n" +"\n" +"Módulo para generar facturas basadas en los costes (recursos humanos, " +"gastos, ...).\n" +"\n" +"Puede definir tarifas en la contabilidad analítica, realizando algún informe " +"teórico de beneficios." #. module: base #: model:ir.module.module,description:base.module_crm @@ -311,6 +334,12 @@ msgid "" "\n" " " msgstr "" +"\n" +"Plan de cuentas y localización de impuestos chilenos.\n" +"==============================================\n" +"Plan contable chileno e impuestos de acuerdo a disposiciones vigentes\n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_sale @@ -358,6 +387,15 @@ msgid "" " * Commitment Date\n" " * Effective Date\n" msgstr "" +"\n" +"Añade información adicional al pedido de venta.\n" +"===================================================\n" +"\n" +"Puede añadir las siguientes fechas adicionales a un pedido de venta:\n" +"-----------------------------------------------------------\n" +" * Fecha solicitada\n" +" * Fecha de confirmación\n" +" * Fecha efectiva\n" #. module: base #: help:ir.actions.act_window,res_id:0 @@ -416,6 +454,13 @@ msgid "" "document and Wiki based Hidden.\n" " " msgstr "" +"\n" +"Instalador oculto para la gestión del conocimiento.\n" +"==========================================\n" +"\n" +"Hace disponible la configuración de la aplicación de conocimiento disponible " +"desde la que se puede instalar el módulo 'document' y el módulo 'wiki'.\n" +" " #. module: base #: model:ir.module.category,name:base.module_category_customer_relationship_management @@ -434,6 +479,13 @@ msgid "" "invoices from picking, OpenERP is able to add and compute the shipping " "line.\n" msgstr "" +"\n" +"Permite añadir métodos de envío en los pedidos de venta y en los albaranes.\n" +"==============================================================\n" +"\n" +"Puede definir su propio transportista y sus tarifas de envío. Cuando se " +"creen facturas desde el albarán, OpenERP podrá añadir y calcular la línea de " +"envío.\n" #. module: base #: code:addons/base/ir/ir_filters.py:83 @@ -863,6 +915,14 @@ msgid "" "

\n" " " msgstr "" +"

\n" +"Pulse para añadir un contacto en la libreta de direcciones.\n" +"

\n" +"OpenERP le ayuda a gestionar todas las actividades relacionadas con los " +"clientes: discusiones, historial de oportunidades de negocio, documentos, " +"etc.\n" +"

\n" +" " #. module: base #: model:ir.module.module,description:base.module_web_linkedin @@ -934,6 +994,9 @@ msgid "" "image, with aspect ratio preserved. Use this field anywhere a small image is " "required." msgstr "" +"Imagen de tamaño pequeño de este contacto. Se redimensiona automáticamente a " +"64x64 px, con el ratio de aspecto preservado. Use este campo donde se " +"requiera una imagen pequeña." #. module: base #: help:ir.actions.server,mobile:0 @@ -1121,6 +1184,13 @@ msgid "" " * the Tax Code Chart for Luxembourg\n" " * the main taxes used in Luxembourg" msgstr "" +"\n" +"Éste es el módulo base para gestionar el plan de cuentas para Luxemburgo.\n" +"======================================================================\n" +"\n" +" * El plan de cuentas KLUWER\n" +" * Los códigos de impuestos para Luxemburgo\n" +" * Los impuestos principales usados en Luxembourg" #. module: base #: model:res.country,name:base.om @@ -1362,7 +1432,7 @@ msgstr "Contribuyentes" #. module: base #: field:ir.rule,perm_unlink:0 msgid "Apply for Delete" -msgstr "" +msgstr "Aplicar para eliminación" #. module: base #: selection:ir.property,type:0 @@ -1377,7 +1447,7 @@ msgstr "Visible" #. module: base #: model:ir.actions.client,name:base.action_client_base_menu msgid "Open Settings Menu" -msgstr "" +msgstr "Abrir menú 'Configuración'" #. module: base #: selection:base.language.install,lang:0 @@ -1437,6 +1507,8 @@ msgid "" " for uploading to OpenERP's translation " "platform," msgstr "" +"Formato TGZ: archivo comprimido que contiene un archivo PO, adecuado para " +"subirlo directamente a la plataforma de traducción de OpenERP." #. module: base #: view:res.lang:0 @@ -1601,6 +1673,15 @@ msgid "" "with a single statement.\n" " " msgstr "" +"\n" +"Este módulo instala la base para las cuentas bancarias IBAN (International " +"Bank Account Number) y comprueba su validez.\n" +"=============================================================================" +"======================\n" +"\n" +"Incluye la habilidad de extraer correctamente las cuentas locales " +"representadas por una cuenta IBAN con un sólo extracto.\n" +" " #. module: base #: view:ir.module.module:0 @@ -1622,6 +1703,12 @@ msgid "" "=============\n" " " msgstr "" +"\n" +"Este módulo añade el menú y características de reclamaciones al portal si " +"los módulos 'claim' y 'portal' están instalados.\n" +"=============================================================================" +"====================\n" +" " #. module: base #: model:ir.actions.act_window,help:base.action_res_partner_bank_account_form @@ -1654,7 +1741,7 @@ msgstr "" #. module: base #: model:res.country,name:base.mf msgid "Saint Martin (French part)" -msgstr "" +msgstr "San Martín (zona francesa)" #. module: base #: model:ir.model,name:base.model_ir_exports @@ -1817,7 +1904,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_project_issue msgid "Portal Issue" -msgstr "" +msgstr "Incidencia de portal" #. module: base #: model:ir.ui.menu,name:base.menu_tools @@ -1837,11 +1924,15 @@ msgid "" "Launch Manually Once: after having been launched manually, it sets " "automatically to Done." msgstr "" +"Manual: Lanzado manualmente.\n" +"Automático: Se ejecuta siempre que se reconfigura el sistema.\n" +"Lanzado manualmente una vez: después de que se lanza manualmente, se " +"establece automáticamente a 'Realizado'." #. module: base #: field:res.partner,image_small:0 msgid "Small-sized image" -msgstr "" +msgstr "Imagen pequeña" #. module: base #: model:ir.module.module,shortdesc:base.module_stock @@ -1904,6 +1995,14 @@ msgid "" "Please keep in mind that you should review and adapt it with your " "Accountant, before using it in a live Environment.\n" msgstr "" +"\n" +"Este módulo provee el plan de cuentas estándar para Austria, que está basado " +"en la plantilla de BMF.gv.at.\n" +"=============================================================================" +"=========\n" +"\n" +"Tenga en mente que debe revisar y adaptarlo con sus contables, antes de " +"usarlo en un entorno en producción.\n" #. module: base #: model:res.country,name:base.kg @@ -1922,6 +2021,15 @@ msgid "" "It assigns manager and user access rights to the Administrator and only user " "rights to the Demo user. \n" msgstr "" +"\n" +"Permisos de acceso contables\n" +"========================\n" +"\n" +"Da al usuario administrador acceso a todas las características de " +"contabilidad, tales como asientos o el plan de cuentas.\n" +"\n" +"Asinga derechos de gestor y de usuario al administrador y sólo permisos de " +"usuario al usuario demo. \n" #. module: base #: field:ir.attachment,res_id:0 @@ -1959,7 +2067,7 @@ msgstr "Países Bajos-Holanda" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_event msgid "Portal Event" -msgstr "" +msgstr "Evento del portal" #. module: base #: selection:ir.translation,state:0 @@ -2093,6 +2201,14 @@ msgid "" "with the effect of creating, editing and deleting either ways.\n" " " msgstr "" +"\n" +"Sincronización de las tareas con el parte de horas.\n" +"====================================================================\n" +"\n" +"Este módulo permite transferir las entradas de las tareas definidas para la " +"gestión de proyectos a las líneas del parte de horas para una fecha y un " +"usuario concretos, con el efecto de crear, editar y borrar en ambas vías.\n" +" " #. module: base #: model:ir.model,name:base.model_ir_model_access @@ -2112,6 +2228,15 @@ msgid "" " templates to target objects.\n" " " msgstr "" +"\n" +" * Soporte multiidioma para los planes de cuentas, impuestos, códigos de " +"impuesto, diarios, plantillas de contabilidad, planes de cuentas analíticos " +"y diarios analíticos.\n" +"* Cambios en el asistente de configuración\n" +" - Copiar traducciones para el plan de cuentas, los impuestos, los " +"códigos de impuesto, las posiciones fiscales de las plantillas a los " +"objetos.\n" +" " #. module: base #: field:workflow.transition,act_from:0 @@ -2234,7 +2359,7 @@ msgstr "" #. module: base #: view:base.language.export:0 msgid "PO(T) format: you should edit it with a PO editor such as" -msgstr "" +msgstr "Formato PO(T): debería editarlo con un editor PO como" #. module: base #: model:ir.ui.menu,name:base.menu_administration @@ -2287,7 +2412,7 @@ msgstr "Coreano (KP) / 한국어 (KP)" #. module: base #: model:res.country,name:base.ax msgid "Åland Islands" -msgstr "" +msgstr "Islas Åland" #. module: base #: field:res.company,logo:0 @@ -2323,7 +2448,7 @@ msgstr "Bahamas" #. module: base #: field:ir.rule,perm_create:0 msgid "Apply for Create" -msgstr "" +msgstr "Aplicar para creación" #. module: base #: model:ir.module.category,name:base.module_category_tools @@ -2346,6 +2471,8 @@ msgid "" "Appears by default on the top right corner of your printed documents (report " "header)." msgstr "" +"Aparece por defecto en la esquina superior derecho de los documentos " +"impresos (encabezado del informe)." #. module: base #: field:base.module.update,update:0 @@ -2395,6 +2522,8 @@ msgstr "" msgid "" "No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'" msgstr "" +"No se han encontrado registros coincidentes para %(field_type)s '%(value)s' " +"en el campo '%%(field)s'" #. module: base #: model:ir.actions.act_window,help:base.action_ui_view @@ -2444,7 +2573,7 @@ msgstr "Belize" #. module: base #: help:ir.actions.report.xml,header:0 msgid "Add or not the corporate RML header" -msgstr "Añadir o no la cabecera corporativa en el informe RML" +msgstr "Añadir o no el encabezado corporativo en el informe RML" #. module: base #: model:res.country,name:base.ge @@ -2572,6 +2701,9 @@ msgid "" "View type: Tree type to use for the tree view, set to 'tree' for a " "hierarchical tree view, or 'form' for a regular list view" msgstr "" +"Tipo de vista: Tipo de árbol a usar para la vista de árbol. Establezca " +"'árbol' para una vista jerárquica de árbol, o 'formulario' para un vista de " +"lista regular" #. module: base #: sql_constraint:ir.ui.view_sc:0 @@ -2730,6 +2862,10 @@ msgid "" "==================================\n" " " msgstr "" +"\n" +"Estados Unidos - Plan de cuentas.\n" +"==================================\n" +" " #. module: base #: field:ir.actions.act_url,target:0 @@ -2850,12 +2986,17 @@ msgid "" "Module to attach a google document to any model.\n" "================================================\n" msgstr "" +"\n" +"Módulo para adjuntar un documento de Google a cualquier modelo.\n" +"========================================================\n" #. module: base #: code:addons/base/ir/ir_fields.py:334 #, python-format msgid "Found multiple matches for field '%%(field)s' (%d matches)" msgstr "" +"Se han encontrado múltiples coincidencias para el campo '%%(field)s' (%d " +"resultados)" #. module: base #: selection:base.language.install,lang:0 @@ -2874,6 +3015,14 @@ msgid "" "\n" " " msgstr "" +"\n" +"Plan de cuentas y localización de impuestos peruano. De acuerdo al 2010.\n" +"========================================================================\n" +"\n" +"Plan contable peruano e impuestos de acuerdo a disposiciones vigentes de la " +"SUNAT 2011 (PCGE 2010).\n" +"\n" +" " #. module: base #: view:ir.actions.server:0 @@ -2889,7 +3038,7 @@ msgstr "Argumentos enviados al cliente junto con la etiqueta de vista" #. module: base #: model:ir.module.module,summary:base.module_contacts msgid "Contacts, People and Companies" -msgstr "" +msgstr "Contactos, personas y compañías" #. module: base #: model:res.country,name:base.tt @@ -2998,6 +3147,19 @@ msgid "" " * Unlimited \"Group By\" levels (not stacked), two cross level analysis " "(stacked)\n" msgstr "" +"\n" +"Vistas de gráficos para el cliente web.\n" +"================================\n" +"\n" +" * Interpreta una vista , pero permite cambiar dinámicamente la " +"presentación\n" +" * Tipos de gráficos: de tarta, líneas, áreas, barras, radar\n" +" * Apilados/No apilados para las áreas y las barras\n" +" * Leyendas: arriba, dentro (arriba/izquierda), ocultas\n" +" * Características: descargables como PNG o CSV, examinar tabla de datos, " +"cambiar orientación\n" +" * Niveles de agrupación ilimitados (no apilados), análisis de dos " +"niveles de cruce (apilados)\n" #. module: base #: view:res.groups:0 @@ -3038,7 +3200,7 @@ msgstr "" #: code:addons/base/ir/ir_fields.py:175 #, python-format msgid "'%s' does not seem to be an integer for field '%%(field)s'" -msgstr "" +msgstr "'%s' no parece ser un entero para el campo '%%(field)s'" #. module: base #: model:ir.module.category,description:base.module_category_report_designer @@ -3095,6 +3257,15 @@ msgid "" " * ``base_stage``: stage management\n" " " msgstr "" +"\n" +"Este módulo gestiona estados y etapas. Se deriva de las clases crm_base y " +"crm_case del crm.\n" +"=============================================================================" +"======================\n" +"\n" +" * \"base_state\": gestión de estados\n" +" * \"base_stage\": gestión de etapas\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_web_linkedin @@ -3279,7 +3450,7 @@ msgstr "Tipo de informe desconocido: %s" #. module: base #: model:ir.module.module,summary:base.module_hr_expense msgid "Expenses Validation, Invoicing" -msgstr "" +msgstr "Validación de gastos, facturación" #. module: base #: model:ir.module.module,description:base.module_l10n_be_hr_payroll_account @@ -3289,6 +3460,10 @@ msgid "" "==========================================\n" " " msgstr "" +"\n" +"Datos de contabilidad para las reglas de nóminas belgas.\n" +"==============================================\n" +" " #. module: base #: model:res.country,name:base.am @@ -3298,7 +3473,7 @@ msgstr "Armenia" #. module: base #: model:ir.module.module,summary:base.module_hr_evaluation msgid "Periodical Evaluations, Appraisals, Surveys" -msgstr "" +msgstr "Evaluaciones periódicas, encuestas" #. module: base #: model:ir.actions.act_window,name:base.ir_property_form @@ -3665,7 +3840,7 @@ msgstr "Seleccione el paquete del módulo que quiere importar (archivo .zip):" #. module: base #: view:ir.filters:0 msgid "Personal" -msgstr "" +msgstr "Personal" #. module: base #: field:base.language.export,modules:0 @@ -3760,6 +3935,13 @@ msgid "" "easily\n" "keep track and order all your purchase orders.\n" msgstr "" +"\n" +"Este módulo permite gestionar las solicitudes de compra.\n" +"===========================================================\n" +"\n" +"Cuando se crea un pedido de compra, tiene la oportunidad de guardar la " +"solicitud relacionada. Este nuevo objeto se reagrupará y permitirá rastrear " +"y ordenar fácilmente todos sus pedidos de compra.\n" #. module: base #: help:ir.mail_server,smtp_host:0 @@ -3844,7 +4026,7 @@ msgstr "Derecha-a-izquierda" #. module: base #: model:res.country,name:base.sx msgid "Sint Maarten (Dutch part)" -msgstr "" +msgstr "San Martín (parte holandesa)" #. module: base #: view:ir.actions.act_window:0 @@ -3930,7 +4112,7 @@ msgstr "Togo" #: field:ir.actions.act_window,res_model:0 #: field:ir.actions.client,res_model:0 msgid "Destination Model" -msgstr "" +msgstr "Modelo destino" #. module: base #: selection:ir.sequence,implementation:0 @@ -4013,11 +4195,22 @@ msgid "" "If you need to manage your meetings, you should install the CRM module.\n" " " msgstr "" +"\n" +"Esto es un sistema completo de calendario.\n" +"========================================\n" +"\n" +"Soporta:\n" +"------------\n" +" - Calendario de eventos\n" +" - Eventos recurrentes\n" +"\n" +"Si necesita gestionar sus reuniones, debería instalar el módulo 'crm'.\n" +" " #. module: base #: model:res.country,name:base.je msgid "Jersey" -msgstr "" +msgstr "Jersey" #. module: base #: model:ir.module.module,description:base.module_auth_anonymous @@ -4027,6 +4220,10 @@ msgid "" "==================================\n" " " msgstr "" +"\n" +"Permite el acceso anónimo a OpenERP.\n" +"==================================\n" +" " #. module: base #: view:res.lang:0 @@ -4084,6 +4281,14 @@ msgid "" "invite.\n" "\n" msgstr "" +"\n" +"Este módulo actualiza los memorándum dentro de OpenERP para usar un pad " +"externo.\n" +"=======================================================================\n" +"\n" +"Úselo para actualizar los textos de los memorándum en tiempo real con los " +"usuarios a los que invite.\n" +"\n" #. module: base #: code:addons/base/module/module.py:609 @@ -4109,7 +4314,7 @@ msgstr "Nauru" #: code:addons/base/res/res_company.py:152 #, python-format msgid "Reg" -msgstr "" +msgstr "Reg" #. module: base #: model:ir.model,name:base.model_ir_property @@ -4258,7 +4463,7 @@ msgstr "Compartir cualquier documento" #. module: base #: model:ir.module.module,summary:base.module_crm msgid "Leads, Opportunities, Phone Calls" -msgstr "" +msgstr "Iniciativas, oportunidades, llamadas telefónicas" #. module: base #: view:res.lang:0 @@ -4438,7 +4643,7 @@ msgstr "Por defecto" #. module: base #: model:ir.module.module,summary:base.module_lunch msgid "Lunch Order, Meal, Food" -msgstr "" +msgstr "Pedidos de comida" #. module: base #: view:ir.model.fields:0 @@ -4494,7 +4699,7 @@ msgstr "Expresión" #. module: base #: view:res.company:0 msgid "Header/Footer" -msgstr "Cabecera / Pie de página" +msgstr "Encabezado / Pie de página" #. module: base #: help:ir.mail_server,sequence:0 @@ -4555,7 +4760,7 @@ msgstr "'código' debe ser único." #. module: base #: model:ir.module.module,shortdesc:base.module_knowledge msgid "Knowledge Management System" -msgstr "" +msgstr "Sistema de gestión del conocimiento" #. module: base #: view:workflow.activity:0 @@ -4618,6 +4823,10 @@ msgid "" "==========================\n" "\n" msgstr "" +"\n" +"Vista web del calendario de OpenERP.\n" +"===============================\n" +"\n" #. module: base #: selection:base.language.install,lang:0 @@ -4632,7 +4841,7 @@ msgstr "Tipo de secuencia" #. module: base #: view:base.language.export:0 msgid "Unicode/UTF-8" -msgstr "" +msgstr "Unicode/UTF-8" #. module: base #: selection:base.language.install,lang:0 @@ -4738,7 +4947,7 @@ msgstr "Guinea ecuatorial" #. module: base #: model:ir.module.module,shortdesc:base.module_web_api msgid "OpenERP Web API" -msgstr "" +msgstr "API de la web de OpenERP" #. module: base #: model:ir.module.module,description:base.module_l10n_fr_rib @@ -4792,7 +5001,7 @@ msgstr "ir.acciones.informe.xml" #. module: base #: model:res.country,name:base.ps msgid "Palestinian Territory, Occupied" -msgstr "" +msgstr "Palestina, Territorio ocupado de" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_ch @@ -4950,22 +5159,22 @@ msgstr "Compra" #. module: base #: selection:base.language.install,lang:0 msgid "Portuguese (BR) / Português (BR)" -msgstr "" +msgstr "Portugués (BR) / Português (BR)" #. module: base #: model:ir.model,name:base.model_ir_needaction_mixin msgid "ir.needaction_mixin" -msgstr "" +msgstr "Mezcla de acción necesaria" #. module: base #: view:base.language.export:0 msgid "This file was generated using the universal" -msgstr "" +msgstr "Este archivo se ha generado usando el universal" #. module: base #: model:res.partner.category,name:base.res_partner_category_7 msgid "IT Services" -msgstr "" +msgstr "Servicios TI" #. module: base #: model:ir.module.category,name:base.module_category_specific_industry_applications @@ -4981,7 +5190,7 @@ msgstr "Integración con Google Docs" #: code:addons/base/ir/ir_fields.py:328 #, python-format msgid "name" -msgstr "" +msgstr "nombre" #. module: base #: model:ir.module.module,description:base.module_mrp_operations @@ -5027,7 +5236,7 @@ msgstr "Saltar" #. module: base #: model:ir.module.module,shortdesc:base.module_event_sale msgid "Events Sales" -msgstr "" +msgstr "Ventas de eventos" #. module: base #: model:res.country,name:base.ls @@ -5109,7 +5318,7 @@ msgstr "Guardar" #. module: base #: field:ir.actions.report.xml,report_xml:0 msgid "XML Path" -msgstr "" +msgstr "Ruta XML" #. module: base #: model:res.country,name:base.bj @@ -5151,7 +5360,7 @@ msgstr "Clave" #. module: base #: field:res.company,rml_header:0 msgid "RML Header" -msgstr "Cabecera RML" +msgstr "Encabezado RML" #. module: base #: help:res.country,address_format:0 @@ -5205,7 +5414,7 @@ msgstr "Seguridad" #. module: base #: selection:base.language.install,lang:0 msgid "Portuguese / Português" -msgstr "" +msgstr "Portugués / Português" #. module: base #: code:addons/base/ir/ir_model.py:364 @@ -5223,7 +5432,7 @@ msgstr "Sólo si esta cuenta bancaria pertenece a su compañía" #: code:addons/base/ir/ir_fields.py:338 #, python-format msgid "Unknown sub-field '%s'" -msgstr "" +msgstr "Sub-campo '%s' desconocido" #. module: base #: model:res.country,name:base.za @@ -5329,6 +5538,10 @@ msgid "" "================\n" "\n" msgstr "" +"\n" +"API de la web de OpenERP.\n" +"======================\n" +"\n" #. module: base #: selection:res.request,state:0 @@ -5347,7 +5560,7 @@ msgstr "Fecha" #. module: base #: model:ir.module.module,shortdesc:base.module_event_moodle msgid "Event Moodle" -msgstr "" +msgstr "Evento Moodle" #. module: base #: model:ir.module.module,description:base.module_email_template @@ -5398,12 +5611,12 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_partner_category_form msgid "Partner Tags" -msgstr "" +msgstr "Etiquetas de empresa" #. module: base #: view:res.company:0 msgid "Preview Header/Footer" -msgstr "" +msgstr "Previsualizar encabezado/pie de página" #. module: base #: field:ir.ui.menu,parent_id:0 @@ -5437,12 +5650,12 @@ msgstr "Separador de decimales" #: code:addons/orm.py:5245 #, python-format msgid "Missing required value for the field '%s'." -msgstr "" +msgstr "Falta el valor requerido para el campo '%s'." #. module: base #: model:ir.model,name:base.model_res_partner_address msgid "res.partner.address" -msgstr "" +msgstr "Dirección de empresa" #. module: base #: view:ir.rule:0 @@ -5487,7 +5700,7 @@ msgstr "Isla de Man" #. module: base #: help:ir.actions.client,res_model:0 msgid "Optional model, mostly used for needactions." -msgstr "" +msgstr "Modelo opcional, usado en su mayoría para acciones requeridas." #. module: base #: field:ir.attachment,create_uid:0 @@ -5502,7 +5715,7 @@ msgstr "Isla Bouvet" #. module: base #: field:ir.model.constraint,type:0 msgid "Constraint Type" -msgstr "" +msgstr "Tipo de restricción" #. module: base #: field:res.company,child_ids:0 @@ -5563,6 +5776,10 @@ msgid "" "=======================\n" " " msgstr "" +"\n" +"Permite a los usuarios acceder.\n" +"==========================\n" +" " #. module: base #: model:res.country,name:base.zm @@ -5577,7 +5794,7 @@ msgstr "Iniciar asistente de configuración" #. module: base #: model:ir.module.module,summary:base.module_mrp msgid "Manufacturing Orders, Bill of Materials, Routing" -msgstr "" +msgstr "Órdenes de fabricación, lista de materiales, rutas de producción" #. module: base #: view:ir.module.module:0 @@ -5722,7 +5939,7 @@ msgstr "Configuración de la precisión decimal" #: model:ir.model,name:base.model_ir_actions_act_url #: selection:ir.ui.menu,action:0 msgid "ir.actions.act_url" -msgstr "" +msgstr "URL de acción" #. module: base #: model:ir.ui.menu,name:base.menu_translation_app @@ -5736,6 +5953,9 @@ msgid "" "

You should try others search criteria.

\n" " " msgstr "" +"

¡No se ha encontrado ningún módulo!

\n" +"

Debería intentar otros criterios de búsqueda.

\n" +" " #. module: base #: model:ir.model,name:base.model_ir_module_module @@ -5875,7 +6095,7 @@ msgstr "" #. module: base #: view:ir.translation:0 msgid "Comments" -msgstr "" +msgstr "Comentarios" #. module: base #: model:res.country,name:base.et @@ -5996,6 +6216,13 @@ msgid "" "membership products (schemes).\n" " " msgstr "" +"\n" +"Este módulo configura los módulos relacionados con una asociación.\n" +"==============================================================\n" +"\n" +"Instala el perfil para asociaciones para gestionar eventos, registros, " +"asociados y productos de asociados (esquemas).\n" +" " #. module: base #: model:ir.ui.menu,name:base.menu_base_config @@ -6033,7 +6260,7 @@ msgstr "" #: code:addons/base/ir/workflow/workflow.py:99 #, python-format msgid "Operation forbidden" -msgstr "" +msgstr "Operación prohibida" #. module: base #: view:ir.actions.server:0 @@ -6047,6 +6274,9 @@ msgid "" "deleting it (if you delete a native record rule, it may be re-created when " "you reload the module." msgstr "" +"Si desmarca el campo activo, se deshabilitará la regla de registro sin " +"eliminarla (si elimina una regla de registro nativa, se recreará cuando " +"recargue el módulo)." #. module: base #: selection:base.language.install,lang:0 @@ -6063,6 +6293,12 @@ msgid "" "Allows users to create custom dashboard.\n" " " msgstr "" +"\n" +"Deja al usuario crear un tablero personalizado.\n" +"========================================\n" +"\n" +"Permite al usuario crear un tablero personalizado.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.ir_access_act @@ -6198,12 +6434,16 @@ msgid "" "========================\n" "\n" msgstr "" +"\n" +"Vista kanban de OpenERP web.\n" +"==========================\n" +"\n" #. module: base #: code:addons/base/ir/ir_fields.py:183 #, python-format msgid "'%s' does not seem to be a number for field '%%(field)s'" -msgstr "" +msgstr "'%s' no parece ser un número para el campo '%%(field)s'" #. module: base #: help:res.country.state,name:0 @@ -6251,7 +6491,7 @@ msgstr "Objeto afectado por esta regla" #. module: base #: selection:ir.actions.act_window,target:0 msgid "Inline View" -msgstr "" +msgstr "Vista incorporada" #. module: base #: field:ir.filters,is_default:0 @@ -6390,7 +6630,7 @@ msgstr "Malasia" #: code:addons/base/ir/ir_sequence.py:131 #, python-format msgid "Increment number must not be zero." -msgstr "" +msgstr "El número de incremento no debe ser cero." #. module: base #: model:ir.module.module,shortdesc:base.module_account_cancel @@ -6400,7 +6640,7 @@ msgstr "Cancelar asientos" #. module: base #: field:res.partner,tz_offset:0 msgid "Timezone offset" -msgstr "" +msgstr "Zona horaria" #. module: base #: model:ir.module.module,description:base.module_marketing_campaign @@ -6461,6 +6701,13 @@ msgid "" "Price and Cost Price.\n" " " msgstr "" +"\n" +"Este módulo añadir el campo 'Margen' en los pedidos de venta.\n" +"===================================================\n" +"\n" +"Da la rentabilidad calculando la diferencia entre el precio unitario y el " +"precio de coste.\n" +" " #. module: base #: selection:ir.actions.todo,type:0 @@ -6498,6 +6745,8 @@ msgid "" "the user will be able to manage his own human resources stuff (leave " "request, timesheets, ...), if he is linked to an employee in the system." msgstr "" +"el usuario podrá gestionar su propio material de recursos humanos (petición " +"de ausencia, partes de horas, ...), si se enlaza a un empleado en el sistema." #. module: base #: code:addons/orm.py:2247 @@ -6594,7 +6843,7 @@ msgstr "ir.cron" #. module: base #: model:res.country,name:base.cw msgid "Curaçao" -msgstr "" +msgstr "Curaçao" #. module: base #: view:ir.sequence:0 @@ -6657,6 +6906,7 @@ msgstr "Rastro de auditoría" #, python-format msgid "Value '%s' not found in selection field '%%(field)s'" msgstr "" +"El valor '%s' no se ha encontrado en el campo de selección '%%(field)s'" #. module: base #: model:res.country,name:base.sd @@ -6763,7 +7013,7 @@ msgstr "Algunas veces llamado BIC o Swift" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_in msgid "Indian - Accounting" -msgstr "" +msgstr "India - Contabilidad" #. module: base #: field:res.partner,mobile:0 @@ -6796,12 +7046,12 @@ msgstr "Formato de hora" #. module: base #: field:res.company,rml_header3:0 msgid "RML Internal Header for Landscape Reports" -msgstr "" +msgstr "Encabezado interno RML para informes apaisados" #. module: base #: model:res.groups,name:base.group_partner_manager msgid "Contact Creation" -msgstr "" +msgstr "Creación de contactos" #. module: base #: view:ir.module.module:0 @@ -6853,6 +7103,12 @@ msgid "" "This module provides the core of the OpenERP Web Client.\n" " " msgstr "" +"\n" +"Módulo principal de OpenERP web.\n" +"=============================\n" +"\n" +"Este módulo provee el núcleo del cliente web de OpenERP.\n" +" " #. module: base #: view:ir.sequence:0 @@ -6959,12 +7215,12 @@ msgstr "Elementos de trabajo" #: code:addons/base/res/res_bank.py:195 #, python-format msgid "Invalid Bank Account Type Name format." -msgstr "" +msgstr "Formato de nombre de tipo de banco no válido." #. module: base #: view:ir.filters:0 msgid "Filters visible only for one user" -msgstr "" +msgstr "Filtros visibles sólo para un usuario" #. module: base #: model:ir.model,name:base.model_ir_attachment @@ -7035,12 +7291,12 @@ msgstr "" #. module: base #: model:res.groups,comment:base.group_hr_user msgid "the user will be able to approve document created by employees." -msgstr "" +msgstr "el usuario podrá aprobar documentos creados por los empleados." #. module: base #: field:ir.ui.menu,needaction_enabled:0 msgid "Target model uses the need action mechanism" -msgstr "" +msgstr "El modelo objetivo usa el mecanismo de acción requerida" #. module: base #: help:ir.model.fields,relation:0 @@ -7094,7 +7350,7 @@ msgstr "¡Archivo de módulo importado con éxito!" #: view:ir.model.constraint:0 #: model:ir.ui.menu,name:base.ir_model_constraint_menu msgid "Model Constraints" -msgstr "" +msgstr "Restricciones del modelo" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_timesheet @@ -7116,6 +7372,10 @@ msgid "" "============================================================\n" " " msgstr "" +"\n" +"Contabilidad china\n" +"============================================================\n" +" " #. module: base #: model:res.country,name:base.lc @@ -7141,7 +7401,7 @@ msgstr "Somalia" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_doctor msgid "Dr." -msgstr "" +msgstr "Dr." #. module: base #: model:res.groups,name:base.group_user @@ -7206,7 +7466,7 @@ msgstr "Copia de" #. module: base #: field:ir.model.data,display_name:0 msgid "Record Name" -msgstr "" +msgstr "Nombre del registro" #. module: base #: model:ir.model,name:base.model_ir_actions_client @@ -7217,12 +7477,12 @@ msgstr "ir.actions.client" #. module: base #: model:res.country,name:base.io msgid "British Indian Ocean Territory" -msgstr "Territorio Británico del Océano Índico" +msgstr "Territorio británico del Océano Índico" #. module: base #: model:ir.actions.server,name:base.action_server_module_immediate_install msgid "Module Immediate Install" -msgstr "" +msgstr "Módulo de instalación inmediata" #. module: base #: view:ir.actions.server:0 @@ -7256,6 +7516,12 @@ msgid "" "includes\n" "taxes and the Quetzal currency." msgstr "" +"\n" +"Éste es el módulo base para gestionar el plan de cuentas para Guatemala.\n" +"=====================================================================\n" +"\n" +"Agrega una nomenclatura contable para Guatemala. También incluye impuestos y " +"la moneda del Quetzal." #. module: base #: selection:res.lang,direction:0 @@ -7292,7 +7558,7 @@ msgstr "Nombre completo" #. module: base #: view:ir.attachment:0 msgid "on" -msgstr "" +msgstr "en" #. module: base #: code:addons/base/module/module.py:284 @@ -7349,7 +7615,7 @@ msgstr "En múltiples doc." #: view:res.users:0 #: view:wizard.ir.model.menu.create:0 msgid "or" -msgstr "" +msgstr "o" #. module: base #: model:ir.module.module,shortdesc:base.module_account_accountant @@ -7574,6 +7840,10 @@ msgid "" "use the same timezone that is otherwise used to pick and render date and " "time values: your computer's timezone." msgstr "" +"Zona horaria de la empresa, usada para mostrar la fecha y hora adecuadas en " +"los informes impresos. Es importante establecer un valor para este campo. " +"Debería usar la misma zona horaria que se coge en caso contrario para " +"mostrar los valores de fecha y hora: la zona horaria de su ordenador." #. module: base #: model:ir.module.module,shortdesc:base.module_account_analytic_default @@ -7588,7 +7858,7 @@ msgstr "mdx" #. module: base #: view:ir.cron:0 msgid "Scheduled Action" -msgstr "" +msgstr "Acción planificada" #. module: base #: model:res.country,name:base.bi @@ -7628,6 +7898,12 @@ msgid "" "=============\n" " " msgstr "" +"\n" +"Este módulo añade el menú y características de eventos a su portal si " +"'event' y 'portal' están instalados.\n" +"=============================================================================" +"=============\n" +" " #. module: base #: help:ir.sequence,number_next:0 @@ -7637,12 +7913,12 @@ msgstr "Número siguiente de esta secuencia." #. module: base #: view:res.partner:0 msgid "at" -msgstr "" +msgstr "en" #. module: base #: view:ir.rule:0 msgid "Rule Definition (Domain Filter)" -msgstr "" +msgstr "Definición de regla (filtro de dominio)" #. module: base #: selection:ir.actions.act_url,target:0 @@ -7704,12 +7980,12 @@ msgstr "Contraseña" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_claim msgid "Portal Claim" -msgstr "" +msgstr "Reclamaciones en el portal" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_pe msgid "Peru Localization Chart Account" -msgstr "" +msgstr "Plan de cuentas peruano" #. module: base #: model:ir.module.module,description:base.module_auth_oauth @@ -7718,6 +7994,9 @@ msgid "" "Allow users to login through OAuth2 Provider.\n" "=============================================\n" msgstr "" +"\n" +"Permite a los usuarios iniciar sesión a través de un proveedor OAuth2.\n" +"==========================================================\n" #. module: base #: model:ir.actions.act_window,name:base.action_model_fields @@ -7737,7 +8016,7 @@ msgstr "Empleados" #. module: base #: field:res.company,rml_header2:0 msgid "RML Internal Header" -msgstr "Cabecera interna RML" +msgstr "Encabezado interno RML" #. module: base #: field:ir.actions.act_window,search_view_id:0 @@ -7747,7 +8026,7 @@ msgstr "Ref. vista búsqueda" #. module: base #: help:res.users,partner_id:0 msgid "Partner-related data of the user" -msgstr "" +msgstr "Datos del usuario relativos a la empresa" #. module: base #: model:ir.module.module,description:base.module_crm_todo @@ -7757,6 +8036,10 @@ msgid "" "==========================================\n" " " msgstr "" +"\n" +"Lista de cosas por hacer para las iniciativas y oportunidades del CRM.\n" +"========================================================\n" +" " #. module: base #: view:ir.mail_server:0 @@ -7863,7 +8146,7 @@ msgstr "Canadá" #. module: base #: view:base.language.export:0 msgid "Launchpad" -msgstr "" +msgstr "Launchpad" #. module: base #: help:res.currency.rate,currency_rate_type_id:0 @@ -7930,12 +8213,12 @@ msgstr "Campo personalizado" #. module: base #: model:ir.module.module,summary:base.module_account_accountant msgid "Financial and Analytic Accounting" -msgstr "" +msgstr "Contabilidad financiera y analítica" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_project msgid "Portal Project" -msgstr "" +msgstr "Proyectos en el portal" #. module: base #: model:res.country,name:base.cc @@ -7968,7 +8251,7 @@ msgstr "Campos tipo de banco" #. module: base #: constraint:ir.rule:0 msgid "Rules can not be applied on Transient models." -msgstr "" +msgstr "Las reglas no se pueden aplicar en modelos transitorios." #. module: base #: selection:base.language.install,lang:0 @@ -8051,12 +8334,12 @@ msgstr "Asistente" #: code:addons/base/ir/ir_fields.py:304 #, python-format msgid "database id" -msgstr "" +msgstr "id de la base de datos" #. module: base #: model:ir.module.module,shortdesc:base.module_base_import msgid "Base import" -msgstr "" +msgstr "Importación base" #. module: base #: report:ir.module.reference:0 @@ -8089,6 +8372,8 @@ msgid "" "Select this if you want to set company's address information for this " "contact" msgstr "" +"Seleccione esto si quiere establecer la información de la dirección de la " +"compañía para este contacto" #. module: base #: field:ir.default,field_name:0 @@ -8127,6 +8412,8 @@ msgid "" "This field holds the image used as avatar for this contact, limited to " "1024x1024px" msgstr "" +"Este campo contiene la imagen utilizada como avatar para este contacto, " +"limitada a 1024x1024 px" #. module: base #: model:res.country,name:base.to @@ -8209,7 +8496,7 @@ msgstr "Numeración de la secuencia de asientos" #. module: base #: view:base.language.export:0 msgid "POEdit" -msgstr "" +msgstr "POEdit" #. module: base #: view:ir.values:0 @@ -8219,12 +8506,12 @@ msgstr "Acciones cliente" #. module: base #: field:res.partner.bank.type,field_ids:0 msgid "Type Fields" -msgstr "" +msgstr "Campos de tipo" #. module: base #: model:ir.module.module,summary:base.module_hr_recruitment msgid "Jobs, Recruitment, Applications, Job Interviews" -msgstr "" +msgstr "Trabajos, reclutamiento, solicitudes, entrevista de trabajo" #. module: base #: code:addons/base/module/module.py:513 @@ -8253,7 +8540,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_pad_project msgid "Pad on tasks" -msgstr "" +msgstr "Pad en las tareas" #. module: base #: model:ir.model,name:base.model_base_update_translations @@ -8271,7 +8558,7 @@ msgstr "¡Aviso!" #. module: base #: view:ir.rule:0 msgid "Full Access Right" -msgstr "" +msgstr "Derecho de acceso total" #. module: base #: field:res.partner.category,parent_id:0 @@ -8286,7 +8573,7 @@ msgstr "Finlandia" #. module: base #: model:ir.module.module,shortdesc:base.module_web_shortcuts msgid "Web Shortcuts" -msgstr "" +msgstr "Accesos rápidos para web" #. module: base #: view:res.partner:0 @@ -8330,17 +8617,17 @@ msgstr "Contabilidad analítica" #. module: base #: model:ir.model,name:base.model_ir_model_constraint msgid "ir.model.constraint" -msgstr "" +msgstr "Restricción de modelo" #. module: base #: model:ir.module.module,shortdesc:base.module_web_graph msgid "Graph Views" -msgstr "" +msgstr "Vistas de gráfico" #. module: base #: help:ir.model.relation,name:0 msgid "PostgreSQL table name implementing a many2many relation." -msgstr "" +msgstr "Nombre de la tabla PostgreSQL que implementa una relación many2many." #. module: base #: model:ir.module.module,description:base.module_base @@ -8349,6 +8636,9 @@ msgid "" "The kernel of OpenERP, needed for all installation.\n" "===================================================\n" msgstr "" +"\n" +"El núcleo de OpenERP, necesario para todas las instalaciones.\n" +"===================================================\n" #. module: base #: model:ir.model,name:base.model_ir_server_object_lines @@ -8373,7 +8663,7 @@ msgstr "Kuwait" #. module: base #: model:ir.module.module,shortdesc:base.module_account_followup msgid "Payment Follow-up Management" -msgstr "" +msgstr "Gestión de seguimientos de pago" #. module: base #: field:workflow.workitem,inst_id:0 @@ -8444,7 +8734,7 @@ msgstr "Siempre puede ser buscado" #. module: base #: help:res.country.state,code:0 msgid "The state code in max. three chars." -msgstr "" +msgstr "El código de provincia en tres caracteres como máximo." #. module: base #: model:res.country,name:base.hk @@ -8454,7 +8744,7 @@ msgstr "Hong Kong" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_sale msgid "Portal Sale" -msgstr "" +msgstr "Ventas en el portal" #. module: base #: field:ir.default,ref_id:0 @@ -8469,7 +8759,7 @@ msgstr "Filipinas" #. module: base #: model:ir.module.module,summary:base.module_hr_timesheet_sheet msgid "Timesheets, Attendances, Activities" -msgstr "" +msgstr "Partes de horas, asistencias, actividades" #. module: base #: model:res.country,name:base.ma @@ -8497,6 +8787,8 @@ msgid "" "Translation features are unavailable until you install an extra OpenERP " "translation." msgstr "" +"Las características de traducción no están disponibles hasta que no instale " +"una traducción extra de OpenERP." #. module: base #: model:ir.module.module,description:base.module_l10n_nl @@ -8585,7 +8877,7 @@ msgstr "Informe detallado de objetos" #. module: base #: model:ir.module.module,shortdesc:base.module_web_analytics msgid "Google Analytics" -msgstr "" +msgstr "Google Analytics" #. module: base #: model:ir.module.module,description:base.module_note @@ -8613,7 +8905,7 @@ msgstr "Dominica" #. module: base #: field:ir.translation,name:0 msgid "Translated field" -msgstr "" +msgstr "Campo traducible" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_location @@ -8633,17 +8925,17 @@ msgstr "Nepal" #. module: base #: model:ir.module.module,shortdesc:base.module_document_page msgid "Document Page" -msgstr "" +msgstr "Página de documento" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_ar msgid "Argentina Localization Chart Account" -msgstr "" +msgstr "Plan de cuentas argentino" #. module: base #: field:ir.module.module,description_html:0 msgid "Description HTML" -msgstr "" +msgstr "Descripción HTML" #. module: base #: help:res.groups,implied_ids:0 @@ -8654,7 +8946,7 @@ msgstr "" #. module: base #: model:ir.module.module,summary:base.module_note msgid "Sticky notes, Collaborative, Memos" -msgstr "" +msgstr "Notas fijadas, colaborativos, memorándums" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_attendance @@ -8693,6 +8985,9 @@ msgid "" "If the selected language is loaded in the system, all documents related to " "this contact will be printed in this language. If not, it will be English." msgstr "" +"Si el idioma seleccionado está cargado en el sistema, todos los documentos " +"relacionados con el contacto se imprimirán en este idioma. Si no, se " +"imprimirán en inglés." #. module: base #: model:ir.module.module,description:base.module_hr_evaluation @@ -8789,7 +9084,7 @@ msgstr "Esloveno / slovenščina" #. module: base #: field:res.currency,position:0 msgid "Symbol Position" -msgstr "" +msgstr "Posición del símbolo" #. module: base #: model:ir.module.module,description:base.module_l10n_de @@ -8827,6 +9122,10 @@ msgid "" "\n" "(Document type: %s)" msgstr "" +"Para este tipo de documento, puede acceder sólo a los registros creados por " +"uno mismo.\n" +"\n" +"(Tipo de documento: %s)" #. module: base #: view:base.language.export:0 @@ -8839,6 +9138,8 @@ msgid "" "This field specifies whether the model is transient or not (i.e. if records " "are automatically deleted from the database or not)" msgstr "" +"Este campo especifica si el modelo es transitorio o no (por ejemplo si los " +"registros se eliminan automáticamente de la base de datos o no)" #. module: base #: code:addons/base/ir/ir_mail_server.py:441 @@ -8882,6 +9183,7 @@ msgstr "Lo siento, no está autorizado a eliminar este documento." #: constraint:ir.rule:0 msgid "Rules can not be applied on the Record Rules model." msgstr "" +"Las reglas no se han podido aplicar en el modelo de reglas de registro." #. module: base #: field:res.partner,supplier:0 @@ -8899,7 +9201,7 @@ msgstr "Multi acciones" #. module: base #: model:ir.module.module,summary:base.module_mail msgid "Discussions, Mailing Lists, News" -msgstr "" +msgstr "Discusiones, listas de correo, noticias" #. module: base #: model:ir.module.module,description:base.module_fleet @@ -8950,7 +9252,7 @@ msgstr "Samoa Americana" #. module: base #: view:ir.attachment:0 msgid "My Document(s)" -msgstr "" +msgstr "Mis documentos" #. module: base #: help:ir.actions.act_window,res_model:0 @@ -9000,7 +9302,7 @@ msgstr "Error de usuario" #. module: base #: model:ir.module.module,summary:base.module_project_issue msgid "Support, Bug Tracker, Helpdesk" -msgstr "" +msgstr "Soporte, gestión de errores, mesa de ayuda" #. module: base #: model:res.country,name:base.ae @@ -9014,6 +9316,8 @@ msgid "" "related to a model that uses the need_action mechanism, this field is set to " "true. Otherwise, it is false." msgstr "" +"Si la acción de menú es act_window, y si esta acción está relacionado con un " +"modelo que usa el mecanismo de acción requerida, este campo estará marcado." #. module: base #: code:addons/orm.py:3929 @@ -9226,11 +9530,15 @@ msgid "" "=============================\n" "\n" msgstr "" +"\n" +"Vista Gantt de OpenERP web.\n" +"=============================\n" +"\n" #. module: base #: model:ir.module.module,shortdesc:base.module_base_status msgid "State/Stage Management" -msgstr "" +msgstr "Gestión de estados/etapas" #. module: base #: model:ir.module.category,name:base.module_category_warehouse_management @@ -9259,6 +9567,18 @@ msgid "" "\n" " " msgstr "" +"\n" +"Este módulo muestra los procesos básicos involucrados en los módulos " +"seleccionados y en la secuencia en los que ocurren.\n" +"=============================================================================" +"=========================\n" +"\n" +"**Nota:** Esto aplica a todos los módulos conteniendo " +"modulename_process.xml.\n" +"\n" +"**e.g.** product/process/product_process.xml.\n" +"\n" +" " #. module: base #: view:res.lang:0 @@ -9284,7 +9604,7 @@ msgstr "Informe" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_prof msgid "Prof." -msgstr "" +msgstr "Prof." #. module: base #: code:addons/base/ir/ir_mail_server.py:239 @@ -9320,7 +9640,7 @@ msgstr "Ninguno" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_holidays msgid "Leave Management" -msgstr "" +msgstr "Gestión de ausencias" #. module: base #: model:res.company,overdue_msg:base.main_company @@ -9336,6 +9656,16 @@ msgid "" "Thank you in advance for your cooperation.\n" "Best Regards," msgstr "" +"Estimado/a señor/señora,\n" +"\n" +"Nuestros registros indican que algunos pagos en nuestra cuenta están aún " +"pendientes. Puede encontrar los detalles a continuación.\n" +"Si la cantidad ha sido ya pagada, por favor, descarte esta notificación. En " +"otro caso, por favor remítanos el importe total abajo indicado.\n" +"Si tiene alguna pregunta con respecto a su cuenta, por favor contáctenos.\n" +"\n" +"Gracias de antemano por su colaboración.\n" +"Saludos cordiales," #. module: base #: view:ir.module.category:0 @@ -9360,7 +9690,7 @@ msgstr "Mali" #. module: base #: model:ir.ui.menu,name:base.menu_project_config_project msgid "Stages" -msgstr "" +msgstr "Etapas" #. module: base #: selection:base.language.install,lang:0 @@ -9387,6 +9717,12 @@ msgid "" "==========================================================\n" " " msgstr "" +"\n" +"Este módulo añade una lista de empleados a su página de contacto del portal " +"si 'hr' y 'portal_crm' (que crea la página de contacto) están instalados.\n" +"=============================================================================" +"============================================\n" +" " #. module: base #: model:res.country,name:base.bn @@ -9409,7 +9745,7 @@ msgstr "Interfaz de usuario" #. module: base #: model:ir.module.module,shortdesc:base.module_mrp_byproduct msgid "MRP Byproducts" -msgstr "" +msgstr "Subproductos MRP" #. module: base #: field:res.request,ref_partner_id:0 @@ -9419,7 +9755,7 @@ msgstr "Ref. empresa" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_expense msgid "Expense Management" -msgstr "" +msgstr "Gestión de gastos" #. module: base #: field:ir.attachment,create_date:0 @@ -9453,6 +9789,12 @@ msgid "" "Indian accounting chart and localization.\n" " " msgstr "" +"\n" +"Plan de cuentas indio.\n" +"====================================\n" +"\n" +"Plan de cuentas y localización indios.\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_uy @@ -9481,6 +9823,14 @@ msgid "" "If set to true it allows user to cancel entries & invoices.\n" " " msgstr "" +"\n" +"Permite cancelar asientos contables.\n" +"===============================\n" +"\n" +"Este módulo añade el campo 'Permitir cancelar asientos' en la vista de " +"formulario de los diarios contables.\n" +"Si está establecido a True, permitirá cancelar asientos y facturas.\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_plugin @@ -9567,7 +9917,7 @@ msgstr "%H - Hora (reloj 24-horas) [00,23]." #. module: base #: field:ir.model.fields,on_delete:0 msgid "On Delete" -msgstr "" +msgstr "Al eliminar" #. module: base #: code:addons/base/ir/ir_model.py:340 @@ -9602,6 +9952,13 @@ msgid "" "=======================================================\n" " " msgstr "" +"\n" +"Este módulo añade una página de contacto (con un formulario de contacto " +"creando una iniciativa cuando se envía) al portal si 'crm' y 'portal' están " +"instalados.\n" +"=============================================================================" +"=======================================================\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_us @@ -9627,7 +9984,7 @@ msgstr "Cancelar" #: code:addons/orm.py:1509 #, python-format msgid "Unknown database identifier '%s'" -msgstr "" +msgstr "Identificador de base de datos '%s' desconocido" #. module: base #: selection:base.language.export,format:0 @@ -9642,6 +9999,10 @@ msgid "" "=========================\n" "\n" msgstr "" +"\n" +"Vista de diagrama de Openerp web.\n" +"==============================\n" +"\n" #. module: base #: model:res.country,name:base.nt @@ -9681,7 +10042,7 @@ msgstr "" #: code:addons/base/ir/ir_fields.py:317 #, python-format msgid "external id" -msgstr "" +msgstr "id. externo" #. module: base #: view:ir.model:0 @@ -9724,6 +10085,12 @@ msgid "" "=====================\n" " " msgstr "" +"\n" +"Este módulo añade el menú y las características de las incidencias al portal " +"si 'project_issue' y 'portal' están instalados.\n" +"=============================================================================" +"=====================\n" +" " #. module: base #: view:res.lang:0 @@ -9738,7 +10105,7 @@ msgstr "Alemania" #. module: base #: model:ir.module.module,shortdesc:base.module_auth_oauth msgid "OAuth2 Authentication" -msgstr "" +msgstr "Autentificación OAuth2" #. module: base #: view:workflow:0 @@ -9749,6 +10116,12 @@ msgid "" "default value. If you don't do that, your customization will be overwrited " "at the next update or upgrade to a future version of OpenERP." msgstr "" +"Cuando se personaliza un flujo de trabajo, asegúrese de no modificar un nodo " +"o flecha existente, en lugar de añadir nuevos nodos o flechas. Si necesita " +"absolutamente modificar un nodo o flecha, sólo puede cambiar los campos que " +"están vacíos o establecidos a su valor por defecto. Si no hace eso, la " +"personalización será sobrescrita en la próxima actualización a una futura " +"versión de OpenERP." #. module: base #: report:ir.module.reference:0 @@ -9781,7 +10154,7 @@ msgstr "¡El código de moneda debe ser único por compañía!" #: code:addons/base/module/wizard/base_export_language.py:38 #, python-format msgid "New Language (Empty translation template)" -msgstr "" +msgstr "Nuevo idioma (Plantilla de traducción vacía)" #. module: base #: model:ir.module.module,description:base.module_auth_reset_password @@ -9794,6 +10167,14 @@ msgid "" "Allow administrator to click a button to send a \"Reset Password\" request " "to a user.\n" msgstr "" +"\n" +"Restablece la contraseña\n" +"=====================\n" +"\n" +"Permite a los usuarios restablecer su contraseña desde la página de inicio " +"de sesión.\n" +"Permite a los administradores pulsar un botón para enviar una petición de " +"restablecimiento de la contraseña a los usuarios.\n" #. module: base #: help:ir.actions.server,email:0 @@ -9863,7 +10244,7 @@ msgstr "Egipto" #. module: base #: view:ir.attachment:0 msgid "Creation" -msgstr "" +msgstr "Creación" #. module: base #: help:ir.actions.server,model_id:0 @@ -9907,7 +10288,7 @@ msgstr "Descripción de campos" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_contract_hr_expense msgid "Contracts Management: hr_expense link" -msgstr "" +msgstr "Gestión de contratos: enlace con hr_expense" #. module: base #: view:ir.attachment:0 @@ -9926,7 +10307,7 @@ msgstr "Agrupar por..." #. module: base #: view:base.module.update:0 msgid "Module Update Result" -msgstr "" +msgstr "Resultado de actualización de módulo" #. module: base #: model:ir.module.module,description:base.module_analytic_contract_hr_expense @@ -9937,6 +10318,11 @@ msgid "" "=============================================================================" "=========================\n" msgstr "" +"\n" +"Este módulo modifica la vista de cuenta analítica para mostrar algunos datos " +"relativos al módulo 'hr_expense'.\n" +"=============================================================================" +"=============\n" #. module: base #: field:res.partner,use_parent_address:0 @@ -9946,7 +10332,7 @@ msgstr "Utilizar la dirección de la empresa" #. module: base #: model:ir.module.module,summary:base.module_hr_holidays msgid "Holidays, Allocation and Leave Requests" -msgstr "" +msgstr "Vacaciones, asignaciones y peticiones de ausencia" #. module: base #: model:ir.module.module,description:base.module_web_hello @@ -9956,6 +10342,10 @@ msgid "" "===========================\n" "\n" msgstr "" +"\n" +"Módulo de ejemplo de OpenERP web.\n" +"===============================\n" +"\n" #. module: base #: selection:ir.module.module,state:0 @@ -9993,6 +10383,14 @@ msgid "" "

\n" " " msgstr "" +"

\n" +"Pulse para añadir un contacto en su libreta de direcciones.\n" +"

\n" +"OpenERP le ayuda a gestionar todas las actividades relacionadas con los " +"proveedores: discusiones, historial de oportunidades de negocio, documentos, " +"etc.\n" +"

\n" +" " #. module: base #: model:res.country,name:base.lr @@ -10007,6 +10405,10 @@ msgid "" "=======================\n" "\n" msgstr "" +"\n" +"Suite de prueba de OpenERP web.\n" +"=============================\n" +"\n" #. module: base #: view:ir.model:0 @@ -10151,6 +10553,8 @@ msgstr "Campaña de marketing - Demo" msgid "" "Can not create Many-To-One records indirectly, import the field separately" msgstr "" +"No se puede crear un registro many2one indirectamente. Importe el campo por " +"separado." #. module: base #: field:ir.cron,interval_type:0 @@ -10193,7 +10597,7 @@ msgstr "China - Contabilidad" #. module: base #: sql_constraint:ir.model.constraint:0 msgid "Constraints with the same name are unique per module." -msgstr "" +msgstr "Las restricciones con el mismo nombre son únicas por módulo." #. module: base #: model:ir.module.module,description:base.module_report_intrastat @@ -10205,6 +10609,12 @@ msgid "" "This module gives the details of the goods traded between the countries of\n" "European Union." msgstr "" +"\n" +"Un módulo que añade informes intrastat.\n" +"=====================================\n" +"\n" +"Este módulo ofrece detalles de los bienes comerciados entre países de la " +"Unión Europea." #. module: base #: help:ir.actions.server,loop_action:0 @@ -10238,7 +10648,7 @@ msgstr "res.solicitud" #. module: base #: field:res.partner,image_medium:0 msgid "Medium-sized image" -msgstr "" +msgstr "Imagen mediana" #. module: base #: view:ir.model:0 @@ -10265,7 +10675,7 @@ msgstr "Contenido del archivo" #: view:ir.model.relation:0 #: model:ir.ui.menu,name:base.ir_model_relation_menu msgid "ManyToMany Relations" -msgstr "" +msgstr "Relaciones many2many" #. module: base #: model:res.country,name:base.pa @@ -10336,7 +10746,7 @@ msgstr "Portal" #. module: base #: selection:ir.translation,state:0 msgid "To Translate" -msgstr "" +msgstr "A traducir" #. module: base #: code:addons/base/ir/ir_fields.py:295 @@ -10377,7 +10787,7 @@ msgstr "" #. module: base #: help:ir.model.constraint,name:0 msgid "PostgreSQL constraint or foreign key name." -msgstr "" +msgstr "Restricción PostgreSQL o nombre de la clave externa." #. module: base #: view:res.lang:0 @@ -10397,17 +10807,17 @@ msgstr "Guinea Bissau" #. module: base #: field:ir.actions.report.xml,header:0 msgid "Add RML Header" -msgstr "Añadir cabecera RML" +msgstr "Añadir encabezado RML" #. module: base #: help:res.company,rml_footer:0 msgid "Footer text displayed at the bottom of all reports." -msgstr "" +msgstr "Texto mostrado en el pie de página de todos los informes." #. module: base #: model:ir.module.module,shortdesc:base.module_note_pad msgid "Memos pad" -msgstr "" +msgstr "Pad de memorándums" #. module: base #: model:ir.module.module,description:base.module_pad @@ -10459,7 +10869,7 @@ msgstr "Otras acciones" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_be_coda msgid "Belgium - Import Bank CODA Statements" -msgstr "" +msgstr "Bélgica - Importar extractos bancarios CODA" #. module: base #: selection:ir.actions.todo,state:0 @@ -10513,7 +10923,7 @@ msgstr "Italia" #. module: base #: model:res.groups,name:base.group_sale_salesman msgid "See Own Leads" -msgstr "" +msgstr "Mostrar las iniciativas propias" #. module: base #: view:ir.actions.todo:0 @@ -10524,7 +10934,7 @@ msgstr "Para ejecutar" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_hr_employees msgid "Portal HR employees" -msgstr "" +msgstr "Empleados de RRHH en el portal" #. module: base #: selection:base.language.install,lang:0 @@ -10543,6 +10953,8 @@ msgid "" "Insufficient fields to generate a Calendar View for %s, missing a date_stop " "or a date_delay" msgstr "" +"Campos insuficientes para generar una vista de calendario para %s. Falta un " +"campo date_stop o date_delay." #. module: base #: field:workflow.activity,action:0 @@ -10597,6 +11009,15 @@ msgid "" "associated to every resource. It also manages the leaves of every resource.\n" " " msgstr "" +"\n" +"Módulo para la gestión de recursos.\n" +"===============================\n" +"\n" +"Un recurso representa algo que puede ser planificado (un desarrollador en " +"una tarea o un centro de trabajo en una orden de fabricación). Este módulo " +"gestiona un calendario asociado a cada recurso. También gestiona las " +"ausencias de cada recurso.\n" +" " #. module: base #: model:ir.model,name:base.model_ir_translation @@ -10618,7 +11039,7 @@ msgstr "" #: model:ir.actions.act_window,name:base.action_view_base_module_upgrade #, python-format msgid "Apply Schedule Upgrade" -msgstr "" +msgstr "Aplicar actualización programada" #. module: base #: view:workflow.activity:0 @@ -10651,6 +11072,8 @@ msgid "" "One of the documents you are trying to access has been deleted, please try " "again after refreshing." msgstr "" +"Uno de los documentos al que está intentado acceder ha sido eliminado. " +"Inténtelo por favor de nuevo tras actualizar." #. module: base #: model:ir.model,name:base.model_ir_mail_server @@ -10663,6 +11086,8 @@ msgid "" "If the target model uses the need action mechanism, this field gives the " "number of actions the current user has to perform." msgstr "" +"Si el modelo objetivo usa el mecanismo de acción requerida, este campo da el " +"número de acciones que el usuario tiene que realizar." #. module: base #: selection:base.language.install,lang:0 @@ -10759,7 +11184,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_stock msgid "Sales and Warehouse Management" -msgstr "" +msgstr "Gestión de ventas y almacén" #. module: base #: field:ir.model.fields,model:0 @@ -10829,6 +11254,8 @@ msgstr "Martinica (Francia)" #: help:res.partner,is_company:0 msgid "Check if the contact is a company, otherwise it is a person" msgstr "" +"Marque esta casilla si el contacto es una compañía. En caso contrario, será " +"una persona." #. module: base #: view:ir.sequence.type:0 @@ -10839,7 +11266,7 @@ msgstr "Tipo de secuencias" #: code:addons/base/res/res_bank.py:195 #, python-format msgid "Formating Error" -msgstr "" +msgstr "Error de formato" #. module: base #: model:res.country,name:base.ye @@ -10977,7 +11404,7 @@ msgstr "Email" #. module: base #: model:res.partner.category,name:base.res_partner_category_12 msgid "Office Supplies" -msgstr "" +msgstr "Material de oficina" #. module: base #: code:addons/custom.py:550 @@ -11051,6 +11478,32 @@ msgid "" " Reporting / Accounting / **Follow-ups Analysis\n" "\n" msgstr "" +"\n" +"Módulo para automatizar las cartas para facturas impagadas, con múltiples " +"niveles de aviso.\n" +"=============================================================================" +"====\n" +"\n" +"Puede configurar niveles múltiples de aviso a través del menú:\n" +"---------------------------------------------------------------\n" +" Configuración / Niveles de seguimiento\n" +" \n" +"Una vez se definan, puede imprimir automáticamente avisos cada día pulsando " +"simplemente en el menú:\n" +"-----------------------------------------------------------------------------" +"-------------------------\n" +" Seguimiento de pagos / Enviar cartas y correos electrónicos\n" +"\n" +"Generará un PDF / enviará correos electrónicos / establecerá acciones " +"manuales dependiendo de los diferentes niveles de aviso definidos. Puede " +"definir políticas diferentes para cada compañía.\n" +"\n" +"Tenga en cuenta que si quiere comprobar el nivel de seguimiento para una " +"empresa en concreto, puede hacerlo desde el menú:\n" +"-----------------------------------------------------------------------------" +"-------------------------------------\n" +" Informes / Contabilidad / **Análisis de seguimientos\n" +"\n" #. module: base #: view:ir.rule:0 @@ -11063,7 +11516,7 @@ msgstr "" #. module: base #: model:res.country,name:base.bl msgid "Saint Barthélémy" -msgstr "" +msgstr "San Bartolomé" #. module: base #: selection:ir.module.module,license:0 @@ -11078,7 +11531,7 @@ msgstr "Ecuador" #. module: base #: view:ir.rule:0 msgid "Read Access Right" -msgstr "" +msgstr "Permiso de lectura" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_user_function @@ -11150,12 +11603,12 @@ msgstr "Traducido" #: model:ir.actions.act_window,name:base.action_inventory_form #: model:ir.ui.menu,name:base.menu_action_inventory_form msgid "Default Company per Object" -msgstr "" +msgstr "Compañía por defecto por objeto" #. module: base #: field:ir.ui.menu,needaction_counter:0 msgid "Number of actions the user has to perform" -msgstr "" +msgstr "Número de acciones que el usuario tiene que realizar" #. module: base #: model:ir.module.module,shortdesc:base.module_web_hello @@ -11185,7 +11638,7 @@ msgstr "Dominio" #: code:addons/base/ir/ir_fields.py:167 #, python-format msgid "Use '1' for yes and '0' for no" -msgstr "" +msgstr "Use '1' para sí y '0' para no" #. module: base #: model:ir.module.module,shortdesc:base.module_marketing_campaign @@ -11200,13 +11653,13 @@ msgstr "Nombre provincia" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_be_hr_payroll_account msgid "Belgium - Payroll with Accounting" -msgstr "" +msgstr "Bélgica - Nóminas con contabilidad" #. module: base #: code:addons/base/ir/ir_fields.py:314 #, python-format msgid "Invalid database id '%s' for the field '%%(field)s'" -msgstr "" +msgstr "Id. de base de datos '%s' no válido para el campo '%%(field)s'" #. module: base #: view:res.lang:0 @@ -11367,12 +11820,12 @@ msgstr "Puerto Rico" #. module: base #: model:ir.module.module,shortdesc:base.module_web_tests_demo msgid "Demonstration of web/javascript tests" -msgstr "" +msgstr "Demostración de test JavaScript/Web" #. module: base #: field:workflow.transition,signal:0 msgid "Signal (Button Name)" -msgstr "" +msgstr "Señal (Nombre del botón)" #. module: base #: view:ir.actions.act_window:0 @@ -11466,13 +11919,13 @@ msgstr "Operaciones de fabricación" #. module: base #: view:base.language.export:0 msgid "Here is the exported translation file:" -msgstr "" +msgstr "Aquí está el archivo de traducción exportado:" #. module: base #: field:ir.actions.report.xml,report_rml_content:0 #: field:ir.actions.report.xml,report_rml_content_data:0 msgid "RML Content" -msgstr "" +msgstr "Contenido RML" #. module: base #: view:res.lang:0 @@ -11510,6 +11963,18 @@ msgid "" "automatically new claims based on incoming emails.\n" " " msgstr "" +"\n" +"\n" +"Gestionar reclamaciones de clientes.\n" +"=============================================================================" +"===\n" +"Esta aplicación permite gestionar las reclamaciones y quejas de sus " +"clientes/proveedores.\n" +"\n" +"Está totalmente integrado con la pasarela de correo electrónico, para que " +"puede crear automáticamente nuevas quejas basadas en los correos " +"electrónicos entrantes.\n" +" " #. module: base #: selection:ir.module.module,license:0 @@ -11630,6 +12095,13 @@ msgid "" "\n" "The decimal precision is configured per company.\n" msgstr "" +"\n" +"Configura la precisión del precio si necesita diversos tipos de uso: " +"contabilidad, ventas, compras...\n" +"=============================================================================" +"====================\n" +"\n" +"La precisión decimal se configura por compañía.\n" #. module: base #: selection:res.company,paper_format:0 @@ -11639,7 +12111,7 @@ msgstr "A4" #. module: base #: view:res.config.installer:0 msgid "Configuration Installer" -msgstr "" +msgstr "Instalador de la configuración" #. module: base #: field:res.partner,customer:0 @@ -11660,6 +12132,10 @@ msgid "" "===================================================\n" " " msgstr "" +"\n" +"Este módulo añade el PAD en todas las vistas kanban de proyecto.\n" +"======================================================\n" +" " #. module: base #: field:ir.actions.act_window,context:0 @@ -11726,17 +12202,19 @@ msgid "" "(if you delete a native ACL, it will be re-created when you reload the " "module." msgstr "" +"Si desmarca el campo activo, deshabilitará el ACL sin borrarlo (si borra un " +"ACL nativo, será recreado cuando recargue el módulo)." #. module: base #: model:ir.model,name:base.model_ir_fields_converter msgid "ir.fields.converter" -msgstr "" +msgstr "Convertidor de campos" #. module: base #: code:addons/base/res/res_partner.py:436 #, python-format msgid "Couldn't create contact without email address !" -msgstr "" +msgstr "¡No se puede crear el contacto sin correo electrónico!" #. module: base #: model:ir.module.category,name:base.module_category_manufacturing @@ -11758,12 +12236,12 @@ msgstr "Cancelar instalación" #. module: base #: model:ir.model,name:base.model_ir_model_relation msgid "ir.model.relation" -msgstr "" +msgstr "Relación" #. module: base #: model:ir.module.module,shortdesc:base.module_account_check_writing msgid "Check Writing" -msgstr "" +msgstr "Escritura de cheques" #. module: base #: model:ir.module.module,description:base.module_plugin_outlook @@ -11999,7 +12477,7 @@ msgstr "Reino Unido - Contabilidad" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_madam msgid "Mrs." -msgstr "" +msgstr "Sra." #. module: base #: code:addons/base/ir/ir_model.py:424 @@ -12035,7 +12513,7 @@ msgstr "Expresión del bucle" #. module: base #: model:res.partner.category,name:base.res_partner_category_16 msgid "Retailer" -msgstr "" +msgstr "Minorista" #. module: base #: view:ir.model.fields:0 @@ -12086,6 +12564,8 @@ msgstr "" msgid "" "Please make sure no workitems refer to an activity before deleting it!" msgstr "" +"¡Asegúrese de que ningún elemento de trabajo se refiera a la actividad antes " +"de borrarla!" #. module: base #: model:res.country,name:base.tr @@ -12138,7 +12618,7 @@ msgstr "4. %b, %B ==> Dic, Diciembre" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_cl msgid "Chile Localization Chart Account" -msgstr "" +msgstr "Plan de cuentas chileno" #. module: base #: selection:base.language.install,lang:0 @@ -12239,6 +12719,20 @@ msgid "" "yearly\n" " account reporting (balance, profit & losses).\n" msgstr "" +"\n" +"Plan de cuentas español (PGCE 2008).\n" +"=======================================\n" +"\n" +" * Define las siguientes plantillas de plan de cuentas:\n" +" * Plan de cuentas general español 2008\n" +" * Plan de cuentas general español 2008 para pequeñas y medianas " +"empresas.\n" +" * Define plantillas para los impuestos de ventas y compras\n" +" * Define plantillas de códigos de impuestos\n" +"\n" +"**Nota:** Debe instalar el módulo 'l10n_es_account_balance_report' para los " +"informes de cuentas anuales (balance de situación, cuenta de pérdidas y " +"ganancias).\n" #. module: base #: field:ir.actions.act_url,type:0 @@ -12309,7 +12803,7 @@ msgstr "" #. module: base #: model:res.country,name:base.cd msgid "Congo, Democratic Republic of the" -msgstr "" +msgstr "Congo, República Democrática del" #. module: base #: model:res.country,name:base.cr @@ -12366,7 +12860,7 @@ msgstr "Valor por defecto o referencia a una acción" #. module: base #: field:ir.actions.report.xml,auto:0 msgid "Custom Python Parser" -msgstr "" +msgstr "Analizador Python personalizado" #. module: base #: sql_constraint:res.groups:0 @@ -12376,7 +12870,7 @@ msgstr "¡El nombre del grupo debe ser único!" #. module: base #: help:ir.translation,module:0 msgid "Module this term belongs to" -msgstr "" +msgstr "Módulo al que pertenece este término" #. module: base #: model:ir.module.module,description:base.module_web_view_editor @@ -12387,6 +12881,11 @@ msgid "" "\n" " " msgstr "" +"\n" +"Editor de vistas de OpenERP web.\n" +"============================\n" +"\n" +" " #. module: base #: view:ir.sequence:0 @@ -12435,6 +12934,13 @@ msgid "" "\n" " " msgstr "" +"\n" +"Plan de cuentas y localización de impuesto argentino.\n" +"==================================================\n" +"\n" +"Plan contable argentino e impuestos de acuerdo a disposiciones vigentes.\n" +"\n" +" " #. module: base #: code:addons/fields.py:126 @@ -12516,7 +13022,7 @@ msgstr "Maldivas" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_crm msgid "Portal CRM" -msgstr "" +msgstr "Portal CRM" #. module: base #: model:ir.ui.menu,name:base.next_id_4 @@ -12661,7 +13167,7 @@ msgstr "" #. module: base #: field:ir.actions.report.xml,report_sxw:0 msgid "SXW Path" -msgstr "" +msgstr "Ruta del archivo SXW" #. module: base #: model:ir.module.module,description:base.module_account_asset @@ -12678,6 +13184,15 @@ msgid "" "\n" " " msgstr "" +"\n" +"Gestión financiera y contable de activos.\n" +"==========================================\n" +"\n" +"Este módulo gestiona los activos que posee una compañía o un individuo. " +"Permite seguir las depreciaciones que ocurren en dichos activos, y permite " +"crear los asientos de las líneas de depreciación.\n" +"\n" +" " #. module: base #: field:ir.cron,numbercall:0 @@ -12770,6 +13285,12 @@ msgid "" "Provide Templates for Chart of Accounts, Taxes for Uruguay.\n" "\n" msgstr "" +"\n" +"Plan general de cuentas.\n" +"====================\n" +"\n" +"Provee plantillas para el plan de cuentas y los impuestos para Uruguay.\n" +"\n" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_gr @@ -12890,7 +13411,7 @@ msgstr "Filtros en mis documentos" #. module: base #: model:ir.module.module,summary:base.module_project_gtd msgid "Personal Tasks, Contexts, Timeboxes" -msgstr "" +msgstr "Tareas personales, contextos, tiempos asignados" #. module: base #: model:ir.module.module,description:base.module_l10n_cr @@ -12912,6 +13433,22 @@ msgid "" "please go to http://translations.launchpad.net/openerp-costa-rica.\n" " " msgstr "" +"\n" +"Plan de cuentas para Costa Rica.\n" +"=================================\n" +"\n" +"Incluye:\n" +"---------\n" +" * account.type\n" +" * account.account.template\n" +" * account.tax.template\n" +" * account.tax.code.template\n" +" * account.chart.template\n" +"\n" +"Todo está en inglés con traducción a español. Más traducciones son " +"bienvenidas, por favor vayan a http://translations.launchpad.net/openerp-" +"costa-rica.\n" +" " #. module: base #: model:ir.actions.act_window,name:base.action_partner_supplier_form @@ -12938,7 +13475,7 @@ msgstr "Gabón" #. module: base #: model:ir.module.module,summary:base.module_stock msgid "Inventory, Logistic, Storage" -msgstr "" +msgstr "Inventario, logística, almacenamiento" #. module: base #: view:ir.actions.act_window:0 @@ -12992,7 +13529,7 @@ msgstr "Nueva Caledonia (Francesa)" #. module: base #: field:ir.model,osv_memory:0 msgid "Transient Model" -msgstr "" +msgstr "Model transitorio" #. module: base #: model:res.country,name:base.cy @@ -13050,7 +13587,7 @@ msgstr "Preferencias" #. module: base #: model:res.partner.category,name:base.res_partner_category_9 msgid "Components Buyer" -msgstr "" +msgstr "Comprador de componentes" #. module: base #: view:ir.module.module:0 @@ -13058,6 +13595,8 @@ msgid "" "Do you confirm the uninstallation of this module? This will permanently " "erase all data currently stored by the module!" msgstr "" +"¿Confirma la desinstalación de este módulo? ¡Esto eliminará permanentemente " +"todos los datos almacenados actualmente por el módulo!" #. module: base #: help:ir.cron,function:0 @@ -13131,7 +13670,7 @@ msgstr "Servidores de correo saliente" #. module: base #: model:ir.ui.menu,name:base.menu_custom msgid "Technical" -msgstr "" +msgstr "Técnico" #. module: base #: model:res.country,name:base.cn @@ -13220,6 +13759,18 @@ msgid "" "routing of the assembly operation.\n" " " msgstr "" +"\n" +"Este módulo permite un proceso de acopio intermedio para proveer de materias " +"primas a las órdenes de fabricación.\n" +"=============================================================================" +"=======================\n" +"\n" +"Un ejemplo de uso de este módulo es para gestionar la fabricación realizada " +"por subcontratistas. Para que se puede hacer de este modo, esteblezca el " +"producto ensamblado que es subcontratado a 'No auto\n" +"sub-contracted to 'Sin auto-acopio' y ponga la ubicación del proveedor en la " +"ruta de producción de la operación de ensamblado.\n" +" " #. module: base #: help:multi_company.default,expression:0 @@ -13255,6 +13806,21 @@ msgid "" " A + B + C -> D + E\n" " " msgstr "" +"\n" +"Este módulo permite fabricar varios productos de una orden de fabricación.\n" +"=============================================================================" +"\n" +"\n" +"Puede configurar subproductos en la lista de materiales.\n" +"\n" +"Sin este módulo:\n" +"--------------------\n" +" A + B + C -> D\n" +"\n" +"Con este módulo:\n" +"-----------------\n" +" A + B + C -> D + E\n" +" " #. module: base #: model:res.country,name:base.tf @@ -13334,6 +13900,9 @@ msgid "" "128x128px image, with aspect ratio preserved. Use this field in form views " "or some kanban views." msgstr "" +"Imagen mediana de este contacto. Se redimensiona automáticamente a 128x128 " +"px, con el ratio de aspecto preservado. Se usa este campo en las vistas los " +"formularios y en algunas vistas de kanban." #. module: base #: view:base.update.translations:0 @@ -13372,7 +13941,7 @@ msgstr "Acción a ejecutar" #: field:ir.model,modules:0 #: field:ir.model.fields,modules:0 msgid "In Modules" -msgstr "" +msgstr "En los módulos" #. module: base #: model:ir.module.module,shortdesc:base.module_contacts @@ -13414,6 +13983,15 @@ msgid "" " - InfoLogic UK counties listing\n" " - a few other adaptations" msgstr "" +"\n" +"Ésta es la última localización de OpenERP para Reino Uinido, necesaria la " +"contabilidad de PYMEs de RU con:\n" +"=============================================================================" +"====================\n" +" - un plan de cuentas preparado para CT600\n" +" - una estructura de impuesto preparada para VAT100\n" +" - listado de condados de RU de InfoLogic\n" +" - otras cuantas adaptaciones" #. module: base #: selection:ir.model,state:0 @@ -13441,7 +14019,7 @@ msgstr "ID de impuesto" #. module: base #: model:ir.module.module,shortdesc:base.module_account_bank_statement_extensions msgid "Bank Statement Extensions to Support e-banking" -msgstr "" +msgstr "Extensiones de extracto bancario para soportar e-banking" #. module: base #: field:ir.model.fields,field_description:0 @@ -13503,6 +14081,15 @@ msgid "" "Adds menu to show relevant information to each manager.You can also view the " "report of account analytic summary user-wise as well as month-wise.\n" msgstr "" +"\n" +"Este módulo modifica la vista de contabilidad analítica para mostrar datos " +"importantes para un gestor de proyectos de una compañía de servicios.\n" +"=============================================================================" +"=================================================\n" +"\n" +"Añade un menú para mostrar información relevante a cada gestor. Puede " +"también ver el informe del resumen de contabilidad analítica por usuario y " +"por mes.\n" #. module: base #: model:ir.module.module,description:base.module_hr_payroll_account @@ -13516,6 +14103,14 @@ msgid "" " * Company Contribution Management\n" " " msgstr "" +"\n" +"Sistema de pago genérico de nóminas integrado con contabilidad.\n" +"======================================================\n" +"\n" +" * Codificación de gastos\n" +" * Codificación de pagos\n" +" * Gestión de participación de las empresas\n" +" " #. module: base #: view:base.module.update:0 @@ -13555,6 +14150,8 @@ msgid "" "The user this filter is private to. When left empty the filter is public and " "available to all users." msgstr "" +"El usuario para el que el filtro es privado. Cuando está vacío, el filtro es " +"público y está disponible para todos los usuarios." #. module: base #: field:ir.actions.act_window,auto_refresh:0 @@ -13577,6 +14174,18 @@ msgid "" "\n" "Used, for example, in food industries." msgstr "" +"\n" +"Gestiona diferentes fechas en los productos y en los lotes de producción.\n" +"============================================================\n" +"\n" +"Se gestionan las siguientes fechas:\n" +"-----------------------------------------\n" +" - fecha de caducidad\n" +" - fecha de consumo seguro\n" +" - fecha de eliminación\n" +" - fecha de alerta\n" +"\n" +"Usado, por ejemplo, en la industria de la comida." #. module: base #: help:ir.translation,state:0 @@ -13584,6 +14193,8 @@ msgid "" "Automatically set to let administators find new terms that might need to be " "translated" msgstr "" +"Establecido automáticamente para dejar que los administradores encuentren " +"nuevos términos que necesiten ser traducidos" #. module: base #: code:addons/base/ir/ir_model.py:84 @@ -13610,7 +14221,7 @@ msgstr "Selección antes de fabricación" #. module: base #: model:ir.module.module,summary:base.module_note_pad msgid "Sticky memos, Collaborative" -msgstr "" +msgstr "Memorándums fijados, colaborativos" #. module: base #: model:res.country,name:base.wf @@ -13641,6 +14252,20 @@ msgid "" "* HR Jobs\n" " " msgstr "" +"\n" +"Gestión de recursos humanos.\n" +"==========================\n" +"\n" +"Esta aplicación habilita la gestión de importantes aspectos del personal de " +"su compañía y otros detalles como sus habilidades, contactos, horario...\n" +"\n" +"Puede gestionar:\n" +"----------------------\n" +"* Empleados y jerarquías: Puede definir sus empleados con usuarios y definir " +"jerarquías.\n" +"* Departamentos\n" +"* Puestos\n" +" " #. module: base #: model:ir.module.module,description:base.module_hr_contract @@ -13657,6 +14282,18 @@ msgid "" "You can assign several contracts per employee.\n" " " msgstr "" +"\n" +"Añade toda la información en el formulario de empleado para gestionar " +"contratos.\n" +"====================================================================\n" +"\n" +" * Contrato\n" +" * Lugar de nacimiento\n" +" * Fecha del examen médico\n" +" * Vehículo de empresa\n" +"\n" +"Puede asignar varios contratos por empleado.\n" +" " #. module: base #: view:ir.model.data:0 @@ -13714,6 +14351,8 @@ msgid "" "the user will have access to all records of everyone in the sales " "application." msgstr "" +"el usuario tendrá acceso a todos los registros de todos en la aplicación de " +"ventas." #. module: base #: model:ir.module.module,shortdesc:base.module_event @@ -13768,6 +14407,8 @@ msgid "" " the rightmost column (value) contains the " "translations" msgstr "" +"Formato CSV: puede editarla directamente en su programa de hoja de cálculo " +"favorito, la columna de más a la derecha contiene las traducciones" #. module: base #: model:ir.module.module,description:base.module_account_chart @@ -13813,6 +14454,9 @@ msgid "" "The common interface for plug-in.\n" "=================================\n" msgstr "" +"\n" +"Interfaz común para los conectores.\n" +"=================================\n" #. module: base #: model:ir.module.module,description:base.module_sale_crm @@ -13831,11 +14475,24 @@ msgid "" "modules.\n" " " msgstr "" +"\n" +"Este módulo añade un acceso directo a uno o varios casos de oportunidad en " +"el CRM.\n" +"===========================================================================\n" +"\n" +"Este acceso directo permite generar pedidos de venta basados en el caso " +"seleccionado.\n" +"Si hay diferentes casos abiertos (una lista), genera un pedido de venta por " +"caso.\n" +"El caso se cierra entonces y se enlaza con el pedido de venta generado.\n" +"\n" +"Le recomendamos instalar este módulo si instala los módulos 'sale' y 'crm'.\n" +" " #. module: base #: model:res.country,name:base.bq msgid "Bonaire, Sint Eustatius and Saba" -msgstr "" +msgstr "Bonaire, San Eustaquio y Saba" #. module: base #: model:ir.actions.report.xml,name:base.ir_module_reference_print @@ -13870,6 +14527,10 @@ msgid "" "your home page.\n" "You can track your suppliers, customers and other contacts.\n" msgstr "" +"\n" +"Este módulo da una vista rápida de su libreta de direcciones, accesible " +"desde su página de inicio.\n" +"Puede seguir a los proveedores, clientes y otros contactos.\n" #. module: base #: help:res.company,custom_footer:0 @@ -13893,7 +14554,7 @@ msgstr "Instalar módulos" #. module: base #: model:ir.ui.menu,name:base.menu_import_crm msgid "Import & Synchronize" -msgstr "" +msgstr "Importar y sincronizar" #. module: base #: view:res.partner:0 @@ -13924,7 +14585,7 @@ msgstr "Texto original" #: field:ir.model.constraint,date_init:0 #: field:ir.model.relation,date_init:0 msgid "Initialization Date" -msgstr "" +msgstr "Fecha de inicialización" #. module: base #: model:res.country,name:base.vu @@ -13972,6 +14633,15 @@ msgid "" "OpenOffice. \n" "Once you have modified it you can upload the report using the same wizard.\n" msgstr "" +"\n" +"Este módulo se usa junto con el conector de OpenERP para " +"LibreOffice/OpenOffice.\n" +"====================================================================\n" +"\n" +"Este módulo añade un asistente para importar/exportar informes .sxw que " +"puede modificar en LibreOffice/OpenOffice\n" +"Una vez modificado, puede volver a subir el informe utilizando el mismo " +"asistente.\n" #. module: base #: view:base.module.upgrade:0 @@ -14033,12 +14703,22 @@ msgid "" "order.\n" " " msgstr "" +"\n" +"Este módulo provee facilidades para el usuario para instalar los módulos " +"'mrp' y 'sale' al mismo tiempo.\n" +"=============================================================================" +"=======\n" +"\n" +"Se usa básicamente para gestionar las órdenes de fabricación generadas desde " +"los pedidos de venta. Añade el nombre y la referencia de ventas en la orden " +"de fabricación.\n" +" " #. module: base #: code:addons/base/ir/ir_fields.py:147 #, python-format msgid "no" -msgstr "" +msgstr "no" #. module: base #: field:ir.actions.server,trigger_obj_id:0 @@ -14056,6 +14736,12 @@ msgid "" "=========================\n" " " msgstr "" +"\n" +"Este módulo añade el menú y las características (tareas) de los proyectos al " +"portal si los módulos 'project' y 'portal' están instalados.\n" +"=============================================================================" +"==============================\n" +" " #. module: base #: code:addons/base/module/wizard/base_module_configuration.py:38 @@ -14171,6 +14857,12 @@ msgid "" "Collects web application usage with Google Analytics.\n" " " msgstr "" +"\n" +"Google Analytics.\n" +"==============================\n" +"\n" +"Recopila información de uso de la aplicación con Google Analytics.\n" +" " #. module: base #: help:ir.sequence,implementation:0 @@ -14201,7 +14893,7 @@ msgstr "Luxemburgo" #. module: base #: model:ir.module.module,summary:base.module_base_calendar msgid "Personal & Shared Calendar" -msgstr "" +msgstr "Calendario personal y compartido" #. module: base #: selection:res.request,priority:0 @@ -14217,7 +14909,7 @@ msgstr "Error ! No puede crear menús recursivos" #. module: base #: view:ir.translation:0 msgid "Web-only translations" -msgstr "" +msgstr "Traducciones sólo para web" #. module: base #: view:ir.rule:0 @@ -14313,7 +15005,7 @@ msgstr "Tailandia" #. module: base #: model:ir.module.module,summary:base.module_account_voucher msgid "Send Invoices and Track Payments" -msgstr "" +msgstr "Enviar factura y gestionar pagos" #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_lead @@ -14323,7 +15015,7 @@ msgstr "Iniciativas y Oportunidades" #. module: base #: model:res.country,name:base.gg msgid "Guernsey" -msgstr "" +msgstr "Guernsey" #. module: base #: selection:base.language.install,lang:0 @@ -14460,7 +15152,7 @@ msgstr "Asistencia/Ayuda" #. module: base #: field:ir.rule,perm_write:0 msgid "Apply for Write" -msgstr "" +msgstr "Aplicar para escritura" #. module: base #: model:ir.module.module,description:base.module_stock @@ -14508,6 +15200,12 @@ msgid "" "Web pages\n" " " msgstr "" +"\n" +"Páginas\n" +"=======\n" +"\n" +"Páginas web\n" +" " #. module: base #: help:ir.actions.server,code:0 @@ -14633,6 +15331,8 @@ msgid "" "If this field is empty, the view applies to all users. Otherwise, the view " "applies to the users of those groups only." msgstr "" +"Si este campo está vacío, la vista se aplica a todos los usuarios. En caso " +"contrario, la vista se aplica sólo a los usuarios de estos grupos." #. module: base #: selection:base.language.install,lang:0 @@ -14670,17 +15370,17 @@ msgstr "" #. module: base #: view:base.language.export:0 msgid "Export Settings" -msgstr "" +msgstr "Preferencias de exportación" #. module: base #: field:ir.actions.act_window,src_model:0 msgid "Source Model" -msgstr "" +msgstr "Modelo origen" #. module: base #: view:ir.sequence:0 msgid "Day of the Week (0:Monday): %(weekday)s" -msgstr "" +msgstr "Día de la semana (0: lunes): %(weekday)s" #. module: base #: code:addons/base/module/wizard/base_module_upgrade.py:84 @@ -14694,7 +15394,7 @@ msgstr "¡Dependencia no resuelta!" #: code:addons/base/ir/ir_model.py:1023 #, python-format msgid "Administrator access is required to uninstall a module" -msgstr "" +msgstr "Se requiere acceso como administrador para desinstalar un módulo" #. module: base #: model:ir.model,name:base.model_base_module_configuration @@ -14710,6 +15410,10 @@ msgid "" "\n" "(Document type: %s, Operation: %s)" msgstr "" +"No se ha podido completar la operación por restricciones de seguridad. " +"Contacte por favor con su administrador de sistema.\n" +"\n" +"(Tipo de documento: %s, Operación: %s)" #. module: base #: model:ir.module.module,description:base.module_idea @@ -14734,6 +15438,8 @@ msgid "" "%s This might be '%s' in the current model, or a field of the same name in " "an o2m." msgstr "" +"%s Esto debe ser '%s' en el modelo actual, o un campo del mismo nombre en " +"una relación one2many." #. module: base #: model:ir.module.module,description:base.module_account_payment @@ -14777,7 +15483,7 @@ msgstr "Acceso" #: field:res.partner,vat:0 #, python-format msgid "TIN" -msgstr "" +msgstr "NIF" #. module: base #: model:res.country,name:base.aw @@ -14842,7 +15548,7 @@ msgstr "Informes avanzados" #. module: base #: model:ir.module.module,summary:base.module_purchase msgid "Purchase Orders, Receptions, Supplier Invoices" -msgstr "" +msgstr "Pedidos de compra, recepciones, facturas de proveedor" #. module: base #: model:ir.module.module,description:base.module_hr_payroll @@ -14861,6 +15567,19 @@ msgid "" " * Integrated with Holiday Management\n" " " msgstr "" +"\n" +"Sistema genérico de sueldos.\n" +"=========================\n" +"\n" +" * Detalles del empleado\n" +" * Contratos del empleado\n" +" * Contrato basado en el pasaporte\n" +" * Provisiones/deducciones\n" +" * Permite configurar salario base/bruto/neto\n" +" * Nómina del empleado\n" +" * Registro mensual de sueldos\n" +" * Integrado con el gestor de vacaciones\n" +" " #. module: base #: model:ir.model,name:base.model_ir_model_data @@ -14939,7 +15658,7 @@ msgstr "Límite" #. module: base #: model:res.groups,name:base.group_hr_user msgid "Officer" -msgstr "" +msgstr "Directivo" #. module: base #: code:addons/orm.py:789 @@ -14990,12 +15709,24 @@ msgid "" "user name and password for the invitation of the survey.\n" " " msgstr "" +"\n" +"Este módulo se usa para encuestas.\n" +"==================================\n" +"\n" +"Depende de las respuestas o revisiones de varias preguntas por diferentes " +"usuarios. Una encuesta tiene múltiples páginas. Cada página puede contener " +"múltiples preguntas y cada pregunta puede tener múltiples respuestas. " +"Diferentes usuarios pueden dar diferentes respuestas a la preguntar y " +"dependiendo de ello la encuesta se realizará. Las empresas también pueden " +"enviar correos con el nombre de usuario y la contraseña para la invitación a " +"la encuesta.\n" +" " #. module: base #: code:addons/base/ir/ir_model.py:163 #, python-format msgid "Model '%s' contains module data and cannot be removed!" -msgstr "" +msgstr "¡El modelo '%s' contiene datos del módulo y no puede ser eliminado!" #. module: base #: model:res.country,name:base.az @@ -15048,7 +15779,7 @@ msgstr "Módulos genéricos" #. module: base #: model:res.country,name:base.mk msgid "Macedonia, the former Yugoslav Republic of" -msgstr "" +msgstr "Macedonia, Antigua república yugoslava de" #. module: base #: model:res.country,name:base.rw @@ -15062,6 +15793,9 @@ msgid "" "Allow users to login through OpenID.\n" "====================================\n" msgstr "" +"\n" +"Permite a los usuarios iniciar sesión a través de OpenID.\n" +"=============================================\n" #. module: base #: help:ir.mail_server,smtp_port:0 @@ -15098,7 +15832,7 @@ msgstr "Ventana actual" #: model:ir.module.category,name:base.module_category_hidden #: view:res.users:0 msgid "Technical Settings" -msgstr "" +msgstr "Configuración técnica" #. module: base #: model:ir.module.category,description:base.module_category_accounting_and_finance @@ -15117,7 +15851,7 @@ msgstr "Conector Thunderbird" #. module: base #: model:ir.module.module,summary:base.module_event msgid "Trainings, Conferences, Meetings, Exhibitions, Registrations" -msgstr "" +msgstr "Formaciones, conferencias, reuniones, exhibiciones, inscripciones" #. module: base #: model:ir.model,name:base.model_res_country @@ -15135,7 +15869,7 @@ msgstr "País" #. module: base #: model:res.partner.category,name:base.res_partner_category_15 msgid "Wholesaler" -msgstr "" +msgstr "Mayorista" #. module: base #: model:ir.module.module,shortdesc:base.module_base_vat @@ -15167,6 +15901,8 @@ msgid "" "file encoding, please be sure to view and edit\n" " using the same encoding." msgstr "" +"codificación de archivo. Asegúrese de que ve y edita usando la misma " +"codificación." #. module: base #: view:ir.rule:0 @@ -15185,7 +15921,7 @@ msgstr "Holanda - Contabilidad" #. module: base #: model:res.country,name:base.gs msgid "South Georgia and the South Sandwich Islands" -msgstr "" +msgstr "Islas Georgia del sur y Sandwich del sur" #. module: base #: view:res.lang:0 @@ -15200,7 +15936,7 @@ msgstr "Español (SV) / Español (SV)" #. module: base #: model:ir.actions.act_window,name:base.open_module_tree msgid "Install a Module" -msgstr "" +msgstr "Instalar un módulo" #. module: base #: field:ir.module.module,auto_install:0 @@ -15220,6 +15956,12 @@ msgid "" "taxes\n" "and the Lempira currency." msgstr "" +"\n" +"Éste es el módulo base para gestionar el plan de cuentas para Honduras.\n" +"====================================================================\n" +" \n" +"Agrega una nomenclatura contable para Honduras. También incluye impuestos y " +"la moneda Lempira." #. module: base #: model:res.country,name:base.jp @@ -15318,6 +16060,8 @@ msgid "" "Ambiguous specification for field '%(field)s', only provide one of name, " "external id or database id" msgstr "" +"Especificación ambigua para el campo '%(field)s'. Especifique sólo uno de " +"estos: nombre, id. externo o id. de la base de datos." #. module: base #: field:ir.sequence,implementation:0 @@ -15337,7 +16081,7 @@ msgstr "Chile" #. module: base #: model:ir.module.module,shortdesc:base.module_web_view_editor msgid "View Editor" -msgstr "" +msgstr "Editor de vistas" #. module: base #: view:ir.cron:0 @@ -15427,7 +16171,7 @@ msgstr "Actualización del sistema" #: field:ir.actions.report.xml,report_sxw_content:0 #: field:ir.actions.report.xml,report_sxw_content_data:0 msgid "SXW Content" -msgstr "" +msgstr "Contenido del SXW" #. module: base #: help:ir.sequence,prefix:0 @@ -15469,7 +16213,7 @@ msgstr "Información general" #. module: base #: field:ir.model.data,complete_name:0 msgid "Complete ID" -msgstr "" +msgstr "Id. completo" #. module: base #: model:res.country,name:base.tc @@ -15482,6 +16226,8 @@ msgid "" "Tax Identification Number. Check the box if this contact is subjected to " "taxes. Used by the some of the legal statements." msgstr "" +"Número de identificación fiscal. Marque la casilla si el contacto está " +"sujeto a impuestos. Usado por algunos documentos legales." #. module: base #: field:res.partner.bank,partner_id:0 @@ -15592,7 +16338,7 @@ msgstr "Solicitudes de compra" #. module: base #: selection:ir.actions.act_window,target:0 msgid "Inline Edit" -msgstr "" +msgstr "Editor incorporado" #. module: base #: selection:ir.cron,interval_type:0 @@ -15659,6 +16405,14 @@ msgid "" "

\n" " " msgstr "" +"

\n" +"Pulse para añadir un contacto en la libreta de direcciones.\n" +"

\n" +"OpenERP le ayuda a gestionar todas las actividades relacionadas con los " +"clientes: discusiones, historial de oportunidades de negocio, documentos, " +"etc.\n" +"

\n" +" " #. module: base #: model:res.partner.category,name:base.res_partner_category_2 @@ -15702,6 +16456,15 @@ msgid "" "on a supplier purchase order into several accounts and analytic plans.\n" " " msgstr "" +"\n" +"El módulo base para gestionar las distribuciones analíticas y los pedidos de " +"compra.\n" +"====================================================================\n" +"\n" +"Permite al usuario mantener varios planes analíticos. Esto deja dividir una " +"línea en un pedido de compra de proveedor en varias cuentas y planes " +"analíticos.\n" +" " #. module: base #: model:res.country,name:base.lk @@ -15721,7 +16484,7 @@ msgstr "Ruso / русский язык" #. module: base #: model:ir.module.module,shortdesc:base.module_auth_signup msgid "Signup" -msgstr "" +msgstr "Registro" #~ msgid "SMS - Gateway: clickatell" #~ msgstr "Puerta de enlace SMS vía clickatell" diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po index a81b7b5d8e9..2d08fbd47ef 100644 --- a/openerp/addons/base/i18n/es_EC.po +++ b/openerp/addons/base/i18n/es_EC.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0.0-rc1\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-11-05 00:42+0000\n" +"PO-Revision-Date: 2012-12-20 02:14+0000\n" "Last-Translator: Cristian Salamea (Gnuthink) \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: 2012-12-04 05:03+0000\n" -"X-Generator: Launchpad (build 16335)\n" +"X-Launchpad-Export-Date: 2012-12-20 04:43+0000\n" +"X-Generator: Launchpad (build 16378)\n" #. module: base #: model:ir.module.module,description:base.module_account_check_writing @@ -24,6 +24,10 @@ msgid "" "================================================\n" " " msgstr "" +"\n" +"Módulo para la emisión e impresión de cheques\n" +"================================================\n" +" " #. module: base #: model:res.country,name:base.sh @@ -59,7 +63,7 @@ msgstr "Código vista" #. module: base #: model:ir.module.module,summary:base.module_sale_stock msgid "Quotation, Sale Orders, Delivery & Invoicing Control" -msgstr "" +msgstr "Presupuesto, órdenes de venta, entrega y control de facturación" #. module: base #: selection:ir.sequence,implementation:0 @@ -88,12 +92,12 @@ msgstr "" #. module: base #: model:ir.module.module,summary:base.module_point_of_sale msgid "Touchscreen Interface for Shops" -msgstr "" +msgstr "Interfaz de pantalla táctil para tiendas" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll msgid "Indian Payroll" -msgstr "" +msgstr "Nomina de la India" #. module: base #: help:ir.cron,model:0 @@ -123,6 +127,17 @@ msgid "" " * Product Attributes\n" " " msgstr "" +"\n" +"Módulo que añade fabricantes y atributos en el formulario de producto.\n" +"===========================================================\n" +"\n" +"Puede definir los siguientes campos para un producto:\n" +"-------------------------------------------------\n" +"* Fabricante\n" +"* Nombre del producto del fabricante\n" +"* Código del producto del fabricante\n" +"* Atributos del producto\n" +" " #. module: base #: field:ir.actions.client,params:0 @@ -136,11 +151,14 @@ msgid "" "The module adds google user in res user.\n" "========================================\n" msgstr "" +"\n" +"El módulo añade usuarios Google al registro de usuarios\n" +"============================================\n" #. module: base #: help:res.partner,employee:0 msgid "Check this box if this contact is an Employee." -msgstr "" +msgstr "Marque si el contacto es un empleado" #. module: base #: help:ir.model.fields,domain:0 @@ -171,7 +189,7 @@ msgstr "Ventana destino" #. module: base #: field:ir.actions.report.xml,report_rml:0 msgid "Main Report File Path" -msgstr "" +msgstr "Ruta de archivo del informe principal" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_analytic_plans @@ -269,7 +287,7 @@ msgstr "creado." #. module: base #: field:ir.actions.report.xml,report_xsl:0 msgid "XSL Path" -msgstr "" +msgstr "Ruta XSL" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_tr @@ -295,7 +313,7 @@ msgstr "Inuktitut / ᐃᓄᒃᑎᑐᑦ" #. module: base #: model:res.groups,name:base.group_multi_currency msgid "Multi Currencies" -msgstr "" +msgstr "Multimoneda" #. module: base #: model:ir.module.module,description:base.module_l10n_cl @@ -307,6 +325,12 @@ msgid "" "\n" " " msgstr "" +"\n" +"Plan de cuentas y localización de impuestos chilenos.\n" +"==============================================\n" +"Plan contable chileno e impuestos de acuerdo a disposiciones vigentes\n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_sale @@ -319,6 +343,7 @@ msgid "" "The internal user that is in charge of communicating with this contact if " "any." msgstr "" +"El usuario interno encargado de comunicarse con este contacto si lo hubiese." #. module: base #: view:res.partner:0 diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po index 915dc7a15c8..a722c4c7e65 100644 --- a/openerp/addons/base/i18n/et.po +++ b/openerp/addons/base/i18n/et.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: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-18 22:00+0000\n" +"PO-Revision-Date: 2012-12-19 19:49+0000\n" "Last-Translator: Ahti Hinnov \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: 2012-12-19 05:13+0000\n" +"X-Launchpad-Export-Date: 2012-12-20 04:41+0000\n" "X-Generator: Launchpad (build 16378)\n" #. module: base @@ -531,7 +531,7 @@ msgstr "Kuupäeva vorming" #. module: base #: model:ir.module.module,shortdesc:base.module_base_report_designer msgid "OpenOffice Report Designer" -msgstr "" +msgstr "OpenOffice aruande kujundaja" #. module: base #: model:res.country,name:base.an @@ -980,7 +980,7 @@ msgstr "" #. module: base #: view:res.users:0 msgid "Email Preferences" -msgstr "" +msgstr "E-posti seadistused" #. module: base #: code:addons/base/ir/ir_fields.py:196 @@ -1571,7 +1571,7 @@ msgstr "" #. module: base #: view:res.company:0 msgid "Report Footer Configuration" -msgstr "" +msgstr "Aruande jaluse seadistamine" #. module: base #: field:ir.translation,comments:0 @@ -1951,7 +1951,7 @@ msgstr "Lisatud mudel" #. module: base #: field:res.partner.bank,footer:0 msgid "Display on Reports" -msgstr "" +msgstr "Kuva aruannetes" #. module: base #: model:ir.module.module,description:base.module_project_timesheet @@ -2144,7 +2144,7 @@ msgstr "Hispaania / Español" #. module: base #: selection:base.language.install,lang:0 msgid "Korean (KP) / 한국어 (KP)" -msgstr "" +msgstr "Korea (KP) / 한국어 (KP)" #. module: base #: model:res.country,name:base.ax @@ -2487,7 +2487,7 @@ msgstr "" #. module: base #: field:res.company,rml_header1:0 msgid "Company Slogan" -msgstr "" +msgstr "Ettevõtte loosung" #. module: base #: model:res.country,name:base.bb @@ -2537,7 +2537,7 @@ msgstr "Kreeka / Ελληνικά" #. module: base #: field:res.company,custom_footer:0 msgid "Custom Footer" -msgstr "" +msgstr "Kohandatud jalus" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_crm @@ -2593,7 +2593,7 @@ msgstr "Arveldus" #. module: base #: field:ir.ui.view_sc,name:0 msgid "Shortcut Name" -msgstr "Kiirkorralduse nimi" +msgstr "Otsetee nimi" #. module: base #: field:res.partner,contact_address:0 @@ -3009,7 +3009,7 @@ msgstr "Norfolki saar" #. module: base #: selection:base.language.install,lang:0 msgid "Korean (KR) / 한국어 (KR)" -msgstr "" +msgstr "Korea (KR) / 한국어 (KR)" #. module: base #: help:ir.model.fields,model:0 @@ -3636,7 +3636,7 @@ msgstr "" #: field:res.company,rml_footer:0 #: field:res.company,rml_footer_readonly:0 msgid "Report Footer" -msgstr "" +msgstr "Aruande jalus" #. module: base #: selection:res.lang,direction:0 @@ -3868,7 +3868,7 @@ msgstr "Peata kõik" #. module: base #: field:res.company,paper_format:0 msgid "Paper Format" -msgstr "" +msgstr "Paberi formaat" #. module: base #: model:ir.module.module,description:base.module_note_pad @@ -4714,7 +4714,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "Portuguese (BR) / Português (BR)" -msgstr "" +msgstr "Portugali (BR) / Português (BR)" #. module: base #: model:ir.model,name:base.model_ir_needaction_mixin @@ -5154,7 +5154,7 @@ msgstr "" #. module: base #: view:res.company:0 msgid "Preview Header/Footer" -msgstr "" +msgstr "Päise/jaluse eelvaade" #. module: base #: field:ir.ui.menu,parent_id:0 @@ -5841,7 +5841,7 @@ msgstr "" #. module: base #: view:ir.ui.view_sc:0 msgid "Shortcut" -msgstr "Lühend" +msgstr "Otsetee" #. module: base #: field:ir.model.data,date_init:0 @@ -6718,7 +6718,7 @@ msgstr "" #. module: base #: selection:res.currency,position:0 msgid "After Amount" -msgstr "" +msgstr "Peale summat" #. module: base #: selection:base.language.install,lang:0 @@ -7044,7 +7044,7 @@ msgstr "Mitmel dokumendil" #: view:res.users:0 #: view:wizard.ir.model.menu.create:0 msgid "or" -msgstr "" +msgstr "või" #. module: base #: model:ir.module.module,shortdesc:base.module_account_accountant @@ -7608,7 +7608,7 @@ msgstr "Kohandatud väli" #. module: base #: model:ir.module.module,summary:base.module_account_accountant msgid "Financial and Analytic Accounting" -msgstr "" +msgstr "Finants- ja analüütiline raamatupidamine" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_project @@ -7708,7 +7708,7 @@ msgstr "" #. module: base #: model:res.partner.bank.type,name:base.bank_normal msgid "Normal Bank Account" -msgstr "" +msgstr "Tavaline pangakonto" #. module: base #: view:ir.actions.wizard:0 @@ -7980,7 +7980,7 @@ msgstr "Tühista eemaldus" #. module: base #: view:res.bank:0 msgid "Communication" -msgstr "Suhtlemine" +msgstr "Kontakt" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic @@ -9571,7 +9571,7 @@ msgstr "Paigaldamise ootel" #: model:ir.module.module,shortdesc:base.module_base #: field:res.currency,base:0 msgid "Base" -msgstr "Baas" +msgstr "Alus" #. module: base #: field:ir.model.data,model:0 @@ -9660,7 +9660,7 @@ msgstr "Minutid" #. module: base #: view:res.currency:0 msgid "Display" -msgstr "" +msgstr "Kuvamine" #. module: base #: model:res.groups,name:base.group_multi_company @@ -12471,7 +12471,7 @@ msgstr "Küpros" #. module: base #: field:res.users,new_password:0 msgid "Set Password" -msgstr "" +msgstr "Määra salasõna" #. module: base #: field:ir.actions.server,subject:0 @@ -12503,7 +12503,7 @@ msgstr "" #. module: base #: selection:res.currency,position:0 msgid "Before Amount" -msgstr "" +msgstr "Enne summat" #. module: base #: field:res.request,act_from:0 @@ -12572,7 +12572,7 @@ msgstr "" #. module: base #: field:res.company,company_registry:0 msgid "Company Registry" -msgstr "Ettevõtte register" +msgstr "Ettevõtte registrikood" #. module: base #: view:ir.actions.report.xml:0 @@ -12917,7 +12917,7 @@ msgstr "Zaire" #. module: base #: model:ir.module.module,summary:base.module_project msgid "Projects, Tasks" -msgstr "" +msgstr "Projektid, ülesanded" #. module: base #: field:workflow.instance,res_id:0 diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po index c18682614bf..0dacf6c6adb 100644 --- a/openerp/addons/base/i18n/hr.po +++ b/openerp/addons/base/i18n/hr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-17 20:19+0000\n" +"PO-Revision-Date: 2012-12-19 20:48+0000\n" "Last-Translator: Goran Kliska \n" "Language-Team: openerp-translators\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-12-18 04:58+0000\n" -"X-Generator: Launchpad (build 16372)\n" +"X-Launchpad-Export-Date: 2012-12-20 04:42+0000\n" +"X-Generator: Launchpad (build 16378)\n" "Language: hr\n" #. module: base @@ -714,7 +714,7 @@ msgstr "Palau" #. module: base #: view:res.partner:0 msgid "Sales & Purchases" -msgstr "Prodaja i naručivanje" +msgstr "Prodaja i nabava" #. module: base #: view:ir.translation:0 @@ -1511,7 +1511,7 @@ msgstr "" #: model:ir.module.category,name:base.module_category_purchase_management #: model:ir.ui.menu,name:base.menu_purchase_root msgid "Purchases" -msgstr "Nabave" +msgstr "Nabava" #. module: base #: model:res.country,name:base.md diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po index 8948d23c89e..514bc4d3a8a 100644 --- a/openerp/addons/base/i18n/hu.po +++ b/openerp/addons/base/i18n/hu.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-18 17:37+0000\n" +"PO-Revision-Date: 2012-12-19 16:59+0000\n" "Last-Translator: krnkris \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-12-19 05:14+0000\n" +"X-Launchpad-Export-Date: 2012-12-20 04:41+0000\n" "X-Generator: Launchpad (build 16378)\n" #. module: base @@ -251,6 +251,35 @@ msgid "" "* Planned Revenue by Stage and User (graph)\n" "* Opportunities by Stage (graph)\n" msgstr "" +"\n" +"Az alapértelemezett OpenERP CRM Ügyfélkapcsolat-kezelés\n" +"=====================================================\n" +"\n" +"Ez az alkalmazás lehetővé teszi egy csoportnak, hogy inteligensen és " +"hatékonyan kezelje a vezetői gyűléseket, lehetőségeket, találkozókat és " +"telefonokat.\n" +"\n" +"Kezeli a kulcsfontosságú munkákat mint kommunikáció, azonosítás, kiosztás, " +"felosztás és értesítés.\n" +"\n" +"OpenERP biztosítja, hogy minden esetben nyomon követhetőek legyenek a " +"felhasználók, vásárlók és beszállítók. Autómatikusan küldhető emlékeztető, " +"kiterjezti az igényt, bekapcsol speciális eszközt és még több cselekvésen " +"alapuló módot, melyet a vállalkozása szabályaira szabhat.\n" +"\n" +"A legnayobb dolog ebben a rendszerben, hgoy a felhasználónak nem kell semmi " +"speciálisat véghezvinnie. A CRM modulnak van egy e-amil átjárója ami " +"szinkronizálja az e-maileket az OpenERP által. Így, a felhasználók e-" +"maileket küldhetnek az igénylés helyére.\n" +"\n" +"OpenERP törődni fog az üzenetek megköszönésével, automatikusan átirányítva a " +"megfelelő osztályhoz, biztosítva a jövőbeni munkafolyamat megfelő helyét.\n" +"\n" +"\n" +"Dashboard / irányítópult a CRM-ben, ezt is beleértve:\n" +"-------------------------------\n" +"* Tervezett bevétel szintek és felhasználók szerint (grafikon)\n" +"* Lehetőségek szintenként (grafikon)\n" #. module: base #: code:addons/base/ir/ir_model.py:397 @@ -5753,6 +5782,23 @@ msgid "" "since it's the same which has been renamed.\n" " " msgstr "" +"\n" +"Ez a modul lehetővé teszi a felhasználók részére a partnerek leválogatását.\n" +"=================================================================\n" +"\n" +"A profil kritériumokat használja az előző leválogató modulból ami fel lett " +"javítva. \n" +"Köszönhető az új felfogású kikérdezőnek. Újra tudja csoportosítani a " +"kérdéseket\n" +"egy kikérdezőbe és direkt használhatja azokat a partnerekhez.\n" +"\n" +"Össze lett kapcsolva az előző CRM & SRM leválogatás eszközzel mivel ezek át " +"lettek fedve.\n" +"\n" +" **Megjegyzés** ez a modul nem kompatibilis a leválogató modullal, mivel " +"ez ugyanaz, csak más \n" +"másként lett elnevezve.\n" +" " #. module: base #: model:res.country,name:base.gt @@ -6358,7 +6404,7 @@ msgstr "Man Sziget" #. module: base #: help:ir.actions.client,res_model:0 msgid "Optional model, mostly used for needactions." -msgstr "" +msgstr "Választható modell, főként szükséges műveletekhez használják." #. module: base #: field:ir.attachment,create_uid:0 @@ -6523,6 +6569,58 @@ msgid "" " * Zip return for separated PDF\n" " * Web client WYSIWYG\n" msgstr "" +"\n" +"Ez a modul hozzáad egy Kimutatás motort WebKit könyvtárt alapul véve " +"(wkhtmltopdf) a HTML +CCS megalkotott kimutatások támogatásához.\n" +"=============================================================================" +"========================================\n" +"\n" +"A modul felépítését és egy pár kódolást a report_openoffice modul " +"ösztönözte.\n" +"\n" +"A modul lehetővé teszi:\n" +"------------------\n" +" - HTML kimutatás meghatározását\n" +" - Többszörös fejléc támogatása\n" +" - Többszörös logó használat\n" +" - Többszörös vállalat támogatás\n" +" - HTML és CSS-3 támogatás (az aktuális WebKIT verzió határain belül)\n" +" - JavaScript támogatás\n" +" - Nyers HTML debugger\n" +" - Könyv nyomtatási lehetőség\n" +" - Margó meghatározás\n" +" - Papír méret meghatározás\n" +"\n" +"Többszörös fejléc és logó meghatározható vállalatonként. CCS stílus, fejléc " +"és\n" +"lábjegyzet meghatározható vállalatonként.\n" +"\n" +"Például kimutatást megtekinthet webkit_report_sample modulban, és ebben a " +"videóban:\n" +" http://files.me.com/nbessi/06n92k.mov\n" +"\n" +"Követelmények és telepítés:\n" +"------------------------------\n" +"Ehhez a modulhoz kell a ``wkthtmltopdf`` könyvtár a HTML dokumentumok PDF " +"ábrázolásához.\n" +"Verzió 0.9.9 vagy későbbi szükséges, és megtalálható a \n" +"http://code.google.com/p/wkhtmltopdf/ a Linux, Mac OS X (i386) és Windows " +"(32bits) rendszerekhez.\n" +"\n" +"A könyvtár OpenERP szerveren való telepítése után, be kell állítani az " +"elérési utat a ``wkthtmltopdf`` futtatójához minden vállalathoz.\n" +"\n" +"Ha nem talál fejlécet/lábjegyzetet vagy egyéb probléma merül fel a Linuxon, " +"akkor győződjön meg, hogy telepíti a könyvtár 'static' verzióját. UBUNTU " +"alatt ez ey ismert ``wkhtmltopdf`` probléma.\n" +"\n" +"\n" +"Tennivaló:\n" +"-----\n" +" * JavaScript támogatás aktiválás deaktiválás\n" +" * Gyűjtő és könyv formátum támogatás\n" +" * Zip visszaadás egy külön PDF-hez\n" +" * Web kliens WYSIWYG\n" #. module: base #: model:res.groups,name:base.group_sale_salesman_all_leads @@ -8175,6 +8273,30 @@ msgid "" "* In a module, so that administrators and users of OpenERP who do not\n" " need or want an online import can avoid it being available to users.\n" msgstr "" +"\n" +"Új fájl import kiterjesztések az OpenERP rendszerhez\n" +"======================================\n" +"\n" +"Az OpenERP fájl rendszerének újra-implementálása:\n" +"\n" +"* Szerver oldal, az előző rendszer a legtöbb végrehalytást a kliensre " +"kényszerítette\n" +" amely megduplázta az energiát (kliensek közt), az importálási rendszert \n" +" nehézkessé teszi a kliens nélkül(direkt RPC vagy\n" +" más automata formátumnál) és az export/import rendszer érthetőségét\n" +" is nehézkessé teszi amint 3 + különböző projekten hajtódik végre.\n" +"\n" +"* Érthetőbben a felhasználók és partnerek a saját import kivitelezést tudnak " +"\n" +" készíteni más fájl formátumokból (pl. OpenDocument fájlok)\n" +" ami leegyszerűsítheti a munka folyamatuk kezelését az adat forrásból " +"való\n" +" előállítását.\n" +"\n" +"* A modulban, azok az OpenERP adminisztrátorok és felhasználók akik nem\n" +" igénylik az online importot biztosíthatják, hogy azok nem lesznek " +"elérhetők \n" +" a felhasználók részére.\n" #. module: base #: selection:res.currency,position:0 @@ -12740,7 +12862,7 @@ msgstr "Olvasási hozzáférési jog" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_user_function msgid "Jobs on Contracts" -msgstr "" +msgstr "Feladatok a szerződésekben" #. module: base #: code:addons/base/res/res_lang.py:187 @@ -14646,6 +14768,8 @@ msgid "" "Helps you manage your inventory and main stock operations: delivery orders, " "receptions, etc." msgstr "" +"Segít Önnek a készletek és a fő készletműveletek kezelésében: " +"szállítólevelek, áruátvételek, stb." #. module: base #: model:ir.model,name:base.model_base_module_update @@ -16029,6 +16153,7 @@ msgstr "" #: help:ir.actions.act_window,usage:0 msgid "Used to filter menu and home actions from the user form." msgstr "" +"A menű és főoldal műveletek szűrésére használták a felhasználói űrlapból." #. module: base #: model:res.country,name:base.sa @@ -16050,6 +16175,15 @@ msgid "" "order.\n" " " msgstr "" +"\n" +"Ez a modul lehetőséget ad MRP és eladási modul egyszeri telepítésére.\n" +"=============================================================================" +"=======\n" +"\n" +"Alapvetően akkor használt, ha nyomon szeretnénk követni a megrendelésekből " +"generált termelési megrendeléseket. A gyártási megrendeléshez ad hozzá " +"eladás nevet és eladási hivatkozást.\n" +" " #. module: base #: code:addons/base/ir/ir_fields.py:147 @@ -16073,6 +16207,12 @@ msgid "" "=========================\n" " " msgstr "" +"\n" +"Ez a modul hozzáadja a portáljához a project/terv menűt és annak " +"tulajdonságait (feladatait) ha a projekt/terv és portál telepítve vannak.\n" +"=============================================================================" +"=========================\n" +" " #. module: base #: code:addons/base/module/wizard/base_module_configuration.py:38 @@ -16085,7 +16225,7 @@ msgstr "Rendszer konfigurálása kész" #: view:ir.config_parameter:0 #: model:ir.ui.menu,name:base.ir_config_menu msgid "System Parameters" -msgstr "" +msgstr "Rendszer paraméterek" #. module: base #: model:ir.module.module,description:base.module_l10n_ch @@ -16203,7 +16343,7 @@ msgstr "Művelet több dokumentumon" #: model:ir.actions.act_window,name:base.action_partner_title_partner #: model:ir.ui.menu,name:base.menu_partner_title_partner msgid "Titles" -msgstr "" +msgstr "Címek" #. module: base #: model:ir.module.module,description:base.module_anonymization @@ -16226,6 +16366,22 @@ msgid "" "anonymization process to recover your previous data.\n" " " msgstr "" +"\n" +"Ez a modul lehetővé teszi az adatbázis titkosítását.\n" +"===============================================\n" +"\n" +"Ezzel a modullal a bizalmas adatait biztonságban tarthatja egy megadott " +"adatbázisban.\n" +"Ez az eljárás hasznos, ha költöztetéskor megakarja védeni a saját ügyfelei " +"bizalmas adatait. \n" +"Az alapelv az, hogy egy titkosító eszközt futtat amely elrejti a bizalmas " +"adatokat (ki lesznek \n" +"cserélve ‘XXX’ karakterekkel). Ekkor elküldheti a titkosított adatokat a " +"költözési csoporhoz.\n" +"Amikor visszatértek a költöztetni kívánt adatok, akkor vissza lehet állítani " +"azokat\n" +"a titkosító eljárással az adatok visszanyeréssel.\n" +" " #. module: base #: model:ir.module.module,description:base.module_web_analytics @@ -16237,6 +16393,12 @@ msgid "" "Collects web application usage with Google Analytics.\n" " " msgstr "" +"\n" +"Google Analytics.\n" +"==============================\n" +"\n" +"Összegyűjti a web alkalmazás használaát a Google Analytics rendszerrel.\n" +" " #. module: base #: help:ir.sequence,implementation:0 @@ -16245,6 +16407,9 @@ msgid "" "later is slower than the former but forbids any gap in the sequence (while " "they are possible in the former)." msgstr "" +"Két sorrendet ajánl a tárgy beillesztésthez: Alapértelmezett és 'Nincs rés'. " +"A későbbi lasúbb mint a mostani, de megtilt minden rést ami ebben a " +"sorrendben van (mivel ezek az előzőben lehettek)." #. module: base #: model:res.country,name:base.gn @@ -16280,7 +16445,7 @@ msgstr "Hiba ! Nem hozhat létre rekurzív menüket." #. module: base #: view:ir.translation:0 msgid "Web-only translations" -msgstr "" +msgstr "Kizárólag-web fordítások" #. module: base #: view:ir.rule:0 @@ -16337,16 +16502,60 @@ msgid "" "\n" " " msgstr "" +"\n" +"Belga számlatükör és lokalizáció \n" +"\n" +"This is the base module to manage the accounting chart for Belgium in " +"OpenERP.\n" +"=============================================================================" +"=\n" +"\n" +"After installing this module, the Configuration wizard for accounting is " +"launched.\n" +" * We have the account templates which can be helpful to generate Charts " +"of Accounts.\n" +" * On that particular wizard, you will be asked to pass the name of the " +"company,\n" +" the chart template to follow, the no. of digits to generate, the code " +"for your\n" +" account and bank account, currency to create journals.\n" +"\n" +"Thus, the pure copy of Chart Template is generated.\n" +"\n" +"Wizards provided by this module:\n" +"--------------------------------\n" +" * Partner VAT Intra: Enlist the partners with their related VAT and " +"invoiced\n" +" amounts. Prepares an XML file format.\n" +" \n" +" **Path to access :** Invoicing/Reporting/Legal Reports/Belgium " +"Statements/Partner VAT Intra\n" +" * Periodical VAT Declaration: Prepares an XML file for Vat Declaration " +"of\n" +" the Main company of the User currently Logged in.\n" +" \n" +" **Path to access :** Invoicing/Reporting/Legal Reports/Belgium " +"Statements/Periodical VAT Declaration\n" +" * Annual Listing Of VAT-Subjected Customers: Prepares an XML file for " +"Vat\n" +" Declaration of the Main company of the User currently Logged in Based " +"on\n" +" Fiscal year.\n" +" \n" +" **Path to access :** Invoicing/Reporting/Legal Reports/Belgium " +"Statements/Annual Listing Of VAT-Subjected Customers\n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_base_gengo msgid "Automated Translations through Gengo API" -msgstr "" +msgstr "Automatikus fordítás a Gengo API keresztül" #. module: base #: model:ir.module.module,shortdesc:base.module_account_payment msgid "Suppliers Payment Management" -msgstr "" +msgstr "Szállítói kifizetések kezelése" #. module: base #: model:res.country,name:base.sv @@ -16376,7 +16585,7 @@ msgstr "Thaiföld" #. module: base #: model:ir.module.module,summary:base.module_account_voucher msgid "Send Invoices and Track Payments" -msgstr "" +msgstr "Számlák küldése és fizetések nyomonkövetése" #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_lead @@ -16387,6 +16596,7 @@ msgstr "Lehetőségek" #: model:res.country,name:base.gg msgid "Guernsey" msgstr "" +"Guernsey-sziget - Guernsey valutaunióban van az Egyesült Királysággal" #. module: base #: selection:base.language.install,lang:0 @@ -16406,6 +16616,17 @@ msgid "" " bilgileriniz, ilgili para birimi gibi bilgiler isteyecek.\n" " " msgstr "" +"\n" +"Török számlatükör és lokalizáció\n" +"\n" +"Türkiye için Tek düzen hesap planı şablonu OpenERP Modülü.\n" +"==========================================================\n" +"\n" +"Bu modül kurulduktan sonra, Muhasebe yapılandırma sihirbazı çalışır\n" +" * Sihirbaz sizden hesap planı şablonu, planın kurulacağı şirket, banka " +"hesap\n" +" bilgileriniz, ilgili para birimi gibi bilgiler isteyecek.\n" +" " #. module: base #: selection:workflow.activity,join_mode:0 @@ -16418,6 +16639,8 @@ msgstr "És" msgid "" "Database identifier of the record to which this applies. 0 = for all records" msgstr "" +"Adatbázis azonosító arra a rekordra amelyre ez vonatkozik. 0 = összes " +"rekordra" #. module: base #: field:ir.model.fields,relation:0 @@ -16427,7 +16650,7 @@ msgstr "Objektum kapcsolat" #. module: base #: model:ir.module.module,shortdesc:base.module_account_voucher msgid "eInvoicing & Payments" -msgstr "" +msgstr "Számlázás & Kifizetések" #. module: base #: model:ir.module.module,description:base.module_base_crypt @@ -16463,6 +16686,42 @@ msgid "" "This module is currently not compatible with the ``user_ldap`` module and\n" "will disable LDAP authentication completely if installed at the same time.\n" msgstr "" +"\n" +"Rendesszövegű jelszó kiváltása biztonsági hasító függvénnyel az " +"adatbázisban.\n" +"================================================================\n" +"\n" +"A meglévő felhasználói adatbázisban, a rendesszövegű jelszavak azonnal el " +"lesznek távolítva\n" +"amint telepítésre kerül a base_crypt.\n" +"\n" +"Minden jelszó ki lesz cserélve egy biztonságos, konzervált, kriptográfiai " +"hasító függvénnyel, \n" +"ezzel megakadályozva az eredeti jelszó kiolvasását az adatbázisból.\n" +"\n" +"Miután telepítette ezt a modult, nem lesz lehetősége az elfelejtett jelszó " +"visszafejtésére \n" +"a felhasználók részéről, az adminisztátor egyedüli lehetősége lesz egy új " +"jelszó megadása.\n" +"\n" +"Biztonsági figyelmeztetés:\n" +"-----------------\n" +"Ennek a modulnak a telepítésével nem hagyhatja figyelmen kívül a többi " +"biztonsági intézkedést,\n" +"mivel a jelszó a hálózaton keresztül kódolatlanul halad keresztül, kivéve, " +"ha \n" +"biztonsági protokolt használ mint a XML-RPCS vagy HTTPS.\n" +"\n" +"Ez nem védi meg az adatbázis többi részét, mely bizalmas\n" +"adatokat is tartalmazhat. Pontos biztonsági intézkedést kell beileszteni\n" +"a rendszer adminisztrátornak minden területen, mint: adatbázis védelmi " +"mentések,\n" +"rendszer fájlok, távoli héj hozzáférések, fizikai szerver hozzáférések.\n" +"\n" +"Kölcsönhatás az LDAP azonosítással:\n" +"-------------------------------------\n" +"Ez a modul most még nem kompatibilis a ``user_ldap`` modullal és\n" +"ki fogja iktatni a LDAP azonosítást teljesen ha ugyanakkor telepítettek.\n" #. module: base #: view:ir.rule:0 @@ -16499,12 +16758,12 @@ msgstr "Valuta árfolyam" #: view:base.module.upgrade:0 #: field:base.module.upgrade,module_info:0 msgid "Modules to Update" -msgstr "" +msgstr "Frissítendő modulok" #. module: base #: model:ir.ui.menu,name:base.menu_custom_multicompany msgid "Multi-Companies" -msgstr "" +msgstr "Többszörös-vállalatok" #. module: base #: field:workflow,osv:0 @@ -16516,12 +16775,12 @@ msgstr "Erőforrás objektum" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_helpdesk msgid "Helpdesk" -msgstr "" +msgstr "Ügyfélszolgálat" #. module: base #: field:ir.rule,perm_write:0 msgid "Apply for Write" -msgstr "" +msgstr "Íráshoz alkamaz" #. module: base #: model:ir.module.module,description:base.module_stock @@ -16569,6 +16828,11 @@ msgid "" "Web pages\n" " " msgstr "" +"\n" +"Oldalak\n" +"=====\n" +"Web oldalak\n" +" " #. module: base #: help:ir.actions.server,code:0 @@ -16576,6 +16840,8 @@ msgid "" "Python code to be executed if condition is met.\n" "It is a Python block that can use the same values as for the condition field" msgstr "" +"Python code to be executed if condition is met.\n" +"It is a Python block that can use the same values as for the condition field" #. module: base #: model:ir.actions.act_window,help:base.grant_menu_access diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po index 9e891fe034f..69035022b92 100644 --- a/openerp/addons/base/i18n/it.po +++ b/openerp/addons/base/i18n/it.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: 2012-12-19 05:14+0000\n" +"X-Launchpad-Export-Date: 2012-12-20 04:42+0000\n" "X-Generator: Launchpad (build 16378)\n" #. module: base diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po index 00826fa3520..837d51ef1f6 100644 --- a/openerp/addons/base/i18n/ro.po +++ b/openerp/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: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-18 18:59+0000\n" +"PO-Revision-Date: 2012-12-19 19:34+0000\n" "Last-Translator: Fekete Mihai \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: 2012-12-19 05:14+0000\n" +"X-Launchpad-Export-Date: 2012-12-20 04:42+0000\n" "X-Generator: Launchpad (build 16378)\n" #. module: base @@ -327,7 +327,7 @@ msgstr "creat(a)." #. module: base #: field:ir.actions.report.xml,report_xsl:0 msgid "XSL Path" -msgstr "" +msgstr "Ruta XSL" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_tr @@ -353,7 +353,7 @@ msgstr "Inuktitut / ᐃᓄᒃᑎᑐᑦ" #. module: base #: model:res.groups,name:base.group_multi_currency msgid "Multi Currencies" -msgstr "" +msgstr "Mzi multe valute" #. module: base #: model:ir.module.module,description:base.module_l10n_cl @@ -365,11 +365,17 @@ msgid "" "\n" " " msgstr "" +"\n" +"Localizarea planului contabil si fiscal chilian\n" +"==============================================\n" +"Plan contabil si fiscal chilian in conformitate cu dispozitiile in vigoare\n" +"\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_sale msgid "Sales Management" -msgstr "Gestiune vanzari" +msgstr "" #. module: base #: help:res.partner,user_id:0 @@ -377,6 +383,8 @@ msgid "" "The internal user that is in charge of communicating with this contact if " "any." msgstr "" +"Utilizatorul intern care este responsabil cu comunicarea cu acest contact, " +"daca exista." #. module: base #: view:res.partner:0 @@ -386,7 +394,7 @@ msgstr "Cauta Partener" #. module: base #: field:ir.module.category,module_nr:0 msgid "Number of Modules" -msgstr "Numar de module" +msgstr "Numar de Module" #. module: base #: help:multi_company.default,company_dest_id:0 @@ -411,6 +419,15 @@ msgid "" " * Commitment Date\n" " * Effective Date\n" msgstr "" +"\n" +"Adauga informatii suplimentare despre date la comanda de vanzare.\n" +"===================================================\n" +"\n" +"Puteti adauga urmatoarele date suplimentare la o comanda de vanzare:\n" +"-----------------------------------------------------------\n" +" * Data Solicitata\n" +" * Data Angajament\n" +" * Data Efectiva\n" #. module: base #: help:ir.actions.act_window,res_id:0 @@ -418,6 +435,8 @@ msgid "" "Database ID of record to open in form view, when ``view_mode`` is set to " "'form' only" msgstr "" +"ID baza de date a inregistrarii de deschis in vizualizare formular, atunci " +"cand ``modul_vizualizare`` este setat doar pe 'formular'" #. module: base #: field:res.partner.address,name:0 @@ -468,11 +487,18 @@ msgid "" "document and Wiki based Hidden.\n" " " msgstr "" +"\n" +"Programul de instalare Ascuns bazat pe cunostinte.\n" +"=====================================\n" +"\n" +"Face Configuratia Aplicatiei Cunostinte disponibila, de unde puteti instala\n" +"documente si Ascuns bazat pe Wiki.\n" +" " #. module: base #: model:ir.module.category,name:base.module_category_customer_relationship_management msgid "Customer Relationship Management" -msgstr "Gestionarea relatiilor cu clientii" +msgstr "Gestionarea Relatiilor cu Clientii" #. module: base #: model:ir.module.module,description:base.module_delivery @@ -486,6 +512,14 @@ msgid "" "invoices from picking, OpenERP is able to add and compute the shipping " "line.\n" msgstr "" +"\n" +"Va permite sa adaugati metode de livrare la comenzile de vanzare si " +"ridicare.\n" +"==============================================================\n" +"\n" +"Va puteti defini propriile grile de preturi pentru transport si livrare. " +"Atunci cand creati \n" +"facturi la ridicare, OpenERP poate adauga si calcula linia de transport.\n" #. module: base #: code:addons/base/ir/ir_filters.py:83 @@ -494,6 +528,8 @@ msgid "" "There is already a shared filter set as default for %(model)s, delete or " "change it before setting a new default" msgstr "" +"Exista deja un filtru comun setat ca default pentru %(model)s, stergeti-l " +"sau schimbati-l inainte de a seta unul nou." #. module: base #: code:addons/orm.py:2648 @@ -536,7 +572,7 @@ msgstr "Obiect Sursa" #. module: base #: model:res.partner.bank.type,format_layout:base.bank_normal msgid "%(bank_name)s: %(acc_number)s" -msgstr "%(bank_name)s: %(acc_number)s" +msgstr "%(nume_banca)s: %(numar_cont)s" #. module: base #: view:ir.actions.todo:0 @@ -591,12 +627,12 @@ msgstr "" #. module: base #: field:ir.model.relation,name:0 msgid "Relation Name" -msgstr "" +msgstr "Nume Relatie" #. module: base #: view:ir.rule:0 msgid "Create Access Right" -msgstr "" +msgstr "Creeaza Drept de acces" #. module: base #: model:res.country,name:base.tv @@ -636,7 +672,7 @@ msgstr "" #. module: base #: view:workflow.transition:0 msgid "Workflow Transition" -msgstr "" +msgstr "Tranzitie Flux de lucru" #. module: base #: model:res.country,name:base.gf @@ -646,7 +682,7 @@ msgstr "Guyana Franceza" #. module: base #: model:ir.module.module,summary:base.module_hr msgid "Jobs, Departments, Employees Details" -msgstr "" +msgstr "Posturi, Departamente, Detalii angajati" #. module: base #: model:ir.module.module,description:base.module_analytic @@ -662,6 +698,16 @@ msgid "" "that have no counterpart in the general financial accounts.\n" " " msgstr "" +"\n" +"Modul pentru definirea obiectului contabilitatii analitice.\n" +"===============================================\n" +"\n" +"In OpenERP, conturile analitice sunt legate de conturile generale, dar sunt " +"tratate\n" +"in mod total independent. Astfel, puteti introduce diverse operatiuni " +"analitice\n" +"care nu au niciun corespondent in conturile financiare generale.\n" +" " #. module: base #: field:ir.ui.view.custom,ref_id:0 @@ -685,6 +731,19 @@ msgid "" "* Use emails to automatically confirm and send acknowledgements for any " "event registration\n" msgstr "" +"\n" +"Organizarea si gestionarea Evenimentelor.\n" +"======================================\n" +"\n" +"Modulul eveniment va permite sa organizati eficient evenimente si toate " +"sarcinile asociate lor: planificare, urmarirea inregistrarii,\n" +"prezente, etc.\n" +"\n" +"Caracteristici cheie:\n" +"------------\n" +"* Gestioneaza Evenimentele si Inregistrarile dumneavoastra\n" +"* Foloseste email-urile pentru a confirma si trimite automat confirmarile " +"pentru inregistrarea oricarui eveniment\n" #. module: base #: selection:base.language.install,lang:0 @@ -710,6 +769,21 @@ msgid "" "requested it.\n" " " msgstr "" +"\n" +"Traduceri Automate prin Gengo API\n" +"----------------------------------------\n" +"\n" +"Acest modul va instala programatorul pasiv pentru traduceri automate \n" +"folosind Gengo API. Pentru a-l activa, trebuie sa\n" +"1) Va configurati parametrii de autentificare Gengo din `Setari > Companii > " +"Parametrii Gengo`\n" +"2) Lansati wizard-ul din `Setari > Termenii Aplicatiei > Gengo: Solicitare " +"Manuala a Traducerii` si sa urmeze wizard-ul.\n" +"\n" +"Acest wizard va activa CRON si Programatorul si va incepe traducerea " +"automata prin intermediul Serviciilor Gengo pentru toti termenii solicitati " +"de dumneavoastra.\n" +" " #. module: base #: help:ir.actions.report.xml,attachment_use:0 diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po index b9890196ea5..755d9f27fb1 100644 --- a/openerp/addons/base/i18n/zh_CN.po +++ b/openerp/addons/base/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-03 16:01+0000\n" -"PO-Revision-Date: 2012-12-06 18:17+0000\n" -"Last-Translator: ccdos \n" +"PO-Revision-Date: 2012-12-19 07:05+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: 2012-12-07 04:34+0000\n" -"X-Generator: Launchpad (build 16341)\n" +"X-Launchpad-Export-Date: 2012-12-20 04:43+0000\n" +"X-Generator: Launchpad (build 16378)\n" #. module: base #: model:ir.module.module,description:base.module_account_check_writing @@ -1517,7 +1517,7 @@ msgstr "海地" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_fr_hr_payroll msgid "French Payroll" -msgstr "" +msgstr "法国薪酬管理" #. module: base #: view:ir.ui.view:0 @@ -2871,6 +2871,9 @@ msgid "" "Module to attach a google document to any model.\n" "================================================\n" msgstr "" +"\n" +"用于附加 Google 文档到任意模型的模块。\n" +"================================================\n" #. module: base #: code:addons/base/ir/ir_fields.py:334 @@ -3118,7 +3121,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_web_linkedin msgid "LinkedIn Integration" -msgstr "" +msgstr "LinkedIn 集成" #. module: base #: code:addons/orm.py:2021 @@ -3301,6 +3304,10 @@ msgid "" "==========================================\n" " " msgstr "" +"\n" +"比利时薪酬规则的会计数据。\n" +"==========================================\n" +" " #. module: base #: model:res.country,name:base.am @@ -4002,6 +4009,17 @@ msgid "" "If you need to manage your meetings, you should install the CRM module.\n" " " msgstr "" +"\n" +"这是功能完整的日程表系统\n" +"========================================\n" +"\n" +"支持:\n" +"------------\n" +" - 约会排程\n" +" - 重复性事件\n" +"\n" +"如果您需要管理您的会议,您应该安装 CRM 模块。\n" +" " #. module: base #: model:res.country,name:base.je @@ -4039,7 +4057,7 @@ msgstr "%x - 使用日期表示" #. module: base #: view:res.partner:0 msgid "Tag" -msgstr "" +msgstr "标签" #. module: base #: view:res.lang:0