diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 43aaa2f58c1..a380a69dc03 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -99,7 +99,6 @@ for a particular financial year and for preparation of vouchers there is a modul 'project/wizard/project_account_analytic_line_view.xml', 'account_end_fy.xml', 'account_invoice_view.xml', - 'partner_view.xml', 'data/account_data.xml', 'data/data_account_type.xml', 'data/configurable_account_chart.xml', @@ -112,6 +111,7 @@ for a particular financial year and for preparation of vouchers there is a modul 'project/wizard/account_analytic_journal_report_view.xml', 'project/wizard/account_analytic_cost_ledger_for_journal_report_view.xml', 'project/wizard/account_analytic_chart_view.xml', + 'partner_view.xml', 'product_view.xml', 'account_assert_test.xml', 'process/statement_process.xml', diff --git a/addons/account/account.py b/addons/account/account.py index 8709b59fa62..66bbaacb91e 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -25,8 +25,9 @@ from dateutil.relativedelta import relativedelta from operator import itemgetter import time +import openerp from openerp import SUPERUSER_ID -from openerp import pooler, tools +from openerp import tools from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp.tools.float_utils import float_round @@ -131,7 +132,6 @@ class account_payment_term_line(osv.osv): (_check_percent, 'Percentages for Payment Term Line must be between 0 and 1, Example: 0.02 for 2%.', ['value_amount']), ] -account_payment_term_line() class account_account_type(osv.osv): _name = "account.account.type" @@ -197,7 +197,6 @@ class account_account_type(osv.osv): } _order = "code" -account_account_type() def _code_get(self, cr, uid, context=None): acc_type_obj = self.pool.get('account.account.type') @@ -211,7 +210,6 @@ def _code_get(self, cr, uid, context=None): class account_tax(osv.osv): _name = 'account.tax' -account_tax() class account_account(osv.osv): _order = "parent_left" @@ -696,7 +694,6 @@ class account_account(osv.osv): self._check_moves(cr, uid, ids, "unlink", context=context) return super(account_account, self).unlink(cr, uid, ids, context=context) -account_account() class account_journal(osv.osv): _name = "account.journal" @@ -848,7 +845,6 @@ class account_journal(osv.osv): return self.name_get(cr, user, ids, context=context) -account_journal() class account_fiscalyear(osv.osv): _name = "account.fiscalyear" @@ -944,7 +940,6 @@ class account_fiscalyear(osv.osv): ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit) return self.name_get(cr, user, ids, context=context) -account_fiscalyear() class account_period(osv.osv): _name = "account.period" @@ -1006,8 +1001,7 @@ class account_period(osv.osv): def find(self, cr, uid, dt=None, context=None): if context is None: context = {} if not dt: - dt = fields.date.context_today(self,cr,uid,context=context) -#CHECKME: shouldn't we check the state of the period? + dt = fields.date.context_today(self, cr, uid, context=context) args = [('date_start', '<=' ,dt), ('date_stop', '>=', dt)] if context.get('company_id', False): args.append(('company_id', '=', context['company_id'])) @@ -1015,7 +1009,7 @@ class account_period(osv.osv): company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id args.append(('company_id', '=', company_id)) result = [] - if context.get('account_period_prefer_normal'): + if context.get('account_period_prefer_normal', True): # look for non-special periods first, and fallback to all if no result is found result = self.search(cr, uid, args + [('special', '=', False)], context=context) if not result: @@ -1026,6 +1020,9 @@ class account_period(osv.osv): def action_draft(self, cr, uid, ids, *args): mode = 'draft' + for period in self.browse(cr, uid, ids): + if period.fiscalyear_id.state == 'done': + raise osv.except_osv(_('Warning !'), _('You can not re-open a period which belongs to closed fiscal year')) cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),)) cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),)) return True @@ -1067,7 +1064,6 @@ class account_period(osv.osv): return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id)]) return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id), ('special', '=', False)]) -account_period() class account_journal_period(osv.osv): _name = "account.journal.period" @@ -1124,7 +1120,6 @@ class account_journal_period(osv.osv): } _order = "period_id" -account_journal_period() class account_fiscalyear(osv.osv): _inherit = "account.fiscalyear" @@ -1141,7 +1136,6 @@ class account_fiscalyear(osv.osv): }) return super(account_fiscalyear, self).copy(cr, uid, id, default=default, context=context) -account_fiscalyear() #---------------------------------------------------------- # Entries #---------------------------------------------------------- @@ -1219,7 +1213,7 @@ class account_move(osv.osv): return res def _get_period(self, cr, uid, context=None): - ctx = dict(context or {}, account_period_prefer_normal=True) + ctx = dict(context or {}) period_ids = self.pool.get('account.period').find(cr, uid, context=ctx) return period_ids[0] @@ -1380,6 +1374,7 @@ class account_move(osv.osv): 'ref':False, 'balance':False, 'account_tax_id':False, + 'statement_id': False, }) if 'journal_id' in vals and vals.get('journal_id', False): @@ -1416,6 +1411,7 @@ class account_move(osv.osv): context = {} if context is None else context.copy() default.update({ 'state':'draft', + 'ref': False, 'name':'/', }) context.update({ @@ -1637,7 +1633,6 @@ class account_move(osv.osv): valid_moves = [move.id for move in valid_moves] return len(valid_moves) > 0 and valid_moves or False -account_move() class account_move_reconcile(osv.osv): _name = "account.move.reconcile" @@ -1675,7 +1670,7 @@ class account_move_reconcile(osv.osv): elif reconcile.line_partial_ids: first_partner = reconcile.line_partial_ids[0].partner_id.id move_lines = reconcile.line_partial_ids - if any([line.partner_id.id != first_partner for line in move_lines]): + if any([(line.account_id.type in ('receivable', 'payable') and line.partner_id.id != first_partner) for line in move_lines]): return False return True @@ -1711,7 +1706,6 @@ class account_move_reconcile(osv.osv): result.append((r.id,r.name)) return result -account_move_reconcile() #---------------------------------------------------------- # Tax @@ -1791,7 +1785,7 @@ class account_tax_code(osv.osv): if context.get('period_id', False): period_id = context['period_id'] else: - period_id = self.pool.get('account.period').find(cr, uid) + period_id = self.pool.get('account.period').find(cr, uid, context=context) if not period_id: return dict.fromkeys(ids, 0.0) period_id = period_id[0] @@ -1859,7 +1853,6 @@ class account_tax_code(osv.osv): ] _order = 'code' -account_tax_code() class account_tax(osv.osv): """ @@ -1883,7 +1876,7 @@ class account_tax(osv.osv): def get_precision_tax(): def change_digit_tax(cr): - res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, SUPERUSER_ID, 'Account') + res = openerp.registry(cr.dbname)['decimal.precision'].precision_get(cr, SUPERUSER_ID, 'Account') return (16, res+2) return change_digit_tax @@ -2267,7 +2260,6 @@ class account_tax(osv.osv): total += r['amount'] return res -account_tax() # --------------------------------------------------------- # Account Entries Models @@ -2379,7 +2371,6 @@ class account_model(osv.osv): return {'value': {'company_id': company_id}} -account_model() class account_model_line(osv.osv): _name = "account.model.line" @@ -2403,7 +2394,6 @@ class account_model_line(osv.osv): ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in model, they must be positive!'), ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in model, they must be positive!'), ] -account_model_line() # --------------------------------------------------------- # Account Subscription @@ -2477,7 +2467,6 @@ class account_subscription(osv.osv): self.write(cr, uid, ids, {'state':'running'}) return True -account_subscription() class account_subscription_line(osv.osv): _name = "account.subscription.line" @@ -2506,7 +2495,6 @@ class account_subscription_line(osv.osv): _rec_name = 'date' -account_subscription_line() # --------------------------------------------------------------- # Account Templates: Account, Tax, Tax Code and chart. + Wizard @@ -2514,7 +2502,6 @@ account_subscription_line() class account_tax_template(osv.osv): _name = 'account.tax.template' -account_tax_template() class account_account_template(osv.osv): _order = "code" @@ -2642,7 +2629,6 @@ class account_account_template(osv.osv): obj_acc._parent_store_compute(cr) return acc_template_ref -account_account_template() class account_add_tmpl_wizard(osv.osv_memory): """Add one more account from the template. @@ -2696,7 +2682,6 @@ class account_add_tmpl_wizard(osv.osv_memory): def action_cancel(self, cr, uid, ids, context=None): return { 'type': 'state', 'state': 'end' } -account_add_tmpl_wizard() class account_tax_code_template(osv.osv): @@ -2768,7 +2753,6 @@ class account_tax_code_template(osv.osv): (_check_recursion, 'Error!\nYou cannot create recursive Tax Codes.', ['parent_id']) ] _order = 'code,name' -account_tax_code_template() class account_chart_template(osv.osv): @@ -2801,7 +2785,6 @@ class account_chart_template(osv.osv): 'complete_tax_set': True, } -account_chart_template() class account_tax_template(osv.osv): @@ -2931,7 +2914,6 @@ class account_tax_template(osv.osv): res.update({'tax_template_to_tax': tax_template_to_tax, 'account_dict': todo_dict}) return res -account_tax_template() # Fiscal Position Templates @@ -2979,7 +2961,6 @@ class account_fiscal_position_template(osv.osv): }) return True -account_fiscal_position_template() class account_fiscal_position_tax_template(osv.osv): _name = 'account.fiscal.position.tax.template' @@ -2992,7 +2973,6 @@ class account_fiscal_position_tax_template(osv.osv): 'tax_dest_id': fields.many2one('account.tax.template', 'Replacement Tax') } -account_fiscal_position_tax_template() class account_fiscal_position_account_template(osv.osv): _name = 'account.fiscal.position.account.template' @@ -3004,7 +2984,6 @@ class account_fiscal_position_account_template(osv.osv): 'account_dest_id': fields.many2one('account.account.template', 'Account Destination', domain=[('type','<>','view')], required=True) } -account_fiscal_position_account_template() # --------------------------------------------------------- # Account generation from template wizards @@ -3397,7 +3376,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): try: tmp2 = obj_data.get_object_reference(cr, uid, *ref) if tmp2: - self.pool.get(tmp2[0]).write(cr, uid, tmp2[1], { + self.pool[tmp2[0]].write(cr, uid, tmp2[1], { 'currency_id': obj_wizard.currency_id.id }) except ValueError, e: @@ -3544,7 +3523,6 @@ class wizard_multi_charts_accounts(osv.osv_memory): current_num += 1 return True -wizard_multi_charts_accounts() class account_bank_accounts_wizard(osv.osv_memory): _name='account.bank.accounts.wizard' @@ -3556,6 +3534,5 @@ class account_bank_accounts_wizard(osv.osv_memory): 'account_type': fields.selection([('cash','Cash'), ('check','Check'), ('bank','Bank')], 'Account Type', size=32), } -account_bank_accounts_wizard() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/account_analytic_line.py b/addons/account/account_analytic_line.py index f3617106f28..e141f33b9d1 100644 --- a/addons/account/account_analytic_line.py +++ b/addons/account/account_analytic_line.py @@ -143,7 +143,6 @@ class account_analytic_line(osv.osv): return res return False -account_analytic_line() class res_partner(osv.osv): """ Inherits partner and adds contract information in the partner form """ @@ -154,6 +153,5 @@ class res_partner(osv.osv): 'partner_id', 'Contracts', readonly=True), } -res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 8e1a5dd26c6..023765d73f0 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -61,7 +61,7 @@ class account_bank_statement(osv.osv): return res def _get_period(self, cr, uid, context=None): - periods = self.pool.get('account.period').find(cr, uid,context=context) + periods = self.pool.get('account.period').find(cr, uid, context=context) if periods: return periods[0] return False @@ -500,7 +500,6 @@ class account_bank_statement(osv.osv): 'context':ctx, } -account_bank_statement() class account_bank_statement_line(osv.osv): @@ -576,6 +575,5 @@ class account_bank_statement_line(osv.osv): 'type': 'general', } -account_bank_statement_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 86d3b0d24de..40f0ca80738 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -66,7 +66,6 @@ class account_cashbox_line(osv.osv): 'bank_statement_id' : fields.many2one('account.bank.statement', ondelete='cascade'), } -account_cashbox_line() class account_cash_statement(osv.osv): @@ -316,7 +315,6 @@ class account_cash_statement(osv.osv): return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context) -account_cash_statement() class account_journal(osv.osv): _inherit = 'account.journal' @@ -336,7 +334,6 @@ class account_journal(osv.osv): 'cashbox_line_ids' : _default_cashbox_line_ids, } -account_journal() class account_journal_cashbox_line(osv.osv): _name = 'account.journal.cashbox.line' @@ -348,6 +345,5 @@ class account_journal_cashbox_line(osv.osv): _order = 'pieces asc' -account_journal_cashbox_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/account_financial_report.py b/addons/account/account_financial_report.py index 1d9a4a794eb..0c2e5845b89 100644 --- a/addons/account/account_financial_report.py +++ b/addons/account/account_financial_report.py @@ -24,8 +24,6 @@ from datetime import datetime from dateutil.relativedelta import relativedelta from operator import itemgetter -from openerp import netsvc -from openerp import pooler from openerp.osv import fields, osv import openerp.addons.decimal_precision as dp from openerp.tools.translate import _ @@ -140,6 +138,5 @@ class account_financial_report(osv.osv): 'style_overwrite': 0, } -account_financial_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/account_financial_report_data.xml b/addons/account/account_financial_report_data.xml index 6410a5e887c..e8ff33151c3 100644 --- a/addons/account/account_financial_report_data.xml +++ b/addons/account/account_financial_report_data.xml @@ -6,16 +6,19 @@ --> Profit and Loss + sum Income + detail_with_hierarchy account_type Expense + detail_with_hierarchy account_type diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index 58e824a6250..b03babc63ac 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -20,10 +20,11 @@

+ - +
+ + {'search_default_partner_id': [active_id], 'default_partner_id': active_id} + Contracts/Analytic Accounts + account.analytic.account + + + + + partner.view.buttons + res.partner + + + + + + +
+ +
+
+
+
+ + + + +
+
+ +
+
+
+ +
+
+
+
+
+
+ \ No newline at end of file diff --git a/addons/im_livechat/__init__.py b/addons/im_livechat/__init__.py new file mode 100644 index 00000000000..2825a75179c --- /dev/null +++ b/addons/im_livechat/__init__.py @@ -0,0 +1,2 @@ + +import im_livechat diff --git a/addons/im_livechat/__openerp__.py b/addons/im_livechat/__openerp__.py new file mode 100644 index 00000000000..8b9ea3924d5 --- /dev/null +++ b/addons/im_livechat/__openerp__.py @@ -0,0 +1,29 @@ +{ + 'name' : 'Live Support', + 'version': '1.0', + 'summary': 'Live Chat with Visitors/Customers', + 'category': 'Tools', + 'complexity': 'easy', + 'description': + """ +Live Chat Support +================= + +Allow to drop instant messaging widgets on any web page that will communicate +with the current server and dispatch visitors request amongst several live +chat operators. + + """, + 'data': [ + "security/im_livechat_security.xml", + "security/ir.model.access.csv", + "im_livechat_view.xml", + ], + 'demo': [ + "im_livechat_demo.xml", + ], + 'depends' : ["im", "mail", "portal_anonymous"], + 'installable': True, + 'auto_install': False, + 'application': True, +} diff --git a/addons/im_livechat/im_livechat.py b/addons/im_livechat/im_livechat.py new file mode 100644 index 00000000000..1ffb422fe6a --- /dev/null +++ b/addons/im_livechat/im_livechat.py @@ -0,0 +1,245 @@ +# -*- 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 . +# +############################################################################## + +import openerp +import openerp.addons.im.im as im +import json +import random +import jinja2 +from openerp.osv import osv, fields +from openerp import tools + +env = jinja2.Environment( + loader=jinja2.PackageLoader('openerp.addons.im_livechat', "."), + autoescape=False +) +env.filters["json"] = json.dumps + +class LiveChatController(openerp.addons.web.http.Controller): + _cp_path = '/im_livechat' + + @openerp.addons.web.http.httprequest + def loader(self, req, **kwargs): + p = json.loads(kwargs["p"]) + db = p["db"] + channel = p["channel"] + user_name = p.get("user_name", None) + req.session._db = db + req.session._uid = None + req.session._login = "anonymous" + req.session._password = "anonymous" + info = req.session.model('im_livechat.channel').get_info_for_chat_src(channel) + info["db"] = db + info["channel"] = channel + info["userName"] = user_name + return req.make_response(env.get_template("loader.js").render(info), + headers=[('Content-Type', "text/javascript")]) + + @openerp.addons.web.http.httprequest + def web_page(self, req, **kwargs): + p = json.loads(kwargs["p"]) + db = p["db"] + channel = p["channel"] + req.session._db = db + req.session._uid = None + req.session._login = "anonymous" + req.session._password = "anonymous" + script = req.session.model('im_livechat.channel').read(channel, ["script"])["script"] + info = req.session.model('im_livechat.channel').get_info_for_chat_src(channel) + info["script"] = script + return req.make_response(env.get_template("web_page.html").render(info), + headers=[('Content-Type', "text/html")]) + + @openerp.addons.web.http.jsonrequest + def available(self, req, db, channel): + req.session._db = db + req.session._uid = None + req.session._login = "anonymous" + req.session._password = "anonymous" + return req.session.model('im_livechat.channel').get_available_user(channel) > 0 + +class im_livechat_channel(osv.osv): + _name = 'im_livechat.channel' + + def _get_default_image(self, cr, uid, context=None): + image_path = openerp.modules.get_module_resource('im_livechat', 'static/src/img', 'default.png') + return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64')) + def _get_image(self, cr, uid, ids, name, args, context=None): + result = dict.fromkeys(ids, False) + for obj in self.browse(cr, uid, ids, context=context): + result[obj.id] = tools.image_get_resized_images(obj.image) + return result + def _set_image(self, cr, uid, id, name, value, args, context=None): + return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) + + + def _are_you_inside(self, cr, uid, ids, name, arg, context=None): + res = {} + for record in self.browse(cr, uid, ids, context=context): + res[record.id] = False + for user in record.user_ids: + if user.id == uid: + res[record.id] = True + break + return res + + def _script(self, cr, uid, ids, name, arg, context=None): + res = {} + for record in self.browse(cr, uid, ids, context=context): + res[record.id] = env.get_template("include.html").render({ + "url": self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'), + "parameters": {"db":cr.dbname, "channel":record.id}, + }) + return res + + def _web_page(self, cr, uid, ids, name, arg, context=None): + res = {} + for record in self.browse(cr, uid, ids, context=context): + res[record.id] = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + \ + "/im_livechat/web_page?p=" + json.dumps({"db":cr.dbname, "channel":record.id}) + return res + + _columns = { + 'name': fields.char(string="Channel Name", size=200, required=True), + 'user_ids': fields.many2many('res.users', 'im_livechat_channel_im_user', 'channel_id', 'user_id', string="Users"), + 'are_you_inside': fields.function(_are_you_inside, type='boolean', string='Are you inside the matrix?', store=False), + 'script': fields.function(_script, type='text', string='Script', store=False), + 'web_page': fields.function(_web_page, type='url', string='Web Page', store=False, size="200"), + 'button_text': fields.char(string="Text of the Button", size=200), + 'input_placeholder': fields.char(string="Chat Input Placeholder", size=200), + 'default_message': fields.char(string="Welcome Message", size=200, help="This is an automated 'welcome' message that your visitor will see when they initiate a new chat session."), + # image: all image fields are base64 encoded and PIL-supported + 'image': fields.binary("Photo", + help="This field holds the image used as photo for the group, limited to 1024x1024px."), + 'image_medium': fields.function(_get_image, fnct_inv=_set_image, + string="Medium-sized photo", type="binary", multi="_get_image", + store={ + 'im_livechat.channel': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), + }, + help="Medium-sized photo of the group. It is automatically "\ + "resized as a 128x128px image, with aspect ratio preserved. "\ + "Use this field in form views or some kanban views."), + 'image_small': fields.function(_get_image, fnct_inv=_set_image, + string="Small-sized photo", type="binary", multi="_get_image", + store={ + 'im_livechat.channel': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), + }, + help="Small-sized photo of the group. It is automatically "\ + "resized as a 64x64px image, with aspect ratio preserved. "\ + "Use this field anywhere a small image is required."), + } + + def _default_user_ids(self, cr, uid, context=None): + return [(6, 0, [uid])] + + _defaults = { + 'button_text': "Have a Question? Chat with us.", + 'input_placeholder': "How may I help you?", + 'default_message': '', + 'user_ids': _default_user_ids, + 'image': _get_default_image, + } + + def get_available_user(self, cr, uid, channel_id, context=None): + channel = self.browse(cr, openerp.SUPERUSER_ID, channel_id, context=context) + users = [] + for user in channel.user_ids: + iuid = self.pool.get("im.user").get_by_user_id(cr, uid, user.id, context=context)["id"] + imuser = self.pool.get("im.user").browse(cr, uid, iuid, context=context) + if imuser.im_status: + users.append(imuser) + if len(users) == 0: + return False + return random.choice(users).id + + def test_channel(self, cr, uid, channel, context=None): + if not channel: + return {} + return { + 'url': self.browse(cr, uid, channel[0], context=context or {}).web_page, + 'type': 'ir.actions.act_url' + } + + def get_info_for_chat_src(self, cr, uid, channel, context=None): + url = self.pool.get('ir.config_parameter').get_param(cr, openerp.SUPERUSER_ID, 'web.base.url') + chan = self.browse(cr, uid, channel, context=context) + return { + "url": url, + 'buttonText': chan.button_text, + 'inputPlaceholder': chan.input_placeholder, + 'defaultMessage': chan.default_message, + "channelName": chan.name, + } + + def join(self, cr, uid, ids, context=None): + self.write(cr, uid, ids, {'user_ids': [(4, uid)]}) + return True + + def quit(self, cr, uid, ids, context=None): + self.write(cr, uid, ids, {'user_ids': [(3, uid)]}) + return True + + +class im_message(osv.osv): + _inherit = 'im.message' + + def _support_member(self, cr, uid, ids, name, arg, context=None): + res = {} + for record in self.browse(cr, uid, ids, context=context): + res[record.id] = False + if record.to_id.user and record.from_id.user: + continue + elif record.to_id.user: + res[record.id] = record.to_id.user.id + elif record.from_id.user: + res[record.id] = record.from_id.user.id + return res + + def _customer(self, cr, uid, ids, name, arg, context=None): + res = {} + for record in self.browse(cr, uid, ids, context=context): + res[record.id] = False + if record.to_id.uuid and record.from_id.uuid: + continue + elif record.to_id.uuid: + res[record.id] = record.to_id.id + elif record.from_id.uuid: + res[record.id] = record.from_id.id + return res + + def _direction(self, cr, uid, ids, name, arg, context=None): + res = {} + for record in self.browse(cr, uid, ids, context=context): + res[record.id] = False + if not not record.to_id.user and not not record.from_id.user: + continue + elif not not record.to_id.user: + res[record.id] = "c2s" + elif not not record.from_id.user: + res[record.id] = "s2c" + return res + + _columns = { + 'support_member_id': fields.function(_support_member, type='many2one', relation='res.users', string='Support Member', store=True, select=True), + 'customer_id': fields.function(_customer, type='many2one', relation='im.user', string='Customer', store=True, select=True), + 'direction': fields.function(_direction, type="selection", selection=[("s2c", "Support Member to Customer"), ("c2s", "Customer to Support Member")], + string='Direction', store=False), + } diff --git a/addons/im_livechat/im_livechat_demo.xml b/addons/im_livechat/im_livechat_demo.xml new file mode 100644 index 00000000000..f199179fb50 --- /dev/null +++ b/addons/im_livechat/im_livechat_demo.xml @@ -0,0 +1,15 @@ + + + + + + YourWebsite.com + Hello, how may I help you? + + + + + + + + diff --git a/addons/im_livechat/im_livechat_view.xml b/addons/im_livechat/im_livechat_view.xml new file mode 100644 index 00000000000..f684fd561fc --- /dev/null +++ b/addons/im_livechat/im_livechat_view.xml @@ -0,0 +1,146 @@ + + + + + + + Live Chat Channels + im_livechat.channel + kanban,form + +

+ Click to define a new live chat channel. +

+ You can create channels for each website on which you want + to integrate the live chat widget, allowing you website + visitors to talk in real time with your operators. +

+ Each channel has it's own URL that you can send by email to + your customers in order to start chatting with you. +

+
+
+ + + + + support_channel.kanban + im_livechat.channel + + + + + + + + +
+ +
+
+

+ +
+ + +
+
+
+
+
+
+
+ + + + support_channel.form + im_livechat.channel + +
+ + +
+
+ + + + + + + + +
+ X +
+ +

+
+
+
+
+
+
+
+ + + + + +
+ +
+ +

+ Copy and paste this code into your website, within the &lt;head&gt; tag: +

+ +

+ or copy this url and send it by email to your customers or suppliers: +

+ +
+ +
+
+
+
+ + + History + im.message + list + ["|", ('to_id.user', '=', None), ('from_id.user', '=', None)] + + + + + im.message.tree + im.message + + + + + + + + + + + +
+
diff --git a/addons/im_livechat/include.html b/addons/im_livechat/include.html new file mode 100644 index 00000000000..55de6212361 --- /dev/null +++ b/addons/im_livechat/include.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/addons/im_livechat/loader.js b/addons/im_livechat/loader.js new file mode 100644 index 00000000000..669591b410f --- /dev/null +++ b/addons/im_livechat/loader.js @@ -0,0 +1,24 @@ + +require.config({ + context: "oelivesupport", + baseUrl: {{url | json}} + "/im_livechat/static/ext/static/js", + shim: { + underscore: { + init: function() { + return _.noConflict(); + }, + }, + "jquery.achtung": { + deps: ['jquery'], + }, + }, +})(["livesupport", "jquery"], function(livesupport, jQuery) { + jQuery.noConflict(); + livesupport.main({{url | json}}, {{db | json}}, "anonymous", "anonymous", {{channel | json}}, { + buttonText: {{buttonText | json}}, + inputPlaceholder: {{inputPlaceholder | json}}, + defaultMessage: {{(defaultMessage or None) | json}}, + auto: window.oe_im_livechat_auto || false, + userName: {{userName | json}} || undefined, + }); +}); diff --git a/addons/im_livechat/security/im_livechat_security.xml b/addons/im_livechat/security/im_livechat_security.xml new file mode 100644 index 00000000000..5ad020a8a78 --- /dev/null +++ b/addons/im_livechat/security/im_livechat_security.xml @@ -0,0 +1,36 @@ + + + + + + Live Support + + + + + User + + The user will be able to join support channels. + + + + Manager + The user will be able to delete support channels. + + + + + + + Live Support Managers can read messages from live support + + + ["|", ('to_id.user', '=', None), ('from_id.user', '=', None)] + + + + + + + + diff --git a/addons/im_livechat/security/ir.model.access.csv b/addons/im_livechat/security/ir.model.access.csv new file mode 100644 index 00000000000..6e17c1a127f --- /dev/null +++ b/addons/im_livechat/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_ls_chann1,im_livechat.channel,model_im_livechat_channel,,1,0,0,0 +access_ls_chann2,im_livechat.channel,model_im_livechat_channel,group_im_livechat,1,1,1,0 +access_ls_chann3,im_livechat.channel,model_im_livechat_channel,group_im_livechat_manager,1,1,1,1 +access_ls_message,im_livechat.im.message,im.model_im_message,portal.group_anonymous,0,0,0,0 +access_im_user,im_livechat.im.user,im.model_im_user,portal.group_anonymous,1,0,0,0 \ No newline at end of file diff --git a/addons/im_livechat/static/ext/Makefile b/addons/im_livechat/static/ext/Makefile new file mode 100644 index 00000000000..b73ca4f2b89 --- /dev/null +++ b/addons/im_livechat/static/ext/Makefile @@ -0,0 +1,3 @@ + +static/js/livesupport_templates.js: static/js/livesupport_templates.html + python static/js/to_jsonp.py static/js/livesupport_templates.html oe_livesupport_templates_callback > static/js/livesupport_templates.js \ No newline at end of file diff --git a/addons/im_livechat/static/ext/static/audio/Ting.mp3 b/addons/im_livechat/static/ext/static/audio/Ting.mp3 new file mode 100644 index 00000000000..6fd090a89ce Binary files /dev/null and b/addons/im_livechat/static/ext/static/audio/Ting.mp3 differ diff --git a/addons/im_livechat/static/ext/static/audio/Ting.ogg b/addons/im_livechat/static/ext/static/audio/Ting.ogg new file mode 100644 index 00000000000..8d17ea85bd3 Binary files /dev/null and b/addons/im_livechat/static/ext/static/audio/Ting.ogg differ diff --git a/addons/im_livechat/static/ext/static/css/livesupport.css b/addons/im_livechat/static/ext/static/css/livesupport.css new file mode 100644 index 00000000000..bfe26b5e838 --- /dev/null +++ b/addons/im_livechat/static/ext/static/css/livesupport.css @@ -0,0 +1,190 @@ + + + +.openerp_style { /* base style of openerp */ + font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif; + color: #4c4c4c; + font-size: 13px; + background: white; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5); +} + +/* button */ + +.oe_chat_button { + position: fixed; + bottom: 0px; + right: 6px; + display: inline-block; + min-width: 100px; + background-color: rgba(60, 60, 60, 0.6); + font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; + font-size: 14px; + font-weight: bold; + padding: 10px; + color: white; + text-shadow: rgb(59, 76, 88) 1px 1px 0px; + border: 1px solid rgb(80, 80, 80); + border-bottom: 0px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + cursor: pointer; +} + +/* conversations */ + +.oe_im_chatview { + position: fixed; + overflow: hidden; + bottom: 42px; + margin-right: 6px; + background: rgba(60, 60, 60, 0.8); + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + -moz-box-shadow: 0 0 3px rgba(0,0,0,0.3), 0 2px 4px rgba(0,0,0,0.3); + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.3); + width: 240px; +} +.oe_im_chatview .oe_im_chatview_disconnected { + display:none; + z-index: 100; + width: 100%; + background: #E8EBEF; + padding: 5px; + font-size: 11px; + color: #999; + line-height: 14px; + height: 28px; + overflow: hidden; +} +.oe_im_chatview.oe_im_chatview_disconnected_status .oe_im_chatview_disconnected { + display: block; +} +.oe_im_chatview .oe_im_chatview_header { + padding: 3px 6px 2px; + background: #DEDEDE; + background: -moz-linear-gradient(#FCFCFC, #DEDEDE); + background: -webkit-gradient(linear, left top, left bottom, from(#FCFCFC), to(#DEDEDE)); + -moz-border-radius: 3px 3px 0 0; + -webkit-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; + border-bottom: 1px solid #AEB9BD; + cursor: pointer; +} +.oe_im_chatview .oe_im_chatview_close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + font-size: 18px; + line-height: 16px; + float: right; + font-weight: bold; + color: black; + text-shadow: 0 1px 0 white; + opacity: 0.2; +} +.oe_im_chatview .oe_im_chatview_content { + overflow: auto; + height: 287px; + width: 240px; +} +.oe_im_chatview.oe_im_chatview_disconnected_status .oe_im_chatview_content { + height: 249px; +} +.oe_im_chatview .oe_im_chatview_footer { + position: relative; + padding: 3px; + border-top: 1px solid #AEB9BD; + background: #DEDEDE; + background: -moz-linear-gradient(#FCFCFC, #DEDEDE); + background: -webkit-gradient(linear, left top, left bottom, from(#FCFCFC), to(#DEDEDE)); + -moz-border-radius: 0 0 3px 3px; + -webkit-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.oe_im_chatview .oe_im_chatview_input { + width: 222px; + font-family: Lato, Helvetica, sans-serif; + font-size: 13px; + color: #333; + padding: 1px 5px; + border: 1px solid #AEB9BD; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + -moz-box-shadow: inset 0 1px 4px rgba(0,0,0,0.2); + -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.2); + box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.2); +} +.oe_im_chatview .oe_im_chatview_bubble { + background: white; + position: relative; + padding: 3px; + margin: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +.oe_im_chatview .oe_im_chatview_clip { + position: relative; + float: left; + width: 26px; + height: 26px; + margin-right: 4px; + -moz-box-shadow: 0 0 2px 1px rgba(0,0,0,0.25); + -webkit-box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.25); + box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.25); +} +.oe_im_chatview .oe_im_chatview_avatar { + float: left; + width: 26px; + height: auto; + clip: rect(0, 26px, 26px, 0); + max-width: 100%; + width: auto 9; + height: auto; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +.oe_im_chatview .oe_im_chatview_time { + position: absolute; + right: 0px; + top: 0px; + margin: 3px; + text-align: right; + line-height: 13px; + font-size: 11px; + color: #999; + width: 60px; + overflow: hidden; +} +.oe_im_chatview .oe_im_chatview_from { + margin: 0 0 2px 0; + line-height: 14px; + font-weight: bold; + font-size: 12px; + width: 140px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + color: #3A87AD; +} +.oe_im_chatview .oe_im_chatview_bubble_list { +} +.oe_im_chatview .oe_im_chatview_bubble_item { + margin: 0 0 2px 30px; + line-height: 14px; + word-wrap: break-word; +} + +.oe_im_chatview_online { + display: none; + margin-top: -4px; + width: 11px; + height: 11px; +} diff --git a/addons/im_livechat/static/ext/static/img/avatar/avatar.jpeg b/addons/im_livechat/static/ext/static/img/avatar/avatar.jpeg new file mode 100644 index 00000000000..7168794022e Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/avatar/avatar.jpeg differ diff --git a/addons/im_livechat/static/ext/static/img/button-gloss.png b/addons/im_livechat/static/ext/static/img/button-gloss.png new file mode 100755 index 00000000000..6f3957702fe Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/button-gloss.png differ diff --git a/addons/im_livechat/static/ext/static/img/glyphicons-halflings-white.png b/addons/im_livechat/static/ext/static/img/glyphicons-halflings-white.png new file mode 100755 index 00000000000..3bf6484a29d Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/glyphicons-halflings-white.png differ diff --git a/addons/im_livechat/static/ext/static/img/glyphicons-halflings.png b/addons/im_livechat/static/ext/static/img/glyphicons-halflings.png new file mode 100755 index 00000000000..a9969993201 Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/glyphicons-halflings.png differ diff --git a/addons/im_livechat/static/ext/static/img/green.png b/addons/im_livechat/static/ext/static/img/green.png new file mode 100644 index 00000000000..01fb373c251 Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/green.png differ diff --git a/addons/im_livechat/static/ext/static/img/logo.png b/addons/im_livechat/static/ext/static/img/logo.png new file mode 100644 index 00000000000..aca5f4c60d8 Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/logo.png differ diff --git a/addons/im_livechat/static/ext/static/img/wood.png b/addons/im_livechat/static/ext/static/img/wood.png new file mode 100644 index 00000000000..22f2450d3ad Binary files /dev/null and b/addons/im_livechat/static/ext/static/img/wood.png differ diff --git a/addons/im_livechat/static/ext/static/js/jquery.achtung.css b/addons/im_livechat/static/ext/static/js/jquery.achtung.css new file mode 100644 index 00000000000..820ae3e9194 --- /dev/null +++ b/addons/im_livechat/static/ext/static/js/jquery.achtung.css @@ -0,0 +1,306 @@ +/** + * achtung 0.3.0 + * + * Growl-like notifications for jQuery + * + * Copyright (c) 2009 Josh Varner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Portions of this file are from the jQuery UI CSS framework. + * + * @license http://www.opensource.org/licenses/mit-license.php + * @author Josh Varner + */ + +/* IE 6 doesn't support position: fixed */ +* html #achtung-overlay { + position:absolute; +} + +/* IE6 includes padding in width */ +* html .achtung { + width: 280px; +} + +#achtung-overlay { + overflow: hidden; + position: fixed; + top: 15px; + right: 15px; + width: 280px; + z-index:50; +} + +.achtung { + display:none; + margin-bottom: 8px; + padding: 15px 15px; + background-color: #000; + color: white; + width: 250px; + font-weight: bold; + position:relative; + overflow: hidden; + -moz-box-shadow: #aaa 1px 1px 2px; + -webkit-box-shadow: #aaa 1px 1px 2px; + box-shadow: #aaa 1px 1px 2px; + -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; + /* Note that if using show/hide animations, IE will lose + this setting */ + opacity: .85; + filter:Alpha(Opacity=85); +} + +/** + * This section from jQuery UI CSS framework + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Can (and should) be removed if you are already loading the jQuery UI CSS + * to reduce payload size. + */ +.ui-icon { display: block; overflow: hidden; background-repeat: no-repeat; } +.ui-icon { width: 16px; height: 16px; } +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + +.achtung .achtung-message-icon { + margin-top: 0px; + margin-left: -.5em; + margin-right: .5em; + float: left; + zoom: 1; +} + +.achtung .ui-icon.achtung-close-button { + float: right; + margin-right: -8px; + margin-top: -12px; + cursor: pointer; + color: white; + text-align: right; +} + +.achtung .ui-icon.achtung-close-button:after { + content: "x" +} + +/* Slightly darker for these colors (readability) */ +.achtungSuccess, .achtungFail, .achtungWait { + /* Note that if using show/hide animations, IE will lose + this setting */ + opacity: .93; filter:Alpha(Opacity=93); +} + +.achtungSuccess { + background-color: #4DB559; +} + +.achtungFail { + background-color: #D64450; +} + +.achtungWait { + background-color: #658093; +} + +.achtungSuccess .ui-icon.achtung-close-button, +.achtungFail .ui-icon.achtung-close-button { +} + +.achtungSuccess .ui-icon.achtung-close-button-hover, +.achtungFail .ui-icon.achtung-close-button-hover { +} + +.achtung .wait-icon { +} + +.achtung .achtung-message { + display: inline; +} diff --git a/addons/im_livechat/static/ext/static/js/jquery.achtung.js b/addons/im_livechat/static/ext/static/js/jquery.achtung.js new file mode 100644 index 00000000000..1aa69469c1d --- /dev/null +++ b/addons/im_livechat/static/ext/static/js/jquery.achtung.js @@ -0,0 +1,273 @@ +/** + * achtung 0.3.0 + * + * Growl-like notifications for jQuery + * + * Copyright (c) 2009 Josh Varner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @license http://www.opensource.org/licenses/mit-license.php + * @author Josh Varner + */ + +/*globals jQuery,clearTimeout,document,navigator,setTimeout +*/ +(function($) { + +/** + * This is based on the jQuery UI $.widget code. I would have just made this + * a $.widget but I didn't want the jQuery UI dependency. + */ +$.fn.achtung = function(options) +{ + var isMethodCall = (typeof options === 'string'), + args = Array.prototype.slice.call(arguments, 0), + name = 'achtung'; + + // handle initialization and non-getter methods + return this.each(function() { + var instance = $.data(this, name); + + // prevent calls to internal methods + if (isMethodCall && options.substring(0, 1) === '_') { + return this; + } + + // constructor + (!instance && !isMethodCall && + $.data(this, name, new $.achtung(this))._init(args)); + + // method call + (instance && isMethodCall && $.isFunction(instance[options]) && + instance[options].apply(instance, args.slice(1))); + }); +}; + +$.achtung = function(element) +{ + var args = Array.prototype.slice.call(arguments, 0), $el; + + if (!element || !element.nodeType) { + $el = $('
'); + return $el.achtung.apply($el, args); + } + + this.$container = $(element); +}; + + +/** + * Static members + **/ +$.extend($.achtung, { + version: '0.3.0', + $overlay: false, + defaults: { + timeout: 10, + disableClose: false, + icon: false, + className: '', + animateClassSwitch: false, + showEffects: {'opacity':'toggle','height':'toggle'}, + hideEffects: {'opacity':'toggle','height':'toggle'}, + showEffectDuration: 500, + hideEffectDuration: 700 + } +}); + +/** + * Non-static members + **/ +$.extend($.achtung.prototype, { + $container: false, + closeTimer: false, + options: {}, + + _init: function(args) + { + var o, self = this; + + args = $.isArray(args) ? args : []; + + + args.unshift($.achtung.defaults); + args.unshift({}); + + o = this.options = $.extend.apply($, args); + + if (!$.achtung.$overlay) { + $.achtung.$overlay = $('
').appendTo(document.body); + } + + if (!o.disableClose) { + $('') + .click(function () { self.close(); }) + .hover(function () { $(this).addClass('achtung-close-button-hover'); }, + function () { $(this).removeClass('achtung-close-button-hover'); }) + .prependTo(this.$container); + } + + this.changeIcon(o.icon, true); + + if (o.message) { + this.$container.append($('' + o.message + '')); + } + + (o.className && this.$container.addClass(o.className)); + (o.css && this.$container.css(o.css)); + + this.$container + .addClass('achtung') + .appendTo($.achtung.$overlay); + + if (o.showEffects) { + this.$container.toggle(); + } else { + this.$container.show(); + } + + if (o.timeout > 0) { + this.timeout(o.timeout); + } + }, + + timeout: function(timeout) + { + var self = this; + + if (this.closeTimer) { + clearTimeout(this.closeTimer); + } + + this.closeTimer = setTimeout(function() { self.close(); }, timeout * 1000); + this.options.timeout = timeout; + }, + + /** + * Change the CSS class associated with this message, using + * a transition if available (not availble in Safari/Webkit). + * If no transition is available, the switch is immediate. + * + * #LATER Check if this has been corrected in Webkit or jQuery UI + * #TODO Make transition time configurable + * @param newClass string Name of new class to associate + */ + changeClass: function(newClass) + { + var self = this; + + if (this.options.className === newClass) { + return; + } + + this.$container.queue(function() { + if (!self.options.animateClassSwitch || + /webkit/.test(navigator.userAgent.toLowerCase()) || + !$.isFunction($.fn.switchClass)) { + self.$container.removeClass(self.options.className); + self.$container.addClass(newClass); + } else { + self.$container.switchClass(self.options.className, newClass, 500); + } + + self.options.className = newClass; + self.$container.dequeue(); + }); + }, + + changeIcon: function(newIcon, force) + { + var self = this; + + if ((force !== true || newIcon === false) && this.options.icon === newIcon) { + return; + } + + if (force || this.options.icon === false) { + this.$container.prepend($('')); + this.options.icon = newIcon; + return; + } else if (newIcon === false) { + this.$container.find('.achtung-message-icon').remove(); + this.options.icon = false; + return; + } + + this.$container.queue(function() { + var $span = $('.achtung-message-icon', self.$container); + + if (!self.options.animateClassSwitch || + /webkit/.test(navigator.userAgent.toLowerCase()) || + !$.isFunction($.fn.switchClass)) { + $span.removeClass(self.options.icon); + $span.addClass(newIcon); + } else { + $span.switchClass(self.options.icon, newIcon, 500); + } + + self.options.icon = newIcon; + self.$container.dequeue(); + }); + }, + + + changeMessage: function(newMessage) + { + this.$container.queue(function() { + $('.achtung-message', $(this)).html(newMessage); + $(this).dequeue(); + }); + }, + + + update: function(options) + { + (options.className && this.changeClass(options.className)); + (options.css && this.$container.css(options.css)); + (typeof(options.icon) !== 'undefined' && this.changeIcon(options.icon)); + (options.message && this.changeMessage(options.message)); + (options.timeout && this.timeout(options.timeout)); + }, + + close: function() + { + var o = this.options, $container = this.$container; + + if (o.hideEffects) { + this.$container.animate(o.hideEffects, o.hideEffectDuration); + } else { + this.$container.hide(); + } + + $container.queue(function() { + $container.removeData('achtung'); + $container.remove(); + + if ($.achtung.$overlay && $.achtung.$overlay.is(':empty')) { + $.achtung.$overlay.remove(); + $.achtung.$overlay = false; + } + + $container.dequeue(); + }); + } +}); + +})(jQuery); \ No newline at end of file diff --git a/addons/im_livechat/static/ext/static/js/jquery.js b/addons/im_livechat/static/ext/static/js/jquery.js new file mode 100644 index 00000000000..ded03845983 --- /dev/null +++ b/addons/im_livechat/static/ext/static/js/jquery.js @@ -0,0 +1,9555 @@ +/*! + * jQuery JavaScript Library v1.9.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-1-14 + */ +(function( window, undefined ) { +"use strict"; +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.9.0", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, all, a, select, opt, input, fragment, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: div.firstChild.nodeType === 3, + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: a.getAttribute("href") === "/a", + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + checkOn: !!input.value, + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: document.compatMode === "CSS1Compat", + + // Will be defined later + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + body.style.zoom = 1; + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})(); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt /* For internal use only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data, false ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name, false ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + // Try to fetch any internally stored data first + return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + } + + this.each(function() { + jQuery.data( this, key, value ); + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + hooks.cur = fn; + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + // Toggle whole class name + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + // In IE9+, Flash objects don't have .getAttribute (#12945) + // Support: IE9+ + if ( typeof elem.getAttribute !== "undefined" ) { + ret = elem.getAttribute( name ); + } + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( rboolean.test( name ) ) { + // Set corresponding property to false for boolean attributes + // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 + if ( !getSetAttribute && ruseDefault.test( name ) ) { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } else { + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + var + // Use .prop to determine if this attribute is understood as boolean + prop = jQuery.prop( elem, name ), + + // Fetch it accordingly + attr = typeof prop === "boolean" && elem.getAttribute( name ), + detail = typeof prop === "boolean" ? + + getSetInput && getSetAttribute ? + attr != null : + // oldIE fabricates an empty string for missing boolean attributes + // and conflates checked/selected into attroperties + ruseDefault.test( name ) ? + elem[ jQuery.camelCase( "default-" + name ) ] : + !!attr : + + // fetch an attribute node for properties not recognized as boolean + elem.getAttributeNode( name ); + + return detail && detail.value !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; + +// fix oldIE value attroperty +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return jQuery.nodeName( elem, "input" ) ? + + // Ignore the value *property* by using defaultValue + elem.defaultValue : + + ret && ret.specified ? ret.value : undefined; + }, + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret == null ? undefined : ret; + } + }); + }); + + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + // Don't attach events to noData or text/comment nodes (but allow plain objects) + elemData = elem.nodeType !== 3 && elem.nodeType !== 8 && jQuery._data( elem ); + + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = event.type || event, + namespaces = event.namespace ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + event.isTrigger = true; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + } + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== document.activeElement && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === document.activeElement && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var i, + cachedruns, + Expr, + getText, + isXML, + compile, + hasDuplicate, + outermostContext, + + // Local document vars + setDocument, + document, + docElem, + documentIsXML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + sortOrder, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + support = {}, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Array methods + arr = [], + pop = arr.pop, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rsibling = /[\x20\t\r\n\f]*[+~]/, + + rnative = /\{\s*\[native code\]\s*\}/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, + funescape = function( _, escaped ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + return high !== high ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Use a stripped-down slice if we can't use a native one +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +/** + * For feature detection + * @param {Function} fn The function to test for native support + */ +function isNative( fn ) { + return rnative.test( fn + "" ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var cache, + keys = []; + + return (cache = function( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + }); +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( !documentIsXML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + + // QSA path + if ( support.qsa && !rbuggyQSA.test(selector) ) { + old = true; + nid = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsXML = isXML( doc ); + + // Check if getElementsByTagName("*") returns only elements + support.tagNameNoComments = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if attributes should be retrieved by attribute nodes + support.attributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }); + + // Check if getElementsByClassName can be trusted + support.getByClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }); + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + support.getByName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = doc.getElementsByName && + // buggy browsers will return fewer than the correct 2 + doc.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + doc.getElementsByName( expando + 0 ).length; + support.getIdNotName = !doc.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + + // IE6/7 return modified attributes + Expr.attrHandle = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }) ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }; + + // ID find and filter + if ( support.getIdNotName ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && !documentIsXML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && !documentIsXML ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.tagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Name + Expr.find["NAME"] = support.getByName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }; + + // Class + Expr.find["CLASS"] = support.getByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) { + return context.getElementsByClassName( className ); + } + }; + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21), + // no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ]; + + if ( (support.qsa = isNative(doc.querySelectorAll)) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE8 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = ""; + if ( div.querySelectorAll("[i^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = new RegExp( rbuggyMatches.join("|") ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = isNative(docElem.contains) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + var compare; + + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { + if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { + if ( a === doc || contains( preferredDoc, a ) ) { + return -1; + } + if ( b === doc || contains( preferredDoc, b ) ) { + return 1; + } + return 0; + } + return compare & 4 ? -1 : 1; + } + + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return ( ~b.sourceIndex || MAX_NEGATIVE ) - ( contains( preferredDoc, a ) && ~a.sourceIndex || MAX_NEGATIVE ); + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + // Always assume the presence of duplicates if sort doesn't + // pass them to our comparison function (as in Google Chrome). + hasDuplicate = false; + [0, 0].sort( sortOrder ); + support.detectDuplicates = hasDuplicate; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyQSA always contains :focus, so no need for an existence check + if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + var val; + + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + if ( !documentIsXML ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( documentIsXML || support.attributes ) { + return elem.getAttribute( name ); + } + return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ? + name : + val && val.specified ? val.value : null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +function siblingCheck( a, b ) { + var cur = a && b && a.nextSibling; + + for ( ; cur; cur = cur.nextSibling ) { + if ( cur === b ) { + return -1; + } + } + + return a ? 1 : -1; +} + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[4] ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + + nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifider + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsXML ? + elem.getAttribute("xml:lang") || elem.getAttribute("lang") : + elem.lang) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push( { + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + // `i` starts as a string, so matchedCount would equal "00" if there are no elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !documentIsXML && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["needsContext"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + documentIsXML, + results, + rsibling.test( selector ) + ); + return results; +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Easy API for creating new setFilters +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Initialize with the default document +setDocument(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, ret, self; + + if ( typeof selector !== "string" ) { + self = this; + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < self.length; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + ret = []; + for ( i = 0; i < this.length; i++ ) { + jQuery.find( selector, this[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( jQuery.unique( ret ) ); + ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true) ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, false, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, false, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + var isFunc = jQuery.isFunction( value ); + + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( !isFunc && typeof value !== "string" ) { + value = jQuery( value ).not( this ).detach(); + } + + return this.domManip( [ value ], true, function( elem ) { + var next = this.nextSibling, + parent = this.parentNode; + + if ( parent && this.nodeType === 1 || this.nodeType === 11 ) { + + jQuery( this ).remove(); + + if ( next ) { + next.parentNode.insertBefore( elem, next ); + } else { + parent.appendChild( elem ); + } + } + }); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, table ? self.html() : undefined ); + } + self.domManip( args, table, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + node, + i + ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery.ajax({ + url: node.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + var attr = elem.getAttributeNode("type"); + elem.type = ( attr && attr.specified ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, data, e; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== "undefined" ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, srcElements, node, i, clone, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var contains, elem, tag, tmp, wrap, tbody, j, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== "undefined" ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + } +}); +var curCSS, getStyles, iframe, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else if ( !values[ index ] && !isHidden( elem ) ) { + jQuery._data( elem, "olddisplay", jQuery.css( elem, "display" ) ); + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + var bool = typeof state === "boolean"; + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery(" + + \ No newline at end of file diff --git a/addons/im_livechat/static/src/img/default.png b/addons/im_livechat/static/src/img/default.png new file mode 100644 index 00000000000..07d2503ce4e Binary files /dev/null and b/addons/im_livechat/static/src/img/default.png differ diff --git a/addons/im_livechat/static/src/img/icon.png b/addons/im_livechat/static/src/img/icon.png new file mode 100644 index 00000000000..07d2503ce4e Binary files /dev/null and b/addons/im_livechat/static/src/img/icon.png differ diff --git a/addons/im_livechat/web_page.html b/addons/im_livechat/web_page.html new file mode 100644 index 00000000000..2e1ea609126 --- /dev/null +++ b/addons/im_livechat/web_page.html @@ -0,0 +1,61 @@ + + + + + {{script}} + + + +
+

{{channelName | escape}}

+
Live Chat Powered by OpenERP.
+
+ + diff --git a/addons/l10n_ar/__init__.py b/addons/l10n_ar/__init__.py index 92da5dbf966..25e7e337165 100644 --- a/addons/l10n_ar/__init__.py +++ b/addons/l10n_ar/__init__.py @@ -23,7 +23,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_at/account_wizard.py b/addons/l10n_at/account_wizard.py index 278837322ac..0aec5392a8a 100644 --- a/addons/l10n_at/account_wizard.py +++ b/addons/l10n_at/account_wizard.py @@ -30,7 +30,6 @@ class AccountWizard_cd(osv.osv_memory): 'code_digits' : 0, } -AccountWizard_cd() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_be/fiscal_templates.xml b/addons/l10n_be/fiscal_templates.xml index 5e26a7e67c1..5cf5a21381b 100644 --- a/addons/l10n_be/fiscal_templates.xml +++ b/addons/l10n_be/fiscal_templates.xml @@ -22,12 +22,6 @@ - - - - - - diff --git a/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py b/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py index d89d427ef6b..b74cfa21b8a 100644 --- a/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py +++ b/addons/l10n_be/wizard/l10n_be_account_vat_declaration.py @@ -209,6 +209,5 @@ class l10n_be_vat_declaration(osv.osv_memory): 'target': 'new', } -l10n_be_vat_declaration() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py index 7aa612d95ff..29a1a1508a4 100644 --- a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py +++ b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py @@ -39,7 +39,6 @@ class vat_listing_clients(osv.osv_memory): 'vat_amount': fields.float('VAT Amount'), } -vat_listing_clients() class partner_vat(osv.osv_memory): """ Vat Listing """ @@ -116,7 +115,6 @@ class partner_vat(osv.osv_memory): 'limit_amount': 250, } -partner_vat() class partner_vat_list(osv.osv_memory): """ Partner Vat Listing """ @@ -321,7 +319,6 @@ class partner_vat_list(osv.osv_memory): 'datas': datas, } -partner_vat_list() class partner_vat_listing_print(report_sxw.rml_parse): diff --git a/addons/l10n_be/wizard/l10n_be_vat_intra.py b/addons/l10n_be/wizard/l10n_be_vat_intra.py index ffd42290ed0..703ab9db59b 100644 --- a/addons/l10n_be/wizard/l10n_be_vat_intra.py +++ b/addons/l10n_be/wizard/l10n_be_vat_intra.py @@ -282,7 +282,6 @@ class partner_vat_intra(osv.osv_memory): 'datas': datas, } -partner_vat_intra() class vat_intra_print(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py index 213040d6204..8aabe601bc8 100644 --- a/addons/l10n_be_coda/wizard/account_coda_import.py +++ b/addons/l10n_be_coda/wizard/account_coda_import.py @@ -128,6 +128,8 @@ class account_coda_import(osv.osv_memory): raise osv.except_osv(_('Error') + ' R1004', _("No matching Bank Account (with Account Journal) found.\n\nPlease set-up a Bank Account with as Account Number '%s' and as Currency '%s' and an Account Journal.") % (statement['acc_number'], statement['currency'])) statement['description'] = rmspaces(line[90:125]) statement['balance_start'] = float(rmspaces(line[43:58])) / 1000 + if line[42] == '1': #1 = Debit, the starting balance is negative + statement['balance_start'] = - statement['balance_start'] statement['balance_start_date'] = time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT, time.strptime(rmspaces(line[58:64]), '%d%m%y')) statement['accountHolder'] = rmspaces(line[64:90]) statement['paperSeqNumber'] = rmspaces(line[2:5]) @@ -389,7 +391,7 @@ class account_coda_import(osv.osv_memory): if statement['coda_note'] != '': self.pool.get('account.bank.statement').write(cr, uid, [statement['id']], {'coda_note': statement['coda_note']}, context=context) model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'action_bank_statement_tree') - action = self.pool.get(model).browse(cr, uid, action_id, context=context) + action = self.pool[model].browse(cr, uid, action_id, context=context) return { 'name': action.name, 'view_type': action.view_type, diff --git a/addons/l10n_be_hr_payroll/l10n_be_hr_payroll.py b/addons/l10n_be_hr_payroll/l10n_be_hr_payroll.py index 79909cf79af..e62ea076079 100644 --- a/addons/l10n_be_hr_payroll/l10n_be_hr_payroll.py +++ b/addons/l10n_be_hr_payroll/l10n_be_hr_payroll.py @@ -39,7 +39,6 @@ class hr_contract_be(osv.osv): 'retained_net_amount': fields.float('Net retained ', digits_compute=dp.get_precision('Payroll')), } -hr_contract_be() class hr_employee_be(osv.osv): _inherit = 'hr.employee' @@ -52,6 +51,5 @@ class hr_employee_be(osv.osv): 'disabled_children_number': fields.integer('Number of disabled children'), } -hr_employee_be() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_be_invoice_bba/partner.py b/addons/l10n_be_invoice_bba/partner.py index 9e0eec10713..bf8d5d7a0c3 100644 --- a/addons/l10n_be_invoice_bba/partner.py +++ b/addons/l10n_be_invoice_bba/partner.py @@ -44,9 +44,13 @@ class res_partner(osv.osv): help='Select Algorithm to generate the Structured Communication on Outgoing Invoices.' ), } + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + \ + ['out_inv_comm_type', 'out_inv_comm_algorithm'] + + _default = { 'out_inv_comm_type': 'none', } -res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_bo/__init__.py b/addons/l10n_bo/__init__.py index 92da5dbf966..25e7e337165 100644 --- a/addons/l10n_bo/__init__.py +++ b/addons/l10n_bo/__init__.py @@ -23,7 +23,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_br/account.py b/addons/l10n_br/account.py index 05ad589ab82..1adb6d92baa 100644 --- a/addons/l10n_br/account.py +++ b/addons/l10n_br/account.py @@ -17,7 +17,7 @@ #along with this program. If not, see . # ################################################################################# -from openerp import pooler +import openerp from openerp.osv import fields, osv TAX_CODE_COLUMNS = { @@ -92,7 +92,8 @@ class account_tax_code(osv.osv): def get_precision_tax(): def change_digit_tax(cr): - res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, 1, 'Account') + decimal_precision = openerp.registry(cr.dbname)['decimal.precision'] + res = decimal_precision.precision_get(cr, 1, 'Account') return (16, res+2) return change_digit_tax diff --git a/addons/l10n_ch/__init__.py b/addons/l10n_ch/__init__.py index f0b006c2b32..12d42707679 100644 --- a/addons/l10n_ch/__init__.py +++ b/addons/l10n_ch/__init__.py @@ -1,8 +1,11 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # Author: Nicolas Bessi. Copyright Camptocamp SA -# Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA +# Financial contributors: Hasa SA, Open Net SA, +# Prisme Solutions Informatique SA, Quod SA +# +# Translation contributors: brain-tec AG, Agile Business Group # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as diff --git a/addons/l10n_ch/__openerp__.py b/addons/l10n_ch/__openerp__.py index e068c7365a1..8960224891d 100644 --- a/addons/l10n_ch/__openerp__.py +++ b/addons/l10n_ch/__openerp__.py @@ -1,8 +1,11 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # Author: Nicolas Bessi. Copyright Camptocamp SA -# Donors: Hasa SA, Open Net SA and Prisme Solutions Informatique SA +# Financial contributors: Hasa SA, Open Net SA, +# Prisme Solutions Informatique SA, Quod SA +# +# Translation contributors: brain-tec AG, Agile Business Group # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -21,29 +24,29 @@ {'name': 'Switzerland - Accounting', 'description': """ -Swiss localization : -==================== -**Multilang swiss STERCHI account chart and taxes** - **Author:** Camptocamp SA + Swiss localization : + ==================== + **Multilang swiss STERCHI account chart and taxes** + **Author:** Camptocamp SA - **Donors:** Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA + **Financial contributors:** Prisme Solutions Informatique SA, Quod SA - **Translators:** brain-tec AG, Agile Business Group + **Translation contributors:** brain-tec AG, Agile Business Group -**This release will introduce major changes to l10n_ch.** + **This release will introduce major changes to l10n_ch.** -Due to important refactoring needs and the Switzerland adoption of new international payment standard during 2013-2014. We have reorganised the swiss localization addons this way: + Due to important refactoring needs and the Switzerland adoption of new international payment standard during 2013-2014. We have reorganised the swiss localization addons this way: -- **l10n_ch**: Multilang swiss STERCHI account chart and taxes (official addon) -- **l10n_ch_base_bank**: Technical module that introduces a new and simplified version of bank type management -- **l10n_ch_bank**: List of swiss banks -- **l10n_ch_zip**: List of swiss postal zip -- **l10n_ch_dta**: Support of dta payment protocol (will be deprecated end 2014) -- **l10n_ch_payment_slip**: Support of ESR/BVR payment slip report and reconciliation. Report refactored with easy element positioning. -- **l10n_ch_sepa**: Alpha implementation of PostFinance SEPA/PAIN support will be completed during 2013/2014 + - **l10n_ch**: Multilang swiss STERCHI account chart and taxes (official addon) + - **l10n_ch_base_bank**: Technical module that introduces a new and simplified version of bank type management + - **l10n_ch_bank**: List of swiss banks + - **l10n_ch_zip**: List of swiss postal zip + - **l10n_ch_dta**: Support of dta payment protocol (will be deprecated end 2014) + - **l10n_ch_payment_slip**: Support of ESR/BVR payment slip report and reconciliation. Report refactored with easy element positioning. + - **l10n_ch_sepa**: Alpha implementation of PostFinance SEPA/PAIN support will be completed during 2013/2014 -The modules will be soon available on OpenERP swiss localization on launchpad: -https://launchpad.net/openerp-swiss-localization + The modules will be soon available on OpenERP swiss localization on launchpad: + https://launchpad.net/openerp-swiss-localization """, 'version': '7.0', 'author': 'Camptocamp', diff --git a/addons/l10n_ch/account_wizard.py b/addons/l10n_ch/account_wizard.py index e0a9e84b90a..4b985c09b76 100644 --- a/addons/l10n_ch/account_wizard.py +++ b/addons/l10n_ch/account_wizard.py @@ -1,8 +1,11 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # Author: Nicolas Bessi. Copyright Camptocamp SA -# Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA +# Financial contributors: Hasa SA, Open Net SA, +# Prisme Solutions Informatique SA, Quod SA +# +# Translation contributors: brain-tec AG, Agile Business Group # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as diff --git a/addons/l10n_cl/__init__.py b/addons/l10n_cl/__init__.py index 92da5dbf966..25e7e337165 100644 --- a/addons/l10n_cl/__init__.py +++ b/addons/l10n_cl/__init__.py @@ -23,7 +23,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_es/__openerp__.py b/addons/l10n_es/__openerp__.py index 2264988fd99..9dd201c20cc 100644 --- a/addons/l10n_es/__openerp__.py +++ b/addons/l10n_es/__openerp__.py @@ -4,57 +4,60 @@ # OpenERP, Open Source Management Solution # Copyright (c) 2008-2010 Zikzakmedia S.L. (http://zikzakmedia.com) All Rights Reserved. # Jordi Esteve +# Copyright (c) 2012-2013, Grupo OPENTIA () Registered EU Trademark. +# Dpto. Consultoría +# Copyright (c) 2013 Serv. Tecnol. Avanzados (http://www.serviciosbaeza.com) +# Pedro Manuel Baeza # $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 +# it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# GNU Affero General Public License for more details. # -# You should have received a copy of the GNU General Public License +# You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # ############################################################################## { - 'name': 'Spanish - Accounting (PGCE 2008)', - 'version': '3.0', - 'author': 'Spanish Localization Team', - 'website': 'https://launchpad.net/openerp-spain', - 'category': 'Localization/Account Charts', - 'description': """ + "name" : "Spanish Charts of Accounts (PGCE 2008)", + "version" : "3.0", + "author" : "Spanish Localization Team", + 'website' : 'https://launchpad.net/openerp-spain', + "category" : "Localization/Account Charts", + "description": """ Spanish Charts of Accounts (PGCE 2008). ======================================= * Defines the following chart of account templates: * Spanish General Chart of Accounts 2008 * Spanish General Chart of Accounts 2008 for small and medium companies + * Spanish General Chart of Accounts 2008 for associations * Defines templates for sale and purchase VAT * Defines tax code templates - -**Note:** You should install the l10n_ES_account_balance_report module for yearly - account reporting (balance, profit & losses). """, - 'license': 'GPL-3', - 'depends': ['account', 'base_vat', 'base_iban'], - 'data': [ - 'account_chart.xml', - 'taxes_data.xml', - 'fiscal_templates.xml', - 'account_chart_pymes.xml', - 'taxes_data_pymes.xml', - 'fiscal_templates_pymes.xml', - 'l10n_es_wizard.xml' + "license" : "AGPL-3", + "depends" : ["account", "base_vat", "base_iban"], + "data" : [ + "account_chart.xml", + "taxes_data.xml", + "fiscal_templates.xml", + "account_chart_pymes.xml", + "taxes_data_pymes.xml", + "fiscal_templates_pymes.xml", + "account_chart_assoc.xml", + "taxes_data_assoc.xml", + "fiscal_templates_assoc.xml", + "l10n_es_wizard.xml", ], - 'demo': [], + "demo" : [], 'auto_install': False, - 'installable': True, + "installable": True, 'images': ['images/config_chart_l10n_es.jpeg','images/l10n_es_chart.jpeg'], } - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_es/account_chart.xml b/addons/l10n_es/account_chart.xml index 8ffabd17fe7..1bc63f6419f 100644 --- a/addons/l10n_es/account_chart.xml +++ b/addons/l10n_es/account_chart.xml @@ -1,6 +1,6 @@ - + @@ -2722,7 +2722,7 @@ view - Amortización acumulada de otras instaciones + Amortización acumulada de otras instalaciones @@ -2730,7 +2730,7 @@ other - Amortización acumulada de otras instaciones + Amortización acumulada de otras instalaciones @@ -4743,7 +4743,7 @@ 460 - + other Anticipos de remuneraciones @@ -4759,7 +4759,7 @@ 465 - + other Remuneraciones pendientes de pago @@ -4775,7 +4775,7 @@ 466 - + other Remuneraciones mediante sistemas de aportación definida pendientes de pago @@ -4805,8 +4805,8 @@ Hacienda Pública, deudora por IVA - - 4700 + + 470000 receivable @@ -4869,6 +4869,14 @@ Hacienda Pública, IVA soportado + + 472000 + + + other + Hacienda Pública. IVA soportado + + 473 @@ -4877,6 +4885,14 @@ Hacienda Pública, retenciones y pagos a cuenta + + 473000 + + + other + Hacienda Pública, retenciones y pagos a cuenta + + 474 @@ -4949,8 +4965,8 @@ Hacienda Pública, acreedora por IVA - - 4750 + + 475000 payable @@ -4965,8 +4981,8 @@ Hacienda Pública, acreedora por retenciones practicadas - - 4751 + + 475100 payable @@ -5029,6 +5045,14 @@ Hacienda Pública, IVA repercutido + + 477000 + + + other + Hacienda Pública. IVA repercutido + + 479 @@ -8722,7 +8746,7 @@ view - Ingresos de créditos a largo plazo + Intereses de deudas @@ -8730,7 +8754,7 @@ view - Ingresos de créditos a largo plazo, empresas del grupo + Intereses de deudas, empresas del grupo @@ -8738,7 +8762,7 @@ other - Ingresos de créditos a largo plazo, empresas del grupo + Intereses de deudas, empresas del grupo @@ -8746,7 +8770,7 @@ view - Ingresos de créditos a largo plazo, empresas asociadas + Intereses de deudas, empresas asociadas @@ -8754,7 +8778,7 @@ other - Ingresos de créditos a largo plazo, empresas asociadas + Intereses de deudas, empresas asociadas @@ -8762,7 +8786,7 @@ view - Ingresos de créditos a largo plazo, otras partes vinculadas + Intereses de deudas, otras partes vinculadas @@ -8770,7 +8794,7 @@ other - Ingresos de créditos a largo plazo, otras partes vinculadas + Intereses de deudas, otras partes vinculadas @@ -8778,7 +8802,7 @@ view - Ingresos de créditos a largo plazo con entidades de crédito + Intereses de deudas con entidades de crédito @@ -8786,7 +8810,7 @@ other - Ingresos de créditos a largo plazo con entidades de crédito + Intereses de deudas con entidades de crédito @@ -8794,7 +8818,7 @@ view - Ingresos de créditos a largo plazo, otras empresas + Intereses de deudas, otras empresas @@ -8802,7 +8826,7 @@ other - Ingresos de créditos a largo plazo, otras empresas + Intereses de deudas, otras empresas diff --git a/addons/l10n_es/account_chart_assoc.xml b/addons/l10n_es/account_chart_assoc.xml new file mode 100644 index 00000000000..670eed53c9b --- /dev/null +++ b/addons/l10n_es/account_chart_assoc.xml @@ -0,0 +1,12426 @@ + + + + + + + + + 0 + + + view + Plan General Contable ASOCIACIONES 2008 + + + + + 1 + + + view + Financiación Básica + + + + 10 + + + view + Capital + + + + + 100 + + + view + Dotación fundacional + + + + 100 + + + other + Dotación fundacional + + + + 101 + + + view + Fondo social + + + + 101 + + + other + Fondo social + + + + 102 + + + view + Capital + + + + 102 + + + other + Capital + + + + 103 + + + view + Fundadores/asociados por desembolsos no exigidos + + + + 1030 + + + view + Fundadores, parte no desembolsada en fundaciones + + + + 1030 + + + other + Fundadores, parte no desembolsada en fundaciones + + + + 1034 + + + view + Asociados, parte no desembolsada en asociaciones + + + + 1034 + + + other + Asociados, parte no desembolsada en asociaciones + + + + 104 + + + view + Fundadores/asociados por aportaciones no dinerarias pendientes + + + + 1040 + + + view + Fundadores, por aportaciones no dinerarias pendientes, en fundaciones + + + + 1040 + + + other + Fundadores, por aportaciones no dinerarias pendientes, en fundaciones + + + + 1044 + + + view + Asociados, por aportaciones no dinerarias pendientes, en asociaciones + + + + 1044 + + + other + Asociados, por aportaciones no dinerarias pendientes, en asociaciones + + + + 108 + + + view + Acciones o participaciones propias en situaciones especiales + + + + 108 + + + other + Acciones o participaciones propias en situaciones especiales + + + + 109 + + + view + Acciones o participaciones propias para reducción de capital + + + + 109 + + + other + Acciones o participaciones propias para reducción de capital + + + + 11 + + + view + Reservas y otros instrumentos de patrimonio + + + + 110 + + + view + Prima de Emisión o asunción + + + + 110 + + + other + Prima de Emisión o asunción + + + + 112 + + + view + Reserva Legal + + + + 112 + + + other + Reserva Legal + + + + 113 + + + view + Reservas voluntarias + + + + 113 + + + other + Reservas voluntarias + + + + 114 + + + view + Reservas especiales + + + + 1140 + + + view + Reservas para acciones o participaciones de la sociedad dominante + + + + 1140 + + + other + Reservas para acciones o participaciones de la sociedad dominante + + + + 1141 + + + view + Reservas estatutarias + + + + 1141 + + + other + Reservas estatutarias + + + + 1142 + + + view + Reserva por capital amortizado + + + + 1142 + + + other + Reserva por capital amortizado + + + + 1144 + + + view + Reservas por acciones propias aceptadas en garantía + + + + 1144 + + + other + Reservas por acciones propias aceptadas en garantía + + + + 118 + + + view + Aportaciones de socios o propietarios + + + + 118 + + + other + Aportaciones de socios o propietarios + + + + 119 + + + view + Diferencias por ajuste del capital a euros + + + + 119 + + + other + Diferencias por ajuste del capital a euros + + + + 12 + + + view + Excedentes pendientes de aplicación + + + + 120 + + + view + Remanente + + + + 120 + + + other + Remanente + + + + 121 + + + view + Excedentes negativos de ejercicios anteriores + + + + 121 + + + other + Excedentes negativos de ejercicios anteriores + + + + 129 + + + view + Excedente del ejercicio + + + + 129 + + + other + Excedente del ejercicio + + + + 13 + + + view + Subvenciones, donaciones y ajustes por cambio de valor + + + + 130 + + + view + Subvenciones oficiales de capital + + + + 1300 + + + view + Subvenciones del Estado + + + + 1300 + + + other + Subvenciones del Estado + + + + 1301 + + + view + Subvenciones de otras Administraciones Públicas + + + + 1301 + + + other + Subvenciones de otras Administraciones Públicas + + + + 131 + + + view + Donaciones y legados de capital + + + + 131 + + + other + Donaciones y legados de capital + + + + 132 + + + view + Otras subvenciones, donaciones y legados + + + + 1320 + + + view + Otras subvenciones + + + + 1320 + + + other + Otras subvenciones + + + + 1321 + + + view + Otras donaciones y legados + + + + 1321 + + + other + Otras donaciones y legados + + + + + 137 + + + view + Ingresos fiscales a distribuir en varios ejercicios + + + + 1370 + + + view + Ingresos fiscales por diferencias permanentes a distribuir en varios ejercicios + + + + 1370 + + + other + Ingresos fiscales por diferencias permanentes a distribuir en varios ejercicios + + + + 1371 + + + view + Ingresos fiscales por deducciones y bonificaciones a distribuir en varios ejercicios + + + + 1371 + + + other + Ingresos fiscales por deducciones y bonificaciones a distribuir en varios ejercicios + + + + 14 + + + view + Provisiones + + + + 141 + + + view + Provisión para impuestos + + + + 141 + + + other + Provisión para impuestos + + + + 142 + + + view + Provisión para otras responsabilidades + + + + 142 + + + other + Provisión para otras responsabilidades + + + + 143 + + + view + Provisión por desmantelamiento, retiro o rehabilitación del inmovilizado + + + + 143 + + + other + Provisión por desmantelamiento, retiro o rehabilitación del inmovilizado + + + + 145 + + + view + Provisión para actuaciones medioambientales + + + + 145 + + + other + Provisión para actuaciones medioambientales + + + + 15 + + + view + Deudas con características especiales + + + + 150 + + + view + Acciones o participaciones consideradas como pasivos financieros + + + + 150 + + + other + Acciones o participaciones consideradas como pasivos financieros + + + + 153 + + + view + Desembolsos no exigidos por acciones o participaciones consideradas como pasivos financieros + + + + 1533 + + + view + Desembolsos no exigidos, empresas del grupo + + + + 1533 + + + other + Desembolsos no exigidos, empresas del grupo + + + + 1534 + + + view + Desembolsos no exigidos, empresas asociadas + + + + 1534 + + + other + Desembolsos no exigidos, empresas asociadas + + + + 1535 + + + view + Desembolsos no exigidos, otras partes vinculadas + + + + 1535 + + + other + Desembolsos no exigidos, otras partes vinculadas + + + + 1536 + + + view + Otros desembolsos no exigidos + + + + 1536 + + + other + Otros desembolsos no exigidos + + + + 154 + + + view + Aportaciones no dinerarias pendientes por acciones o participaciones consideradas como pasivos financieros + + + + 1543 + + + view + Aportaciones no dinerarias pendientes, empresas del grupo + + + + 1543 + + + other + Aportaciones no dinerarias pendientes, empresas del grupo + + + + 1544 + + + view + Aportaciones no dinerarias pendientes, empresas asociadas + + + + 1544 + + + other + Aportaciones no dinerarias pendientes, empresas asociadas + + + + 1545 + + + view + Aportaciones no dinerarias pendientes, otras partes vinculadas + + + + 1545 + + + other + Aportaciones no dinerarias pendientes, otras partes vinculadas + + + + 1546 + + + view + Otras aportaciones no dinerarias pendientes + + + + 1546 + + + other + Otras aportaciones no dinerarias pendientes + + + + 16 + + + view + Deudas con partes vinculadas + + + + 160 + + + view + Deudas con entidades de crédito vinculadas + + + + 1603 + + + view + Deudas con entidades de crédito vinculadas, empresas del grupo + + + + 1603 + + + other + Deudas con entidades de crédito vinculadas, empresas del grupo + + + + 1604 + + + view + Deudas con entidades de crédito vinculadas, empresas asociadas + + + + 1604 + + + other + Deudas con entidades de crédito vinculadas, empresas asociadas + + + + 1605 + + + view + Deudas con otras entidades de crédito vinculadas + + + + 1605 + + + other + Deudas con otras entidades de crédito vinculadas + + + + 161 + + + view + Proveedores de inmovilizado, partes vinculadas + + + + 1613 + + + view + Proveedores de inmovilizado, empresas del grupo + + + + 1613 + + + other + Proveedores de inmovilizado, empresas del grupo + + + + 1614 + + + view + Proveedores de inmovilizado, empresas asociadas + + + + 1614 + + + other + Proveedores de inmovilizado, empresas asociadas + + + + 1615 + + + view + Proveedores de inmovilizado, otras partes vinculadas + + + + 1615 + + + other + Proveedores de inmovilizado, otras partes vinculadas + + + + 162 + + + view + Acreedores por arrendamiento financiero, partes vinculadas + + + + 1623 + + + view + Acreedores por arrendamiento financiero, empresas de grupo + + + + 1623 + + + other + Acreedores por arrendamiento financiero, empresas de grupo + + + + 1624 + + + view + Acreedores por arrendamiento financiero, empresas asociadas + + + + 1624 + + + other + Acreedores por arrendamiento financiero, empresas asociadas + + + + 1625 + + + view + Acreedores por arrendamiento financiero, otras partes vinculadas + + + + 1625 + + + other + Acreedores por arrendamiento financiero, otras partes vinculadas + + + + 163 + + + view + Otras deudas con partes vinculadas + + + + 1633 + + + view + Otras deudas, empresas del grupo + + + + 1633 + + + other + Otras deudas, empresas del grupo + + + + 1634 + + + view + Otras deudas, empresas asociadas + + + + 1634 + + + other + Otras deudas, empresas asociadas + + + + 1635 + + + view + Otras deudas, con otras partes vinculadas + + + + 1635 + + + other + Otras deudas, con otras partes vinculadas + + + + 17 + + + view + Deudas por préstamos recibidos, empréstitos y otros conceptos + + + + 170 + + + view + Deudas con entidades de crédito + + + + 170 + + + other + Deudas con entidades de crédito + + + + 171 + + + view + Deudas + + + + 171 + + + other + Deudas + + + + 172 + + + view + Deudas transformables en subvenciones, donaciones y legados + + + + 172 + + + other + Deudas transformables en subvenciones, donaciones y legados + + + + 173 + + + view + Proveedores de inmovilizado + + + + 173 + + + other + Proveedores de inmovilizado + + + + 174 + + + view + Acreedores por arrendamiento financiero + + + + 174 + + + other + Acreedores por arrendamiento financiero + + + + 175 + + + view + Efectos a pagar + + + + 175 + + + other + Efectos a pagar + + + + 176 + + + view + Pasivos por derivados financieros + + + + 176 + + + other + Pasivos por derivados financieros + + + + 177 + + + view + Obligaciones y bonos + + + + 177 + + + other + Obligaciones y bonos + + + + 179 + + + view + Deudas representadas en otros valores negociables + + + + 179 + + + other + Deudas representadas en otros valores negociables + + + + 18 + + + view + Pasivos por fianzas, garantías y otros conceptos + + + + 180 + + + view + Fianzas recibidas + + + + 180 + + + other + Fianzas recibidas + + + + 181 + + + view + Anticipos recibidos por ventas o prestaciones de servicios + + + + 181 + + + other + Anticipos recibidos por ventas o prestaciones de servicios + + + + 185 + + + view + Depósitos recibidos + + + + 185 + + + other + Depósitos recibidos + + + + 19 + + + view + Situaciones transitorias de financiación + + + + 190 + + + view + Acciones o participaciones emitidas + + + + 190 + + + other + Acciones o participaciones emitidas + + + + 192 + + + view + Suscriptores de acciones + + + + 192 + + + other + Suscriptores de acciones + + + + 194 + + + view + Capital emitido pendiente de inscripción + + + + 194 + + + other + Capital emitido pendiente de inscripción + + + + 195 + + + view + Acciones o participaciones emitidas consideradas como pasivos financieros + + + + 195 + + + other + Acciones o participaciones emitidas consideradas como pasivos financieros + + + + 197 + + + view + Suscriptores de acciones consideradas como pasivos financieros + + + + 197 + + + other + Suscriptores de acciones consideradas como pasivos financieros + + + + 199 + + + view + Acciones o participaciones emitidas consideradas como pasivos financieros pendientes de inscripción + + + + 199 + + + other + Acciones o participaciones emitidas consideradas como pasivos financieros pendientes de inscripción + + + + 2 + + + view + Activo no corriente + + + + 20 + + + view + Inmovilizaciones intangibles + + + + 200 + + + view + Investigación + + + + 200 + + + other + Investigación + + + + 201 + + + view + Desarrollo + + + + 201 + + + other + Desarrollo + + + + 202 + + + view + Concesiones administrativas + + + + 202 + + + other + Concesiones administrativas + + + + 203 + + + view + Propiedad industrial + + + + 203 + + + other + Propiedad industrial + + + + 205 + + + view + Derechos de traspaso + + + + 205 + + + other + Derechos de traspaso + + + + 206 + + + view + Aplicaciones informáticas + + + + 206 + + + other + Aplicaciones informáticas + + + + 207 + + + view + Derechos sobre activos cedidos en uso + + + + 207 + + + other + Derechos sobre activos cedidos en uso + + + + 209 + + + view + Anticipos para inmovilizaciones intangibles + + + + 209 + + + other + Anticipos para inmovilizaciones intangibles + + + + 21 + + + view + Inmovilizaciones materiales + + + + 210 + + + view + Terrenos y bienes naturales + + + + 210 + + + other + Terrenos y bienes naturales + + + + 211 + + + view + Construcciones + + + + 211 + + + other + Construcciones + + + + 212 + + + view + Instalaciones técnicas + + + + 212 + + + other + Instalaciones técnicas + + + + 213 + + + view + Maquinaria + + + + 213 + + + other + Maquinaria + + + + 214 + + + view + Utillaje + + + + 214 + + + other + Utillaje + + + + 215 + + + view + Otras instalaciones + + + + 215 + + + other + Otras instalaciones + + + + 216 + + + view + Mobiliario + + + + 216 + + + other + Mobiliario + + + + 217 + + + view + Equipos para proceso de información + + + + 217 + + + other + Equipos para proceso de información + + + + 218 + + + view + Elementos de transporte + + + + 218 + + + other + Elementos de transporte + + + + 219 + + + view + Otro inmovilizado material + + + + 219 + + + other + Otro inmovilizado material + + + + 22 + + + view + Inversiones inmobiliarias + + + + 220 + + + view + Inversiones en terrenos y bienes naturales + + + + 220 + + + other + Inversiones en terrenos y bienes naturales + + + + 221 + + + view + Inversiones en construcciones + + + + 221 + + + other + Inversiones en construcciones + + + + 23 + + + view + Inmovilizaciones materiales en curso + + + + 230 + + + view + Adaptación de terrenos y bienes naturales + + + + 230 + + + other + Adaptación de terrenos y bienes naturales + + + + 231 + + + view + Construcciones en curso + + + + 231 + + + other + Construcciones en curso + + + + 232 + + + view + Instalaciones técnicas en montaje + + + + 232 + + + other + Instalaciones técnicas en montaje + + + + 233 + + + view + Maquinaria en montaje + + + + 233 + + + other + Maquinaria en montaje + + + + 237 + + + view + Equipos para procesos de información en montaje + + + + 237 + + + other + Equipos para procesos de información en montaje + + + + 239 + + + view + Anticipos para inmovilizaciones materiales + + + + 239 + + + other + Anticipos para inmovilizaciones materiales + + + + 24 + + + view + Bienes del patrimonio histórico + + + + 240 + + + view + Bienes inmuebles + + + + 2400 + + + view + Monumentos + + + + 2400 + + + other + Monumentos + + + + + 2401 + + + view + Jardines históricos + + + + 2401 + + + other + Jardines históricos + + + + + 2402 + + + view + Conjuntos históricos + + + + 2402 + + + other + Conjuntos históricos + + + + + 2403 + + + view + Sitios históricos + + + + 2403 + + + other + Sitios históricos + + + + 2404 + + + view + Zonas arqueológicas + + + + 2404 + + + other + Zonas arqueológicas + + + + 2405 + + + view + Participaciones en otras partes vinculadas + + + + 2405 + + + other + Participaciones en otras partes vinculadas + + + + 241 + + + view + Archivos + + + + 2413 + + + view + Valores representativos de deuda de empresas del grupo + + + + 2413 + + + other + Valores representativos de deuda de empresas del grupo + + + + 2414 + + + view + Valores representativos de deuda de empresas asociadas + + + + 2414 + + + other + Valores representativos de deuda de empresas asociadas + + + + 2415 + + + view + Valores representativos de deuda de otras partes vinculadas + + + + 2415 + + + other + Valores representativos de deuda de otras partes vinculadas + + + + 242 + + + view + Bibliotecas + + + + 2423 + + + view + Créditos a empresas del grupo + + + + 2423 + + + other + Créditos a empresas del grupo + + + + 2424 + + + view + Créditos a empresas asociadas + + + + 2424 + + + other + Créditos a empresas asociadas + + + + 2425 + + + view + Créditos a otras partes vinculadas + + + + 2425 + + + other + Créditos a otras partes vinculadas + + + + + 243 + + + view + Museos + + + + + 243 + + + other + Museos + + + + + 244 + + + view + Bienes muebles + + + + + 244 + + + other + Bienes muebles + + + + + + 249 + + + view + Anticipos sobre bienes del Patrimonio Histórico + + + + + 2490 + + + view + Anticipos sobre bienes inmuebles del Patrimonio Histórico + + + + 2490 + + + other + Anticipos sobre bienes inmuebles del Patrimonio Histórico + + + + + 2491 + + + view + Anticipos sobre archivos del Patrimonio Histórico + + + + 2491 + + + other + Anticipos sobre archivos del Patrimonio Histórico + + + + + 2492 + + + view + Anticipos sobre bibliotecas del Patrimonio Histórico + + + + 2492 + + + other + Anticipos sobre bibliotecas del Patrimonio Histórico + + + + + + 2493 + + + view + Anticipos sobre museos del Patrimonio Histórico + + + + 2493 + + + other + Anticipos sobre museos del Patrimonio Histórico + + + + + 2494 + + + view + Anticipos sobre bienes muebles del Patrimonio Histórico + + + + 2494 + + + other + Anticipos sobre bienes muebles del Patrimonio Histórico + + + + 2495 + + + view + Desembolsos pendientes sobre participaciones en otras partes vinculadas + + + + 2495 + + + other + Desembolsos pendientes sobre participaciones en otras partes vinculadas + + + + 25 + + + view + Otras inversiones financieras + + + + 250 + + + view + Inversiones financieras en instrumentos de patrimonio + + + + 250 + + + other + Inversiones financieras en instrumentos de patrimonio + + + + 251 + + + view + Valores representativos de deuda + + + + 251 + + + other + Valores representativos de deuda + + + + 252 + + + view + Créditos + + + + 252 + + + other + Créditos + + + + 253 + + + view + Créditos por enajenación de inmovilizado + + + + 253 + + + other + Créditos por enajenación de inmovilizado + + + + 254 + + + view + Créditos al personal + + + + 254 + + + other + Créditos al personal + + + + 255 + + + view + Activos por derivados financieros + + + + 255 + + + other + Activos por derivados financieros + + + + 258 + + + view + Imposiciones + + + + 258 + + + other + Imposiciones + + + + 259 + + + view + Desembolsos pendientes sobre participaciones en el patrimonio neto + + + + 259 + + + other + Desembolsos pendientes sobre participaciones en el patrimonio neto + + + + 26 + + + view + Fianzas y depósitos constituidos + + + + 260 + + + view + Fianzas constituidas + + + + 260 + + + other + Fianzas constituidas + + + + 265 + + + view + Depósitos constituidos + + + + 265 + + + other + Depósitos constituidos + + + + 28 + + + view + Amortización acumulada del inmovilizado y otras cuentas correctoras + + + + 280 + + + view + Amortización acumulada del inmovilizado intangible + + + + + 2800 + + + view + Amortización acumulada de investigación + + + + 2800 + + + other + Amortización acumulada de investigación + + + + + + 2801 + + + view + Amortización acumulada de desarrollo + + + + 2801 + + + other + Amortización acumulada de desarrollo + + + + 2802 + + + view + Amortización acumulada de concesiones administrativas + + + + 2802 + + + other + Amortización acumulada de concesiones administrativas + + + + 2803 + + + view + Amortización acumulada de propiedad industrial + + + + 2803 + + + other + Amortización acumulada de propiedad industrial + + + + 2805 + + + view + Amortización acumulada de derechos de traspaso + + + + 2805 + + + other + Amortización acumulada de derechos de traspaso + + + + + 2806 + + + view + Amortización acumulada de aplicaciones informáticas + + + + 2806 + + + other + Amortización acumulada de aplicaciones informáticas + + + + + 2807 + + + view + Amortización acumulada de derechos sobre activos cedidos en uso + + + + 2807 + + + other + Amortización acumulada de derechos sobre activos cedidos en uso + + + + + + + 281 + + + view + Amortización acumulada del inmovilizado material + + + + 2811 + + + view + Amortización acumulada de construcciones + + + + 2811 + + + other + Amortización acumulada de construcciones + + + + 2812 + + + view + Amortización acumulada de instalaciones técnicas + + + + 2812 + + + other + Amortización acumulada de instalaciones técnicas + + + + 2813 + + + view + Amortización acumulada de maquinaria + + + + 2813 + + + other + Amortización acumulada de maquinaria + + + + 2814 + + + view + Amortización acumulada de utillaje + + + + 2814 + + + other + Amortización acumulada de utillaje + + + + 2815 + + + view + Amortización acumulada de otras instaciones + + + + 2815 + + + other + Amortización acumulada de otras instaciones + + + + 2816 + + + view + Amortización acumulada de mobiliario + + + + 2816 + + + other + Amortización acumulada de mobiliario + + + + 2817 + + + view + Amortización acumulada de equipos para proceso de información + + + + 2817 + + + other + Amortización acumulada de equipos para proceso de información + + + + 2818 + + + view + Amortización acumulada de elementos de transporte + + + + 2818 + + + other + Amortización acumulada de elementos de transporte + + + + 2819 + + + view + Amortización acumulada de otro inmovilizado material + + + + 2819 + + + other + Amortización acumulada de otro inmovilizado material + + + + 282 + + + view + Amortización acumulada de las inversiones inmobiliarias + + + + 282 + + + other + Amortización acumulada de las inversiones inmobiliarias + + + + + 283 + + + view + Cesiones de uso sin contraprestación + + + + 2830 + + + view + Cesiones de uso del inmovilizado intangible + + + + 2830 + + + other + Cesiones de uso del inmovilizado intangible + + + + + + 2831 + + + view + Cesiones de uso del inmovilizado material + + + + 2831 + + + other + Cesiones de uso del inmovilizado material + + + + + + 2832 + + + view + Cesiones de uso de las inversiones inmobiliarias + + + + + + 2832 + + + other + Cesiones de uso de las inversiones inmobiliarias + + + + + + 29 + + + view + Deterioro de valor de activos no corrientes + + + + 290 + + + view + Deterioro de valor del inmovilizado intangible + + + + 2900 + + + view + Deterioro del valor de investigación + + + + 2900 + + + other + Deterioro del valor de investigación + + + + 2901 + + + view + Deterioro del valor de desarrollo + + + + 2901 + + + other + Deterioro del valor de desarrollo + + + + 2902 + + + view + Deterioro del valor de concesiones administrativas + + + + 2902 + + + other + Deterioro del valor de concesiones administrativas + + + + 2903 + + + view + Deterioro del valor de propiedad industrial + + + + 2903 + + + other + Deterioro del valor de propiedad industrial + + + + 2905 + + + view + Deterioro del valor de derechos de traspaso + + + + 2905 + + + other + Deterioro del valor de derechos de traspaso + + + + 2906 + + + view + Deterioro del valor de aplicaciones informáticas + + + + 2906 + + + other + Deterioro del valor de aplicaciones informáticas + + + + + 2907 + + + view + Deterioro del valor sobre activos cedidos en uso + + + + 2907 + + + other + Deterioro del valor sobre activos cedidos en uso + + + + + + + + 291 + + + view + Deterioro del valor del inmovilizado material + + + + 2910 + + + view + Deterioro de valor de terrenos y bienes naturales + + + + 2910 + + + other + Deterioro de valor de terrenos y bienes naturales + + + + 2911 + + + view + Deterioro de valor de construcciones + + + + 2911 + + + other + Deterioro de valor de construcciones + + + + 2912 + + + view + Deterioro de valor de instalaciones técnicas + + + + 2912 + + + other + Deterioro de valor de instalaciones técnicas + + + + 2913 + + + view + Deterioro de valor de maquinaria + + + + 2913 + + + other + Deterioro de valor de maquinaria + + + + 2914 + + + view + Deterioro de valor de utillaje + + + + 2914 + + + other + Deterioro de valor de utillaje + + + + 2915 + + + view + Deterioro de valor de otras instaciones + + + + 2915 + + + other + Deterioro de valor de otras instaciones + + + + 2916 + + + view + Deterioro de valor de mobiliario + + + + 2916 + + + other + Deterioro de valor de mobiliario + + + + 2917 + + + view + Deterioro de valor de equipos para proceso de información + + + + 2917 + + + other + Deterioro de valor de equipos para proceso de información + + + + 2918 + + + view + Deterioro de valor de elementos de transporte + + + + 2918 + + + other + Deterioro de valor de elementos de transporte + + + + 2919 + + + view + Deterioro de valor de otro inmovilizado material + + + + 2919 + + + other + Deterioro de valor de otro inmovilizado material + + + + 292 + + + view + Deterioro de valor de las inversiones inmobiliarias + + + + 2920 + + + view + Deterioro de valor de los terrenos y bienes naturales + + + + 2920 + + + other + Deterioro de valor de los terrenos y bienes naturales + + + + 2921 + + + view + Deterioro de valor de construcciones + + + + 2921 + + + other + Deterioro de valor de construcciones + + + + 293 + + + view + Deterioro de valor de participaciones en partes vinculadas + + + + 2933 + + + view + Deterioro de valor de participaciones en empresas del grupo + + + + 2933 + + + other + Deterioro de valor de participaciones en empresas del grupo + + + + 2934 + + + view + Deterioro de valor de participaciones en empresas asociadas + + + + 2934 + + + other + Deterioro de valor de participaciones en empresas asociadas + + + + 2935 + + + view + Deterioro de valor de participaciones a largo plazo en otras partes vinculadas + + + + 2935 + + + other + Deterioro de valor de participaciones a largo plazo en otras partes vinculadas + + + + 294 + + + view + Deterioro de valor de valores representativos de deuda de partes vinculadas + + + + 2943 + + + view + Deterioro de valor de valores representativos de deuda de empresas del grupo + + + + 2943 + + + other + Deterioro de valor de valores representativos de deuda de empresas del grupo + + + + 2944 + + + view + Deterioro de valor de valores representativos de deuda de empresas asociadas + + + + 2944 + + + other + Deterioro de valor de valores representativos de deuda de empresas asociadas + + + + 2945 + + + view + Deterioro de valor de valores representativos de deuda de otras partes vinculadas + + + + 2945 + + + other + Deterioro de valor de valores representativos de deuda de otras partes vinculadas + + + + 295 + + + view + Deterioro de valor de créditos a partes vinculadas + + + + 2953 + + + view + Deterioro de valor de créditos a empresas del grupo + + + + 2953 + + + other + Deterioro de valor de créditos a empresas del grupo + + + + 2954 + + + view + Deterioro de valor de créditos a empresas asociadas + + + + 2954 + + + other + Deterioro de valor de créditos a empresas asociadas + + + + 2955 + + + view + Deterioro de valor de créditos a otras partes vinculadas + + + + 2955 + + + other + Deterioro de valor de créditos a otras partes vinculadas + + + + 296 + + + view + Deterioro de valor de participaciones en el patrimonio neto a largo plazo + + + + 296 + + + other + Deterioro de valor de participaciones en el patrimonio neto a largo plazo + + + + 297 + + + view + Deterioro de valor de valores representativos de deuda + + + + 297 + + + other + Deterioro de valor de valores representativos de deuda + + + + + 298 + + + view + Deterioro de valor de créditos + + + + 298 + + + other + Deterioro de valor de créditos + + + + + 299 + + + view + Deterioro de valor de bienes del Patrimonio Histórico + + + + 299 + + + other + Deterioro de valor de bienes del Patrimonio Histórico + + + + + 2990 + + + view + Deterioro de valor de bienes inmuebles + + + + + 2991 + + + view + Deterioro de valor de archivos + + + + 2991 + + + other + Deterioro de valor de archivos + + + + + + 2992 + + + view + Deterioro de valor de bibliotecas + + + + 2992 + + + other + Deterioro de valor de bibliotecas + + + + + 2993 + + + view + Deterioro de valor de Museos + + + + 2993 + + + other + Deterioro de valor de Museos + + + + + + 2994 + + + view + Deterioro de valor de bienes muebles + + + + 2994 + + + other + Deterioro de valor de bienes muebles + + + + + + 3 + + + view + Existencias + + + + 30 + + + view + Bienes destinados a la actividad + + + + 300 + + + view + Mercaderías A + + + + 300 + + + other + Mercaderías A + + + + 301 + + + view + Mercaderías B + + + + 301 + + + other + Mercaderías B + + + + 31 + + + view + Materias Primas + + + + 310 + + + view + Materias Primas A + + + + 310 + + + other + Materias Primas A + + + + 311 + + + view + Materias Primas B + + + + 311 + + + other + Materias Primas B + + + + 32 + + + view + Otros aprovisionamientos + + + + 320 + + + view + Elementos y conjuntos incorporables + + + + 320 + + + other + Elementos y conjuntos incorporables + + + + 321 + + + view + Combustibles + + + + 321 + + + other + Combustibles + + + + 322 + + + view + Repuestos + + + + 322 + + + other + Repuestos + + + + 325 + + + view + Materiales diversos + + + + 325 + + + other + Materiales diversos + + + + 326 + + + view + Embalajes + + + + 326 + + + other + Embalajes + + + + 327 + + + view + Envases + + + + 327 + + + other + Envases + + + + 328 + + + view + Material de oficina + + + + 328 + + + other + Material de oficina + + + + 33 + + + view + Productos en curso + + + + 330 + + + view + Productos en curso A + + + + 330 + + + other + Productos en curso A + + + + 331 + + + view + Productos en curso B + + + + 331 + + + other + Productos en curso B + + + + 34 + + + view + Productos semiterminados + + + + 340 + + + view + Productos semiterminados A + + + + 340 + + + other + Productos semiterminados A + + + + 341 + + + view + Productos semiterminados B + + + + 341 + + + other + Productos semiterminados B + + + + 35 + + + view + Productos terminados + + + + 350 + + + view + Productos terminados A + + + + 350 + + + other + Productos terminados A + + + + 351 + + + view + Productos terminados B + + + + 351 + + + other + Productos terminados B + + + + 36 + + + view + Subproductos, residuos y materiales recuperados + + + + 360 + + + view + Subproductos A + + + + 360 + + + other + Subproductos A + + + + 361 + + + view + Subproductos B + + + + 361 + + + other + Subproductos B + + + + 365 + + + view + Residuos A + + + + 365 + + + other + Residuos A + + + + 366 + + + view + Residuos B + + + + 366 + + + other + Residuos B + + + + 368 + + + view + Materiales recuperados A + + + + 368 + + + other + Materiales recuperados A + + + + 369 + + + view + Materiales recuperados B + + + + 369 + + + other + Materiales recuperados B + + + + 39 + + + view + Deterioro de valor de las existencias + + + + 390 + + + view + Deterioro de valor de bienes destinados a la actividad + + + + 390 + + + other + Deterioro de valor de bienes destinados a la actividad + + + + 391 + + + view + Deterioro de valor de las materias primas + + + + 391 + + + other + Deterioro de valor de las materias primas + + + + 392 + + + view + Deterioro de valor de otros aprovisionamientos + + + + 392 + + + other + Deterioro de valor de otros aprovisionamientos + + + + 393 + + + view + Deterioro de valor de los productos en curso + + + + 393 + + + other + Deterioro de valor de los productos en curso + + + + 394 + + + view + Deterioro de valor de los productos semiterminados + + + + 394 + + + other + Deterioro de valor de los productos semiterminados + + + + 395 + + + view + Deterioro de valor de los productos terminados + + + + 395 + + + other + Deterioro de valor de los productos terminados + + + + 396 + + + view + Deterioro de valor de los subproductos, residuos y materiales recuperados + + + + 396 + + + other + Deterioro de valor de los subproductos, residuos y materiales recuperados + + + + 4 + + + view + Acreedores y deudores por operaciones de la actividad + + + + 40 + + + view + Proveedores + + + + 400 + + + view + Proveedores + + + + 4000 + + + view + Proveedores (euros) + + + + 4000 + + + payable + Proveedores (euros) + + + + 4004 + + + view + Proveedores (moneda extranjera) + + + + 4004 + + + payable + Proveedores (moneda extranjera) + + + + 4009 + + + view + Proveedores, facturas pendientes de recibir o de formalizar + + + + 4009 + + + payable + Proveedores, facturas pendientes de recibir o de formalizar + + + + 401 + + + view + Proveedores, efectos comerciales a pagar + + + + 401 + + + other + Proveedores, efectos comerciales a pagar + + + + 403 + + + view + Proveedores, empresas del grupo + + + + 4030 + + + view + Proveedores, empresas del grupo (euros) + + + + 4030 + + + payable + Proveedores, empresas del grupo (euros) + + + + 4031 + + + view + Efectos comerciales a pagar, empresas del grupo + + + + 4031 + + + payable + Efectos comerciales a pagar, empresas del grupo + + + + 4034 + + + view + Proveedores, empresas del grupo (moneda extranjera) + + + + 4034 + + + payable + Proveedores, empresas del grupo (moneda extranjera) + + + + 4036 + + + view + Envases y embalajes a devolver a proveedores, empresas del grupo + + + + 4036 + + + payable + Envases y embalajes a devolver a proveedores, empresas del grupo + + + + 4039 + + + view + Proveedores, empresas del grupo, facturas pendientes de recibir o de formalizar + + + + 4039 + + + payable + Proveedores, empresas del grupo, facturas pendientes de recibir o de formalizar + + + + 404 + + + view + Proveedores, empresas asociadas + + + + 404 + + + other + Proveedores, empresas asociadas + + + + 405 + + + view + Proveedores, otras partes vinculadas + + + + 405 + + + other + Proveedores, otras partes vinculadas + + + + 406 + + + view + Envases y embalajes a devolver a proveedores + + + + 406 + + + other + Envases y embalajes a devolver a proveedores + + + + 407 + + + view + Anticipos a proveedores + + + + 407 + + + other + Anticipos a proveedores + + + + 41 + + + view + Benerificiarios y acreedores varios + + + + 410 + + + view + Acreedores por prestaciones de servicios + + + + 4100 + + + view + Acreedores por prestaciones de servicios (euros) + + + + 4100 + + + payable + Acreedores por prestaciones de servicios (euros) + + + + 4104 + + + view + Acreedores por prestaciones de servicios (moneda extranjera) + + + + 4104 + + + payable + Acreedores por prestaciones de servicios (moneda extranjera) + + + + 4109 + + + view + Acreedores por prestaciones de servicios, facturas pendientes de recibir o de formalizar + + + + 4109 + + + payable + Acreedores por prestaciones de servicios, facturas pendientes de recibir o de formalizar + + + + 411 + + + view + Acreedores, efectos comerciales a pagar + + + + 411 + + + other + Acreedores, efectos comerciales a pagar + + + + 412 + + + view + Beneficiarios, acreedores + + + + 412 + + + other + Beneficiarios, acreedores + + + + + + + + + 419 + + + view + Acreedores por operaciones en común + + + + 419 + + + other + Acreedores por operaciones en común + + + + 43 + + + view + Clientes + + + + 430 + + + view + Clientes + + + + 4300 + + + view + Clientes (euros) + + + + 4300 + + + receivable + Clientes (euros) + + + + 4304 + + + view + Clientes (moneda extranjera) + + + + 4304 + + + receivable + Clientes (moneda extranjera) + + + + 4309 + + + view + Clientes, facturas pendientes de recibir o de formalizar + + + + 4309 + + + receivable + Clientes, facturas pendientes de recibir o de formalizar + + + + 431 + + + view + Clientes, efectos comerciales a cobrar + + + + 4310 + + + view + Efectos comerciales en cartera + + + + 4310 + + + receivable + Efectos comerciales en cartera + + + + 4311 + + + view + Efectos comerciales descontados + + + + 4311 + + + receivable + Efectos comerciales descontados + + + + 4312 + + + view + Efectos comerciales en gestión de cobro + + + + 4312 + + + receivable + Efectos comerciales en gestión de cobro + + + + 4315 + + + view + Efectos comerciales impagados + + + + 4315 + + + receivable + Efectos comerciales impagados + + + + 432 + + + view + Clientes, operaciones de factoring + + + + 432 + + + other + Clientes, operaciones de factoring + + + + 433 + + + view + Clientes, empresas del grupo + + + + 4330 + + + view + Clientes empresas del grupo (euros) + + + + 4330 + + + receivable + Clientes empresas del grupo (euros) + + + + 4331 + + + view + Efectos comerciales a cobrar, empresas del grupo + + + + 4331 + + + receivable + Efectos comerciales a cobrar, empresas del grupo + + + + 4332 + + + view + Clientes empresas del grupo, operaciones de factoring + + + + 4332 + + + receivable + Clientes empresas del grupo, operaciones de factoring + + + + 4334 + + + view + Clientes empresas del grupo (moneda extranjera) + + + + 4334 + + + receivable + Clientes empresas del grupo (moneda extranjera) + + + + 4336 + + + view + Clientes empresas del grupo de dudoso cobro + + + + 4336 + + + receivable + Clientes empresas del grupo de dudoso cobro + + + + 4337 + + + view + Envases y embalajes a devolver a clientes, empresas del grupo + + + + 4337 + + + receivable + Envases y embalajes a devolver a clientes, empresas del grupo + + + + 4339 + + + view + Clientes empresas del grupo, facturas pendientes de formalizar + + + + 4339 + + + receivable + Clientes empresas del grupo, facturas pendientes de formalizar + + + + 434 + + + view + Clientes, empresas asociadas + + + + 434 + + + other + Clientes, empresas asociadas + + + + 435 + + + view + Clientes, otras partes vinculadas + + + + 435 + + + other + Clientes, otras partes vinculadas + + + + 436 + + + view + Clientes de dudoso cobro + + + + 436 + + + other + Clientes de dudoso cobro + + + + 437 + + + view + Envases y embalajes a devolver por clientes + + + + 437 + + + other + Envases y embalajes a devolver por clientes + + + + 438 + + + view + Anticipos de clientes + + + + 438 + + + other + Anticipos de clientes + + + + 44 + + + view + Usuarios y deudores varios + + + + 440 + + + view + Deudores + + + + 4400 + + + view + Deudores (euros) + + + + 4400 + + + receivable + Deudores (euros) + + + + 4404 + + + view + Deudores (moneda extranjera) + + + + 4404 + + + receivable + Deudores (moneda extranjera) + + + + 4409 + + + view + Deudores, facturas pendientes de formalizar + + + + 4409 + + + receivable + Deudores, facturas pendientes de formalizar + + + + 441 + + + view + Deudores, efectos comerciales a cobrar + + + + 4410 + + + view + Deudores, efectos comerciales en cartera + + + + 4410 + + + receivable + Deudores, efectos comerciales en cartera + + + + 4411 + + + view + Deudores, efectos comerciales descontados + + + + 4411 + + + receivable + Deudores, efectos comerciales descontados + + + + 4412 + + + view + Deudores, efectos comerciales en gestión de cobro + + + + 4412 + + + receivable + Deudores, efectos comerciales en gestión de cobro + + + + 4415 + + + view + Deudores, efectos comerciales impagados + + + + 4415 + + + receivable + Deudores, efectos comerciales impagados + + + + 446 + + + view + Deudores de dudoso cobro + + + + 446 + + + other + Deudores de dudoso cobro + + + + + 447 + + + view + Usuarios, deudores + + + + 447 + + + other + Usuarios, deudores + + + + 448 + + + view + Patrocinadores, afiliados y otros deudores + + + + 4480 + + + view + Patrocinadores + + + + 4480 + + + other + Patrocinadores + + + + 4482 + + + view + Afiliados + + + + 4482 + + + other + Afiliados + + + + + 4489 + + + view + Otros deudores + + + + 4489 + + + other + Otros deudores + + + + + + 449 + + + view + Deudores por operaciones en común + + + + 449 + + + other + Deudores por operaciones en común + + + + 46 + + + view + Personal + + + + 460 + + + view + Anticipos de remuneraciones + + + + 460 + + + other + Anticipos de remuneraciones + + + + + 464 + + + view + Entregas para gastos a justificar + + + + 464 + + + other + Entregas para gastos a justificar + + + + + + 465 + + + view + Remuneraciones pendientes de pago + + + + 465 + + + other + Remuneraciones pendientes de pago + + + + 47 + + + view + Administraciones públicas + + + + 470 + + + view + Hacienda Pública, deudora por diversos conceptos + + + + 4700 + + + view + Hacienda Pública, deudora por IVA + + + + 4700 + + + receivable + Hacienda Pública, deudora por IVA + + + + 4707 + + + view + Hacienda Pública, deudora por colaboración en la entrega y distribución de subvenciones (art.12 Ley de Subvenciones) + + + + 4707 + + + receivable + Hacienda Pública, deudora por colaboración en la entrega y distribución de subvenciones (art.12 Ley de Subvenciones) + + + + + + 4708 + + + view + Hacienda Pública, deudora por subvenciones concedidas + + + + 4708 + + + receivable + Hacienda Pública, deudora por subvenciones concedidas + + + + 4709 + + + view + Hacienda Pública, deudora por devolución de impuestos + + + + 4709 + + + receivable + Hacienda Pública, deudora por devolución de impuestos + + + + 471 + + + view + Organismos de la Seguridad Social, deudores + + + + 471 + + + other + Organismos de la Seguridad Social, deudores + + + + 472 + + + view + Hacienda Pública, IVA soportado + + + + 472000 + + + other + Hacienda Pública. IVA soportado + + + + 473 + + + view + Hacienda Pública, retenciones y pagos a cuenta + + + + 474 + + + view + Activos por impuesto diferido + + + + 4740 + + + view + Activos por diferencias temporarias deducibles + + + + 4740 + + + other + Activos por diferencias temporarias deducibles + + + + 4742 + + + view + Derechos por deducciones y bonificaciones pendientes de aplicar + + + + 4742 + + + other + Derechos por deducciones y bonificaciones pendientes de aplicar + + + + 4745 + + + view + Crédito por pérdidas a compensar del ejercicio + + + + 4745 + + + other + Crédito por pérdidas a compensar del ejercicio + + + + 475 + + + view + Hacienda Pública, acreedora por conceptos fiscales + + + + 4750 + + + view + Hacienda Pública, acreedora por IVA + + + + 475000 + + + payable + Hacienda Pública, acreedora por IVA + + + + 4751 + + + view + Hacienda Pública, acreedora por retenciones practicadas + + + + 4751 + + + payable + Hacienda Pública, acreedora por retenciones practicadas + + + + 4752 + + + view + Hacienda Pública, acreedora por impuesto sobre sociedades + + + + 4752 + + + payable + Hacienda Pública, acreedora por impuesto sobre sociedades + + + + + 4757 + + + view + Hacienda Pública, acreedora por subvenciones recibidas en concepto de entidad colaboradora (art.12 Ley de Subvenciones) + + + + 4757 + + + payable + Hacienda Pública, acreedora por subvenciones recibidas en concepto de entidad colaboradora (art.12 Ley de Subvencioens) + + + + + 4758 + + + view + Hacienda Pública, acreedora por subvenciones a reintegrar + + + + 4758 + + + payable + Hacienda Pública, acreedora por subvenciones a reintegrar + + + + 476 + + + view + Organismos de la Seguridad Social, acreedores + + + + 476 + + + other + Organismos de la Seguridad Social, acreedores + + + + 477 + + + view + Hacienda Pública, IVA repercutido + + + + 477000 + + + other + Hacienda Pública. IVA repercutido + + + + 479 + + + view + Pasivos por diferencias temporarias imponibles + + + + 479 + + + other + Pasivos por diferencias temporarias imponibles + + + + 48 + + + view + Ajustes por periodificación + + + + 480 + + + view + Gastos anticipados + + + + 480 + + + other + Gastos anticipados + + + + 485 + + + view + Ingresos anticipados + + + + 485 + + + other + Ingresos anticipados + + + + 49 + + + view + Deterioro de valor por operaciones de la actividad y provisiones a corto plazo + + + + 490 + + + view + Deterioro de valor de créditos por operaciones de la actividad + + + + 490 + + + other + Deterioro de valor de créditos por operaciones de la actividad + + + + 493 + + + view + Deterioro de valor de créditos por operaciones comerciales con partes vinculadas + + + + 4933 + + + view + Deterioro de valor de créditos por operaciones comerciales con empresas del grupo + + + + 4933 + + + other + Deterioro de valor de créditos por operaciones comerciales con empresas del grupo + + + + 4934 + + + view + Deterioro de valor de créditos por operaciones comerciales con empresas asociadas + + + + 4934 + + + other + Deterioro de valor de créditos por operaciones comerciales con empresas asociadas + + + + 4935 + + + view + Deterioro de valor de créditos por operaciones comerciales con otras partes vinculadas + + + + 4935 + + + other + Deterioro de valor de créditos por operaciones comerciales con otras partes vinculadas + + + + 499 + + + view + Provisiones por operaciones comerciales + + + + 4994 + + + view + Provisión por contratos onerosos + + + + 4994 + + + other + Provisión por contratos onerosos + + + + 4999 + + + view + Provisión para otras operaciones comerciales + + + + 4999 + + + other + Provisión para otras operaciones comerciales + + + + 5 + + + view + Cuentas financieras + + + + 50 + + + view + Empréstitos, deudas con características especiales y otras emisiones análogas a corto plazo + + + + 500 + + + view + Obligaciones y bonos a corto plazo + + + + 500 + + + other + Obligaciones y bonos a corto plazo + + + + 502 + + + view + Acciones o participaciones a corto plazo consideradas como pasivos financieros + + + + 502 + + + other + Acciones o participaciones a corto plazo consideradas como pasivos financieros + + + + 505 + + + view + Deudas representadas en otros valores negociables a corto plazo + + + + 505 + + + other + Deudas representadas en otros valores negociables a corto plazo + + + + 506 + + + view + Intereses a corto plazo de empréstitos y otras emisiones análogas + + + + 506 + + + other + Intereses a corto plazo de empréstitos y otras emisiones análogas + + + + 507 + + + view + Dividendos de acciones o participaciones consideradas como pasivos financieros + + + + 507 + + + other + Dividendos de acciones o participaciones consideradas como pasivos financieros + + + + 509 + + + view + Valores negociables amortizados + + + + 5090 + + + view + Obligaciones y bonos amortizados + + + + 5090 + + + other + Obligaciones y bonos amortizados + + + + 5095 + + + view + Otros valores negociables amortizados + + + + 5095 + + + other + Otros valores negociables amortizados + + + + 51 + + + view + Deudas a corto plazo con partes vinculadas + + + + 510 + + + view + Deudas a corto plazo con entidades de crédito vinculadas + + + + 5103 + + + view + Deudas a corto plazo con entidades de crédito, empresas del grupo + + + + 5103 + + + other + Deudas a corto plazo con entidades de crédito, empresas del grupo + + + + 5104 + + + view + Deudas a corto plazo con entidades de crédito, empresas asociadas + + + + 5104 + + + other + Deudas a corto plazo con entidades de crédito, empresas asociadas + + + + 5105 + + + view + Deudas a corto plazo con otras entidades de crédito vinculadas + + + + 5105 + + + other + Deudas a corto plazo con otras entidades de crédito vinculadas + + + + 511 + + + view + Proveedores de inmovilizado a corto plazo, partes vinculadas + + + + 5113 + + + view + Proveedores de inmovilizado a corto plazo, empresas del grupo + + + + 5113 + + + other + Proveedores de inmovilizado a corto plazo, empresas del grupo + + + + 5114 + + + view + Proveedores de inmovilizado a corto plazo, empresas asociadas + + + + 5114 + + + other + Proveedores de inmovilizado a corto plazo, empresas asociadas + + + + 5115 + + + view + Proveedores de inmovilizado a corto plazo, otras partes vinculadas + + + + 5115 + + + other + Proveedores de inmovilizado a corto plazo, otras partes vinculadas + + + + 512 + + + view + Acreedores por arrendamiento financiero a corto plazo, partes vinculadas + + + + 5123 + + + view + Acreedores por arrendamiento financiero a corto plazo, empresas del grupo + + + + 5123 + + + other + Acreedores por arrendamiento financiero a corto plazo, empresas del grupo + + + + 5124 + + + view + Acreedores por arrendamiento financiero a corto plazo, empresas asociadas + + + + 5124 + + + other + Acreedores por arrendamiento financiero a corto plazo, empresas asociadas + + + + 5125 + + + view + Acreedores por arrendamiento financiero a corto plazo, otras partes vinculadas + + + + 5125 + + + other + Acreedores por arrendamiento financiero a corto plazo, otras partes vinculadas + + + + 513 + + + view + Otras deudas a corto plazo con partes vinculadas + + + + 5133 + + + view + Otras deudas a corto plazo con empresas del grupo + + + + 5133 + + + other + Otras deudas a corto plazo con empresas del grupo + + + + 5134 + + + view + Otras deudas a corto plazo con empresas asociadas + + + + 5134 + + + other + Otras deudas a corto plazo con empresas asociadas + + + + 5135 + + + view + Otras deudas a corto plazo con otras partes vinculadas + + + + 5135 + + + other + Otras deudas a corto plazo con otras partes vinculadas + + + + 514 + + + view + Intereses a corto plazo de deudas con partes vinculadas + + + + 5143 + + + view + Intereses a corto plazo de deudas con empresas del grupo + + + + 5143 + + + other + Intereses a corto plazo de deudas con empresas del grupo + + + + 5144 + + + view + Intereses a corto plazo de deudas con empresas asociadas + + + + 5144 + + + other + Intereses a corto plazo de deudas con empresas asociadas + + + + 5145 + + + view + Intereses a corto plazo de deudas con otras partes vinculadas + + + + 5145 + + + other + Intereses a corto plazo de deudas con otras partes vinculadas + + + + 52 + + + view + Deudas a corto plazo por préstamos recibidos y otros conceptos + + + + 520 + + + view + Deudas a corto plazo con entidades de crédito + + + + 5200 + + + view + Préstamos a corto plazo de entidades de crédito + + + + 5200 + + + other + Préstamos a corto plazo de entidades de crédito + + + + 5201 + + + view + Deudas a corto plazo por crédito dispuesto + + + + 5201 + + + other + Deudas a corto plazo por crédito dispuesto + + + + 5208 + + + view + Deudas por efectos descontados + + + + 5208 + + + other + Deudas por efectos descontados + + + + 5209 + + + view + Deudas por operaciones de “factoring” + + + + 5209 + + + other + Deudas por operaciones de “factoring” + + + + 521 + + + view + Deudas a corto plazo + + + + 521 + + + other + Deudas a corto plazo + + + + 522 + + + view + Deudas a corto plazo transformables en subvenciones, donaciones y legados + + + + 522 + + + other + Deudas a corto plazo transformables en subvenciones, donaciones y legados + + + + 523 + + + view + Proveedores de inmovilizado a corto plazo + + + + 523 + + + other + Proveedores de inmovilizado a corto plazo + + + + 524 + + + view + Acreedores por arrendamiento financiero a corto plazo + + + + 524 + + + other + Acreedores por arrendamiento financiero a corto plazo + + + + 525 + + + view + Efectos a pagar a corto plazo + + + + 525 + + + other + Efectos a pagar a corto plazo + + + + 526 + + + view + Dividendo activo a pagar + + + + 526 + + + other + Dividendo activo a pagar + + + + 527 + + + view + Intereses a corto plazo de deudas con entidades de crédito + + + + 527 + + + other + Intereses a corto plazo de deudas con entidades de crédito + + + + 528 + + + view + Intereses a corto plazo de deudas + + + + 528 + + + other + Intereses a corto plazo de deudas + + + + 529 + + + view + Provisiones a corto plazo + + + + 5290 + + + view + Provisión a corto plazo por retribuciones al personal + + + + 5290 + + + other + Provisión a corto plazo por retribuciones al personal + + + + 5291 + + + view + Provisión a corto plazo para impuestos + + + + 5291 + + + other + Provisión a corto plazo para impuestos + + + + 5292 + + + view + Provisión a corto plazo para otras responsabilidades + + + + 5292 + + + other + Provisión a corto plazo para otras responsabilidades + + + + 5293 + + + view + Provisión a corto plazo por desmantelamiento, retiro o rehabilitación del inmovilizado + + + + 5293 + + + other + Provisión a corto plazo por desmantelamiento, retiro o rehabilitación del inmovilizado + + + + 5295 + + + view + Provisión a corto plazo para actuaciones medioambientales + + + + 5295 + + + other + Provisión a corto plazo para actuaciones medioambientales + + + + 53 + + + view + Inversiones financieras a corto plazo en partes vinculadas + + + + 530 + + + view + Participaciones a corto plazo en partes vinculadas + + + + 5303 + + + view + Participaciones a corto plazo en empresas del grupo + + + + 5303 + + + other + Participaciones a corto plazo en empresas del grupo + + + + 5304 + + + view + Participaciones a corto plazo en empresas asociadas + + + + 5304 + + + other + Participaciones a corto plazo en empresas asociadas + + + + 5305 + + + view + Participaciones a corto plazo en otras partes vinculadas + + + + 5305 + + + other + Participaciones a corto plazo en otras partes vinculadas + + + + 531 + + + view + Valores representativos de deuda a corto plazo de partes vinculadas + + + + 5313 + + + view + Valores representativos de deuda a corto plazo de empresas del grupo + + + + 5313 + + + other + Valores representativos de deuda a corto plazo de empresas del grupo + + + + 5314 + + + view + Valores representativos de deuda a corto plazo de empresas asociadas + + + + 5314 + + + other + Valores representativos de deuda a corto plazo de empresas asociadas + + + + 5315 + + + view + Valores representativos de deuda a corto plazo de otras partes vinculadas + + + + 5315 + + + other + Valores representativos de deuda a corto plazo de otras partes vinculadas + + + + 532 + + + view + Créditos a corto plazo a partes vinculadas + + + + 5323 + + + view + Créditos a corto plazo a empresas del grupo + + + + 5323 + + + other + Créditos a corto plazo a empresas del grupo + + + + 5324 + + + view + Créditos a corto plazo a empresas asociadas + + + + 5324 + + + other + Créditos a corto plazo a empresas asociadas + + + + 5325 + + + view + Créditos a corto plazo a otras partes vinculadas + + + + 5325 + + + other + Créditos a corto plazo a otras partes vinculadas + + + + 533 + + + view + Intereses a corto plazo de valores representativos de deuda de partes vinculadas + + + + 5333 + + + view + Intereses a corto plazo de valores representativos de deuda de empresas del grupo + + + + 5333 + + + other + Intereses a corto plazo de valores representativos de deuda de empresas del grupo + + + + 5334 + + + view + Intereses a corto plazo de valores representativos de deuda de empresas asociadas + + + + 5334 + + + other + Intereses a corto plazo de valores representativos de deuda de empresas asociadas + + + + 5335 + + + view + Intereses a corto plazo de valores representativos de deuda de otras partes vinculadas + + + + 5335 + + + other + Intereses a corto plazo de valores representativos de deuda de otras partes vinculadas + + + + 534 + + + view + Intereses a corto plazo de créditos a partes vinculadas + + + + 5343 + + + view + Intereses a corto plazo de créditos a empresas del grupo + + + + 5343 + + + other + Intereses a corto plazo de créditos a empresas del grupo + + + + 5344 + + + view + Intereses a corto plazo de créditos a empresas asociadas + + + + 5344 + + + other + Intereses a corto plazo de créditos a empresas asociadas + + + + 5345 + + + view + Intereses a corto plazo de créditos a otras partes vinculadas + + + + 5345 + + + other + Intereses a corto plazo de créditos a otras partes vinculadas + + + + 535 + + + view + Dividendo a cobrar de inversiones financieras en partes vinculadas + + + + 5353 + + + view + Dividendo a cobrar de inversiones financieras en empresas del grupo + + + + 5353 + + + other + Dividendo a cobrar de inversiones financieras en empresas del grupo + + + + 5354 + + + view + Dividendo a cobrar de inversiones financieras en empresas asociadas + + + + 5354 + + + other + Dividendo a cobrar de inversiones financieras en empresas asociadas + + + + 5355 + + + view + Dividendo a cobrar de inversiones financieras en otras partes vinculadas + + + + 5355 + + + other + Dividendo a cobrar de inversiones financieras en otras partes vinculadas + + + + 539 + + + view + Desembolsos pendientes sobre participaciones a corto plazo en partes vinculadas + + + + 5393 + + + view + Desembolsos pendientes sobre participaciones a corto plazo en empresas del grupo + + + + 5393 + + + other + Desembolsos pendientes sobre participaciones a corto plazo en empresas del grupo + + + + 5394 + + + view + Desembolsos pendientes sobre participaciones a corto plazo en empresas asociadas + + + + 5394 + + + other + Desembolsos pendientes sobre participaciones a corto plazo en empresas asociadas + + + + 5395 + + + view + Desembolsos pendientes sobre participaciones a corto plazo en otras partes vinculadas + + + + 5395 + + + other + Desembolsos pendientes sobre participaciones a corto plazo en otras partes vinculadas + + + + 54 + + + view + Otras inversiones financieras a corto plazo + + + + 540 + + + view + Inversiones financieras a corto plazo en instrumentos de patrimonio + + + + 540 + + + other + Inversiones financieras a corto plazo en instrumentos de patrimonio + + + + 541 + + + view + Valores representativos de deuda a corto plazo + + + + 541 + + + other + Valores representativos de deuda a corto plazo + + + + 542 + + + view + Créditos a corto plazo + + + + 542 + + + other + Créditos a corto plazo + + + + 543 + + + view + Créditos a corto plazo por enajenación de inmovilizado + + + + 543 + + + other + Créditos a corto plazo por enajenación de inmovilizado + + + + 544 + + + view + Créditos a corto plazo al personal + + + + 544 + + + other + Créditos a corto plazo al personal + + + + 545 + + + view + Dividendo a cobrar + + + + 545 + + + other + Dividendo a cobrar + + + + 546 + + + view + Intereses a corto plazo de valores representativos de deudas + + + + 546 + + + other + Intereses a corto plazo de valores representativos de deudas + + + + 547 + + + view + Intereses a corto plazo de créditos + + + + 547 + + + other + Intereses a corto plazo de créditos + + + + 548 + + + view + Imposiciones a corto plazo + + + + 548 + + + other + Imposiciones a corto plazo + + + + 549 + + + view + Desembolsos pendientes sobre participaciones en el patrimonio neto a corto plazo + + + + 549 + + + other + Desembolsos pendientes sobre participaciones en el patrimonio neto a corto plazo + + + + 55 + + + view + Otras cuentas no bancarias + + + + 550 + + + view + Titular de la explotación + + + + 550 + + + other + Titular de la explotación + + + + 551 + + + view + Cuenta corriente con patronos y otros + + + + 551 + + + other + Cuenta corriente con patronos y otros + + + + 552 + + + view + Cuenta corriente con otras personas y entidades vinculadas + + + + 5523 + + + view + Cuenta corriente con empresas del grupo + + + + 5523 + + + other + Cuenta corriente con empresas del grupo + + + + 5524 + + + view + Cuenta corriente con empresas asociadas + + + + 5524 + + + other + Cuenta corriente con empresas asociadas + + + + 5525 + + + view + Cuenta corriente con otras partes vinculadas + + + + 5525 + + + other + Cuenta corriente con otras partes vinculadas + + + + 554 + + + view + Cuenta corriente con uniones temporales de empresas y comunidades de bienes + + + + 554 + + + other + Cuenta corriente con uniones temporales de empresas y comunidades de bienes + + + + 555 + + + view + Partidas pendientes de aplicación + + + + 555 + + + other + Partidas pendientes de aplicación + + + + 556 + + + view + Desembolsos exigidos sobre participaciones en el patrimonio neto + + + + 5563 + + + view + Desembolsos exigidos sobre participaciones, empresas del grupo + + + + 5563 + + + other + Desembolsos exigidos sobre participaciones, empresas del grupo + + + + 5564 + + + view + Desembolsos exigidos sobre participaciones, empresas asociadas + + + + 5564 + + + other + Desembolsos exigidos sobre participaciones, empresas asociadas + + + + 5565 + + + view + Desembolsos exigidos sobre participaciones, otras partes vinculadas + + + + 5565 + + + other + Desembolsos exigidos sobre participaciones, otras partes vinculadas + + + + 5566 + + + view + Desembolsos exigidos sobre participaciones de otras empresas + + + + 5566 + + + other + Desembolsos exigidos sobre participaciones de otras empresas + + + + 557 + + + view + Dividendo activo a cuenta + + + + 557 + + + other + Dividendo activo a cuenta + + + + 558 + + + view + Fundadores y asociados por desembolsos exigidos + + + + 5580 + + + view + Socios por desembolsos exigidos sobre acciones o participaciones ordinarias + + + + 5580 + + + other + Socios por desembolsos exigidos sobre acciones o participaciones ordinarias + + + + 5585 + + + view + Socios por desembolsos exigidos sobre acciones o participaciones consideradas como pasivos financieros + + + + 5585 + + + other + Socios por desembolsos exigidos sobre acciones o participaciones consideradas como pasivos financieros + + + + 559 + + + view + Derivados financieros a corto plazo + + + + 5590 + + + view + Activos por derivados financieros a corto plazo + + + + 5590 + + + other + Activos por derivados financieros a corto plazo + + + + 5595 + + + view + Pasivos por derivados financieros a corto plazo + + + + 5595 + + + other + Pasivos por derivados financieros a corto plazo + + + + 56 + + + view + Fianzas y depósitos recibidos y constituidos a corto plazo y ajustes por periodificación + + + + 560 + + + view + Fianzas recibidas a corto plazo + + + + 560 + + + other + Fianzas recibidas a corto plazo + + + + 561 + + + view + Depósitos recibidos a corto plazo + + + + 561 + + + other + Depósitos recibidos a corto plazo + + + + 565 + + + view + Fianzas constituidas a corto plazo + + + + 565 + + + other + Fianzas constituidas a corto plazo + + + + 566 + + + view + Depósitos constituidos a corto plazo + + + + 566 + + + other + Depósitos constituidos a corto plazo + + + + 567 + + + view + Intereses pagados por anticipado + + + + 567 + + + other + Intereses pagados por anticipado + + + + 568 + + + view + Intereses cobrados por anticipado + + + + 568 + + + other + Intereses cobrados por anticipado + + + + 57 + + + view + Tesorería + + + + 570 + + + view + Caja, euros + + + + 570 + + + liquidity + Caja, euros + + + + 571 + + + view + Caja, moneda extranjera + + + + 571 + + + liquidity + Caja, moneda extranjera + + + + 572 + + + view + Bancos e instituciones de crédito c/c vista, euros + + + + 572 + + + liquidity + Bancos e instituciones de crédito c/c vista, euros + + + + 573 + + + view + Bancos e instituciones de crédito c/c vista, moneda extranjera + + + + 573 + + + liquidity + Bancos e instituciones de crédito c/c vista, moneda extranjera + + + + 574 + + + view + Bancos e instituciones de crédito, cuentas de ahorro, euros + + + + 574 + + + liquidity + Bancos e instituciones de crédito, cuentas de ahorro, euros + + + + 575 + + + view + Bancos e instituciones de crédito, cuentas de ahorro, moneda extranjera + + + + 575 + + + liquidity + Bancos e instituciones de crédito, cuentas de ahorro, moneda extranjera + + + + 576 + + + view + Inversiones a corto plazo de gran liquidez + + + + 576 + + + liquidity + Inversiones a corto plazo de gran liquidez + + + + 59 + + + view + Deterioro del valor de inversiones financieras a corto plazo y de activos no corrientes mantenidos para la venta + + + + 593 + + + view + Deterioro de valor de participaciones a corto plazo en partes vinculadas + + + + 5933 + + + view + Deterioro de valor de participaciones a corto plazo en empresas del grupo + + + + 5933 + + + other + Deterioro de valor de participaciones a corto plazo en empresas del grupo + + + + 5934 + + + view + Deterioro de valor de participaciones a corto plazo en empresas asociadas + + + + 5934 + + + other + Deterioro de valor de participaciones a corto plazo en empresas asociadas + + + + 5935 + + + view + Deterioro de valor de participaciones a corto plazo en otras partes vinculadas + + + + 5935 + + + other + Deterioro de valor de participaciones a corto plazo en otras partes vinculadas + + + + 594 + + + view + Deterioro de valor de valores representativos de deuda a corto plazo de partes vinculadas + + + + 5943 + + + view + Deterioro de valor de valores representativos de deuda a corto plazo de empresas del grupo + + + + 5943 + + + other + Deterioro de valor de valores representativos de deuda a corto plazo de empresas del grupo + + + + 5944 + + + view + Deterioro de valor de valores representativos de deuda a corto plazo de empresas asociadas + + + + 5944 + + + other + Deterioro de valor de valores representativos de deuda a corto plazo de empresas asociadas + + + + 5945 + + + view + Deterioro de valor de valores representativos de deuda a corto plazo de otras partes vinculadas + + + + 5945 + + + other + Deterioro de valor de valores representativos de deuda a corto plazo de otras partes vinculadas + + + + 595 + + + view + Deterioro de valor de créditos a corto plazo a partes vinculadas + + + + 5953 + + + view + Deterioro de valor de créditos a corto plazo a empresas del grupo + + + + 5953 + + + other + Deterioro de valor de créditos a corto plazo a empresas del grupo + + + + 5954 + + + view + Deterioro de valor de créditos a corto plazo a empresas asociadas + + + + 5954 + + + other + Deterioro de valor de créditos a corto plazo a empresas asociadas + + + + 5955 + + + view + Deterioro de valor de créditos a corto plazo a otras partes vinculadas + + + + 5955 + + + other + Deterioro de valor de créditos a corto plazo a otras partes vinculadas + + + + 596 + + + view + Deterioro de valor de participaciones a corto plazo + + + + 596 + + + other + Deterioro de valor de participaciones a corto plazo + + + + 597 + + + view + Deterioro de valor de valores representativos de deuda a corto plazo + + + + 597 + + + other + Deterioro de valor de valores representativos de deuda a corto plazo + + + + 598 + + + view + Deterioro de valor de créditos a corto plazo + + + + 598 + + + other + Deterioro de valor de créditos a corto plazo + + + + 6 + + + view + Compras y Gastos + + + + 60 + + + view + Compras + + + + 600 + + + view + Compras de bienes destinados a la actividad + + + + 600 + + + other + Compras de bienes destinados a la actividad + + + + 601 + + + view + Compras de materias primas + + + + 601 + + + other + Compras de materias primas + + + + 602 + + + view + Compras de otros aprovisionamientos + + + + 602 + + + other + Compras de otros aprovisionamientos + + + + 606 + + + view + Descuentos sobre compras por pronto pago + + + + 6060 + + + view + Descuentos sobre compras por pronto pago de bienes destinados a la actividad + + + + 6060 + + + other + Descuentos sobre compras por pronto pago de bienes destinados a la actividad + + + + 6061 + + + view + Descuentos sobre compras por pronto pago de materias primas + + + + 6061 + + + other + Descuentos sobre compras por pronto pago de materias primas + + + + 6062 + + + view + Descuentos sobre compras por pronto pago de otros aprovisionamientos + + + + 6062 + + + other + Descuentos sobre compras por pronto pago de otros aprovisionamientos + + + + 607 + + + view + Trabajos realizados por otras empresas + + + + 607 + + + other + Trabajos realizados por otras empresas + + + + 608 + + + view + Devoluciones de compras y operaciones similares + + + + 6080 + + + view + Devoluciones de compras de bienes destinados a la actividad + + + + 6080 + + + other + Devoluciones de compras de bienes destinados a la actividad + + + + 6081 + + + view + Devoluciones de compras de materias primas + + + + 6081 + + + other + Devoluciones de compras de materias primas + + + + 6082 + + + view + Devoluciones de compras de otros aprovisionamientos + + + + 6082 + + + other + Devoluciones de compras de otros aprovisionamientos + + + + 609 + + + view + “Rappels” por compras + + + + 6090 + + + view + "Rappels" por compras de bienes destinados a la actividad + + + + 6090 + + + other + "Rappels" por compras de bienes destinados a la actividad + + + + 6091 + + + view + "Rappels" por compras de materias primas + + + + 6091 + + + other + "Rappels" por compras de materias primas + + + + 6092 + + + view + "Rappels" por compras de otros aprovisionamientos + + + + 6092 + + + other + "Rappels" por compras de otros aprovisionamientos + + + + 61 + + + view + Variación de existencias + + + + 610 + + + view + Variación de existencias de bienes destinados a la actividad + + + + 610 + + + other + Variación de existencias de mercaderías + + + + 611 + + + view + Variación de existencias de materias primas + + + + 611 + + + other + Variación de existencias de materias primas + + + + 612 + + + view + Variación de existencias de otros aprovisionamientos + + + + 612 + + + other + Variación de existencias de otros aprovisionamientos + + + + 62 + + + view + Servicios Exteriores + + + + 620 + + + view + Gastos en investigación y desarrollo del ejercicio + + + + 620 + + + other + Gastos en investigación y desarrollo del ejercicio + + + + 621 + + + view + Arrendamientos y cánones + + + + 621 + + + other + Arrendamientos y cánones + + + + 622 + + + view + Reparaciones y conservación + + + + 622 + + + other + Reparaciones y conservación + + + + 623 + + + view + Servicios de profesionales independientes + + + + 623 + + + other + Servicios de profesionales independientes + + + + 624 + + + view + Transportes + + + + 624 + + + other + Transportes + + + + 625 + + + view + Primas de seguros + + + + 625 + + + other + Primas de seguros + + + + 626 + + + view + Servicios bancarios y similares + + + + 626 + + + other + Servicios bancarios y similares + + + + 627 + + + view + Publicidad, propaganda y relaciones públicas + + + + 627 + + + other + Publicidad, propaganda y relaciones públicas + + + + 628 + + + view + Suministros + + + + 628 + + + other + Suministros + + + + 629 + + + view + Otros servicios + + + + 629 + + + other + Otros servicios + + + + 63 + + + view + Tributos + + + + 630 + + + view + Impuesto sobre beneficios + + + + 6300 + + + view + Impuesto corriente + + + + 6300 + + + other + Impuesto corriente + + + + 6301 + + + view + Impuesto diferido + + + + 6301 + + + other + Impuesto diferido + + + + 631 + + + view + Otros tributos + + + + 631 + + + other + Otros tributos + + + + 633 + + + view + Ajustes negativos en la imposición sobre beneficios + + + + 633 + + + other + Ajustes negativos en la imposición sobre beneficios + + + + 634 + + + view + Ajustes negativos en la imposición indirecta + + + + 6341 + + + view + Ajustes negativos en IVA de activo corriente + + + + 6341 + + + other + Ajustes negativos en IVA de activo corriente + + + + 6342 + + + view + Ajustes negativos en IVA de inversiones + + + + 6342 + + + other + Ajustes negativos en IVA de inversiones + + + + 636 + + + view + Devolución de impuestos + + + + 636 + + + other + Devolución de impuestos + + + + 638 + + + view + Ajustes positivos en la imposición sobre beneficios + + + + 638 + + + other + Ajustes positivos en la imposición sobre beneficios + + + + 639 + + + view + Ajustes positivos en la imposición indirecta + + + + 6391 + + + view + Ajustes positivos en IVA de activo corriente + + + + 6391 + + + other + Ajustes positivos en IVA de activo corriente + + + + 6392 + + + view + Ajustes positivos en IVA de inversiones + + + + 6392 + + + other + Ajustes positivos en IVA de inversiones + + + + 64 + + + view + Gastos de personal + + + + 640 + + + view + Sueldos y salarios + + + + 640 + + + other + Sueldos y salarios + + + + 641 + + + view + Indemnizaciones + + + + 641 + + + other + Indemnizaciones + + + + 642 + + + view + Seguridad Social a cargo de la empresa + + + + 642 + + + other + Seguridad Social a cargo de la empresa + + + + 649 + + + view + Otros gastos sociales + + + + 649 + + + other + Otros gastos sociales + + + + 65 + + + view + Ayudas monetarias de la entidad y otros gastos de gestión + + + + 650 + + + view + Ayudas monetarias + + + + + 6501 + + + view + Ayudas monetarias individuales + + + + 6501 + + + other + Ayudas monetarias individuales + + + + + 6502 + + + view + Ayudas monetarias a entidades + + + + 6502 + + + other + Ayudas monetarias a entidades + + + + + 6503 + + + view + Ayudas monetarias realizadas a través de otras entidades o centros + + + + 6503 + + + other + Ayudas monetarias realizadas a través de otras entidades o centros + + + + + 6504 + + + view + Ayudas monetarias de cooperación internacional + + + + 6504 + + + other + Ayudas monetarias de cooperación internacional + + + + + + + + 651 + + + view + Ayudas no monetarias + + + + 6510 + + + view + Beneficio transferido (gestor) + + + + 6510 + + + other + Beneficio transferido (gestor) + + + + 6511 + + + view + Ayudas no monetarias individuales + + + + 6511 + + + other + Ayudas no monetarias individuales + + + + 6512 + + + view + Ayudas no monetarias a entidades + + + + 6512 + + + other + Ayudas no monetarias a entidades + + + + + 6513 + + + view + Ayudas no monetarias realizadas a través de otras entidades o centros + + + + 6513 + + + other + Ayudas no monetarias realizadas a través de otras entidades o centros + + + + + 6514 + + + view + Ayudas no monetarias de cooperación internacional + + + + 6514 + + + other + Ayudas no monetarias de cooperación internacional + + + + + 653 + + + view + Compensación de gastos por prestaciones de colaboración + + + + 653 + + + other + Compensación de gastos por prestaciones de colaboración + + + + + 654 + + + view + Reembolsos de gastos al órgano de gobierno + + + + 654 + + + other + Reembolsos de gastos al órgano de gobierno + + + + + 655 + + + view + Pérdidas de créditos derivados de la actividad incobrables + + + + 655 + + + other + Pérdidas de créditos derivados de la actividad incobrables + + + + + + 656 + + + view + Resultados de operaciones en común + + + + 6560 + + + view + Beneficio transferido (gestor) + + + + 6560 + + + other + Beneficio transferido (gestor) + + + + + 6561 + + + view + Pérdida soportada (partícipe o asociado no gestor) + + + + 6561 + + + other + Pérdida soportada(partícipe o asociado no gestor) + + + + + 658 + + + view + Reintegro de subvenciones, donaciones y legados recibidos, afectados a la actividad propia de la entidad + + + + 658 + + + other + Reintegro de subvenciones, donaciones y legados recibidos, afectos a la actividad propia de la entidad + + + + + + 659 + + + view + Otras pérdidas en gestión corriente + + + + 659 + + + other + Otras pérdidas en gestión corriente + + + + 66 + + + view + Gastos financieros + + + + 660 + + + view + Gastos financieros por actualización de provisiones + + + + 660 + + + other + Gastos financieros por actualización de provisiones + + + + 661 + + + view + Intereses de obligaciones y bonos + + + + 6610 + + + view + Intereses de obligaciones y bonos, empresas del grupo + + + + 6610 + + + other + Intereses de obligaciones y bonos, empresas del grupo + + + + 6611 + + + view + Intereses de obligaciones y bonos, empresas asociadas + + + + 6611 + + + other + Intereses de obligaciones y bonos, empresas asociadas + + + + 6612 + + + view + Intereses de obligaciones y bonos, otras partes vinculadas + + + + 6612 + + + other + Intereses de obligaciones y bonos, otras partes vinculadas + + + + 6613 + + + view + Intereses de obligaciones y bonos, otras empresas + + + + 6613 + + + other + Intereses de obligaciones y bonos, otras empresas + + + + 6615 + + + view + Intereses de obligaciones y bonos a corto plazo, empresas del grupo + + + + 6615 + + + other + Intereses de obligaciones y bonos a corto plazo, empresas del grupo + + + + 6616 + + + view + Intereses de obligaciones y bonos a corto plazo, empresas asociadas + + + + 6616 + + + other + Intereses de obligaciones y bonos a corto plazo, empresas asociadas + + + + 6617 + + + view + Intereses de obligaciones y bonos a corto plazo, otras partes vinculadas + + + + 6617 + + + other + Intereses de obligaciones y bonos a corto plazo, otras partes vinculadas + + + + 6618 + + + view + Intereses de obligaciones y bonos a corto plazo, otras empresas + + + + 6618 + + + other + Intereses de obligaciones y bonos a corto plazo, otras empresas + + + + 662 + + + view + Ingresos de créditos a largo plazo + + + + 6620 + + + view + Ingresos de créditos a largo plazo, empresas del grupo + + + + 6620 + + + other + Ingresos de créditos a largo plazo, empresas del grupo + + + + 6621 + + + view + Ingresos de créditos a largo plazo, empresas asociadas + + + + 6621 + + + other + Ingresos de créditos a largo plazo, empresas asociadas + + + + 6622 + + + view + Ingresos de créditos a largo plazo, otras partes vinculadas + + + + 6622 + + + other + Ingresos de créditos a largo plazo, otras partes vinculadas + + + + 6623 + + + view + Ingresos de créditos a largo plazo con entidades de crédito + + + + 6623 + + + other + Ingresos de créditos a largo plazo con entidades de crédito + + + + 6624 + + + view + Ingresos de créditos a largo plazo, otras empresas + + + + 6624 + + + other + Ingresos de créditos a largo plazo, otras empresas + + + + 663 + + + view + Pérdidas por valoración de activos y pasivos financieros por su valor razonable + + + + 663 + + + other + Pérdidas por valoración de activos y pasivos financieros por su valor razonable + + + + 664 + + + view + Dividendos de acciones o participaciones consideradas como pasivos financieros + + + + 6640 + + + view + Dividendos de pasivos, empresas del grupo + + + + 6640 + + + other + Dividendos de pasivos, empresas del grupo + + + + 6641 + + + view + Dividendos de pasivos, empresas asociadas + + + + 6641 + + + other + Dividendos de pasivos, empresas asociadas + + + + 6642 + + + view + Dividendos de pasivos, otras partes vinculadas + + + + 6642 + + + other + Dividendos de pasivos, otras partes vinculadas + + + + 6643 + + + view + Dividendos de pasivos, otras empresas + + + + 6643 + + + other + Dividendos de pasivos, otras empresas + + + + 665 + + + view + Intereses por descuento de efectos y operaciones de “factoring” + + + + 6650 + + + view + Intereses por descuento de efectos en entidades de crédito del grupo + + + + 6650 + + + other + Intereses por descuento de efectos en entidades de crédito del grupo + + + + 6651 + + + view + Intereses por descuento de efectos en entidades de crédito asociadas + + + + 6651 + + + other + Intereses por descuento de efectos en entidades de crédito asociadas + + + + 6652 + + + view + Intereses por descuento de efectos en entidades de crédito vinculadas + + + + 6652 + + + other + Intereses por descuento de efectos en entidades de crédito vinculadas + + + + 6653 + + + view + Intereses por descuento de efectos en otras entidades de crédito + + + + 6653 + + + other + Intereses por descuento de efectos en otras entidades de crédito + + + + 6654 + + + view + Intereses por operaciones de "factoring" con entidades de crédito del grupo + + + + 6654 + + + other + Intereses por operaciones de "factoring" con entidades de crédito del grupo + + + + 6655 + + + view + Intereses por operaciones de "factoring" con entidades de crédito asociadas + + + + 6655 + + + other + Intereses por operaciones de "factoring" con entidades de crédito asociadas + + + + 6656 + + + view + Intereses por operaciones de "factoring" con entidades de crédito vinculadas + + + + 6656 + + + other + Intereses por operaciones de "factoring" con entidades de crédito vinculadas + + + + 6657 + + + view + Intereses por operaciones de "factoring" con otras entidades de crédito + + + + 6657 + + + other + Intereses por operaciones de "factoring" con otras entidades de crédito + + + + 666 + + + view + Pérdidas en participaciones y valores representativos de deuda + + + + 6660 + + + view + Pérdidas en valores representativos de deuda, empresas del grupo + + + + 6660 + + + other + Pérdidas en valores representativos de deuda, empresas del grupo + + + + 6661 + + + view + Pérdidas en valores representativos de deuda, empresas asociadas + + + + 6661 + + + other + Pérdidas en valores representativos de deuda, empresas asociadas + + + + 6662 + + + view + Pérdidas en valores representativos de deuda, otras partes vinculadas + + + + 6662 + + + other + Pérdidas en valores representativos de deuda, otras partes vinculadas + + + + 6663 + + + view + Pérdidas en valores representativos de deuda, otras empresas + + + + 6663 + + + other + Pérdidas en valores representativos de deuda, otras empresas + + + + 6665 + + + view + Pérdidas en valores representativos de deuda a corto plazo, empresas del grupo + + + + 6665 + + + other + Pérdidas en valores representativos de deuda a corto plazo, empresas del grupo + + + + 6666 + + + view + Pérdidas en valores representativos de deuda a corto plazo, empresas asociadas + + + + 6666 + + + other + Pérdidas en valores representativos de deuda a corto plazo, empresas asociadas + + + + 6667 + + + view + Pérdidas en valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 6667 + + + other + Pérdidas en valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 6668 + + + view + Pérdidas en valores representativos de deuda a corto plazo, otras empresas + + + + 6668 + + + other + Pérdidas en valores representativos de deuda a corto plazo, otras empresas + + + + 667 + + + view + Pérdidas de créditos no comerciales + + + + 6670 + + + view + Pérdidas de créditos, empresas del grupo + + + + 6670 + + + other + Pérdidas de créditos, empresas del grupo + + + + 6671 + + + view + Pérdidas de créditos, empresas asociadas + + + + 6671 + + + other + Pérdidas de créditos, empresas asociadas + + + + 6672 + + + view + Pérdidas de créditos, otras partes vinculadas + + + + 6672 + + + other + Pérdidas de créditos, otras partes vinculadas + + + + 6673 + + + view + Pérdidas de créditos, otras empresas + + + + 6673 + + + other + Pérdidas de créditos, otras empresas + + + + 6675 + + + view + Pérdidas de créditos a corto plazo, empresas del grupo + + + + 6675 + + + other + Pérdidas de créditos a corto plazo, empresas del grupo + + + + 6676 + + + view + Pérdidas de créditos a corto plazo, empresas asociadas + + + + 6676 + + + other + Pérdidas de créditos a corto plazo, empresas asociadas + + + + 6677 + + + view + Pérdidas de créditos a corto plazo, otras partes vinculadas + + + + 6677 + + + other + Pérdidas de créditos a corto plazo, otras partes vinculadas + + + + 6678 + + + view + Pérdidas de créditos a corto plazo, otras empresas + + + + 6678 + + + other + Pérdidas de créditos a corto plazo, otras empresas + + + + 668 + + + view + Diferencias negativas de cambio + + + + 668 + + + other + Diferencias negativas de cambio + + + + 669 + + + view + Otros gastos financieros + + + + 669 + + + other + Otros gastos financieros + + + + 67 + + + view + Pérdidas procedentes de activos no corrientes y gastos excepcionales + + + + 670 + + + view + Pérdidas procedentes del inmovilizado intangible + + + + 670 + + + other + Pérdidas procedentes del inmovilizado intangible + + + + 671 + + + view + Pérdidas procedentes del inmovilizado material y bienes del Patrimonio Histórico + + + + 671 + + + other + Pérdidas procedentes del inmovilizado material y bienes del Patrimonio Histórico + + + + 672 + + + view + Pérdidas procedentes de las inversiones inmobiliarias + + + + 672 + + + other + Pérdidas procedentes de las inversiones inmobiliarias + + + + 673 + + + view + Pérdidas procedentes de participaciones en partes vinculadas + + + + 6733 + + + view + Pérdidas procedentes de participaciones en, empresas del grupo + + + + 6733 + + + other + Pérdidas procedentes de participaciones en, empresas del grupo + + + + 6734 + + + view + Pérdidas procedentes de participaciones, empresas asociadas + + + + 6734 + + + other + Pérdidas procedentes de participaciones, empresas asociadas + + + + 6735 + + + view + Pérdidas procedentes de participaciones, otras partes vinculadas + + + + 6735 + + + other + Pérdidas procedentes de participaciones, otras partes vinculadas + + + + 675 + + + view + Pérdidas por operaciones con obligaciones propias + + + + 675 + + + other + Pérdidas por operaciones con obligaciones propias + + + + 678 + + + view + Gastos excepcionales + + + + 678 + + + other + Gastos excepcionales + + + + 68 + + + view + Dotaciones para amortizaciones + + + + 680 + + + view + Amortización del inmovilizado intangible + + + + 680 + + + other + Amortización del inmovilizado intangible + + + + 681 + + + view + Amortización del inmovilizado material + + + + 681 + + + other + Amortización del inmovilizado material + + + + 682 + + + view + Amortización de las inversiones inmobiliarias + + + + 682 + + + other + Amortización de las inversiones inmobiliarias + + + + 69 + + + view + Pérdidas por deterioro y otras dotaciones + + + + 690 + + + view + Pérdidas por deterioro del inmovilizado intangible + + + + 690 + + + other + Pérdidas por deterioro del inmovilizado intangible + + + + 691 + + + view + Pérdidas por deterioro del inmovilizado material y bienes del Patrimonio Histórico + + + + 691 + + + other + Pérdidas por deterioro del inmovilizado material y bienes del Patrimonio Histórico + + + + + 6910 + + + view + Pérdidas por deterioro del inmovilizado material + + + + + 6911 + + + view + Pérdidas por deterioro de bienes del Patrimonio Histórico + + + + 6911 + + + other + Pérdidas por deterioro bienes del Patrimonio Histórico + + + + + + + 692 + + + view + Pérdidas por deterioro de las inversiones inmobiliarias + + + + 692 + + + other + Pérdidas por deterioro de las inversiones inmobiliarias + + + + 693 + + + view + Pérdidas por deterioro de existencias + + + + 6930 + + + view + Pérdidas por deterioro de productos terminados y en curso de fabricación + + + + 6930 + + + other + Pérdidas por deterioro de productos terminados y en curso de fabricación + + + + 6931 + + + view + Pérdidas por deterioro de mercaderías + + + + 6931 + + + other + Pérdidas por deterioro de mercaderías + + + + 6932 + + + view + Pérdidas por deterioro de materias primas + + + + 6932 + + + other + Pérdidas por deterioro de materias primas + + + + 6933 + + + view + Pérdidas por deterioro de otros aprovisionamientos + + + + 6933 + + + other + Pérdidas por deterioro de otros aprovisionamientos + + + + 694 + + + view + Pérdidas por deterioro de créditos por operaciones de la actividad + + + + 694 + + + other + Pérdidas por deterioro de créditos por operaciones de la actividad + + + + 695 + + + view + Dotación a la provisión por operaciones comerciales + + + + 6954 + + + view + Dotación a la provisión por contratos onerosos + + + + 6954 + + + other + Dotación a la provisión por contratos onerosos + + + + 6959 + + + view + Dotación a la provisión para otras operaciones comerciales + + + + 6959 + + + other + Dotación a la provisión para otras operaciones comerciales + + + + 696 + + + view + Pérdidas por deterioro de participaciones y valores representativos de deuda + + + + 6960 + + + view + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, empresas del grupo + + + + 6960 + + + other + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, empresas del grupo + + + + 6961 + + + view + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, empresas asociadas + + + + 6961 + + + other + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, empresas asociadas + + + + 6962 + + + view + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, otras partes vinculadas + + + + 6962 + + + other + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, otras partes vinculadas + + + + 6963 + + + view + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, otras empresas + + + + 6963 + + + other + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto, otras empresas + + + + 6965 + + + view + Pérdidas por deterioro en valores representativos de deuda, empresas del grupo + + + + 6965 + + + other + Pérdidas por deterioro en valores representativos de deuda, empresas del grupo + + + + 6966 + + + view + Pérdidas por deterioro en valores representativos de deuda, empresas asociadas + + + + 6966 + + + other + Pérdidas por deterioro en valores representativos de deuda, empresas asociadas + + + + 6967 + + + view + Pérdidas por deterioro en valores representativos de deuda, otras partes vinculadas + + + + 6967 + + + other + Pérdidas por deterioro en valores representativos de deuda, otras partes vinculadas + + + + 6968 + + + view + Pérdidas por deterioro en valores representativos de deuda, otras empresas + + + + 6968 + + + other + Pérdidas por deterioro en valores representativos de deuda, otras empresas + + + + 697 + + + view + Pérdidas por deterioro de créditos + + + + 6970 + + + view + Pérdidas por deterioro de créditos, empresas del grupo + + + + 6970 + + + other + Pérdidas por deterioro de créditos, empresas del grupo + + + + 6971 + + + view + Pérdidas por deterioro de créditos, empresas asociadas + + + + 6971 + + + other + Pérdidas por deterioro de créditos, empresas asociadas + + + + 6972 + + + view + Pérdidas por deterioro de créditos, otras partes vinculadas + + + + 6972 + + + other + Pérdidas por deterioro de créditos, otras partes vinculadas + + + + 6973 + + + view + Pérdidas por deterioro de créditos, otras empresas + + + + 6973 + + + other + Pérdidas por deterioro de créditos, otras empresas + + + + 698 + + + view + Pérdidas por deterioro de participaciones y valores representativos de deuda a corto plazo + + + + 6980 + + + view + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas del grupo + + + + 6980 + + + other + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas del grupo + + + + 6981 + + + view + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas asociadas + + + + 6981 + + + other + Pérdidas por deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas asociadas + + + + 6985 + + + view + Pérdidas por deterioro en valores representativos de deuda a corto plazo, empresas del grupo + + + + 6985 + + + other + Pérdidas por deterioro en valores representativos de deuda a corto plazo, empresas del grupo + + + + 6986 + + + view + Pérdidas por deterioro en valores representativos de deuda a corto plazo, empresas asociadas + + + + 6986 + + + other + Pérdidas por deterioro en valores representativos de deuda a corto plazo, empresas asociadas + + + + 6987 + + + view + Pérdidas por deterioro en valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 6987 + + + other + Pérdidas por deterioro en valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 6988 + + + view + Pérdidas por deterioro en valores representativos de deuda a corto plazo, otras empresas + + + + 6988 + + + other + Pérdidas por deterioro en valores representativos de deuda a corto plazo, otras empresas + + + + 699 + + + view + Pérdidas por deterioro de créditos a corto plazo + + + + 6990 + + + view + Pérdidas por deterioro de créditos a corto plazo, empresas del grupo + + + + 6990 + + + other + Pérdidas por deterioro de créditos a corto plazo, empresas del grupo + + + + 6991 + + + view + Pérdidas por deterioro de créditos a corto plazo, empresas asociadas + + + + 6991 + + + other + Pérdidas por deterioro de créditos a corto plazo, empresas asociadas + + + + 6992 + + + view + Pérdidas por deterioro de créditos a corto plazo, otras partes vinculadas + + + + 6992 + + + other + Pérdidas por deterioro de créditos a corto plazo, otras partes vinculadas + + + + 6993 + + + view + Pérdidas por deterioro de créditos a corto plazo, otras empresas + + + + 6993 + + + other + Pérdidas por deterioro de créditos a corto plazo, otras empresas + + + + 7 + + + view + Ventas e ingresos + + + + 70 + + + view + Ventas de mercaderías, de producción propia, de servicios, etc. + + + + 700 + + + view + Ventas de mercaderías + + + + 7000 + + + view + Ventas de mercaderías en España + + + + 7000 + + + other + Ventas de mercaderías en España + + + + 7001 + + + view + Ventas de mercaderías Intracomunitarias + + + + 7001 + + + other + Ventas de mercaderías Intracomunitarias + + + + 7002 + + + view + Ventas de mercaderías Exportación + + + + 7002 + + + other + Ventas de mercaderías Exportación + + + + 701 + + + view + Ventas de productos terminados + + + + 7010 + + + view + Ventas de productos terminados en España + + + + 7010 + + + other + Ventas de productos terminados en España + + + + 7011 + + + view + Ventas de productos terminados Intracomunitarias + + + + 7011 + + + other + Ventas de productos terminados Intracomunitarias + + + + 7012 + + + view + Ventas de productos terminados Exportación + + + + 7012 + + + other + Ventas de productos terminados Exportación + + + + 702 + + + view + Ventas de productos semiterminados + + + + 7020 + + + view + Ventas de productos semiterminados en España + + + + 7020 + + + other + Ventas de productos semiterminados en España + + + + 7021 + + + view + Ventas de productos semiterminados Intracomunitarias + + + + 7021 + + + other + Ventas de productos semiterminados Intracomunitarias + + + + 7022 + + + view + Ventas de productos semiterminados Exportación + + + + 7022 + + + other + Ventas de productos semiterminados Exportación + + + + 703 + + + view + Ventas de subproductos y residuos + + + + 7030 + + + view + Ventas de subproductos y residuos en España + + + + 7030 + + + other + Ventas de subproductos y residuos en España + + + + 7031 + + + view + Ventas de subproductos y residuos Intracomunitarias + + + + 7031 + + + other + Ventas de subproductos y residuos Intracomunitarias + + + + 7032 + + + view + Ventas de subproductos y residuos Exportación + + + + 7032 + + + other + Ventas de subproductos y residuos Exportación + + + + 704 + + + view + Ventas de envases y embalajes + + + + 7040 + + + view + Ventas de envases y embalajes en España + + + + 7040 + + + other + Ventas de envases y embalajes en España + + + + 7041 + + + view + Ventas de envases y embalajes Intracomunitarias + + + + 7041 + + + other + Ventas de envases y embalajes Intracomunitarias + + + + 7042 + + + view + Ventas de envases y embalajes Exportación + + + + 7042 + + + other + Ventas de envases y embalajes Exportación + + + + 705 + + + view + Prestaciones de servicios + + + + 7050 + + + view + Prestaciones de servicios en España + + + + 7050 + + + other + Prestaciones de servicios en España + + + + 7051 + + + view + Prestaciones de servicios Intracomunitarias + + + + 7051 + + + other + Prestaciones de servicios Intracomunitarias + + + + 7052 + + + view + Prestaciones de servicios fuera de la UE + + + + 7052 + + + other + Prestaciones de servicios fuera de la UE + + + + 706 + + + view + Descuentos sobre ventas por pronto pago + + + + 7060 + + + view + Descuentos sobre ventas por pronto pago de mercaderías + + + + 7060 + + + other + Descuentos sobre ventas por pronto pago de mercaderías + + + + 7061 + + + view + Descuentos sobre ventas por pronto pago de productos terminados + + + + 7061 + + + other + Descuentos sobre ventas por pronto pago de productos terminados + + + + 7062 + + + view + Descuentos sobre ventas por pronto pago de productos semiterminados + + + + 7062 + + + other + Descuentos sobre ventas por pronto pago de productos semiterminados + + + + 7063 + + + view + Descuentos sobre ventas por pronto pago de subproductos y residuos + + + + 7063 + + + other + Descuentos sobre ventas por pronto pago de subproductos y residuos + + + + 708 + + + view + Devoluciones de ventas y operaciones similares + + + + 7080 + + + view + Devoluciones de ventas de mercaderías + + + + 7080 + + + other + Devoluciones de ventas de mercaderías + + + + 7081 + + + view + Devoluciones de ventas de productos terminados + + + + 7081 + + + other + Devoluciones de ventas de productos terminados + + + + 7082 + + + view + Devoluciones de ventas de productos semiterminados + + + + 7082 + + + other + Devoluciones de ventas de productos semiterminados + + + + 7083 + + + view + Devoluciones de ventas de subproductos y residuos + + + + 7083 + + + other + Devoluciones de ventas de subproductos y residuos + + + + 7084 + + + view + Devoluciones de ventas de envases y embalajes + + + + 7084 + + + other + Devoluciones de ventas de envases y embalajes + + + + 709 + + + view + "Rappels" sobre ventas + + + + 7090 + + + view + "Rappels" sobre ventas de mercaderías + + + + 7090 + + + other + "Rappels" sobre ventas de mercaderías + + + + 7091 + + + view + "Rappels" sobre ventas de productos terminados + + + + 7091 + + + other + "Rappels" sobre ventas de productos terminados + + + + 7092 + + + view + "Rappels" sobre ventas de productos semiterminados + + + + 7092 + + + other + "Rappels" sobre ventas de productos semiterminados + + + + 7093 + + + view + "Rappels" sobre ventas de subproductos y residuos + + + + 7093 + + + other + "Rappels" sobre ventas de subproductos y residuos + + + + 7094 + + + view + "Rappels" sobre ventas de envases y embalajes + + + + 7094 + + + other + "Rappels" sobre ventas de envases y embalajes + + + + 71 + + + view + Variación de existencias + + + + 710 + + + view + Variación de existencias de productos en curso + + + + 710 + + + other + Variación de existencias de productos en curso + + + + 711 + + + view + Variación de existencias de productos semiterminados + + + + 711 + + + other + Variación de existencias de productos semiterminados + + + + 712 + + + view + Variación de existencias de productos terminados + + + + 712 + + + other + Variación de existencias de productos terminados + + + + 713 + + + view + Variación de existencias de subproductos, residuos y materiales recuperados + + + + 713 + + + other + Variación de existencias de subproductos, residuos y materiales recuperados + + + + 72 + + + view + Ingresos propios de la entidad + + + + 720 + + + view + Cuotas de asociados y afiliados + + + + 720 + + + other + Cuotas de asociados y afiliados + + + + + 721 + + + view + Cuotas de usuarios + + + + 721 + + + other + Cuotas de usuarios + + + + + 722 + + + view + Promociones de captación de recursos + + + + 722 + + + other + Promociones de captación de recursos + + + + + 723 + + + view + Ingresos de patrocinadores y colaboraciones + + + + 7230 + + + view + Patrocinio + + + + 7230 + + + other + Patrocinio + + + + + 7231 + + + view + Patrocinio publicitario + + + + 7231 + + + other + Patrocinio publicitario + + + + + + 7233 + + + view + Colaboraciones empresariales + + + + 7233 + + + other + Colaboraciones empresariales + + + + + + + 728 + + + view + Ingresos por reintegro de ayudas y asignaciones + + + + 728 + + + other + Ingresos por reintegro de ayudas y asignaciones + + + + + + + 73 + + + view + Trabajos realizados para la empresa + + + + 730 + + + view + Trabajos realizados para el inmovilizado intangible + + + + 730 + + + other + Trabajos realizados para el inmovilizado intangible + + + + 731 + + + view + Trabajos realizados para el inmovilizado material + + + + 731 + + + other + Trabajos realizados para el inmovilizado material + + + + 732 + + + view + Trabajos realizados en inversiones inmobiliarias + + + + 732 + + + other + Trabajos realizados en inversiones inmobiliarias + + + + 733 + + + view + Trabajos realizados para el inmovilizado material en curso + + + + 733 + + + other + Trabajos realizados para el inmovilizado material en curso + + + + 74 + + + view + Subvenciones, donaciones y legados + + + + 740 + + + view + Subvenciones, donaciones y legados a la explotación + + + + 740 + + + other + Subvenciones, donaciones y legados a la explotación + + + + 746 + + + view + Subvenciones, donaciones y legados de capital transferidos al resultado del ejercicio + + + + 746 + + + other + Subvenciones, donaciones y legados de capital transferidos al resultado del ejercicio + + + + 747 + + + view + Otras subvenciones, donaciones y legados transferidos al resultado del ejercicio + + + + 747 + + + other + Otras subvenciones, donaciones y legados transferidos al resultado del ejercicio + + + + 75 + + + view + Otros ingresos de gestión + + + + 751 + + + view + Resultados de operaciones en común + + + + 7510 + + + view + Pérdida transferido (gestor) + + + + 7510 + + + other + Pérdida transferido (gestor) + + + + 7511 + + + view + Beneficio atribuido (partícipe o asociado no gestor) + + + + 7511 + + + other + Beneficio atribuido (partícipe o asociado no gestor) + + + + 752 + + + view + Ingresos por arrendamientos + + + + 752 + + + other + Ingresos por arrendamientos + + + + 753 + + + view + Ingresos de propiedad industrial cedida en explotación + + + + 753 + + + other + Ingresos de propiedad industrial cedida en explotación + + + + 754 + + + view + Ingresos por comisiones + + + + 754 + + + other + Ingresos por comisiones + + + + 755 + + + view + Ingresos por servicios al personal + + + + 755 + + + other + Ingresos por servicios al personal + + + + 759 + + + view + Ingresos por servicios diversos + + + + 759 + + + other + Ingresos por servicios diversos + + + + 76 + + + view + Ingresos financieros + + + + 760 + + + view + Ingresos de participaciones en instrumentos de patrimonio + + + + 7600 + + + view + Ingresos de participaciones en instrumentos de patrimonio, empresas del grupo + + + + 7600 + + + other + Ingresos de participaciones en instrumentos de patrimonio, empresas del grupo + + + + 7601 + + + view + Ingresos de participaciones en instrumentos de patrimonio, empresas asociadas + + + + 7601 + + + other + Ingresos de participaciones en instrumentos de patrimonio, empresas asociadas + + + + 7602 + + + view + Ingresos de participaciones en instrumentos de patrimonio, otras partes vinculadas + + + + 7602 + + + other + Ingresos de participaciones en instrumentos de patrimonio, otras partes vinculadas + + + + 7603 + + + view + Ingresos de participaciones en instrumentos de patrimonio, otras empresas + + + + 7603 + + + other + Ingresos de participaciones en instrumentos de patrimonio, otras empresas + + + + 761 + + + view + Ingresos de valores representativos de deuda + + + + 7610 + + + view + Ingresos de valores representativos de deuda, empresas del grupo + + + + 7610 + + + other + Ingresos de valores representativos de deuda, empresas del grupo + + + + 7611 + + + view + Ingresos de valores representativos de deuda, empresas asociadas + + + + 7611 + + + other + Ingresos de valores representativos de deuda, empresas asociadas + + + + 7612 + + + view + Ingresos de valores representativos de deuda, otras partes vinculadas + + + + 7612 + + + other + Ingresos de valores representativos de deuda, otras partes vinculadas + + + + 7613 + + + view + Ingresos de valores representativos de deuda, otras empresas + + + + 7613 + + + other + Ingresos de valores representativos de deuda, otras empresas + + + + 762 + + + view + Ingresos de créditos + + + + 7620 + + + view + Ingresos de créditos a largo plazo + + + + 76200 + + + view + Ingresos de créditos a largo plazo, empresas del grupo + + + + 76200 + + + other + Ingresos de créditos a largo plazo, empresas del grupo + + + + 76201 + + + view + Ingresos de créditos a largo plazo, empresas asociadas + + + + 76201 + + + other + Ingresos de créditos a largo plazo, empresas asociadas + + + + 76202 + + + view + Ingresos de créditos a largo plazo, otras partes vinculadas + + + + 76202 + + + other + Ingresos de créditos a largo plazo, otras partes vinculadas + + + + 76203 + + + view + Ingresos de créditos a largo plazo, otras empresas + + + + 76203 + + + other + Ingresos de créditos a largo plazo, otras empresas + + + + 7621 + + + view + Ingresos de créditos a corto plazo + + + + 76210 + + + view + Ingresos de créditos a corto plazo, empresas del grupo + + + + 76210 + + + other + Ingresos de créditos a corto plazo, empresas del grupo + + + + 76211 + + + view + Ingresos de créditos a corto plazo, empresas asociadas + + + + 76211 + + + other + Ingresos de créditos a corto plazo, empresas asociadas + + + + 76212 + + + view + Ingresos de créditos a corto plazo, otras partes vinculadas + + + + 76212 + + + other + Ingresos de créditos a corto plazo, otras partes vinculadas + + + + 76213 + + + view + Ingresos de créditos a corto plazo, otras empresas + + + + 76213 + + + other + Ingresos de créditos a corto plazo, otras empresas + + + + 763 + + + view + Beneficios por valoración de activos y pasivos financieros por su valor razonable + + + + 763 + + + other + Beneficios por valoración de activos y pasivos financieros por su valor razonable + + + + 766 + + + view + Beneficios en participaciones y valores representativos de deuda + + + + 7660 + + + view + Beneficios en valores representativos de deuda a largo plazo, empresas del grupo + + + + 7660 + + + other + Beneficios en valores representativos de deuda a largo plazo, empresas del grupo + + + + 7661 + + + view + Beneficios en valores representativos de deuda a largo plazo, empresas asociadas + + + + 7661 + + + other + Beneficios en valores representativos de deuda a largo plazo, empresas asociadas + + + + 7662 + + + view + Beneficios en valores representativos de deuda a largo plazo, otras partes vinculadas + + + + 7662 + + + other + Beneficios en valores representativos de deuda a largo plazo, otras partes vinculadas + + + + 7663 + + + view + Beneficios en valores representativos de deuda a largo plazo, otras empresas + + + + 7663 + + + other + Beneficios en valores representativos de deuda a largo plazo, otras empresas + + + + 7665 + + + view + Beneficios en valores representativos de deuda a corto plazo, empresas del grupo + + + + 7665 + + + other + Beneficios en valores representativos de deuda a corto plazo, empresas del grupo + + + + 7666 + + + view + Beneficios en valores representativos de deuda a corto plazo, empresas asociadas + + + + 7666 + + + other + Beneficios en valores representativos de deuda a corto plazo, empresas asociadas + + + + 7667 + + + view + Beneficios en valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 7667 + + + other + Beneficios en valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 7668 + + + view + Beneficios en valores representativos de deuda a corto plazo, otras empresas + + + + 7668 + + + other + Beneficios en valores representativos de deuda a corto plazo, otras empresas + + + + 768 + + + view + Diferencias positivas de cambio + + + + 768 + + + other + Diferencias positivas de cambio + + + + 769 + + + view + Otros ingresos financieros + + + + 769 + + + other + Otros ingresos financieros + + + + 77 + + + view + Beneficios procedentes de activos no corrientes e ingresos excepcionales + + + + 770 + + + view + Beneficios procedentes del inmovilizado intangible + + + + 770 + + + other + Beneficios procedentes del inmovilizado intangible + + + + 771 + + + view + Beneficios procedentes del inmovilizado material + + + + 771 + + + other + Beneficios procedentes del inmovilizado material + + + + 772 + + + view + Beneficios procedentes de las inversiones inmobiliarias + + + + 772 + + + other + Beneficios procedentes de las inversiones inmobiliarias + + + + 773 + + + view + Beneficios procedentes de participaciones a largo plazo en partes vinculadas + + + + 7733 + + + view + Beneficios procedentes de participaciones a largo plazo en, empresas del grupo + + + + 7733 + + + other + Beneficios procedentes de participaciones a largo plazo en, empresas del grupo + + + + 7734 + + + view + Beneficios procedentes de participaciones a largo plazo, empresas asociadas + + + + 7734 + + + other + Beneficios procedentes de participaciones a largo plazo, empresas asociadas + + + + 7735 + + + view + Beneficios procedentes de participaciones a largo plazo, otras partes vinculadas + + + + 7735 + + + other + Beneficios procedentes de participaciones a largo plazo, otras partes vinculadas + + + + 775 + + + view + Beneficos por operaciones con obligaciones propias + + + + 775 + + + other + Beneficos por operaciones con obligaciones propias + + + + 778 + + + view + Ingresos excepcionales + + + + 778 + + + other + Ingresos excepcionales + + + + 79 + + + view + Excesos y aplicaciones de provisiones y de pérdidas por deterioro + + + + 790 + + + view + Reversión del deterioro del inmovilizado intangible + + + + 790 + + + other + Reversión del deterioro del inmovilizado intangible + + + + 791 + + + view + Reversión del deterioro del inmovilizado material y de bienes del Patrimonio Histórico + + + + 791 + + + other + Reversión del deterioro del inmovilizado material y de bienes del Patrimonio Histórico + + + + 792 + + + view + Reversión del deterioro de las inversiones inmobiliarias + + + + 792 + + + other + Reversión del deterioro de las inversiones inmobiliarias + + + + 793 + + + view + Reversión del deterioro de existencias + + + + 7930 + + + view + Reversión del deterioro de productos terminados y en curso de fabricación + + + + 7930 + + + other + Reversión del deterioro de productos terminados y en curso de fabricación + + + + 7931 + + + view + Reversión del deterioro de mercaderías + + + + 7931 + + + other + Reversión del deterioro de mercaderías + + + + 7932 + + + view + Reversión del deterioro de materias primas + + + + 7932 + + + other + Reversión del deterioro de materias primas + + + + 7933 + + + view + Reversión del deterioro de otros aprovisionamientos + + + + 7933 + + + other + Reversión del deterioro de otros aprovisionamientos + + + + 794 + + + view + Reversión del deterioro de créditos por operaciones de la actividad + + + + 794 + + + other + Reversión del deterioro de créditos por operaciones de la actividad + + + + 795 + + + view + Exceso de provisiones + + + + 7951 + + + view + Exceso de provisión para impuestos + + + + 7951 + + + other + Exceso de provisión para impuestos + + + + 7952 + + + view + Exceso de provisión para otras responsabilidades + + + + 7952 + + + other + Exceso de provisión para otras responsabilidades + + + + 7954 + + + view + Exceso de provisión por operaciones comerciales + + + + 79544 + + + view + Exceso de provisión por contratos onerosos + + + + 79544 + + + other + Exceso de provisión por contratos onerosos + + + + 79549 + + + view + Exceso de provisión para otras operaciones comerciales + + + + 79549 + + + other + Exceso de provisión para otras operaciones comerciales + + + + 7955 + + + view + Exceso de provisión para actuaciones medioambientales + + + + 7955 + + + other + Exceso de provisión para actuaciones medioambientales + + + + 796 + + + view + Reversión del deterioro de participaciones y valores representativos de deuda a largo plazo + + + + 7960 + + + view + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, empresas del grupo + + + + 7960 + + + other + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, empresas del grupo + + + + 7961 + + + view + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, empresas asociadas + + + + 7961 + + + other + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, empresas asociadas + + + + 7962 + + + view + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, otras partes vinculadas + + + + 7962 + + + other + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, otras partes vinculadas + + + + 7963 + + + view + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, otras empresas + + + + 7963 + + + other + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a largo plazo, otras empresas + + + + 7965 + + + view + Reversión del deterioro de valores representativos de deuda a largo plazo, empresas del grupo + + + + 7965 + + + other + Reversión del deterioro de valores representativos de deuda a largo plazo, empresas del grupo + + + + 7966 + + + view + Reversión del deterioro de valores representativos de deuda a largo plazo, empresas asociadas + + + + 7966 + + + other + Reversión del deterioro de valores representativos de deuda a largo plazo, empresas asociadas + + + + 7967 + + + view + Reversión del deterioro de valores representativos de deuda a largo plazo, otras partes vinculadas + + + + 7967 + + + other + Reversión del deterioro de valores representativos de deuda a largo plazo, otras partes vinculadas + + + + 7968 + + + view + Reversión del deterioro de valores representativos de deuda a largo plazo, otras empresas + + + + 7968 + + + other + Reversión del deterioro de valores representativos de deuda a largo plazo, otras empresas + + + + 797 + + + view + Reversión del deterioro de créditos a largo plazo + + + + 7970 + + + view + Reversión del deterioro de créditos a largo plazo, empresas del grupo + + + + 7970 + + + other + Reversión del deterioro de créditos a largo plazo, empresas del grupo + + + + 7971 + + + view + Reversión del deterioro de créditos a largo plazo, empresas asociadas + + + + 7971 + + + other + Reversión del deterioro de créditos a largo plazo, empresas asociadas + + + + 7972 + + + view + Reversión del deterioro de créditos a largo plazo, otras partes vinculadas + + + + 7972 + + + other + Reversión del deterioro de créditos a largo plazo, otras partes vinculadas + + + + 7973 + + + view + Reversión del deterioro de créditos a largo plazo, otras empresas + + + + 7973 + + + other + Reversión del deterioro de créditos a largo plazo, otras empresas + + + + 798 + + + view + Reversión del deterioro de participaciones y valores representativos de deuda a corto plazo + + + + 7980 + + + view + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas del grupo + + + + 7980 + + + other + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas del grupo + + + + 7981 + + + view + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas asociadas + + + + 7981 + + + other + Reversión del deterioro de participaciones en instrumentos de patrimonio neto a corto plazo, empresas asociadas + + + + 7985 + + + view + Reversión del deterioro de valores representativos de deuda a corto plazo, empresas del grupo + + + + 7985 + + + other + Reversión del deterioro de valores representativos de deuda a corto plazo, empresas del grupo + + + + 7986 + + + view + Reversión del deterioro de valores representativos de deuda a corto plazo, empresas asociadas + + + + 7986 + + + other + Reversión del deterioro de valores representativos de deuda a corto plazo, empresas asociadas + + + + 7987 + + + view + Reversión del deterioro de valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 7987 + + + other + Reversión del deterioro de valores representativos de deuda a corto plazo, otras partes vinculadas + + + + 7988 + + + view + Reversión del deterioro de valores representativos de deuda a corto plazo, otras empresas + + + + 7988 + + + other + Reversión del deterioro de valores representativos de deuda a corto plazo, otras empresas + + + + 799 + + + view + Reversión del deterioro de créditos a corto plazo + + + + 7990 + + + view + Reversión del deterioro de créditos a corto plazo, empresas del grupo + + + + 7990 + + + other + Reversión del deterioro de créditos a corto plazo, empresas del grupo + + + + 7991 + + + view + Reversión del deterioro de créditos a corto plazo, empresas asociadas + + + + 7991 + + + other + Reversión del deterioro de créditos a corto plazo, empresas asociadas + + + + 7992 + + + view + Reversión del deterioro de créditos a corto plazo, otras partes vinculadas + + + + 7992 + + + other + Reversión del deterioro de créditos a corto plazo, otras partes vinculadas + + + + 7993 + + + view + Reversión del deterioro de créditos a corto plazo, otras empresas + + + + 7993 + + + other + Reversión del deterioro de créditos a corto plazo, otras empresas + + + + + + + Plantilla Plan de Impuestos ASSOC + + + + + + Plantilla PGCE Asociaciones 2008 + + + + + + + + + + + diff --git a/addons/l10n_es/account_chart_pymes.xml b/addons/l10n_es/account_chart_pymes.xml index ed2e4f18e7c..223d80e3193 100644 --- a/addons/l10n_es/account_chart_pymes.xml +++ b/addons/l10n_es/account_chart_pymes.xml @@ -1,6 +1,6 @@ - + + Jordi Esteve (Zikzakmedia) - jesteve@zikzakmedia.com 2010-02-18 + + Añadido mapeo de cuentas del regimen de equivalencia para compras : + Ignacio Ibeas (Acysos) - ignacio@acysos.com 2011-02-22 --> + + - Régimen Nacional @@ -32,6 +36,16 @@ + + Retención IRPF 21% + + + + + Retención IRPF 20% + + + Retención IRPF 19% @@ -47,6 +61,11 @@ + + Retención IRPF 9% + + + Retención IRPF 7% @@ -68,6 +87,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -78,7 +145,7 @@ - + @@ -90,35 +157,15 @@ - + - - + + - + - - - - - - - - - - - - - - - - - - - - - - + + @@ -138,6 +185,12 @@ + + + + + + @@ -148,29 +201,24 @@ + + + + + - + - - + + - + + - - - - - - - - - - - - - + + @@ -178,30 +226,71 @@ + + + - + + - - + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -215,27 +304,87 @@ - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -260,42 +409,188 @@ - + - - + + - + - - - - - - - - + + - - - - + + + + - - - - + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -372,7 +667,310 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -386,18 +984,6 @@ - - - - - - - - - - - - @@ -410,6 +996,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -434,6 +1044,18 @@ + + + + + + + + + + + + @@ -446,18 +1068,6 @@ - - - - - - - - - - - - @@ -470,6 +1080,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -495,6 +1129,18 @@ + + + + + + + + + + + + @@ -508,6 +1154,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -520,18 +1190,6 @@ - - - - - - - - - - - - @@ -556,6 +1214,18 @@ + + + + + + + + + + + + @@ -568,6 +1238,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -580,18 +1274,6 @@ - - - - - - - - - - - - @@ -616,7 +1298,19 @@ - + + + + + + + + + + + + + @@ -630,18 +1324,6 @@ - - - - - - - - - - - - @@ -654,6 +1336,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -678,6 +1384,18 @@ + + + + + + + + + + + + @@ -690,18 +1408,6 @@ - - - - - - - - - - - - @@ -714,6 +1420,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -738,7 +1468,142 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -752,18 +1617,6 @@ - - - - - - - - - - - - @@ -776,6 +1629,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -800,6 +1677,18 @@ + + + + + + + + + + + + @@ -812,6 +1701,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -824,18 +1737,6 @@ - - - - - - - - - - - - @@ -862,6 +1763,18 @@ + + + + + + + + + + + + @@ -874,18 +1787,6 @@ - - - - - - - - - - - - @@ -898,6 +1799,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -922,6 +1847,18 @@ + + + + + + + + + + + + @@ -934,18 +1871,6 @@ - - - - - - - - - - - - @@ -958,6 +1883,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -984,6 +1933,19 @@ + + + + + + + + + + + + + @@ -996,18 +1958,6 @@ - - - - - - - - - - - - @@ -1020,6 +1970,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -1044,6 +2018,18 @@ + + + + + + + + + + + + @@ -1056,18 +2042,6 @@ - - - - - - - - - - - - @@ -1080,6 +2054,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -1104,5 +2102,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/l10n_es/fiscal_templates_assoc.xml b/addons/l10n_es/fiscal_templates_assoc.xml new file mode 100644 index 00000000000..42c7ab464ee --- /dev/null +++ b/addons/l10n_es/fiscal_templates_assoc.xml @@ -0,0 +1,2047 @@ + + + + + + + + Régimen Nacional + + + + + Recargo de Equivalencia + + + + + Régimen Extracomunitario + + + + + Régimen Intracomunitario + + + + + Retención IRPF 21% + + + + + Retención IRPF 20% + + + + + Retención IRPF 19% + + + + + Retención IRPF 18% + + + + + Retención IRPF 15% + + + + + Retención IRPF 9% + + + + + Retención IRPF 7% + + + + + Retención IRPF 2% + + + + + Retención IRPF 1% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/l10n_es/fiscal_templates_pymes.xml b/addons/l10n_es/fiscal_templates_pymes.xml index 05871fad842..2e84e63bc34 100644 --- a/addons/l10n_es/fiscal_templates_pymes.xml +++ b/addons/l10n_es/fiscal_templates_pymes.xml @@ -1,10 +1,10 @@ - + + Añadidas posiciones fiscales Retención de IRPF 19%, 2% : + Jordi Esteve (Zikzakmedia) - jesteve@zikzakmedia.com 2010-02-18 + + Añadido mapeo de cuentas del regimen de equivalencia para compras y ventas separados: + Ignacio Ibeas (Acysos) - ignacio@acysos.com 2011-05-06 --> + + - Régimen Nacional @@ -59,6 +63,16 @@ + + Retención IRPF 21% + + + + + Retención IRPF 20% + + + Retención IRPF 19% @@ -74,6 +88,11 @@ + + Retención IRPF 9% + + + Retención IRPF 7% @@ -94,26 +113,16 @@ + + + + + - + - - - - - - - - - - - - - - - - - + + @@ -121,30 +130,69 @@ + + + - + + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -164,6 +212,12 @@ + + + + + + @@ -175,8 +229,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -198,35 +306,15 @@ - + - - + + - + - - - - - - - - - - - - - - - - - - - - - - + + @@ -246,6 +334,12 @@ + + + + + + @@ -257,30 +351,24 @@ + + + + + + - + - - + + - + - - - - - - - - - - - - - - + + @@ -294,7 +382,7 @@ - + @@ -307,16 +395,220 @@ - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -395,9 +687,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -410,18 +1005,6 @@ - - - - - - - - - - - - @@ -434,6 +1017,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -458,6 +1065,18 @@ + + + + + + + + + + + + @@ -470,6 +1089,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -482,18 +1125,6 @@ - - - - - - - - - - - - @@ -520,6 +1151,18 @@ + + + + + + + + + + + + @@ -532,18 +1175,6 @@ - - - - - - - - - - - - @@ -556,6 +1187,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -580,6 +1235,18 @@ + + + + + + + + + + + + @@ -592,18 +1259,6 @@ - - - - - - - - - - - - @@ -616,6 +1271,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -642,6 +1321,18 @@ + + + + + + + + + + + + @@ -654,18 +1345,6 @@ - - - - - - - - - - - - @@ -678,6 +1357,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -702,6 +1405,18 @@ + + + + + + + + + + + + @@ -714,18 +1429,6 @@ - - - - - - - - - - - - @@ -738,6 +1441,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -762,8 +1489,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -776,18 +1637,6 @@ - - - - - - - - - - - - @@ -800,6 +1649,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -824,6 +1697,18 @@ + + + + + + + + + + + + @@ -836,6 +1721,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -848,17 +1757,6 @@ - - - - - - - - - - - @@ -886,6 +1784,18 @@ + + + + + + + + + + + + @@ -898,18 +1808,6 @@ - - - - - - - - - - - - @@ -922,6 +1820,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -946,6 +1868,18 @@ + + + + + + + + + + + + @@ -958,18 +1892,6 @@ - - - - - - - - - - - - @@ -982,6 +1904,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -1008,6 +1954,18 @@ + + + + + + + + + + + + @@ -1020,18 +1978,6 @@ - - - - - - - - - - - - @@ -1044,6 +1990,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -1068,6 +2038,18 @@ + + + + + + + + + + + + @@ -1080,6 +2062,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -1092,18 +2098,6 @@ - - - - - - - - - - - - @@ -1128,5 +2122,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/l10n_es/taxes_data.xml b/addons/l10n_es/taxes_data.xml index 41b52ee077d..586358ffc70 100644 --- a/addons/l10n_es/taxes_data.xml +++ b/addons/l10n_es/taxes_data.xml @@ -1,25 +1,37 @@ - - - + + - + + Ignacio Ibeas (Acysos) - ignacio@acysos.com (2011-02-22) + Modificado type_tax_use de los recargos de equivalencia a "all" + + Jordi Esteve (Zikzakmedia) - jesteve@zikzakmedia.com (2011-08-29) + Cambiado Recargos de equivalencia de "all" a "venta" (ya existen los de compra). Ahora quedan definidos de la misma forma que en taxes_data_pymes.xml + + Pedro M. Baeza (Serv. Tecnol. Avanzados) - pedro.baeza@serviciosbaeza.com (2013-01-29) + Limpieza de subcuentas de impuestos y corrección de inversión de sujeto pasivo + + --> + + - - + + - + @@ -28,46 +40,102 @@ 1.0 - - - + + + + Base adquisiciones exentas + + -- + 1.0 + + + + Base ventas exentas + -- + + 1.0 + + + + + + IVA Soportado exento (operaciones corrientes) + + percent + + + + + + + purchase + + + + + + IVA Exento + + percent + + + + + + + sale + + - + Régimen general IVA Devengado. Base Imponible 4% [01] 1.0 - + Régimen general IVA Devengado. Base Imponible 7% [04] 1.0 - + Régimen general IVA Devengado. Base Imponible 8% [04] 1.0 - + + + Régimen general IVA Devengado. Base Imponible 10% + [04] + + 1.0 + + Régimen general IVA Devengado. Base Imponible 16% [07] 1.0 - + Régimen general IVA Devengado. Base Imponible 18% [07] 1.0 - + + Régimen general IVA Devengado. Base Imponible 21% + [07] + + 1.0 + + - + Recargo Equivalencia Base Imponible 0.5% [10] 1.0 - + Recargo Equivalencia Base Imponible 1% [13] 1.0 - + + + Recargo Equivalencia Base Imponible 1.4% + [13] + + 1.0 + + Recargo Equivalencia Base Imponible 4% [16] 1.0 - - + + + Recargo Equivalencia Base Imponible 5.2% + [16] + + 1.0 + + - + Adquisiciones intracomunitarias. Base Imponible [19] 1.0 - + - - + + - - + + IVA Cuota total devengada [21] 1.0 - + Régimen general IVA Devengado. Cuota 4% [03] 1.0 - + Régimen general IVA Devengado. Cuota 7% [06] 1.0 - + Régimen general IVA Devengado. Cuota 8% [06] 1.0 - + + + Régimen general IVA Devengado. Cuota 10% + [06] + + 1.0 + + Régimen general IVA Devengado. Cuota 16% [09] @@ -155,7 +243,14 @@ 1.0 - + + + Régimen general IVA Devengado. Cuota 21% + [09] + + 1.0 + + - + Recargo Equivalencia. Cuota 0.5% [12] 1.0 - + Recargo Equivalencia. Cuota 1% [15] 1.0 - + + + Recargo Equivalencia. Cuota 1.4% + [15] + + 1.0 + + Recargo Equivalencia. Cuota 4% [18] 1.0 - - + + + Recargo Equivalencia. Cuota 5.2% + [18] + + 1.0 + + + - + Adquisiciones intracomunitarias. Cuota [20] 1.0 - - - - - + + + + + - - + + @@ -212,7 +321,7 @@ 1.0 - + Base operaciones interiores corrientes @@ -220,19 +329,12 @@ 1.0 - - Base operaciones interiores corrientes (16%) + + Base operaciones interiores corrientes (4%) -- 1.0 - - Base operaciones interiores corrientes (18%) - -- - - 1.0 - - Base operaciones interiores corrientes (7%) -- @@ -245,13 +347,30 @@ 1.0 - - Base operaciones interiores corrientes (4%) + + Base operaciones interiores corrientes (10%) + -- + + 1.0 + + + Base operaciones interiores corrientes (16%) + -- + + 1.0 + + + Base operaciones interiores corrientes (18%) + -- + + 1.0 + + + Base operaciones interiores corrientes (21%) -- 1.0 - Base operaciones interiores bienes inversión @@ -259,19 +378,12 @@ 1.0 - - Base operaciones interiores bienes inversión (16%) + + Base operaciones interiores bienes inversión (4%) -- 1.0 - - Base operaciones interiores bienes inversión (18%) - -- - - 1.0 - - Base operaciones interiores bienes inversión (7%) -- @@ -284,14 +396,31 @@ 1.0 - - Base operaciones interiores bienes inversión (4%) + + Base operaciones interiores bienes inversión (10%) -- 1.0 - - + + Base operaciones interiores bienes inversión (16%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (18%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (21%) + -- + + 1.0 + + Base importaciones bienes corrientes @@ -299,6 +428,30 @@ 1.0 + + Base importaciones bienes corrientes (4%) + -- + + 1.0 + + + Base importaciones bienes corrientes (7%) + -- + + 1.0 + + + Base importaciones bienes corrientes (8%) + -- + + 1.0 + + + Base importaciones bienes corrientes (10%) + -- + + 1.0 + Base importaciones bienes corrientes (16%) -- @@ -311,26 +464,13 @@ 1.0 - - - Base importaciones bienes corrientes (7%) + + Base importaciones bienes corrientes (21%) -- 1.0 - - Base importaciones bienes corrientes (8%) - -- - - 1.0 - - - Base importaciones bienes corrientes (4%) - -- - - 1.0 - - + Base importaciones bienes inversión @@ -338,19 +478,12 @@ 1.0 - - Base importaciones bienes inversión (16%) + + Base importaciones bienes inversión (4%) -- 1.0 - - Base importaciones bienes inversión (18%) - -- - - 1.0 - - Base importaciones bienes inversión (7%) -- @@ -363,13 +496,31 @@ 1.0 - - Base importaciones bienes inversión (4%) + + Base importaciones bienes inversión (10%) -- 1.0 - + + Base importaciones bienes inversión (16%) + -- + + 1.0 + + + Base importaciones bienes inversión (18%) + -- + + 1.0 + + + Base importaciones bienes inversión (21%) + -- + + 1.0 + + Base adquisiciones intracomunitarias bienes corrientes @@ -377,6 +528,30 @@ 1.0 + + Base adquisiciones intracomunitarias bienes corrientes (4%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (7%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (8%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (10%) + -- + + 1.0 + Base adquisiciones intracomunitarias bienes corrientes (16%) -- @@ -389,26 +564,13 @@ 1.0 - - - Base adquisiciones intracomunitarias bienes corrientes (7%) + + Base adquisiciones intracomunitarias bienes corrientes (21%) -- 1.0 - - Base adquisiciones intracomunitarias bienes corrientes (8%) - -- - - 1.0 - - - Base adquisiciones intracomunitarias bienes corrientes (4%) - -- - - 1.0 - - + Base adquisiciones intracomunitarias bienes inversión @@ -416,19 +578,12 @@ 1.0 - - Base adquisiciones intracomunitarias bienes inversión (16%) + + Base adquisiciones intracomunitarias bienes inversión (4%) -- 1.0 - - Base adquisiciones intracomunitarias bienes inversión (18%) - -- - - 1.0 - - Base adquisiciones intracomunitarias bienes inversión (7%) -- @@ -441,18 +596,71 @@ 1.0 - - Base adquisiciones intracomunitarias bienes inversión (4%) + + Base adquisiciones intracomunitarias bienes inversión (10%) -- 1.0 - - - + + Base adquisiciones intracomunitarias bienes inversión (16%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (18%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (21%) + -- + + 1.0 + + + + + Recargo Equivalencia Ded. Base Imponible 0.5% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 1% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 1.4% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 4% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 5.2% + -- + + 1.0 + + + - + IVA deducible (Cuota)- Total a deducir [Mod.303] [37] @@ -467,19 +675,12 @@ 1.0 - - Cuotas soportadas operaciones interiores corrientes (16%) + + Cuotas soportadas operaciones interiores corrientes (4%) -- 1.0 - - Cuotas soportadas operaciones interiores corrientes (18%) - -- - - 1.0 - - Cuotas soportadas operaciones interiores corrientes (7%) -- @@ -492,13 +693,31 @@ 1.0 - - Cuotas soportadas operaciones interiores corrientes (4%) + + Cuotas soportadas operaciones interiores corrientes (10%) -- 1.0 - + + Cuotas soportadas operaciones interiores corrientes (16%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (18%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (21%) + -- + + 1.0 + + Cuotas soportadas operaciones interiores bienes inversión @@ -506,19 +725,12 @@ 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (16%) + + Cuotas soportadas operaciones interiores bienes inversión (4%) -- 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (18%) - -- - - 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (7%) -- @@ -531,13 +743,31 @@ 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (4%) + + Cuotas soportadas operaciones interiores bienes inversión (10%) -- 1.0 - + + Cuotas soportadas operaciones interiores bienes inversión (16%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (18%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (21%) + -- + + 1.0 + + Cuotas devengadas importaciones bienes corrientes @@ -545,19 +775,12 @@ 1.0 - - Cuotas devengadas importaciones bienes corrientes (16%) + + Cuotas devengadas importaciones bienes corrientes (4%) -- 1.0 - - Cuotas devengadas importaciones bienes corrientes (18%) - -- - - 1.0 - - Cuotas devengadas importaciones bienes corrientes (7%) -- @@ -570,13 +793,31 @@ 1.0 - - Cuotas devengadas importaciones bienes corrientes (4%) + + Cuotas devengadas importaciones bienes corrientes (10%) -- 1.0 - + + Cuotas devengadas importaciones bienes corrientes (16%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (18%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (21%) + -- + + 1.0 + + Cuotas devengadas importaciones bienes inversión @@ -584,19 +825,12 @@ 1.0 - - Cuotas devengadas importaciones bienes inversión (16%) + + Cuotas devengadas importaciones bienes inversión (4%) -- 1.0 - - Cuotas devengadas importaciones bienes inversión (18%) - -- - - 1.0 - - Cuotas devengadas importaciones bienes inversión (7%) -- @@ -609,13 +843,30 @@ 1.0 - - Cuotas devengadas importaciones bienes inversión (4%) + + Cuotas devengadas importaciones bienes inversión (10%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (16%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (18%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (21%) -- 1.0 - En adquisiciones intracomunitarias bienes corrientes @@ -623,6 +874,30 @@ 1.0 + + En adquisiciones intracomunitarias bienes corrientes (4%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (7%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (8%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (10%) + -- + + 1.0 + En adquisiciones intracomunitarias bienes corrientes (16%) -- @@ -635,26 +910,12 @@ 1.0 - - - En adquisiciones intracomunitarias bienes corrientes (7%) + + En adquisiciones intracomunitarias bienes corrientes (21%) -- 1.0 - - En adquisiciones intracomunitarias bienes corrientes (8%) - -- - - 1.0 - - - En adquisiciones intracomunitarias bienes corrientes (4%) - -- - - 1.0 - - En adquisiciones intracomunitarias bienes inversión @@ -662,19 +923,12 @@ 1.0 - - En adquisiciones intracomunitarias bienes inversión (16%) + + En adquisiciones intracomunitarias bienes inversión (4%) -- 1.0 - - En adquisiciones intracomunitarias bienes inversión (18%) - -- - - 1.0 - - En adquisiciones intracomunitarias bienes inversión (7%) -- @@ -687,8 +941,26 @@ 1.0 - - En adquisiciones intracomunitarias bienes inversión (4%) + + En adquisiciones intracomunitarias bienes inversión (10%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (16%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (18%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (21%) -- 1.0 @@ -716,110 +988,42 @@ 1.0 - - - - - - 472004 - - - other - Hacienda Pública. IVA soportado 4% - - - - - 472007 - - - other - Hacienda Pública. IVA soportado 7% - - - - - 472008 - - - other - Hacienda Pública. IVA soportado 8% - - - - - 472016 - - - other - Hacienda Pública. IVA soportado 16% - - - - - 472018 - - - other - Hacienda Pública. IVA soportado 18% - - - - - 477004 - - - other - Hacienda Pública. IVA repercutido 4% - - - - - 477007 - - - other - Hacienda Pública. IVA repercutido 7% - - - - - 477008 - - - other - Hacienda Pública. IVA repercutido 8% - - - - - 477016 - - - other - Hacienda Pública. IVA repercutido 16% - + + + Recargo Equivalencia Ded. Cuota 0.5% + [12] + + 1.0 - - 477018 - - - other - Hacienda Pública. IVA repercutido 18% - + + Recargo Equivalencia Ded. Cuota 1% + [15] + + 1.0 - - - 475001 - - - payable - Hacienda acreedora IVA - + + + Recargo Equivalencia Ded. Cuota 1.4% + [15] + + 1.0 - - + + + Recargo Equivalencia Ded. Cuota 4% + [18] + + 1.0 + + + + Recargo Equivalencia Ded. Cuota 5.2% + [18] + + 1.0 + + @@ -831,8 +1035,8 @@ 4% IVA Soportado (operaciones corrientes) percent - - + + @@ -843,14 +1047,14 @@ purchase - + 4% IVA Soportado (bienes de inversión) percent - - + + @@ -861,14 +1065,14 @@ purchase - + 7% IVA Soportado (operaciones corrientes) percent - - + + @@ -879,14 +1083,14 @@ purchase - + 7% IVA Soportado (bienes de inversión) percent - - + + @@ -897,14 +1101,14 @@ purchase - + 8% IVA Soportado (operaciones corrientes) percent - - + + @@ -915,14 +1119,14 @@ purchase - + 8% IVA Soportado (bienes de inversión) percent - - + + @@ -933,14 +1137,50 @@ purchase - + + + + 10% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 10% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + 16% IVA Soportado (operaciones corrientes) percent - - + + @@ -951,14 +1191,14 @@ purchase - + 16% IVA Soportado (bienes de inversión) percent - - + + @@ -969,14 +1209,14 @@ purchase - + 18% IVA Soportado (operaciones corrientes) percent - - + + @@ -986,15 +1226,16 @@ purchase + - + 18% IVA Soportado (bienes de inversión) percent - - + + @@ -1005,7 +1246,44 @@ purchase - + + + + 21% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + + 21% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + @@ -1036,15 +1314,15 @@ purchase - + IVA 4% Importaciones bienes corrientes IVA 4% Importaciones bienes corrientes percent - - + + @@ -1061,8 +1339,8 @@ IVA 4% Importaciones bienes de inversión percent - - + + @@ -1073,15 +1351,15 @@ purchase - + IVA 7% Importaciones bienes corrientes IVA 7% Importaciones bienes corrientes percent - - + + @@ -1098,8 +1376,8 @@ IVA 7% Importaciones bienes de inversión percent - - + + @@ -1110,15 +1388,15 @@ purchase - + IVA 8% Importaciones bienes corrientes IVA 8% Importaciones bienes corrientes percent - - + + @@ -1135,8 +1413,8 @@ IVA 8% Importaciones bienes de inversión percent - - + + @@ -1147,15 +1425,53 @@ purchase - + + + + IVA 10% Importaciones bienes corrientes + IVA 10% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 10% Importaciones bienes de inversión + IVA 10% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + IVA 16% Importaciones bienes corrientes IVA 16% Importaciones bienes corrientes percent - - + + @@ -1172,8 +1488,8 @@ IVA 16% Importaciones bienes de inversión percent - - + + @@ -1184,15 +1500,15 @@ purchase - + IVA 18% Importaciones bienes corrientes IVA 18% Importaciones bienes corrientes percent - - + + @@ -1209,8 +1525,8 @@ IVA 18% Importaciones bienes de inversión percent - - + + @@ -1221,7 +1537,44 @@ purchase - + + + + IVA 21% Importaciones bienes corrientes + IVA 21% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 21% Importaciones bienes de inversión + IVA 21% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + @@ -1269,16 +1622,16 @@ percent - - + + - + - + purchase @@ -1287,8 +1640,8 @@ percent - - + + @@ -1299,7 +1652,7 @@ purchase - + IVA 18% Inversión del sujeto pasivo @@ -1333,16 +1686,16 @@ percent - - + + - + - + purchase @@ -1351,8 +1704,8 @@ percent - - + + @@ -1363,16 +1716,81 @@ purchase - - + + + + + IVA 21% Inversión del sujeto pasivo + IVA 21% Inversión del sujeto pasivo + + percent + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (1) + + + percent + + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (2) + + + percent + + + + + + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (3) + + + percent + + + + + + + + + + + purchase + + + IVA 4% percent - - + + @@ -1383,14 +1801,14 @@ sale - + IVA 7% percent - - + + @@ -1401,14 +1819,14 @@ sale - + IVA 8% percent - - + + @@ -1419,14 +1837,32 @@ sale - + + + + IVA 10% + + percent + + + + + + + + + + + sale + + IVA 16% percent - - + + @@ -1437,14 +1873,14 @@ sale - + IVA 18% percent - - + + @@ -1454,17 +1890,37 @@ sale + - - + + + + IVA 21% + + percent + + + + + + + + + + + sale + + + + - 0.50% Recargo Equivalencia + 0.50% Recargo Equivalencia Ventas percent - - + + @@ -1475,14 +1931,14 @@ sale - + - 1% Recargo Equivalencia + 1% Recargo Equivalencia Ventas percent - - + + @@ -1493,14 +1949,32 @@ sale - + + + + 1.4% Recargo Equivalencia Ventas + + percent + + + + + + + + + + + sale + + - 4% Recargo Equivalencia + 4% Recargo Equivalencia Ventas percent - - + + @@ -1511,10 +1985,118 @@ sale - - + + + + 5.2% Recargo Equivalencia Ventas + + percent + + + + + + + + + + + sale + + + + + 0.50% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 1% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 1.4% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 4% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 5.2% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + - + @@ -1528,366 +2110,11 @@ sale - - + + - - - IVA 16% Intracomunitario. Bienes corrientes - IVA 16% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 16% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 16% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes corrientes - IVA 18% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 18% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - - purchase - - - - - - IVA 16% Intracomunitario. Bienes de inversión - IVA 16% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 16% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 16% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - - IVA 18% Intracomunitario. Bienes de inversión - IVA 18% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 18% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes corrientes - IVA 7% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 7% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes de inversión - IVA 7% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 7% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes corrientes - IVA 8% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 8% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes de inversión - IVA 8% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 8% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - + IVA 4% Intracomunitario. Bienes corrientes IVA 4% Intracomunitario. Bienes corrientes @@ -1902,8 +2129,8 @@ IVA 4% Intracomunitario. Bienes corrientes (1) percent - - + + @@ -1918,8 +2145,8 @@ IVA 4% Intracomunitario. Bienes corrientes (2) percent - - + + @@ -1945,8 +2172,8 @@ IVA 4% Intracomunitario. Bienes de inversión (1) percent - - + + @@ -1961,8 +2188,8 @@ IVA 4% Intracomunitario. Bienes de inversión (2) percent - - + + @@ -1972,7 +2199,538 @@ purchase - + + + + IVA 7% Intracomunitario. Bienes corrientes + IVA 7% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión + IVA 7% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes + IVA 8% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión + IVA 8% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes + IVA 10% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión + IVA 10% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes + IVA 16% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión + IVA 16% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes + IVA 18% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + + + IVA 18% Intracomunitario. Bienes de inversión + IVA 18% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes + IVA 21% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión + IVA 21% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + - + - + IRPF Retenciones practicadas Base Imponible @@ -1990,56 +2748,70 @@ 1.0 - + IRPF Retenciones practicadas Base Imponible 1% B.IRPF1 1.0 - + IRPF Retenciones practicadas Base Imponible 2% B.IRPF2 1.0 - + IRPF Retenciones practicadas Base Imponible 7% B.IRPF7 1.0 - + + + IRPF Retenciones practicadas Base Imponible 9% + B.IRPF9 + + 1.0 + + IRPF Retenciones practicadas Base Imponible 15% B.IRPF15 1.0 - + IRPF Retenciones practicadas Base Imponible 18% B.IRPF18 1.0 - + IRPF Retenciones practicadas Base Imponible 19% B.IRPF19 1.0 - + + + IRPF Retenciones practicadas Base Imponible 20% + B.IRPF20 + + 1.0 + + IRPF Retenciones practicadas Base Imponible 21% B.IRPF21 1.0 - + IRPF Retenciones practicadas Total Cuota @@ -2047,128 +2819,78 @@ 1.0 - + IRPF Retenciones practicadas Cuota 1% IRPF1 1.0 - + IRPF Retenciones practicadas Cuota 2% IRPF2 1.0 - + IRPF Retenciones practicadas Cuota 7% IRPF7 1.0 - + + + IRPF Retenciones practicadas Cuota 9% + IRPF9 + + 1.0 + + IRPF Retenciones practicadas Cuota 15% IRPF15 1.0 - + IRPF Retenciones practicadas Cuota 18% IRPF18 1.0 - + IRPF Retenciones practicadas Cuota 19% IRPF19 1.0 - + + + IRPF Retenciones practicadas Cuota 20% + IRPF20 + + 1.0 + + IRPF Retenciones practicadas Cuota 21% IRPF21 1.0 - - - - 475101 - - - other - Hacienda Pública. Retenciones empresarios módulos 1% - - - - - 475102 - - - other - Hacienda Pública. Retenciones act. agrícolas, ganaderas, forestales 2% - - - - - 475107 - - - other - Hacienda Pública. Retenciones act. profesionales 7% - - - - - 475115 - - - other - Hacienda Pública. Retenciones act. profesionales 15% - - - - - 475118 - - - other - Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 18% - - - - - 475119 - - - other - Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 19% - - - - - 475121 - - - other - Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 21% - - - + Retenciones IRPF 1% percent - - + + @@ -2179,14 +2901,14 @@ purchase - + Retenciones IRPF 2% percent - - + + @@ -2197,14 +2919,14 @@ purchase - + Retenciones IRPF 7% percent - - + + @@ -2215,14 +2937,32 @@ purchase - + + + + Retenciones IRPF 9% + + percent + + + + + + + + + + + purchase + + Retenciones IRPF 15% percent - - + + @@ -2233,14 +2973,14 @@ purchase - + Retenciones IRPF 18% percent - - + + @@ -2251,14 +2991,14 @@ purchase - + Retenciones IRPF 19% percent - - + + @@ -2269,14 +3009,32 @@ purchase - + + + + Retenciones IRPF 20% + + percent + + + + + + + + + + + purchase + + Retenciones IRPF 21% percent - - + + @@ -2287,9 +3045,9 @@ purchase - + - + IRPF Retenciones a cuenta Base Imponible @@ -2297,56 +3055,70 @@ 1.0 - + IRPF Retenciones a cuenta Base Imponible 1% B.IRPF1 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 2% B.IRPF2 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 7% B.IRPF7 AC 1.0 - + + + IRPF Retenciones a cuenta Base Imponible 9% + B.IRPF9 AC + + 1.0 + + IRPF Retenciones a cuenta Base Imponible 15% B.IRPF15 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 18% B.IRPF18 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 19% B.IRPF19 AC 1.0 - + + + IRPF Retenciones a cuenta Base Imponible 20% + B.IRPF20 AC + + 1.0 + + IRPF Retenciones a cuenta Base Imponible 21% B.IRPF21 AC 1.0 - + IRPF Retenciones a cuenta Total Cuota @@ -2354,128 +3126,78 @@ 1.0 - + IRPF Retenciones a cuenta Cuota 1% IRPF1 AC 1.0 - + IRPF Retenciones a cuenta Cuota 2% IRPF2 AC 1.0 - + IRPF Retenciones a cuenta Cuota 7% IRPF7 AC 1.0 - + + + IRPF Retenciones a cuenta Cuota 9% + IRPF9 AC + + 1.0 + + IRPF Retenciones a cuenta Cuota 15% IRPF15 AC 1.0 - + IRPF Retenciones a cuenta Cuota 18% IRPF18 AC 1.0 - + IRPF Retenciones a cuenta Cuota 19% IRPF19 AC 1.0 - + + + IRPF Retenciones a cuenta Cuota 20% + IRPF20 AC + + 1.0 + + IRPF Retenciones a cuenta Cuota 21% IRPF21 AC 1.0 - - - - 473001 - - - other - Hacienda Pública. Retenciones a cuenta empresarios módulos 1% - - - - - 473002 - - - other - Hacienda Pública. Retenciones a cuenta act. agrícolas, ganaderas, forestales 2% - - - - 473007 - - - other - Hacienda Pública. Retenciones a cuenta act. profesionales 7% - - - - - 473015 - - - other - Hacienda Pública. Retenciones a cuenta act. profesionales 15% - - - - - 473018 - - - other - Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 18% - - - - - 473019 - - - other - Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 19% - - - - - 473021 - - - other - Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 21% - - - Retenciones a cuenta IRPF 1% percent - - + + @@ -2486,14 +3208,14 @@ sale - + Retenciones a cuenta IRPF 2% percent - - + + @@ -2504,14 +3226,14 @@ sale - + Retenciones a cuenta IRPF 7% percent - - + + @@ -2522,14 +3244,32 @@ sale - + + + + Retenciones a cuenta IRPF 9% + + percent + + + + + + + + + + + sale + + Retenciones a cuenta IRPF 15% percent - - + + @@ -2540,14 +3280,14 @@ sale - + Retenciones a cuenta IRPF 18% percent - - + + @@ -2558,14 +3298,14 @@ sale - + Retenciones a cuenta IRPF 19% percent - - + + @@ -2576,14 +3316,32 @@ sale - + + + + Retenciones a cuenta IRPF 20% + + percent + + + + + + + + + + + sale + + Retenciones a cuenta IRPF 21% percent - - + + diff --git a/addons/l10n_es/taxes_data_assoc.xml b/addons/l10n_es/taxes_data_assoc.xml new file mode 100644 index 00000000000..e2ebb47fb59 --- /dev/null +++ b/addons/l10n_es/taxes_data_assoc.xml @@ -0,0 +1,3540 @@ + + + + + + + + + + + + + + + + + + + + IVA Devengado Base Imponible + -- + 1.0 + + + + + + Base adquisiciones exentas + + + -- + 1.0 + + + + Base ventas exentas + -- + + + 1.0 + + + + + + IVA Soportado exento (operaciones corrientes) + + percent + + + + + + + purchase + + + + + + IVA Exento + + percent + + + + + + + sale + + + + + + + + Régimen general IVA Devengado. Base Imponible 4% + [01] + + 1.0 + + + + Régimen general IVA Devengado. Base Imponible 7% + [04] + + 1.0 + + + Régimen general IVA Devengado. Base Imponible 8% + [04] + + 1.0 + + + + Régimen general IVA Devengado. Base Imponible 10% + [04] + + 1.0 + + + + Régimen general IVA Devengado. Base Imponible 16% + [07] + + 1.0 + + + Régimen general IVA Devengado. Base Imponible 18% + [07] + + 1.0 + + + + Régimen general IVA Devengado. Base Imponible 21% + [07] + + 1.0 + + + + + + + Recargo Equivalencia Base Imponible 0.5% + [10] + + 1.0 + + + + Recargo Equivalencia Base Imponible 1% + [13] + + 1.0 + + + + Recargo Equivalencia Base Imponible 1.4% + [13] + + 1.0 + + + + Recargo Equivalencia Base Imponible 4% + [16] + + 1.0 + + + + Recargo Equivalencia Base Imponible 5.2% + [16] + + 1.0 + + + + + + + Adquisiciones intracomunitarias. Base Imponible + [19] + + 1.0 + + + + + + + + + + + IVA Cuota total devengada + [21] + 1.0 + + + + + Régimen general IVA Devengado. Cuota 4% + [03] + + 1.0 + + + + Régimen general IVA Devengado. Cuota 7% + [06] + + 1.0 + + + + Régimen general IVA Devengado. Cuota 8% + [06] + + 1.0 + + + + Régimen general IVA Devengado. Cuota 10% + [06] + + 1.0 + + + + Régimen general IVA Devengado. Cuota 16% + [09] + + 1.0 + + + + Régimen general IVA Devengado. Cuota 18% + [09] + + 1.0 + + + + Régimen general IVA Devengado. Cuota 21% + [09] + + 1.0 + + + + + + + Recargo Equivalencia. Cuota 0.5% + [12] + + 1.0 + + + + Recargo Equivalencia. Cuota 1% + [15] + + 1.0 + + + + Recargo Equivalencia. Cuota 1.4% + [15] + + 1.0 + + + + Recargo Equivalencia. Cuota 4% + [18] + + 1.0 + + + + Recargo Equivalencia. Cuota 5.2% + [18] + + 1.0 + + + + + + + Adquisiciones intracomunitarias. Cuota + [20] + + 1.0 + + + + + + + + + + + + + + + IVA Deducible Base Imponible + -- + 1.0 + + + + + + Base operaciones interiores corrientes + [22] + + 1.0 + + + Base operaciones interiores corrientes (16%) + -- + + 1.0 + + + Base operaciones interiores corrientes (18%) + -- + + 1.0 + + + + Base operaciones interiores corrientes (7%) + -- + + 1.0 + + + Base operaciones interiores corrientes (8%) + -- + + 1.0 + + + Base operaciones interiores corrientes (4%) + -- + + 1.0 + + + + Base operaciones interiores corrientes (10%) + -- + + 1.0 + + + + Base operaciones interiores corrientes (21%) + -- + + 1.0 + + + + + Base operaciones interiores bienes inversión + [24] + + 1.0 + + + Base operaciones interiores bienes inversión (16%) + -- + + 1.0 + + + + Base operaciones interiores bienes inversión (18%) + -- + + 1.0 + + + + Base operaciones interiores bienes inversión (7%) + -- + + 1.0 + + + + Base operaciones interiores bienes inversión (8%) + -- + + 1.0 + + + + Base operaciones interiores bienes inversión (4%) + -- + + 1.0 + + + + Base operaciones interiores bienes inversión (10%) + -- + + 1.0 + + + + Base operaciones interiores bienes inversión (21%) + -- + + 1.0 + + + + + + Base importaciones bienes corrientes + [26] + + 1.0 + + + Base importaciones bienes corrientes (16%) + -- + + 1.0 + + + Base importaciones bienes corrientes (18%) + -- + + 1.0 + + + + Base importaciones bienes corrientes (7%) + -- + + 1.0 + + + Base importaciones bienes corrientes (8%) + -- + + 1.0 + + + Base importaciones bienes corrientes (4%) + -- + + 1.0 + + + + Base importaciones bienes corrientes (10%) + -- + + 1.0 + + + Base importaciones bienes corrientes (21%) + -- + + 1.0 + + + + + Base importaciones bienes inversión + [28] + + 1.0 + + + Base importaciones bienes inversión (16%) + -- + + 1.0 + + + Base importaciones bienes inversión (18%) + -- + + 1.0 + + + + Base importaciones bienes inversión (7%) + -- + + 1.0 + + + Base importaciones bienes inversión (8%) + -- + + 1.0 + + + Base importaciones bienes inversión (4%) + -- + + 1.0 + + + Base importaciones bienes inversión (10%) + -- + + 1.0 + + + Base importaciones bienes inversión (21%) + -- + + 1.0 + + + + + Base adquisiciones intracomunitarias bienes corrientes + [30] + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (16%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (18%) + -- + + 1.0 + + + + Base adquisiciones intracomunitarias bienes corrientes (7%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (8%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (4%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (10%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (21%) + -- + + 1.0 + + + + + Base adquisiciones intracomunitarias bienes inversión + [32] + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (16%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (18%) + -- + + 1.0 + + + + Base adquisiciones intracomunitarias bienes inversión (7%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (8%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (4%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (10%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (21%) + -- + + 1.0 + + + + + Recargo Equivalencia Ded. Base Imponible 0.5% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 1% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 1.4% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 4% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 5.2% + -- + + 1.0 + + + + + + + + IVA deducible (Cuota)- Total a deducir [Mod.303] + [37] + + 1.0 + + + + + Cuotas soportadas operaciones interiores corrientes + [23] + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (16%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (18%) + -- + + 1.0 + + + + Cuotas soportadas operaciones interiores corrientes (7%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (8%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (10%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (4%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (21%) + -- + + 1.0 + + + + + Cuotas soportadas operaciones interiores bienes inversión + [25] + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (16%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (18%) + -- + + 1.0 + + + + Cuotas soportadas operaciones interiores bienes inversión (7%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (8%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (4%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (10%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (21%) + -- + + 1.0 + + + + + Cuotas devengadas importaciones bienes corrientes + [27] + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (16%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (18%) + -- + + 1.0 + + + + Cuotas devengadas importaciones bienes corrientes (7%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (8%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (4%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (10%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (21%) + -- + + 1.0 + + + + + Cuotas devengadas importaciones bienes inversión + [29] + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (16%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (18%) + -- + + 1.0 + + + + Cuotas devengadas importaciones bienes inversión (7%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (8%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (4%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (10%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (21%) + -- + + 1.0 + + + + En adquisiciones intracomunitarias bienes corrientes + [31] + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (16%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (18%) + -- + + 1.0 + + + + En adquisiciones intracomunitarias bienes corrientes (7%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (8%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (4%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (10%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (21%) + -- + + 1.0 + + + + En adquisiciones intracomunitarias bienes inversión + [33] + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (16%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (18%) + -- + + 1.0 + + + + En adquisiciones intracomunitarias bienes inversión (7%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (8%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (4%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (10%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (21%) + -- + + 1.0 + + + + + Entregas Intracomunitarias + [42] + + 1.0 + + + + Exportaciones y operaciones asimiladas + [43] + + 1.0 + + + + Inversión del sujeto pasivo + [44] + + 1.0 + + + + + Recargo Equivalencia Ded. Cuota 0.5% + [12] + + 1.0 + + + + Recargo Equivalencia Ded. Cuota 1% + [15] + + 1.0 + + + + Recargo Equivalencia Ded. Cuota 1.4% + [15] + + 1.0 + + + + Recargo Equivalencia Ded. Cuota 4% + [18] + + 1.0 + + + + Recargo Equivalencia Ded. Cuota 5.2% + [18] + + 1.0 + + + + + + + + + + + 4% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 4% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + 7% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 7% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + 8% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 8% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + 10% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 10% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + 16% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 16% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + 18% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 18% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + 21% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + + 21% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + + + + + + IVA 0% Importaciones bienes corrientes + IVA 0% Importaciones bienes corrientes + + percent + + + + + + + purchase + + + + IVA 0% Importaciones bienes de inversión + IVA 0% Importaciones bienes de inversión + + percent + + + + + + + purchase + + + + + IVA 4% Importaciones bienes corrientes + IVA 4% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 4% Importaciones bienes de inversión + IVA 4% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + IVA 7% Importaciones bienes corrientes + IVA 7% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 7% Importaciones bienes de inversión + IVA 7% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + IVA 8% Importaciones bienes corrientes + IVA 8% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 8% Importaciones bienes de inversión + IVA 8% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + IVA 10% Importaciones bienes corrientes + IVA 10% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 10% Importaciones bienes de inversión + IVA 10% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + IVA 16% Importaciones bienes corrientes + IVA 16% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 16% Importaciones bienes de inversión + IVA 16% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + IVA 18% Importaciones bienes corrientes + IVA 18% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 18% Importaciones bienes de inversión + IVA 18% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + IVA 21% Importaciones bienes corrientes + IVA 21% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 21% Importaciones bienes de inversión + IVA 21% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + + + + + + IVA 0% Exportaciones + IVA 0% Exportaciones + + percent + + + + sale + + + + + + IVA 16% Inversión del sujeto pasivo + IVA 16% Inversión del sujeto pasivo + + percent + + + + + + purchase + + + + IVA 16% Inversión del sujeto pasivo (1) + + + percent + + + + + + + purchase + + + + IVA 16% Inversión del sujeto pasivo (2) + + + percent + + + + + + + + + + + purchase + + + + IVA 16% Inversión del sujeto pasivo (3) + + + percent + + + + + + + + + + + purchase + + + + + IVA 18% Inversión del sujeto pasivo + IVA 18% Inversión del sujeto pasivo + + percent + + + + + + purchase + + + + IVA 18% Inversión del sujeto pasivo (1) + + + percent + + + + + + + purchase + + + + IVA 18% Inversión del sujeto pasivo (2) + + + percent + + + + + + + + + + + purchase + + + + IVA 18% Inversión del sujeto pasivo (3) + + + percent + + + + + + + + + + + purchase + + + + + IVA 21% Inversión del sujeto pasivo + IVA 21% Inversión del sujeto pasivo + + percent + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (1) + + + percent + + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (2) + + + percent + + + + + + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (3) + + + percent + + + + + + + + + + + purchase + + + + + + IVA 4% + + percent + + + + + + + + + + + sale + + + + + IVA 7% + + percent + + + + + + + + + + + sale + + + + + IVA 8% + + percent + + + + + + + + + + + sale + + + + + IVA 10% + + percent + + + + + + + + + + + sale + + + + + IVA 16% + + percent + + + + + + + + + + + sale + + + + + IVA 18% + + percent + + + + + + + + + + + sale + + + + + IVA 21% + + percent + + + + + + + + + + + sale + + + + + + + + 0.50% Recargo Equivalencia + + percent + + + + + + + + + + + sale + + + + + 1% Recargo Equivalencia + + percent + + + + + + + + + + + sale + + + + + 1.4% Recargo Equivalencia + + percent + + + + + + + + + + + sale + + + + + 4% Recargo Equivalencia + + percent + + + + + + + + + + + sale + + + + + 5.2% Recargo Equivalencia + + percent + + + + + + + + + + + sale + + + + + 0.50% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 1% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 1.4% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 4% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 5.2% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + + + + + IVA 0% Intracomunitario + IVA 0% Intracomunitario 0 + + percent + + + + + sale + + + + + + + IVA 16% Intracomunitario. Bienes corrientes + IVA 16% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes + IVA 18% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + + + IVA 16% Intracomunitario. Bienes de inversión + IVA 16% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión + IVA 18% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes + IVA 7% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión + IVA 7% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes + IVA 8% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión + IVA 8% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 4% Intracomunitario. Bienes corrientes + IVA 4% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 4% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 4% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 4% Intracomunitario. Bienes de inversión + IVA 4% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 4% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 4% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes + IVA 10% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión + IVA 10% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes + IVA 21% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión + IVA 21% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + + + + + + IRPF Retenciones practicadas Base Imponible + B.IRPF + 1.0 + + + + + IRPF Retenciones practicadas Base Imponible 1% + B.IRPF1 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 2% + B.IRPF2 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 7% + B.IRPF7 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 9% + B.IRPF9 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 15% + B.IRPF15 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 18% + B.IRPF18 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 19% + B.IRPF19 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 20% + B.IRPF20 + + 1.0 + + + + IRPF Retenciones practicadas Base Imponible 21% + B.IRPF21 + + 1.0 + + + + + IRPF Retenciones practicadas Total Cuota + IRPF + + 1.0 + + + + IRPF Retenciones practicadas Cuota 1% + IRPF1 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 2% + IRPF2 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 7% + IRPF7 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 9% + IRPF9 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 15% + IRPF15 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 18% + IRPF18 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 19% + IRPF19 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 20% + IRPF20 + + 1.0 + + + + IRPF Retenciones practicadas Cuota 21% + IRPF21 + + 1.0 + + + + + 475101 + + + other + Hacienda Pública. Retenciones empresarios módulos 1% + + + + + 475102 + + + other + Hacienda Pública. Retenciones act. agrícolas, ganaderas, forestales 2% + + + + + 475107 + + + other + Hacienda Pública. Retenciones act. profesionales 7% + + + + + 475109 + + + other + Hacienda Pública. Retenciones act. profesionales 9% + + + + + 475115 + + + other + Hacienda Pública. Retenciones act. profesionales 15% + + + + + 475118 + + + other + Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 18% + + + + + 475119 + + + other + Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 19% + + + + + 475120 + + + other + Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 20% + + + + + 475121 + + + other + Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 21% + + + + + + + Retenciones IRPF 1% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 2% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 7% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 9% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 15% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 18% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 19% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 20% + + percent + + + + + + + + + + + purchase + + + + + Retenciones IRPF 21% + + percent + + + + + + + + + + + purchase + + + + + + + IRPF Retenciones a cuenta Base Imponible + B.IRPF AC + 1.0 + + + + + IRPF Retenciones a cuenta Base Imponible 1% + B.IRPF1 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 2% + B.IRPF2 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 7% + B.IRPF7 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 9% + B.IRPF9 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 15% + B.IRPF15 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 18% + B.IRPF18 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 19% + B.IRPF19 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 20% + B.IRPF20 AC + + 1.0 + + + + IRPF Retenciones a cuenta Base Imponible 21% + B.IRPF21 AC + + 1.0 + + + + + IRPF Retenciones a cuenta Total Cuota + IRPF AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 1% + IRPF1 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 2% + IRPF2 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 7% + IRPF7 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 9% + IRPF9 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 15% + IRPF15 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 18% + IRPF18 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 19% + IRPF19 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 20% + IRPF20 AC + + 1.0 + + + + IRPF Retenciones a cuenta Cuota 21% + IRPF21 AC + + 1.0 + + + + + 473001 + + + other + Hacienda Pública. Retenciones a cuenta empresarios módulos 1% + + + + + 473002 + + + other + Hacienda Pública. Retenciones a cuenta act. agrícolas, ganaderas, forestales 2% + + + + + 473007 + + + other + Hacienda Pública. Retenciones a cuenta act. profesionales 7% + + + + + 473009 + + + other + Hacienda Pública. Retenciones a cuenta act. profesionales 9% + + + + + 473015 + + + other + Hacienda Pública. Retenciones a cuenta act. profesionales 15% + + + + + 473018 + + + other + Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 18% + + + + + 473019 + + + other + Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 19% + + + + + 473020 + + + other + Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 20% + + + + + 473021 + + + other + Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 21% + + + + + + + Retenciones a cuenta IRPF 1% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 2% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 7% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 9% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 15% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 18% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 19% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 20% + + percent + + + + + + + + + + + sale + + + + + Retenciones a cuenta IRPF 21% + + percent + + + + + + + + + + + sale + + + diff --git a/addons/l10n_es/taxes_data_pymes.xml b/addons/l10n_es/taxes_data_pymes.xml index 7467dbb9596..f48d46d951a 100644 --- a/addons/l10n_es/taxes_data_pymes.xml +++ b/addons/l10n_es/taxes_data_pymes.xml @@ -1,9 +1,10 @@ - + - + + - - - + Ignacio Ibeas (Acysos) - ignacio@acysos.com (2011-05-06) + Añadido Recargos de equivalencia para venta y compra + + Pedro M. Baeza (Serv. Tecnol. Avanzados) - pedro.baeza@serviciosbaeza.com (2013-01-30) + Limpieza de subcuentas de impuestos y corrección de inversión de sujeto pasivo + + --> + + - - + + - + @@ -48,44 +54,103 @@ 1.0 - - - + + + + Base adquisiciones exentas + + -- + 1.0 + + + + Base ventas exentas + -- + + 1.0 + + + + + + IVA Soportado exento (operaciones corrientes) + + percent + + + + + + + purchase + + + + + + IVA Exento + + percent + + + + + + + sale + + - + Régimen general IVA Devengado. Base Imponible 4% [01] 1.0 - + Régimen general IVA Devengado. Base Imponible 7% [04] 1.0 + Régimen general IVA Devengado. Base Imponible 8% [04] 1.0 - + + + Régimen general IVA Devengado. Base Imponible 10% + [04] + + 1.0 + + Régimen general IVA Devengado. Base Imponible 16% [07] 1.0 + Régimen general IVA Devengado. Base Imponible 18% [07] 1.0 - + + + Régimen general IVA Devengado. Base Imponible 21% + [07] + + 1.0 + + - + Recargo Equivalencia Base Imponible 0.5% [10] 1.0 - + Recargo Equivalencia Base Imponible 1% [13] 1.0 - + + + Recargo Equivalencia Base Imponible 1.4% + [13] + + 1.0 + + Recargo Equivalencia Base Imponible 4% [16] 1.0 - - + + + Recargo Equivalencia Base Imponible 5.2% + [16] + + 1.0 + + - + Adquisiciones intracomunitarias. Base Imponible [19] 1.0 - + - - + + - - + + IVA Cuota total devengada [21] 1.0 - + Régimen general IVA Devengado. Cuota 4% [03] 1.0 - + Régimen general IVA Devengado. Cuota 7% [06] 1.0 - + Régimen general IVA Devengado. Cuota 8% [06] 1.0 - + + + Régimen general IVA Devengado. Cuota 10% + [06] + + 1.0 + + Régimen general IVA Devengado. Cuota 16% [09] @@ -173,7 +258,14 @@ 1.0 - + + + Régimen general IVA Devengado. Cuota 21% + [09] + + 1.0 + + - + Recargo Equivalencia. Cuota 0.5% [12] 1.0 - + Recargo Equivalencia. Cuota 1% [15] 1.0 - + + + Recargo Equivalencia. Cuota 1.4% + [15] + + 1.0 + + Recargo Equivalencia. Cuota 4% [18] 1.0 - - + + + Recargo Equivalencia. Cuota 5.2% + [18] + + 1.0 + + + - + Adquisiciones intracomunitarias. Cuota [20] 1.0 - - - - - + + + + + - - + + @@ -230,7 +336,7 @@ 1.0 - + Base operaciones interiores corrientes @@ -238,19 +344,12 @@ 1.0 - - Base operaciones interiores corrientes (16%) + + Base operaciones interiores corrientes (4%) -- 1.0 - - Base operaciones interiores corrientes (18%) - -- - - 1.0 - - Base operaciones interiores corrientes (7%) -- @@ -263,13 +362,31 @@ 1.0 - - Base operaciones interiores corrientes (4%) + + Base operaciones interiores corrientes (10%) -- 1.0 - + + Base operaciones interiores corrientes (16%) + -- + + 1.0 + + + Base operaciones interiores corrientes (18%) + -- + + 1.0 + + + Base operaciones interiores corrientes (21%) + -- + + 1.0 + + Base operaciones interiores bienes inversión @@ -277,48 +394,79 @@ 1.0 - - Base operaciones interiores bienes inversión (16%) - -- - - 1.0 - - - - Base operaciones interiores bienes inversión (18%) - -- - - 1.0 - - - - Base operaciones interiores bienes inversión (7%) - -- - - 1.0 - - - - Base operaciones interiores bienes inversión (8%) - -- - - 1.0 - - Base operaciones interiores bienes inversión (4%) -- 1.0 - - + + Base operaciones interiores bienes inversión (7%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (8%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (10%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (16%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (18%) + -- + + 1.0 + + + Base operaciones interiores bienes inversión (21%) + -- + + 1.0 + + Base importaciones bienes corrientes [26] 1.0 + + + Base importaciones bienes corrientes (4%) + -- + + 1.0 + + + Base importaciones bienes corrientes (7%) + -- + + 1.0 + + + Base importaciones bienes corrientes (8%) + -- + + 1.0 + + + Base importaciones bienes corrientes (10%) + -- + + 1.0 Base importaciones bienes corrientes (16%) @@ -332,26 +480,13 @@ 1.0 - - - Base importaciones bienes corrientes (7%) + + Base importaciones bienes corrientes (21%) -- 1.0 - - Base importaciones bienes corrientes (8%) - -- - - 1.0 - - - Base importaciones bienes corrientes (4%) - -- - - 1.0 - - + Base importaciones bienes inversión @@ -359,19 +494,12 @@ 1.0 - - Base importaciones bienes inversión (16%) + + Base importaciones bienes inversión (4%) -- 1.0 - - Base importaciones bienes inversión (18%) - -- - - 1.0 - - Base importaciones bienes inversión (7%) -- @@ -384,13 +512,30 @@ 1.0 - - Base importaciones bienes inversión (4%) + + Base importaciones bienes inversión (10%) + -- + + 1.0 + + + Base importaciones bienes inversión (16%) + -- + + 1.0 + + + Base importaciones bienes inversión (18%) + -- + + 1.0 + + + Base importaciones bienes inversión (21%) -- 1.0 - Base adquisiciones intracomunitarias bienes corrientes @@ -398,19 +543,12 @@ 1.0 - - Base adquisiciones intracomunitarias bienes corrientes (16%) + + Base adquisiciones intracomunitarias bienes corrientes (4%) -- 1.0 - - Base adquisiciones intracomunitarias bienes corrientes (18%) - -- - - 1.0 - - Base adquisiciones intracomunitarias bienes corrientes (7%) -- @@ -423,13 +561,30 @@ 1.0 - - Base adquisiciones intracomunitarias bienes corrientes (4%) + + Base adquisiciones intracomunitarias bienes corrientes (10%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (16%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (18%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes corrientes (21%) -- 1.0 - Base adquisiciones intracomunitarias bienes inversión @@ -437,6 +592,30 @@ 1.0 + + Base adquisiciones intracomunitarias bienes inversión (4%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (7%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (8%) + -- + + 1.0 + + + Base adquisiciones intracomunitarias bienes inversión (10%) + -- + + 1.0 + Base adquisiciones intracomunitarias bienes inversión (16%) -- @@ -449,31 +628,53 @@ 1.0 - - - Base adquisiciones intracomunitarias bienes inversión (7%) - -- - - 1.0 - - - Base adquisiciones intracomunitarias bienes inversión (8%) - -- - - 1.0 - - - Base adquisiciones intracomunitarias bienes inversión (4%) + + Base adquisiciones intracomunitarias bienes inversión (21%) -- 1.0 - - + + + Recargo Equivalencia Ded. Base Imponible 0.5% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 1% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 1.4% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 4% + -- + + 1.0 + + + + Recargo Equivalencia Ded. Base Imponible 5.2% + -- + + 1.0 + + + - + IVA deducible (Cuota)- Total a deducir [Mod.303] [37] @@ -488,19 +689,12 @@ 1.0 - - Cuotas soportadas operaciones interiores corrientes (16%) + + Cuotas soportadas operaciones interiores corrientes (4%) -- 1.0 - - Cuotas soportadas operaciones interiores corrientes (18%) - -- - - 1.0 - - Cuotas soportadas operaciones interiores corrientes (7%) -- @@ -513,13 +707,30 @@ 1.0 - - Cuotas soportadas operaciones interiores corrientes (4%) + + Cuotas soportadas operaciones interiores corrientes (10%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (16%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (18%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores corrientes (21%) -- 1.0 - Cuotas soportadas operaciones interiores bienes inversión @@ -527,19 +738,12 @@ 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (16%) + + Cuotas soportadas operaciones interiores bienes inversión (4%) -- 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (18%) - -- - - 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (7%) -- @@ -552,13 +756,30 @@ 1.0 - - Cuotas soportadas operaciones interiores bienes inversión (4%) + + Cuotas soportadas operaciones interiores bienes inversión (10%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (16%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (18%) + -- + + 1.0 + + + Cuotas soportadas operaciones interiores bienes inversión (21%) -- 1.0 - Cuotas devengadas importaciones bienes corrientes @@ -566,19 +787,12 @@ 1.0 - - Cuotas devengadas importaciones bienes corrientes (16%) + + Cuotas devengadas importaciones bienes corrientes (4%) -- 1.0 - - Cuotas devengadas importaciones bienes corrientes (18%) - -- - - 1.0 - - Cuotas devengadas importaciones bienes corrientes (7%) -- @@ -591,13 +805,30 @@ 1.0 - - Cuotas devengadas importaciones bienes corrientes (4%) + + Cuotas devengadas importaciones bienes corrientes (10%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (16%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (18%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes corrientes (21%) -- 1.0 - Cuotas devengadas importaciones bienes inversión @@ -605,19 +836,12 @@ 1.0 - - Cuotas devengadas importaciones bienes inversión (16%) + + Cuotas devengadas importaciones bienes inversión (4%) -- 1.0 - - Cuotas devengadas importaciones bienes inversión (18%) - -- - - 1.0 - - Cuotas devengadas importaciones bienes inversión (7%) -- @@ -630,13 +854,30 @@ 1.0 - - Cuotas devengadas importaciones bienes inversión (4%) + + Cuotas devengadas importaciones bienes inversión (10%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (16%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (18%) + -- + + 1.0 + + + Cuotas devengadas importaciones bienes inversión (21%) -- 1.0 - En adquisiciones intracomunitarias bienes corrientes @@ -644,19 +885,12 @@ 1.0 - - En adquisiciones intracomunitarias bienes corrientes (16%) + + En adquisiciones intracomunitarias bienes corrientes (4%) -- 1.0 - - En adquisiciones intracomunitarias bienes corrientes (18%) - -- - - 1.0 - - En adquisiciones intracomunitarias bienes corrientes (7%) -- @@ -669,13 +903,30 @@ 1.0 - - En adquisiciones intracomunitarias bienes corrientes (4%) + + En adquisiciones intracomunitarias bienes corrientes (10%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (16%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (18%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes corrientes (21%) -- 1.0 - En adquisiciones intracomunitarias bienes inversión @@ -683,19 +934,12 @@ 1.0 - - En adquisiciones intracomunitarias bienes inversión (16%) + + En adquisiciones intracomunitarias bienes inversión (4%) -- 1.0 - - En adquisiciones intracomunitarias bienes inversión (18%) - -- - - 1.0 - - En adquisiciones intracomunitarias bienes inversión (7%) -- @@ -708,13 +952,30 @@ 1.0 - - En adquisiciones intracomunitarias bienes inversión (4%) + + En adquisiciones intracomunitarias bienes inversión (10%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (16%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (18%) + -- + + 1.0 + + + En adquisiciones intracomunitarias bienes inversión (21%) -- 1.0 - Entregas Intracomunitarias @@ -737,109 +998,42 @@ 1.0 - - - + + + Recargo Equivalencia Ded. Cuota 0.5% + [12] + + 1.0 + - - 472004 - - - other - Hacienda Pública. IVA soportado 4% - + + Recargo Equivalencia Ded. Cuota 1% + [15] + + 1.0 - - - 472007 - - - other - Hacienda Pública. IVA soportado 7% - + + + Recargo Equivalencia Ded. Cuota 1.4% + [15] + + 1.0 - - - 472008 - - - other - Hacienda Pública. IVA soportado 8% - + + + Recargo Equivalencia Ded. Cuota 4% + [18] + + 1.0 - - - 472016 - - - other - Hacienda Pública. IVA soportado 16% - + + + Recargo Equivalencia Ded. Cuota 5.2% + [18] + + 1.0 - - - 472018 - - - other - Hacienda Pública. IVA soportado 18% - - - - - 477004 - - - other - Hacienda Pública. IVA repercutido 4% - - - - - 477007 - - - other - Hacienda Pública. IVA repercutido 7% - - - - 477008 - - - other - Hacienda Pública. IVA repercutido 8% - - - - - 477016 - - - other - Hacienda Pública. IVA repercutido 16% - - - - - 477018 - - - other - Hacienda Pública. IVA repercutido 18% - - - - - 475001 - - - payable - Hacienda acreedora IVA - - - - + @@ -851,8 +1045,8 @@ 4% IVA Soportado (operaciones corrientes) percent - - + + @@ -863,14 +1057,14 @@ purchase - + 4% IVA Soportado (bienes de inversión) percent - - + + @@ -881,14 +1075,14 @@ purchase - + 7% IVA Soportado (operaciones corrientes) percent - - + + @@ -899,14 +1093,14 @@ purchase - + 7% IVA Soportado (bienes de inversión) percent - - + + @@ -917,14 +1111,14 @@ purchase - + 8% IVA Soportado (operaciones corrientes) percent - - + + @@ -935,14 +1129,14 @@ purchase - + 8% IVA Soportado (bienes de inversión) percent - - + + @@ -953,14 +1147,50 @@ purchase - + + + + 10% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + 10% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + 16% IVA Soportado (operaciones corrientes) percent - - + + @@ -971,14 +1201,14 @@ purchase - + 16% IVA Soportado (bienes de inversión) percent - - + + @@ -989,14 +1219,14 @@ purchase - + 18% IVA Soportado (operaciones corrientes) percent - - + + @@ -1006,15 +1236,16 @@ purchase + - + 18% IVA Soportado (bienes de inversión) percent - - + + @@ -1025,7 +1256,44 @@ purchase - + + + + 21% IVA Soportado (operaciones corrientes) + + percent + + + + + + + + + + + purchase + + + + + + 21% IVA Soportado (bienes de inversión) + + percent + + + + + + + + + + + purchase + + @@ -1056,15 +1324,15 @@ purchase - + IVA 4% Importaciones bienes corrientes IVA 4% Importaciones bienes corrientes percent - - + + @@ -1081,8 +1349,8 @@ IVA 4% Importaciones bienes de inversión percent - - + + @@ -1093,15 +1361,15 @@ purchase - + IVA 7% Importaciones bienes corrientes IVA 7% Importaciones bienes corrientes percent - - + + @@ -1118,8 +1386,8 @@ IVA 7% Importaciones bienes de inversión percent - - + + @@ -1130,15 +1398,15 @@ purchase - + IVA 8% Importaciones bienes corrientes IVA 8% Importaciones bienes corrientes percent - - + + @@ -1155,8 +1423,8 @@ IVA 8% Importaciones bienes de inversión percent - - + + @@ -1167,15 +1435,52 @@ purchase - + + + + IVA 10% Importaciones bienes corrientes + IVA 10% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 10% Importaciones bienes de inversión + IVA 10% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + + IVA 16% Importaciones bienes corrientes IVA 16% Importaciones bienes corrientes percent - - + + @@ -1192,8 +1497,8 @@ IVA 16% Importaciones bienes de inversión percent - - + + @@ -1204,15 +1509,15 @@ purchase - + IVA 18% Importaciones bienes corrientes IVA 18% Importaciones bienes corrientes percent - - + + @@ -1229,8 +1534,8 @@ IVA 18% Importaciones bienes de inversión percent - - + + @@ -1241,7 +1546,42 @@ purchase - + + + IVA 21% Importaciones bienes corrientes + IVA 21% Importaciones bienes corrientes + + percent + + + + + + + + + + + purchase + + + + IVA 21% Importaciones bienes de inversión + IVA 21% Importaciones bienes de inversión + + percent + + + + + + + + + + + purchase + @@ -1255,7 +1595,7 @@ sale - + @@ -1290,16 +1630,16 @@ percent - - + + - + - + purchase @@ -1308,8 +1648,8 @@ percent - - + + @@ -1320,7 +1660,7 @@ purchase - + IVA 18% Inversión del sujeto pasivo @@ -1354,16 +1694,16 @@ percent - - + + - + - + purchase @@ -1372,8 +1712,8 @@ percent - - + + @@ -1384,15 +1724,79 @@ purchase - + + + IVA 21% Inversión del sujeto pasivo + IVA 21% Inversión del sujeto pasivo + + percent + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (1) + + + percent + + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (2) + + + percent + + + + + + + + + + + purchase + + + + IVA 21% Inversión del sujeto pasivo (3) + + + percent + + + + + + + + + + + purchase + + + IVA 4% percent - - + + @@ -1403,14 +1807,14 @@ sale - + IVA 7% percent - - + + @@ -1421,14 +1825,14 @@ sale - + IVA 8% percent - - + + @@ -1439,14 +1843,32 @@ sale - + + + + IVA 10% + + percent + + + + + + + + + + + sale + + IVA 16% percent - - + + @@ -1457,14 +1879,14 @@ sale - + IVA 18% percent - - + + @@ -1474,17 +1896,36 @@ sale + - - + + + + IVA 21% + + percent + + + + + + + + + + + sale + + + - 0.50% Recargo Equivalencia + 0.50% Recargo Equivalencia Ventas percent - - + + @@ -1495,14 +1936,14 @@ sale - + - 1% Recargo Equivalencia + 1% Recargo Equivalencia Ventas percent - - + + @@ -1513,14 +1954,32 @@ sale - + + + + 1.4% Recargo Equivalencia Ventas + + percent + + + + + + + + + + + sale + + - 4% Recargo Equivalencia + 4% Recargo Equivalencia Ventas percent - - + + @@ -1531,10 +1990,117 @@ sale - - + + + + 5.2% Recargo Equivalencia Ventas + + percent + + + + + + + + + + + sale + + + + 0.50% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 1% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 1.4% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 4% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + + + 5.2% Recargo Equivalencia Compras + + percent + + + + + + + + + + + purchase + + + - + @@ -1548,365 +2114,9 @@ sale - - + + - - - IVA 16% Intracomunitario. Bienes corrientes - IVA 16% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 16% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 16% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes corrientes - IVA 18% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 18% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - - purchase - - - - - - - IVA 16% Intracomunitario. Bienes de inversión - IVA 16% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 16% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 16% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes de inversión - IVA 18% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 18% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 18% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes corrientes - IVA 7% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 7% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes de inversión - IVA 7% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 7% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 7% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes corrientes - IVA 8% Intracomunitario. Bienes corrientes - - percent - - purchase - - - - - IVA 8% Intracomunitario. Bienes corrientes (1) - - percent - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes corrientes (2) - - percent - - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes de inversión - IVA 8% Intracomunitario. Bienes de inversión - - percent - - purchase - - - - - IVA 8% Intracomunitario. Bienes de inversión (1) - - percent - - - - - - - - - purchase - - - - - IVA 8% Intracomunitario. Bienes de inversión (2) - - percent - - - - - - - - - - purchase - @@ -1923,8 +2133,8 @@ IVA 4% Intracomunitario. Bienes corrientes (1) percent - - + + @@ -1939,8 +2149,8 @@ IVA 4% Intracomunitario. Bienes corrientes (2) percent - - + + @@ -1966,8 +2176,8 @@ IVA 4% Intracomunitario. Bienes de inversión (1) percent - - + + @@ -1982,8 +2192,8 @@ IVA 4% Intracomunitario. Bienes de inversión (2) percent - - + + @@ -1993,7 +2203,539 @@ purchase - + + + IVA 7% Intracomunitario. Bienes corrientes + IVA 7% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 7% Intracomunitario. Bienes de inversión + IVA 7% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + + IVA 7% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + + IVA 7% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes + IVA 8% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión + IVA 8% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 8% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes + IVA 10% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión + IVA 10% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 10% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes + IVA 16% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión + IVA 16% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 16% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes + IVA 18% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + + + IVA 18% Intracomunitario. Bienes de inversión + IVA 18% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 18% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + + + + + IVA 21% Intracomunitario. Bienes corrientes + IVA 21% Intracomunitario. Bienes corrientes + + percent + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes (1) + + percent + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes corrientes (2) + + percent + + + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión + IVA 21% Intracomunitario. Bienes de inversión + + percent + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión (1) + + percent + + + + + + + + + purchase + + + + + IVA 21% Intracomunitario. Bienes de inversión (2) + + percent + + + + + + + + + + purchase + + - + - + IRPF Retenciones practicadas Base Imponible @@ -2011,56 +2753,70 @@ 1.0 - + IRPF Retenciones practicadas Base Imponible 1% B.IRPF1 1.0 - + IRPF Retenciones practicadas Base Imponible 2% B.IRPF2 1.0 - + IRPF Retenciones practicadas Base Imponible 7% B.IRPF7 1.0 - + + + IRPF Retenciones practicadas Base Imponible 9% + B.IRPF9 + + 1.0 + + IRPF Retenciones practicadas Base Imponible 15% B.IRPF15 1.0 - + IRPF Retenciones practicadas Base Imponible 18% B.IRPF18 1.0 - + IRPF Retenciones practicadas Base Imponible 19% B.IRPF19 1.0 - + + + IRPF Retenciones practicadas Base Imponible 20% + B.IRPF20 + + 1.0 + + IRPF Retenciones practicadas Base Imponible 21% B.IRPF21 1.0 - + IRPF Retenciones practicadas Total Cuota @@ -2068,56 +2824,70 @@ 1.0 - + IRPF Retenciones practicadas Cuota 1% IRPF1 1.0 - + IRPF Retenciones practicadas Cuota 2% IRPF2 1.0 - + IRPF Retenciones practicadas Cuota 7% IRPF7 1.0 - + + + IRPF Retenciones practicadas Cuota 9% + IRPF9 + + 1.0 + + IRPF Retenciones practicadas Cuota 15% IRPF15 1.0 - + IRPF Retenciones practicadas Cuota 18% IRPF18 1.0 - + IRPF Retenciones practicadas Cuota 19% IRPF19 1.0 - + + + IRPF Retenciones practicadas Cuota 20% + IRPF20 + + 1.0 + + IRPF Retenciones practicadas Cuota 21% IRPF21 1.0 - + 475101 @@ -2127,7 +2897,7 @@ Hacienda Pública. Retenciones empresarios módulos 1% - + 475102 @@ -2136,7 +2906,7 @@ Hacienda Pública. Retenciones act. agrícolas, ganaderas, forestales 2% - + 475107 @@ -2145,7 +2915,16 @@ Hacienda Pública. Retenciones act. profesionales 7% - + + + 475109 + + + other + Hacienda Pública. Retenciones act. profesionales 9% + + + 475115 @@ -2154,7 +2933,7 @@ Hacienda Pública. Retenciones act. profesionales 15% - + 475118 @@ -2163,7 +2942,7 @@ Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 18% - + 475119 @@ -2172,7 +2951,16 @@ Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 19% - + + + 475120 + + + other + Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 20% + + + 475121 @@ -2181,7 +2969,7 @@ Hacienda Pública. Retenciones arrendamientos, cap. mobiliario 21% - + @@ -2200,7 +2988,7 @@ purchase - + Retenciones IRPF 2% @@ -2218,7 +3006,7 @@ purchase - + Retenciones IRPF 7% @@ -2236,7 +3024,25 @@ purchase - + + + + Retenciones IRPF 9% + + percent + + + + + + + + + + + purchase + + Retenciones IRPF 15% @@ -2254,7 +3060,7 @@ purchase - + Retenciones IRPF 18% @@ -2272,7 +3078,7 @@ purchase - + Retenciones IRPF 19% @@ -2291,6 +3097,24 @@ purchase + + + Retenciones IRPF 20% + + percent + + + + + + + + + + + purchase + + Retenciones IRPF 21% @@ -2308,9 +3132,9 @@ purchase - + - + IRPF Retenciones a cuenta Base Imponible @@ -2318,56 +3142,70 @@ 1.0 - + IRPF Retenciones a cuenta Base Imponible 1% B.IRPF1 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 2% B.IRPF2 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 7% B.IRPF7 AC 1.0 - + + + IRPF Retenciones a cuenta Base Imponible 9% + B.IRPF9 AC + + 1.0 + + IRPF Retenciones a cuenta Base Imponible 15% B.IRPF15 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 18% B.IRPF18 AC 1.0 - + IRPF Retenciones a cuenta Base Imponible 19% B.IRPF19 AC 1.0 - + + + IRPF Retenciones a cuenta Base Imponible 20% + B.IRPF20 AC + + 1.0 + + IRPF Retenciones a cuenta Base Imponible 21% B.IRPF21 AC 1.0 - + IRPF Retenciones a cuenta Total Cuota @@ -2375,56 +3213,70 @@ 1.0 - + IRPF Retenciones a cuenta Cuota 1% IRPF1 AC 1.0 - + IRPF Retenciones a cuenta Cuota 2% IRPF2 AC 1.0 - + IRPF Retenciones a cuenta Cuota 7% IRPF7 AC 1.0 - + + + IRPF Retenciones a cuenta Cuota 9% + IRPF9 AC + + 1.0 + + IRPF Retenciones a cuenta Cuota 15% IRPF15 AC 1.0 - + IRPF Retenciones a cuenta Cuota 18% IRPF18 AC 1.0 - + IRPF Retenciones a cuenta Cuota 19% IRPF19 AC 1.0 - + + + IRPF Retenciones a cuenta Cuota 20% + IRPF20 AC + + 1.0 + + IRPF Retenciones a cuenta Cuota 21% IRPF21 AC 1.0 - + 473001 @@ -2434,7 +3286,7 @@ Hacienda Pública. Retenciones a cuenta empresarios módulos 1% - + 473002 @@ -2443,7 +3295,7 @@ Hacienda Pública. Retenciones a cuenta act. agrícolas, ganaderas, forestales 2% - + 473007 @@ -2452,7 +3304,16 @@ Hacienda Pública. Retenciones a cuenta act. profesionales 7% - + + + 473009 + + + other + Hacienda Pública. Retenciones a cuenta act. profesionales 9% + + + 473015 @@ -2461,7 +3322,7 @@ Hacienda Pública. Retenciones a cuenta act. profesionales 15% - + 473018 @@ -2470,7 +3331,7 @@ Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 18% - + 473019 @@ -2479,7 +3340,16 @@ Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 19% - + + + 473020 + + + other + Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 20% + + + 473021 @@ -2488,7 +3358,7 @@ Hacienda Pública. Retenciones a cuenta arrendamientos, cap. mobiliario 21% - + @@ -2507,7 +3377,7 @@ sale - + Retenciones a cuenta IRPF 2% @@ -2525,7 +3395,7 @@ sale - + Retenciones a cuenta IRPF 7% @@ -2543,7 +3413,25 @@ sale - + + + + Retenciones a cuenta IRPF 9% + + percent + + + + + + + + + + + sale + + Retenciones a cuenta IRPF 15% @@ -2561,7 +3449,7 @@ sale - + Retenciones a cuenta IRPF 18% @@ -2579,7 +3467,7 @@ sale - + Retenciones a cuenta IRPF 19% @@ -2597,7 +3485,25 @@ sale - + + + + Retenciones a cuenta IRPF 20% + + percent + + + + + + + + + + + sale + + Retenciones a cuenta IRPF 21% diff --git a/addons/l10n_fr/__init__.py b/addons/l10n_fr/__init__.py index 8d5728e334e..592068eedda 100644 --- a/addons/l10n_fr/__init__.py +++ b/addons/l10n_fr/__init__.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_fr/__openerp__.py b/addons/l10n_fr/__openerp__.py index e1d4b9ac334..9a563eeb197 100644 --- a/addons/l10n_fr/__openerp__.py +++ b/addons/l10n_fr/__openerp__.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## { diff --git a/addons/l10n_fr/l10n_fr.py b/addons/l10n_fr/l10n_fr.py index c995b44a614..676121b4292 100644 --- a/addons/l10n_fr/l10n_fr.py +++ b/addons/l10n_fr/l10n_fr.py @@ -33,7 +33,6 @@ class l10n_fr_report(osv.osv): ('code_uniq', 'unique (code)','The code report must be unique !') ] -l10n_fr_report() class l10n_fr_line(osv.osv): _name = 'l10n.fr.line' @@ -48,7 +47,6 @@ class l10n_fr_line(osv.osv): ('code_uniq', 'unique (code)', 'The variable name must be unique !') ] -l10n_fr_line() class res_company(osv.osv): _inherit = 'res.company' @@ -58,6 +56,5 @@ class res_company(osv.osv): 'ape': fields.char('APE', size=64), } -res_company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr/l10n_fr_view.xml b/addons/l10n_fr/l10n_fr_view.xml old mode 100755 new mode 100644 diff --git a/addons/l10n_fr/report/__init__.py b/addons/l10n_fr/report/__init__.py index 9907a2f5765..c73179a9023 100644 --- a/addons/l10n_fr/report/__init__.py +++ b/addons/l10n_fr/report/__init__.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_fr/report/base_report.py b/addons/l10n_fr/report/base_report.py index 39a18bc7ca4..bc2cd308bf8 100644 --- a/addons/l10n_fr/report/base_report.py +++ b/addons/l10n_fr/report/base_report.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_fr/report/bilan_report.py b/addons/l10n_fr/report/bilan_report.py index a7947434da0..2ffbd24cc4f 100644 --- a/addons/l10n_fr/report/bilan_report.py +++ b/addons/l10n_fr/report/bilan_report.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_fr/report/compute_resultant_report.py b/addons/l10n_fr/report/compute_resultant_report.py index 9a1809fd7cc..5eb62d7e82d 100644 --- a/addons/l10n_fr/report/compute_resultant_report.py +++ b/addons/l10n_fr/report/compute_resultant_report.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_fr/test/l10n_fr_report.yml b/addons/l10n_fr/test/l10n_fr_report.yml index 44db53d0a77..25de74dd313 100644 --- a/addons/l10n_fr/test/l10n_fr_report.yml +++ b/addons/l10n_fr/test/l10n_fr_report.yml @@ -3,8 +3,9 @@ - !python {model: account.move.line}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.l10n.fr.bilan').create(cr, uid, [], {'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [], 'l10n.fr.bilan', {'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'l10n_fr-bilan_report.'+format), 'wb+').write(data) @@ -13,7 +14,8 @@ - !python {model: account.move.line}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.l10n.fr.compute_resultant').create(cr, uid, [], {'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [], 'l10n.fr.compute_resultant', {'model':'account.move.line', 'form':{'fiscalyear_id': ref('account.data_fiscalyear')}}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'l10n_fr-compute_resultant_report.'+format), 'wb+').write(data) diff --git a/addons/l10n_fr/wizard/__init__.py b/addons/l10n_fr/wizard/__init__.py index 6e29471a975..1bbaf351ea4 100644 --- a/addons/l10n_fr/wizard/__init__.py +++ b/addons/l10n_fr/wizard/__init__.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_fr/wizard/fr_report_bilan.py b/addons/l10n_fr/wizard/fr_report_bilan.py index 90e97389eed..e7ae542fa3f 100644 --- a/addons/l10n_fr/wizard/fr_report_bilan.py +++ b/addons/l10n_fr/wizard/fr_report_bilan.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## @@ -52,6 +52,5 @@ class account_bilan_report(osv.osv_memory): data['form']['fiscalyear_id'] = self.browse(cr, uid, ids)[0].fiscalyear_id.id return {'type': 'ir.actions.report.xml', 'report_name': 'l10n.fr.bilan', 'datas': data} -account_bilan_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr/wizard/fr_report_compute_resultant.py b/addons/l10n_fr/wizard/fr_report_compute_resultant.py index eff52189bc9..c83f7494d4a 100644 --- a/addons/l10n_fr/wizard/fr_report_compute_resultant.py +++ b/addons/l10n_fr/wizard/fr_report_compute_resultant.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## @@ -52,6 +52,5 @@ class account_cdr_report(osv.osv_memory): data['form']['fiscalyear_id'] = self.browse(cr, uid, ids)[0].fiscalyear_id.id return { 'type': 'ir.actions.report.xml', 'report_name': 'l10n.fr.compute_resultant', 'datas': data} -account_cdr_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr_hr_payroll/__init__.py b/addons/l10n_fr_hr_payroll/__init__.py old mode 100755 new mode 100644 diff --git a/addons/l10n_fr_hr_payroll/__openerp__.py b/addons/l10n_fr_hr_payroll/__openerp__.py old mode 100755 new mode 100644 diff --git a/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll.py b/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll.py index 0519fd86a47..ec17792dacd 100644 --- a/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll.py +++ b/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll.py @@ -34,7 +34,6 @@ class res_company(osv.osv): 'conv_coll': fields.char('Convention collective', size=64), } -res_company() class hr_contract(osv.osv): _inherit = 'hr.contract' @@ -44,7 +43,6 @@ class hr_contract(osv.osv): 'niveau': fields.char('Niveau', size=64), 'coef': fields.char('Coefficient', size=64), } -hr_contract() class hr_payslip(osv.osv): _inherit = 'hr.payslip' @@ -52,6 +50,5 @@ class hr_payslip(osv.osv): _columns = { 'payment_mode': fields.char('Mode de paiement', size=64), } -hr_payslip() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll_data.xml b/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll_data.xml old mode 100755 new mode 100644 diff --git a/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll_view.xml b/addons/l10n_fr_hr_payroll/l10n_fr_hr_payroll_view.xml old mode 100755 new mode 100644 diff --git a/addons/l10n_fr_hr_payroll/report/__init__.py b/addons/l10n_fr_hr_payroll/report/__init__.py index 40d2ccc3c05..d6c9481579e 100644 --- a/addons/l10n_fr_hr_payroll/report/__init__.py +++ b/addons/l10n_fr_hr_payroll/report/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################################################## diff --git a/addons/l10n_fr_rib/bank.py b/addons/l10n_fr_rib/bank.py index 8ad86932a34..1f5264ef5ac 100644 --- a/addons/l10n_fr_rib/bank.py +++ b/addons/l10n_fr_rib/bank.py @@ -19,7 +19,6 @@ # ############################################################################## -from openerp import netsvc from openerp.osv import fields, osv from openerp.tools.translate import _ @@ -81,7 +80,6 @@ class res_partner_bank(osv.osv): _constraints = [(_check_key, 'The RIB and/or IBAN is not valid', ['rib_acc_number', 'bank_code', 'office', 'key'])] -res_partner_bank() class res_bank(osv.osv): """Add the bank code to make it easier to enter RIB data""" @@ -103,6 +101,5 @@ class res_bank(osv.osv): _columns = { 'rib_code': fields.char('RIB Bank Code', size=64), } -res_bank() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_hr/l10n_hr_chart_template.xml b/addons/l10n_hr/l10n_hr_chart_template.xml old mode 100755 new mode 100644 diff --git a/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py b/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py index 6a7638d919a..348bb71c95e 100644 --- a/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py +++ b/addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py @@ -48,7 +48,6 @@ class hr_contract(osv.osv): 'supplementary_allowance': fields.float('Supplementary Allowance', digits_compute=dp.get_precision('Payroll')), } -hr_contract() class payroll_advice(osv.osv): ''' @@ -157,7 +156,6 @@ class payroll_advice(osv.osv): return { 'value':res } -payroll_advice() class hr_payslip_run(osv.osv): @@ -216,7 +214,6 @@ class hr_payslip_run(osv.osv): advice_line_pool.create(cr, uid, advice_line, context=context) return self.write(cr, uid, ids, {'available_advice' : True}) -hr_payslip_run() class payroll_advice_line(osv.osv): ''' @@ -247,7 +244,6 @@ class payroll_advice_line(osv.osv): 'debit_credit': 'C', } -payroll_advice_line() class hr_payslip(osv.osv): ''' @@ -265,7 +261,6 @@ class hr_payslip(osv.osv): default.update({'advice_id' : False}) return super(hr_payslip, self).copy(cr, uid, id, default, context=context) -hr_payslip() class res_company(osv.osv): @@ -277,6 +272,5 @@ class res_company(osv.osv): 'dearness_allowance': True, } -res_company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_in_hr_payroll/report/__init__.py b/addons/l10n_in_hr_payroll/report/__init__.py index 8a20170c384..e76f45b69c0 100644 --- a/addons/l10n_in_hr_payroll/report/__init__.py +++ b/addons/l10n_in_hr_payroll/report/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python #-*- coding:utf-8 -*- ############################################################################## diff --git a/addons/l10n_in_hr_payroll/report/payment_advice_report.py b/addons/l10n_in_hr_payroll/report/payment_advice_report.py index 59456b13b55..32c589d2a90 100644 --- a/addons/l10n_in_hr_payroll/report/payment_advice_report.py +++ b/addons/l10n_in_hr_payroll/report/payment_advice_report.py @@ -82,6 +82,5 @@ class payment_advice_report(osv.osv): l.employee_id,l.advice_id,l.bysal,l.ifsc_code, l.name ) """) -payment_advice_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_in_hr_payroll/report/payslip_report.py b/addons/l10n_in_hr_payroll/report/payslip_report.py index b44f123547b..2e1a543a80a 100644 --- a/addons/l10n_in_hr_payroll/report/payslip_report.py +++ b/addons/l10n_in_hr_payroll/report/payslip_report.py @@ -83,6 +83,5 @@ class payslip_report(osv.osv): l.employee_id,p.struct_id,l.category_id ) """) -payslip_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_in_hr_payroll/test/payment_advice.yml b/addons/l10n_in_hr_payroll/test/payment_advice.yml index ff391dd5363..0b4b16a629c 100644 --- a/addons/l10n_in_hr_payroll/test/payment_advice.yml +++ b/addons/l10n_in_hr_payroll/test/payment_advice.yml @@ -36,7 +36,8 @@ - !python {model: hr.payroll.advice}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.payroll.advice').create(cr, uid, [ref('l10n_in_hr_payroll.payment_advice_1')], {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('l10n_in_hr_payroll.payment_advice_1')], 'payroll.advice', {}, {}) if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], 'l10n_in_hr_payroll_summary report'+format), 'wb+').write(data) \ No newline at end of file + file(os.path.join(tools.config['test_report_directory'], 'l10n_in_hr_payroll_summary report'+format), 'wb+').write(data) diff --git a/addons/l10n_in_hr_payroll/wizard/hr_salary_employee_bymonth.py b/addons/l10n_in_hr_payroll/wizard/hr_salary_employee_bymonth.py index 62d332ea5b8..93594e1dff8 100644 --- a/addons/l10n_in_hr_payroll/wizard/hr_salary_employee_bymonth.py +++ b/addons/l10n_in_hr_payroll/wizard/hr_salary_employee_bymonth.py @@ -66,6 +66,5 @@ class hr_salary_employee_bymonth(osv.osv_memory): 'datas': datas, } -hr_salary_employee_bymonth() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/l10n_in_hr_payroll/wizard/hr_yearly_salary_detail.py b/addons/l10n_in_hr_payroll/wizard/hr_yearly_salary_detail.py index ed2a02e8d42..de3680f2dd3 100644 --- a/addons/l10n_in_hr_payroll/wizard/hr_yearly_salary_detail.py +++ b/addons/l10n_in_hr_payroll/wizard/hr_yearly_salary_detail.py @@ -61,6 +61,5 @@ class yearly_salary_detail(osv.osv_memory): 'datas': datas, } -yearly_salary_detail() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_lu/test/l10n_lu_report.yml b/addons/l10n_lu/test/l10n_lu_report.yml index cacb3015ab2..0ee032d581c 100644 --- a/addons/l10n_lu/test/l10n_lu_report.yml +++ b/addons/l10n_lu/test/l10n_lu_report.yml @@ -9,8 +9,9 @@ - !python {model: res.partner}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.l10n_lu.tax.report.print').create(cr, uid, [], {'model':'ir.ui.menu', 'form':{'tax_code_id': ref('account_tax_code_id_r1'), 'period_id': ref('account.period_1')}}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [], 'l10n_lu.tax.report.print', {'model':'ir.ui.menu', 'form':{'tax_code_id': ref('account_tax_code_id_r1'), 'period_id': ref('account.period_1')}}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'l10n_lu-vat_report.'+format), 'wb+').write(data) diff --git a/addons/l10n_lu/wizard/print_vat.py b/addons/l10n_lu/wizard/print_vat.py index 9e1190cfae5..bfa058720d3 100644 --- a/addons/l10n_lu/wizard/print_vat.py +++ b/addons/l10n_lu/wizard/print_vat.py @@ -5,13 +5,14 @@ #Tranquil IT Systems from __future__ import with_statement + +import openerp from openerp.osv import fields, osv -from openerp import pooler from openerp import tools +from openerp.modules.module import get_module_resource from openerp.tools.translate import _ from openerp.report.render import render from openerp.report.interface import report_int -from openerp import addons import tempfile import os @@ -30,8 +31,8 @@ class report_custom(report_int): def create(self, cr, uid, ids, datas, context=None): - pool = pooler.get_pool(cr.dbname) - taxobj = pool.get('account.tax.code') + registry = openerp.registry(cr.dbname) + taxobj = registry['account.tax.code'] if context is None: context = {} @@ -40,7 +41,7 @@ class report_custom(report_int): for t in taxobj.browse(cr, uid, code_ids, {'period_id': datas['form']['period_id']}): if str(t.code): result['case_'+str(t.code)] = '%.2f' % (t.sum_period or 0.0, ) - user = pool.get('res.users').browse(cr, uid, uid, context) + user = registry['res.users'].browse(cr, uid, uid, context) # Not Clean, to be changed partner = user.company_id.partner_id @@ -52,7 +53,7 @@ class report_custom(report_int): try: tmp_file = tempfile.mkstemp(".pdf")[1] try: - tools.pdf_utils.fill_pdf(addons.get_module_resource('l10n_lu','wizard', '2008_DECL_F_M10.pdf'), tmp_file, result) + tools.pdf_utils.fill_pdf(get_module_resource('l10n_lu','wizard', '2008_DECL_F_M10.pdf'), tmp_file, result) with open(tmp_file, "r") as ofile: self.obj = external_pdf(ofile.read()) finally: @@ -91,6 +92,5 @@ class vat_declaration_report(osv.osv_memory): data['form']['period_id'] = self.browse(cr, uid, ids)[0].period_id.id return { 'type': 'ir.actions.report.xml', 'report_name': 'l10n_lu.tax.report.print', 'datas': data} -vat_declaration_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_ma/l10n_ma.py b/addons/l10n_ma/l10n_ma.py index 6321516cf0f..a2a28a21f82 100644 --- a/addons/l10n_ma/l10n_ma.py +++ b/addons/l10n_ma/l10n_ma.py @@ -33,7 +33,6 @@ class l10n_ma_report(osv.osv): _sql_constraints = [ ('code_uniq', 'unique (code)','The code report must be unique !') ] -l10n_ma_report() class l10n_ma_line(osv.osv): _name = 'l10n.ma.line' @@ -47,6 +46,5 @@ class l10n_ma_line(osv.osv): _sql_constraints = [ ('code_uniq', 'unique (code)', 'The variable name must be unique !') ] -l10n_ma_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_multilang/account.py b/addons/l10n_multilang/account.py index 4cb0e28b672..55770c5ec14 100644 --- a/addons/l10n_multilang/account.py +++ b/addons/l10n_multilang/account.py @@ -31,21 +31,18 @@ class account_account_template(osv.osv): _columns = { 'name': fields.char('Name', size=128, required=True, select=True, translate=True), } -account_account_template() class account_account(osv.osv): _inherit = 'account.account' _columns = { 'name': fields.char('Name', size=128, required=True, select=True, translate=True), } -account_account() class account_tax(osv.osv): _inherit = 'account.tax' _columns = { 'name': fields.char('Tax Name', size=128, required=True, select=True, translate=True), } -account_tax() class account_tax_template(osv.osv): @@ -53,7 +50,6 @@ class account_tax_template(osv.osv): _columns = { 'name': fields.char('Tax Name', size=128, required=True, select=True, translate=True), } -account_tax_template() class account_tax_code_template(osv.osv): @@ -61,7 +57,6 @@ class account_tax_code_template(osv.osv): _columns = { 'name': fields.char('Tax Case Name', size=64, required=True, translate=True), } -account_tax_code_template() class account_chart_template(osv.osv): @@ -71,7 +66,6 @@ class account_chart_template(osv.osv): 'spoken_languages': fields.char('Spoken Languages', size=64, help="State here the languages for which the translations of templates could be loaded at the time of installation of this localization module and copied in the final object when generating them from templates. You must provide the language codes separated by ';'"), } _order = 'name' -account_chart_template() class account_fiscal_position(osv.osv): @@ -79,7 +73,6 @@ class account_fiscal_position(osv.osv): _columns = { 'name': fields.char('Fiscal Position', size=64, required=True, translate=True), } -account_fiscal_position() class account_fiscal_position_template(osv.osv): @@ -87,7 +80,6 @@ class account_fiscal_position_template(osv.osv): _columns = { 'name': fields.char('Fiscal Position Template', size=64, required=True, translate=True), } -account_fiscal_position_template() class account_journal(osv.osv): @@ -95,7 +87,6 @@ class account_journal(osv.osv): _columns = { 'name': fields.char('Journal Name', size=64, required=True, translate=True), } -account_journal() class account_analytic_account(osv.osv): @@ -103,7 +94,6 @@ class account_analytic_account(osv.osv): _columns = { 'name': fields.char('Account Name', size=128, required=True, translate=True), } -account_analytic_account() class account_analytic_journal(osv.osv): @@ -111,4 +101,3 @@ class account_analytic_journal(osv.osv): _columns = { 'name': fields.char('Journal Name', size=64, required=True, translate=True), } -account_analytic_journal() diff --git a/addons/l10n_multilang/l10n_multilang.py b/addons/l10n_multilang/l10n_multilang.py index 9596b292ff3..b7564a9960a 100644 --- a/addons/l10n_multilang/l10n_multilang.py +++ b/addons/l10n_multilang/l10n_multilang.py @@ -78,7 +78,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): else: #replace the value in the destination object only if it's the user lang if context.get('lang') == lang: - self.pool.get(out_obj._name).write(cr, uid, out_ids[j], {in_field: value[in_id]}) + self.pool[out_obj._name].write(cr, uid, out_ids[j], {in_field: value[in_id]}) else: _logger.info('Language: %s. Translation from template: there is no translation available for %s!' %(lang, src[in_id]))#out_obj._name)) return True @@ -150,6 +150,5 @@ class wizard_multi_charts_accounts(osv.osv_memory): out_ids = obj_fiscal_position.search(cr, uid, [('company_id', '=', company_id)], order='id') return self.process_translations(cr, uid, langs, obj_fiscal_position_template, field, in_ids, obj_fiscal_position, out_ids, force_write=False, context=context) -wizard_multi_charts_accounts() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_nl/__init__.py b/addons/l10n_nl/__init__.py index 57a3bb10df3..ee9f0292f12 100644 --- a/addons/l10n_nl/__init__.py +++ b/addons/l10n_nl/__init__.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_nl/__openerp__.py b/addons/l10n_nl/__openerp__.py index 5e811511c01..aec85016ea5 100644 --- a/addons/l10n_nl/__openerp__.py +++ b/addons/l10n_nl/__openerp__.py @@ -22,7 +22,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## # diff --git a/addons/l10n_nl/account_chart_netherlands.xml b/addons/l10n_nl/account_chart_netherlands.xml index 516c88bdcf9..c7eefb42cde 100644 --- a/addons/l10n_nl/account_chart_netherlands.xml +++ b/addons/l10n_nl/account_chart_netherlands.xml @@ -3940,7 +3940,7 @@ 2a - Leveringen/diensten waarbij de heffing van omzetbelasting naar u is verlegd (BTW) + Heffing van omzetbelasting is naar u verlegd (BTW) @@ -4052,7 +4052,7 @@ 2a - Leveringen/diensten waarbij de heffing van omzetbelasting naar u is verlegd (omzet) + Heffing van omzetbelasting is naar u verlegd (omzet) @@ -4260,7 +4260,7 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge - purchase + sale 15 @@ -4279,9 +4279,9 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge - 99 + 98 - BTW af te dragen verlegd (inkopen1) + BTW te vorderen verlegd (inkopen1) percent @@ -4304,54 +4304,8 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + - - purchase - - - 15 - - BTW te vorderen verlegd (inkopen) - 21% BTW verlegd - - percent - - - - - - - purchase - - - - 99 - - BTW te vorderen verlegd (inkopen1) - - percent - - - - - - - - purchase - - - 99 - - BTW te vorderen verlegd (inkopen2) - - percent - - - - - - - purchase @@ -4402,6 +4356,7 @@ TODO rubriek 1c en 1d moeten nog, zijn variabel, dus BTW percentage moet door ge + 20 Inkopen import binnen EU hoog 21% BTW import binnen EU diff --git a/addons/l10n_nl/account_fiscal_position_tax_template.xml b/addons/l10n_nl/account_fiscal_position_tax_template.xml index 622ffafa67c..9fe9a3df786 100644 --- a/addons/l10n_nl/account_fiscal_position_tax_template.xml +++ b/addons/l10n_nl/account_fiscal_position_tax_template.xml @@ -90,6 +90,13 @@ + + + + + + + diff --git a/addons/l10n_nl/account_fiscal_position_template.xml b/addons/l10n_nl/account_fiscal_position_template.xml index fe658c6d4b7..1c69f2d1198 100644 --- a/addons/l10n_nl/account_fiscal_position_template.xml +++ b/addons/l10n_nl/account_fiscal_position_template.xml @@ -7,6 +7,10 @@ Binnenland + + BTW verlegd + + EU landen diff --git a/addons/l10n_pa/__init__.py b/addons/l10n_pa/__init__.py index 92da5dbf966..25e7e337165 100644 --- a/addons/l10n_pa/__init__.py +++ b/addons/l10n_pa/__init__.py @@ -23,7 +23,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_pe/__init__.py b/addons/l10n_pe/__init__.py index 92da5dbf966..25e7e337165 100644 --- a/addons/l10n_pe/__init__.py +++ b/addons/l10n_pe/__init__.py @@ -23,7 +23,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/l10n_ro/partner_view.xml b/addons/l10n_ro/partner_view.xml index c03d5c9a1a6..102ba3d92f0 100644 --- a/addons/l10n_ro/partner_view.xml +++ b/addons/l10n_ro/partner_view.xml @@ -7,7 +7,6 @@ res.partner - diff --git a/addons/l10n_ro/res_partner.py b/addons/l10n_ro/res_partner.py old mode 100755 new mode 100644 index 1cfe7390a77..79933dc468e --- a/addons/l10n_ro/res_partner.py +++ b/addons/l10n_ro/res_partner.py @@ -1,4 +1,3 @@ - # -*- encoding: utf-8 -*- ############################################################################## # @@ -28,10 +27,32 @@ class res_partner(osv.osv): _columns = { 'nrc' : fields.char('NRC', size=16, help='Registration number at the Registry of Commerce'), } + + # The SQL constraints are no-ops but present only to display the right error message to the + # user when the partial unique indexes defined below raise errors/ + # The real constraints need to be implemented with PARTIAL UNIQUE INDEXES (see auto_init), + # due to the way accounting data is delegated by contacts to their companies in OpenERP 7.0. _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 !') + ('vat_uniq', 'unique (id)', 'The vat of the partner must be unique !'), + ('nrc_uniq', 'unique (id)', 'The code of the partner must be unique !') ] -res_partner() + + def _auto_init(self, cr, context=None): + result = super(res_partner, self)._auto_init(cr, context=context) + # Real implementation of the vat/nrc constraints: only "commercial entities" need to have + # unique numbers, and the condition for being a commercial entity is "is_company or parent_id IS NULL". + # Contacts inside a company automatically have a copy of the company's commercial fields + # (see _commercial_fields()), so they are automatically consistent. + cr.execute(""" + DROP INDEX IF EXISTS res_partner_vat_uniq_for_companies; + DROP INDEX IF EXISTS res_partner_nrc_uniq_for_companies; + CREATE UNIQUE INDEX res_partner_vat_uniq_for_companies ON res_partner (vat) WHERE is_company OR parent_id IS NULL; + CREATE UNIQUE INDEX res_partner_nrc_uniq_for_companies ON res_partner (nrc) WHERE is_company OR parent_id IS NULL; + """) + return result + + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['nrc'] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_vn/__init__.py b/addons/l10n_vn/__init__.py new file mode 100644 index 00000000000..4b18956216e --- /dev/null +++ b/addons/l10n_vn/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module is Copyright (c) 2009-2013 General Solutions (http://gscom.vn) 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 . +# +############################################################################## + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_vn/__openerp__.py b/addons/l10n_vn/__openerp__.py new file mode 100644 index 00000000000..19b81654523 --- /dev/null +++ b/addons/l10n_vn/__openerp__.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module is Copyright (c) 2009-2013 General Solutions (http://gscom.vn) 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 . +# +############################################################################## + +{ + "name" : "Vietnam Chart of Accounts", + "version" : "1.0", + "author" : "General Solutions", + 'website': 'http://gscom.vn', + "category" : "Localization/Account Charts", + "description": """ +This is the module to manage the accounting chart for Vietnam in OpenERP. +======================================================================== + +This module applies to companies based in Vietnamese Accounting Standard (VAS). + +**Credits:** General Solutions. +""", + "depends" : ["account","base_vat","base_iban"], + "data" : ["account_tax_code.xml","account_chart.xml","account_tax.xml","l10n_vn_wizard.xml"], + "demo" : [], + 'auto_install': False, + "installable": True, +} + diff --git a/addons/l10n_vn/account_chart.xml b/addons/l10n_vn/account_chart.xml new file mode 100755 index 00000000000..c7d3f6a9ee3 --- /dev/null +++ b/addons/l10n_vn/account_chart.xml @@ -0,0 +1,2022 @@ + + + + + + + + 1. TÀI SẢN NGẮN HẠN + current_asset + balance + asset + + + + 1. TÀI SẢN NGẮN HẠN - REC + current_asset + unreconciled + asset + + + + 2. TÀI SẢN DÀI HẠN + long_term_asset + balance + asset + + + + 3. NỢ PHẢI TRẢ + liability + unreconciled + liability + + + + 4. VỐN CHỦ SỞ HỮU + equity + balance + asset + + + + 5. DOANH THU + income + none + income + + + + 6. CHI PHÍ SẢN XUẤT, KINH DOANH + expense + none + expense + + + + 7. THU NHẬP KHÁC + other_income + none + income + + + + 8. CHI PHÍ KHÁC + other_expense + none + expense + + + + 9. XÁC ĐỊNH KẾT QUẢ KINH DOANH + evaluation + none + + + + X. TÀI KHOẢN NGOÀI BẢNG + other + none + + + + CHỈ XEM + view + none + + + + + + + + 0 + Hệ thống tài khoản kế toán Việt Nam + view + + + + + + 1 + TÀI SẢN NGẮN HẠN + view + + + + + + 111 + + view + + + Tiền mặt + + + 1111 + + liquidity + + + Tiền Việt Nam + + + 1112 + + other + + + Ngoại tệ + + + 1113 + + other + + + Vàng bạc, kim khí quý, đá quý + + + + 112 + + view + + + Tiền gửi ngân hàng + + + 1121 + + liquidity + + + Tiền Việt Nam + + + 1122 + + other + + + Ngoại tệ + + + 1123 + + other + + + Vàng bạc, kim khí quý, đá quý + + + + 113 + + view + + + Tiền đang chuyển + + + 1131 + + other + + + Tiền Việt Nam + + + 1132 + + other + + + Ngoại tệ + + + + 121 + + view + + + Đầu tư tài chính ngắn hạn + + + 1211 + + other + + + Cổ phiếu + + + 1212 + + other + + + Trái phiếu, Tín phiếu, Kỳ phiếu + + + + 128 + + view + + + Đầu tư ngắn hạn khác + + + 1281 + + other + + + Tiền gửi có kỳ hạn + + + 1282 + + other + + + Đầu tư ngắn hạn khác + + + + 129 + + other + + + Dự phòng giảm giá đầu tư ngắn hạn + + + + 131 + + receivable + + + Phải thu của khách hàng + + + + 133 + + view + + + Thuế GTGT được khấu trừ + + + 1331 + + other + + + Thuế GTGT được khấu trừ của hàng hóa, dịch vụ + + + + 1332 + + other + + + Thuế GTGT được khấu trừ của TSCĐ + + + + 136 + + view + + + Phải thu nội bộ + + + 1361 + + other + + + Vốn kinh doanh ở đơn vị trực thuộc + + + 1368 + + other + + + Phải thu nội bộ khác + + + + 138 + + view + + + Phải thu khác + + + 1381 + + other + + + Tài sản thiếu chờ xử lý + + + 1385 + + other + + + Phải thu về cổ phần hóa + + + 1388 + + other + + + Phải thu khác + + + + 139 + + other + + + Dự phòng phải thu khó đòi + + + + 141 + + other + + + Tạm ứng + + + + 142 + + other + + + Chi phí trả trước ngắn hạn + + + + 144 + + other + + + Cầm cố, ký cược, ký quỹ ngắn hạn + + + + 151 + + other + + + Hàng hóa mua đang đi trên đường + + + + 152 + + other + + + Nguyên liệu, vật liệu + + + + 153 + + other + + + Công cụ, dụng cụ + + + + 154 + + other + + + Chi phí sản xuất kinh doanh dở dang + + + + 155 + + other + + + Thành phẩm + + + + 156 + + view + + + Hàng hóa + + + 1561 + + other + + + Giá mua hàng hóa + + + 1562 + + other + + + Chi phí thu mua hàng hóa + + + 1567 + + other + + + Hàng hóa bất động sản + + + + 157 + + other + + + Hàng gửi đi bán + + + + 158 + + other + + + Hàng hóa kho bảo thuế + + + + 159 + + other + + + Dự phòng giảm giá hàng tồn kho + + + + 161 + + view + + + Chi sự nghiệp + + + 1611 + + other + + + Chi sự nghiệp năm trước + + + 1612 + + other + + + Chi sự nghiệp năm nay + + + + + 2 + TÀI SẢN DÀI HẠN + view + + + + + + 211 + + view + + + Tài sản cố định hữu hình + + + 2111 + + other + + + Nhà cửa, vật kiến trúc + + + 2112 + + other + + + Máy móc, thiết bị + + + 2113 + + other + + + Phương tiện vận tải truyền dẫn + + + 2114 + + other + + + Thiết bị, dụng cụ quản lý + + + 2115 + + other + + + Cây lâu năm, súc vật làm việc và cho sản phẩm + + + + 2118 + + other + + + Tài sản cố định khác + + + + 212 + + other + + + Tài sản cố định thuê tài chính + + + + 213 + + view + + + Tài sản cố định vô hình + + + 2131 + + other + + + Quyền sử dụng đất + + + 2132 + + other + + + Quyền phát hành + + + 2133 + + other + + + Bản quyền, bằng sáng chế + + + 2134 + + other + + + Nhãn hiệu hàng hóa + + + 2135 + + other + + + Phần mềm máy tính + + + 2136 + + other + + + Giấy phép và giấy phép nhượng quyền + + + 2138 + + other + + + Tài sản cố định vô hình khác + + + + 214 + + view + + + Hao mòn TSCĐ + + + 2141 + + other + + + Hao mòn TSCĐ cố định hữu hình + + + 2142 + + other + + + Hao mòn TSCĐ thuê tài chính + + + 2143 + + other + + + Hao mòn TSCĐ vô hình + + + 2147 + + other + + + Hao mòn bất động sản đầu tư + + + + 217 + + other + + + Bất động sản đầu tư + + + + 221 + + other + + + Đầu tư vào công ty con + + + + 222 + + other + + + Vốn góp liên doanh + + + + 223 + + other + + + Đầu tư vào công ty liên kết + + + + 228 + + view + + + Đầu tư dài hạn khác + + + 2281 + + other + + + Cổ phiếu + + + 2282 + + other + + + Trái phiếu + + + 2288 + + other + + + Đầu tư dài hạn khác + + + + 229 + + other + + + Dự phòng giảm giá đầu tư dài hạn + + + + 241 + + view + + + Xây dựng cơ bản dở dang + + + 2411 + + other + + + Mua sắm TSCĐ + + + 2412 + + other + + + Xây dựng cơ bản + + + 2413 + + other + + + Sửa chữa lớn TSCĐ + + + + 242 + + other + + + Chi phí trả trước dài hạn + + + + 243 + + other + + + Tài sản thuế thu nhập hoãn lại + + + + 244 + + other + + + Ký quỹ, ký cược dài hạn + + + + + 3 + NỢ PHẢI TRẢ + view + + + + + + 311 + + other + + + Vay ngắn hạn + + + + 315 + + other + + + Nợ dài hạn đến hạn trả + + + + 331 + + payable + + + Phải trả người bán + + + + 333 + + view + + + Thuế và các khoản phải nộp Nhà nước + + + 3331 + + view + + + Thuế GTGT phải nộp + + + 33311 + + other + + + Thuế GTGT đầu ra + + + 33312 + + other + + + Thuế GTGT hàng nhập khẩu + + + 3332 + + other + + + Thuế tiêu thụ đặc biệt + + + 3333 + + other + + + Thuế xuất, nhập khẩu + + + 3334 + + other + + + Thuế thu nhập doanh nghiệp + + + 3335 + + other + + + Thuế thu nhập cá nhân + + + 3336 + + other + + + Thuế tài nguyên + + + 3337 + + other + + + Thuế nhà đất, tiền thuê đất + + + 3338 + + other + + + Các loại thuế khác + + + 3339 + + other + + + Phí, lệ phí và các khoản phải nộp khác + + + + 334 + + view + + + Phải trả người lao động + + + 3341 + + other + + + Phải trả công nhân viên + + + 3342 + + other + + + Phải trả người lao động khác + + + + 335 + + other + + + Chi phí phải trả + + + + 336 + + other + + + Phải trả nội bộ + + + + 337 + + other + + + Thanh toán theo tiến độ kế hoạch hợp đồng xây dựng + + + + + 338 + + view + + + Phải trả, phải nộp khác + + + 3381 + + other + + + Tài sản thừa chờ giải quyết + + + 3382 + + other + + + Kinh phí công đoàn + + + 3383 + + other + + + Bảo hiểm xã hội + + + 3384 + + other + + + Bảo hiểm y tế + + + 3385 + + other + + + Phải trả về cổ phần hóa + + + 3386 + + other + + + Nhận ký quỹ, ký cược ngắn hạn + + + 3387 + + other + + + Doanh thu chưa thực hiện + + + 3388 + + other + + + Phải trả, phải nộp khác + + + + 341 + + other + + + Vay dài hạn + + + + 342 + + other + + + Nợ dài hạn + + + + 343 + + view + + + Trái phiếu phát hành + + + 3431 + + other + + + Mệnh giá trái phiếu + + + 3432 + + other + + + Chiết khấu trái phiếu + + + 3434 + + other + + + Phụ trội trái phiếu + + + + 344 + + other + + + Nhận ký quỹ, ký cược dài hạn + + + + 347 + + other + + + Thuế thu nhập hoãn lại phải trả + + + + 351 + + other + + + Quỹ dự phòng trợ cấp mất việc làm + + + + 352 + + other + + + Dự phòng phải trả + + + + + 4 + VỐN CHỦ SỞ HỮU + view + + + + + + 411 + + view + + + Nguồn vốn kinh doanh + + + 4111 + + other + + + Vốn đầu tư chủ sỡ hữu + + + 4112 + + other + + + Thặng dư vốn cổ phần + + + 4118 + + other + + + Vốn khác + + + + 412 + + other + + + Chênh lệch đánh giá lại tài sản + + + + 413 + + view + + + Chênh lệnh tỉ giá hối đoái + + + 4131 + + other + + + Chênh lệnh tỉ giá hối đoái đánh giá lại cuối năm + tài chính + + + 4132 + + other + + + Chênh lệnh tỉ giá hối đoái trong giai đoạn đầu tư + XDCB + + + + 414 + + other + + + Quỹ đầu tư phát triển + + + + 415 + + other + + + Quỹ dự phòng tài chính + + + + 418 + + other + + + Các quỹ khác thuộc vốn chủ sở hữu + + + + 419 + + other + + + Cổ phiếu quỹ + + + + 421 + + view + + + Lợi nhuận chưa phân phối + + + 4211 + + other + + + Lợi nhuận chưa phân phối năm trước + + + 4212 + + other + + + Lợi nhuận chưa phân phối năm nay + + + + 431 + + view + + + Quỹ khen thưởng phúc lợi + + + 4311 + + other + + + Quỹ khen thưởng + + + 4312 + + other + + + Quỹ phúc lợi + + + 4313 + + other + + + Quỹ phúc lợi đã hình thành TSCĐ + + + + 441 + + other + + + Ngồn vố đầu tư xây dựng cơ bản + + + + 461 + + view + + + Nguồn kinh phí sự nghiệp + + + 4611 + + other + + + Nguồn kinh phí sự nghiệp năm trước + + + 4612 + + other + + + Nguồn kinh phí sự nghiệp năm nay + + + + 466 + + other + + + Nguồn kinh phí đã hình thành TSCĐ + + + + + 5 + DOANH THU + view + + + + + + 511 + + view + + + Doanh thu bán hàng và cung cấp dịch vụ + + + 5111 + + other + + + Doanh thu bán hàng hóa + + + 5112 + + other + + + Doanh thu bán các thành phẩm + + + 5113 + + other + + + Doanh thu cung cấp dịch vụ + + + 5114 + + other + + + Doanh thu trợ cấp, trợ giá + + + 5117 + + other + + + Doanh thu kinh doanh bất động sản đầu tư + + + + 512 + + view + + + Doanh thu bán hàng nội bộ + + + 5121 + + other + + + Doanh thu bán hàng hóa + + + 5122 + + other + + + Doanh thu bán các thành phẩm + + + 5123 + + other + + + Doanh thu cung cấp dịch vụ + + + + 515 + + other + + + Doanh thu hoạt động tài chính khác + + + + 521 + + other + + + Chiết khấu thương mại + + + + 531 + + other + + + Hàng bán bị trả lại + + + + 532 + + other + + + Giảm giá hàng bán + + + + + 6 + CHI PHÍ SẢN XUẤT, KINH DOANH + view + + + + + + 611 + + view + + + Mua hàng + + + 6111 + + other + + + Mua nguyên liệu, vật liệu + + + 6112 + + other + + + Mua hàng hóa + + + + 621 + + other + + + Chi phí nguyên liệu, vật liệu trực tiếp + + + + 622 + + other + + + Chi phí nhân công trực tiếp + + + + 623 + + view + + + Chi phí sử dụng máy thi công + + + 6231 + + other + + + Chi phí nhân công + + + 6232 + + other + + + Chi phí vật liệu + + + 6233 + + other + + + Chi phí dụng cụ sản xuất + + + 6234 + + other + + + Chi phí khấu hao máy thi công + + + 6237 + + other + + + Chi phí dịch vụ mua ngoài + + + 6238 + + other + + + Chi phí bằng tiền khác + + + + 627 + + view + + + Chi phí sản xuất chung + + + 6271 + + other + + + Chi phí nhân viên phân xưởng + + + 6272 + + other + + + Chi phí vật liệu + + + 6273 + + other + + + Chi phí dụng cụ sản xuất + + + 6274 + + other + + + Chi phí khấu hao TSCĐ + + + 6277 + + other + + + Chi phí dịch vụ mua ngoài + + + 6278 + + other + + + Chi phí bằng tiền khác + + + + 631 + + other + + + Giá thành sản xuất + + + + 632 + + other + + + Giá vốn hàng bán + + + + 635 + + other + + + Chi phí tài chính + + + + 641 + + view + + + Chi phí bán hàng + + + 6411 + + other + + + Chi phí nhân viên + + + 6412 + + other + + + Chi phí vật liệu, bao bì + + + 6413 + + other + + + Chi phí dụng cụ, đồ dùng + + + 6414 + + other + + + Chi phí khấu hao TSCĐ + + + 6415 + + other + + + Chi phí bảo hành + + + 6417 + + other + + + Chi phí dịch vụ mua ngoài + + + 6418 + + other + + + Chi phí bằng tiền khác + + + + 642 + + view + + + Chi phí quản lý doanh nghiệp + + + 6421 + + other + + + Chi phí nhân viên quản lý + + + 6422 + + other + + + Chi phí vật liệu quản lý + + + 6423 + + other + + + Chi phí đồ dùng văn phòng + + + 6424 + + other + + + Chi phí khấu hao tài sản cố định + + + 6425 + + other + + + Thuế, phí và lệ phí + + + 6426 + + other + + + Chi phí dự phòng + + + 6427 + + other + + + Chi phí dịch vụ mua ngoài + + + 6428 + + other + + + Chi phí bằng tiền khác + + + + + 7 + THU NHẬP KHÁC + view + + + + + + 711 + + other + + + Thu nhập khác + + + + + 8 + CHI PHÍ KHÁC + view + + + + + + 811 + + other + + + Chi phí khác + + + + 821 + + view + + + Chi phí thuế thu nhập doanh nghiệp + + + 8211 + + other + + + Chi phí thuế TNDN hiện hành + + + 8212 + + other + + + Chi phí thuế TNDN hoãn lại + + + + + 9 + XÁC ĐỊNH KẾT QUẢ KINH DOANH + view + + + + + + 911 + + other + + + Xác định kết quả kinh doanh + + + + + X10 + TÀI KHOẢN NGOÀI BẢNG + view + + + + + + 001 + + other + + + Tài sản thuê ngoài + + + + 002 + + other + + + Vật tư, hàng hóa nhận giữ hộ, nhận gia công + + + + 003 + + other + + + Hàng hóa nhận bán hộ, nhận ký gửi, ký cược + + + + 004 + + other + + + Nợ khó đòi đã xử lý + + + + 007 + + other + + + Ngoại tệ các loại + + + + 008 + + other + + + Dự toán chi sự nghiệp, dự án + + + + OBA + + other + + + Opening Balance Account + + + + + VN - Chart of Accounts + 0 + + + + + + + + + + + + diff --git a/addons/l10n_vn/account_tax.xml b/addons/l10n_vn/account_tax.xml new file mode 100755 index 00000000000..85f068023c2 --- /dev/null +++ b/addons/l10n_vn/account_tax.xml @@ -0,0 +1,90 @@ + + + + + + + + + + Thuế GTGT được khấu trừ 10% + + percent + + + purchase + + + + + + + + Thuế GTGT được khấu trừ 5% + + percent + + + purchase + + + + + + + + Thuế GTGT được khấu trừ 0% + + percent + + + purchase + + + + + + + + + + Thuế GTGT phải nộp 10% + + percent + + + sale + + + + + + + + Thuế GTGT phải nộp 5% + + percent + + + sale + + + + + + + + Thuế GTGT phải nộp 0% + + percent + + + sale + + + + + + + + diff --git a/addons/l10n_vn/account_tax_code.xml b/addons/l10n_vn/account_tax_code.xml new file mode 100755 index 00000000000..4f3aee1bfc6 --- /dev/null +++ b/addons/l10n_vn/account_tax_code.xml @@ -0,0 +1,122 @@ + + + + + + + + Tờ khai thuế GTGT + MAIN + + + + HHDV mua vào + + IN + + + + HHDV bán ra + + OUT + + + + + Giá trị HHDV mua vào + + IN_BASE + + + + Giá trị HHDV mua vào chịu thuế 0% + + IN_BASE_00 + + + + Giá trị HHDV mua vào chịu thuế 5% + + IN_BASE_05 + + + + Giá trị HHDV mua vào chịu thuế 10% + + IN_BASE_10 + + + + Giá trị HHDV bán ra + + OUT_BASE + + + + Giá trị HHDV bán ra chịu thuế 0% + + OUT_BASE_00 + + + + Giá trị HHDV bán ra chịu thuế 5% + + OUT_BASE_05 + + + + Giá trị HHDV bán ra chịu thuế 10% + + OUT_BASE_10 + + + + + Thuế GTGT HHDV mua vào + + IN_BALANCE + + + + Thuế GTGT HHDV mua vào chịu thuế 0% + + IN_BALANCE_00 + + + + Thuế GTGT HHDV mua vào chịu thuế 5% + + IN_BALANCE_05 + + + + Thuế GTGT HHDV mua vào chịu thuế 10% + + IN_BALANCE_10 + + + + Thuế GTGT HHDV bán ra + + OUT_BALANCE + + + + Thuế GTGT HHDV bán ra chịu thuế 0% + + OUT_BALANCE_00 + + + + Thuế GTGT HHDV bán ra chịu thuế 5% + + OUT_BALANCE_05 + + + + Thuế GTGT HHDV bán ra chịu thuế 10% + + OUT_BALANCE_10 + + + diff --git a/addons/l10n_vn/l10n_vn_wizard.xml b/addons/l10n_vn/l10n_vn_wizard.xml new file mode 100755 index 00000000000..368a3cbd8b3 --- /dev/null +++ b/addons/l10n_vn/l10n_vn_wizard.xml @@ -0,0 +1,10 @@ + + + + + + open + + + + \ No newline at end of file diff --git a/addons/l10n_vn/static/src/img/icon.png b/addons/l10n_vn/static/src/img/icon.png new file mode 100755 index 00000000000..241a2d3fa74 Binary files /dev/null and b/addons/l10n_vn/static/src/img/icon.png differ diff --git a/addons/lunch/i18n/ko.po b/addons/lunch/i18n/ko.po new file mode 100644 index 00000000000..e76966ad73b --- /dev/null +++ b/addons/lunch/i18n/ko.po @@ -0,0 +1,896 @@ +# Korean translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-05-11 19:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-12 05:28+0000\n" +"X-Generator: Launchpad (build 16598)\n" + +#. module: lunch +#: field:lunch.product,category_id:0 +#: field:lunch.product.category,name:0 +msgid "Category" +msgstr "범주" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_order_by_supplier_form +msgid "Today's Orders by Supplier" +msgstr "" + +#. module: lunch +#: view:lunch.order:0 +msgid "My Orders" +msgstr "" + +#. module: lunch +#: selection:lunch.order,state:0 +msgid "Partially Confirmed" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +#: view:lunch.order.line:0 +msgid "Group By..." +msgstr "" + +#. module: lunch +#: field:lunch.alert,sunday:0 +msgid "Sunday" +msgstr "" + +#. module: lunch +#: field:lunch.order.line,supplier:0 +#: field:lunch.product,supplier:0 +msgid "Supplier" +msgstr "공급업체" + +#. module: lunch +#: view:lunch.order.line:0 +msgid "Today" +msgstr "오늘" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "March" +msgstr "3월" + +#. module: lunch +#: view:lunch.cashmove:0 +msgid "By Employee" +msgstr "직원에 의해" + +#. module: lunch +#: field:lunch.alert,friday:0 +msgid "Friday" +msgstr "" + +#. module: lunch +#: view:lunch.validation:0 +msgid "validate order lines" +msgstr "" + +#. module: lunch +#: view:lunch.order.line:0 +msgid "Order lines Tree" +msgstr "" + +#. module: lunch +#: field:lunch.alert,specific_day:0 +#: field:report.lunch.order.line,day:0 +msgid "Day" +msgstr "" + +#. module: lunch +#: view:lunch.order.line:0 +#: selection:lunch.order.line,state:0 +msgid "Received" +msgstr "받음" + +#. module: lunch +#: view:lunch.order.line:0 +msgid "By Supplier" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_order_tree +msgid "" +"

\n" +" Click to create a lunch order. \n" +"

\n" +"

\n" +" A lunch order is defined by its user, date and order lines.\n" +" Each order line corresponds to a product, an additional note " +"and a price.\n" +" Before selecting your order lines, don't forget to read the " +"warnings displayed in the reddish area.\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: view:lunch.order.line:0 +msgid "Not Received" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_order_by_supplier_form +#: model:ir.ui.menu,name:lunch.menu_lunch_control_suppliers +msgid "Orders by Supplier" +msgstr "" + +#. module: lunch +#: view:lunch.validation:0 +msgid "Receive Meals" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +msgid "cashmove form" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_cashmove_form +msgid "" +"

\n" +" Here you can see your cash moves.
A cash moves can be " +"either an expense or a payment.\n" +" An expense is automatically created when an order is " +"received while a payment is a reimbursement to the company encoded by the " +"manager.\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: field:lunch.cashmove,amount:0 +msgid "Amount" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_products +#: model:ir.ui.menu,name:lunch.menu_lunch_products +#: field:lunch.order,order_line_ids:0 +msgid "Products" +msgstr "상품" + +#. module: lunch +#: view:lunch.order.line:0 +msgid "By Date" +msgstr "" + +#. module: lunch +#: selection:lunch.order,state:0 +#: view:lunch.order.line:0 +#: selection:lunch.order.line,state:0 +msgid "Cancelled" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +msgid "lunch employee payment" +msgstr "" + +#. module: lunch +#: view:lunch.alert:0 +msgid "alert tree" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_report_lunch_order_line +msgid "Lunch Orders Statistics" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_alert +msgid "Lunch Alert" +msgstr "" + +#. module: lunch +#: code:addons/lunch/lunch.py:183 +#, python-format +msgid "Select a product and put your order comments on the note." +msgstr "" + +#. module: lunch +#: selection:lunch.alert,alter_type:0 +msgid "Every Week" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_cashmove +msgid "Register Cash Moves" +msgstr "" + +#. module: lunch +#: selection:lunch.order,state:0 +msgid "Confirmed" +msgstr "" + +#. module: lunch +#: view:lunch.order:0 +msgid "lunch orders" +msgstr "" + +#. module: lunch +#: view:lunch.order.line:0 +msgid "Confirm" +msgstr "확정" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_cashmove_form +msgid "Your Account" +msgstr "" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_cashmove_form +msgid "Your Lunch Account" +msgstr "점심 계정" + +#. module: lunch +#: field:lunch.alert,active_from:0 +msgid "Between" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_order_order +msgid "Wizard to order a meal" +msgstr "" + +#. module: lunch +#: selection:lunch.order,state:0 +#: selection:lunch.order.line,state:0 +msgid "New" +msgstr "" + +#. module: lunch +#: code:addons/lunch/lunch.py:180 +#, python-format +msgid "This is the first time you order a meal" +msgstr "이것은 첫번쨰 고기 주문입니다." + +#. module: lunch +#: field:report.lunch.order.line,price_total:0 +msgid "Total Price" +msgstr "총액" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_validation +msgid "lunch validation for order" +msgstr "" + +#. module: lunch +#: report:lunch.order.line:0 +msgid "Name/Date" +msgstr "이름/날짜" + +#. module: lunch +#: report:lunch.order.line:0 +msgid "Total :" +msgstr "합계 :" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "July" +msgstr "" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_config +msgid "Configuration" +msgstr "" + +#. module: lunch +#: field:lunch.order,state:0 +#: field:lunch.order.line,state:0 +msgid "Status" +msgstr "상태" + +#. module: lunch +#: view:lunch.order.order:0 +msgid "" +"Order a meal doesn't mean that we have to pay it.\n" +" A meal should be paid when it is received." +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_control_accounts +#: model:ir.ui.menu,name:lunch.menu_lunch_control_accounts +msgid "Control Accounts" +msgstr "" + +#. module: lunch +#: selection:lunch.alert,alter_type:0 +msgid "Every Day" +msgstr "매일" + +#. module: lunch +#: field:lunch.order.line,cashmove:0 +msgid "Cash Move" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.order_order_lines +msgid "Order meals" +msgstr "육류 주문" + +#. module: lunch +#: view:lunch.alert:0 +msgid "Schedule Hour" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "September" +msgstr "9월" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_control_suppliers +msgid "" +"

\n" +" Here you can see every orders grouped by suppliers and by " +"date.\n" +"

\n" +"

\n" +" - Click on the to announce " +"that the order is ordered
\n" +" - Click on the to announce that " +"the order is received
\n" +" - Click on the red X to announce " +"that the order isn't available\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: field:lunch.alert,tuesday:0 +msgid "Tuesday" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_order_tree +msgid "Your Orders" +msgstr "" + +#. module: lunch +#: field:report.lunch.order.line,month:0 +msgid "Month" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_products +msgid "" +"

\n" +" Click to create a product for lunch. \n" +"

\n" +"

\n" +" A product is defined by its name, category, price and " +"supplier.\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: view:lunch.alert:0 +#: field:lunch.alert,message:0 +msgid "Message" +msgstr "" + +#. module: lunch +#: view:lunch.order.order:0 +msgid "Order Meals" +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +#: view:lunch.order.order:0 +#: view:lunch.validation:0 +msgid "or" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_product_categories +msgid "" +"

\n" +" Click to create a lunch category. \n" +"

\n" +"

\n" +" Here you can find every lunch categories for products.\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: view:lunch.order.order:0 +msgid "Order meal" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_product_categories +#: model:ir.ui.menu,name:lunch.menu_lunch_product_categories +msgid "Product Categories" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_control_suppliers +msgid "Control Suppliers" +msgstr "" + +#. module: lunch +#: view:lunch.alert:0 +msgid "Schedule Date" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_alert +#: model:ir.ui.menu,name:lunch.menu_lunch_alert +#: field:lunch.order,alerts:0 +msgid "Alerts" +msgstr "" + +#. module: lunch +#: field:lunch.order.line,note:0 +#: field:report.lunch.order.line,note:0 +msgid "Note" +msgstr "" + +#. module: lunch +#: code:addons/lunch/lunch.py:250 +#, python-format +msgid "Add" +msgstr "" + +#. module: lunch +#: view:lunch.product:0 +#: view:lunch.product.category:0 +msgid "Products Form" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.cancel_order_lines +msgid "Cancel meals" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_cashmove +#: view:lunch.cashmove:0 +msgid "lunch cashmove" +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +msgid "Are you sure you want to cancel these meals?" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +msgid "My Account" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "August" +msgstr "" + +#. module: lunch +#: field:lunch.alert,monday:0 +msgid "Monday" +msgstr "" + +#. module: lunch +#: field:lunch.order.line,name:0 +msgid "unknown" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.validate_order_lines +msgid "Receive meals" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "June" +msgstr "" + +#. module: lunch +#: field:lunch.cashmove,user_id:0 +#: field:lunch.order,user_id:0 +#: field:report.lunch.order.line,user_id:0 +msgid "User Name" +msgstr "" + +#. module: lunch +#: model:ir.module.category,name:lunch.module_lunch_category +#: model:ir.ui.menu,name:lunch.menu_lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_title +msgid "Lunch" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_order_line +msgid "lunch order line" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_product +msgid "lunch product" +msgstr "" + +#. module: lunch +#: field:lunch.order.line,user_id:0 +#: model:res.groups,name:lunch.group_lunch_user +msgid "User" +msgstr "" + +#. module: lunch +#: field:lunch.cashmove,date:0 +#: field:lunch.order,date:0 +#: field:lunch.order.line,date:0 +msgid "Date" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "November" +msgstr "" + +#. module: lunch +#: view:lunch.order:0 +msgid "Orders Tree" +msgstr "" + +#. module: lunch +#: view:lunch.order:0 +msgid "Orders Form" +msgstr "" + +#. module: lunch +#: view:lunch.alert:0 +#: view:lunch.order.line:0 +msgid "Search" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "October" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_order_by_supplier_form +msgid "" +"

\n" +" Here you can see today's orders grouped by suppliers.\n" +"

\n" +"

\n" +" - Click on the to announce " +"that the order is ordered
\n" +" - Click on the to announce that " +"the order is received
\n" +" - Click on the to announce that " +"the order isn't available\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "January" +msgstr "" + +#. module: lunch +#: selection:lunch.alert,alter_type:0 +msgid "Specific Day" +msgstr "" + +#. module: lunch +#: field:lunch.alert,wednesday:0 +msgid "Wednesday" +msgstr "" + +#. module: lunch +#: view:lunch.product.category:0 +msgid "Product Category: " +msgstr "" + +#. module: lunch +#: field:lunch.alert,active_to:0 +msgid "And" +msgstr "" + +#. module: lunch +#: selection:lunch.order.line,state:0 +msgid "Ordered" +msgstr "" + +#. module: lunch +#: field:report.lunch.order.line,date:0 +msgid "Date Order" +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +msgid "Cancel Orders" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_alert +msgid "" +"

\n" +" Click to create a lunch alert. \n" +"

\n" +"

\n" +" Alerts are used to warn employee from possible issues " +"concerning the lunch orders.\n" +" To create a lunch alert you have to define its recurrency, " +"the time interval during which the alert should be executed and the message " +"to display.\n" +"

\n" +"

\n" +" Example:
\n" +" - Recurency: Everyday
\n" +" - Time interval: from 00h00 am to 11h59 pm
\n" +" - Message: \"You must order before 10h30 am\"\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +msgid "A cancelled meal should not be paid by employees." +msgstr "" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_cash +msgid "Administrate Cash Moves" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_cancel +msgid "cancel lunch order" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "December" +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +#: view:lunch.order.line:0 +#: view:lunch.order.order:0 +#: view:lunch.validation:0 +msgid "Cancel" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_cashmove +msgid "" +"

\n" +" Click to create a payment. \n" +"

\n" +"

\n" +" Here you can see the employees' payment. A payment is a cash " +"move from the employee to the company.\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: code:addons/lunch/lunch.py:186 +#, python-format +msgid "Your favorite meals will be created based on your last orders." +msgstr "" + +#. module: lunch +#: model:ir.module.category,description:lunch.module_lunch_category +msgid "" +"Helps you handle your lunch needs, if you are a manager you will be able to " +"create new products, cashmoves and to confirm or cancel orders." +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,help:lunch.action_lunch_control_accounts +msgid "" +"

\n" +" Click to create a new payment. \n" +"

\n" +"

\n" +" A cashmove can either be an expense or a payment.
\n" +" An expense is automatically created at the order " +"receipt.
\n" +" A payment represents the employee reimbursement to the " +"company.\n" +"

\n" +" " +msgstr "" + +#. module: lunch +#: field:lunch.alert,alter_type:0 +msgid "Recurrency" +msgstr "" + +#. module: lunch +#: code:addons/lunch/lunch.py:189 +#, python-format +msgid "Don't forget the alerts displayed in the reddish area" +msgstr "" + +#. module: lunch +#: field:lunch.alert,thursday:0 +msgid "Thursday" +msgstr "" + +#. module: lunch +#: report:lunch.order.line:0 +msgid "Unit Price" +msgstr "" + +#. module: lunch +#: field:lunch.order.line,product_id:0 +#: field:lunch.product,name:0 +msgid "Product" +msgstr "" + +#. module: lunch +#: field:lunch.cashmove,description:0 +#: report:lunch.order.line:0 +#: field:lunch.product,description:0 +msgid "Description" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "May" +msgstr "" + +#. module: lunch +#: field:lunch.order.line,price:0 +#: field:lunch.product,price:0 +msgid "Price" +msgstr "" + +#. module: lunch +#: field:lunch.cashmove,state:0 +msgid "Is an order or a Payment" +msgstr "" + +#. module: lunch +#: model:ir.actions.act_window,name:lunch.action_lunch_order_form +#: model:ir.ui.menu,name:lunch.menu_lunch_order_form +msgid "New Order" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +msgid "cashmove tree" +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +msgid "Cancel a meal means that we didn't receive it from the supplier." +msgstr "" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_cashmove +msgid "Employee Payments" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +#: selection:lunch.cashmove,state:0 +msgid "Payment" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "February" +msgstr "" + +#. module: lunch +#: field:report.lunch.order.line,year:0 +msgid "Year" +msgstr "" + +#. module: lunch +#: view:lunch.order:0 +msgid "List" +msgstr "" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_admin +msgid "Administrate Orders" +msgstr "" + +#. module: lunch +#: selection:report.lunch.order.line,month:0 +msgid "April" +msgstr "" + +#. module: lunch +#: view:lunch.order:0 +msgid "Select your order" +msgstr "" + +#. module: lunch +#: field:lunch.cashmove,order_id:0 +#: selection:lunch.cashmove,state:0 +#: report:lunch.order.line:0 +#: view:lunch.order.line:0 +#: field:lunch.order.line,order_id:0 +msgid "Order" +msgstr "" + +#. module: lunch +#: model:ir.actions.report.xml,name:lunch.report_lunch_order +#: model:ir.model,name:lunch.model_lunch_order +#: report:lunch.order.line:0 +msgid "Lunch Order" +msgstr "" + +#. module: lunch +#: view:lunch.order.order:0 +msgid "Are you sure you want to order these meals?" +msgstr "" + +#. module: lunch +#: view:lunch.cancel:0 +msgid "cancel order lines" +msgstr "" + +#. module: lunch +#: model:ir.model,name:lunch.model_lunch_product_category +msgid "lunch product category" +msgstr "" + +#. module: lunch +#: field:lunch.alert,saturday:0 +msgid "Saturday" +msgstr "" + +#. module: lunch +#: model:res.groups,name:lunch.group_lunch_manager +msgid "Manager" +msgstr "" + +#. module: lunch +#: view:lunch.validation:0 +msgid "Did your received these meals?" +msgstr "" + +#. module: lunch +#: view:lunch.validation:0 +msgid "Once a meal is received a new cash move is created for the employee." +msgstr "" + +#. module: lunch +#: view:lunch.product:0 +msgid "Products Tree" +msgstr "" + +#. module: lunch +#: view:lunch.cashmove:0 +#: view:lunch.order:0 +#: field:lunch.order,total:0 +#: view:lunch.order.line:0 +msgid "Total" +msgstr "" + +#. module: lunch +#: model:ir.ui.menu,name:lunch.menu_lunch_order_tree +msgid "Previous Orders" +msgstr "" diff --git a/addons/lunch/lunch.py b/addons/lunch/lunch.py index 9f18c391eec..efad6fd6944 100644 --- a/addons/lunch/lunch.py +++ b/addons/lunch/lunch.py @@ -169,7 +169,7 @@ class lunch_order(osv.Model): line_ref = self.pool.get("lunch.order.line") if view_type == 'form': doc = etree.XML(res['arch']) - pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='create_date desc', context=context) + pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='id desc', context=context) xml_start = etree.Element("div") #If there are no preference (it's the first time for the user) if len(pref_ids)==0: @@ -215,63 +215,70 @@ class lunch_order(osv.Model): currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id #For each preferences that we get, we will create the XML structure - for key,value in categories.items(): + for key, value in categories.items(): xml_pref_1 = etree.Element("div") - xml_pref_1.set('class','oe_lunch_30pc') + xml_pref_1.set('class', 'oe_lunch_30pc') xml_pref_2 = etree.Element("h2") xml_pref_2.text = key xml_pref_1.append(xml_pref_2) i = 0 value = value.values() + #TODO: sorted_values is used for a quick and dirty hack in order to display the 5 last orders of each categories. + #It would be better to fetch only the 5 items to display instead of fetching everything then sorting them in order to keep only the 5 last. + #NB: The note could also be ignored + we could fetch the preferences on the most ordered products instead of the last ones... + sorted_values = {} for val in value: - for pref in val.values(): - #We only show 5 preferences per category (or it will be too long) - if i==5: break - i+=1 - xml_pref_3 = etree.Element("div") - xml_pref_3.set('class','oe_lunch_vignette') - xml_pref_1.append(xml_pref_3) + for elmt in val.values(): + sorted_values[elmt.id] = elmt + for key, pref in sorted(sorted_values.iteritems(), key=lambda (k, v): (k, v), reverse=True): + #We only show 5 preferences per category (or it will be too long) + if i == 5: + break + i += 1 + xml_pref_3 = etree.Element("div") + xml_pref_3.set('class','oe_lunch_vignette') + xml_pref_1.append(xml_pref_3) - xml_pref_4 = etree.Element("span") - xml_pref_4.set('class','oe_lunch_button') - xml_pref_3.append(xml_pref_4) + xml_pref_4 = etree.Element("span") + xml_pref_4.set('class','oe_lunch_button') + xml_pref_3.append(xml_pref_4) - xml_pref_5 = etree.Element("button") - xml_pref_5.set('name',"add_preference_"+str(pref.id)) - xml_pref_5.set('class','oe_link oe_i oe_button_plus') - xml_pref_5.set('type','object') - xml_pref_5.set('string','+') - xml_pref_4.append(xml_pref_5) + xml_pref_5 = etree.Element("button") + xml_pref_5.set('name',"add_preference_"+str(pref.id)) + xml_pref_5.set('class','oe_link oe_i oe_button_plus') + xml_pref_5.set('type','object') + xml_pref_5.set('string','+') + xml_pref_4.append(xml_pref_5) - xml_pref_6 = etree.Element("button") - xml_pref_6.set('name',"add_preference_"+str(pref.id)) - xml_pref_6.set('class','oe_link oe_button_add') - xml_pref_6.set('type','object') - xml_pref_6.set('string',_("Add")) - xml_pref_4.append(xml_pref_6) + xml_pref_6 = etree.Element("button") + xml_pref_6.set('name',"add_preference_"+str(pref.id)) + xml_pref_6.set('class','oe_link oe_button_add') + xml_pref_6.set('type','object') + xml_pref_6.set('string',_("Add")) + xml_pref_4.append(xml_pref_6) - xml_pref_7 = etree.Element("div") - xml_pref_7.set('class','oe_group_text_button') - xml_pref_3.append(xml_pref_7) + xml_pref_7 = etree.Element("div") + xml_pref_7.set('class','oe_group_text_button') + xml_pref_3.append(xml_pref_7) - xml_pref_8 = etree.Element("div") - xml_pref_8.set('class','oe_lunch_text') - xml_pref_8.text = escape(pref.product_id.name)+str(" ") - xml_pref_7.append(xml_pref_8) + xml_pref_8 = etree.Element("div") + xml_pref_8.set('class','oe_lunch_text') + xml_pref_8.text = escape(pref.product_id.name)+str(" ") + xml_pref_7.append(xml_pref_8) - price = pref.product_id.price or 0.0 - cur = currency.name or '' - xml_pref_9 = etree.Element("span") - xml_pref_9.set('class','oe_tag') - xml_pref_9.text = str(price)+str(" ")+cur - xml_pref_8.append(xml_pref_9) + price = pref.product_id.price or 0.0 + cur = currency.name or '' + xml_pref_9 = etree.Element("span") + xml_pref_9.set('class','oe_tag') + xml_pref_9.text = str(price)+str(" ")+cur + xml_pref_8.append(xml_pref_9) - xml_pref_10 = etree.Element("div") - xml_pref_10.set('class','oe_grey') - xml_pref_10.text = escape(pref.note or '') - xml_pref_3.append(xml_pref_10) + xml_pref_10 = etree.Element("div") + xml_pref_10.set('class','oe_grey') + xml_pref_10.text = escape(pref.note or '') + xml_pref_3.append(xml_pref_10) - xml_start.append(xml_pref_1) + xml_start.append(xml_pref_1) first_node = doc.xpath("//div[@name='preferences']") if first_node and len(first_node)>0: diff --git a/addons/lunch/report/report_lunch_order.py b/addons/lunch/report/report_lunch_order.py index 3a439a4a4dd..13c885e7896 100644 --- a/addons/lunch/report/report_lunch_order.py +++ b/addons/lunch/report/report_lunch_order.py @@ -60,6 +60,5 @@ class report_lunch_order(osv.osv): lo.date,lo.user_id,lo.note ) """) -report_lunch_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml index 3f517ee7858..4e935e4aa88 100644 --- a/addons/mail/data/mail_data.xml +++ b/addons/mail/data/mail_data.xml @@ -27,6 +27,25 @@ 1000
+ + Garbage Collect Mail Attachments + + + 1 + weeks + -1 + + mail.thread + _garbage_collect_attachments + () + + + + + mail.catchall.alias + catchall + + Discussions diff --git a/addons/mail/i18n/cs.po b/addons/mail/i18n/cs.po new file mode 100644 index 00000000000..e12668ab3ee --- /dev/null +++ b/addons/mail/i18n/cs.po @@ -0,0 +1,1687 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-03-25 07:50+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-26 04:44+0000\n" +"X-Generator: Launchpad (build 16540)\n" + +#. module: mail +#: view:mail.followers:0 +msgid "Followers Form" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_publisher_warranty_contract +msgid "publisher_warranty.contract" +msgstr "" + +#. module: mail +#: field:mail.compose.message,author_id:0 +#: field:mail.message,author_id:0 +msgid "Author" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Message Details" +msgstr "" + +#. module: mail +#: help:mail.mail,email_to:0 +msgid "Message recipients" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,default:0 +msgid "Activated by default when subscribing." +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Comments" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: view:mail.mail:0 +msgid "Group By..." +msgstr "" + +#. module: mail +#: help:mail.compose.message,body:0 +#: help:mail.message,body:0 +msgid "Automatically sanitized HTML contents" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_name:0 +msgid "" +"The name of the email alias, e.g. 'jobs' if you want to catch emails for " +"" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard +#: view:mail.compose.message:0 +msgid "Compose Email" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:132 +#, python-format +msgid "Add them into recipients and followers" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Group Name" +msgstr "" + +#. module: mail +#: selection:mail.group,public:0 +msgid "Public" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Body" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Show messages to read" +msgstr "" + +#. module: mail +#: help:mail.compose.message,email_from:0 +#: help:mail.message,email_from:0 +msgid "" +"Email address of the sender. This field is set when no matching partner is " +"found for incoming emails." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:23 +#, python-format +msgid "Add others" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,parent_id:0 +msgid "Parent" +msgstr "" + +#. module: mail +#: field:mail.group,message_unread:0 +#: field:mail.thread,message_unread:0 +#: field:res.partner,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:296 +#, python-format +msgid "show" +msgstr "" + +#. module: mail +#: help:mail.group,group_ids:0 +msgid "" +"Members of those groups will automatically added as followers. Note that " +"they will be able to manage their subscription manually if necessary." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail.js:1019 +#, python-format +msgid "Do you really want to delete this message?" +msgstr "" + +#. module: mail +#: view:mail.message:0 +#: field:mail.notification,read:0 +msgid "Read" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Search Groups" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail_followers.js:159 +#, python-format +msgid "followers" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:726 +#, python-format +msgid "Access Denied" +msgstr "" + +#. module: mail +#: help:mail.group,image_medium:0 +msgid "" +"Medium-sized photo of the group. It is automatically resized as a 128x128px " +"image, with aspect ratio preserved. Use this field in form views or some " +"kanban views." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:212 +#, python-format +msgid "Uploading error" +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_support +msgid "Support" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:727 +#, python-format +msgid "" +"The requested operation cannot be completed due to security restrictions. " +"Please contact your system administrator.\n" +"\n" +"(Document type: %s, Operation: %s)" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: selection:mail.mail,state:0 +msgid "Received" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Thread" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:29 +#, python-format +msgid "Open the full mail composer" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:29 +#, python-format +msgid "ò" +msgstr "" + +#. module: mail +#: field:base.config.settings,alias_domain:0 +msgid "Alias Domain" +msgstr "" + +#. module: mail +#: field:mail.group,group_ids:0 +msgid "Auto Subscription" +msgstr "" + +#. module: mail +#: field:mail.mail,references:0 +msgid "References" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:206 +#, python-format +msgid "No messages." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_group +msgid "Discussion group" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:98 +#: code:addons/mail/static/src/xml/mail.xml:110 +#, python-format +msgid "uploading" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:52 +#, python-format +msgid "more." +msgstr "" + +#. module: mail +#: help:mail.compose.message,type:0 +#: help:mail.message,type:0 +msgid "" +"Message type: email for email message, notification for system message, " +"comment for other messages such as user replies" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,relation_field:0 +msgid "" +"Field used to link the related model to the subtype model when using " +"automatic subscription on a related document. The field is used to compute " +"getattr(related_document.relation_field)." +msgstr "" + +#. module: mail +#: selection:mail.mail,state:0 +msgid "Cancelled" +msgstr "" + +#. module: mail +#: field:mail.mail,reply_to:0 +msgid "Reply-To" +msgstr "" + +#. module: mail +#: code:addons/mail/wizard/invite.py:37 +#, python-format +msgid "
You have been invited to follow %s.
" +msgstr "" + +#. module: mail +#: help:mail.group,message_unread:0 +#: help:mail.thread,message_unread:0 +#: help:res.partner,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: mail +#: field:mail.group,image_medium:0 +msgid "Medium-sized photo" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_to_me_feeds +#: model:ir.ui.menu,name:mail.mail_tomefeeds +msgid "To: me" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,name:0 +msgid "Message Type" +msgstr "" + +#. module: mail +#: field:mail.mail,auto_delete:0 +msgid "Auto Delete" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:12 +#: view:mail.group:0 +#, python-format +msgid "Unfollow" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:295 +#, python-format +msgid "show one more message" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_mail.py:74 +#: code:addons/mail/res_users.py:69 +#, python-format +msgid "Invalid Action!" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:25 +#, python-format +msgid "User img" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_mail_mail +#: model:ir.ui.menu,name:mail.menu_mail_mail +#: view:mail.mail:0 +#: view:mail.message:0 +msgid "Emails" +msgstr "" + +#. module: mail +#: field:mail.followers,partner_id:0 +msgid "Related Partner" +msgstr "" + +#. module: mail +#: help:mail.group,message_summary:0 +#: help:mail.thread,message_summary:0 +#: help:res.partner,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: mail +#: help:mail.alias,alias_model_id:0 +msgid "" +"The model (OpenERP Document Kind) to which this alias corresponds. Any " +"incoming email that does not reply to an existing record will cause the " +"creation of a new record of this model (e.g. a Project Task)" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,relation_field:0 +msgid "Relation field" +msgstr "" + +#. module: mail +#: selection:mail.compose.message,type:0 +#: selection:mail.message,type:0 +msgid "System notification" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_res_partner +#: view:mail.mail:0 +msgid "Partner" +msgstr "" + +#. module: mail +#: model:ir.ui.menu,name:mail.mail_my_stuff +msgid "Organizer" +msgstr "" + +#. module: mail +#: field:mail.compose.message,subject:0 +#: field:mail.message,subject:0 +msgid "Subject" +msgstr "" + +#. module: mail +#: field:mail.wizard.invite,partner_ids:0 +msgid "Partners" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Retry" +msgstr "" + +#. module: mail +#: field:mail.compose.message,email_from:0 +#: field:mail.mail,email_from:0 +#: field:mail.message,email_from:0 +msgid "From" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: view:mail.message.subtype:0 +msgid "Email message" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_base_config_settings +msgid "base.config.settings" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:36 +#: view:mail.compose.message:0 +#, python-format +msgid "Send" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail_followers.js:155 +#, python-format +msgid "No followers" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Failed" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:22 +#: model:ir.actions.act_window,name:mail.action_view_followers +#: model:ir.ui.menu,name:mail.menu_email_followers +#: view:mail.followers:0 +#: field:mail.group,message_follower_ids:0 +#: field:mail.thread,message_follower_ids:0 +#: field:res.partner,message_follower_ids:0 +#, python-format +msgid "Followers" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_archives_feeds +#: model:ir.ui.menu,name:mail.mail_archivesfeeds +msgid "Archives" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:97 +#: code:addons/mail/static/src/xml/mail.xml:109 +#, python-format +msgid "Delete this attachment" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:245 +#: view:mail.mail:0 +#, python-format +msgid "Reply" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail_followers.js:157 +#, python-format +msgid "One follower" +msgstr "" + +#. module: mail +#: field:mail.compose.message,type:0 +#: field:mail.message,type:0 +msgid "Type" +msgstr "" + +#. module: mail +#: selection:mail.compose.message,type:0 +#: view:mail.mail:0 +#: selection:mail.message,type:0 +msgid "Email" +msgstr "" + +#. module: mail +#: field:ir.ui.menu,mail_group_id:0 +msgid "Mail Group" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "Comments and Emails" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_defaults:0 +msgid "Default Values" +msgstr "" + +#. module: mail +#: code:addons/mail/res_users.py:89 +#, python-format +msgid "%s has joined the %s network." +msgstr "" + +#. module: mail +#: help:mail.group,image_small:0 +msgid "" +"Small-sized photo of the group. It is automatically resized as a 64x64px " +"image, with aspect ratio preserved. Use this field anywhere a small image is " +"required." +msgstr "" + +#. module: mail +#: view:mail.compose.message:0 +#: field:mail.message,partner_ids:0 +msgid "Recipients" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:142 +#, python-format +msgid "<<<" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:43 +#, python-format +msgid "Write to the followers of this document..." +msgstr "" + +#. module: mail +#: field:mail.group,group_public_id:0 +msgid "Authorized Group" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Join Group" +msgstr "" + +#. module: mail +#: help:mail.mail,email_from:0 +msgid "Message sender, taken from user preferences." +msgstr "" + +#. module: mail +#: code:addons/mail/wizard/invite.py:40 +#, python-format +msgid "
You have been invited to follow a new document.
" +msgstr "" + +#. module: mail +#: field:mail.compose.message,parent_id:0 +#: field:mail.message,parent_id:0 +msgid "Parent Message" +msgstr "" + +#. module: mail +#: field:mail.compose.message,res_id:0 +#: field:mail.followers,res_id:0 +#: field:mail.message,res_id:0 +#: field:mail.wizard.invite,res_id:0 +msgid "Related Document ID" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_to_me_feeds +msgid "" +"

\n" +" No private message.\n" +"

\n" +" This list contains messages sent to you.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_rd +msgid "R&D" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:61 +#, python-format +msgid "/web/binary/upload_attachment" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Advanced" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:244 +#, python-format +msgid "Move to Inbox" +msgstr "" + +#. module: mail +#: code:addons/mail/wizard/mail_compose_message.py:165 +#, python-format +msgid "Re:" +msgstr "" + +#. module: mail +#: field:mail.compose.message,to_read:0 +#: field:mail.message,to_read:0 +msgid "To read" +msgstr "" + +#. module: mail +#: code:addons/mail/res_users.py:69 +#, python-format +msgid "" +"You may not create a user. To create new users, you should use the " +"\"Settings > Users\" menu." +msgstr "" + +#. module: mail +#: help:mail.followers,res_model:0 +#: help:mail.wizard.invite,res_model:0 +msgid "Model of the followed resource" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:320 +#, python-format +msgid "like" +msgstr "" + +#. module: mail +#: view:mail.compose.message:0 +#: view:mail.wizard.invite:0 +msgid "Cancel" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:47 +#, python-format +msgid "Share with my followers..." +msgstr "" + +#. module: mail +#: field:mail.notification,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "" +"Only the invited followers can read the\n" +" discussions on this group." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_ir_ui_menu +msgid "ir.ui.menu" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Has attachments" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "on" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:915 +#, python-format +msgid "" +"The following partners chosen as recipients for the email have no email " +"address linked :" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_defaults:0 +msgid "" +"A Python dictionary that will be evaluated to provide default values when " +"creating new records for this alias." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_message_subtype +msgid "Message subtypes" +msgstr "" + +#. module: mail +#: help:mail.compose.message,notified_partner_ids:0 +#: help:mail.message,notified_partner_ids:0 +msgid "" +"Partners that have a notification pushing this message in their mailboxes" +msgstr "" + +#. module: mail +#: selection:mail.compose.message,type:0 +#: view:mail.mail:0 +#: selection:mail.message,type:0 +msgid "Comment" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_inbox_feeds +msgid "" +"

\n" +" Good Job! Your inbox is empty.\n" +"

\n" +" Your inbox contains private messages or emails sent to " +"you\n" +" as well as information related to documents or people " +"you\n" +" follow.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: field:mail.mail,notification:0 +msgid "Is Notification" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:188 +#, python-format +msgid "Compose a new message" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Send Now" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_mail.py:74 +#, python-format +msgid "" +"Unable to send email, please configure the sender's email address or alias." +msgstr "" + +#. module: mail +#: help:res.users,alias_id:0 +msgid "" +"Email address internally associated with this user. Incoming emails will " +"appear in the user's notifications." +msgstr "" + +#. module: mail +#: field:mail.group,image:0 +msgid "Photo" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:56 +#: code:addons/mail/static/src/xml/mail.xml:191 +#: view:mail.compose.message:0 +#: view:mail.wizard.invite:0 +#, python-format +msgid "or" +msgstr "" + +#. module: mail +#: help:mail.compose.message,vote_user_ids:0 +#: help:mail.message,vote_user_ids:0 +msgid "Users that voted for this message" +msgstr "" + +#. module: mail +#: help:mail.group,alias_id:0 +msgid "" +"The email address associated with this group. New emails received will " +"automatically create new topics." +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Month" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Email Search" +msgstr "" + +#. module: mail +#: field:mail.compose.message,child_ids:0 +#: field:mail.message,child_ids:0 +msgid "Child Messages" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_user_id:0 +msgid "Owner" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_res_users +msgid "Users" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_message +#: field:mail.mail,mail_message_id:0 +#: view:mail.message:0 +#: field:mail.notification,message_id:0 +#: field:mail.wizard.invite,message:0 +msgid "Message" +msgstr "" + +#. module: mail +#: help:mail.followers,res_id:0 +#: help:mail.wizard.invite,res_id:0 +msgid "Id of the followed resource" +msgstr "" + +#. module: mail +#: field:mail.compose.message,body:0 +#: field:mail.message,body:0 +msgid "Contents" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_mail_alias +#: model:ir.ui.menu,name:mail.mail_alias_menu +msgid "Aliases" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,description:0 +msgid "" +"Description that will be added in the message posted for this subtype. If " +"void, the name will be added instead." +msgstr "" + +#. module: mail +#: field:mail.compose.message,vote_user_ids:0 +#: field:mail.message,vote_user_ids:0 +msgid "Votes" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Group" +msgstr "" + +#. module: mail +#: help:mail.compose.message,starred:0 +#: help:mail.message,starred:0 +msgid "Current user has a starred notification linked to this message" +msgstr "" + +#. module: mail +#: field:mail.group,public:0 +msgid "Privacy" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Notification" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail.js:650 +#, python-format +msgid "Please complete partner's informations" +msgstr "" + +#. module: mail +#: view:mail.wizard.invite:0 +msgid "Add Followers" +msgstr "" + +#. module: mail +#: view:mail.compose.message:0 +msgid "Followers of selected items and" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_force_thread_id:0 +msgid "Record Thread ID" +msgstr "" + +#. module: mail +#: model:ir.ui.menu,name:mail.mail_group_root +msgid "My Groups" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_archives_feeds +msgid "" +"

\n" +" No message found and no message sent yet.\n" +"

\n" +" Click on the top-right icon to compose a message. This\n" +" message will be sent by email if it's an internal " +"contact.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: field:mail.mail,state:0 +msgid "Status" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: selection:mail.mail,state:0 +msgid "Outgoing" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "All feeds" +msgstr "" + +#. module: mail +#: help:mail.compose.message,record_name:0 +#: help:mail.message,record_name:0 +msgid "Name get of the related document." +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_notifications +#: model:ir.model,name:mail.model_mail_notification +#: model:ir.ui.menu,name:mail.menu_email_notifications +#: field:mail.compose.message,notification_ids:0 +#: view:mail.message:0 +#: field:mail.message,notification_ids:0 +#: view:mail.notification:0 +msgid "Notifications" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +msgid "Search Alias" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_force_thread_id:0 +msgid "" +"Optional ID of a thread (record) to which all incoming messages will be " +"attached, even if they did not reply to it. If set, this will disable the " +"creation of new records completely." +msgstr "" + +#. module: mail +#: help:mail.message.subtype,name:0 +msgid "" +"Message subtype gives a more precise type on the message, especially for " +"system notifications. For example, it can be a notification related to a new " +"record (New), or to a stage change in a process (Stage change). Message " +"subtypes allow to precisely tune the notifications the user want to receive " +"on its wall." +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "by" +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_best_sales_practices +msgid "Best Sales Practices" +msgstr "" + +#. module: mail +#: selection:mail.group,public:0 +msgid "Selected Group Only" +msgstr "" + +#. module: mail +#: field:mail.group,message_is_follower:0 +#: field:mail.thread,message_is_follower:0 +#: field:res.partner,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: view:mail.mail:0 +msgid "User" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Groups" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Messages Search" +msgstr "" + +#. module: mail +#: field:mail.compose.message,date:0 +#: field:mail.message,date:0 +msgid "Date" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:34 +#, python-format +msgid "Post" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Extended Filters..." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:122 +#, python-format +msgid "To:" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:193 +#, python-format +msgid "Write to my followers" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,default:0 +msgid "Default" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:294 +#, python-format +msgid "show more message" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:246 +#, python-format +msgid "Mark as Todo" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,parent_id:0 +msgid "Parent subtype, used for automatic subscription." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_wizard_invite +msgid "Invite wizard" +msgstr "" + +#. module: mail +#: field:mail.group,message_summary:0 +#: field:mail.thread,message_summary:0 +#: field:res.partner,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,res_model:0 +msgid "" +"Model the subtype applies to. If False, this subtype applies to all models." +msgstr "" + +#. module: mail +#: field:mail.compose.message,subtype_id:0 +#: field:mail.followers,subtype_ids:0 +#: field:mail.message,subtype_id:0 +#: view:mail.message.subtype:0 +msgid "Subtype" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Group Form" +msgstr "" + +#. module: mail +#: field:mail.compose.message,starred:0 +#: field:mail.message,starred:0 +#: field:mail.notification,starred:0 +msgid "Starred" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:296 +#, python-format +msgid "more messages" +msgstr "" + +#. module: mail +#: code:addons/mail/update.py:93 +#, python-format +msgid "Error" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:13 +#, python-format +msgid "Following" +msgstr "" + +#. module: mail +#: sql_constraint:mail.alias:0 +msgid "" +"Unfortunately this email alias is already used, please choose a unique one" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_user_id:0 +msgid "" +"The owner of records created upon receiving emails on this alias. If this " +"field is not set the system will attempt to find the right owner based on " +"the sender (From) address, or will use the Administrator account if no " +"system user is found for that address." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:52 +#, python-format +msgid "And" +msgstr "" + +#. module: mail +#: field:mail.compose.message,message_id:0 +#: field:mail.message,message_id:0 +msgid "Message-Id" +msgstr "" + +#. module: mail +#: help:mail.group,image:0 +msgid "" +"This field holds the image used as photo for the group, limited to " +"1024x1024px." +msgstr "" + +#. module: mail +#: field:mail.compose.message,attachment_ids:0 +#: view:mail.mail:0 +#: field:mail.message,attachment_ids:0 +msgid "Attachments" +msgstr "" + +#. module: mail +#: field:mail.compose.message,record_name:0 +#: field:mail.message,record_name:0 +msgid "Message Record Name" +msgstr "" + +#. module: mail +#: field:mail.mail,email_cc:0 +msgid "Cc" +msgstr "" + +#. module: mail +#: help:mail.notification,starred:0 +msgid "Starred message that goes into the todo mailbox" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:125 +#: view:mail.compose.message:0 +#, python-format +msgid "Followers of" +msgstr "" + +#. module: mail +#: help:mail.mail,auto_delete:0 +msgid "Permanently delete this email after sending it, to save space" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_group_feeds +msgid "Discussion Group" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:242 +#, python-format +msgid "Done" +msgstr "" + +#. module: mail +#: model:mail.message.subtype,name:mail.mt_comment +msgid "Discussions" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:11 +#, python-format +msgid "Follow" +msgstr "" + +#. module: mail +#: field:mail.group,name:0 +msgid "Name" +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_all_employees +msgid "Whole Company" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:131 +#: code:addons/mail/static/src/xml/mail.xml:278 +#: view:mail.compose.message:0 +#, python-format +msgid "and" +msgstr "" + +#. module: mail +#: help:mail.mail,body_html:0 +msgid "Rich-text/HTML message" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Creation Month" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:306 +#, python-format +msgid "Compose new Message" +msgstr "" + +#. module: mail +#: field:mail.group,menu_id:0 +msgid "Related Menu" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Content" +msgstr "" + +#. module: mail +#: field:mail.mail,email_to:0 +msgid "To" +msgstr "" + +#. module: mail +#: field:mail.compose.message,notified_partner_ids:0 +#: field:mail.message,notified_partner_ids:0 +msgid "Notified partners" +msgstr "" + +#. module: mail +#: help:mail.group,public:0 +msgid "" +"This group is visible by non members. Invisible groups can add " +"members through the invite button." +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_board +msgid "Board meetings" +msgstr "" + +#. module: mail +#: constraint:mail.alias:0 +msgid "" +"Invalid expression, it must be a literal python dictionary definition e.g. " +"\"{'field': 'value'}\"" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_model_id:0 +msgid "Aliased Model" +msgstr "" + +#. module: mail +#: help:mail.compose.message,message_id:0 +#: help:mail.message,message_id:0 +msgid "Message unique identifier" +msgstr "" + +#. module: mail +#: field:mail.group,description:0 +#: field:mail.message.subtype,description:0 +msgid "Description" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_followers +msgid "Document Followers" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:35 +#, python-format +msgid "Remove this follower" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "Never" +msgstr "" + +#. module: mail +#: field:mail.mail,mail_server_id:0 +msgid "Outgoing mail server" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:919 +#, python-format +msgid "Partners email addresses not found" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: selection:mail.mail,state:0 +msgid "Sent" +msgstr "" + +#. module: mail +#: field:mail.mail,body_html:0 +msgid "Rich-text Contents" +msgstr "" + +#. module: mail +#: help:mail.compose.message,to_read:0 +#: help:mail.message,to_read:0 +msgid "Current user has an unread notification linked to this message" +msgstr "" + +#. module: mail +#: help:res.partner,notification_email_send:0 +msgid "" +"Choose in which case you want to receive an email when you receive new feeds." +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_groups +#: model:ir.ui.menu,name:mail.mail_allgroups +msgid "Join a group" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_group_feeds +msgid "" +"

\n" +" No message in this group.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:213 +#, python-format +msgid "Please, wait while the file is uploading." +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "" +"This group is visible by everyone,\n" +" including your customers if you " +"installed\n" +" the portal module." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:243 +#, python-format +msgid "Set back to Todo" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:128 +#, python-format +msgid "this document" +msgstr "" + +#. module: mail +#: field:mail.compose.message,filter_id:0 +msgid "Filters" +msgstr "" + +#. module: mail +#: field:res.partner,notification_email_send:0 +msgid "Receive Feeds by Email" +msgstr "" + +#. module: mail +#: help:base.config.settings,alias_domain:0 +msgid "" +"If you have setup a catch-all email domain redirected to the OpenERP server, " +"enter the domain name here." +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_mail_message +#: model:ir.ui.menu,name:mail.menu_mail_message +#: field:mail.group,message_ids:0 +#: view:mail.message:0 +#: field:mail.thread,message_ids:0 +#: field:res.partner,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:141 +#, python-format +msgid "others..." +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_star_feeds +#: model:ir.ui.menu,name:mail.mail_starfeeds +msgid "To-do" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: field:mail.alias,alias_name:0 +#: field:mail.group,alias_id:0 +#: field:res.users,alias_id:0 +msgid "Alias" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: mail +#: help:mail.compose.message,notification_ids:0 +#: help:mail.message,notification_ids:0 +msgid "" +"Technical field holding the message notifications. Use notified_partner_ids " +"to access notified partners." +msgstr "" + +#. module: mail +#: model:ir.ui.menu,name:mail.mail_feeds +#: model:ir.ui.menu,name:mail.mail_feeds_main +msgid "Messaging" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: field:mail.message.subtype,res_model:0 +msgid "Model" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Unread" +msgstr "" + +#. module: mail +#: help:mail.followers,subtype_ids:0 +msgid "" +"Message subtypes followed, meaning subtypes that will be pushed onto the " +"user's Wall." +msgstr "" + +#. module: mail +#: help:mail.group,message_ids:0 +#: help:mail.thread,message_ids:0 +#: help:res.partner,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: mail +#: help:mail.mail,references:0 +msgid "Message references, such as identifiers of previous messages" +msgstr "" + +#. module: mail +#: field:mail.compose.message,composition_mode:0 +msgid "Composition mode" +msgstr "" + +#. module: mail +#: field:mail.compose.message,model:0 +#: field:mail.followers,res_model:0 +#: field:mail.message,model:0 +#: field:mail.wizard.invite,res_model:0 +msgid "Related Document Model" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:321 +#, python-format +msgid "unlike" +msgstr "" + +#. module: mail +#: help:mail.compose.message,author_id:0 +#: help:mail.message,author_id:0 +msgid "" +"Author of the message. If not set, email_from may hold an email address that " +"did not match any partner." +msgstr "" + +#. module: mail +#: help:mail.mail,email_cc:0 +msgid "Carbon copy message recipients" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_domain:0 +msgid "Alias domain" +msgstr "" + +#. module: mail +#: code:addons/mail/update.py:93 +#, python-format +msgid "Error during communication with the publisher warranty server." +msgstr "" + +#. module: mail +#: selection:mail.group,public:0 +msgid "Private" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_star_feeds +msgid "" +"

\n" +" No todo.\n" +"

\n" +" When you process messages in your inbox, you can mark " +"some\n" +" as todo. From this menu, you can process all your " +"todo.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: selection:mail.mail,state:0 +msgid "Delivery Failed" +msgstr "" + +#. module: mail +#: field:mail.compose.message,partner_ids:0 +msgid "Additional contacts" +msgstr "" + +#. module: mail +#: help:mail.compose.message,parent_id:0 +#: help:mail.message,parent_id:0 +msgid "Initial thread message." +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_hr_policies +msgid "HR Policies" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "Emails only" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_inbox_feeds +#: model:ir.ui.menu,name:mail.mail_inboxfeeds +msgid "Inbox" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:58 +#, python-format +msgid "File" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/many2many_tags_email.js:63 +#, python-format +msgid "Please complete partner's informations and Email" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_message_subtype +#: model:ir.ui.menu,name:mail.menu_message_subtype +msgid "Subtypes" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_alias +msgid "Email Aliases" +msgstr "" + +#. module: mail +#: field:mail.group,image_small:0 +msgid "Small-sized photo" +msgstr "" + +#. module: mail +#: help:mail.mail,reply_to:0 +msgid "Preferred response address for the message" +msgstr "" diff --git a/addons/mail/i18n/ko.po b/addons/mail/i18n/ko.po new file mode 100644 index 00000000000..6315792f4fc --- /dev/null +++ b/addons/mail/i18n/ko.po @@ -0,0 +1,1687 @@ +# Korean translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-05-12 07:37+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-13 05:17+0000\n" +"X-Generator: Launchpad (build 16614)\n" + +#. module: mail +#: view:mail.followers:0 +msgid "Followers Form" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_publisher_warranty_contract +msgid "publisher_warranty.contract" +msgstr "" + +#. module: mail +#: field:mail.compose.message,author_id:0 +#: field:mail.message,author_id:0 +msgid "Author" +msgstr "작성자" + +#. module: mail +#: view:mail.mail:0 +msgid "Message Details" +msgstr "" + +#. module: mail +#: help:mail.mail,email_to:0 +msgid "Message recipients" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,default:0 +msgid "Activated by default when subscribing." +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Comments" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: view:mail.mail:0 +msgid "Group By..." +msgstr "" + +#. module: mail +#: help:mail.compose.message,body:0 +#: help:mail.message,body:0 +msgid "Automatically sanitized HTML contents" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_name:0 +msgid "" +"The name of the email alias, e.g. 'jobs' if you want to catch emails for " +"" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard +#: view:mail.compose.message:0 +msgid "Compose Email" +msgstr "메일 작성" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:132 +#, python-format +msgid "Add them into recipients and followers" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Group Name" +msgstr "그룹명" + +#. module: mail +#: selection:mail.group,public:0 +msgid "Public" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Body" +msgstr "본문" + +#. module: mail +#: view:mail.message:0 +msgid "Show messages to read" +msgstr "" + +#. module: mail +#: help:mail.compose.message,email_from:0 +#: help:mail.message,email_from:0 +msgid "" +"Email address of the sender. This field is set when no matching partner is " +"found for incoming emails." +msgstr "보내는 사람의 이메일 주소. 이 필드는 수신 메일에서 일치하는 파트너를 찾을 수 없을 때 설정됩니다." + +#. module: mail +#: model:ir.model,name:mail.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:23 +#, python-format +msgid "Add others" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,parent_id:0 +msgid "Parent" +msgstr "" + +#. module: mail +#: field:mail.group,message_unread:0 +#: field:mail.thread,message_unread:0 +#: field:res.partner,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:296 +#, python-format +msgid "show" +msgstr "" + +#. module: mail +#: help:mail.group,group_ids:0 +msgid "" +"Members of those groups will automatically added as followers. Note that " +"they will be able to manage their subscription manually if necessary." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail.js:1019 +#, python-format +msgid "Do you really want to delete this message?" +msgstr "" + +#. module: mail +#: view:mail.message:0 +#: field:mail.notification,read:0 +msgid "Read" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Search Groups" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail_followers.js:159 +#, python-format +msgid "followers" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:726 +#, python-format +msgid "Access Denied" +msgstr "" + +#. module: mail +#: help:mail.group,image_medium:0 +msgid "" +"Medium-sized photo of the group. It is automatically resized as a 128x128px " +"image, with aspect ratio preserved. Use this field in form views or some " +"kanban views." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:212 +#, python-format +msgid "Uploading error" +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_support +msgid "Support" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:727 +#, python-format +msgid "" +"The requested operation cannot be completed due to security restrictions. " +"Please contact your system administrator.\n" +"\n" +"(Document type: %s, Operation: %s)" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: selection:mail.mail,state:0 +msgid "Received" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Thread" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:29 +#, python-format +msgid "Open the full mail composer" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:29 +#, python-format +msgid "ò" +msgstr "" + +#. module: mail +#: field:base.config.settings,alias_domain:0 +msgid "Alias Domain" +msgstr "" + +#. module: mail +#: field:mail.group,group_ids:0 +msgid "Auto Subscription" +msgstr "" + +#. module: mail +#: field:mail.mail,references:0 +msgid "References" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:206 +#, python-format +msgid "No messages." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_group +msgid "Discussion group" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:98 +#: code:addons/mail/static/src/xml/mail.xml:110 +#, python-format +msgid "uploading" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:52 +#, python-format +msgid "more." +msgstr "" + +#. module: mail +#: help:mail.compose.message,type:0 +#: help:mail.message,type:0 +msgid "" +"Message type: email for email message, notification for system message, " +"comment for other messages such as user replies" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,relation_field:0 +msgid "" +"Field used to link the related model to the subtype model when using " +"automatic subscription on a related document. The field is used to compute " +"getattr(related_document.relation_field)." +msgstr "" + +#. module: mail +#: selection:mail.mail,state:0 +msgid "Cancelled" +msgstr "" + +#. module: mail +#: field:mail.mail,reply_to:0 +msgid "Reply-To" +msgstr "" + +#. module: mail +#: code:addons/mail/wizard/invite.py:37 +#, python-format +msgid "
You have been invited to follow %s.
" +msgstr "" + +#. module: mail +#: help:mail.group,message_unread:0 +#: help:mail.thread,message_unread:0 +#: help:res.partner,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: mail +#: field:mail.group,image_medium:0 +msgid "Medium-sized photo" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_to_me_feeds +#: model:ir.ui.menu,name:mail.mail_tomefeeds +msgid "To: me" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,name:0 +msgid "Message Type" +msgstr "" + +#. module: mail +#: field:mail.mail,auto_delete:0 +msgid "Auto Delete" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:12 +#: view:mail.group:0 +#, python-format +msgid "Unfollow" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:295 +#, python-format +msgid "show one more message" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_mail.py:74 +#: code:addons/mail/res_users.py:69 +#, python-format +msgid "Invalid Action!" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:25 +#, python-format +msgid "User img" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_mail_mail +#: model:ir.ui.menu,name:mail.menu_mail_mail +#: view:mail.mail:0 +#: view:mail.message:0 +msgid "Emails" +msgstr "" + +#. module: mail +#: field:mail.followers,partner_id:0 +msgid "Related Partner" +msgstr "" + +#. module: mail +#: help:mail.group,message_summary:0 +#: help:mail.thread,message_summary:0 +#: help:res.partner,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: mail +#: help:mail.alias,alias_model_id:0 +msgid "" +"The model (OpenERP Document Kind) to which this alias corresponds. Any " +"incoming email that does not reply to an existing record will cause the " +"creation of a new record of this model (e.g. a Project Task)" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,relation_field:0 +msgid "Relation field" +msgstr "" + +#. module: mail +#: selection:mail.compose.message,type:0 +#: selection:mail.message,type:0 +msgid "System notification" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_res_partner +#: view:mail.mail:0 +msgid "Partner" +msgstr "" + +#. module: mail +#: model:ir.ui.menu,name:mail.mail_my_stuff +msgid "Organizer" +msgstr "" + +#. module: mail +#: field:mail.compose.message,subject:0 +#: field:mail.message,subject:0 +msgid "Subject" +msgstr "" + +#. module: mail +#: field:mail.wizard.invite,partner_ids:0 +msgid "Partners" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Retry" +msgstr "" + +#. module: mail +#: field:mail.compose.message,email_from:0 +#: field:mail.mail,email_from:0 +#: field:mail.message,email_from:0 +msgid "From" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: view:mail.message.subtype:0 +msgid "Email message" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_base_config_settings +msgid "base.config.settings" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:36 +#: view:mail.compose.message:0 +#, python-format +msgid "Send" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail_followers.js:155 +#, python-format +msgid "No followers" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Failed" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:22 +#: model:ir.actions.act_window,name:mail.action_view_followers +#: model:ir.ui.menu,name:mail.menu_email_followers +#: view:mail.followers:0 +#: field:mail.group,message_follower_ids:0 +#: field:mail.thread,message_follower_ids:0 +#: field:res.partner,message_follower_ids:0 +#, python-format +msgid "Followers" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_archives_feeds +#: model:ir.ui.menu,name:mail.mail_archivesfeeds +msgid "Archives" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:97 +#: code:addons/mail/static/src/xml/mail.xml:109 +#, python-format +msgid "Delete this attachment" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:245 +#: view:mail.mail:0 +#, python-format +msgid "Reply" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail_followers.js:157 +#, python-format +msgid "One follower" +msgstr "" + +#. module: mail +#: field:mail.compose.message,type:0 +#: field:mail.message,type:0 +msgid "Type" +msgstr "" + +#. module: mail +#: selection:mail.compose.message,type:0 +#: view:mail.mail:0 +#: selection:mail.message,type:0 +msgid "Email" +msgstr "" + +#. module: mail +#: field:ir.ui.menu,mail_group_id:0 +msgid "Mail Group" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "Comments and Emails" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_defaults:0 +msgid "Default Values" +msgstr "" + +#. module: mail +#: code:addons/mail/res_users.py:89 +#, python-format +msgid "%s has joined the %s network." +msgstr "" + +#. module: mail +#: help:mail.group,image_small:0 +msgid "" +"Small-sized photo of the group. It is automatically resized as a 64x64px " +"image, with aspect ratio preserved. Use this field anywhere a small image is " +"required." +msgstr "" + +#. module: mail +#: view:mail.compose.message:0 +#: field:mail.message,partner_ids:0 +msgid "Recipients" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:142 +#, python-format +msgid "<<<" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:43 +#, python-format +msgid "Write to the followers of this document..." +msgstr "" + +#. module: mail +#: field:mail.group,group_public_id:0 +msgid "Authorized Group" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Join Group" +msgstr "" + +#. module: mail +#: help:mail.mail,email_from:0 +msgid "Message sender, taken from user preferences." +msgstr "" + +#. module: mail +#: code:addons/mail/wizard/invite.py:40 +#, python-format +msgid "
You have been invited to follow a new document.
" +msgstr "" + +#. module: mail +#: field:mail.compose.message,parent_id:0 +#: field:mail.message,parent_id:0 +msgid "Parent Message" +msgstr "" + +#. module: mail +#: field:mail.compose.message,res_id:0 +#: field:mail.followers,res_id:0 +#: field:mail.message,res_id:0 +#: field:mail.wizard.invite,res_id:0 +msgid "Related Document ID" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_to_me_feeds +msgid "" +"

\n" +" No private message.\n" +"

\n" +" This list contains messages sent to you.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_rd +msgid "R&D" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:61 +#, python-format +msgid "/web/binary/upload_attachment" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Advanced" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:244 +#, python-format +msgid "Move to Inbox" +msgstr "" + +#. module: mail +#: code:addons/mail/wizard/mail_compose_message.py:165 +#, python-format +msgid "Re:" +msgstr "" + +#. module: mail +#: field:mail.compose.message,to_read:0 +#: field:mail.message,to_read:0 +msgid "To read" +msgstr "" + +#. module: mail +#: code:addons/mail/res_users.py:69 +#, python-format +msgid "" +"You may not create a user. To create new users, you should use the " +"\"Settings > Users\" menu." +msgstr "" + +#. module: mail +#: help:mail.followers,res_model:0 +#: help:mail.wizard.invite,res_model:0 +msgid "Model of the followed resource" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:320 +#, python-format +msgid "like" +msgstr "" + +#. module: mail +#: view:mail.compose.message:0 +#: view:mail.wizard.invite:0 +msgid "Cancel" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:47 +#, python-format +msgid "Share with my followers..." +msgstr "" + +#. module: mail +#: field:mail.notification,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "" +"Only the invited followers can read the\n" +" discussions on this group." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_ir_ui_menu +msgid "ir.ui.menu" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Has attachments" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "on" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:915 +#, python-format +msgid "" +"The following partners chosen as recipients for the email have no email " +"address linked :" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_defaults:0 +msgid "" +"A Python dictionary that will be evaluated to provide default values when " +"creating new records for this alias." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_message_subtype +msgid "Message subtypes" +msgstr "" + +#. module: mail +#: help:mail.compose.message,notified_partner_ids:0 +#: help:mail.message,notified_partner_ids:0 +msgid "" +"Partners that have a notification pushing this message in their mailboxes" +msgstr "" + +#. module: mail +#: selection:mail.compose.message,type:0 +#: view:mail.mail:0 +#: selection:mail.message,type:0 +msgid "Comment" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_inbox_feeds +msgid "" +"

\n" +" Good Job! Your inbox is empty.\n" +"

\n" +" Your inbox contains private messages or emails sent to " +"you\n" +" as well as information related to documents or people " +"you\n" +" follow.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: field:mail.mail,notification:0 +msgid "Is Notification" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:188 +#, python-format +msgid "Compose a new message" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Send Now" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_mail.py:74 +#, python-format +msgid "" +"Unable to send email, please configure the sender's email address or alias." +msgstr "" + +#. module: mail +#: help:res.users,alias_id:0 +msgid "" +"Email address internally associated with this user. Incoming emails will " +"appear in the user's notifications." +msgstr "" + +#. module: mail +#: field:mail.group,image:0 +msgid "Photo" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:56 +#: code:addons/mail/static/src/xml/mail.xml:191 +#: view:mail.compose.message:0 +#: view:mail.wizard.invite:0 +#, python-format +msgid "or" +msgstr "" + +#. module: mail +#: help:mail.compose.message,vote_user_ids:0 +#: help:mail.message,vote_user_ids:0 +msgid "Users that voted for this message" +msgstr "" + +#. module: mail +#: help:mail.group,alias_id:0 +msgid "" +"The email address associated with this group. New emails received will " +"automatically create new topics." +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Month" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Email Search" +msgstr "" + +#. module: mail +#: field:mail.compose.message,child_ids:0 +#: field:mail.message,child_ids:0 +msgid "Child Messages" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_user_id:0 +msgid "Owner" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_res_users +msgid "Users" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_message +#: field:mail.mail,mail_message_id:0 +#: view:mail.message:0 +#: field:mail.notification,message_id:0 +#: field:mail.wizard.invite,message:0 +msgid "Message" +msgstr "" + +#. module: mail +#: help:mail.followers,res_id:0 +#: help:mail.wizard.invite,res_id:0 +msgid "Id of the followed resource" +msgstr "" + +#. module: mail +#: field:mail.compose.message,body:0 +#: field:mail.message,body:0 +msgid "Contents" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_mail_alias +#: model:ir.ui.menu,name:mail.mail_alias_menu +msgid "Aliases" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,description:0 +msgid "" +"Description that will be added in the message posted for this subtype. If " +"void, the name will be added instead." +msgstr "" + +#. module: mail +#: field:mail.compose.message,vote_user_ids:0 +#: field:mail.message,vote_user_ids:0 +msgid "Votes" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Group" +msgstr "" + +#. module: mail +#: help:mail.compose.message,starred:0 +#: help:mail.message,starred:0 +msgid "Current user has a starred notification linked to this message" +msgstr "" + +#. module: mail +#: field:mail.group,public:0 +msgid "Privacy" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Notification" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/mail.js:650 +#, python-format +msgid "Please complete partner's informations" +msgstr "" + +#. module: mail +#: view:mail.wizard.invite:0 +msgid "Add Followers" +msgstr "" + +#. module: mail +#: view:mail.compose.message:0 +msgid "Followers of selected items and" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_force_thread_id:0 +msgid "Record Thread ID" +msgstr "" + +#. module: mail +#: model:ir.ui.menu,name:mail.mail_group_root +msgid "My Groups" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_archives_feeds +msgid "" +"

\n" +" No message found and no message sent yet.\n" +"

\n" +" Click on the top-right icon to compose a message. This\n" +" message will be sent by email if it's an internal " +"contact.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: field:mail.mail,state:0 +msgid "Status" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: selection:mail.mail,state:0 +msgid "Outgoing" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "All feeds" +msgstr "" + +#. module: mail +#: help:mail.compose.message,record_name:0 +#: help:mail.message,record_name:0 +msgid "Name get of the related document." +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_notifications +#: model:ir.model,name:mail.model_mail_notification +#: model:ir.ui.menu,name:mail.menu_email_notifications +#: field:mail.compose.message,notification_ids:0 +#: view:mail.message:0 +#: field:mail.message,notification_ids:0 +#: view:mail.notification:0 +msgid "Notifications" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +msgid "Search Alias" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_force_thread_id:0 +msgid "" +"Optional ID of a thread (record) to which all incoming messages will be " +"attached, even if they did not reply to it. If set, this will disable the " +"creation of new records completely." +msgstr "" + +#. module: mail +#: help:mail.message.subtype,name:0 +msgid "" +"Message subtype gives a more precise type on the message, especially for " +"system notifications. For example, it can be a notification related to a new " +"record (New), or to a stage change in a process (Stage change). Message " +"subtypes allow to precisely tune the notifications the user want to receive " +"on its wall." +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "by" +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_best_sales_practices +msgid "Best Sales Practices" +msgstr "" + +#. module: mail +#: selection:mail.group,public:0 +msgid "Selected Group Only" +msgstr "" + +#. module: mail +#: field:mail.group,message_is_follower:0 +#: field:mail.thread,message_is_follower:0 +#: field:res.partner,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: view:mail.mail:0 +msgid "User" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Groups" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Messages Search" +msgstr "" + +#. module: mail +#: field:mail.compose.message,date:0 +#: field:mail.message,date:0 +msgid "Date" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:34 +#, python-format +msgid "Post" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Extended Filters..." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:122 +#, python-format +msgid "To:" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:193 +#, python-format +msgid "Write to my followers" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: mail +#: field:mail.message.subtype,default:0 +msgid "Default" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:294 +#, python-format +msgid "show more message" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:246 +#, python-format +msgid "Mark as Todo" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,parent_id:0 +msgid "Parent subtype, used for automatic subscription." +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_wizard_invite +msgid "Invite wizard" +msgstr "" + +#. module: mail +#: field:mail.group,message_summary:0 +#: field:mail.thread,message_summary:0 +#: field:res.partner,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: mail +#: help:mail.message.subtype,res_model:0 +msgid "" +"Model the subtype applies to. If False, this subtype applies to all models." +msgstr "" + +#. module: mail +#: field:mail.compose.message,subtype_id:0 +#: field:mail.followers,subtype_ids:0 +#: field:mail.message,subtype_id:0 +#: view:mail.message.subtype:0 +msgid "Subtype" +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "Group Form" +msgstr "" + +#. module: mail +#: field:mail.compose.message,starred:0 +#: field:mail.message,starred:0 +#: field:mail.notification,starred:0 +msgid "Starred" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:296 +#, python-format +msgid "more messages" +msgstr "" + +#. module: mail +#: code:addons/mail/update.py:93 +#, python-format +msgid "Error" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:13 +#, python-format +msgid "Following" +msgstr "" + +#. module: mail +#: sql_constraint:mail.alias:0 +msgid "" +"Unfortunately this email alias is already used, please choose a unique one" +msgstr "" + +#. module: mail +#: help:mail.alias,alias_user_id:0 +msgid "" +"The owner of records created upon receiving emails on this alias. If this " +"field is not set the system will attempt to find the right owner based on " +"the sender (From) address, or will use the Administrator account if no " +"system user is found for that address." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:52 +#, python-format +msgid "And" +msgstr "" + +#. module: mail +#: field:mail.compose.message,message_id:0 +#: field:mail.message,message_id:0 +msgid "Message-Id" +msgstr "" + +#. module: mail +#: help:mail.group,image:0 +msgid "" +"This field holds the image used as photo for the group, limited to " +"1024x1024px." +msgstr "" + +#. module: mail +#: field:mail.compose.message,attachment_ids:0 +#: view:mail.mail:0 +#: field:mail.message,attachment_ids:0 +msgid "Attachments" +msgstr "" + +#. module: mail +#: field:mail.compose.message,record_name:0 +#: field:mail.message,record_name:0 +msgid "Message Record Name" +msgstr "" + +#. module: mail +#: field:mail.mail,email_cc:0 +msgid "Cc" +msgstr "" + +#. module: mail +#: help:mail.notification,starred:0 +msgid "Starred message that goes into the todo mailbox" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:125 +#: view:mail.compose.message:0 +#, python-format +msgid "Followers of" +msgstr "" + +#. module: mail +#: help:mail.mail,auto_delete:0 +msgid "Permanently delete this email after sending it, to save space" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_group_feeds +msgid "Discussion Group" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:242 +#, python-format +msgid "Done" +msgstr "" + +#. module: mail +#: model:mail.message.subtype,name:mail.mt_comment +msgid "Discussions" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:11 +#, python-format +msgid "Follow" +msgstr "" + +#. module: mail +#: field:mail.group,name:0 +msgid "Name" +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_all_employees +msgid "Whole Company" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:131 +#: code:addons/mail/static/src/xml/mail.xml:278 +#: view:mail.compose.message:0 +#, python-format +msgid "and" +msgstr "" + +#. module: mail +#: help:mail.mail,body_html:0 +msgid "Rich-text/HTML message" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +msgid "Creation Month" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:306 +#, python-format +msgid "Compose new Message" +msgstr "" + +#. module: mail +#: field:mail.group,menu_id:0 +msgid "Related Menu" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Content" +msgstr "" + +#. module: mail +#: field:mail.mail,email_to:0 +msgid "To" +msgstr "" + +#. module: mail +#: field:mail.compose.message,notified_partner_ids:0 +#: field:mail.message,notified_partner_ids:0 +msgid "Notified partners" +msgstr "" + +#. module: mail +#: help:mail.group,public:0 +msgid "" +"This group is visible by non members. Invisible groups can add " +"members through the invite button." +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_board +msgid "Board meetings" +msgstr "" + +#. module: mail +#: constraint:mail.alias:0 +msgid "" +"Invalid expression, it must be a literal python dictionary definition e.g. " +"\"{'field': 'value'}\"" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_model_id:0 +msgid "Aliased Model" +msgstr "" + +#. module: mail +#: help:mail.compose.message,message_id:0 +#: help:mail.message,message_id:0 +msgid "Message unique identifier" +msgstr "" + +#. module: mail +#: field:mail.group,description:0 +#: field:mail.message.subtype,description:0 +msgid "Description" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_followers +msgid "Document Followers" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail_followers.xml:35 +#, python-format +msgid "Remove this follower" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "Never" +msgstr "" + +#. module: mail +#: field:mail.mail,mail_server_id:0 +msgid "Outgoing mail server" +msgstr "" + +#. module: mail +#: code:addons/mail/mail_message.py:919 +#, python-format +msgid "Partners email addresses not found" +msgstr "" + +#. module: mail +#: view:mail.mail:0 +#: selection:mail.mail,state:0 +msgid "Sent" +msgstr "" + +#. module: mail +#: field:mail.mail,body_html:0 +msgid "Rich-text Contents" +msgstr "" + +#. module: mail +#: help:mail.compose.message,to_read:0 +#: help:mail.message,to_read:0 +msgid "Current user has an unread notification linked to this message" +msgstr "" + +#. module: mail +#: help:res.partner,notification_email_send:0 +msgid "" +"Choose in which case you want to receive an email when you receive new feeds." +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_groups +#: model:ir.ui.menu,name:mail.mail_allgroups +msgid "Join a group" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_group_feeds +msgid "" +"

\n" +" No message in this group.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:213 +#, python-format +msgid "Please, wait while the file is uploading." +msgstr "" + +#. module: mail +#: view:mail.group:0 +msgid "" +"This group is visible by everyone,\n" +" including your customers if you " +"installed\n" +" the portal module." +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:243 +#, python-format +msgid "Set back to Todo" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:128 +#, python-format +msgid "this document" +msgstr "" + +#. module: mail +#: field:mail.compose.message,filter_id:0 +msgid "Filters" +msgstr "" + +#. module: mail +#: field:res.partner,notification_email_send:0 +msgid "Receive Feeds by Email" +msgstr "" + +#. module: mail +#: help:base.config.settings,alias_domain:0 +msgid "" +"If you have setup a catch-all email domain redirected to the OpenERP server, " +"enter the domain name here." +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_mail_message +#: model:ir.ui.menu,name:mail.menu_mail_message +#: field:mail.group,message_ids:0 +#: view:mail.message:0 +#: field:mail.thread,message_ids:0 +#: field:res.partner,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:141 +#, python-format +msgid "others..." +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_star_feeds +#: model:ir.ui.menu,name:mail.mail_starfeeds +msgid "To-do" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: field:mail.alias,alias_name:0 +#: field:mail.group,alias_id:0 +#: field:res.users,alias_id:0 +msgid "Alias" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: mail +#: help:mail.compose.message,notification_ids:0 +#: help:mail.message,notification_ids:0 +msgid "" +"Technical field holding the message notifications. Use notified_partner_ids " +"to access notified partners." +msgstr "" + +#. module: mail +#: model:ir.ui.menu,name:mail.mail_feeds +#: model:ir.ui.menu,name:mail.mail_feeds_main +msgid "Messaging" +msgstr "" + +#. module: mail +#: view:mail.alias:0 +#: field:mail.message.subtype,res_model:0 +msgid "Model" +msgstr "" + +#. module: mail +#: view:mail.message:0 +msgid "Unread" +msgstr "읽지 않음" + +#. module: mail +#: help:mail.followers,subtype_ids:0 +msgid "" +"Message subtypes followed, meaning subtypes that will be pushed onto the " +"user's Wall." +msgstr "" + +#. module: mail +#: help:mail.group,message_ids:0 +#: help:mail.thread,message_ids:0 +#: help:res.partner,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: mail +#: help:mail.mail,references:0 +msgid "Message references, such as identifiers of previous messages" +msgstr "" + +#. module: mail +#: field:mail.compose.message,composition_mode:0 +msgid "Composition mode" +msgstr "" + +#. module: mail +#: field:mail.compose.message,model:0 +#: field:mail.followers,res_model:0 +#: field:mail.message,model:0 +#: field:mail.wizard.invite,res_model:0 +msgid "Related Document Model" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:321 +#, python-format +msgid "unlike" +msgstr "" + +#. module: mail +#: help:mail.compose.message,author_id:0 +#: help:mail.message,author_id:0 +msgid "" +"Author of the message. If not set, email_from may hold an email address that " +"did not match any partner." +msgstr "" + +#. module: mail +#: help:mail.mail,email_cc:0 +msgid "Carbon copy message recipients" +msgstr "" + +#. module: mail +#: field:mail.alias,alias_domain:0 +msgid "Alias domain" +msgstr "" + +#. module: mail +#: code:addons/mail/update.py:93 +#, python-format +msgid "Error during communication with the publisher warranty server." +msgstr "" + +#. module: mail +#: selection:mail.group,public:0 +msgid "Private" +msgstr "" + +#. module: mail +#: model:ir.actions.client,help:mail.action_mail_star_feeds +msgid "" +"

\n" +" No todo.\n" +"

\n" +" When you process messages in your inbox, you can mark " +"some\n" +" as todo. From this menu, you can process all your " +"todo.\n" +"

\n" +" " +msgstr "" + +#. module: mail +#: selection:mail.mail,state:0 +msgid "Delivery Failed" +msgstr "" + +#. module: mail +#: field:mail.compose.message,partner_ids:0 +msgid "Additional contacts" +msgstr "" + +#. module: mail +#: help:mail.compose.message,parent_id:0 +#: help:mail.message,parent_id:0 +msgid "Initial thread message." +msgstr "" + +#. module: mail +#: model:mail.group,name:mail.group_hr_policies +msgid "HR Policies" +msgstr "" + +#. module: mail +#: selection:res.partner,notification_email_send:0 +msgid "Emails only" +msgstr "" + +#. module: mail +#: model:ir.actions.client,name:mail.action_mail_inbox_feeds +#: model:ir.ui.menu,name:mail.mail_inboxfeeds +msgid "Inbox" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/xml/mail.xml:58 +#, python-format +msgid "File" +msgstr "" + +#. module: mail +#. openerp-web +#: code:addons/mail/static/src/js/many2many_tags_email.js:63 +#, python-format +msgid "Please complete partner's informations and Email" +msgstr "" + +#. module: mail +#: model:ir.actions.act_window,name:mail.action_view_message_subtype +#: model:ir.ui.menu,name:mail.menu_message_subtype +msgid "Subtypes" +msgstr "" + +#. module: mail +#: model:ir.model,name:mail.model_mail_alias +msgid "Email Aliases" +msgstr "" + +#. module: mail +#: field:mail.group,image_small:0 +msgid "Small-sized photo" +msgstr "" + +#. module: mail +#: help:mail.mail,reply_to:0 +msgid "Preferred response address for the message" +msgstr "" diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py index d5e3b675b56..870695e074e 100644 --- a/addons/mail/mail_alias.py +++ b/addons/mail/mail_alias.py @@ -117,8 +117,13 @@ class mail_alias(osv.Model): mail catchall domain from config. e.g. `jobs@openerp.my.openerp.com` or `sales@openerp.my.openerp.com` """ - return [(record['id'], "%s@%s" % (record['alias_name'], record['alias_domain'])) - for record in self.read(cr, uid, ids, ['alias_name', 'alias_domain'], context=context)] + res = [] + for record in self.browse(cr, uid, ids, context=context): + if record.alias_name and record.alias_domain: + res.append((record['id'], "%s@%s" % (record.alias_name, record.alias_domain))) + else: + res.append((record['id'], False)) + return res def _find_unique(self, cr, uid, name, context=None): """Find a unique alias name similar to ``name``. If ``name`` is @@ -134,7 +139,7 @@ class mail_alias(osv.Model): return new_name def migrate_to_alias(self, cr, child_model_name, child_table_name, child_model_auto_init_fct, - alias_id_column, alias_key, alias_prefix = '', alias_force_key = '', alias_defaults = {}, context=None): + alias_id_column, alias_key, alias_prefix='', alias_force_key='', alias_defaults={}, context=None): """ Installation hook to create aliases for all users and avoid constraint errors. :param child_model_name: model name of the child class (i.e. res.users) @@ -149,25 +154,27 @@ class mail_alias(osv.Model): :param alias_defaults: dict, keys = mail.alias columns, values = child model column name used for default values (i.e. {'job_id': 'id'}) """ + if context is None: + context = {} - # disable the unique alias_id not null constraint, to avoid spurious warning during + # disable the unique alias_id not null constraint, to avoid spurious warning during # super.auto_init. We'll reinstall it afterwards. alias_id_column.required = False # call _auto_init - child_model_auto_init_fct(cr, context=context) + res = child_model_auto_init_fct(cr, context=context) registry = RegistryManager.get(cr.dbname) mail_alias = registry.get('mail.alias') - child_class_model = registry.get(child_model_name) - no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test':False}) + child_class_model = registry[child_model_name] + no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test': False}) # Use read() not browse(), to avoid prefetching uninitialized inherited fields for obj_data in child_class_model.read(cr, SUPERUSER_ID, no_alias_ids, [alias_key]): - alias_vals = {'alias_name': '%s%s' % (alias_prefix, obj_data[alias_key]) } + alias_vals = {'alias_name': '%s%s' % (alias_prefix, obj_data[alias_key])} if alias_force_key: alias_vals['alias_force_thread_id'] = obj_data[alias_force_key] - alias_vals['alias_defaults'] = dict( (k, obj_data[v]) for k, v in alias_defaults.iteritems()) - alias_id = mail_alias.create_unique_alias(cr, SUPERUSER_ID, alias_vals, model_name=child_model_name) + alias_vals['alias_defaults'] = dict((k, obj_data[v]) for k, v in alias_defaults.iteritems()) + alias_id = mail_alias.create_unique_alias(cr, SUPERUSER_ID, alias_vals, model_name=context.get('alias_model_name', child_model_name)) child_class_model.write(cr, SUPERUSER_ID, obj_data['id'], {'alias_id': alias_id}) _logger.info('Mail alias created for %s %s (uid %s)', child_model_name, obj_data[alias_key], obj_data['id']) @@ -183,6 +190,8 @@ class mail_alias(osv.Model): # set back the unique alias_id constraint alias_id_column.required = True + return res + def create_unique_alias(self, cr, uid, vals, model_name=None, context=None): """Creates an email.alias record according to the values provided in ``vals``, with 2 alterations: the ``alias_name`` value may be suffixed in order to diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py index d729efc0f5c..98e88b664e6 100644 --- a/addons/mail/mail_followers.py +++ b/addons/mail/mail_followers.py @@ -90,7 +90,7 @@ class mail_notification(osv.Model): continue partner = notification.partner_id # If partners_to_notify specified: restrict to them - if partners_to_notify and partner.id not in partners_to_notify: + if partners_to_notify is not None and partner.id not in partners_to_notify: continue # Do not send to partners without email address defined if not partner.email: @@ -118,8 +118,8 @@ class mail_notification(osv.Model): Administrator

- Send by Your Company using OpenERP. OR - Send by Administrator using OpenERP. + Sent by Your Company using OpenERP. OR + Sent by Administrator using OpenERP.
""" footer = "" @@ -135,11 +135,14 @@ class mail_notification(osv.Model): footer = tools.append_content_to_html(footer, signature, plaintext=False, container_tag='p') # add company signature - if user.company_id: - company = user.company_id.website and "%s" % (user.company_id.website, user.company_id.name) or user.company_id.name + if user.company_id.website: + website_url = ('http://%s' % user.company_id.website) if not user.company_id.website.lower().startswith(('http:', 'https:')) \ + else user.company_id.website + company = "%s" % (website_url, user.company_id.name) else: - company = user.name - signature_company = _('Send by %(company)s using %(openerp)s.' % { + company = user.company_id.name + sent_by = _('Sent by %(company)s using %(openerp)s.') + signature_company = '%s' % (sent_by % { 'company': company, 'openerp': "OpenERP" }) diff --git a/addons/mail/mail_group.py b/addons/mail/mail_group.py index 24aed942b1b..977608f487e 100644 --- a/addons/mail/mail_group.py +++ b/addons/mail/mail_group.py @@ -144,11 +144,19 @@ class mail_group(osv.Model): search_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'view_message_search') params = { 'search_view_id': search_ref and search_ref[1] or False, - 'domain': [('model', '=', 'mail.group'), ('res_id', '=', mail_group_id)], - 'context': {'default_model': 'mail.group', 'default_res_id': mail_group_id, 'search_default_message_unread': True}, + 'domain': [ + ('model', '=', 'mail.group'), + ('res_id', '=', mail_group_id), + ], + 'context': { + 'default_model': 'mail.group', + 'default_res_id': mail_group_id, + }, 'res_model': 'mail.message', 'thread_level': 1, - 'header_description': self._generate_header_description(cr, uid, group, context=context) + 'header_description': self._generate_header_description(cr, uid, group, context=context), + 'view_mailbox': True, + 'compose_placeholder': 'Send a message to the group', } cobj = self.pool.get('ir.actions.client') newref = cobj.copy(cr, SUPERUSER_ID, ref[1], default={'params': str(params), 'name': vals['name']}, context=context) diff --git a/addons/mail/mail_group_view.xml b/addons/mail/mail_group_view.xml index 77c0b8f6c86..04212b2f58a 100644 --- a/addons/mail/mail_group_view.xml +++ b/addons/mail/mail_group_view.xml @@ -7,7 +7,6 @@ mail.wall mail.message { - 'search_default_message_unread': True } { 'read_action': 'read' @@ -30,6 +29,7 @@ +
@@ -43,6 +43,9 @@

+
+ %% +
@@ -69,39 +72,43 @@
- +

-
- -
+
- - - - - - - -
- This group is visible by everyone, - including your customers if you installed - the portal module. -
-
- Only the invited followers can read the - discussions on this group. -
-
+ + + + + + +
+ This group is visible by everyone, + including your customers if you installed + the portal module. +
+
+ Only the invited followers can read the + discussions on this group. +
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index c5a7e227465..7b2eff5e743 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -28,7 +28,6 @@ from urlparse import urljoin from openerp import tools from openerp import SUPERUSER_ID from openerp.osv import fields, osv -from openerp.osv.orm import except_orm from openerp.tools.translate import _ _logger = logging.getLogger(__name__) @@ -93,32 +92,42 @@ class mail_mail(osv.Model): """ Return a specific reply_to: alias of the document through message_get_reply_to or take the email_from """ + # if value specified: directly return it if values.get('reply_to'): return values.get('reply_to') - email_reply_to = False - # model, res_id: comes from values OR related message - model = values.get('model') - res_id = values.get('res_id') - if values.get('mail_message_id') and (not model or not res_id): + mailgateway = True # tells whether the answer will go through the mailgateway, leading to the formatting of reply_to + ir_config_parameter = self.pool.get("ir.config_parameter") + catchall_domain = ir_config_parameter.get_param(cr, uid, "mail.catchall.domain", context=context) + + # model, res_id, email_from, reply_to: comes from values OR related message + message = None + if values.get('mail_message_id'): message = self.pool.get('mail.message').browse(cr, uid, values.get('mail_message_id'), context=context) - if not model: - model = message.model - if not res_id: - res_id = message.res_id + model = values.get('model', message and message.model or False) + res_id = values.get('res_id', message and message.res_id or False) + email_from = values.get('email_from', message and message.email_from or False) + email_reply_to = message and message.reply_to or False # if model and res_id: try to use ``message_get_reply_to`` that returns the document alias - if model and res_id and hasattr(self.pool.get(model), 'message_get_reply_to'): - email_reply_to = self.pool.get(model).message_get_reply_to(cr, uid, [res_id], context=context)[0] + if not email_reply_to and model and res_id and hasattr(self.pool[model], 'message_get_reply_to'): + email_reply_to = self.pool[model].message_get_reply_to(cr, uid, [res_id], context=context)[0] + # no alias reply_to -> catchall alias + if not email_reply_to: + catchall_alias = ir_config_parameter.get_param(cr, uid, "mail.catchall.alias", context=context) + if catchall_domain and catchall_alias: + email_reply_to = '%s@%s' % (catchall_alias, catchall_domain) # no alias reply_to -> reply_to will be the email_from, only the email part - if not email_reply_to and values.get('email_from'): - emails = tools.email_split(values.get('email_from')) + if not email_reply_to and email_from: + emails = tools.email_split(email_from) if emails: email_reply_to = emails[0] + if emails[0].split('@')[1] != catchall_domain: + mailgateway = False # format 'Document name ' - if email_reply_to and model and res_id: - document_name = self.pool.get(model).name_get(cr, SUPERUSER_ID, [res_id], context=context)[0] + if email_reply_to and model and res_id and mailgateway: + document_name = self.pool[model].name_get(cr, SUPERUSER_ID, [res_id], context=context)[0] if document_name: # sanitize document name sanitized_doc_name = re.sub(r'[^\w+.]+', '-', document_name[1]) @@ -195,6 +204,36 @@ class mail_mail(osv.Model): self.unlink(cr, SUPERUSER_ID, [mail.id], context=context) return True + #------------------------------------------------------ + # mail_mail formatting, tools and send mechanism + #------------------------------------------------------ + + # TODO in 8.0(+): maybe factorize this to enable in modules link generation + # independently of mail_mail model + # TODO in 8.0(+): factorize doc name sanitized and 'Followers of ...' formatting + # because it begins to appear everywhere + + def _get_partner_access_link(self, cr, uid, mail, partner=None, context=None): + """ Generate URLs for links in mails: + - partner is an user and has read access to the document: direct link to document with model, res_id + """ + if partner and partner.user_ids: + base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') + # the parameters to encode for the query and fragment part of url + query = {'db': cr.dbname} + fragment = { + 'login': partner.user_ids[0].login, + 'action': 'mail.action_mail_redirect', + } + if mail.notification: + fragment.update({ + 'message_id': mail.mail_message_id.id, + }) + url = urljoin(base_url, "?%s#%s" % (urlencode(query), urlencode(fragment))) + return _("""Access your messages and documents in OpenERP""") % url + else: + return None + def send_get_mail_subject(self, cr, uid, mail, force=False, partner=None, context=None): """ If subject is void and record_name defined: ' posted on ' @@ -202,36 +241,12 @@ class mail_mail(osv.Model): :param browse_record mail: mail.mail browse_record :param browse_record partner: specific recipient partner """ - if force or (not mail.subject and mail.model and mail.res_id): + if (force or not mail.subject) and mail.record_name: return 'Re: %s' % (mail.record_name) + elif (force or not mail.subject) and mail.parent_id and mail.parent_id.subject: + return 'Re: %s' % (mail.parent_id.subject) return mail.subject - def send_get_mail_body_footer(self, cr, uid, mail, partner=None, context=None): - """ Return a specific footer for the ir_email body. The main purpose of this method - is to be inherited by Portal, to add modify the link for signing in, in - each notification email a partner receives. - """ - body_footer = "" - # partner is a user, link to a related document (incentive to install portal) - if partner and partner.user_ids and mail.model and mail.res_id \ - and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False): - related_user = partner.user_ids[0] - try: - self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context) - base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') - # the parameters to encode for the query and fragment part of url - query = {'db': cr.dbname} - fragment = { - 'login': related_user.login, - 'model': mail.model, - 'id': mail.res_id, - } - url = urljoin(base_url, "?%s#%s" % (urlencode(query), urlencode(fragment))) - body_footer = _("""Access this document directly in OpenERP""") % url - except except_orm, e: - pass - return body_footer - def send_get_mail_body(self, cr, uid, mail, partner=None, context=None): """ Return a specific ir_email body. The main purpose of this method is to be inherited to add custom content depending on some module. @@ -241,9 +256,10 @@ class mail_mail(osv.Model): """ body = mail.body_html - # add footer - body_footer = self.send_get_mail_body_footer(cr, uid, mail, partner=partner, context=context) - body = tools.append_content_to_html(body, body_footer, plaintext=False, container_tag='div') + # generate footer + link = self._get_partner_access_link(cr, uid, mail, partner, context=context) + if link: + body = tools.append_content_to_html(body, link, plaintext=False, container_tag='div') return body def send_get_email_dict(self, cr, uid, mail, partner=None, context=None): @@ -256,7 +272,19 @@ class mail_mail(osv.Model): body = self.send_get_mail_body(cr, uid, mail, partner=partner, context=context) subject = self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context) body_alternative = tools.html2plaintext(body) - email_to = ['%s <%s>' % (partner.name, partner.email)] if partner else tools.email_split(mail.email_to) + + # generate email_to, heuristic: + # 1. if 'partner' is specified and there is a related document: Followers of 'Doc' + # 2. if 'partner' is specified, but no related document: Partner Name + # 3; fallback on mail.email_to that we split to have an email addresses list + if partner and mail.record_name: + sanitized_record_name = re.sub(r'[^\w+.]+', '-', mail.record_name) + email_to = [_('"Followers of %s" <%s>') % (sanitized_record_name, partner.email)] + elif partner: + email_to = ['%s <%s>' % (partner.name, partner.email)] + else: + email_to = tools.email_split(mail.email_to) + return { 'body': body, 'body_alternative': body_alternative, diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 8442891f3f9..0b6a4aebd18 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -76,9 +76,9 @@ class mail_message(osv.Model): # TDE note: regroup by model/ids, to have less queries to perform result = dict.fromkeys(ids, False) for message in self.read(cr, uid, ids, ['model', 'res_id'], context=context): - if not message.get('model') or not message.get('res_id') or not self.pool.get(message['model']): + if not message.get('model') or not message.get('res_id') or message['model'] not in self.pool: continue - result[message['id']] = self.pool.get(message['model']).name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1] + result[message['id']] = self.pool[message['model']].name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1] return result def _get_to_read(self, cr, uid, ids, name, arg, context=None): @@ -236,6 +236,8 @@ class mail_message(osv.Model): :param bool read: set notification as (un)read :param bool create_missing: create notifications for missing entries (i.e. when acting on displayed messages not notified) + + :return number of message mark as read """ notification_obj = self.pool.get('mail.notification') user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] @@ -246,14 +248,16 @@ class mail_message(osv.Model): # all message have notifications: already set them as (un)read if len(notif_ids) == len(msg_ids) or not create_missing: - return notification_obj.write(cr, uid, notif_ids, {'read': read}, context=context) + notification_obj.write(cr, uid, notif_ids, {'read': read}, context=context) + return len(notif_ids) # some messages do not have notifications: find which one, create notification, update read status notified_msg_ids = [notification.message_id.id for notification in notification_obj.browse(cr, uid, notif_ids, context=context)] to_create_msg_ids = list(set(msg_ids) - set(notified_msg_ids)) for msg_id in to_create_msg_ids: notification_obj.create(cr, uid, {'partner_id': user_pid, 'read': read, 'message_id': msg_id}, context=context) - return notification_obj.write(cr, uid, notif_ids, {'read': read}, context=context) + notification_obj.write(cr, uid, notif_ids, {'read': read}, context=context) + return len(notif_ids) def set_message_starred(self, cr, uid, msg_ids, starred, create_missing=True, context=None): """ Set messages as (un)starred. Technically, the notifications related @@ -268,19 +272,25 @@ class mail_message(osv.Model): domain = [('partner_id', '=', user_pid), ('message_id', 'in', msg_ids)] if not create_missing: domain += [('starred', '=', not starred)] + values = { + 'starred': starred + } + if starred: + values['read'] = False + notif_ids = notification_obj.search(cr, uid, domain, context=context) # all message have notifications: already set them as (un)starred if len(notif_ids) == len(msg_ids) or not create_missing: - notification_obj.write(cr, uid, notif_ids, {'starred': starred}, context=context) + notification_obj.write(cr, uid, notif_ids, values, context=context) return starred # some messages do not have notifications: find which one, create notification, update starred status notified_msg_ids = [notification.message_id.id for notification in notification_obj.browse(cr, uid, notif_ids, context=context)] to_create_msg_ids = list(set(msg_ids) - set(notified_msg_ids)) for msg_id in to_create_msg_ids: - notification_obj.create(cr, uid, {'partner_id': user_pid, 'starred': starred, 'message_id': msg_id}, context=context) - notification_obj.write(cr, uid, notif_ids, {'starred': starred}, context=context) + notification_obj.create(cr, uid, dict(values, partner_id=user_pid, message_id=msg_id), context=context) + notification_obj.write(cr, uid, notif_ids, values, context=context) return starred #------------------------------------------------------ @@ -363,6 +373,7 @@ class mail_message(osv.Model): return {'id': message.id, 'type': message.type, + 'subtype': message.subtype_id.name if message.subtype_id else False, 'body': body_html, 'model': message.model, 'res_id': message.res_id, @@ -563,7 +574,7 @@ class mail_message(osv.Model): def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None): doc_ids = doc_dict.keys() - allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context) + allowed_doc_ids = self.pool[doc_model].search(cr, uid, [('id', 'in', doc_ids)], context=context) return set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]]) def _find_allowed_doc_ids(self, cr, uid, model_ids, context=None): @@ -711,7 +722,7 @@ class mail_message(osv.Model): model_record_ids = _generate_model_record_ids(message_values, other_ids) document_related_ids = [] for model, doc_dict in model_record_ids.items(): - model_obj = self.pool.get(model) + model_obj = self.pool[model] mids = model_obj.exists(cr, uid, doc_dict.keys()) if operation in ['create', 'write', 'unlink']: model_obj.check_access_rights(cr, uid, 'write') @@ -736,7 +747,7 @@ class mail_message(osv.Model): default_starred = context.pop('default_starred', False) # generate message_id, to redirect answers to the right discussion thread if not values.get('message_id') and values.get('reply_to'): - values['message_id'] = tools.generate_tracking_message_id('reply_to-%(model)s' % values) + values['message_id'] = tools.generate_tracking_message_id('reply_to') elif not values.get('message_id') and values.get('res_id') and values.get('model'): values['message_id'] = tools.generate_tracking_message_id('%(res_id)s-%(model)s' % values) elif not values.get('message_id'): @@ -767,7 +778,7 @@ class mail_message(osv.Model): attachments_to_delete = [] for message in self.browse(cr, uid, ids, context=context): for attach in message.attachment_ids: - if attach.res_model == self._name and attach.res_id == message.id: + if attach.res_model == self._name and (attach.res_id == message.id or attach.res_id == 0): attachments_to_delete.append(attach.id) if attachments_to_delete: self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context) diff --git a/addons/mail/mail_message_view.xml b/addons/mail/mail_message_view.xml index 8f2fb3f1020..02f4ef7fdbe 100644 --- a/addons/mail/mail_message_view.xml +++ b/addons/mail/mail_message_view.xml @@ -59,6 +59,9 @@ + + + diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 778d7d53bd1..80df8ad6e99 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -33,7 +33,7 @@ from email.message import Message from openerp import tools from openerp import SUPERUSER_ID from openerp.addons.mail.mail_message import decode -from openerp.osv import fields, osv +from openerp.osv import fields, osv, orm from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ @@ -89,6 +89,46 @@ class mail_thread(osv.AbstractModel): # :param function lambda: returns whether the tracking should record using this subtype _track = {} + def get_empty_list_help(self, cr, uid, help, context=None): + """ Override of BaseModel.get_empty_list_help() to generate an help message + that adds alias information. """ + model = context.get('empty_list_help_model') + res_id = context.get('empty_list_help_id') + ir_config_parameter = self.pool.get("ir.config_parameter") + catchall_domain = ir_config_parameter.get_param(cr, uid, "mail.catchall.domain", context=context) + document_name = context.get('empty_list_help_document_name', _('document')) + alias = None + + if catchall_domain and model and res_id: # specific res_id -> find its alias (i.e. section_id specified) + object_id = self.pool.get(model).browse(cr, uid, res_id, context=context) + alias = object_id.alias_id + elif catchall_domain and model: # no specific res_id given -> generic help message, take an example alias (i.e. alias of some section_id) + model_id = self.pool.get('ir.model').search(cr, uid, [("model", "=", self._name)], context=context)[0] + alias_obj = self.pool.get('mail.alias') + alias_ids = alias_obj.search(cr, uid, [("alias_model_id", "=", model_id)], context=context, limit=1, order='id ASC') + if alias_ids: + alias = alias_obj.browse(cr, uid, alias_ids[0], context=context) + + if alias: + alias_email = alias.name_get()[0][1] + return _("""

+ Click here to add a new %(document)s or send an email to: %(email)s +

+ %(static_help)s""" + ) % { + 'document': document_name, + 'email': alias_email, + 'static_help': help or '' + } + + if document_name != 'document' and help and help.find("oe_view_nocontent_create") == -1: + return _("

Click here to add a new %(document)s

%(static_help)s") % { + 'document': document_name, + 'static_help': help or '', + } + + return help + def _get_message_data(self, cr, uid, ids, name, args, context=None): """ Computes: - message_unread: has uid unread message for the document @@ -368,7 +408,7 @@ class mail_thread(osv.AbstractModel): posted = False for subtype in subtypes: try: - subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1]) + subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1], context=context) except ValueError, e: _logger.debug('subtype %s not found, giving error "%s"' % (subtype, e)) continue @@ -389,6 +429,90 @@ class mail_thread(osv.AbstractModel): return [('message_unread', '=', True)] return [] + def _garbage_collect_attachments(self, cr, uid, context=None): + """ Garbage collect lost mail attachments. Those are attachments + - linked to res_model 'mail.compose.message', the composer wizard + - with res_id 0, because they were created outside of an existing + wizard (typically user input through Chatter or reports + created on-the-fly by the templates) + - unused since at least one day (create_date and write_date) + """ + limit_date = datetime.datetime.utcnow() - datetime.timedelta(days=1) + limit_date_str = datetime.datetime.strftime(limit_date, tools.DEFAULT_SERVER_DATETIME_FORMAT) + ir_attachment_obj = self.pool.get('ir.attachment') + attach_ids = ir_attachment_obj.search(cr, uid, [ + ('res_model', '=', 'mail.compose.message'), + ('res_id', '=', 0), + ('create_date', '<', limit_date_str), + ('write_date', '<', limit_date_str), + ], context=context) + ir_attachment_obj.unlink(cr, uid, attach_ids, context=context) + return True + + def _get_formview_action(self, cr, uid, id, model=None, context=None): + """ Return an action to open the document. This method is meant to be + overridden in addons that want to give specific view ids for example. + + :param int id: id of the document to open + :param string model: specific model that overrides self._name + """ + return { + 'type': 'ir.actions.act_window', + 'res_model': model or self._name, + 'view_type': 'form', + 'view_mode': 'form', + 'views': [(False, 'form')], + 'target': 'current', + 'res_id': id, + } + + def _get_inbox_action_xml_id(self, cr, uid, context=None): + """ When redirecting towards the Inbox, choose which action xml_id has + to be fetched. This method is meant to be inherited, at least in portal + because portal users have a different Inbox action than classic users. """ + return ('mail', 'action_mail_inbox_feeds') + + def message_redirect_action(self, cr, uid, context=None): + """ For a given message, return an action that either + - opens the form view of the related document if model, res_id, and + read access to the document + - opens the Inbox with a default search on the conversation if model, + res_id + - opens the Inbox with context propagated + + """ + if context is None: + context = {} + + # default action is the Inbox action + self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) + act_model, act_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, *self._get_inbox_action_xml_id(cr, uid, context=context)) + action = self.pool.get(act_model).read(cr, uid, act_id, []) + + # if msg_id specified: try to redirect to the document or fallback on the Inbox + msg_id = context.get('params', {}).get('message_id') + if not msg_id: + return action + msg = self.pool.get('mail.message').browse(cr, uid, msg_id, context=context) + if msg.model and msg.res_id: + action.update({ + 'context': { + 'search_default_model': msg.model, + 'search_default_res_id': msg.res_id, + } + }) + if self.pool.get(msg.model).check_access_rights(cr, uid, 'read', raise_exception=False): + try: + model_obj = self.pool.get(msg.model) + model_obj.check_access_rule(cr, uid, [msg.res_id], 'read', context=context) + if not hasattr(model_obj, '_get_formview_action'): + action = self.pool.get('mail.thread')._get_formview_action(cr, uid, msg.res_id, model=msg.model, context=context) + else: + action = model_obj._get_formview_action(cr, uid, msg.res_id, context=context) + except (osv.except_osv, orm.except_orm): + pass + return action + #------------------------------------------------------ # Email specific #------------------------------------------------------ @@ -399,7 +523,7 @@ class mail_thread(osv.AbstractModel): return ["%s@%s" % (record['alias_name'], record['alias_domain']) if record.get('alias_domain') and record.get('alias_name') else False - for record in self.read(cr, uid, ids, ['alias_name', 'alias_domain'], context=context)] + for record in self.read(cr, SUPERUSER_ID, ids, ['alias_name', 'alias_domain'], context=context)] #------------------------------------------------------ # Mail gateway @@ -409,13 +533,15 @@ class mail_thread(osv.AbstractModel): """ Used by the plugin addon, based for plugin_outlook and others. """ ret_dict = {} for model_name in self.pool.obj_list(): - model = self.pool.get(model_name) + model = self.pool[model_name] if 'mail.thread' in getattr(model, '_inherit', []): ret_dict[model_name] = model._description return ret_dict def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None): - """ Find partners related to some header fields of the message. """ + """ Find partners related to some header fields of the message. + + TDE TODO: merge me with other partner finding methods in 8.0 """ partner_obj = self.pool.get('res.partner') partner_ids = [] s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)]) @@ -427,6 +553,7 @@ class mail_thread(osv.AbstractModel): return partner_ids def _message_find_user_id(self, cr, uid, message, context=None): + """ TDE TODO: check and maybe merge me with other user finding methods in 8.0 """ from_local_part = tools.email_split(decode(message.get('From')))[0] # FP Note: canonification required, the minimu: .lower() user_ids = self.pool.get('res.users').search(cr, uid, ['|', @@ -468,6 +595,8 @@ class mail_thread(osv.AbstractModel): """ assert isinstance(message, Message), 'message must be an email.message.Message at this point' message_id = message.get('Message-Id') + email_from = decode_header(message, 'From') + email_to = decode_header(message, 'To') references = decode_header(message, 'References') in_reply_to = decode_header(message, 'In-Reply-To') @@ -478,12 +607,12 @@ class mail_thread(osv.AbstractModel): if ref_match: thread_id = int(ref_match.group(1)) model = ref_match.group(2) or model - model_pool = self.pool.get(model) - if thread_id and model and model_pool and model_pool.exists(cr, uid, thread_id) \ - and hasattr(model_pool, 'message_update'): - _logger.debug('Routing mail with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s', - message_id, model, thread_id, custom_values, uid) - return [(model, thread_id, custom_values, uid)] + if thread_id and model in self.pool: + model_obj = self.pool[model] + if model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'): + _logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s', + email_from, email_to, message_id, model, thread_id, custom_values, uid) + return [(model, thread_id, custom_values, uid)] # Verify whether this is a reply to a private message if in_reply_to: @@ -493,8 +622,8 @@ class mail_thread(osv.AbstractModel): ], limit=1, context=context) if message_ids: message = self.pool.get('mail.message').browse(cr, uid, message_ids[0], context=context) - _logger.debug('Routing mail with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s', - message_id, message.id, custom_values, uid) + _logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s', + email_from, email_to, message_id, message.id, custom_values, uid) return [(message.model, message.res_id, custom_values, uid)] # 2. Look for a matching mail.alias entry @@ -521,10 +650,11 @@ class mail_thread(osv.AbstractModel): # Note: recognized partners will be added as followers anyway # user_id = self._message_find_user_id(cr, uid, message, context=context) user_id = uid - _logger.debug('No matching user_id for the alias %s', alias.alias_name) + _logger.info('No matching user_id for the alias %s', alias.alias_name) routes.append((alias.alias_model_id.model, alias.alias_force_thread_id, \ eval(alias.alias_defaults), user_id)) - _logger.debug('Routing mail with Message-Id %s: direct alias match: %r', message_id, routes) + _logger.info('Routing mail from %s to %s with Message-Id %s: direct alias match: %r', + email_from, email_to, message_id, routes) return routes # 3. Fallback to the provided parameters, if they work @@ -539,14 +669,14 @@ class mail_thread(osv.AbstractModel): except: thread_id = False assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \ - "No possible route found for incoming message with Message-Id %s. " \ - "Create an appropriate mail.alias or force the destination model." % message_id + "No possible route found for incoming message from %s to %s (Message-Id %s:)." \ + "Create an appropriate mail.alias or force the destination model." % (email_from, email_to, message_id) if thread_id and not model_pool.exists(cr, uid, thread_id): _logger.warning('Received mail reply to missing document %s! Ignoring and creating new document instead for Message-Id %s', - thread_id, message_id) + thread_id, message_id) thread_id = None - _logger.debug('Routing mail with Message-Id %s: fallback to model:%s, thread_id:%s, custom_values:%s, uid:%s', - message_id, model, thread_id, custom_values, uid) + _logger.info('Routing mail from %s to %s with Message-Id %s: fallback to model:%s, thread_id:%s, custom_values:%s, uid:%s', + email_from, email_to, message_id, model, thread_id, custom_values, uid) return [(model, thread_id, custom_values, uid)] def message_process(self, cr, uid, model, message, custom_values=None, @@ -596,12 +726,24 @@ class mail_thread(osv.AbstractModel): if isinstance(message, unicode): message = message.encode('utf-8') msg_txt = email.message_from_string(message) - routes = self.message_route(cr, uid, msg_txt, model, - thread_id, custom_values, - context=context) + + # parse the message, verify we are not in a loop by checking message_id is not duplicated msg = self.message_parse(cr, uid, msg_txt, save_original=save_original, context=context) if strip_attachments: msg.pop('attachments', None) + if msg.get('message_id'): # should always be True as message_parse generate one if missing + existing_msg_ids = self.pool.get('mail.message').search(cr, SUPERUSER_ID, [ + ('message_id', '=', msg.get('message_id')), + ], context=context) + if existing_msg_ids: + _logger.info('Ignored mail from %s to %s with Message-Id %s:: found duplicated Message-Id during processing', + msg.get('from'), msg.get('to'), msg.get('message_id')) + return False + + # find possible routes for the message + routes = self.message_route(cr, uid, msg_txt, model, + thread_id, custom_values, + context=context) # postpone setting msg.partner_ids after message_post, to avoid double notifications partner_ids = msg.pop('partner_ids', []) @@ -611,7 +753,7 @@ class mail_thread(osv.AbstractModel): if self._name == 'mail.thread': context.update({'thread_model': model}) if model: - model_pool = self.pool.get(model) + model_pool = self.pool[model] 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) @@ -665,7 +807,7 @@ class mail_thread(osv.AbstractModel): if isinstance(custom_values, dict): data = custom_values.copy() model = context.get('thread_model') or self._name - model_pool = self.pool.get(model) + model_pool = self.pool[model] fields = model_pool.fields_get(cr, uid, context=context) if 'name' in fields and not data.get('name'): data['name'] = msg_dict.get('subject', '') @@ -798,7 +940,7 @@ class mail_thread(osv.AbstractModel): # as RFC2822 requires timezone offset in Date headers. stored_date = parsed_date.replace(tzinfo=pytz.utc) else: - stored_date = parsed_date.astimezone(pytz.utc) + stored_date = parsed_date.astimezone(tz=pytz.utc) except Exception: _logger.warning('Failed to parse Date header %r in incoming mail ' 'with message-id %r, assuming current date/time.', @@ -817,7 +959,7 @@ class mail_thread(osv.AbstractModel): if parent_ids: msg_dict['parent_id'] = parent_ids[0] - msg_dict['body'], msg_dict['attachments'] = self._message_extract_payload(message) + msg_dict['body'], msg_dict['attachments'] = self._message_extract_payload(message, save_original=save_original) return msg_dict #------------------------------------------------------ @@ -837,7 +979,8 @@ class mail_thread(osv.AbstractModel): recipient in the result dictionary. The form is : partner_id, partner_name or partner_name, reason """ if email and not partner: - partner_info = self.message_get_partner_info_from_emails(cr, uid, [email], context=context)[0] + # get partner info from email + partner_info = self.message_get_partner_info_from_emails(cr, uid, [email], context=context, res_id=obj.id)[0] if partner_info.get('partner_id'): partner = self.pool.get('res.partner').browse(cr, SUPERUSER_ID, [partner_info.get('partner_id')], context=context)[0] if email and email in [val[1] for val in result[obj.id]]: # already existing email -> skip @@ -865,29 +1008,49 @@ class mail_thread(osv.AbstractModel): self._message_add_suggested_recipient(cr, uid, result, obj, partner=obj.user_id.partner_id, reason=self._all_columns['user_id'].column.string, context=context) return result - def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None): + def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None, res_id=None): + """ Wrapper with weird order parameter because of 7.0 fix. + + TDE TODO: remove me in 8.0 """ + return self.message_find_partner_from_emails(cr, uid, res_id, emails, link_mail=link_mail, context=context) + + def message_find_partner_from_emails(self, cr, uid, id, emails, link_mail=False, context=None): """ Convert a list of emails into a list partner_ids and a list new_partner_ids. The return value is non conventional because it is meant to be used by the mail widget. :return dict: partner_ids and new_partner_ids - """ + + TDE TODO: merge me with other partner finding methods in 8.0 """ mail_message_obj = self.pool.get('mail.message') partner_obj = self.pool.get('res.partner') result = list() + if id and self._name != 'mail.thread': + obj = self.browse(cr, SUPERUSER_ID, id, context=context) + else: + obj = None for email in emails: partner_info = {'full_name': email, 'partner_id': False} m = re.search(r"((.+?)\s*<)?([^<>]+@[^<>]+)>?", email, re.IGNORECASE | re.DOTALL) if not m: continue email_address = m.group(3) - ids = partner_obj.search(cr, SUPERUSER_ID, [('email', '=', email_address)], context=context) - if ids: - partner_info['partner_id'] = ids[0] + # first try: check in document's followers + if obj: + for follower in obj.message_follower_ids: + if follower.email == email_address: + partner_info['partner_id'] = follower.id + # second try: check in partners + if not partner_info.get('partner_id'): + ids = partner_obj.search(cr, SUPERUSER_ID, [('email', 'ilike', email_address), ('user_ids', '!=', False)], limit=1, context=context) + if not ids: + ids = partner_obj.search(cr, SUPERUSER_ID, [('email', 'ilike', email_address)], limit=1, context=context) + if ids: + partner_info['partner_id'] = ids[0] result.append(partner_info) # link mail with this from mail to the new partner id - if link_mail and ids: + if link_mail and partner_info['partner_id']: message_ids = mail_message_obj.search(cr, SUPERUSER_ID, [ '|', ('email_from', '=', email), @@ -895,7 +1058,7 @@ class mail_thread(osv.AbstractModel): ('author_id', '=', False) ], context=context) if message_ids: - mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': ids[0]}, context=context) + mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': partner_info['partner_id']}, context=context) return result def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', @@ -942,7 +1105,7 @@ class mail_thread(osv.AbstractModel): model = context.get('thread_model', self._name) if self._name == 'mail.thread' else self._name if model != self._name: del context['thread_model'] - return self.pool.get(model).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs) + return self.pool[model].message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs) # 0: Parse email-from, try to find a better author_id based on document's followers for incoming emails email_from = kwargs.get('email_from') @@ -956,12 +1119,15 @@ class mail_thread(osv.AbstractModel): ], limit=1, context=context) if author_ids: kwargs['author_id'] = author_ids[0] + author_id = kwargs.get('author_id') + if author_id is None: # keep False values + author_id = self.pool.get('mail.message')._get_default_author(cr, uid, context=context) # 1: Handle content subtype: if plaintext, converto into HTML if content_subtype == 'plaintext': body = tools.plaintext2html(body) - # 2: Private message: add recipients (recipients and author of parent message) + # 2: Private message: add recipients (recipients and author of parent message) - current author # + legacy-code management (! we manage only 4 and 6 commands) partner_ids = set() kwargs_partner_ids = kwargs.pop('partner_ids', []) @@ -974,11 +1140,13 @@ class mail_thread(osv.AbstractModel): partner_ids.add(partner_id) else: pass # we do not manage anything else - if parent_id and model == 'mail.thread': + if parent_id and not model: parent_message = mail_message.browse(cr, uid, parent_id, context=context) - partner_ids |= set([partner.id for partner in parent_message.partner_ids]) + private_followers = set([partner.id for partner in parent_message.partner_ids]) if parent_message.author_id: - partner_ids.add(parent_message.author_id.id) + private_followers.add(parent_message.author_id.id) + private_followers -= set([author_id]) + partner_ids |= private_followers # 3. Attachments # - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message @@ -986,7 +1154,6 @@ class mail_thread(osv.AbstractModel): if attachment_ids: filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [ ('res_model', '=', 'mail.compose.message'), - ('res_id', '=', 0), ('create_uid', '=', uid), ('id', 'in', attachment_ids)], context=context) if filtered_attachment_ids: @@ -1039,6 +1206,7 @@ class mail_thread(osv.AbstractModel): values = kwargs values.update({ + 'author_id': author_id, 'model': model, 'res_id': thread_id or False, 'body': body, @@ -1096,19 +1264,35 @@ class mail_thread(osv.AbstractModel): """ Add partners to the records followers. """ user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] if set(partner_ids) == set([user_pid]): - self.check_access_rights(cr, uid, 'read') + try: + self.check_access_rights(cr, uid, 'read') + except (osv.except_osv, orm.except_orm): + return else: self.check_access_rights(cr, uid, 'write') + # subscribe partners self.write(cr, SUPERUSER_ID, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context) - # if subtypes are not specified (and not set to a void list), fetch default ones - if subtype_ids is None: - subtype_obj = self.pool.get('mail.message.subtype') - subtype_ids = subtype_obj.search(cr, uid, [('default', '=', True), '|', ('res_model', '=', self._name), ('res_model', '=', False)], context=context) - # update the subscriptions + + # subtype specified: update the subscriptions fol_obj = self.pool.get('mail.followers') - fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids), ('partner_id', 'in', partner_ids)], context=context) - fol_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context) + if subtype_ids is not None: + fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids), ('partner_id', 'in', partner_ids)], context=context) + fol_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context) + # no subtypes: default ones for new subscription, do not update existing subscriptions + else: + # search new subscriptions: subtype_ids is False + fol_ids = fol_obj.search(cr, SUPERUSER_ID, [ + ('res_model', '=', self._name), + ('res_id', 'in', ids), + ('partner_id', 'in', partner_ids), + ('subtype_ids', '=', False) + ], context=context) + if fol_ids: + subtype_obj = self.pool.get('mail.message.subtype') + subtype_ids = subtype_obj.search(cr, uid, [('default', '=', True), '|', ('res_model', '=', self._name), ('res_model', '=', False)], context=context) + fol_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context) + return True def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None): diff --git a/addons/mail/mail_thread_view.xml b/addons/mail/mail_thread_view.xml index 75c86e4645d..c9c5141d303 100644 --- a/addons/mail/mail_thread_view.xml +++ b/addons/mail/mail_thread_view.xml @@ -8,6 +8,7 @@ { 'default_model': 'res.users', 'default_res_id': uid, + 'needaction_menu_ref': ['mail.mail_tomefeeds', 'mail.mail_starfeeds'] } { 'default_model': 'res.users', 'default_res_id': uid, - 'search_default_message_unread': True + 'search_default_message_unread': True, + 'needaction_menu_ref': ['mail.mail_starfeeds', 'mail.mail_inboxfeeds'] } mail.wall { 'default_model': 'res.users', - 'default_res_id': uid + 'default_res_id': uid, + 'needaction_menu_ref': ['mail.mail_tomefeeds', 'mail.mail_starfeeds', 'mail.mail_inboxfeeds'] } + Mail Redirection (Document / Inbox) + True + + action = pool.get('mail.thread').message_redirect_action(cr, uid, context) + code + ir.actions.server + + diff --git a/addons/mail/res_config.py b/addons/mail/res_config.py index 91606e1c720..c19eb4a38ee 100644 --- a/addons/mail/res_config.py +++ b/addons/mail/res_config.py @@ -23,11 +23,12 @@ import urlparse from openerp.osv import osv, fields + class project_configuration(osv.TransientModel): _inherit = 'base.config.settings' _columns = { - 'alias_domain' : fields.char('Alias Domain', + 'alias_domain': fields.char('Alias Domain', help="If you have setup a catch-all email domain redirected to " "the OpenERP server, enter the domain name here."), } diff --git a/addons/mail/res_users.py b/addons/mail/res_users.py index f7c91939b98..5545745b235 100644 --- a/addons/mail/res_users.py +++ b/addons/mail/res_users.py @@ -60,8 +60,9 @@ class res_users(osv.Model): def _auto_init(self, cr, context=None): """ Installation hook: aliases, partner following themselves """ # create aliases for all users and avoid constraint errors - self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(res_users, self)._auto_init, + res = self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(res_users, self)._auto_init, self._columns['alias_id'], 'login', alias_force_key='id', context=context) + return res def create(self, cr, uid, data, context=None): # create default alias same as the login diff --git a/addons/mail/static/scripts/openerp_mailgate.py b/addons/mail/static/scripts/openerp_mailgate.py old mode 100644 new mode 100755 diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css index 51306727a09..958c2bccd5f 100644 --- a/addons/mail/static/src/css/mail.css +++ b/addons/mail/static/src/css/mail.css @@ -57,6 +57,9 @@ .openerp .oe_mail .oe_msg.oe_msg_nobody{ background: #F8F8F8; } +.openerp .oe_mail .oe_msg.oe_msg_notification{ + background: #F8F8F8; +} .openerp .oe_mail .oe_msg .oe_msg_left{ position: absolute; left:0; top: 0; bottom: 0; width: 40px; @@ -561,14 +564,6 @@ text-align: center; width:100%; } -.openerp .oe_followers button.oe_invite{ - margin: 5px 0; - padding: 2px 8px; - font-size: 12px; - text-shadow: none; - width: 100%; -} -.openerp .oe_followers button.oe_invite, .openerp .oe_followers button.oe_follower.oe_following{ color: white; background-color: #3465A4; @@ -622,10 +617,16 @@ margin-top: 12px; margin-bottom: 4px; } +.openerp .oe_followers .oe_invite{ + float: right; +} .openerp .oe_followers .oe_partner { height: 32px; + margin-right: 8px; overflow: hidden; white-space: nowrap; + text-overflow: ellipsis; + margin-right: 10px; } .openerp .oe_followers .oe_partner img{ width: 32px; diff --git a/addons/mail/static/src/css/mail_group.css b/addons/mail/static/src/css/mail_group.css index c1cefee9070..4f2b8a16dd0 100644 --- a/addons/mail/static/src/css/mail_group.css +++ b/addons/mail/static/src/css/mail_group.css @@ -14,6 +14,10 @@ padding: 0px 18px; } +.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_avatar { + padding-top: 3px; +} + /* Resize footer width */ .openerp .oe_form div.oe_mail_group_footer { max-width: 80%; @@ -21,7 +25,7 @@ /* Resize group description */ .openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_text > textarea { - height: 40px; + height: 60px; } /* ------------------------------ */ diff --git a/addons/mail/static/src/img/email_icon.png b/addons/mail/static/src/img/email_icon.png old mode 100755 new mode 100644 diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index ad69f7e41c3..8631bc70baa 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -217,6 +217,7 @@ openerp.mail = function (session) { this.res_id = datasets.res_id || this.context.default_res_id || false, this.parent_id = datasets.parent_id || false, this.type = datasets.type || false, + this.subtype = datasets.subtype || false, this.is_author = datasets.is_author || false, this.is_private = datasets.is_private || false, this.subject = datasets.subject || false, @@ -619,7 +620,10 @@ openerp.mail = function (session) { // have unknown names -> call message_get_partner_info_from_emails to try to find partner_id var find_done = $.Deferred(); if (names_to_find.length > 0) { - find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [names_to_find]); + var values = { + 'res_id': this.context.default_res_id, + } + find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [names_to_find], values); } else { find_done.resolve([]); @@ -665,7 +669,11 @@ openerp.mail = function (session) { var new_names_to_find = _.difference(names_to_find, names_to_remove); find_done = $.Deferred(); if (new_names_to_find.length > 0) { - find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [new_names_to_find, true]); + var values = { + 'link_mail': true, + 'res_id': self.context.default_res_id, + } + find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [new_names_to_find], values); } else { find_done.resolve([]); @@ -1048,9 +1056,7 @@ openerp.mail = function (session) { msg.renderElement(); msg.start(); } - if( self.options.root_thread.__parentedParent.__parentedParent.do_reload_menu_emails ) { - self.options.root_thread.__parentedParent.__parentedParent.do_reload_menu_emails(); - } + self.options.root_thread.MailWidget.do_reload_menu_emails(); }); }); @@ -1190,6 +1196,7 @@ openerp.mail = function (session) { init: function (parent, datasets, options) { var self = this; this._super(parent, options); + this.MailWidget = parent.__proto__ == mail.Widget.prototype ? parent : false; this.domain = options.domain || []; this.context = _.extend(options.context || {}); @@ -1208,7 +1215,7 @@ openerp.mail = function (session) { this.author_id = datasets.author_id || false; this.thread_level = (datasets.thread_level+1) || 0; datasets.partner_ids = datasets.partner_ids || []; - if (datasets.author_id && ! _.contains(datasets.partner_ids, datasets.author_id) && datasets.author_id[0]) { + if (datasets.author_id && !_.contains(_.flatten(datasets.partner_ids),datasets.author_id[0]) && datasets.author_id[0]) { datasets.partner_ids.push(datasets.author_id); } this.partner_ids = datasets.partner_ids; @@ -1389,7 +1396,10 @@ openerp.mail = function (session) { if (this.options.help) { no_message.html(this.options.help); } - no_message.appendTo(this.$el); + if (!this.$el.find(".oe_view_nocontent").length) + { + no_message.appendTo(this.$el); + } }, /** @@ -1420,11 +1430,16 @@ openerp.mail = function (session) { message_fetch_set_read: function (message_list) { if (! this.context.mail_read_set_read) return; - this.render_mutex.exec(_.bind(function() { + var self = this; + this.render_mutex.exec(function() { msg_ids = _.pluck(message_list, 'id'); - return this.ds_message.call('set_message_read', [ - msg_ids, true, false, this.context]); - }, this)); + return self.ds_message.call('set_message_read', [msg_ids, true, false, self.context]) + .then(function (nb_read) { + if (nb_read) { + self.options.root_thread.MailWidget.do_reload_menu_emails(); + } + }); + }); }, /** @@ -1689,6 +1704,22 @@ openerp.mail = function (session) { this.bind_events(); }, + /** + * create an object "related_menu" + * contains the menu widget and the sub menu related of this wall + */ + do_reload_menu_emails: function () { + var menu = session.webclient.menu; + if (!menu || !menu.current_menu) { + return $.when(); + } + return menu.rpc("/web/menu/load_needaction", {'menu_ids': [menu.current_menu]}).done(function(r) { + menu.on_needaction_loaded(r); + }).then(function () { + menu.trigger("need_action_reloaded"); + }); + }, + /** *Create the root thread and display this object in the DOM. * Call the no_message method then c all the message_fetch method @@ -1738,6 +1769,7 @@ openerp.mail = function (session) { init: function (parent, node) { this._super.apply(this, arguments); + this.ParentViewManager = parent; this.node = _.clone(node); this.node.params = _.extend({ 'display_indented_thread': -1, @@ -1757,7 +1789,7 @@ openerp.mail = function (session) { this.domain = this.node.params && this.node.params.domain || []; - if (!this.__parentedParent.is_action_enabled('edit')) { + if (!this.ParentViewManager.is_action_enabled('edit')) { this.node.params.show_link = false; } }, @@ -1828,12 +1860,20 @@ openerp.mail = function (session) { */ init: function (parent, action) { this._super(parent, action); + this.ActionManager = parent; this.action = _.clone(action); this.domain = this.action.params.domain || this.action.domain || []; this.context = _.extend(this.action.params.context || {}, this.action.context || {}); + // filter some parameters that we will propagate as search_default this.defaults = {}; + for (var key in this.action.context.params) { + if (_.indexOf(['model', 'res_id'], key) == -1) { + continue; + } + this.context['search_default_' + key] = this.action.context.params[key]; + } for (var key in this.context) { if (key.match(/^search_default_/)) { this.defaults[key.replace(/^search_default_/, '')] = this.context[key]; @@ -1860,23 +1900,6 @@ openerp.mail = function (session) { } }, - /** - * crete an object "related_menu" - * contain the menu widget and the the sub menu related of this wall - */ - do_reload_menu_emails: function () { - var menu = this.__parentedParent.__parentedParent.menu; - // return this.rpc("/web/menu/load", {'menu_id': 100}).done(function(r) { - // _.each(menu.data.data.children, function (val) { - // if (val.id == 100) { - // val.children = _.find(r.data.children, function (r_val) {return r_val.id == 100;}).children; - // } - // }); - // var r = menu.data; - // window.setTimeout(function(){menu.do_reload();}, 0); - // }); - }, - /** * Load the mail.message search view * @param {Object} defaults ?? @@ -1934,6 +1957,7 @@ openerp.mail = function (session) { this.$(".oe_write_full").click(function (event) { event.stopPropagation(); var action = { + name: _t('Compose Email'), type: 'ir.actions.act_window', res_model: 'mail.compose.message', view_mode: 'form', diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js index 6fc2f0fdfcd..f812844194b 100644 --- a/addons/mail/static/src/js/mail_followers.js +++ b/addons/mail/static/src/js/mail_followers.js @@ -148,8 +148,6 @@ openerp_mail_followers = function(session, mail) { }).then(self.proxy('display_generic')); }, _format_followers: function(count){ - // TDE note: why redefining _t ? - function _t(str) { return str; } var str = ''; if(count <= 0){ str = _t('No followers'); diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index b26ef06f5e4..ab82d650f30 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -144,7 +144,9 @@
@@ -226,7 +228,7 @@ -
+
@@ -246,7 +248,11 @@

- : + + + + + :

@@ -259,13 +265,23 @@ - + + updated document + + • + + + logged a note - + to + + nobody + - + @@ -275,6 +291,9 @@ and more + + notified + • • diff --git a/addons/mail/static/src/xml/mail_followers.xml b/addons/mail/static/src/xml/mail_followers.xml index 16bef174470..5ad3ff09bb3 100644 --- a/addons/mail/static/src/xml/mail_followers.xml +++ b/addons/mail/static/src/xml/mail_followers.xml @@ -19,7 +19,7 @@

Followers

- + Add others
@@ -30,7 +30,7 @@ -->
- + X
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py index 2d0019c0b8a..46f4555349d 100644 --- a/addons/mail/tests/test_mail_features.py +++ b/addons/mail/tests/test_mail_features.py @@ -19,12 +19,15 @@ # ############################################################################## +from openerp.addons.mail.mail_mail import mail_mail +from openerp.addons.mail.mail_thread import mail_thread from openerp.addons.mail.tests.test_mail_base import TestMailBase +from openerp.tools import mute_logger from openerp.tools.mail import html_sanitize class test_mail(TestMailBase): - + def test_000_alias_setup(self): """ Test basic mail.alias setup works, before trying to use them for routing """ cr, uid = self.cr, self.uid @@ -43,7 +46,6 @@ class test_mail(TestMailBase): self.user_barty = self.res_users.browse(cr, uid, self.user_barty_id) self.assertEquals(self.user_barty.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens') - def test_00_followers_function_field(self): """ Tests designed for the many2many function field 'follower_ids'. We will test to perform writes using the many2many commands 0, 3, 4, @@ -116,18 +118,66 @@ class test_mail(TestMailBase): # CASE1: test subscriptions with subtypes # ---------------------------------------- - # Do: Subscribe Raoul three times (niak niak) through message_subscribe_users + # Do: subscribe Raoul, should have default subtypes + group_pigs.message_subscribe_users([user_raoul.id]) + group_pigs.refresh() + # Test: 2 followers (Admin and Raoul) + follower_ids = [follower.id for follower in group_pigs.message_follower_ids] + self.assertEqual(set(follower_ids), set([user_raoul.partner_id.id, user_admin.partner_id.id]), + 'message_subscribe: Admin and Raoul should be the only 2 Pigs fans') + # Raoul follows default subtypes + fol_ids = self.mail_followers.search(cr, uid, [ + ('res_model', '=', 'mail.group'), + ('res_id', '=', self.group_pigs_id), + ('partner_id', '=', user_raoul.partner_id.id) + ]) + fol_obj = self.mail_followers.browse(cr, uid, fol_ids)[0] + fol_subtype_ids = set([subtype.id for subtype in fol_obj.subtype_ids]) + self.assertEqual(set(fol_subtype_ids), set(default_group_subtypes), + 'message_subscribe: Raoul subscription subtypes are incorrect, should be all default ones') + + # Do: subscribe Raoul with specified new subtypes + group_pigs.message_subscribe_users([user_raoul.id], subtype_ids=[mt_mg_nodef]) + # Test: 2 followers (Admin and Raoul) + follower_ids = [follower.id for follower in group_pigs.message_follower_ids] + self.assertEqual(set(follower_ids), set([user_raoul.partner_id.id, user_admin.partner_id.id]), + 'message_subscribe: Admin and Raoul should be the only 2 Pigs fans') + # Test: 2 lines in mail.followers (no duplicate for Raoul) + fol_ids = self.mail_followers.search(cr, uid, [ + ('res_model', '=', 'mail.group'), + ('res_id', '=', self.group_pigs_id), + ]) + self.assertEqual(len(fol_ids), 2, + 'message_subscribe: subscribing an already-existing follower should not create new entries in mail.followers') + # Test: Raoul follows only specified subtypes + fol_ids = self.mail_followers.search(cr, uid, [ + ('res_model', '=', 'mail.group'), + ('res_id', '=', self.group_pigs_id), + ('partner_id', '=', user_raoul.partner_id.id) + ]) + fol_obj = self.mail_followers.browse(cr, uid, fol_ids)[0] + fol_subtype_ids = set([subtype.id for subtype in fol_obj.subtype_ids]) + self.assertEqual(set(fol_subtype_ids), set([mt_mg_nodef]), + 'message_subscribe: Raoul subscription subtypes are incorrect, should be only specified') + + # Do: Subscribe Raoul without specified subtypes: should not erase existing subscription subtypes group_pigs.message_subscribe_users([user_raoul.id, user_raoul.id]) group_pigs.message_subscribe_users([user_raoul.id]) group_pigs.refresh() # Test: 2 followers (Admin and Raoul) follower_ids = [follower.id for follower in group_pigs.message_follower_ids] - self.assertEqual(set(follower_ids), set([user_raoul.partner_id.id, user_admin.partner_id.id]), 'Admin and Raoul should be the only 2 Pigs fans') + self.assertEqual(set(follower_ids), set([user_raoul.partner_id.id, user_admin.partner_id.id]), + 'message_subscribe: Admin and Raoul should be the only 2 Pigs fans') # Test: Raoul follows default subtypes - fol_ids = self.mail_followers.search(cr, uid, [('res_model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id), ('partner_id', '=', user_raoul.partner_id.id)]) + fol_ids = self.mail_followers.search(cr, uid, [ + ('res_model', '=', 'mail.group'), + ('res_id', '=', self.group_pigs_id), + ('partner_id', '=', user_raoul.partner_id.id) + ]) fol_obj = self.mail_followers.browse(cr, uid, fol_ids)[0] fol_subtype_ids = set([subtype.id for subtype in fol_obj.subtype_ids]) - self.assertEqual(set(fol_subtype_ids), set(default_group_subtypes), 'subscription subtypes are incorrect') + self.assertEqual(set(fol_subtype_ids), set([mt_mg_nodef]), + 'message_subscribe: Raoul subscription subtypes are incorrect, should be only specified') # Do: Unsubscribe Raoul twice through message_unsubscribe_users group_pigs.message_unsubscribe_users([user_raoul.id, user_raoul.id]) @@ -135,6 +185,13 @@ class test_mail(TestMailBase): # Test: 1 follower (Admin) follower_ids = [follower.id for follower in group_pigs.message_follower_ids] self.assertEqual(follower_ids, [user_admin.partner_id.id], 'Admin must be the only Pigs fan') + # Test: 1 lines in mail.followers (no duplicate for Raoul) + fol_ids = self.mail_followers.search(cr, uid, [ + ('res_model', '=', 'mail.group'), + ('res_id', '=', self.group_pigs_id) + ]) + self.assertEqual(len(fol_ids), 1, + 'message_subscribe: group should have only 1 entry in mail.follower for 1 follower') # Do: subscribe Admin with subtype_ids group_pigs.message_subscribe_users([uid], [mt_mg_nodef, mt_all_nodef]) @@ -171,6 +228,64 @@ class test_mail(TestMailBase): self.assertNotIn('First answer, should not be displayed', result, 'Old answer should not be in quote.') self.assertNotIn('My answer I am propagating', result, 'Thread header content should be in quote.') + def test_11_notification_url(self): + """ Tests designed to test the URL added in notification emails. """ + cr, uid, group_pigs = self.cr, self.uid, self.group_pigs + + # Partner data + partner_raoul = self.res_partner.browse(cr, uid, self.partner_raoul_id) + partner_bert_id = self.res_partner.create(cr, uid, {'name': 'bert'}) + partner_bert = self.res_partner.browse(cr, uid, partner_bert_id) + # Mail data + mail_mail_id = self.mail_mail.create(cr, uid, {'state': 'exception'}) + mail = self.mail_mail.browse(cr, uid, mail_mail_id) + + # Test: link for nobody -> None + url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail) + self.assertEqual(url, None, + 'notification email: mails not send to a specific partner should not have any URL') + + # Test: link for partner -> None + url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail, partner=partner_bert) + self.assertEqual(url, None, + 'notification email: mails send to a not-user partner should not have any URL') + + # Test: link for user -> signin + url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail, partner=partner_raoul) + self.assertIn('action=mail.action_mail_redirect', url, + 'notification email: link should contain the redirect action') + self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url, + 'notification email: link should contain the user login') + + @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm') + def test_12_inbox_redirection(self): + """ Tests designed to test the inbox redirection of emails notification URLs. """ + cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs + model, act_id = self.ir_model_data.get_object_reference(cr, uid, 'mail', 'action_mail_inbox_feeds') + # Data: post a message on pigs + msg_id = self.group_pigs.message_post(body='My body', partner_ids=[self.partner_bert_id], type='comment', subtype='mail.mt_comment') + + # No specific parameters -> should redirect to Inbox + action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_raoul_id, {'params': {}}) + self.assertEqual(action.get('type'), 'ir.actions.client', + 'URL redirection: action without parameters should redirect to client action Inbox') + self.assertEqual(action.get('id'), act_id, + 'URL redirection: action without parameters should redirect to client action Inbox') + + # Bert has read access to Pigs -> should redirect to form view of Pigs + action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_raoul_id, {'params': {'message_id': msg_id}}) + self.assertEqual(action.get('type'), 'ir.actions.act_window', + 'URL redirection: action with message_id for read-accredited user should redirect to Pigs') + self.assertEqual(action.get('res_id'), group_pigs.id, + 'URL redirection: action with message_id for read-accredited user should redirect to Pigs') + + # Bert has no read access to Pigs -> should redirect to Inbox + action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_bert_id, {'params': {'message_id': msg_id}}) + self.assertEqual(action.get('type'), 'ir.actions.client', + 'URL redirection: action without parameters should redirect to client action Inbox') + self.assertEqual(action.get('id'), act_id, + 'URL redirection: action without parameters should redirect to client action Inbox') + def test_20_message_post(self): """ Tests designed for message_post. """ cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs @@ -280,7 +395,8 @@ class test_mail(TestMailBase): 'message_post: mail.mail notifications should have been auto-deleted!') # Test: notifications emails: to a and b, c is email only, r is author - test_emailto = ['Administrator ', 'Bert Tartopoils '] + # test_emailto = ['Administrator ', 'Bert Tartopoils '] + test_emailto = ['"Followers of -Pigs-" ', '"Followers of -Pigs-" '] self.assertEqual(len(sent_emails), 2, 'message_post: notification emails wrong number of send emails') self.assertEqual(set([m['email_to'][0] for m in sent_emails]), set(test_emailto), @@ -353,7 +469,8 @@ class test_mail(TestMailBase): self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg2_id)]), 'mail.mail notifications should have been auto-deleted!') # Test: emails send by server (to a, b, c, d) - test_emailto = [u'Administrator ', u'Bert Tartopoils ', u'Carine Poilvache ', u'D\xe9d\xe9 Grosbedon '] + # test_emailto = [u'Administrator ', u'Bert Tartopoils ', u'Carine Poilvache ', u'D\xe9d\xe9 Grosbedon '] + test_emailto = [u'"Followers of Pigs" ', u'"Followers of Pigs" ', u'"Followers of Pigs" ', u'"Followers of Pigs" '] # self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect') for sent_email in sent_emails: self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon ', @@ -362,8 +479,8 @@ class test_mail(TestMailBase): 'message_post: notification email sent to more than one email address instead of a precise partner') self.assertIn(sent_email['email_to'][0], test_emailto, 'message_post: notification email email_to incorrect') - self.assertEqual(sent_email['reply_to'], '"Followers of Pigs" ', - 'message_post: notification email reply_to incorrect: should name Followers of Pigs, and have raoul email') + self.assertEqual(sent_email['reply_to'], 'r@r', # was '"Followers of Pigs" ', but makes no sense + 'message_post: notification email reply_to incorrect: should have raoul email') self.assertEqual(_mail_subject, sent_email['subject'], 'message_post: notification email subject incorrect') self.assertIn(html_sanitize(_body2), sent_email['body'], diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py index eb6ba22067b..ee166b82dde 100644 --- a/addons/mail/tests/test_mail_gateway.py +++ b/addons/mail/tests/test_mail_gateway.py @@ -20,6 +20,7 @@ ############################################################################## from openerp.addons.mail.tests.test_mail_base import TestMailBase +from openerp.tools import mute_logger MAIL_TEMPLATE = """Return-Path: To: {to} @@ -83,7 +84,148 @@ Sylvie class TestMailgateway(TestMailBase): - def test_00_message_process(self): + def test_00_partner_find_from_email(self): + """ Tests designed for partner fetch based on emails. """ + cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs + + # -------------------------------------------------- + # Data creation + # -------------------------------------------------- + # 1 - Partner ARaoul + p_a_id = self.res_partner.create(cr, uid, {'name': 'ARaoul', 'email': 'test@test.fr'}) + + # -------------------------------------------------- + # CASE1: without object + # -------------------------------------------------- + + # Do: find partner with email -> first partner should be found + partner_info = self.mail_thread.message_find_partner_from_emails(cr, uid, None, ['Maybe Raoul '], link_mail=False)[0] + self.assertEqual(partner_info['full_name'], 'Maybe Raoul ', + 'mail_thread: message_find_partner_from_emails did not handle email') + self.assertEqual(partner_info['partner_id'], p_a_id, + 'mail_thread: message_find_partner_from_emails wrong partner found') + + # Data: add some data about partners + # 2 - User BRaoul + p_b_id = self.res_partner.create(cr, uid, {'name': 'BRaoul', 'email': 'test@test.fr', 'user_ids': [(4, user_raoul.id)]}) + + # Do: find partner with email -> first user should be found + partner_info = self.mail_thread.message_find_partner_from_emails(cr, uid, None, ['Maybe Raoul '], link_mail=False)[0] + self.assertEqual(partner_info['partner_id'], p_b_id, + 'mail_thread: message_find_partner_from_emails wrong partner found') + + # -------------------------------------------------- + # CASE1: with object + # -------------------------------------------------- + + # Do: find partner in group where there is a follower with the email -> should be taken + self.mail_group.message_subscribe(cr, uid, [group_pigs.id], [p_b_id]) + partner_info = self.mail_group.message_find_partner_from_emails(cr, uid, group_pigs.id, ['Maybe Raoul '], link_mail=False)[0] + self.assertEqual(partner_info['partner_id'], p_b_id, + 'mail_thread: message_find_partner_from_emails wrong partner found') + + def test_05_mail_message_mail_mail(self): + """ Tests designed for testing email values based on mail.message, aliases, ... """ + cr, uid = self.cr, self.uid + + # Data: clean catchall domain + param_ids = self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.domain')]) + self.registry('ir.config_parameter').unlink(cr, uid, param_ids) + + # Do: create a mail_message with a reply_to, without message-id + msg_id = self.mail_message.create(cr, uid, {'subject': 'Subject', 'body': 'Body', 'reply_to': 'custom@example.com'}) + msg = self.mail_message.browse(cr, uid, msg_id) + # Test: message content + self.assertIn('reply_to', msg.message_id, + 'mail_message: message_id should be specific to a mail_message with a given reply_to') + self.assertEqual('custom@example.com', msg.reply_to, + 'mail_message: incorrect reply_to') + # Do: create a mail_mail with the previous mail_message and specified reply_to + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'reply_to': 'other@example.com', 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, 'other@example.com', + 'mail_mail: reply_to should be equal to the one coming from creation values') + # Do: create a mail_mail with the previous mail_message + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, msg.reply_to, + 'mail_mail: reply_to should be equal to the one coming from the mail_message') + + # Do: create a mail_message without a reply_to + msg_id = self.mail_message.create(cr, uid, {'subject': 'Subject', 'body': 'Body', 'model': 'mail.group', 'res_id': self.group_pigs_id, 'email_from': False}) + msg = self.mail_message.browse(cr, uid, msg_id) + # Test: message content + self.assertIn('mail.group', msg.message_id, + 'mail_message: message_id should contain model') + self.assertIn('%s' % self.group_pigs_id, msg.message_id, + 'mail_message: message_id should contain res_id') + self.assertFalse(msg.reply_to, + 'mail_message: should not generate a reply_to address when not specified') + # Do: create a mail_mail based on the previous mail_message + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertFalse(mail.reply_to, + 'mail_mail: reply_to should not have been guessed') + # Update message + self.mail_message.write(cr, uid, [msg_id], {'email_from': 'someone@example.com'}) + msg.refresh() + # Do: create a mail_mail based on the previous mail_message + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, msg.email_from, + 'mail_mail: reply_to should equal to mail_message.email_from when having no document or default alias') + + # Data: set catchall domain + self.registry('ir.config_parameter').set_param(cr, uid, 'mail.catchall.domain', 'schlouby.fr') + self.registry('ir.config_parameter').unlink(cr, uid, self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.alias')])) + + # Do: create a mail_mail based on the previous mail_message + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, '"Followers of Pigs" ', + 'mail_mail: reply_to should equal the mail.group alias') + + # Update message + self.mail_message.write(cr, uid, [msg_id], {'res_id': False, 'email_from': 'someone@schlouby.fr'}) + msg.refresh() + # Do: create a mail_mail based on the previous mail_message + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, msg.email_from, + 'mail_mail: reply_to should equal the mail_message email_from') + + # Data: set catchall alias + self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.alias', 'gateway') + + # Do: create a mail_mail based on the previous mail_message + mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, 'gateway@schlouby.fr', + 'mail_mail: reply_to should equal the catchall email alias') + + # Do: create a mail_mail + mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, 'gateway@schlouby.fr', + 'mail_mail: reply_to should equal the catchall email alias') + + # Do: create a mail_mail + mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel', 'reply_to': 'someone@example.com'}) + mail = self.mail_mail.browse(cr, uid, mail_id) + # Test: mail_mail content + self.assertEqual(mail.reply_to, 'someone@example.com', + 'mail_mail: reply_to should equal the rpely_to given to create') + + @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm') + def test_10_message_process(self): """ Testing incoming emails processing. """ cr, uid, user_raoul = self.cr, self.uid, self.user_raoul @@ -116,8 +258,11 @@ class TestMailgateway(TestMailBase): frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') sent_emails = self._build_email_kwargs_list # Test: one group created by mailgateway administrator - self.assertTrue(len(frog_groups) == 1) + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) + res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False) + self.assertEqual(res[0].get('create_uid'), uid, + 'message_process: group should have been created by uid as alias_user__id is False on the alias') # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, 'message_process: newly created group should have the incoming email in message_ids') @@ -150,9 +295,12 @@ class TestMailgateway(TestMailBase): self._init_mock_build_email() frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') sent_emails = self._build_email_kwargs_list - # Test: one group created by raoul - self.assertTrue(len(frog_groups) == 1) + # Test: one group created by Raoul + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) + res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False) + self.assertEqual(res[0].get('create_uid'), self.user_raoul_id, + 'message_process: group should have been created by alias_user_id') # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, 'message_process: newly created group should have the incoming email in message_ids') @@ -175,8 +323,8 @@ class TestMailgateway(TestMailBase): # Do: incoming email from a known partner that is also an user that can create a mail.group self.res_users.create(cr, uid, {'partner_id': p1id, 'login': 'sylvie', 'groups_id': [(6, 0, [self.group_employee_id])]}) frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') - # Test: one group created by Sylvie - self.assertTrue(len(frog_groups) == 1) + # Test: one group created by Raoul (or Sylvie maybe, if we implement it) + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, @@ -195,6 +343,7 @@ class TestMailgateway(TestMailBase): # Do: even with a wrong destination, a reply should end up in the correct thread frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other@gmail.com', + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', to='erroneous@example.com>', subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) # Test: no group 'Re: news' created, still only 1 Frogs group @@ -205,12 +354,30 @@ class TestMailgateway(TestMailBase): 'message_process: reply on Frogs should not have created a duplicate group with old subject') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one new message - self.assertTrue(len(frog_group.message_ids) == 2, 'message_process: group should contain 2 messages after reply') + self.assertEqual(len(frog_group.message_ids), 2, 'message_process: group should contain 2 messages after reply') # Test: author (and not recipient) added as follower frog_follower_ids = set([p.id for p in frog_group.message_follower_ids]) self.assertEqual(frog_follower_ids, set([p1id, p2id]), 'message_process: after reply, group should have 2 followers') + # Do: due to some issue, same email goes back into the mailgateway + frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other@gmail.com', + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', + subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + # Test: no group 'Re: news' created, still only 1 Frogs group + self.assertEqual(len(frog_groups), 0, + 'message_process: reply on Frogs should not have created a new group with new subject') + frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) + self.assertEqual(len(frog_groups), 1, + 'message_process: reply on Frogs should not have created a duplicate group with old subject') + frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) + # Test: no new message + self.assertEqual(len(frog_group.message_ids), 2, 'message_process: message with already existing message_id should not have been duplicated') + # Test: message_id is still unique + msg_ids = self.mail_message.search(cr, uid, [('message_id', 'ilike', '<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>')]) + self.assertEqual(len(msg_ids), 1, + 'message_process: message with already existing message_id should not have been duplicated') + # -------------------------------------------------- # Test3: email_from and partner finding # -------------------------------------------------- @@ -223,6 +390,7 @@ class TestMailgateway(TestMailBase): # Do: post a new message, with a known partner -> duplicate emails -> partner format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik ', to='erroneous@example.com>', subject='Re: news (2)', + msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) @@ -236,6 +404,7 @@ class TestMailgateway(TestMailBase): self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'}) format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik ', to='erroneous@example.com>', subject='Re: news (3)', + msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) @@ -250,6 +419,7 @@ class TestMailgateway(TestMailBase): self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'}) format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik ', to='erroneous@example.com>', subject='Re: news (3)', + msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) @@ -265,30 +435,40 @@ class TestMailgateway(TestMailBase): # Do: incoming email with model that does not accepts incoming emails must raise self.assertRaises(AssertionError, - format_and_process, - MAIL_TEMPLATE, to='noone@example.com', subject='spam', extra='', model='res.country') + format_and_process, + MAIL_TEMPLATE, + to='noone@example.com', subject='spam', extra='', model='res.country', + msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>') # Do: incoming email without model and without alias must raise self.assertRaises(AssertionError, - format_and_process, - MAIL_TEMPLATE, to='noone@example.com', subject='spam', extra='') + format_and_process, + MAIL_TEMPLATE, + to='noone@example.com', subject='spam', extra='', + msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>') # Do: incoming email with model that accepting incoming emails as fallback - frog_groups = format_and_process(MAIL_TEMPLATE, to='noone@example.com', subject='Spammy', extra='', model='mail.group') + frog_groups = format_and_process(MAIL_TEMPLATE, + to='noone@example.com', + subject='Spammy', extra='', model='mail.group', + msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>') self.assertEqual(len(frog_groups), 1, 'message_process: erroneous email but with a fallback model should have created a new mail.group') # Do: incoming email in plaintext should be stored as html - frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT, to='groups@example.com', subject='Frogs Return', extra='', msg_id='') + frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT, + to='groups@example.com', subject='Frogs Return', extra='', + msg_id='') # Test: one group created with one message - self.assertTrue(len(frog_groups) == 1) + self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) msg = frog_group.message_ids[0] # Test: plain text content should be wrapped and stored as html self.assertEqual(msg.body, '
\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
', 'message_process: plaintext incoming email incorrectly parsed') - def test_10_thread_parent_resolution(self): + @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm') + def test_20_thread_parent_resolution(self): """ Testing parent/child relationships are correctly established when processing incoming mails """ cr, uid = self.cr, self.uid @@ -305,19 +485,27 @@ class TestMailgateway(TestMailBase): # Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms # 0. Direct alias match - reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs ', extra='In-Reply-To: %s' % msg1.message_id) + reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs ', + extra='In-Reply-To: %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg1) # 1. In-Reply-To header - reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='In-Reply-To: %s' % msg1.message_id) + reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com', + extra='In-Reply-To: %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg2) # 2. References header - reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id) + reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com', + extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg3) # 3. Subject contains [] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids) - reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='', subject='Re: [%s] 1' % self.group_pigs_id) + reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com', + extra='', subject='Re: [%s] 1' % self.group_pigs_id, + msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>') self.mail_group.message_process(cr, uid, 'mail.group', reply_msg4) group_pigs.refresh() @@ -325,6 +513,57 @@ class TestMailgateway(TestMailBase): self.assertEqual(6, len(group_pigs.message_ids), 'message_process: group should contain 6 messages') self.assertEqual(3, len(msg1.child_ids), 'message_process: msg1 should have 3 children now') - def test_20_private_discussion(self): + def test_30_private_discussion(self): """ Testing private discussion between partners. """ - pass + cr, uid = self.cr, self.uid + + # Do: Raoul writes to Bert and Administrator, with a thread_model in context that should not be taken into account + msg1_pids = [self.partner_admin_id, self.partner_bert_id] + msg1_id = self.mail_thread.message_post(cr, self.user_raoul_id, False, + partner_ids=msg1_pids, + subtype='mail.mt_comment', + context={'thread_model': 'mail.group'}) + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg1_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = msg1_pids + test_nids = msg1_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients') + self.assertEqual(msg.model, False, + 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id') + + # Do: Bert replies through mailgateway (is a customer) + msg2_id = self.mail_thread.message_post(cr, uid, False, + author_id=self.partner_bert_id, + parent_id=msg1_id, subtype='mail.mt_comment') + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg2_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = [self.partner_admin_id, self.partner_raoul_id] + test_nids = test_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients when replying') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients when replying') + + # Do: Administrator replies + msg3_id = self.mail_thread.message_post(cr, uid, False, + parent_id=msg2_id, subtype='mail.mt_comment') + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg3_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = [self.partner_bert_id, self.partner_raoul_id] + test_nids = test_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients when replying') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients when replying') diff --git a/addons/mail/update.py b/addons/mail/update.py index bcec6f5f8b6..94416aeb356 100644 --- a/addons/mail/update.py +++ b/addons/mail/update.py @@ -5,7 +5,7 @@ import sys import urllib import urllib2 -from openerp import pooler +import openerp from openerp import release from openerp.osv import fields, osv from openerp.tools.translate import _ @@ -26,7 +26,7 @@ def get_sys_logs(self, cr, uid): """ Utility method to send a publisher warranty get logs messages. """ - pool = pooler.get_pool(cr.dbname) + pool = openerp.registry(cr.dbname) dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date') diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py index 2eb48f3d998..a6bfc34c213 100644 --- a/addons/mail/wizard/invite.py +++ b/addons/mail/wizard/invite.py @@ -37,10 +37,10 @@ class invite_wizard(osv.osv_memory): res_id = result.get('res_id') if 'message' in fields and model and res_id: ir_model = self.pool.get('ir.model') - model_ids = ir_model.search(cr, uid, [('model', '=', self.pool.get(model)._name)], context=context) + model_ids = ir_model.search(cr, uid, [('model', '=', self.pool[model]._name)], context=context) model_name = ir_model.name_get(cr, uid, model_ids, context=context)[0][1] - document_name = self.pool.get(model).name_get(cr, uid, [res_id], context=context)[0][1] + document_name = self.pool[model].name_get(cr, uid, [res_id], context=context)[0][1] message = _('

Hello,

%s invited you to follow %s document: %s.

') % (user_name, model_name, document_name) result['message'] = message elif 'message' in fields: @@ -63,7 +63,7 @@ class invite_wizard(osv.osv_memory): def add_followers(self, cr, uid, ids, context=None): for wizard in self.browse(cr, uid, ids, context=context): - model_obj = self.pool.get(wizard.res_model) + model_obj = self.pool[wizard.res_model] document = model_obj.browse(cr, uid, wizard.res_id, context=context) # filter partner_ids to get the new followers, to avoid sending email to already following partners @@ -75,7 +75,7 @@ class invite_wizard(osv.osv_memory): model_name = ir_model.name_get(cr, uid, model_ids, context=context)[0][1] # send an email if option checked and if a message exists (do not send void emails) - if wizard.send_mail and wizard.message: + if wizard.send_mail and wizard.message and not wizard.message == '
': # when deleting the message, cleditor keeps a
# add signature # FIXME 8.0: use notification_email_send, send a wall message and let mail handle email notification + message box signature_company = self.pool.get('mail.notification').get_signature_footer(cr, uid, user_id=uid, res_model=wizard.res_model, res_id=wizard.res_id, context=context) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 66e7149ac6d..dfda3038de8 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -19,10 +19,8 @@ # ############################################################################## -import base64 import re from openerp import tools - from openerp import SUPERUSER_ID from openerp.osv import osv from openerp.osv import fields @@ -174,12 +172,18 @@ class mail_compose_message(osv.TransientModel): related to. :param int res_id: id of the document record this mail is related to """ - doc_name_get = self.pool.get(model).name_get(cr, uid, [res_id], context=context) + doc_name_get = self.pool[model].name_get(cr, uid, [res_id], context=context) + record_name = False if doc_name_get: record_name = doc_name_get[0][1] - else: - record_name = False - return {'model': model, 'res_id': res_id, 'record_name': record_name} + values = { + 'model': model, + 'res_id': res_id, + 'record_name': record_name, + } + if record_name: + values['subject'] = 'Re: %s' % record_name + return values def get_message_data(self, cr, uid, message_id, context=None): """ Returns a defaults-like dict with initial values for the composition @@ -197,7 +201,7 @@ class mail_compose_message(osv.TransientModel): # create subject re_prefix = _('Re:') - reply_subject = tools.ustr(message_data.subject or '') + reply_subject = tools.ustr(message_data.subject or message_data.record_name or '') if not (reply_subject.startswith('Re:') or reply_subject.startswith(re_prefix)) and message_data.subject: reply_subject = "%s %s" % (re_prefix, reply_subject) # get partner_ids from original message @@ -224,33 +228,35 @@ class mail_compose_message(osv.TransientModel): email(s), rendering any template patterns on the fly if needed. """ if context is None: context = {} + ir_attachment_obj = self.pool.get('ir.attachment') active_ids = context.get('active_ids') is_log = context.get('mail_compose_log', False) for wizard in self.browse(cr, uid, ids, context=context): mass_mail_mode = wizard.composition_mode == 'mass_mail' - if mass_mail_mode: # mass mail: avoid any auto subscription because this could lead to people being follower of plenty of documents - context['mail_create_nosubscribe'] = True - active_model_pool = self.pool.get(wizard.model if wizard.model else 'mail.thread') + active_model_pool = self.pool[wizard.model if wizard.model else 'mail.thread'] # wizard works in batch mode: [res_id] or active_ids res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id] for res_id in res_ids: - # default values, according to the wizard options + # mail.message values, according to the wizard options post_values = { 'subject': wizard.subject, 'body': wizard.body, 'parent_id': wizard.parent_id and wizard.parent_id.id, 'partner_ids': [partner.id for partner in wizard.partner_ids], - 'attachments': [(attach.datas_fname or attach.name, base64.b64decode(attach.datas)) for attach in wizard.attachment_ids], + 'attachment_ids': [attach.id for attach in wizard.attachment_ids], } # mass mailing: render and override default values if mass_mail_mode and wizard.model: email_dict = self.render_message(cr, uid, wizard, res_id, context=context) - new_partner_ids = email_dict.pop('partner_ids', []) - post_values['partner_ids'] += new_partner_ids - new_attachments = email_dict.pop('attachments', []) - post_values['attachments'] += new_attachments + post_values['partner_ids'] += email_dict.pop('partner_ids', []) + post_values['attachments'] = email_dict.pop('attachments', []) + attachment_ids = [] + for attach_id in post_values.pop('attachment_ids'): + new_attach_id = ir_attachment_obj.copy(cr, uid, attach_id, {'res_model': self._name, 'res_id': wizard.id}, context=context) + attachment_ids.append(new_attach_id) + post_values['attachment_ids'] = attachment_ids post_values.update(email_dict) # email_from: mass mailing only can specify another email_from if email_dict.get('email_from'): @@ -313,7 +319,7 @@ class mail_compose_message(osv.TransientModel): exp = str(match.group()[2:-1]).strip() result = eval(exp, { 'user': self.pool.get('res.users').browse(cr, uid, uid, context=context), - 'object': self.pool.get(model).browse(cr, uid, res_id, context=context), + 'object': self.pool[model].browse(cr, uid, res_id, context=context), 'context': dict(context), # copy context to prevent side-effects of eval }) return result and tools.ustr(result) or '' diff --git a/addons/marketing_campaign/marketing_campaign.py b/addons/marketing_campaign/marketing_campaign.py index d4b05c50127..fdec2fb39e0 100644 --- a/addons/marketing_campaign/marketing_campaign.py +++ b/addons/marketing_campaign/marketing_campaign.py @@ -32,7 +32,6 @@ import re from openerp.addons.decimal_precision import decimal_precision as dp from openerp.osv import fields, osv -from openerp import netsvc from openerp.tools.translate import _ _intervalTypes = { @@ -166,7 +165,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor # dead code def signal(self, cr, uid, model, res_id, signal, run_existing=True, context=None): - record = self.pool.get(model).browse(cr, uid, res_id, context) + record = self.pool[model].browse(cr, uid, res_id, context) return self._signal(cr, uid, record, signal, run_existing, context) #dead code @@ -229,7 +228,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor if unique_value: if unique_field.ttype == 'many2one': unique_value = unique_value.id - similar_res_ids = self.pool.get(campaign_rec.object_id.model).search(cr, uid, + similar_res_ids = self.pool[campaign_rec.object_id.model].search(cr, uid, [(unique_field.name, '=', unique_value)], context=context) if similar_res_ids: duplicate_workitem_domain = [('res_id','in', similar_res_ids), @@ -237,7 +236,6 @@ Normal - the campaign runs normally and automatically sends all emails and repor return Workitems.search(cr, uid, duplicate_workitem_domain, context=context) -marketing_campaign() class marketing_campaign_segment(osv.osv): _name = "marketing.campaign.segment" @@ -350,7 +348,7 @@ class marketing_campaign_segment(osv.osv): act_ids = self.pool.get('marketing.campaign.activity').search(cr, uid, [('start', '=', True), ('campaign_id', '=', segment.campaign_id.id)], context=context) - model_obj = self.pool.get(segment.object_id.model) + model_obj = self.pool[segment.object_id.model] criteria = [] if segment.sync_last_date and segment.sync_mode != 'all': criteria += [(segment.sync_mode, '>', segment.sync_last_date)] @@ -384,7 +382,6 @@ class marketing_campaign_segment(osv.osv): Workitems.process_all(cr, uid, list(campaigns), context=context) return True -marketing_campaign_segment() class marketing_campaign_activity(osv.osv): _name = "marketing.campaign.activity" @@ -511,7 +508,6 @@ class marketing_campaign_activity(osv.osv): workitem = workitem_obj.browse(cr, uid, wi_id, context=context) return action(cr, uid, activity, workitem, context=context) -marketing_campaign_activity() class marketing_campaign_transition(osv.osv): _name = "marketing.campaign.transition" @@ -583,7 +579,6 @@ class marketing_campaign_transition(osv.osv): ('interval_positive', 'CHECK(interval_nbr >= 0)', 'The interval must be positive or zero') ] -marketing_campaign_transition() class marketing_campaign_workitem(osv.osv): _name = "marketing.campaign.workitem" @@ -595,7 +590,7 @@ class marketing_campaign_workitem(osv.osv): if not wi.res_id: continue - proxy = self.pool.get(wi.object_id.model) + proxy = self.pool[wi.object_id.model] if not proxy.exists(cr, uid, [wi.res_id]): continue ng = proxy.name_get(cr, uid, [wi.res_id], context=context) @@ -629,7 +624,7 @@ class marketing_campaign_workitem(osv.osv): for id, res_id, model in res: workitem_map.setdefault(model,{}).setdefault(res_id,set()).add(id) for model, id_map in workitem_map.iteritems(): - model_pool = self.pool.get(model) + model_pool = self.pool[model] condition_name[0] = model_pool._rec_name condition = [('id', 'in', id_map.keys()), condition_name] for res_id in model_pool.search(cr, uid, condition, context=context): @@ -677,7 +672,7 @@ class marketing_campaign_workitem(osv.osv): return False activity = workitem.activity_id - proxy = self.pool.get(workitem.object_id.model) + proxy = self.pool[workitem.object_id.model] object_id = proxy.browse(cr, uid, workitem.res_id, context=context) eval_context = { @@ -819,7 +814,6 @@ class marketing_campaign_workitem(osv.osv): raise osv.except_osv(_('No preview'),_('The current step for this item has no email or report to preview.')) return res -marketing_campaign_workitem() class email_template(osv.osv): _inherit = "email.template" @@ -829,7 +823,6 @@ class email_template(osv.osv): # TODO: add constraint to prevent disabling / disapproving an email account used in a running campaign -email_template() class report_xml(osv.osv): _inherit = 'ir.actions.report.xml' @@ -842,7 +835,6 @@ class report_xml(osv.osv): args.append(('model', '=', model)) return super(report_xml, self).search(cr, uid, args, offset, limit, order, context, count) -report_xml() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/marketing_campaign/report/campaign_analysis.py b/addons/marketing_campaign/report/campaign_analysis.py index 1fc8a5f1dc7..f09ed966857 100644 --- a/addons/marketing_campaign/report/campaign_analysis.py +++ b/addons/marketing_campaign/report/campaign_analysis.py @@ -98,6 +98,5 @@ class campaign_analysis(osv.osv): wi.date::date ) """) -campaign_analysis() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/marketing_campaign/res_partner.py b/addons/marketing_campaign/res_partner.py index c151c2f4050..b012cbb7181 100644 --- a/addons/marketing_campaign/res_partner.py +++ b/addons/marketing_campaign/res_partner.py @@ -36,7 +36,6 @@ class res_partner(osv.osv): }) return super(res_partner, self).copy(cr, uid, id, default=default, context=context) -res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/membership/membership.py b/addons/membership/membership.py index ae7f4948d72..b75284637c9 100644 --- a/addons/membership/membership.py +++ b/addons/membership/membership.py @@ -169,7 +169,6 @@ class membership_line(osv.osv): (_check_membership_date, 'Error, this membership product is out of date', []) ] -membership_line() class Partner(osv.osv): @@ -442,7 +441,6 @@ class Partner(osv.osv): self.pool.get('res.partner').write(cr, uid, ids, {}) return invoice_list -Partner() class Product(osv.osv): @@ -476,7 +474,6 @@ class Product(osv.osv): 'membership': False, } -Product() class Invoice(osv.osv): @@ -494,7 +491,6 @@ class Invoice(osv.osv): member_line_obj.write(cr, uid, mlines, {'date_cancel': today}) return super(Invoice, self).action_cancel(cr, uid, ids, context=context) -Invoice() class account_invoice_line(osv.osv): _inherit='account.invoice.line' @@ -561,6 +557,5 @@ class account_invoice_line(osv.osv): }, context=context) return result -account_invoice_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/membership/report/report_membership.py b/addons/membership/report/report_membership.py index f68e52992af..081a2f0d8a5 100644 --- a/addons/membership/report/report_membership.py +++ b/addons/membership/report/report_membership.py @@ -139,6 +139,5 @@ class report_membership(osv.osv): membership_amount )""") -report_membership() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/membership/wizard/membership_invoice.py b/addons/membership/wizard/membership_invoice.py index 2425cd648ea..a1e07146da0 100644 --- a/addons/membership/wizard/membership_invoice.py +++ b/addons/membership/wizard/membership_invoice.py @@ -73,6 +73,5 @@ class membership_invoice(osv.osv_memory): 'search_view_id': search_view_id, } -membership_invoice() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/company.py b/addons/mrp/company.py index af8a21f4934..375a318c9d0 100644 --- a/addons/mrp/company.py +++ b/addons/mrp/company.py @@ -30,7 +30,6 @@ class company(osv.osv): _defaults = { 'manufacturing_lead': lambda *a: 1.0, } -company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/html/index.html b/addons/mrp/html/index.html new file mode 100644 index 00000000000..afdc50ceb63 --- /dev/null +++ b/addons/mrp/html/index.html @@ -0,0 +1,171 @@ +
+
+
+

Manufacturing Resource Planning

+

Manage Bill of Materials, Plan Manufacturing Orders, Track Work Orders

+
+
+
+ + + +   + +
+
+
+

+Get all your assembly or manufacturing operations managed by OpenERP. Schedule +manufacturing orders and work orders automatically. Review the proposed +planning with the smart kanban and gantt views. Use the advanced analytics +features to detect bottleneck in resources capacities and inventory locations. +

+ +
+
+
+ + +
+
+

Schedule Manufacuring Orders Efficiently

+
+

+Get manufacturing orders and work orders scheduled automatically based on your +procurement rules, quantities forecasted and dependent demand (demand for this +part based on another part consuming it). +

+
+
+ +
+
+
+ + +
+
+

Define Flexible Master Data

+

Products, Bill of Materials and Routings

+
+ +
+
+

+Get the flexibility to create multi-level bill of materials, optional routing, +version changes and phantom bill of materials. You can use BoM for kits or for +manufacturing orders. +

+
+
+
+ +
+
+

Get Flexibility In All Opertions

+
+

+ Edit manually all proposed operations at any level of the progress. + With OpenERP, you will not be frustrated by a rigid system. +

+
+
+ +
+
+
+ + +
+
+

Schedule Work Orders

+

Check resources capacities and fix bottlenecks

+
+
+ +
+
+
+

+Define routings and plan the working time and capacity of your resources. +Quickly identify resource requirements and bottlenecks to ensure your production +meets your delivery schedule dates. +

+
+
+
+ +
+
+ +
+ Download our free E-book +
+ +
+
+

A Productive User Interface

+

Work with lists, calendars or gantt charts

+
+

+Organize manufacturing orders and work orders the way you like it. Process next +orders from the list view, control inthe calendar view and edit the proposed +schedule in the Gantt view. +

+
+
+

Lists

+
+ +
+
+
+

Gantt Charts

+ +

+
+
+

Calendar

+ +
+
+
+ +
+
+

Inventory & Manufacturing Analytics

+
+
+ +
+
+
+

+Track the evolution of the stock value, according to the level of manufacturing +activities as they progress in the transformation process. +

+
+
+
+ +
+
+

Fully Integrated with Operations

+

Sales, Purchases and Accounting integration

+
+

+Get your manufacturing resource planning accurate with it's full integration +with sales and purchases apps. The accounting integration allows real time +accounting valuation and deeper reporting on costs and revenues on your +manufacturing operations. +

+
+
+
+ +
+
+
+
diff --git a/addons/mrp/html/manufacturing_illu_01.png b/addons/mrp/html/manufacturing_illu_01.png new file mode 100644 index 00000000000..771223a8dd9 Binary files /dev/null and b/addons/mrp/html/manufacturing_illu_01.png differ diff --git a/addons/mrp/html/manufacturing_illu_02.png b/addons/mrp/html/manufacturing_illu_02.png new file mode 100644 index 00000000000..4a1910c0b73 Binary files /dev/null and b/addons/mrp/html/manufacturing_illu_02.png differ diff --git a/addons/mrp/html/mrp_bom.png b/addons/mrp/html/mrp_bom.png new file mode 100644 index 00000000000..29b0fd48ca9 Binary files /dev/null and b/addons/mrp/html/mrp_bom.png differ diff --git a/addons/mrp/html/mrp_calendar.png b/addons/mrp/html/mrp_calendar.png new file mode 100644 index 00000000000..a2d52775a0e Binary files /dev/null and b/addons/mrp/html/mrp_calendar.png differ diff --git a/addons/mrp/html/mrp_gantt.png b/addons/mrp/html/mrp_gantt.png new file mode 100644 index 00000000000..05c9315d5cd Binary files /dev/null and b/addons/mrp/html/mrp_gantt.png differ diff --git a/addons/mrp/html/mrp_integrate.png b/addons/mrp/html/mrp_integrate.png new file mode 100644 index 00000000000..954f54953cb Binary files /dev/null and b/addons/mrp/html/mrp_integrate.png differ diff --git a/addons/mrp/html/mrp_list.png b/addons/mrp/html/mrp_list.png new file mode 100644 index 00000000000..5813c32e6b7 Binary files /dev/null and b/addons/mrp/html/mrp_list.png differ diff --git a/addons/mrp/html/mrp_mo.png b/addons/mrp/html/mrp_mo.png new file mode 100644 index 00000000000..6138973570f Binary files /dev/null and b/addons/mrp/html/mrp_mo.png differ diff --git a/addons/mrp/html/mrp_product.png b/addons/mrp/html/mrp_product.png new file mode 100644 index 00000000000..cbfd054d72e Binary files /dev/null and b/addons/mrp/html/mrp_product.png differ diff --git a/addons/mrp/i18n/es_MX.po b/addons/mrp/i18n/es_MX.po index 82d584be219..f9fb2d53cb7 100644 --- a/addons/mrp/i18n/es_MX.po +++ b/addons/mrp/i18n/es_MX.po @@ -1,72 +1,61 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * mrp +# Spanish (Mexico) translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. # msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 6.0dev\n" -"Report-Msgid-Bugs-To: support@openerp.com\n" -"POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-03-12 16:35+0000\n" -"Last-Translator: Jordi Esteve (www.zikzakmedia.com) " -"\n" -"Language-Team: \n" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-03-23 21:44+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Spanish (Mexico) \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 04:59+0000\n" -"X-Generator: Launchpad (build 13830)\n" +"X-Launchpad-Export-Date: 2013-03-24 04:45+0000\n" +"X-Generator: Launchpad (build 16540)\n" #. module: mrp -#: field:mrp.production,move_created_ids:0 -#: field:mrp.production,move_created_ids2:0 -msgid "Moves Created" -msgstr "Movimientos creados" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_production_action +#: help:mrp.config.settings,module_mrp_repair:0 msgid "" -"Manufacturing Orders are usually proposed automatically by OpenERP based on " -"the bill of materials and the procurement rules, but you can also create " -"manufacturing orders manually. OpenERP will handle the consumption of the " -"raw materials (stock decrease) and the production of the finished products " -"(stock increase) when the order is processed." +"Allows to manage all product repairs.\n" +" * Add/remove products in the reparation\n" +" * Impact for stocks\n" +" * Invoicing (products and/or services)\n" +" * Warranty concept\n" +" * Repair quotation report\n" +" * Notes for the technician and for the final customer.\n" +" This installs the module mrp_repair." msgstr "" -"Las órdenes de fabricación suelen ser propuestas automáticamente por OpenERP " -"en base a la lista de materiales y las reglas de abastecimiento, pero " -"también puede crear órdenes de fabricación manualmente. OpenERP controlará " -"el consumo de las materias primas (disminución de stock) y la producción de " -"los productos terminados (aumento de stock) cuando se procese la orden." - -#. module: mrp -#: help:mrp.production,location_src_id:0 -msgid "Location where the system will look for components." -msgstr "Ubicación donde el sistema buscará los componentes." - -#. module: mrp -#: field:mrp.production,workcenter_lines:0 -msgid "Work Centers Utilisation" -msgstr "Utilización del centro de producción" - -#. module: mrp -#: view:mrp.routing.workcenter:0 -msgid "Routing Work Centers" -msgstr "Ruta de centros de producción" - -#. module: mrp -#: model:ir.module.module,shortdesc:mrp.module_meta_information -msgid "Manufacturing Resource Planning" -msgstr "Planificación de recursos de fabricación (MRP)" #. module: mrp #: report:mrp.production.order:0 msgid "No. Of Cycles" -msgstr "Núm. de ciclos" +msgstr "" #. module: mrp +#: help:mrp.production,location_src_id:0 +msgid "Location where the system will look for components." +msgstr "" + +#. module: mrp +#: field:mrp.production,workcenter_lines:0 +msgid "Work Centers Utilisation" +msgstr "" + +#. module: mrp +#: view:mrp.routing.workcenter:0 +msgid "Routing Work Centers" +msgstr "" + +#. module: mrp +#: field:mrp.production.workcenter.line,cycle:0 #: field:mrp.routing.workcenter,cycle_nbr:0 +#: field:report.workcenter.load,cycle:0 msgid "Number of Cycles" -msgstr "Número de ciclos" +msgstr "" #. module: mrp #: model:process.transition,note:mrp.process_transition_minimumstockprocure0 @@ -74,26 +63,12 @@ msgid "" "The 'Minimum stock rule' allows the system to create procurement orders " "automatically as soon as the minimum stock is reached." msgstr "" -"La 'regla de stock mínimo' permite al sistema de crear órdenes de " -"abasteciemiento automáticamente cuando el stock mínimo es alcanzado" - -#. module: mrp -#: field:mrp.production,picking_id:0 -#: field:mrp.production.order,picking_id:0 -msgid "Picking list" -msgstr "Albarán" - -#. module: mrp -#: code:addons/mrp/report/price.py:121 -#, python-format -msgid "Hourly Cost" -msgstr "Coste horario" #. module: mrp #: code:addons/mrp/report/price.py:130 #, python-format -msgid "Cost Price per Uom" -msgstr "Precio de coste pour Udm" +msgid "Hourly Cost" +msgstr "" #. module: mrp #: view:mrp.production:0 @@ -101,36 +76,32 @@ msgid "Scrap Products" msgstr "Productos de desecho" #. module: mrp -#: view:mrp.production.order:0 -#: field:mrp.production.order,day:0 -msgid "Day" -msgstr "Día" +#: view:mrp.workcenter:0 +msgid "Mrp Workcenter" +msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.mrp_routing_action #: model:ir.ui.menu,name:mrp.menu_mrp_routing_action msgid "Routings" -msgstr "Procesos productivos" - -#. module: mrp -#: field:mrp.workcenter,product_id:0 -msgid "Work Center Product" -msgstr "Producto centro de producción" +msgstr "" #. module: mrp #: view:mrp.bom:0 msgid "Search Bill Of Material" -msgstr "Buscar lista de materiales" +msgstr "" #. module: mrp #: model:process.node,note:mrp.process_node_stockproduct1 msgid "For stockable products and consumables" -msgstr "Para productos almacenables y consumibles" +msgstr "" #. module: mrp -#: model:process.transition,name:mrp.process_transition_stockproduction0 -msgid "To Produce" -msgstr "A producir" +#: help:mrp.bom,message_unread:0 +#: help:mrp.production,message_unread:0 +#: help:mrp.production.workcenter.line,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" #. module: mrp #: help:mrp.routing.workcenter,cycle_nbr:0 @@ -138,76 +109,63 @@ msgid "" "Number of iterations this work center has to do in the specified operation " "of the routing." msgstr "" -"Número de iteraciones que debe realizar este centro de producción en la " -"operación indicada de la ruta." + +#. module: mrp +#: view:product.product:0 +msgid "False" +msgstr "" #. module: mrp #: view:mrp.bom:0 #: field:mrp.bom,code:0 -#: view:mrp.production:0 #: field:mrp.production,name:0 msgid "Reference" -msgstr "Referencia" +msgstr "" #. module: mrp #: view:mrp.production:0 msgid "Finished Products" -msgstr "Productos finalizados" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Manufacturing Orders which are currently in production." +msgstr "" + +#. module: mrp +#: help:mrp.bom,message_summary:0 +#: help:mrp.production,message_summary:0 +#: help:mrp.production.workcenter.line,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_servicerfq0 #: model:process.transition,name:mrp.process_transition_stockrfq0 msgid "To Buy" -msgstr "A comprar" - -#. module: mrp -#: view:mrp.production.order:0 -msgid "Raw Material Location" -msgstr "Ubicación de materias primas" - -#. module: mrp -#: help:mrp.installer,mrp_operations:0 -msgid "" -"Enhances production orders with readiness states as well as the start date " -"and end date of execution of the order." msgstr "" -"Mejora las órdenes de producción con los estados de preparación, así como la " -"fecha de inicio y final de la ejecución de la orden." #. module: mrp #: model:process.transition,note:mrp.process_transition_purchaseprocure0 msgid "The system launches automatically a RFQ to the preferred supplier." msgstr "" -"El sistema crea automáticamente una petición de presupuesto al proveedor " -"preferido." #. module: mrp #: view:mrp.production:0 msgid "Products to Finish" -msgstr "Productos a terminar" +msgstr "" #. module: mrp #: selection:mrp.bom,method:0 msgid "Set / Pack" -msgstr "Conjunto / Paquete" - -#. module: mrp -#: field:mrp.installer,mrp_subproduct:0 -msgid "MRP Subproducts" -msgstr "Subproductos MRP" - -#. module: mrp -#: view:mrp.production:0 -#: field:mrp.production,state:0 -#: view:mrp.production.order:0 -#: field:mrp.production.order,state:0 -msgid "State" -msgstr "Estado" +msgstr "" #. module: mrp #: field:mrp.workcenter,costs_hour:0 msgid "Cost per hour" -msgstr "Coste por hora" +msgstr "" #. module: mrp #: model:process.transition,note:mrp.process_transition_stockproduction0 @@ -215,188 +173,221 @@ msgid "" "In case the Supply method of the product is Produce, the system creates a " "production order." msgstr "" -"En caso de que el método de suministro del producto es Producir, el sistema " -"crea una orden de producción." - -#. module: mrp -#: view:mrp.production:0 -msgid "UOM" -msgstr "UdM" #. module: mrp #: field:change.production.qty,product_qty:0 -#: field:mrp.bom,product_qty:0 -#: field:mrp.production,product_qty:0 -#: view:mrp.production.order:0 -#: field:mrp.production.order,product_qty:0 -#: field:mrp.production.product.line,product_qty:0 msgid "Product Qty" -msgstr "Ctdad producto" +msgstr "" #. module: mrp -#: help:mrp.workcenter,product_id:0 -msgid "" -"Fill this product to track easily your production costs in the analytic " -"accounting." +#: view:mrp.production:0 +msgid "Unit of Measure" msgstr "" -"Introduzca este producto para realizar fácilmente un seguimiento de sus " -"costes de producción en la contabilidad analítica." #. module: mrp #: model:process.node,note:mrp.process_node_purchaseprocure0 msgid "For purchased material" -msgstr "Para material comprado" +msgstr "" #. module: mrp -#: field:mrp.bom.revision,indice:0 -msgid "Revision" -msgstr "Revisión" +#: model:ir.ui.menu,name:mrp.menu_mrp_production_order_action +msgid "Order Planning" +msgstr "" #. module: mrp -#: model:ir.ui.menu,name:mrp.next_id_77 -msgid "Reporting" -msgstr "Informe" +#: field:mrp.config.settings,module_mrp_operations:0 +msgid "Allow detailed planning of work order" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:633 +#, python-format +msgid "Cannot cancel manufacturing order!" +msgstr "" #. module: mrp #: field:mrp.workcenter,costs_cycle_account_id:0 msgid "Cycle Account" -msgstr "Cuenta ciclo" +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:121 +#: code:addons/mrp/report/price.py:130 #, python-format msgid "Work Cost" -msgstr "Coste del trabajo" - -#. module: mrp -#: report:bom.structure:0 -msgid "[" -msgstr "[" +msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_procureserviceproduct0 msgid "Procurement of services" -msgstr "Abastecimiento de servicios" +msgstr "" #. module: mrp #: view:mrp.workcenter:0 msgid "Capacity Information" -msgstr "Información de capacidad" +msgstr "" + +#. module: mrp +#: field:mrp.routing,workcenter_lines:0 +msgid "Work Centers" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,help:mrp.mrp_routing_action +msgid "" +"

\n" +" Click to create a routing.\n" +"

\n" +" Routings allow you to create and manage the manufacturing\n" +" operations that should be followed within your work centers " +"in\n" +" order to produce a product. They are attached to bills of\n" +" materials that will define the required raw materials.\n" +"

\n" +" " +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: field:mrp.production,move_created_ids2:0 +msgid "Produced Products" +msgstr "" #. module: mrp #: report:mrp.production.order:0 msgid "Destination Location" -msgstr "Ubicación destino" - -#. module: mrp -#: view:mrp.installer:0 -msgid "title" -msgstr "título" - -#. module: mrp -#: model:ir.ui.menu,name:mrp.menu_mrp_bom -msgid "Master Data" -msgstr "Datos principales" - -#. module: mrp -#: model:process.transition,note:mrp.process_transition_stockmts0 -msgid "" -"The system waits for the products to be available in the stock. These " -"products are typically procured manually or through a minimum stock rule." msgstr "" -"El sistema espera a que los productos estén disponibles en el stock. Estos " -"productos suelen ser adquiridos de forma manual o a través de una regla de " -"stock mínimo." + +#. module: mrp +#: view:mrp.config.settings:0 +msgid "Master Data" +msgstr "" + +#. module: mrp +#: field:mrp.config.settings,module_mrp_byproduct:0 +msgid "Produce several products from one manufacturing order" +msgstr "" + +#. module: mrp +#: help:mrp.config.settings,group_mrp_properties:0 +msgid "" +"The selection of the right Bill of Material to use will depend on the " +"properties specified on the sales order and the Bill of Material." +msgstr "" + +#. module: mrp +#: view:mrp.bom:0 +msgid "" +"When processing a sales order for this product, the delivery order\n" +" will contain the raw materials, instead of " +"the finished product." +msgstr "" #. module: mrp #: report:mrp.production.order:0 msgid "Partner Ref" -msgstr "Ref. empresa" +msgstr "" #. module: mrp #: selection:mrp.workcenter.load,measure_unit:0 msgid "Amount in hours" -msgstr "Cantidad en horas" +msgstr "" #. module: mrp #: field:mrp.production,product_lines:0 msgid "Scheduled goods" -msgstr "Bienes planificados" +msgstr "" #. module: mrp #: selection:mrp.bom,type:0 msgid "Sets / Phantom" -msgstr "Conjuntos / Fantasma" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: field:mrp.production,state:0 +msgid "Status" +msgstr "" #. module: mrp #: help:mrp.bom,position:0 msgid "Reference to a position in an external plan." -msgstr "Referencia a una ubicación en una plan. externa" +msgstr "" #. module: mrp -#: selection:mrp.production.order,month:0 -msgid "August" -msgstr "Agosto" - -#. module: mrp -#: constraint:stock.move:0 -msgid "You try to assign a lot which is not from the same product" -msgstr "Está intentando asignar un lote que no es del mismo producto" - -#. module: mrp -#: model:ir.model,name:mrp.model_mrp_production_order -msgid "Production Order Report" -msgstr "Informe de órden de producción" - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "June" -msgstr "Junio" +#: model:res.groups,name:mrp.group_mrp_routings +msgid "Manage Routings" +msgstr "" #. module: mrp #: model:ir.model,name:mrp.model_mrp_product_produce msgid "Product Produce" -msgstr "Producir producto" +msgstr "" #. module: mrp -#: selection:mrp.production.order,month:0 -msgid "October" -msgstr "Octubre" +#: constraint:mrp.bom:0 +msgid "Error ! You cannot create recursive BoM." +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:177 -#, python-format -msgid "Components Cost of " -msgstr "Coste de los componentes de " +#: model:ir.model,name:mrp.model_mrp_routing_workcenter +msgid "Work Center Usage" +msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_procurestockableproduct0 msgid "Procurement of stockable Product" -msgstr "Abastecimiento de producto almacenable" +msgstr "" #. module: mrp -#: view:mrp.bom:0 -msgid "Default UOM" -msgstr "UdM por defecto" +#: model:ir.actions.act_window,help:mrp.mrp_production_action +msgid "" +"

\n" +" Click to create a manufacturing order. \n" +"

\n" +" A manufacuring order, based on a bill of materials, will\n" +" consume raw materials and produce finished products.\n" +"

\n" +" Manufacturing orders are usually proposed automatically " +"based\n" +" on customer requirements or automated rules like the " +"minimum\n" +" stock rule.\n" +"

\n" +" " +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:130 +#: sql_constraint:mrp.production:0 +msgid "Reference must be unique per Company!" +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:139 #: report:bom.structure:0 +#: view:mrp.bom:0 #: field:mrp.product_price,number:0 +#: view:mrp.production:0 #: report:mrp.production.order:0 #, python-format msgid "Quantity" -msgstr "Cantidad" +msgstr "" #. module: mrp -#: field:mrp.production.workcenter.line,hour:0 -msgid "Nbr of hours" -msgstr "Nº de horas" +#: help:mrp.workcenter,product_id:0 +msgid "" +"Fill this product to easily track your production costs in the analytic " +"accounting." +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,product_id:0 +msgid "Work Center Product" +msgstr "" #. module: mrp #: view:mrp.production:0 msgid "Confirm Production" -msgstr "Confirmar producción" +msgstr "" #. module: mrp #: model:process.transition,note:mrp.process_transition_stockproduct0 @@ -404,8 +395,6 @@ msgid "" "The system creates an order (production or purchased) depending on the sold " "quantity and the products parameters." msgstr "" -"El sistema crea una orden (de producción o de compra) en función de la " -"cantidad vendida y los parámetros de los productos." #. module: mrp #: model:process.transition,note:mrp.process_transition_servicemts0 @@ -413,49 +402,85 @@ msgid "" "This is used in case of a service without any impact in the system, a " "training session for instance." msgstr "" -"Esto se utiliza en caso de un servicio sin ningún tipo de impacto en el " -"sistema, una sesión de formación, por ejemplo." #. module: mrp -#: field:mrp.installer,mrp_repair:0 -msgid "Repairs" -msgstr "Reparaciones" +#: field:mrp.bom,product_qty:0 +#: field:mrp.production,product_qty:0 +#: field:mrp.production.product.line,product_qty:0 +msgid "Product Quantity" +msgstr "" #. module: mrp -#: field:mrp.installer,stock_location:0 -msgid "Advanced Routes" -msgstr "Rutas avanzadas" +#: help:mrp.production,picking_id:0 +msgid "" +"This is the Internal Picking List that brings the finished product to the " +"production plan" +msgstr "" #. module: mrp #: model:ir.ui.menu,name:mrp.menu_view_resource_calendar_search_mrp msgid "Working Time" -msgstr "Horario trabajo" +msgstr "" + +#. module: mrp +#: help:mrp.production,state:0 +msgid "" +"When the production order is created the status is set to 'Draft'.\n" +" If the order is confirmed the status is set to 'Waiting " +"Goods'.\n" +" If any exceptions are there, the status is set to 'Picking " +"Exception'.\n" +" If the stock is available then the status is set to 'Ready " +"to Produce'.\n" +" When the production gets started then the status is set to " +"'In Production'.\n" +" When the production is over, the status is set to 'Done'." +msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.action_report_in_out_picking_tree msgid "Weekly Stock Value Variation" -msgstr "Variación del valor del stock semanal" - -#. module: mrp -#: help:mrp.installer,mrp_repair:0 -msgid "" -"Enables warranty and repair management (and their impact on stocks and " -"invoicing)." msgstr "" -"Activa la garantía y la gestión de reparaciones (y su impacto sobre stocks y " -"facturación)" #. module: mrp -#: field:mrp.production,date_planned_date:0 +#: model:ir.actions.act_window,help:mrp.mrp_property_action +msgid "" +"

\n" +" Click to create a new property.\n" +"

\n" +" The Properties in OpenERP are used to select the right bill " +"of\n" +" materials for manufacturing a product when you have " +"different\n" +" ways of building the same product. You can assign several\n" +" properties to each bill of materials. When a salesperson\n" +" creates a sales order, they can relate it to several " +"properties\n" +" and OpenERP will automatically select the BoM to use " +"according\n" +" the needs.\n" +"

\n" +" " +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: field:mrp.production,date_planned:0 #: report:mrp.production.order:0 -#: field:mrp.production.order,date_planned:0 msgid "Scheduled Date" -msgstr "Fecha programada" +msgstr "" #. module: mrp +#: code:addons/mrp/procurement.py:124 +#, python-format +msgid "Manufacturing Order %s created." +msgstr "" + +#. module: mrp +#: view:mrp.bom:0 #: report:mrp.production.order:0 msgid "Bill Of Material" -msgstr "Lista de Material" +msgstr "" #. module: mrp #: help:mrp.routing,location_id:0 @@ -464,165 +489,140 @@ msgid "" "needed.Set a location if you produce at a fixed location. This can be a " "partner location if you subcontract the manufacturing operations." msgstr "" -"Dejarlo vacío si se produce en el mismo lugar en que los productos acabados " -"son necesarios. Indique una ubicación si se produce en una ubicación fija. " -"Puede ser una ubicación de otra empresa si subcontrata las operaciones de " -"fabricación." #. module: mrp #: view:board.board:0 msgid "Stock Value Variation" -msgstr "Variación del valor de stock" +msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.action2 msgid "Bill of Materials Structure" -msgstr "Estructura lista de materiales" +msgstr "" #. module: mrp #: model:process.node,note:mrp.process_node_serviceproduct0 msgid "Product type is service" -msgstr "Producto de tipo servicio" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_property_group_action -msgid "" -"Define specific property groups that can be assigned to the properties of " -"your bill of materials." msgstr "" -"Definir grupos específicos de propiedad que se pueden asignar a las " -"propiedades de su lista de materiales." - -#. module: mrp -#: model:process.transition,name:mrp.process_transition_bom0 -msgid "Manufacturing decomposition" -msgstr "Descomposición fabricación" - -#. module: mrp -#: model:process.node,note:mrp.process_node_serviceproduct1 -msgid "For Services." -msgstr "Para servicios" - -#. module: mrp -#: field:mrp.bom.revision,date:0 -msgid "Modification Date" -msgstr "Fecha de modificación" - -#. module: mrp -#: help:mrp.workcenter,costs_cycle_account_id:0 -#: help:mrp.workcenter,costs_hour_account_id:0 -msgid "" -"Complete this only if you want automatic analytic accounting entries on " -"production orders." -msgstr "" -"Rellenarlo sólo si desea crear entradas automáticas de contabilidad " -"analítica según órdenes de producción." - -#. module: mrp -#: field:mrp.production.workcenter.line,cycle:0 -msgid "Nbr of cycles" -msgstr "Nº de ciclos" - -#. module: mrp -#: model:process.node,note:mrp.process_node_orderrfq0 -#: model:process.node,note:mrp.process_node_rfq0 -msgid "Request for Quotation." -msgstr "Solicitud de presupuesto." - -#. module: mrp -#: model:process.transition,note:mrp.process_transition_billofmaterialrouting0 -msgid "" -"The Bill of Material is linked to a routing, i.e. the succession of work " -"centers." -msgstr "" -"La lista de materiales está vinculada a una ruta, es decir, la sucesión de " -"centros de producción." - -#. module: mrp -#: constraint:product.product:0 -msgid "Error: Invalid ean code" -msgstr "Error: Código EAN no válido" - -#. module: mrp -#: view:mrp.routing:0 -#: field:mrp.routing,location_id:0 -msgid "Production Location" -msgstr "Ubicación de producción" - -#. module: mrp -#: view:mrp.production:0 -msgid "Change Qty" -msgstr "Cambiar Ctd." - -#. module: mrp -#: view:mrp.production:0 -msgid "Force Reservation" -msgstr "Forzar reservas" - -#. module: mrp -#: field:mrp.bom.revision,author_id:0 -msgid "Author" -msgstr "Autor" - -#. module: mrp -#: field:report.mrp.inout,value:0 -msgid "Stock value" -msgstr "Valor del stock" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.action_product_bom_structure -msgid "Product BoM Structure" -msgstr "Estructura LdM del producto" - -#. module: mrp -#: view:mrp.production:0 -msgid "Search Production" -msgstr "Buscar producción" - -#. module: mrp -#: code:addons/mrp/report/price.py:130 -#, python-format -msgid "Supplier Price per Uom" -msgstr "Precio proveedor por UdM" - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "March" -msgstr "Marzo" - -#. module: mrp -#: field:mrp.bom,child_complete_ids:0 -msgid "BoM Hierarchy" -msgstr "Estructura LdM" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.act_mrp_product_produce -#: view:mrp.product.produce:0 -#: view:mrp.production:0 -msgid "Produce" -msgstr "Producir" #. module: mrp #: help:mrp.workcenter,costs_cycle:0 msgid "Specify Cost of Work Center per cycle." msgstr "" +#. module: mrp +#: model:process.transition,name:mrp.process_transition_bom0 +msgid "Manufacturing decomposition" +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_serviceproduct1 +msgid "For Services." +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_orderrfq0 +#: model:process.node,note:mrp.process_node_rfq0 +msgid "Request for Quotation." +msgstr "" + +#. module: mrp +#: view:change.production.qty:0 +#: view:mrp.config.settings:0 +#: view:mrp.product.produce:0 +#: view:mrp.product_price:0 +#: view:mrp.workcenter.load:0 +msgid "or" +msgstr "" + +#. module: mrp +#: model:process.transition,note:mrp.process_transition_billofmaterialrouting0 +msgid "" +"The Bill of Material is linked to a routing, i.e. the succession of work " +"centers." +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: field:mrp.production,move_created_ids:0 +msgid "Products to Produce" +msgstr "" + +#. module: mrp +#: view:mrp.config.settings:0 +msgid "Apply" +msgstr "" + +#. module: mrp +#: view:mrp.routing:0 +#: field:mrp.routing,location_id:0 +msgid "Production Location" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Force Reservation" +msgstr "" + +#. module: mrp +#: field:report.mrp.inout,value:0 +msgid "Stock value" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.action_product_bom_structure +msgid "Product BoM Structure" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Search Production" +msgstr "" + +#. module: mrp +#: help:mrp.routing.workcenter,sequence:0 +msgid "" +"Gives the sequence order when displaying a list of routing Work Centers." +msgstr "" + +#. module: mrp +#: field:mrp.bom,child_complete_ids:0 +msgid "BoM Hierarchy" +msgstr "" + +#. module: mrp +#: model:process.transition,name:mrp.process_transition_stockproduction0 +msgid "To Produce" +msgstr "" + +#. module: mrp +#: help:mrp.config.settings,module_stock_no_autopicking:0 +msgid "" +"This module allows an intermediate picking process to provide raw materials " +"to production orders.\n" +" For example to manage production made by your suppliers (sub-" +"contracting).\n" +" To achieve this, set the assembled product which is sub-" +"contracted to \"No Auto-Picking\"\n" +" and put the location of the supplier in the routing of the " +"assembly operation.\n" +" This installs the module stock_no_autopicking." +msgstr "" + #. module: mrp #: selection:mrp.production,state:0 -#: view:mrp.production.order:0 -#: selection:mrp.production.order,state:0 msgid "Picking Exception" -msgstr "Excepción albarán" +msgstr "" #. module: mrp #: field:mrp.bom,bom_lines:0 msgid "BoM Lines" -msgstr "Líneas de las listas de materiales" +msgstr "" #. module: mrp #: field:mrp.workcenter,time_start:0 msgid "Time before prod." -msgstr "Tiempo antes producción" +msgstr "" #. module: mrp #: help:mrp.routing,active:0 @@ -630,59 +630,53 @@ msgid "" "If the active field is set to False, it will allow you to hide the routing " "without removing it." msgstr "" -"Si el campo activo se desmarca, permite ocultar la ruta sin eliminarla." #. module: mrp #: model:process.transition,name:mrp.process_transition_billofmaterialrouting0 msgid "Material Routing" -msgstr "Ruta del material" +msgstr "" #. module: mrp #: view:mrp.production:0 #: field:mrp.production,move_lines2:0 #: report:mrp.production.order:0 -#: field:mrp.production.order,consumed_products:0 msgid "Consumed Products" -msgstr "Productos consumidos" - -#. module: mrp -#: constraint:mrp.bom:0 -msgid "Error ! You can not create recursive BoM." -msgstr "¡Error! No puede crear Listas de Material recursivas." +msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.action_mrp_workcenter_load_wizard #: model:ir.model,name:mrp.model_mrp_workcenter_load #: model:ir.model,name:mrp.model_report_workcenter_load msgid "Work Center Load" -msgstr "Carga centro de producción" +msgstr "" #. module: mrp -#: code:addons/mrp/procurement.py:45 +#: code:addons/mrp/procurement.py:50 #, python-format msgid "No BoM defined for this product !" -msgstr "¡No se ha definido LdM para este producto!" +msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.mrp_bom_form_action2 #: model:ir.ui.menu,name:mrp.menu_mrp_bom_form_action2 msgid "Bill of Material Components" -msgstr "Componentes de lista de materiales" +msgstr "" #. module: mrp -#: field:mrp.production.order,nbr:0 -msgid "# of Lines" -msgstr "Nº de líneas" +#: model:ir.model,name:mrp.model_stock_move +msgid "Stock Move" +msgstr "" #. module: mrp #: model:ir.ui.menu,name:mrp.menu_mrp_planning +#: view:mrp.config.settings:0 msgid "Planning" -msgstr "Planificación" +msgstr "" #. module: mrp #: view:mrp.production:0 msgid "Ready" -msgstr "Preparado" +msgstr "" #. module: mrp #: help:mrp.production,routing_id:0 @@ -692,142 +686,151 @@ msgid "" "operations and to plan future loads on work centers based on production " "plannification." msgstr "" -"Lista de las operaciones (lista de los centros de trabajo) para producir los " -"productos acabados. La ruta se utiliza principalmente para calcular los " -"costes del centro de trabajo durante las operaciones y planificar la carga " -"en el futuro en los centros de trabajo basada en la planificación de " -"producción." #. module: mrp #: help:mrp.workcenter,time_cycle:0 msgid "Time in hours for doing one cycle." -msgstr "Tiempo en horas para realizar un ciclo." +msgstr "" #. module: mrp -#: report:bom.structure:0 -msgid "BOM Ref" -msgstr "Ref LdM" +#: model:ir.actions.act_window,help:mrp.mrp_bom_form_action2 +msgid "" +"

\n" +" Click to add a component to a bill of material.\n" +"

\n" +" Bills of materials components are components and by-" +"products\n" +" used to create master bills of materials. Use this menu to\n" +" search in which BoM a specific component is used.\n" +"

\n" +" " +msgstr "" + +#. module: mrp +#: constraint:mrp.bom:0 +msgid "BoM line product should not be same as BoM product." +msgstr "" #. module: mrp #: view:mrp.production:0 -#: selection:mrp.production,state:0 -#: view:mrp.production.order:0 -#: selection:mrp.production.order,state:0 msgid "In Production" -msgstr "En producción" +msgstr "" #. module: mrp #: model:ir.ui.menu,name:mrp.menu_mrp_property msgid "Master Bill of Materials" -msgstr "Lista de materiales maestra" +msgstr "" #. module: mrp -#: help:mrp.bom,product_uos:0 +#: help:mrp.config.settings,module_product_manufacturer:0 msgid "" -"Product UOS (Unit of Sale) is the unit of measurement for the invoicing and " -"promotion of stock." +"This allows you to define the following for a product:\n" +" * Manufacturer\n" +" * Manufacturer Product Name\n" +" * Manufacturer Product Code\n" +" * Product Attributes.\n" +" This installs the module product_manufacturer." msgstr "" -"UdV del producto (Unidad de Venta) es la unidad de medida para la " -"facturación y la promoción de existencias." #. module: mrp #: view:mrp.product_price:0 #: view:mrp.workcenter.load:0 msgid "Print" -msgstr "Imprimir" +msgstr "" #. module: mrp #: view:mrp.bom:0 #: view:mrp.workcenter:0 msgid "Type" -msgstr "Tipo" +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:150 -#: code:addons/mrp/report/price.py:201 -#, python-format -msgid "Total Cost of " -msgstr "Coste total de " +#: model:ir.actions.act_window,help:mrp.mrp_workcenter_action +msgid "" +"

\n" +" Click to add a work center.\n" +"

\n" +" Work Centers allow you to create and manage manufacturing\n" +" units. They consist of workers and/or machines, which are\n" +" considered as units for task assignation as well as " +"capacity\n" +" and planning forecast.\n" +"

\n" +" " +msgstr "" #. module: mrp #: model:process.node,note:mrp.process_node_minimumstockrule0 msgid "Linked to the 'Minimum stock rule' supplying method." -msgstr "Vinculado al método de abastecimiento 'Regla de stock mínimo'." +msgstr "" #. module: mrp #: selection:mrp.workcenter.load,time_unit:0 msgid "Per month" -msgstr "Por mes" +msgstr "" #. module: mrp -#: code:addons/mrp/mrp.py:595 -#: code:addons/mrp/wizard/change_production_qty.py:77 -#: code:addons/mrp/wizard/change_production_qty.py:82 -#, python-format -msgid "Couldn't find bill of material for product" -msgstr "No se puede encontrar la lista de material para el producto" +#: help:mrp.bom,product_uom:0 +msgid "" +"Unit of Measure (Unit of Measure) is the unit of measurement for the " +"inventory control" +msgstr "" #. module: mrp #: report:bom.structure:0 msgid "Product Name" -msgstr "Nombre producto" - -#. module: mrp -#: code:addons/mrp/mrp.py:495 -#, python-format -msgid "Invalid action !" -msgstr "¡Acción no válida!" +msgstr "" #. module: mrp #: help:mrp.bom,product_efficiency:0 msgid "A factor of 0.9 means a loss of 10% within the production process." msgstr "" -"Un factor de 0.9 indica una pérdida del 10% en el proceso de producción." #. module: mrp -#: view:mrp.installer:0 -msgid "" -"Add more functionalities to the core Manufacturing Application with the " -"following addons." +#: code:addons/mrp/mrp.py:737 +#: code:addons/mrp/mrp.py:765 +#, python-format +msgid "Warning!" msgstr "" -"Añada más funcionalidades en el núcleo de la aplicación de fabricación con " -"los siguientes módulos." #. module: mrp #: report:mrp.production.order:0 msgid "Printing date" -msgstr "Fecha impresión" +msgstr "" #. module: mrp #: model:process.node,name:mrp.process_node_orderrfq0 #: model:process.node,name:mrp.process_node_rfq0 msgid "RFQ" -msgstr "Petición presupuesto" +msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_producttostockrules0 msgid "Procurement rule" -msgstr "Regla de abastecimiento" +msgstr "" #. module: mrp -#: help:mrp.workcenter,costs_hour:0 -msgid "Specify Cost of Work center per hour." -msgstr "Especificar costes del centro de trabajo por hora." +#: help:mrp.workcenter,costs_cycle_account_id:0 +#: help:mrp.workcenter,costs_hour_account_id:0 +msgid "" +"Fill this only if you want automatic analytic accounting entries on " +"production orders." +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Mark as Started" +msgstr "" #. module: mrp #: view:mrp.production:0 msgid "Partial" -msgstr "Parcial" - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "September" -msgstr "Septiembre" +msgstr "" #. module: mrp #: report:mrp.production.order:0 msgid "WorkCenter" -msgstr "Centro de producción" +msgstr "" #. module: mrp #: model:process.transition,note:mrp.process_transition_procureserviceproduct0 @@ -836,188 +839,282 @@ msgid "" "order creates a RFQ for a subcontracting purchase order or waits until the " "service is done (= the delivery of the products)." msgstr "" -"Dependiendo del método elegido para \"suministrar\" del servicio, la orden " -"de abastecimiento crea una solicitud de presupuesto para un pedido de compra " -"(subcontratación) o espera hasta que el servicio se realice (= la entrega de " -"los productos)." #. module: mrp #: selection:mrp.production,priority:0 -#: selection:mrp.production.order,priority:0 msgid "Urgent" -msgstr "Urgente" +msgstr "" #. module: mrp -#: model:ir.model,name:mrp.model_mrp_routing_workcenter -msgid "Work Center Usage" +#: view:mrp.production:0 +msgid "Manufacturing Orders which are waiting for raw materials." +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:285 +#, python-format +msgid "" +"The Product Unit of Measure you chose has a different category than in the " +"product form." msgstr "" #. module: mrp #: model:ir.model,name:mrp.model_mrp_production +#: view:mrp.config.settings:0 +#: view:mrp.production:0 +#: field:mrp.production.workcenter.line,production_id:0 +#: field:procurement.order,production_id:0 msgid "Manufacturing Order" -msgstr "Órden de producción" +msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_productionprocureproducts0 msgid "Procurement of raw material" -msgstr "Abastecimiento de materias primas" +msgstr "" #. module: mrp -#: help:mrp.routing.workcenter,hour_nbr:0 +#: sql_constraint:mrp.bom:0 msgid "" -"Time in hours for this work center to achieve the operation of the specified " -"routing." +"All product quantities must be greater than 0.\n" +"You should install the mrp_byproduct module if you want to manage extra " +"products on BoMs !" msgstr "" -"Tiempo en horas para este centro de producción para realizar la operación de " -"la ruta indicada." #. module: mrp #: view:mrp.production:0 #: field:mrp.production,cycle_total:0 msgid "Total Cycles" -msgstr "Total ciclos" +msgstr "" #. module: mrp #: selection:mrp.production,state:0 -#: view:mrp.production.order:0 -#: selection:mrp.production.order,state:0 msgid "Ready to Produce" -msgstr "Listo para producir" +msgstr "" #. module: mrp -#: field:mrp.bom.revision,name:0 -msgid "Modification name" -msgstr "Nombre de modificación" +#: field:mrp.bom,message_is_follower:0 +#: field:mrp.production,message_is_follower:0 +#: field:mrp.production.workcenter.line,message_is_follower:0 +msgid "Is a Follower" +msgstr "" #. module: mrp #: view:mrp.bom:0 #: view:mrp.production:0 -#: field:mrp.production.order,date:0 msgid "Date" -msgstr "Fecha" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,help:mrp.mrp_production_action_planning +msgid "" +"

\n" +" Click to start a new manufacturing order. \n" +"

\n" +" A manufacuring order, based on a bill of materials, will\n" +" consume raw materials and produce finished products.\n" +"

\n" +" Manufacturing orders are usually proposed automatically " +"based\n" +" on customer requirements or automated rules like the " +"minimum\n" +" stock rule.\n" +"

\n" +" " +msgstr "" #. module: mrp #: field:mrp.bom,type:0 msgid "BoM Type" -msgstr "Tipo de lista de materiales" +msgstr "" #. module: mrp -#: view:mrp.production.order:0 -msgid "Extended Filters..." -msgstr "Filtros extendidos..." - -#. module: mrp -#: code:addons/mrp/procurement.py:47 +#: code:addons/mrp/procurement.py:52 #, python-format msgid "" "Procurement '%s' has an exception: 'No BoM defined for this product !'" msgstr "" -"Abastecimiento '%s' tiene una excepción: 'El producto no tiene LdM definida!'" #. module: mrp -#: view:mrp.production.order:0 #: view:mrp.property:0 msgid "Search" -msgstr "Buscar" +msgstr "" #. module: mrp -#: field:report.workcenter.load,cycle:0 -msgid "Nbr of cycle" -msgstr "Núm. de ciclo" +#: model:process.node,note:mrp.process_node_billofmaterial0 +msgid "Product's structure" +msgstr "" #. module: mrp #: model:ir.model,name:mrp.model_res_company msgid "Companies" -msgstr "Compañías" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:634 +#, python-format +msgid "" +"You must first cancel related internal picking attached to this " +"manufacturing order." +msgstr "" #. module: mrp #: model:process.node,name:mrp.process_node_minimumstockrule0 #: model:process.node,name:mrp.process_node_productminimumstockrule0 msgid "Minimum Stock" -msgstr "Stock mínimo" +msgstr "" #. module: mrp -#: model:ir.ui.menu,name:mrp.menus_dash_mrp -msgid "Dashboard" -msgstr "Tablero" - -#. module: mrp -#: view:board.board:0 -msgid "Work Center Future Load" -msgstr "Carga futura del centro de producción" +#: code:addons/mrp/report/price.py:160 +#: code:addons/mrp/report/price.py:211 +#, python-format +msgid "Total Cost of %s %s" +msgstr "" #. module: mrp #: model:process.node,name:mrp.process_node_stockproduct0 #: model:process.node,name:mrp.process_node_stockproduct1 #: model:process.process,name:mrp.process_process_stockableproductprocess0 msgid "Stockable Product" -msgstr "Producto almacenable" +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:121 +#: code:addons/mrp/report/price.py:130 #, python-format msgid "Work Center name" -msgstr "Nombre del centro de producción" +msgstr "" #. module: mrp #: field:mrp.routing,code:0 msgid "Code" -msgstr "Código" +msgstr "" #. module: mrp #: report:mrp.production.order:0 msgid "No. Of Hours" -msgstr "Núm. de horas" - -#. module: mrp -#: field:mrp.installer,mrp_jit:0 -msgid "Just In Time Scheduling" -msgstr "Planificación 'Just in Time'" +msgstr "" #. module: mrp #: view:mrp.property:0 -#: view:mrp.property.group:0 msgid "Property Group" -msgstr "Grupo de propiedad" +msgstr "" #. module: mrp -#: view:mrp.production:0 -msgid "Qty" -msgstr "Ctd." +#: field:mrp.config.settings,group_mrp_routings:0 +msgid "Manage routings and work orders " +msgstr "" #. module: mrp #: model:process.node,note:mrp.process_node_production0 msgid "Manufacturing Plan." -msgstr "Plan de producción" +msgstr "" #. module: mrp #: view:mrp.routing:0 #: view:mrp.workcenter:0 msgid "Inactive" -msgstr "Inactivo" - -#. module: mrp -#: help:mrp.installer,mrp_subproduct:0 -msgid "" -"Enables multiple product output from a single production order: without " -"this, a production order can have only one output product." msgstr "" -"Habilita la salida de múltiples productos de una sola orden de producción: " -"sin ello, una orden de producción sólo puede tener un producto de salida." #. module: mrp #: view:change.production.qty:0 +#: view:mrp.config.settings:0 #: view:mrp.product.produce:0 #: view:mrp.product_price:0 -#: view:mrp.production:0 #: view:mrp.workcenter.load:0 msgid "Cancel" -msgstr "Cancelar" +msgstr "" + +#. module: mrp +#: model:process.transition,note:mrp.process_transition_servicerfq0 +msgid "" +"If the service has a 'Buy' supply method, this creates a RFQ, a " +"subcontracting demand for instance." +msgstr "" #. module: mrp #: view:mrp.production:0 -msgid "Split in production lots" -msgstr "Dividir en lotes de producción" +msgid "Late" +msgstr "" + +#. module: mrp +#: model:process.node,name:mrp.process_node_servicemts0 +msgid "Make to stock" +msgstr "" + +#. module: mrp +#: report:bom.structure:0 +msgid "BOM Name" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.act_product_manufacturing_open +#: model:ir.actions.act_window,name:mrp.mrp_production_action +#: model:ir.actions.act_window,name:mrp.mrp_production_action_planning +#: model:ir.ui.menu,name:mrp.menu_mrp_production_action +#: view:mrp.production:0 +msgid "Manufacturing Orders" +msgstr "" + +#. module: mrp +#: selection:mrp.production,state:0 +msgid "Awaiting Raw Materials" +msgstr "" + +#. module: mrp +#: field:mrp.bom,position:0 +msgid "Internal Reference" +msgstr "" + +#. module: mrp +#: field:mrp.production,product_uos_qty:0 +msgid "Product UoS Quantity" +msgstr "" + +#. module: mrp +#: field:mrp.bom,name:0 +#: report:mrp.production.order:0 +#: field:mrp.production.product.line,name:0 +#: view:mrp.property:0 +#: field:mrp.routing,name:0 +#: field:mrp.routing.workcenter,name:0 +msgid "Name" +msgstr "" + +#. module: mrp +#: report:mrp.production.order:0 +msgid "Production Order N° :" +msgstr "" + +#. module: mrp +#: field:mrp.product.produce,mode:0 +msgid "Mode" +msgstr "" + +#. module: mrp +#: help:mrp.bom,message_ids:0 +#: help:mrp.production,message_ids:0 +#: help:mrp.production.workcenter.line,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: mrp +#: field:mrp.workcenter.load,measure_unit:0 +msgid "Amount measuring unit" +msgstr "" + +#. module: mrp +#: help:mrp.config.settings,module_mrp_jit:0 +msgid "" +"This allows Just In Time computation of procurement orders.\n" +" All procurement orders will be processed immediately, which " +"could in some\n" +" cases entail a small performance impact.\n" +" This installs the module mrp_jit." +msgstr "" + +#. module: mrp +#: help:mrp.workcenter,costs_hour:0 +msgid "Specify Cost of Work Center per hour." +msgstr "" #. module: mrp #: help:mrp.workcenter,capacity_per_cycle:0 @@ -1026,1257 +1123,140 @@ msgid "" "Center represents a team of 5 workers, the capacity per cycle is 5." msgstr "" -#. module: mrp -#: model:process.transition,note:mrp.process_transition_servicerfq0 -msgid "" -"If the service has a 'Buy' supply method, this creates a RFQ, a " -"subcontracting demand for instance." -msgstr "" -"Si el servicio tiene un método de suministro 'Comprar', se crea una " -"solicitud de presupuesto, por ejemplo, una petición de subcontratación." - -#. module: mrp -#: field:mrp.production,move_prod_id:0 -msgid "Move product" -msgstr "Movimiento producto" - -#. module: mrp -#: view:mrp.production:0 -msgid "Late" -msgstr "Retrasado" - -#. module: mrp -#: model:process.node,name:mrp.process_node_servicemts0 -msgid "Make to stock" -msgstr "Obtener para stock" - -#. module: mrp -#: help:mrp.routing.workcenter,sequence:0 -msgid "" -"Gives the sequence order when displaying a list of routing work centers." -msgstr "" -"Proporciona el orden de secuencias cuando se muestra una lista de " -"enrutamiento de los centros de trabajo." - -#. module: mrp -#: report:bom.structure:0 -msgid "BOM Name" -msgstr "Nombre LdM" - -#. module: mrp -#: view:mrp.production:0 -msgid "Start Production" -msgstr "Empezar producción" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.open_board_manufacturing -#: model:ir.ui.menu,name:mrp.menu_board_manufacturing -msgid "Production Dashboard" -msgstr "Tablero de producción" - -#. module: mrp -#: view:mrp.production:0 -msgid "Source Loc." -msgstr "Ubic. orígen" - -#. module: mrp -#: field:mrp.bom,position:0 -msgid "Internal Reference" -msgstr "Referencia interna" - -#. module: mrp -#: help:mrp.installer,stock_location:0 -msgid "" -"Manages product routes and paths within and between locations (e.g. " -"warehouses)." -msgstr "" -"Gestiona las rutas y caminos de los productos dentro y entre las ubicaciones " -"(por ejemplo, almacenes)." - -#. module: mrp -#: model:process.node,note:mrp.process_node_billofmaterial0 -msgid "Product's structure" -msgstr "Estructura de producto" - -#. module: mrp -#: field:mrp.bom,name:0 -#: report:mrp.production.order:0 -#: field:mrp.production.product.line,name:0 -#: field:mrp.routing,name:0 -#: field:mrp.routing.workcenter,name:0 -msgid "Name" -msgstr "Nombre" - -#. module: mrp -#: view:mrp.installer:0 -msgid "MRP Application Configuration" -msgstr "Configuración aplicación MRP" - -#. module: mrp -#: help:mrp.installer,mrp_jit:0 -msgid "" -"Enables Just In Time computation of procurement orders.\n" -"\n" -"While it's more resource intensive than the default setup, the JIT computer " -"avoids having to wait for the procurement scheduler to run or having to run " -"the procurement scheduler manually." -msgstr "" -"Permite el cálculo de las órdenes de abastecimiento justo a tiempo (Just In " -"Time).\n" -"\n" -"Si bien consume más recursos que la configuración predeterminada, el cálculo " -"JIT evita tener que esperar a que se ejecute el planificador de " -"abastecimientos o tener que ejecutar el planificador de abastecimientos de " -"forma manual." - -#. module: mrp -#: field:mrp.product.produce,mode:0 -msgid "Mode" -msgstr "Modo" - -#. module: mrp -#: report:bom.structure:0 -msgid "]" -msgstr "]" - -#. module: mrp -#: field:mrp.workcenter.load,measure_unit:0 -msgid "Amount measuring unit" -msgstr "Importe unidad de medida" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_production_action_planning -msgid "" -"Manufacturing Orders describe the operations that need to be carried out and " -"the raw materials usage for each production stage. You use specifications " -"(bills of materials or BoM) to work out the raw material requirements and " -"the manufacturing orders needed for the finished products. Once the bills of " -"materials have been defined, OpenERP is capable of automatically deciding on " -"the manufacturing route depending on the needs of the company." -msgstr "" -"Las órdenes de fabricación describen las operaciones que deben ser " -"realizadas y las materias primas necesarias para cada etapa de fabricación. " -"Utilice las especificaciones (listas de materiales o LdM) para obtener las " -"necesidades de materias primas y las órdenes de fabricación necesarias para " -"los productos finales. Una vez las listas de materiales hayan sido " -"definidas, OpenERP es capz de decidir automáticamente al ruta de fabricación " -"en función de las necesidades de la compañía." - -#. module: mrp -#: constraint:mrp.production:0 -msgid "Order quantity cannot be negative or zero !" -msgstr "¡Cantidad ordenada no puede ser negativa o cero!" - #. module: mrp #: model:ir.actions.act_window,name:mrp.mrp_production_action3 msgid "Manufacturing Orders in Progress" -msgstr "Órdenes de producción en progreso" +msgstr "" #. module: mrp -#: model:ir.module.module,description:mrp.module_meta_information -msgid "" -"\n" -" This is the base module to manage the manufacturing process in OpenERP.\n" -"\n" -" Features:\n" -" * Make to Stock / Make to Order (by line)\n" -" * Multi-level BoMs, no limit\n" -" * Multi-level routing, no limit\n" -" * Routing and work center integrated with analytic accounting\n" -" * Scheduler computation periodically / Just In Time module\n" -" * Multi-pos, multi-warehouse\n" -" * Different reordering policies\n" -" * Cost method by product: standard price, average price\n" -" * Easy analysis of troubles or needs\n" -" * Very flexible\n" -" * Allows to browse Bill of Materials in complete structure\n" -" that include child and phantom BoMs\n" -" It supports complete integration and planification of stockable goods,\n" -" consumable of services. Services are completely integrated with the " -"rest\n" -" of the software. For instance, you can set up a sub-contracting service\n" -" in a BoM to automatically purchase on order the assembly of your " -"production.\n" -"\n" -" Reports provided by this module:\n" -" * Bill of Material structure and components\n" -" * Load forecast on Work Centers\n" -" * Print a production order\n" -" * Stock forecasts\n" -" Dashboard provided by this module::\n" -" * List of next production orders\n" -" * List of deliveries (out picking)\n" -" * Graph of work center load\n" -" * List of procurement in exception\n" -" " +#: model:ir.actions.client,name:mrp.action_client_mrp_menu +msgid "Open MRP Menu" msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.mrp_production_action4 msgid "Manufacturing Orders Waiting Products" -msgstr "Órdenes de producción en espera de productos" +msgstr "" #. module: mrp #: view:mrp.bom:0 #: view:mrp.production:0 -#: view:mrp.production.order:0 #: view:mrp.property:0 #: view:mrp.routing:0 #: view:mrp.workcenter:0 msgid "Group By..." -msgstr "Agrupar por..." +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:121 +#: code:addons/mrp/report/price.py:130 #, python-format msgid "Cycles Cost" -msgstr "Coste ciclos" +msgstr "" + +#. module: mrp +#: code:addons/mrp/wizard/change_production_qty.py:83 +#: code:addons/mrp/wizard/change_production_qty.py:88 +#, python-format +msgid "Cannot find bill of material for this product." +msgstr "" #. module: mrp #: selection:mrp.workcenter.load,measure_unit:0 msgid "Amount in cycles" -msgstr "Valor en ciclos" +msgstr "" #. module: mrp #: field:mrp.production,location_dest_id:0 -#: view:mrp.production.order:0 -#: field:mrp.production.order,location_dest_id:0 msgid "Finished Products Location" -msgstr "Ubicación productos finalizados" +msgstr "" #. module: mrp #: model:ir.ui.menu,name:mrp.menu_pm_resources_config msgid "Resources" -msgstr "Recursos" +msgstr "" + +#. module: mrp +#: help:mrp.routing.workcenter,hour_nbr:0 +msgid "" +"Time in hours for this Work Center to achieve the operation of the specified " +"routing." +msgstr "" #. module: mrp #: field:mrp.workcenter,costs_journal_id:0 msgid "Analytic Journal" -msgstr "Diario analítico" +msgstr "" #. module: mrp -#: model:ir.actions.act_window,name:mrp.mrp_workcenter_action -#: model:ir.ui.menu,name:mrp.menu_view_resource_search_mrp -#: field:mrp.routing,workcenter_lines:0 -msgid "Work Centers" -msgstr "Centros de producción" +#: code:addons/mrp/report/price.py:139 +#, python-format +msgid "Supplier Price per Unit of Measure" +msgstr "" #. module: mrp #: selection:mrp.workcenter.load,time_unit:0 msgid "Per week" -msgstr "Por semana" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_routing_action -msgid "" -"Routings allow you to create and manage the manufacturing operations that " -"should be followed within your work centers in order to produce a product. " -"They are attached to bills of materials that will define the required raw " -"materials." msgstr "" -"Las rutas le permiten crear y gestionar las operaciones de fabricación a " -"realizar en sus centros de producción para fabricar un producto. Están " -"relacionadas con las listas de materiales que definirán las materias primas " -"necesarias." #. module: mrp -#: field:report.workcenter.load,hour:0 -msgid "Nbr of hour" -msgstr "Núm. de hora" +#: field:mrp.bom,message_unread:0 +#: field:mrp.production,message_unread:0 +#: field:mrp.production.workcenter.line,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: mrp +#: model:process.transition,note:mrp.process_transition_stockmts0 +msgid "" +"The system waits for the products to be available in the stock. These " +"products are typically procured manually or through a minimum stock rule." +msgstr "" #. module: mrp #: view:mrp.routing:0 msgid "Work Center Operations" -msgstr "Operaciones del centro de producción" +msgstr "" #. module: mrp #: view:mrp.routing:0 msgid "Notes" -msgstr "Notas" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Manufacturing Orders which are ready to start production." +msgstr "" #. module: mrp #: model:ir.model,name:mrp.model_mrp_bom #: view:mrp.bom:0 #: field:mrp.production,bom_id:0 -#: field:mrp.production.order,bom_id:0 #: model:process.node,name:mrp.process_node_billofmaterial0 msgid "Bill of Material" -msgstr "Lista de material" +msgstr "" #. module: mrp #: view:mrp.workcenter.load:0 msgid "Select time unit" -msgstr "Seleccionar unidad de tiempo" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.product_supply_method_produce +#: model:ir.ui.menu,name:mrp.menu_mrp_bom +#: model:ir.ui.menu,name:mrp.menu_mrp_product_form +#: view:mrp.config.settings:0 +msgid "Products" +msgstr "" #. module: mrp #: view:report.workcenter.load:0 msgid "Work Center load" -msgstr "Carga centro de producción" +msgstr "" #. module: mrp #: help:mrp.production,location_dest_id:0 msgid "Location where the system will stock the finished products." -msgstr "Ubicación donde el sistema almacenará los productos finalizados." - -#. module: mrp -#: help:mrp.production,picking_id:0 -msgid "" -"This is the Internal Picking List that brings the finished product to the " -"production plan" msgstr "" -"Este es el albarán interno que trae el producto terminado hacia el plan de " -"producción." - -#. module: mrp -#: field:stock.change.standard.price,change_parent_price:0 -msgid "Change Parent Price" -msgstr "Cambiar precio padre" - -#. module: mrp -#: model:ir.model,name:mrp.model_stock_move -msgid "Stock Move" -msgstr "Moviemiento de stock" - -#. module: mrp -#: model:process.transition,note:mrp.process_transition_producttostockrules0 -msgid "" -"The Minimum Stock Rule is an automatic procurement rule based on a mini and " -"maxi quantity. It's available in the Inventory management menu and " -"configured by product." -msgstr "" -"La regla de stock mínimo es una regla de abastecimiento automático basado en " -"una cantidad mínima y máxima. Está disponible en el menú de gestión de " -"inventario y configurable por producto." - -#. module: mrp -#: selection:mrp.workcenter.load,time_unit:0 -msgid "Day by day" -msgstr "Día por día" - -#. module: mrp -#: view:mrp.bom:0 -msgid "Revisions" -msgstr "Revisiones" - -#. module: mrp -#: view:mrp.installer:0 -msgid "Configure Your Manufacturing Resource Planning Application" -msgstr "" -"Configure su aplicación de planificación de recursos de fabricación (MRP)" - -#. module: mrp -#: field:mrp.production,priority:0 -#: field:mrp.production.order,priority:0 -msgid "Priority" -msgstr "Prioridad" - -#. module: mrp -#: model:ir.model,name:mrp.model_stock_picking -msgid "Picking List" -msgstr "Albarán" - -#. module: mrp -#: view:mrp.production.order:0 -msgid "Month -1" -msgstr "Mes -1" - -#. module: mrp -#: code:addons/mrp/mrp.py:924 -#, python-format -msgid "Manufacturing order '%s' is scheduled for the %s." -msgstr "Órden de producción '%s' planificada para el '%s'" - -#. module: mrp -#: report:mrp.production.order:0 -msgid "Production Order N° :" -msgstr "Núm. orden producción :" - -#. module: mrp -#: code:addons/mrp/mrp.py:640 -#, python-format -msgid "Manufacturing order '%s' is ready to produce." -msgstr "Orden fabricación '%s' está preparada para producir." - -#. module: mrp -#: model:ir.model,name:mrp.model_mrp_production_product_line -msgid "Production Scheduled Product" -msgstr "Fabricación planificada producto" - -#. module: mrp -#: help:res.company,manufacturing_lead:0 -msgid "Security days for each manufacturing operation." -msgstr "Días de seguridad para cada operación de fabricación." - -#. module: mrp -#: model:process.node,name:mrp.process_node_mts0 -#: model:process.transition,name:mrp.process_transition_servicemts0 -#: model:process.transition,name:mrp.process_transition_stockmts0 -msgid "Make to Stock" -msgstr "Obtener para stock" - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "July" -msgstr "Julio" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_bom_form_action -msgid "" -"Master Bills of Materials allow you to create and manage the list of " -"necessary raw materials used to make a finished product. OpenERP will use " -"these BoMs to automatically propose manufacturing orders according to " -"product needs. You can either create a bill of materials to define specific " -"production steps or define a single multi-level bill of materials." -msgstr "" -"Las listas de materiales maestras le permiten crear y gestionar la lista de " -"las materias primas necesarias utilizadas para fabricar un producto acabado. " -"OpenERP utilizará estas LdMs para proponer automáticamente órdenes de " -"fabricación en función de las necesidades de producto. Puede crear una lista " -"de materiales para definir los pasos de producción o definir una única lista " -"de materiales multi-nivel." - -#. module: mrp -#: model:process.transition,note:mrp.process_transition_stockrfq0 -msgid "" -"In case the Supply method of the product is Buy, the system creates a " -"purchase order." -msgstr "" -"En caso de que el método de suministro del producto se Compra, el sistema " -"crea un pedido de compra." - -#. module: mrp -#: model:ir.model,name:mrp.model_procurement_order -msgid "Procurement" -msgstr "Abastecimiento" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.action_view_mrp_product_price_wizard -#: view:mrp.product_price:0 -msgid "Product Cost Structure" -msgstr "Estructura de los costes del producto" - -#. module: mrp -#: code:addons/mrp/report/price.py:130 -#, python-format -msgid "Components suppliers" -msgstr "Proveedores de componentes" - -#. module: mrp -#: model:ir.model,name:mrp.model_mrp_installer -msgid "mrp.installer" -msgstr "mrp.instalador" - -#. module: mrp -#: view:mrp.production:0 -msgid "Production Work Centers" -msgstr "Centros de trabajo de producción" - -#. module: mrp -#: view:mrp.production.order:0 -#: field:mrp.production.order,month:0 -msgid "Month" -msgstr "Mes" - -#. module: mrp -#: code:addons/mrp/wizard/change_production_qty.py:62 -#, python-format -msgid "Active Id is not found" -msgstr "ID activo no se encuentra" - -#. module: mrp -#: view:mrp.workcenter:0 -msgid "Search for mrp workcenter" -msgstr "Buscar por centro de producción mrp" - -#. module: mrp -#: view:mrp.bom:0 -msgid "BoM Structure" -msgstr "Despiece de la LdM" - -#. module: mrp -#: field:mrp.production,date_start:0 -#: field:mrp.production.order,date_start:0 -msgid "Start Date" -msgstr "Fecha inicial" - -#. module: mrp -#: field:mrp.workcenter,costs_hour_account_id:0 -msgid "Hour Account" -msgstr "Cuenta horas" - -#. module: mrp -#: view:mrp.production:0 -msgid "Destination Loc." -msgstr "Ubic. destino" - -#. module: mrp -#: field:mrp.production.order,product_id2:0 -msgid "Product Consumed" -msgstr "Producto consumido" - -#. module: mrp -#: view:mrp.production:0 -msgid "Pending" -msgstr "Pendiente" - -#. module: mrp -#: field:mrp.bom,active:0 -#: field:mrp.routing,active:0 -msgid "Active" -msgstr "Activo" - -#. module: mrp -#: model:process.node,name:mrp.process_node_procureproducts0 -msgid "Procure Products" -msgstr "Abastecer productos" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.action_report_workcenter_load_tree -#: view:report.workcenter.load:0 -msgid "Work Center Loads" -msgstr "Cargas centro de producción" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.mrp_property_action -#: model:ir.ui.menu,name:mrp.menu_mrp_property_action -#: view:mrp.bom:0 -#: field:mrp.bom,property_ids:0 -#: view:mrp.property:0 -#: view:procurement.order:0 -#: field:procurement.order,property_ids:0 -msgid "Properties" -msgstr "Propiedades" - -#. module: mrp -#: help:mrp.production,origin:0 -msgid "" -"Reference of the document that generated this production order request." -msgstr "" -"Referencia al documento que generó esta solicitud de orden de producción." - -#. module: mrp -#: sql_constraint:mrp.bom:0 -msgid "" -"All product quantities must be greater than 0.\n" -"You should install the mrp_subproduct module if you want to manage extra " -"products on BoMs !" -msgstr "" -"Todas las cantidades de producto deben de ser superiores a cero.\n" -"¡Debe instalar el módulo mrp_subproduct si quiere gestionar productos extra " -"en las LdM!" - -#. module: mrp -#: view:mrp.production:0 -msgid "Extra Information" -msgstr "Información extra" - -#. module: mrp -#: model:ir.model,name:mrp.model_change_production_qty -msgid "Change Quantity of Products" -msgstr "Cambiar cantidad de productos" - -#. module: mrp -#: model:process.node,note:mrp.process_node_productionorder0 -msgid "Drives the procurement orders for raw material." -msgstr "Guía las órdenes de abastecimiento para materias primas." - -#. module: mrp -#: view:mrp.production.order:0 -msgid "Current" -msgstr "Actual" - -#. module: mrp -#: field:mrp.workcenter,costs_general_account_id:0 -msgid "General Account" -msgstr "Cuenta general" - -#. module: mrp -#: report:mrp.production.order:0 -msgid "SO Number" -msgstr "Número venta" - -#. module: mrp -#: selection:mrp.production,state:0 -#: view:mrp.production.order:0 -#: selection:mrp.production.order,state:0 -msgid "Done" -msgstr "Realizado" - -#. module: mrp -#: model:ir.model,name:mrp.model_stock_change_standard_price -msgid "Change Standard Price" -msgstr "Cambio de precio estándar" - -#. module: mrp -#: field:mrp.production,origin:0 -#: report:mrp.production.order:0 -#: field:mrp.production.order,origin:0 -msgid "Source Document" -msgstr "Documento origen" - -#. module: mrp -#: selection:mrp.production,priority:0 -#: selection:mrp.production.order,priority:0 -msgid "Not urgent" -msgstr "No urgente" - -#. module: mrp -#: help:stock.change.standard.price,change_parent_price:0 -msgid "" -"This will change the price of parent products also according to the BoM " -"structure specified for the product." -msgstr "" -"Esto cambiará el precio de los productos padre de acuerdo a la estructura de " -"la lista de materiales del producto." - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.mrp_production_action2 -msgid "Manufacturing Orders To Start" -msgstr "Órdenes de producción a iniciar" - -#. module: mrp -#: code:addons/mrp/mrp.py:495 -#, python-format -msgid "Cannot delete Production Order(s) which are in %s State!" -msgstr "" -"¡No se puede eliminar orden(es) de producción que están en estado %s!" - -#. module: mrp -#: model:ir.model,name:mrp.model_mrp_workcenter -#: field:mrp.production.workcenter.line,workcenter_id:0 -#: field:mrp.routing.workcenter,workcenter_id:0 -#: view:mrp.workcenter:0 -#: field:report.workcenter.load,workcenter_id:0 -msgid "Work Center" -msgstr "Centro de producción" - -#. module: mrp -#: field:mrp.workcenter,capacity_per_cycle:0 -msgid "Capacity per Cycle" -msgstr "Capacidad por ciclo" - -#. module: mrp -#: model:ir.model,name:mrp.model_product_product -#: view:mrp.bom:0 -#: field:mrp.bom,product_id:0 -#: view:mrp.production:0 -#: field:mrp.production,product_id:0 -#: report:mrp.production.order:0 -#: view:mrp.production.order:0 -#: field:mrp.production.order,product_id:0 -#: field:mrp.production.product.line,product_id:0 -msgid "Product" -msgstr "Producto" - -#. module: mrp -#: view:mrp.production:0 -#: field:mrp.production,hour_total:0 -msgid "Total Hours" -msgstr "Total horas" - -#. module: mrp -#: field:mrp.production,location_src_id:0 -#: field:mrp.production.order,location_src_id:0 -msgid "Raw Materials Location" -msgstr "Ubicación materias primas" - -#. module: mrp -#: view:mrp.product_price:0 -msgid "Print Cost Structure of Product." -msgstr "Imprimir la estructura de costes del producto" - -#. module: mrp -#: field:mrp.bom,product_uos:0 -#: field:mrp.production.product.line,product_uos:0 -msgid "Product UOS" -msgstr "UdV del producto" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_workcenter_action -msgid "" -"Work Centers allow you to create and manage manufacturing units consisting " -"of one or more persons and/or machines that can be considered as a unit for " -"capacity and planning forecasting." -msgstr "" -"Los centros de trabajo le permiten crear y administrar unidades de " -"producción que consisten en una o más personas y / o máquinas que se pueden " -"considerar como una unidad para la capacidad de planificación y previsión." - -#. module: mrp -#: view:mrp.production:0 -msgid "Consume Products" -msgstr "Consumir productos" - -#. module: mrp -#: field:mrp.bom,product_uom:0 -#: field:mrp.production,product_uom:0 -#: field:mrp.production.order,product_uom:0 -#: field:mrp.production.product.line,product_uom:0 -msgid "Product UOM" -msgstr "UdM del producto" - -#. module: mrp -#: model:process.node,name:mrp.process_node_stock0 -#: model:process.transition,name:mrp.process_transition_servicemto0 -#: model:process.transition,name:mrp.process_transition_stockproduct0 -msgid "Make to Order" -msgstr "Obtener bajo pedido" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.action_report_mrp_production_order -#: model:ir.ui.menu,name:mrp.menu_report_mrp_production_orders_tree -msgid "Production Analysis" -msgstr "Análisis de producción" - -#. module: mrp -#: code:addons/mrp/mrp.py:349 -#, python-format -msgid "Copy" -msgstr "Copiar" - -#. module: mrp -#: view:mrp.production.lot.line:0 -msgid "Production Products" -msgstr "Productos producidos" - -#. module: mrp -#: field:mrp.production,date_finished:0 -#: field:mrp.production.order,date_finished:0 -msgid "End Date" -msgstr "Fecha final" - -#. module: mrp -#: field:mrp.workcenter,resource_id:0 -msgid "Resource" -msgstr "Recurso" - -#. module: mrp -#: help:mrp.bom,date_start:0 -#: help:mrp.bom,date_stop:0 -msgid "Validity of this BoM or component. Keep empty if it's always valid." -msgstr "" -"Validez de esta LdM o componente. Dejarlo vacío si siempre es válido." - -#. module: mrp -#: field:mrp.production,product_uos:0 -msgid "Product UoS" -msgstr "UdV del producto" - -#. module: mrp -#: view:mrp.production.order:0 -msgid "#Line Orders" -msgstr "Nº línea órdenes" - -#. module: mrp -#: selection:mrp.production,priority:0 -#: selection:mrp.production.order,priority:0 -msgid "Very Urgent" -msgstr "Muy urgente" - -#. module: mrp -#: help:mrp.bom,routing_id:0 -msgid "" -"The list of operations (list of work centers) to produce the finished " -"product. The routing is mainly used to compute work center costs during " -"operations and to plan future loads on work centers based on production " -"planning." -msgstr "" -"La lista de operaciones (lista de los centros de trabajo) para producir los " -"productos terminados. La ruta se utiliza principalmente para calcular los " -"costes del centro de trabajo durante las operaciones de carga y planificar " -"el futuro en los centros de trabajo basado en la planificación de la " -"producción." - -#. module: mrp -#: view:change.production.qty:0 -msgid "Approve" -msgstr "Aprobar" - -#. module: mrp -#: view:mrp.property.group:0 -msgid "Properties categories" -msgstr "Categorías de propiedades" - -#. module: mrp -#: help:mrp.production.workcenter.line,sequence:0 -msgid "Gives the sequence order when displaying a list of work orders." -msgstr "" -"Indica el orden de secuencia cuando se muestra una lista de órdenes de " -"trabajo." - -#. module: mrp -#: report:mrp.production.order:0 -msgid "Source Location" -msgstr "Ubicación origen" - -#. module: mrp -#: view:mrp.production:0 -#: view:mrp.production.product.line:0 -msgid "Scheduled Products" -msgstr "Productos planificados" - -#. module: mrp -#: view:mrp.production.lot.line:0 -msgid "Production Products Consommation" -msgstr "Consumición de productos producidos" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.mrp_production_action -#: model:ir.actions.act_window,name:mrp.mrp_production_action_planning -#: model:ir.ui.menu,name:mrp.menu_mrp_production_action -#: model:ir.ui.menu,name:mrp.menu_mrp_production_order_action -#: view:mrp.production:0 -msgid "Manufacturing Orders" -msgstr "Órdenes de producción" - -#. module: mrp -#: help:mrp.product.produce,mode:0 -msgid "" -"'Consume only' mode will only consume the products with the quantity " -"selected.\n" -"'Consume & Produce' mode will consume as well as produce the products with " -"the quantity selected and it will finish the production order when total " -"ordered quantities are produced." -msgstr "" -"El modo 'Sólo consumir' sólo se consumen los productos con la cantidad " -"seleccionada.\n" -"El modo 'Consumo y Producción' se consumen y también se producen los " -"productos con la cantidad seleccionada y finalizará la orden de producción " -"cuando el total de las cantidades solicitadas se han producido." - -#. module: mrp -#: view:mrp.production:0 -#: report:mrp.production.order:0 -msgid "Work Orders" -msgstr "Órdenes de trabajo" - -#. module: mrp -#: field:mrp.workcenter,costs_cycle:0 -msgid "Cost per cycle" -msgstr "Coste por ciclo" - -#. module: mrp -#: model:process.node,name:mrp.process_node_serviceproduct0 -#: model:process.node,name:mrp.process_node_serviceproduct1 -msgid "Service" -msgstr "Servicio" - -#. module: mrp -#: selection:mrp.production,state:0 -#: selection:mrp.production.order,state:0 -msgid "Cancelled" -msgstr "Cancelado" - -#. module: mrp -#: view:mrp.production.order:0 -msgid "BOM" -msgstr "LdM" - -#. module: mrp -#: help:mrp.bom,product_uom:0 -msgid "" -"UoM (Unit of Measure) is the unit of measurement for the inventory control" -msgstr "" -"UdM(Unidad de medida) es la unidad de medida para el control de inventario" - -#. module: mrp -#: model:process.transition,note:mrp.process_transition_bom0 -msgid "" -"The Bill of Material is the product's decomposition. The components (that " -"are products themselves) can also have their own Bill of Material (multi-" -"level)." -msgstr "" -"La lista de materiales es la composición del producto. Los componentes (que " -"son también productos) pueden tener sus propias listas de materiales (multi-" -"nivel)." - -#. module: mrp -#: field:mrp.bom,company_id:0 -#: field:mrp.production,company_id:0 -#: view:mrp.production.order:0 -#: field:mrp.production.order,company_id:0 -#: field:mrp.routing,company_id:0 -#: field:mrp.routing.workcenter,company_id:0 -#: view:mrp.workcenter:0 -msgid "Company" -msgstr "Compañía" - -#. module: mrp -#: field:mrp.workcenter,time_cycle:0 -msgid "Time for 1 cycle (hour)" -msgstr "Tiempo para 1 ciclo (horas)" - -#. module: mrp -#: model:ir.actions.report.xml,name:mrp.report_mrp_production_report -#: field:mrp.production.product.line,production_id:0 -#: field:mrp.production.workcenter.line,production_id:0 -#: model:process.node,name:mrp.process_node_production0 -#: model:process.node,name:mrp.process_node_productionorder0 -msgid "Production Order" -msgstr "Orden de producción" - -#. module: mrp -#: model:process.node,note:mrp.process_node_productminimumstockrule0 -msgid "Automatic procurement rule" -msgstr "Regla de abastecimiento automática" - -#. module: mrp -#: view:mrp.production:0 -msgid "Compute Data" -msgstr "Calcular datos" - -#. module: mrp -#: field:mrp.production,product_uos_qty:0 -msgid "Product UoS Qty" -msgstr "Cant. UdV del producto" - -#. module: mrp -#: code:addons/mrp/report/price.py:130 -#: view:mrp.bom:0 -#, python-format -msgid "Components" -msgstr "Componentes" - -#. module: mrp -#: report:bom.structure:0 -#: model:ir.actions.report.xml,name:mrp.report_bom_structure -msgid "BOM Structure" -msgstr "Despiece de la LdM" - -#. module: mrp -#: field:mrp.bom,date_stop:0 -msgid "Valid Until" -msgstr "Válido hasta" - -#. module: mrp -#: field:mrp.bom,date_start:0 -msgid "Valid From" -msgstr "Válido desde" - -#. module: mrp -#: selection:mrp.bom,type:0 -msgid "Normal BoM" -msgstr "LdM normal" - -#. module: mrp -#: field:res.company,manufacturing_lead:0 -msgid "Manufacturing Lead Time" -msgstr "Tiempo entrega de fabricación" - -#. module: mrp -#: field:mrp.bom,product_uos_qty:0 -#: field:mrp.production.product.line,product_uos_qty:0 -msgid "Product UOS Qty" -msgstr "Ctdad UdV producto" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.action_report_in_out_picking_tree -msgid "" -"Weekly Stock Value Variation enables you to track the stock value evolution " -"linked to manufacturing activities, receptions of products and delivery " -"orders." -msgstr "" -"La variación semanal del valor del stock permite realizar un seguimiento de " -"la evolución del valor del stock relativo a las actividades de fabricacion, " -"recepciónd de productos y ordenes de entrega." - -#. module: mrp -#: view:mrp.product.produce:0 -msgid "Confirm" -msgstr "Confirmar" - -#. module: mrp -#: field:mrp.bom,product_efficiency:0 -msgid "Manufacturing Efficiency" -msgstr "Eficiencia de la producción" - -#. module: mrp -#: constraint:res.company:0 -msgid "Error! You can not create recursive companies." -msgstr "¡Error! No puede crear compañías recursivas." - -#. module: mrp -#: help:mrp.bom,active:0 -msgid "" -"If the active field is set to False, it will allow you to hide the bills of " -"material without removing it." -msgstr "" -"Si el campo activo se desmarca, permite ocultar las listas de material sin " -"eliminarlas." - -#. module: mrp -#: field:mrp.bom,product_rounding:0 -msgid "Product Rounding" -msgstr "Redondeo del producto" - -#. module: mrp -#: model:ir.model,name:mrp.model_mrp_production_workcenter_line -#: field:mrp.production.workcenter.line,name:0 -msgid "Work Order" -msgstr "Orden de trabajo" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.action_report_mrp_production_order -msgid "" -"This reporting allows you to analyse your manufacturing activities and " -"performance." -msgstr "" -"Estos informes le permiten analizar sus actividad productiva y su " -"rendimiento." - -#. module: mrp -#: selection:mrp.product.produce,mode:0 -msgid "Consume Only" -msgstr "Consumir únicamente" - -#. module: mrp -#: view:mrp.production:0 -msgid "Recreate Picking" -msgstr "Volver a crear albarán" - -#. module: mrp -#: help:mrp.bom,type:0 -msgid "" -"If a sub-product is used in several products, it can be useful to create its " -"own BoM. Though if you don't want separated production orders for this sub-" -"product, select Set/Phantom as BoM type. If a Phantom BoM is used for a root " -"product, it will be sold and shipped as a set of components, instead of " -"being produced." -msgstr "" -"Si un sub-producto se utiliza en varios productos, puede ser útil crear su " -"propia lista de materiales. Aunque si no quiere órdenes de producción " -"separadas para este sub-producto, seleccione Conjunto/Fantasma como tipo de " -"LdM. Si una LdM fantasma se utiliza para un producto raíz, será vendida y " -"enviada como un conjunto de componentes, en vez de ser producida." - -#. module: mrp -#: field:mrp.bom,method:0 -msgid "Method" -msgstr "Método" - -#. module: mrp -#: help:mrp.production,state:0 -msgid "" -"When the production order is created the state is set to 'Draft'.\n" -" If the order is confirmed the state is set to 'Waiting Goods'.\n" -" If any exceptions are there, the state is set to 'Picking Exception'. " -" \n" -"If the stock is available then the state is set to 'Ready to Produce'.\n" -" When the production gets started then the state is set to 'In Production'.\n" -" When the production is over, the state is set to 'Done'." -msgstr "" -"Cuando se crea la orden de fabricación su estado es fijado a \"Borrador\"\n" -" Si la orden está confirmdada, el estado es fijado a \"Esperando " -"mercancía\"\n" -" Si existe alguna excepción, el estado es fijado a \"Excepcion de " -"abastecimiento\"\n" -"Si el stock está disponible, el estado es fijado a \"Listo para producir\"\n" -" Cuando la fabricación comienza, el estado es fijado a \"En producción\"\n" -" Cuando la fabricación finaliza, el estado es fijado a \"Realizado\"" - -#. module: mrp -#: selection:mrp.bom,method:0 -msgid "On Order" -msgstr "En orden" - -#. module: mrp -#: model:ir.ui.menu,name:mrp.menu_mrp_configuration -#: view:res.company:0 -msgid "Configuration" -msgstr "Configuración" - -#. module: mrp -#: field:mrp.workcenter,time_stop:0 -msgid "Time after prod." -msgstr "Tiempo después producción" - -#. module: mrp -#: field:mrp.workcenter.load,time_unit:0 -msgid "Type of period" -msgstr "Tipo de período" - -#. module: mrp -#: view:mrp.production:0 -msgid "Total Qty" -msgstr "Ctdad total" - -#. module: mrp -#: field:mrp.routing.workcenter,hour_nbr:0 -msgid "Number of Hours" -msgstr "Número de horas" - -#. module: mrp -#: view:mrp.workcenter:0 -msgid "Costing Information" -msgstr "Información de costes" - -#. module: mrp -#: model:process.node,name:mrp.process_node_purchaseprocure0 -msgid "Procurement Orders" -msgstr "Órdenes de abastecimiento" - -#. module: mrp -#: help:mrp.bom,product_rounding:0 -msgid "Rounding applied on the product quantity." -msgstr "Redondeo aplicado sobre la cantidad de producto" - -#. module: mrp -#: model:process.node,note:mrp.process_node_stock0 -msgid "Assignment from Production or Purchase Order." -msgstr "Asignación desde producción o pedido de compra." - -#. module: mrp -#: field:mrp.routing.workcenter,routing_id:0 -msgid "Parent Routing" -msgstr "Proceso productivo padre" - -#. module: mrp -#: view:mrp.installer:0 -msgid "Configure" -msgstr "Configurar" - -#. module: mrp -#: help:mrp.workcenter,time_start:0 -msgid "Time in hours for the setup." -msgstr "Tiempo en horas para la configuración." - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "December" -msgstr "Diciembre" - -#. module: mrp -#: field:mrp.installer,config_logo:0 -msgid "Image" -msgstr "Imagen" - -#. module: mrp -#: field:mrp.bom.revision,bom_id:0 -#: field:procurement.order,bom_id:0 -msgid "BoM" -msgstr "Lista de materiales (LdM)" - -#. module: mrp -#: model:ir.model,name:mrp.model_report_mrp_inout -#: view:report.mrp.inout:0 -msgid "Stock value variation" -msgstr "Variación del valor del stock" - -#. module: mrp -#: model:process.node,note:mrp.process_node_mts0 -#: model:process.node,note:mrp.process_node_servicemts0 -msgid "Assignment from stock." -msgstr "Asignación desde stock." - -#. module: mrp -#: selection:mrp.production,state:0 -#: view:mrp.production.order:0 -#: selection:mrp.production.order,state:0 -msgid "Waiting Goods" -msgstr "Esperando mercancía" - -#. module: mrp -#: field:mrp.bom.revision,last_indice:0 -msgid "last indice" -msgstr "Último índice" - -#. module: mrp -#: field:mrp.bom,revision_ids:0 -#: view:mrp.bom.revision:0 -msgid "BoM Revisions" -msgstr "Revisiones lista de materiales" - -#. module: mrp -#: selection:mrp.production,state:0 -#: selection:mrp.production.order,state:0 -msgid "Draft" -msgstr "Borrador" - -#. module: mrp -#: field:report.mrp.inout,date:0 -#: field:report.workcenter.load,name:0 -msgid "Week" -msgstr "Semana" - -#. module: mrp -#: field:mrp.installer,progress:0 -msgid "Configuration Progress" -msgstr "Progreso de la configuración" - -#. module: mrp -#: selection:mrp.production,priority:0 -#: selection:mrp.production.order,priority:0 -msgid "Normal" -msgstr "Normal" - -#. module: mrp -#: model:process.node,note:mrp.process_node_routing0 -msgid "Manufacturing Steps." -msgstr "Etapas de producción." - -#. module: mrp -#: code:addons/mrp/report/price.py:136 -#: model:ir.actions.report.xml,name:mrp.report_cost_structure -#, python-format -msgid "Cost Structure" -msgstr "Estructura de costes" - -#. module: mrp -#: selection:mrp.product.produce,mode:0 -msgid "Consume & Produce" -msgstr "Consumir y Producir" - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "November" -msgstr "Noviembre" - -#. module: mrp -#: field:mrp.bom,bom_id:0 -msgid "Parent BoM" -msgstr "Lista de materiales (LdM) padre" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_bom_form_action2 -msgid "" -"Bills of materials components are components and sub-products used to create " -"master bills of materials. Use this menu to search in which BoM a specific " -"component is used." -msgstr "" -"Los componente de listas de materiales son componentes y sub-productos " -"utilizados para crear listas de materiales maestras. Utilice este menú para " -"buscar en qué LdM es utilizado un componente específico." - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "January" -msgstr "Enero" - -#. module: mrp -#: model:process.node,note:mrp.process_node_stockproduct0 -msgid "Product type is Stockable or Consumable." -msgstr "Tipo de producto es almacenable o consumible." - -#. module: mrp -#: code:addons/mrp/mrp.py:595 -#: code:addons/mrp/wizard/change_production_qty.py:77 -#: code:addons/mrp/wizard/change_production_qty.py:82 -#, python-format -msgid "Error" -msgstr "Error" - -#. module: mrp -#: field:mrp.product.produce,product_qty:0 -msgid "Select Quantity" -msgstr "Seleccionar cantidad" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.act_product_product_2_mrp_bom -#: model:ir.actions.act_window,name:mrp.mrp_bom_form_action -#: model:ir.ui.menu,name:mrp.menu_mrp_bom_form_action -#: field:product.product,bom_ids:0 -msgid "Bill of Materials" -msgstr "Lista de materiales (LdM)" #. module: mrp #: help:mrp.routing.workcenter,routing_id:0 @@ -2287,26 +1267,359 @@ msgid "" msgstr "" #. module: mrp -#: model:ir.model,name:mrp.model_mrp_bom_revision -msgid "Bill of Material Revision" -msgstr "Revisión de lista de materiales" +#: code:addons/mrp/mrp.py:505 +#, python-format +msgid "Invalid Action!" +msgstr "" #. module: mrp -#: view:mrp.routing.workcenter:0 -#: view:mrp.workcenter:0 -msgid "General Information" -msgstr "Información general" +#: model:process.transition,note:mrp.process_transition_producttostockrules0 +msgid "" +"The Minimum Stock Rule is an automatic procurement rule based on a mini and " +"maxi quantity. It's available in the Inventory management menu and " +"configured by product." +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:187 +#, python-format +msgid "Components Cost of %s %s" +msgstr "" + +#. module: mrp +#: selection:mrp.workcenter.load,time_unit:0 +msgid "Day by day" +msgstr "" + +#. module: mrp +#: field:mrp.production,priority:0 +msgid "Priority" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_stock_picking +#: field:mrp.production,picking_id:0 +msgid "Picking List" +msgstr "" + +#. module: mrp +#: help:mrp.production,bom_id:0 +msgid "" +"Bill of Materials allow you to define the list of required raw materials to " +"make a finished product." +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:375 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_mrp_production_product_line +msgid "Production Scheduled Product" +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:204 +#, python-format +msgid "Work Cost of %s %s" +msgstr "" + +#. module: mrp +#: help:res.company,manufacturing_lead:0 +msgid "Security days for each manufacturing operation." +msgstr "" + +#. module: mrp +#: model:process.node,name:mrp.process_node_mts0 +#: model:process.transition,name:mrp.process_transition_servicemts0 +#: model:process.transition,name:mrp.process_transition_stockmts0 +msgid "Make to Stock" +msgstr "" + +#. module: mrp +#: constraint:mrp.production:0 +msgid "Order quantity cannot be negative or zero!" +msgstr "" + +#. module: mrp +#: model:process.transition,note:mrp.process_transition_stockrfq0 +msgid "" +"In case the Supply method of the product is Buy, the system creates a " +"purchase order." +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_procurement_order +msgid "Procurement" +msgstr "" + +#. module: mrp +#: field:mrp.config.settings,module_product_manufacturer:0 +msgid "Define manufacturers on products " +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.action_view_mrp_product_price_wizard +#: view:mrp.product_price:0 +msgid "Product Cost Structure" +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:139 +#, python-format +msgid "Components suppliers" +msgstr "" #. module: mrp #: view:mrp.production:0 -msgid "Productions" -msgstr "Producciones" +msgid "Production Work Centers" +msgstr "" #. module: mrp -#: code:addons/mrp/report/price.py:194 +#: view:mrp.workcenter:0 +msgid "Search for mrp workcenter" +msgstr "" + +#. module: mrp +#: view:mrp.bom:0 +msgid "BoM Structure" +msgstr "" + +#. module: mrp +#: field:mrp.production,date_start:0 +msgid "Start Date" +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,costs_hour_account_id:0 +msgid "Hour Account" +msgstr "" + +#. module: mrp +#: field:mrp.bom,product_uom:0 +#: field:mrp.production,product_uom:0 +#: field:mrp.production.product.line,product_uom:0 +msgid "Product Unit of Measure" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Destination Loc." +msgstr "" + +#. module: mrp +#: field:mrp.bom,method:0 +msgid "Method" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Pending" +msgstr "" + +#. module: mrp +#: field:mrp.bom,active:0 +#: field:mrp.routing,active:0 +msgid "Active" +msgstr "" + +#. module: mrp +#: help:mrp.config.settings,group_mrp_routings:0 +msgid "" +"Routings allow you to create and manage the manufacturing operations that " +"should be followed\n" +" within your work centers in order to produce a product. They " +"are attached to bills of materials\n" +" that will define the required raw materials." +msgstr "" + +#. module: mrp +#: view:report.workcenter.load:0 +msgid "Work Center Loads" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.mrp_property_action +#: model:ir.ui.menu,name:mrp.menu_mrp_property_action +#: view:mrp.bom:0 +#: field:mrp.bom,property_ids:0 +#: view:mrp.property:0 +#: field:procurement.order,property_ids:0 +msgid "Properties" +msgstr "" + +#. module: mrp +#: help:mrp.production,origin:0 +msgid "" +"Reference of the document that generated this production order request." +msgstr "" + +#. module: mrp +#: model:process.transition,name:mrp.process_transition_minimumstockprocure0 +msgid "'Minimum stock rule' material" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Extra Information" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_change_production_qty +msgid "Change Quantity of Products" +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_productionorder0 +msgid "Drives the procurement orders for raw material." +msgstr "" + +#. module: mrp +#: field:mrp.production.product.line,product_uos_qty:0 +msgid "Product UOS Quantity" +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,costs_general_account_id:0 +msgid "General Account" +msgstr "" + +#. module: mrp +#: report:mrp.production.order:0 +msgid "SO Number" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:505 #, python-format -msgid "Work Cost of " -msgstr "Coste trabajo de " +msgid "Cannot delete a manufacturing order in state '%s'." +msgstr "" + +#. module: mrp +#: selection:mrp.production,state:0 +msgid "Done" +msgstr "" + +#. module: mrp +#: view:product.product:0 +msgid "When you sell this product, OpenERP will trigger" +msgstr "" + +#. module: mrp +#: field:mrp.production,origin:0 +#: report:mrp.production.order:0 +msgid "Source Document" +msgstr "" + +#. module: mrp +#: selection:mrp.production,priority:0 +msgid "Not urgent" +msgstr "" + +#. module: mrp +#: field:mrp.production,user_id:0 +msgid "Responsible" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.mrp_production_action2 +msgid "Manufacturing Orders To Start" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.mrp_workcenter_action +#: model:ir.model,name:mrp.model_mrp_workcenter +#: model:ir.ui.menu,name:mrp.menu_view_resource_search_mrp +#: field:mrp.production.workcenter.line,workcenter_id:0 +#: field:mrp.routing.workcenter,workcenter_id:0 +#: view:mrp.workcenter:0 +#: field:report.workcenter.load,workcenter_id:0 +msgid "Work Center" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,help:mrp.mrp_property_group_action +msgid "" +"

\n" +" Click to create a group of properties.\n" +"

\n" +" Define specific property groups that can be assigned to " +"your\n" +" bill of materials and sales orders. Properties allows " +"OpenERP\n" +" to automatically select the right bill of materials " +"according\n" +" to properties selected in the sales order by salesperson.\n" +"

\n" +" For instance, in the property group \"Warranty\", you an " +"have\n" +" two properties: 1 year warranty, 3 years warranty. " +"Depending\n" +" on the propoerties selected in the sales order, OpenERP " +"will\n" +" schedule a production using the matching bill of materials.\n" +"

\n" +" " +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,capacity_per_cycle:0 +msgid "Capacity per Cycle" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_product_product +#: view:mrp.bom:0 +#: field:mrp.bom,product_id:0 +#: view:mrp.production:0 +#: field:mrp.production,product_id:0 +#: report:mrp.production.order:0 +#: field:mrp.production.product.line,product_id:0 +msgid "Product" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: field:mrp.production,hour_total:0 +msgid "Total Hours" +msgstr "" + +#. module: mrp +#: field:mrp.production,location_src_id:0 +msgid "Raw Materials Location" +msgstr "" + +#. module: mrp +#: view:mrp.product_price:0 +msgid "Print Cost Structure of Product." +msgstr "" + +#. module: mrp +#: field:mrp.bom,product_uos:0 +#: field:mrp.production.product.line,product_uos:0 +msgid "Product UOS" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Consume Products" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.act_mrp_product_produce +#: view:mrp.product.produce:0 +#: view:mrp.production:0 +msgid "Produce" +msgstr "" + +#. module: mrp +#: model:process.node,name:mrp.process_node_stock0 +#: model:process.transition,name:mrp.process_transition_servicemto0 +#: model:process.transition,name:mrp.process_transition_stockproduct0 +msgid "Make to Order" +msgstr "" #. module: mrp #: help:mrp.workcenter,note:0 @@ -2316,160 +1629,656 @@ msgid "" msgstr "" #. module: mrp -#: model:ir.model,name:mrp.model_mrp_routing -#: view:mrp.bom:0 -#: field:mrp.bom,routing_id:0 -#: view:mrp.production:0 -#: field:mrp.production,routing_id:0 -#: field:mrp.production.order,routing_id:0 -#: view:mrp.routing:0 -#: model:process.node,name:mrp.process_node_routing0 -msgid "Routing" -msgstr "Proceso productivo" - -#. module: mrp -#: field:mrp.installer,mrp_operations:0 -msgid "Manufacturing Operations" -msgstr "Operaciones de producción" - -#. module: mrp -#: field:mrp.production,date_planned:0 -msgid "Scheduled date" -msgstr "Fecha planificada" - -#. module: mrp -#: constraint:stock.move:0 -msgid "You must assign a production lot for this product" -msgstr "Debe asignar un lote de producción para este producto" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.mrp_property_action -msgid "" -"The Properties in OpenERP are used to select the right bill of materials for " -"manufacturing a product when you have different ways of building the same " -"product. You can assign several properties to each Bill of Materials. When a " -"sales person creates a sales order, he can relate it to several properties " -"and OpenERP will automatically select the BoM to use according the the needs." +#: field:mrp.production,date_finished:0 +msgid "End Date" msgstr "" -"Las propiedades en OpenERP se utilizan para seleccionar la correcta lista de " -"materiales para la fabricación de uno de los productos cuando se tienen " -"diferentes formas de fabricar el mismo producto. Puede asignar varias " -"propiedades para cada lista de materiales. Cuando un vendedor crea un pedido " -"de cliente, él puede relacionarlo con varias propiedades y OpenERP " -"seleccionará automáticamente la lista de materiales para utilizar según las " -"necesidades." #. module: mrp -#: view:mrp.production.order:0 +#: field:mrp.workcenter,resource_id:0 +msgid "Resource" +msgstr "" + +#. module: mrp +#: help:mrp.bom,date_start:0 +#: help:mrp.bom,date_stop:0 +msgid "Validity of this BoM or component. Keep empty if it's always valid." +msgstr "" + +#. module: mrp +#: field:mrp.production,product_uos:0 +msgid "Product UoS" +msgstr "" + +#. module: mrp +#: selection:mrp.production,priority:0 +msgid "Very Urgent" +msgstr "" + +#. module: mrp +#: help:mrp.bom,routing_id:0 +msgid "" +"The list of operations (list of work centers) to produce the finished " +"product. The routing is mainly used to compute work center costs during " +"operations and to plan future loads on work centers based on production " +"planning." +msgstr "" + +#. module: mrp +#: view:change.production.qty:0 +msgid "Approve" +msgstr "" + +#. module: mrp +#: view:mrp.config.settings:0 +msgid "Order" +msgstr "" + +#. module: mrp +#: view:mrp.property.group:0 +msgid "Properties categories" +msgstr "" + +#. module: mrp +#: help:mrp.production.workcenter.line,sequence:0 +msgid "Gives the sequence order when displaying a list of work orders." +msgstr "" + +#. module: mrp +#: report:mrp.production.order:0 +msgid "Source Location" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: view:mrp.production.product.line:0 +msgid "Scheduled Products" +msgstr "" + +#. module: mrp +#: model:res.groups,name:mrp.group_mrp_manager +msgid "Manager" +msgstr "" + +#. module: mrp +#: help:mrp.product.produce,mode:0 +msgid "" +"'Consume only' mode will only consume the products with the quantity " +"selected.\n" +"'Consume & Produce' mode will consume as well as produce the products with " +"the quantity selected and it will finish the production order when total " +"ordered quantities are produced." +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +#: report:mrp.production.order:0 +msgid "Work Orders" +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,costs_cycle:0 +msgid "Cost per cycle" +msgstr "" + +#. module: mrp +#: model:process.node,name:mrp.process_node_serviceproduct0 +#: model:process.node,name:mrp.process_node_serviceproduct1 +msgid "Service" +msgstr "" + +#. module: mrp +#: selection:mrp.production,state:0 +msgid "Cancelled" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "(Update)" +msgstr "" + +#. module: mrp +#: help:mrp.config.settings,module_mrp_operations:0 +msgid "" +"This allows to add state, date_start,date_stop in production order operation " +"lines (in the \"Work Centers\" tab).\n" +" This installs the module mrp_operations." +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:737 +#, python-format +msgid "" +"You are going to consume total %s quantities of \"%s\".\n" +"But you can only consume up to total %s quantities." +msgstr "" + +#. module: mrp +#: model:process.transition,note:mrp.process_transition_bom0 +msgid "" +"The Bill of Material is the product's decomposition. The components (that " +"are products themselves) can also have their own Bill of Material (multi-" +"level)." +msgstr "" + +#. module: mrp +#: field:mrp.bom,company_id:0 +#: field:mrp.production,company_id:0 +#: field:mrp.routing,company_id:0 +#: field:mrp.routing.workcenter,company_id:0 +#: view:mrp.workcenter:0 +msgid "Company" +msgstr "" + +#. module: mrp +#: view:mrp.bom:0 +msgid "Default Unit of Measure" +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,time_cycle:0 +msgid "Time for 1 cycle (hour)" +msgstr "" + +#. module: mrp +#: model:ir.actions.report.xml,name:mrp.report_mrp_production_report +#: field:mrp.production.product.line,production_id:0 +#: model:process.node,name:mrp.process_node_production0 +#: model:process.node,name:mrp.process_node_productionorder0 +msgid "Production Order" +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_productminimumstockrule0 +msgid "Automatic procurement rule" +msgstr "" + +#. module: mrp +#: field:mrp.bom,message_ids:0 +#: field:mrp.production,message_ids:0 +#: field:mrp.production.workcenter.line,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Compute Data" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:610 +#: code:addons/mrp/wizard/change_production_qty.py:83 +#: code:addons/mrp/wizard/change_production_qty.py:88 +#, python-format +msgid "Error!" +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:139 +#: view:mrp.bom:0 +#, python-format +msgid "Components" +msgstr "" + +#. module: mrp +#: report:bom.structure:0 +#: model:ir.actions.report.xml,name:mrp.report_bom_structure +msgid "BOM Structure" +msgstr "" + +#. module: mrp +#: field:mrp.config.settings,module_mrp_jit:0 +msgid "Generate procurement in real time" +msgstr "" + +#. module: mrp +#: field:mrp.bom,date_stop:0 +msgid "Valid Until" +msgstr "" + +#. module: mrp +#: field:mrp.bom,date_start:0 +msgid "Valid From" +msgstr "" + +#. module: mrp +#: selection:mrp.bom,type:0 +msgid "Normal BoM" +msgstr "" + +#. module: mrp +#: field:res.company,manufacturing_lead:0 +msgid "Manufacturing Lead Time" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:285 +#, python-format +msgid "Warning" +msgstr "" + +#. module: mrp +#: field:mrp.bom,product_uos_qty:0 +msgid "Product UOS Qty" +msgstr "" + +#. module: mrp +#: field:mrp.production,move_prod_id:0 +msgid "Product Move" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,help:mrp.action_report_in_out_picking_tree +msgid "" +"Weekly Stock Value Variation enables you to track the stock value evolution " +"linked to manufacturing activities, receptions of products and delivery " +"orders." +msgstr "" + +#. module: mrp +#: view:mrp.product.produce:0 +msgid "Confirm" +msgstr "" + +#. module: mrp +#: field:mrp.bom,product_efficiency:0 +msgid "Manufacturing Efficiency" +msgstr "" + +#. module: mrp +#: field:mrp.bom,message_follower_ids:0 +#: field:mrp.production,message_follower_ids:0 +#: field:mrp.production.workcenter.line,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: mrp +#: help:mrp.bom,active:0 +msgid "" +"If the active field is set to False, it will allow you to hide the bills of " +"material without removing it." +msgstr "" + +#. module: mrp +#: field:mrp.bom,product_rounding:0 +msgid "Product Rounding" +msgstr "" + +#. module: mrp +#: selection:mrp.production,state:0 +msgid "New" +msgstr "" + +#. module: mrp +#: selection:mrp.product.produce,mode:0 +msgid "Consume Only" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Recreate Picking" +msgstr "" + +#. module: mrp +#: selection:mrp.bom,method:0 +msgid "On Order" +msgstr "" + +#. module: mrp +#: model:ir.ui.menu,name:mrp.menu_mrp_configuration +msgid "Configuration" +msgstr "" + +#. module: mrp +#: view:mrp.bom:0 +msgid "Starting Date" +msgstr "" + +#. module: mrp +#: field:mrp.workcenter,time_stop:0 +msgid "Time after prod." +msgstr "" + +#. module: mrp +#: field:mrp.workcenter.load,time_unit:0 +msgid "Type of period" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Total Qty" +msgstr "" + +#. module: mrp +#: field:mrp.production.workcenter.line,hour:0 +#: field:mrp.routing.workcenter,hour_nbr:0 +#: field:report.workcenter.load,hour:0 +msgid "Number of Hours" +msgstr "" + +#. module: mrp +#: view:mrp.workcenter:0 +msgid "Costing Information" +msgstr "" + +#. module: mrp +#: model:process.node,name:mrp.process_node_purchaseprocure0 +msgid "Procurement Orders" +msgstr "" + +#. module: mrp +#: help:mrp.bom,product_rounding:0 +msgid "Rounding applied on the product quantity." +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_stock0 +msgid "Assignment from Production or Purchase Order." +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,help:mrp.mrp_bom_form_action +msgid "" +"

\n" +" Click to create a bill of material. \n" +"

\n" +" Bills of Materials allow you to define the list of required " +"raw\n" +" materials used to make a finished product; through a " +"manufacturing\n" +" order or a pack of products.\n" +"

\n" +" OpenERP uses these BoMs to automatically propose " +"manufacturing\n" +" orders according to procurement needs.\n" +"

\n" +" " +msgstr "" + +#. module: mrp +#: field:mrp.routing.workcenter,routing_id:0 +msgid "Parent Routing" +msgstr "" + +#. module: mrp +#: help:mrp.workcenter,time_start:0 +msgid "Time in hours for the setup." +msgstr "" + +#. module: mrp +#: field:mrp.config.settings,module_mrp_repair:0 +msgid "Manage repairs of products " +msgstr "" + +#. module: mrp +#: help:mrp.config.settings,module_mrp_byproduct:0 +msgid "" +"You can configure by-products in the bill of material.\n" +" Without this module: A + B + C -> D.\n" +" With this module: A + B + C -> D + E.\n" +" This installs the module mrp_byproduct." +msgstr "" + +#. module: mrp +#: field:procurement.order,bom_id:0 +msgid "BoM" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_report_mrp_inout +#: view:report.mrp.inout:0 +msgid "Stock value variation" +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_mts0 +#: model:process.node,note:mrp.process_node_servicemts0 +msgid "Assignment from stock." +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:139 +#, python-format +msgid "Cost Price per Unit of Measure" +msgstr "" + +#. module: mrp +#: field:report.mrp.inout,date:0 +#: view:report.workcenter.load:0 +#: field:report.workcenter.load,name:0 +msgid "Week" +msgstr "" + +#. module: mrp +#: selection:mrp.production,priority:0 +msgid "Normal" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Production started late" +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_routing0 +msgid "Manufacturing Steps." +msgstr "" + +#. module: mrp +#: code:addons/mrp/report/price.py:146 +#: model:ir.actions.report.xml,name:mrp.report_cost_structure +#, python-format +msgid "Cost Structure" +msgstr "" + +#. module: mrp +#: model:res.groups,name:mrp.group_mrp_user +msgid "User" +msgstr "" + +#. module: mrp +#: selection:mrp.product.produce,mode:0 +msgid "Consume & Produce" +msgstr "" + +#. module: mrp +#: field:mrp.bom,bom_id:0 +msgid "Parent BoM" +msgstr "" + +#. module: mrp +#: report:bom.structure:0 +msgid "BOM Ref" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:765 +#, python-format +msgid "" +"You are going to produce total %s quantities of \"%s\".\n" +"But you can only produce up to total %s quantities." +msgstr "" + +#. module: mrp +#: model:process.node,note:mrp.process_node_stockproduct0 +msgid "Product type is Stockable or Consumable." +msgstr "" + +#. module: mrp +#: selection:mrp.production,state:0 +msgid "Production Started" +msgstr "" + +#. module: mrp +#: model:process.node,name:mrp.process_node_procureproducts0 +msgid "Procure Products" +msgstr "" + +#. module: mrp +#: field:mrp.product.produce,product_qty:0 +msgid "Select Quantity" +msgstr "" + +#. module: mrp +#: model:ir.actions.act_window,name:mrp.mrp_bom_form_action +#: model:ir.actions.act_window,name:mrp.product_open_bom +#: model:ir.ui.menu,name:mrp.menu_mrp_bom_form_action +#: view:mrp.bom:0 +#: view:product.product:0 +#: field:product.product,bom_ids:0 +msgid "Bill of Materials" +msgstr "" + +#. module: mrp +#: code:addons/mrp/mrp.py:610 +#, python-format +msgid "Cannot find a bill of material for this product." +msgstr "" + +#. module: mrp +#: view:product.product:0 +msgid "" +"using the bill of materials assigned to this product.\n" +" The delivery order will be ready once the production " +"is done." +msgstr "" + +#. module: mrp +#: field:mrp.config.settings,module_stock_no_autopicking:0 +msgid "Manage manual picking to fulfill manufacturing orders " +msgstr "" + +#. module: mrp +#: view:mrp.routing.workcenter:0 +#: view:mrp.workcenter:0 +msgid "General Information" +msgstr "" + +#. module: mrp +#: view:mrp.production:0 +msgid "Productions" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_stock_move_split +#: view:mrp.production:0 +msgid "Split in Serial Numbers" +msgstr "" + +#. module: mrp +#: help:mrp.bom,product_uos:0 +msgid "" +"Product UOS (Unit of Sale) is the unit of measurement for the invoicing and " +"promotion of stock." +msgstr "" + +#. module: mrp +#: view:mrp.production:0 #: field:stock.move,production_id:0 msgid "Production" -msgstr "Producción" +msgstr "" + +#. module: mrp +#: model:ir.model,name:mrp.model_mrp_production_workcenter_line +#: field:mrp.production.workcenter.line,name:0 +msgid "Work Order" +msgstr "" #. module: mrp #: view:board.board:0 msgid "Procurements in Exception" -msgstr "Abastecimientos en excepción" - -#. module: mrp -#: model:process.transition,name:mrp.process_transition_minimumstockprocure0 -msgid "'Minimum stock rule' material" -msgstr "material 'regla stock mínimo'" +msgstr "" #. module: mrp #: model:ir.model,name:mrp.model_mrp_product_price msgid "Product Price" -msgstr "Precio del producto" - -#. module: mrp -#: model:ir.actions.act_window,name:mrp.action_mrp_installer -msgid "MRP Applications Configuration" -msgstr "Configuración de las aplicaciónes MRP" - -#. module: mrp -#: model:ir.model,name:mrp.model_stock_move_split -msgid "Split in Production lots" -msgstr "Dividir en lotes de producción" +msgstr "" #. module: mrp #: view:change.production.qty:0 msgid "Change Quantity" -msgstr "Cambiar cantidad" +msgstr "" #. module: mrp #: view:change.production.qty:0 #: model:ir.actions.act_window,name:mrp.action_change_production_qty msgid "Change Product Qty" -msgstr "Cambiar Ctd. producto" +msgstr "" #. module: mrp -#: view:mrp.bom.revision:0 -#: field:mrp.bom.revision,description:0 -#: view:mrp.property:0 -#: view:mrp.property.group:0 #: field:mrp.routing,note:0 -#: view:mrp.routing.workcenter:0 #: field:mrp.routing.workcenter,note:0 -#: view:mrp.workcenter:0 #: field:mrp.workcenter,note:0 msgid "Description" -msgstr "Descripción" - -#. module: mrp -#: selection:mrp.production.order,month:0 -msgid "May" -msgstr "Mayo" +msgstr "" #. module: mrp #: view:board.board:0 msgid "Manufacturing board" -msgstr "Tablero fabricación" - -#. module: mrp -#: field:mrp.production,date_planned_end:0 -msgid "Scheduled End Date" -msgstr "Fecha de fin planificada" - -#. module: mrp -#: model:ir.actions.act_window,help:mrp.action_report_workcenter_load_tree -msgid "" -"Work Center Loads gives you a projection of work center loads over a " -"specified period. It is expressed in number of hours and machine related " -"cycles." msgstr "" -"Las cargas de los centros de producción muestran un pronóstico de la carga " -"de los centros de producción respecto a un periodo determinado. Está " -"expresado en número de horas y ciclos de máquina relacionados." + +#. module: mrp +#: code:addons/mrp/wizard/change_production_qty.py:68 +#, python-format +msgid "Active Id not found" +msgstr "" #. module: mrp #: model:process.node,note:mrp.process_node_procureproducts0 msgid "The way to procurement depends on the product type." -msgstr "La forma de abastecer depende del tipo de producto." +msgstr "" #. module: mrp +#: model:ir.actions.act_window,name:mrp.open_board_manufacturing +#: model:ir.ui.menu,name:mrp.menu_board_manufacturing #: model:ir.ui.menu,name:mrp.menu_mrp_manufacturing +#: model:ir.ui.menu,name:mrp.next_id_77 msgid "Manufacturing" -msgstr "Fabricación" +msgstr "" #. module: mrp -#: view:board.board:0 -msgid "Next Production Orders" -msgstr "Próximas órdenes de producción" +#: help:mrp.bom,type:0 +msgid "" +"If a by-product is used in several products, it can be useful to create its " +"own BoM. Though if you don't want separated production orders for this by-" +"product, select Set/Phantom as BoM type. If a Phantom BoM is used for a root " +"product, it will be sold and shipped as a set of components, instead of " +"being produced." +msgstr "" #. module: mrp -#: selection:mrp.production.order,month:0 -msgid "February" -msgstr "Febrero" +#: model:ir.actions.act_window,name:mrp.action_mrp_configuration +#: view:mrp.config.settings:0 +msgid "Configure Manufacturing" +msgstr "" + +#. module: mrp +#: view:product.product:0 +msgid "" +"a manufacturing\n" +" order" +msgstr "" + +#. module: mrp +#: field:mrp.config.settings,group_mrp_properties:0 +msgid "Allow several bill of materials per products using properties" +msgstr "" #. module: mrp #: model:ir.actions.act_window,name:mrp.mrp_property_group_action #: model:ir.ui.menu,name:mrp.menu_mrp_property_group_action msgid "Property Groups" -msgstr "Grupos de propiedades" +msgstr "" #. module: mrp -#: selection:mrp.production.order,month:0 -msgid "April" -msgstr "Abril" +#: model:ir.model,name:mrp.model_mrp_routing +#: view:mrp.bom:0 +#: field:mrp.bom,routing_id:0 +#: view:mrp.production:0 +#: field:mrp.production,routing_id:0 +#: view:mrp.routing:0 +#: model:process.node,name:mrp.process_node_routing0 +msgid "Routing" +msgstr "" #. module: mrp #: model:process.transition,note:mrp.process_transition_procurestockableproduct0 @@ -2477,19 +2286,23 @@ msgid "" "Depending on the chosen method to supply the stockable products, the " "procurement order creates a RFQ, a production order, ... " msgstr "" -"Dependiendo del método elegido para suministrar los productos almacenables, " -"la orden de abastecimiento crea una petición de presupuesto, una orden de " -"producción, ... " #. module: mrp #: help:mrp.workcenter,time_stop:0 msgid "Time in hours for the cleaning." -msgstr "Tiempo en horas para la limpieza." +msgstr "" + +#. module: mrp +#: field:mrp.bom,message_summary:0 +#: field:mrp.production,message_summary:0 +#: field:mrp.production.workcenter.line,message_summary:0 +msgid "Summary" +msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_purchaseprocure0 msgid "Automatic RFQ" -msgstr "Petición de presupuesto automática" +msgstr "" #. module: mrp #: model:process.transition,note:mrp.process_transition_servicemto0 @@ -2497,8 +2310,6 @@ msgid "" "If the service has a 'Produce' supply method, this creates a task in the " "project management module of OpenERP." msgstr "" -"Si el servicio tiene un método de suministro 'Producir', se crea una tarea " -"en el módulo de gestión de proyectos de OpenERP." #. module: mrp #: model:process.transition,note:mrp.process_transition_productionprocureproducts0 @@ -2507,10 +2318,6 @@ msgid "" "production order creates as much procurement orders as components listed in " "the BOM, through a run of the schedulers (MRP)." msgstr "" -"Para poder suministrar materias primas (que deben ser compradas o " -"producidas), la orden de producción genera tantas órdenes de abastecimiento " -"como componentes figuren en la lista de materiales, a través de una " -"ejecución de las planificaciones (MRP)." #. module: mrp #: help:mrp.product_price,number:0 @@ -2518,13 +2325,11 @@ msgid "" "Specify quantity of products to produce or buy. Report of Cost structure " "will be displayed base on this quantity." msgstr "" -"Indique la cantidad de productos a producir o comprar. El informe de la " -"estructura de costes se muestra basándose en esta cantidad." #. module: mrp #: selection:mrp.bom,method:0 msgid "On Stock" -msgstr "En stock" +msgstr "" #. module: mrp #: field:mrp.bom,sequence:0 @@ -2532,897 +2337,26 @@ msgstr "En stock" #: field:mrp.production.workcenter.line,sequence:0 #: field:mrp.routing.workcenter,sequence:0 msgid "Sequence" -msgstr "Secuencia" +msgstr "" #. module: mrp #: model:ir.ui.menu,name:mrp.menu_view_resource_calendar_leaves_search_mrp msgid "Resource Leaves" -msgstr "Ausencias recursos" +msgstr "" #. module: mrp #: help:mrp.bom,sequence:0 msgid "Gives the sequence order when displaying a list of bills of material." msgstr "" -"Indica el orden de secuencia cuando se muestra una lista de listas de " -"materiales." + +#. module: mrp +#: model:ir.model,name:mrp.model_mrp_config_settings +msgid "mrp.config.settings" +msgstr "" #. module: mrp #: view:mrp.production:0 #: field:mrp.production,move_lines:0 #: report:mrp.production.order:0 -#: field:mrp.production.order,products_to_consume:0 msgid "Products to Consume" -msgstr "Productos a consumir" - -#. module: mrp -#: view:mrp.production.order:0 -#: field:mrp.production.order,year:0 -msgid "Year" -msgstr "Año" - -#~ msgid "-" -#~ msgstr "-" - -#~ msgid "" -#~ "Triggers an automatic procurement for all products that have a virtual stock " -#~ "under 0. You should probably not use this option, we suggest using a MTO " -#~ "configuration on products." -#~ msgstr "" -#~ "Dispara un abastecimiento automático para todos los productos que tienen un " -#~ "stock virtual menor que 0. Probablemente no debería utilizar esta opción, " -#~ "sugerimos utilizar una configuración de MTO en productos." - -#~ msgid "Compute Stock Minimum Rules Only" -#~ msgstr "Calcular sólo reglas de stock mínimo" - -#~ msgid "Exceptions Procurements" -#~ msgstr "Excepciones de abastecimientos" - -#~ msgid "UoS Quantity" -#~ msgstr "Cantidad UdV" - -#~ msgid "Routing Workcenters" -#~ msgstr "Procesos productivos de los centros de producción" - -#~ msgid "Not used in computations, for information purpose only." -#~ msgstr "No utilizado en cálculos, sólo con la finalidad de informar." - -#~ msgid "Packing list" -#~ msgstr "Albarán" - -#~ msgid "Stockable Stock" -#~ msgstr "Stock productos almacenables" - -#~ msgid "Origin" -#~ msgstr "Origen" - -#~ msgid "Automatic orderpoint" -#~ msgstr "Generación de orden automática" - -#, python-format -#~ msgid "No supplier defined for this product !" -#~ msgstr "¡No se ha definido un proveedor para este producto!" - -#, python-format -#~ msgid "Product name" -#~ msgstr "Nombre producto" - -#~ msgid "Invalid XML for View Architecture!" -#~ msgstr "¡XML inválido para la definición de la vista!" - -#~ msgid "" -#~ "This is the days added to what you promise to customers for security purpose" -#~ msgstr "" -#~ "Éstos son los días añadidos a los que promete a los clientes por razones de " -#~ "seguridad" - -#~ msgid "Best price (not yet active!)" -#~ msgstr "Mejor precio (aún no activo!)" - -#~ msgid "Product & Location" -#~ msgstr "Producto & Ubicación" - -#~ msgid "MRP & Logistic Scheduler" -#~ msgstr "Planificador MRP & Logística" - -#~ msgid "" -#~ "Number of operation this workcenter can do in parallel. If this workcenter " -#~ "represent a team of 5 workers, the capacity per cycle is 5." -#~ msgstr "" -#~ "Número de operaciones que este centro de producción puede realizar en " -#~ "paralelo. Si este centro de producción tuviera un equipo de 5 trabajadores, " -#~ "la capacidad por ciclo sería de 5." - -#~ msgid "Ask New Products" -#~ msgstr "Solicitar nuevos productos" - -#~ msgid "Automatic Procurements" -#~ msgstr "Abastecimientos automáticos" - -#~ msgid "Products Consummed" -#~ msgstr "Productos consumidos" - -#~ msgid "Packing Exception" -#~ msgstr "Excepción de empaquetado" - -#~ msgid "A purchase order is created for a sub-contracting demand." -#~ msgstr "Una orden de compra es creada para sub-contratar la demanda." - -#~ msgid "Analytic Accounting" -#~ msgstr "Contabilidad analítica" - -#~ msgid "Do nothing" -#~ msgstr "No hacer nada" - -#, python-format -#~ msgid "products" -#~ msgstr "productos" - -#~ msgid "If the stock of a product is under 0, it will act like an orderpoint" -#~ msgstr "Si el stock de un producto es menor que 0, actuará como una orden" - -#~ msgid "you can see the minimum stock rules from product" -#~ msgstr "puede ver las reglas de stock mínimo desde producto" - -#~ msgid "This wizard will schedule procurements." -#~ msgstr "Este asistente planificará abastecimientos." - -#~ msgid "Internal Ref." -#~ msgstr "Ref. interna" - -#~ msgid "Status" -#~ msgstr "Estado" - -#~ msgid "Stockable Production Order" -#~ msgstr "Orden producción almacenable" - -#~ msgid "Stockable Request" -#~ msgstr "Solicitud almacenable" - -#, python-format -#~ msgid "Workcenter name" -#~ msgstr "Nombre centro de producción" - -#~ msgid "Service on Order" -#~ msgstr "Servicio sobre orden" - -#~ msgid "" -#~ "When the virtual stock goes belong the Min Quantity, Open ERP generates a " -#~ "procurement to bring the virtual stock to the Max Quantity." -#~ msgstr "" -#~ "Cuando el stock virtual disminuye por debajo de la cantidad mínima, OpenERP " -#~ "genera un abastecimiento para que el stock virtual sea la cantidad máxima." - -#~ msgid "Stockable Make to Stock" -#~ msgstr "Almacenable obtenido para stock" - -#~ msgid "Production Orders" -#~ msgstr "Órdenes de producción" - -#~ msgid "Procure Service Product" -#~ msgstr "Abastecer producto servicio" - -#, python-format -#~ msgid "Product Quantity" -#~ msgstr "Cantidad producto" - -#~ msgid "Procurements" -#~ msgstr "Abastecimientos" - -#~ msgid "Production scheduled products" -#~ msgstr "Producción planificada de productos" - -#~ msgid "Details" -#~ msgstr "Detalles" - -#~ msgid "Procurement Process" -#~ msgstr "Proceso de abastecimiento" - -#, python-format -#~ msgid "Product Standard Price" -#~ msgstr "Precio estándar producto" - -#~ msgid "" -#~ "Rounding applied on the product quantity. For integer only values, put 1.0" -#~ msgstr "" -#~ "Redondeo aplicado a la cantidad de producto. Para valores siempre enteros " -#~ "introduzca 1.0" - -#~ msgid "Reservation" -#~ msgstr "Reserva" - -#~ msgid "product" -#~ msgstr "producto" - -#~ msgid "max" -#~ msgstr "máx" - -#~ msgid "Product to stock rules" -#~ msgstr "Producto a reglas de stock" - -#, python-format -#~ msgid "from stock: products assigned." -#~ msgstr "desde stock: productos asignados." - -#~ msgid "Print product price" -#~ msgstr "Imprimir coste del producto" - -#~ msgid "Make Procurement" -#~ msgstr "Realizar abastecimiento" - -#~ msgid "If Procure method is Make to order and supply method is produce" -#~ msgstr "" -#~ "si método de abastecimiento es obtener bajo pedido y método de suministro es " -#~ "producir" - -#~ msgid "Purchase Lead Time" -#~ msgstr "Plazo de tiempo de compra" - -#~ msgid "Stockable Product Stock" -#~ msgstr "Stock de producto almacenable" - -#~ msgid "Production Procure Products" -#~ msgstr "Productos para abastecer la producción" - -#~ msgid "Service Product Process" -#~ msgstr "Proceso producto de servicios" - -#~ msgid "Procurement convert into the draft purchase order." -#~ msgstr "Abastecimiento se convierte en la orden de compra borrador." - -#~ msgid "Latest error" -#~ msgstr "Último error" - -#, python-format -#~ msgid "from stock and no minimum orderpoint rule defined" -#~ msgstr "desde stock y no se ha definido regla mínima generación orden" - -#~ msgid "Routing workcenter usage" -#~ msgstr "Procesos productivos del centro de producción" - -#~ msgid "If Product type is Stockable and procure method is make to stock" -#~ msgstr "" -#~ "Si el tipo de producto es almacenable y el método de abastecimiento es " -#~ "obtener para stock" - -#~ msgid "Manufacturity Lead Time" -#~ msgstr "Plazo de entrega de fabricación" - -#~ msgid "Exceptions Procurements to Fix" -#~ msgstr "Excepciones de abastecimientos a corregir" - -#~ msgid "Workcenter Operations" -#~ msgstr "Operaciones del centro de producción" - -#~ msgid "Production Orders Planning" -#~ msgstr "Planificación órdenes de producción" - -#~ msgid "Factor that multiplies all times expressed in the workcenter." -#~ msgstr "" -#~ "Factor que multiplica todos los tiempos expresados en el centro de " -#~ "producción." - -#~ msgid "" -#~ "This is the Internal Picking List take bring the raw materials to the " -#~ "production plan." -#~ msgstr "" -#~ "Ésta es la lista de empaquetado interna que lleva las materias primas a la " -#~ "producción planificada." - -#~ msgid "Qty Multiple" -#~ msgstr "Ctdad múltiple" - -#~ msgid "Waiting" -#~ msgstr "En espera" - -#~ msgid "For stockable and consumable" -#~ msgstr "Para almacenables y consumibles" - -#~ msgid "indice type" -#~ msgstr "Tipo de índice" - -#, python-format -#~ msgid "Hours Cost" -#~ msgstr "Coste horas" - -#~ msgid "Production orders are created for the product manufacturing." -#~ msgstr "Se crean órdenes de producción para la fabricación del producto." - -#~ msgid "Min Quantity" -#~ msgstr "Cantidad mín" - -#~ msgid "Production orders" -#~ msgstr "Órdenes de producción" - -#~ msgid "BoM Hyerarchy" -#~ msgstr "Jerarquía LdM" - -#~ msgid "Procurement Lines" -#~ msgstr "Líneas de abastecimiento" - -#~ msgid "If Product type is service and procure method is Make to stock" -#~ msgstr "" -#~ "si el tipo de producto es servicio y el método de abastecimiento es obtener " -#~ "para stock" - -#~ msgid "If Product type is service" -#~ msgstr "Si el tipo de producto es servicio" - -#, python-format -#~ msgid "SUBTOTAL" -#~ msgstr "SUBTOTAL" - -#~ msgid "Security Days" -#~ msgstr "Días de seguridad" - -#~ msgid "Exception" -#~ msgstr "Excepción" - -#~ msgid "" -#~ "This wizard will planify the procurement for this product. This procurement " -#~ "may generate task, production orders or purchase orders." -#~ msgstr "" -#~ "Este asistente planificará el abastecimiento para este producto. El " -#~ "abastecimiento puede generar tareas, órdenes de producción o órdenes de " -#~ "compra." - -#~ msgid "The system waits for requested products in stock." -#~ msgstr "El sistema espera los productos solicitados en stock." - -#~ msgid "Serivce Stockable Order" -#~ msgstr "Orden servicio almacenable" - -#~ msgid "From minimum stock rules, it goes for procure product." -#~ msgstr "Desde reglas de stock mínimo, va a abastecer el producto." - -#~ msgid "Production done" -#~ msgstr "Producción realizada" - -#, python-format -#~ msgid "Unit Product Price" -#~ msgstr "Precio producto unidad" - -#~ msgid "References" -#~ msgstr "Referencias" - -#~ msgid "Machine" -#~ msgstr "Fabricación" - -#~ msgid "Workcenter Name" -#~ msgstr "Nombre centro de producción" - -#~ msgid "min" -#~ msgstr "mín" - -#~ msgid "" -#~ "Description of the workcenter. Explain here what's a cycle according to this " -#~ "workcenter." -#~ msgstr "" -#~ "Descripción del centro de producción. Describa aquí que es un ciclo según " -#~ "este centro de producción." - -#~ msgid "Human Resource" -#~ msgstr "Recurso humano" - -#~ msgid "Workcenters" -#~ msgstr "Centros de producción" - -#~ msgid "on order" -#~ msgstr "bajo pedido" - -#~ msgid "Compute All Schedulers" -#~ msgstr "Calcular todas las planificaciones" - -#~ msgid "Create Procurement" -#~ msgstr "Crear abastecimiento" - -#, python-format -#~ msgid "Product uom" -#~ msgstr "UdM producto" - -#~ msgid "Number of Cycle" -#~ msgstr "Número de ciclos" - -#~ msgid "Run procurement" -#~ msgstr "Ejecutar abastecimiento" - -#~ msgid "" -#~ "This is the time frame analysed by the scheduler when computing " -#~ "procurements. All procurement that are not between today and today+range are " -#~ "skipped for futur computation." -#~ msgstr "" -#~ "Éste es el intervalo temporal analizado por el planificador al calcular " -#~ "abastecimientos. Todos los abastecimientos que no estén entre hoy y " -#~ "hoy+intervalo son omitidos para el cálculos futuros." - -#~ msgid "Time Efficiency" -#~ msgstr "Eficiencia temporal" - -#~ msgid "Scheduler Parameters" -#~ msgstr "Parámetros del planificador" - -#~ msgid "A cycle is defined in the workcenter definition." -#~ msgstr "En la definición de un centro de producción se define un ciclo." - -#~ msgid "Unit of Measure" -#~ msgstr "Unidad de medida" - -#~ msgid "Procurement Method" -#~ msgstr "Método abastecimiento" - -#~ msgid "Compute Procurements" -#~ msgstr "Calcular abastecimientos" - -#~ msgid "Wait for available products for reservation" -#~ msgstr "Esperar productos disponibles para reservarlos" - -#~ msgid "Validate" -#~ msgstr "Validar" - -#~ msgid "Procurement Purchase" -#~ msgstr "Compra de abastecimiento" - -#~ msgid "Number of products to produce" -#~ msgstr "Número de productos a producir" - -#~ msgid "Material routing" -#~ msgstr "Procesos productivos del material" - -#~ msgid "Minimum stock rule" -#~ msgstr "Regla de stock mínimo" - -#~ msgid "Product Efficiency" -#~ msgstr "Eficiencia del producto" - -#~ msgid "Orderpoint minimum rule" -#~ msgstr "Regla mínima generación orden" - -#~ msgid "Service Make to Stock" -#~ msgstr "Servicio obtener para stock" - -#~ msgid "Sale Ref" -#~ msgstr "Ref. venta" - -#~ msgid "Location" -#~ msgstr "Ubicación" - -#~ msgid "New Procurement" -#~ msgstr "Nuevo abastecimiento" - -#~ msgid "Tool" -#~ msgstr "Maquinaria" - -#~ msgid "" -#~ "Location where the system will look for products used in raw materials." -#~ msgstr "" -#~ "Ubicación donde el sistema buscará productos utilizados en las materias " -#~ "primas." - -#~ msgid "Planned Date" -#~ msgstr "Fecha prevista" - -#~ msgid "Procurement orders" -#~ msgstr "Órdenes de abastecimiento" - -#~ msgid "If product type is service and procure method is Make to order" -#~ msgstr "" -#~ "si el tipo de producto es servicio y el método de abastecimiento es obtener " -#~ "bajo pedido" - -#~ msgid "Scheduler Range" -#~ msgstr "Margen planificador" - -#~ msgid "Max Quantity" -#~ msgstr "Cantidad máx" - -#~ msgid "Minimum Stock Procure" -#~ msgstr "Abastecer stock mínimo" - -#~ msgid "This is the leads/security time for each purchase order." -#~ msgstr "Éste es el plazo/seguridad de tiempo para cada orden de compra." - -#~ msgid "alphabetical indices" -#~ msgstr "índices alfabéticos" - -#~ msgid "Procurement for raw materials." -#~ msgstr "Abastecimiento para materia primas." - -#~ msgid "Note" -#~ msgstr "Nota" - -#~ msgid "Procure Stockable Product" -#~ msgstr "Abastecimiento producto almacenable" - -#~ msgid "Paid ?" -#~ msgstr "¿Pagado?" - -#~ msgid "Define a routing to describe the manufacturing steps." -#~ msgstr "" -#~ "Definir un proceso productivo para describir los pasos de fabricación" - -#~ msgid "Define the product structure, with sub-products and/or components." -#~ msgstr "" -#~ "Definir la estructura del producto, con subproductos y/o componentes." - -#~ msgid "" -#~ "Procurement is created if the product quantity is lower than the minimum " -#~ "limit." -#~ msgstr "" -#~ "Se crea el abastecimiento si la cantidad de producto es menor que el límite " -#~ "mínimo." - -#~ msgid "Date Closed" -#~ msgstr "Fecha de cierre" - -#~ msgid "Properties composition" -#~ msgstr "Composición de propiedades" - -#~ msgid "Production Orders Waiting Products" -#~ msgstr "Órdenes de producción esperando productos" - -#~ msgid "Change Product Qty." -#~ msgstr "Cambiar Ctd. producto" - -#~ msgid "The procurement quantity will by rounded up to this multiple." -#~ msgstr "La cantidad abastecida será redondeada hacia arriba a este múltiplo." - -#~ msgid "Reordering Mode" -#~ msgstr "Modo de pedir de nuevo" - -#~ msgid "" -#~ "The Object name must start with x_ and not contain any special character !" -#~ msgstr "" -#~ "¡El nombre del objeto debe empezar con x_ y no contener ningún carácter " -#~ "especial!" - -#~ msgid "Central document to procure products" -#~ msgstr "Documento central para abastecer productos" - -#~ msgid "Production Orders in Progress" -#~ msgstr "Órdenes de producción en proceso" - -#~ msgid "Minimum Stock Rules" -#~ msgstr "Reglas de stock mínimo" - -#~ msgid "" -#~ "Reference of the document that created this procurement.\n" -#~ "This is automatically completed by Open ERP." -#~ msgstr "" -#~ "Referencia del documento que ha creado este abastecimiento.\n" -#~ "Éste es completado automáticamente por OpenERP." - -#~ msgid "Product type is Stockable and procure method is make to stock" -#~ msgstr "" -#~ "Tipo de producto es almacenable y método de abastecimiento es obtener para " -#~ "stock" - -#~ msgid "Product UoM" -#~ msgstr "UdM del producto" - -#~ msgid "Workcenter" -#~ msgstr "Centro de producción" - -#~ msgid "Purchase Order" -#~ msgstr "Orden de compra" - -#~ msgid "" -#~ "If you encode manually a procurement, you probably want to use a make to " -#~ "order method." -#~ msgstr "" -#~ "Si codifica manualmente un abastecimiento, probablemente desea usar un " -#~ "método obtener bajo pedido." - -#~ msgid "Stockable Order Request" -#~ msgstr "Solicitud orden almacenable" - -#~ msgid "numeric indices" -#~ msgstr "índices numéricos" - -#~ msgid "If Procure method is Make to order and supply method is buy" -#~ msgstr "" -#~ "si método de abastecimiento es obtener bajo pedido y método de suministro es " -#~ "comprar" - -#~ msgid "if Product type is Stockable in procurement order" -#~ msgstr "si el tipo de producto es almacenable en orden de abastecimiento" - -#~ msgid "Bill of material revisions" -#~ msgstr "Revisiones lista de material" - -#~ msgid "Planification" -#~ msgstr "Planificación" - -#~ msgid "" -#~ "Use a phantom bill of material in raw materials lines that have to be " -#~ "automatically computed in on eproduction order and not one per level.If you " -#~ "put \"Phantom/Set\" at the root level of a bill of material it is considered " -#~ "as a set or pack: the products are replaced by the components between the " -#~ "sale order to the picking without going through the production order.The " -#~ "normal BoM will generate one production order per BoM level." -#~ msgstr "" -#~ "Utilice una lista de materiales fantasma en líneas de materias primas que se " -#~ "deban calcular automáticamente en una orden de producción y no una por " -#~ "nivel. Si indica \"Fantasma/Conjunto\" en el nivel raíz de una lista de " -#~ "materiales es considerada como un conjunto o paquete: Los productos se " -#~ "reemplazan por los componentes entre el pedido de venta y el empaquetado sin " -#~ "generar la orden de producción. La LdM normal generará una orden de " -#~ "producción por nivel de LdM." - -#, python-format -#~ msgid "No address defined for the supplier" -#~ msgstr "No se ha definido dirección para el proveedor" - -#~ msgid "Your procurement request has been sent !" -#~ msgstr "¡Su petición de abastecimiento ha sido enviada!" - -#~ msgid "Internal Procurement Request" -#~ msgstr "Solicitud de abastecimiento interna" - -#~ msgid "Property Categories" -#~ msgstr "Categorías de propiedades" - -#~ msgid "Compute Procurements Only" -#~ msgstr "Calcular sólo abastecimientos" - -#~ msgid "Temporary Procurement Exceptions" -#~ msgstr "Excepciones de abastecimiento temporales" - -#~ msgid "Confirmed" -#~ msgstr "Confirmada" - -#~ msgid "Parameters" -#~ msgstr "Parámetros" - -#~ msgid "Production workcenters used" -#~ msgstr "Centros de producción utilizados" - -#~ msgid "Workcenters Utilisation" -#~ msgstr "Utilización del centro de producción" - -#~ msgid "" -#~ "Efficiency on the production. A factor of 0.9 means a loss of 10% in the " -#~ "production." -#~ msgstr "" -#~ "Eficiencia en la producción. Un factor de 0.9 significa una pérdida del 10% " -#~ "en la producción." - -#~ msgid "If procurement is make to order" -#~ msgstr "si abastecimiento es obtener bajo pedido" - -#~ msgid "Minimum Stock Rule" -#~ msgstr "Regla de stock mínimo" - -#~ msgid "New Bill of Materials" -#~ msgstr "Nueva lista de materiales" - -#, python-format -#~ msgid "Product quantity" -#~ msgstr "Cantidad producto" - -#~ msgid "Property" -#~ msgstr "Propiedad" - -#~ msgid "Canceled" -#~ msgstr "Cancelado" - -#~ msgid "plus" -#~ msgstr "más" - -#~ msgid "Stockable Product Process" -#~ msgstr "Proceso producto almacenable" - -#~ msgid "New Production Order" -#~ msgstr "Nueva orden de producción" - -#~ msgid "A Request for Quotation is created and sent to the supplier." -#~ msgstr "Una solicitud de presupuesto es creada y enviada al proveedor." - -#~ msgid "Retry" -#~ msgstr "Volver a intentar" - -#~ msgid "When any procuere products, it comes into the prpcurement orders" -#~ msgstr "" -#~ "Cuando alguien abastece productos, se convierte en las órdenes de " -#~ "abastecimiento" - -#~ msgid "Production Orders To Start" -#~ msgstr "Órdenes de producción a iniciar" - -#~ msgid "Procurement Reason" -#~ msgstr "Motivo del abastecimiento" - -#~ msgid "An entry is being made from billing material to routing." -#~ msgstr "Se crea una entrada desde material facturable a proceso productivo." - -#~ msgid "The normal working time of the workcenter." -#~ msgstr "El horario de trabajo normal del centro de producción." - -#~ msgid "Order to Max" -#~ msgstr "Ordenar el máximo" - -#~ msgid "In procurement order, if product type is service" -#~ msgstr "En orden de abastecimiento, si tipo de producto es servicio" - -#~ msgid "from stock" -#~ msgstr "desde stock" - -#~ msgid "Close" -#~ msgstr "Cerrar" - -#, python-format -#~ msgid "TOTAL" -#~ msgstr "TOTAL" - -#~ msgid "Sale Name" -#~ msgstr "Nombre venta" - -#, python-format -#~ msgid "Product supplier" -#~ msgstr "Proveedor producto" - -#~ msgid "Create minimum stock rules" -#~ msgstr "Crear reglas de stock mínimo" - -#~ msgid "Warehouse" -#~ msgstr "Almacén" - -#~ msgid "Service Product" -#~ msgstr "Producto servicio" - -#~ msgid "Close Move at end" -#~ msgstr "Movimiento de cierre al final" - -#~ msgid "Running" -#~ msgstr "En proceso" - -#~ msgid "Unscheduled procurements" -#~ msgstr "Abastecimientos no planificados" - -#~ msgid "Bill of Material Structure" -#~ msgstr "Despiece de la lista de materiales" - -#~ msgid "Workcenter load" -#~ msgstr "Carga del centro de producción" - -#~ msgid "Procurement Details" -#~ msgstr "Detalles de abastecimiento" - -#~ msgid "You can see its bill of material which are used to make product" -#~ msgstr "" -#~ "Puede ver su lista de material que se utiliza para fabricar el producto" - -#~ msgid "Bill of Materials Components" -#~ msgstr "Componentes de la lista de materiales" - -#, python-format -#~ msgid "Warning !" -#~ msgstr "¡Aviso!" - -#, python-format -#~ msgid "" -#~ "The production is in \"%s\" state. You can not change the production " -#~ "quantity anymore" -#~ msgstr "" -#~ "La producción está en estado \"%s\". Ya no puede cambiar la cantidad a " -#~ "producir." - -#~ msgid "Production Workcenters" -#~ msgstr "Centros de producción" - -#~ msgid "Invalid model name in the action definition." -#~ msgstr "Nombre de modelo no válido en la definición de acción." - -#~ msgid "" -#~ "The list of operations (list of workcenters) to produce the finished " -#~ "product. The routing is mainly used to compute workcenter costs during " -#~ "operations and to plan futur loads on workcenters based on production " -#~ "plannification." -#~ msgstr "" -#~ "La lista de operaciones (lista de centros de producción) para producir el " -#~ "producto terminado. La ruta se utiliza principalmente para calcular los " -#~ "costes de los centros de producción durante la fabricación y para prever " -#~ "futuras cargas de los centros de producción a partir de la planificación de " -#~ "la producción." - -#~ msgid "Workcenter Usage" -#~ msgstr "Uso centro de producción" - -#~ msgid "" -#~ "Routing indicates all the workcenters used, for how long and/or cycles.If " -#~ "Routing is indicated then,the third tab of a production order (workcenters) " -#~ "will be automatically pre-completed." -#~ msgstr "" -#~ "La ruta indica todos los centros de producción utilizados, por cuánto tiempo " -#~ "y/o ciclos. Si se indica la ruta, entonces la tercera pestaña de una orden " -#~ "de producción (centros de producción) será automáticamente pre-completada." - -#~ msgid "" -#~ "Number of operations this work center can do in parallel. If this work " -#~ "center represents a team of 5 workers, the capacity per cycle is 5." -#~ msgstr "" -#~ "El número de operaciones de este centro de trabajo se puede hacer en " -#~ "paralelo. Si este centro de trabajo representa un equipo del 5 trabajadores, " -#~ "la capacidad por ciclo es de 5." - -#~ msgid "" -#~ "Description of the work center. Explain here what's a cycle according to " -#~ "this work center." -#~ msgstr "" -#~ "Descripción del centro de trabajo. Explique aquí lo que es un ciclo de " -#~ "acuerdo con este centro de trabajo." - -#~ msgid "Specify Cost of Work center per cycle." -#~ msgstr "Especificar costes del centro de trabajo por ciclo." - -#~ msgid "" -#~ "\n" -#~ " This is the base module to manage the manufacturing process in OpenERP.\n" -#~ "\n" -#~ " Features:\n" -#~ " * Make to Stock / Make to Order (by line)\n" -#~ " * Multi-level BoMs, no limit\n" -#~ " * Multi-level routing, no limit\n" -#~ " * Routing and work center integrated with analytic accounting\n" -#~ " * Scheduler computation periodically / Just In Time module\n" -#~ " * Multi-pos, multi-warehouse\n" -#~ " * Different reordering policies\n" -#~ " * Cost method by product: standard price, average price\n" -#~ " * Easy analysis of troubles or needs\n" -#~ " * Very flexible\n" -#~ " * Allows to browse Bill of Materials in complete structure\n" -#~ " that include child and phantom BoMs\n" -#~ " It supports complete integration and planification of stockable goods,\n" -#~ " consumable of services. Services are completely integrated with the " -#~ "rest\n" -#~ " of the software. For instance, you can set up a sub-contracting service\n" -#~ " in a BoM to automatically purchase on order the assembly of your " -#~ "production.\n" -#~ "\n" -#~ " Reports provided by this module:\n" -#~ " * Bill of Material structure and components\n" -#~ " * Load forecast on workcenters\n" -#~ " * Print a production order\n" -#~ " * Stock forecasts\n" -#~ " Dashboard provided by this module::\n" -#~ " * List of next production orders\n" -#~ " * List of deliveries (out picking)\n" -#~ " * Graph of work center load\n" -#~ " * List of procurement in exception\n" -#~ " " -#~ msgstr "" -#~ "\n" -#~ " Este es el módulo base para gestionar los procesos de fabricación en " -#~ "OpenERP.\n" -#~ "\n" -#~ " Características:\n" -#~ " *Obtener para stock / Obtener bajo pedido (por línea)\n" -#~ " *BoMs multi-niveles, sin límite\n" -#~ " *Ubicaciones multi-nivel, sin límite\n" -#~ " *Ubicaciones y centros de trabajo integrados con la contabilidad " -#~ "analítica\n" -#~ " *Ejecución periódica del cálculo de la planificación / Módulo 'Just In " -#~ "Time'\n" -#~ " *Multi-pv, multi-almacén\n" -#~ " *Diferentes políticas de pedido\n" -#~ " *Método de coste por producto: precio estándar, precio medio\n" -#~ " *Fácil análisis de problemas o necesidades\n" -#~ " *Muy flexible\n" -#~ " *Permite inspeccionar la estructura completa de Facturas de Materiales\n" -#~ " que incluyen BoMs hijas y fantasmas\n" -#~ " Soporta integración y planificación de mercancías almacenables,\n" -#~ " y consumo de servicios. Los servicios se integran completamente con el " -#~ "resto\n" -#~ " de la aplicación. Por ejemplo, se puede establecer una servicio de " -#~ "subcontratación\n" -#~ " en una BoM para encargar automáticamente el montaje de su producción.\n" -#~ "\n" -#~ " Los informes que facilita este módulo:\n" -#~ " *Componentes y estructura de la BoMs\n" -#~ " *Previsión de carga de los centros de trabajo\n" -#~ " *Previsión de almacén\n" -#~ " Tableros proporcionados en este módulo:\n" -#~ " *Lista de órdenes de producción próximas\n" -#~ " *Lista de entregas\n" -#~ " *Gráfico de carga del centro de trabajo\n" -#~ " *Lista de órdenes de fabricación con excepciones\n" -#~ " " +msgstr "" diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 58fcacaa1f5..7fb40ce12af 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -70,7 +70,6 @@ class mrp_workcenter(osv.osv): value = {'costs_hour': cost.standard_price} return {'value': value} -mrp_workcenter() class mrp_routing(osv.osv): @@ -98,7 +97,6 @@ class mrp_routing(osv.osv): 'active': lambda *a: 1, 'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.routing', context=context) } -mrp_routing() class mrp_routing_workcenter(osv.osv): """ @@ -124,7 +122,6 @@ class mrp_routing_workcenter(osv.osv): 'cycle_nbr': lambda *a: 1.0, 'hour_nbr': lambda *a: 0.0, } -mrp_routing_workcenter() class mrp_bom(osv.osv): """ diff --git a/addons/mrp/procurement.py b/addons/mrp/procurement.py index 1f94f0034ad..3ad7155dad6 100644 --- a/addons/mrp/procurement.py +++ b/addons/mrp/procurement.py @@ -122,6 +122,5 @@ class procurement_order(osv.osv): body = _("Manufacturing Order %s created.") % ( procurement.production_id.name,) self.message_post(cr, uid, [procurement.id], body=body, context=context) -procurement_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/product.py b/addons/mrp/product.py index f5e29a1d103..d7a19c718fa 100644 --- a/addons/mrp/product.py +++ b/addons/mrp/product.py @@ -37,6 +37,5 @@ class product_product(osv.osv): return super(product_product, self).copy(cr, uid, id, default, context=context) -product_product() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/report/bom_structure.py b/addons/mrp/report/bom_structure.py index ae26bc4f8cd..b153ea2e4e9 100644 --- a/addons/mrp/report/bom_structure.py +++ b/addons/mrp/report/bom_structure.py @@ -21,8 +21,6 @@ import time from openerp.report import report_sxw -from openerp.osv import osv -from openerp import pooler class bom_structure(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/mrp/report/mrp_report.py b/addons/mrp/report/mrp_report.py index 7dff886a4ba..76474ccb6ab 100644 --- a/addons/mrp/report/mrp_report.py +++ b/addons/mrp/report/mrp_report.py @@ -52,7 +52,6 @@ class report_workcenter_load(osv.osv): to_char(p.date_planned,'YYYY:mm:dd') )""") -report_workcenter_load() class report_mrp_inout(osv.osv): @@ -97,7 +96,6 @@ class report_mrp_inout(osv.osv): to_char(sm.date,'YYYY:IW') )""") -report_mrp_inout() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/report/price.py b/addons/mrp/report/price.py index 2e37011e2bc..5afd6b3ee49 100644 --- a/addons/mrp/report/price.py +++ b/addons/mrp/report/price.py @@ -20,7 +20,8 @@ ############################################################################## import time -from openerp import pooler + +import openerp from openerp.report.interface import report_rml from openerp.tools import to_xml from openerp.report import report_sxw @@ -30,14 +31,14 @@ from openerp.tools.translate import _ class report_custom(report_rml): def create_xml(self, cr, uid, ids, datas, context=None): number = (datas.get('form', False) and datas['form']['number']) or 1 - pool = pooler.get_pool(cr.dbname) - product_pool = pool.get('product.product') - product_uom_pool = pool.get('product.uom') - supplier_info_pool = pool.get('product.supplierinfo') - workcenter_pool = pool.get('mrp.workcenter') - user_pool = pool.get('res.users') - bom_pool = pool.get('mrp.bom') - pricelist_pool = pool.get('product.pricelist') + registry = openerp.registry(cr.dbname) + product_pool = registry.get('product.product') + product_uom_pool = registry.get('product.uom') + supplier_info_pool = registry.get('product.supplierinfo') + workcenter_pool = registry.get('mrp.workcenter') + user_pool = registry.get('res.users') + bom_pool = registry.get('mrp.bom') + pricelist_pool = registry.get('product.pricelist') rml_obj=report_sxw.rml_parse(cr, uid, product_pool._name,context) rml_obj.localcontext.update({'lang':context.get('lang',False)}) company_currency = user_pool.browse(cr, uid, uid).company_id.currency_id diff --git a/addons/mrp/res_config.py b/addons/mrp/res_config.py index c780576099c..22a14addcd1 100644 --- a/addons/mrp/res_config.py +++ b/addons/mrp/res_config.py @@ -20,7 +20,6 @@ ############################################################################## from openerp.osv import fields, osv -from openerp import pooler from openerp.tools.translate import _ class mrp_config_settings(osv.osv_memory): diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index 1ff121c78bd..0ebc7bd199d 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -45,7 +45,7 @@ class StockMove(osv.osv): procurement_obj = self.pool.get('procurement.order') product_obj = self.pool.get('product.product') processed_ids = [move.id] - if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order': + if move.product_id.supply_method == 'produce': bis = bom_obj.search(cr, uid, [ ('product_id','=',move.product_id.id), ('bom_id','=',False), @@ -145,7 +145,6 @@ class StockMove(osv.osv): res.append(new_move) return res -StockMove() class StockPicking(osv.osv): @@ -162,7 +161,6 @@ class StockPicking(osv.osv): todo.extend(move_obj._action_explode(cr, uid, move)) return list(set(todo)) -StockPicking() class split_in_production_lot(osv.osv_memory): @@ -179,6 +177,5 @@ class split_in_production_lot(osv.osv_memory): production_obj.write(cr, uid, production_ids, {'move_lines': [(4, m) for m in new_moves]}) return new_moves -split_in_production_lot() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/test/order_process.yml b/addons/mrp/test/order_process.yml index 89331d5c255..acbfea48182 100644 --- a/addons/mrp/test/order_process.yml +++ b/addons/mrp/test/order_process.yml @@ -215,9 +215,10 @@ - !python {model: mrp.production}: | import os - from openerp import netsvc, tools + import openerp.report + from openerp import tools order = self.browse(cr, uid, ref("mrp_production_test1")) - (data, format) = netsvc.LocalService('report.bom.structure').create(cr, uid, [order.bom_id.id], {}, {}) + data, format = openerp.report.render_report(cr, uid, [order.bom_id.id], 'bom.structure', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'mrp-bom_structure_report.'+format), 'wb+').write(data) - @@ -225,8 +226,9 @@ - !python {model: mrp.production}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.mrp.production.order').create(cr, uid, [ref("mrp_production_test1")], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref("mrp_production_test1")], 'mrp.production.order', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'mrp-production_order_report.'+format), 'wb+').write(data) - diff --git a/addons/mrp/wizard/change_production_qty.py b/addons/mrp/wizard/change_production_qty.py index 74309b50825..41b6022a178 100644 --- a/addons/mrp/wizard/change_production_qty.py +++ b/addons/mrp/wizard/change_production_qty.py @@ -101,6 +101,5 @@ class change_production_qty(osv.osv_memory): self._update_product_to_produce(cr, uid, prod, wiz_qty.product_qty, context=context) return {} -change_production_qty() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/wizard/mrp_price.py b/addons/mrp/wizard/mrp_price.py index 08506ccf0e2..70b4482b019 100644 --- a/addons/mrp/wizard/mrp_price.py +++ b/addons/mrp/wizard/mrp_price.py @@ -52,6 +52,5 @@ class mrp_price(osv.osv_memory): 'datas' : datas, } -mrp_price() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/wizard/mrp_product_produce.py b/addons/mrp/wizard/mrp_product_produce.py index 3a3c5961d1e..0851657587c 100644 --- a/addons/mrp/wizard/mrp_product_produce.py +++ b/addons/mrp/wizard/mrp_product_produce.py @@ -67,6 +67,5 @@ class mrp_product_produce(osv.osv_memory): data.product_qty, data.mode, context=context) return {} -mrp_product_produce() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/wizard/mrp_workcenter_load.py b/addons/mrp/wizard/mrp_workcenter_load.py index 265c6ddcea0..79905673a6b 100644 --- a/addons/mrp/wizard/mrp_workcenter_load.py +++ b/addons/mrp/wizard/mrp_workcenter_load.py @@ -51,6 +51,5 @@ class mrp_workcenter_load(osv.osv_memory): 'datas' : datas, } -mrp_workcenter_load() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_byproduct/mrp_byproduct.py b/addons/mrp_byproduct/mrp_byproduct.py index 22bbface59d..2425c2d8fea 100644 --- a/addons/mrp_byproduct/mrp_byproduct.py +++ b/addons/mrp_byproduct/mrp_byproduct.py @@ -64,7 +64,6 @@ class mrp_subproduct(osv.osv): res['value'].update({'product_uom': product.uom_id.id}) return res -mrp_subproduct() class mrp_bom(osv.osv): _name = 'mrp.bom' @@ -75,7 +74,6 @@ class mrp_bom(osv.osv): 'sub_products':fields.one2many('mrp.subproduct', 'bom_id', 'Byproducts'), } -mrp_bom() class mrp_production(osv.osv): _description = 'Production' @@ -143,7 +141,6 @@ class mrp_production(osv.osv): return subproduct_factor return super(mrp_production, self)._get_subproduct_factor(cr, uid, production_id, move_id, context=context) -mrp_production() class change_production_qty(osv.osv_memory): _inherit = 'change.production.qty' diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index cce27d3a6c2..d6f026530dc 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -21,7 +21,6 @@ from openerp.osv import fields from openerp.osv import osv -from openerp import netsvc import time from datetime import datetime from openerp.tools.translate import _ @@ -47,7 +46,6 @@ class stock_move(osv.osv): }) return super(stock_move, self).copy(cr, uid, id, default, context) -stock_move() class mrp_production_workcenter_line(osv.osv): @@ -372,7 +370,6 @@ class mrp_production(osv.osv): self._compute_planned_workcenter(cr, uid, ids, context=context) return result -mrp_production() class mrp_operations_operation_code(osv.osv): _name="mrp_operations.operation.code" @@ -381,7 +378,6 @@ class mrp_operations_operation_code(osv.osv): 'code': fields.char('Code', size=16, required=True), 'start_stop': fields.selection([('start','Start'),('pause','Pause'),('resume','Resume'),('cancel','Cancelled'),('done','Done')], 'Status', required=True), } -mrp_operations_operation_code() class mrp_operations_operation(osv.osv): _name="mrp_operations.operation" @@ -561,6 +557,5 @@ class mrp_operations_operation(osv.osv): 'date_start': lambda *a:datetime.now().strftime('%Y-%m-%d %H:%M:%S') } -mrp_operations_operation() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_operations/report/mrp_code_barcode.py b/addons/mrp_operations/report/mrp_code_barcode.py index ee9b7a64a40..ea2ba7165b4 100644 --- a/addons/mrp_operations/report/mrp_code_barcode.py +++ b/addons/mrp_operations/report/mrp_code_barcode.py @@ -19,7 +19,6 @@ # ############################################################################## -from openerp import pooler import time from openerp.report import report_sxw diff --git a/addons/mrp_operations/report/mrp_wc_barcode.py b/addons/mrp_operations/report/mrp_wc_barcode.py index 746ed6d71c7..ee1bbe64cd4 100644 --- a/addons/mrp_operations/report/mrp_wc_barcode.py +++ b/addons/mrp_operations/report/mrp_wc_barcode.py @@ -19,7 +19,6 @@ # ############################################################################## -from openerp import pooler import time from openerp.report import report_sxw diff --git a/addons/mrp_operations/report/mrp_workorder_analysis.py b/addons/mrp_operations/report/mrp_workorder_analysis.py index 73982b09f8b..f91961ad74c 100644 --- a/addons/mrp_operations/report/mrp_workorder_analysis.py +++ b/addons/mrp_operations/report/mrp_workorder_analysis.py @@ -71,6 +71,5 @@ class mrp_workorder(osv.osv): w.costs_hour, mp.product_id, mp.name, wl.state, wl.date_planned, wl.production_id, wl.workcenter_id )""") -mrp_workorder() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_repair/i18n/lv.po b/addons/mrp_repair/i18n/lv.po new file mode 100644 index 00000000000..2e4e1148cf5 --- /dev/null +++ b/addons/mrp_repair/i18n/lv.po @@ -0,0 +1,819 @@ +# Latvian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-03-24 11:43+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Latvian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-25 04:38+0000\n" +"X-Generator: Launchpad (build 16540)\n" + +#. module: mrp_repair +#: field:mrp.repair.line,move_id:0 +msgid "Inventory Move" +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Group By..." +msgstr "Grupēt pēc..." + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Recreate Invoice" +msgstr "Pārveidot rēķinu" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:371 +#, python-format +msgid "You have to select a Partner Invoice Address in the repair form !" +msgstr "Labojumu formā Jums ir jānorāda partnera rēķina adrese!" + +#. module: mrp_repair +#: model:ir.actions.act_window,name:mrp_repair.action_cancel_repair +#: view:mrp.repair.cancel:0 +msgid "Cancel Repair Order" +msgstr "Atcelt labojumu orderi" + +#. module: mrp_repair +#: field:mrp.repair.fee,to_invoice:0 +#: field:mrp.repair.line,to_invoice:0 +msgid "To Invoice" +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Unit of Measure" +msgstr "Mērvienība" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Printing Date" +msgstr "Drukāšanas datums" + +#. module: mrp_repair +#: field:mrp.repair.make_invoice,group:0 +msgid "Group by partner invoice address" +msgstr "Grupēt pēc partnera rēķina adreses" + +#. module: mrp_repair +#: field:mrp.repair,message_unread:0 +msgid "Unread Messages" +msgstr "Neizlasītie ziņojumi" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:435 +#, python-format +msgid "No product defined on Fees!" +msgstr "Maksājumam nav nodefinēts produkts!" + +#. module: mrp_repair +#: view:mrp.repair:0 +#: field:mrp.repair,company_id:0 +msgid "Company" +msgstr "Uzņēmums" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Set to Draft" +msgstr "Atzīmēt kā melnrakstu" + +#. module: mrp_repair +#: selection:mrp.repair,state:0 +msgid "Invoice Exception" +msgstr "Rēķina izņēmums" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Serial Number" +msgstr "Sērijas numurs" + +#. module: mrp_repair +#: field:mrp.repair,address_id:0 +msgid "Delivery Address" +msgstr "Piegādes adrese" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "History" +msgstr "Vēsture" + +#. module: mrp_repair +#: field:mrp.repair.fee,price_subtotal:0 +#: field:mrp.repair.line,price_subtotal:0 +msgid "Subtotal" +msgstr "Kopā" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Invoice address :" +msgstr "Rēķina adrese:" + +#. module: mrp_repair +#: help:mrp.repair,partner_id:0 +msgid "Choose partner for whom the order will be invoiced and delivered." +msgstr "" +"Izvēlieties partneri kuram pēc ordera tiks izveidots rēķins un piegādāts." + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Guarantee limit" +msgstr "Garantijas limits" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Notes" +msgstr "Piezīmes" + +#. module: mrp_repair +#: field:mrp.repair,message_ids:0 +msgid "Messages" +msgstr "Ziņojumi" + +#. module: mrp_repair +#: field:mrp.repair,amount_tax:0 +#: field:mrp.repair.fee,tax_id:0 +#: field:mrp.repair.line,tax_id:0 +msgid "Taxes" +msgstr "Nodokļi" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:385 +#: code:addons/mrp_repair/mrp_repair.py:413 +#: code:addons/mrp_repair/mrp_repair.py:442 +#, python-format +msgid "Error!" +msgstr "Kļūda!" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Net Total :" +msgstr "Neto kopā:" + +#. module: mrp_repair +#: selection:mrp.repair,state:0 +#: selection:mrp.repair.line,state:0 +msgid "Cancelled" +msgstr "Atcelts" + +#. module: mrp_repair +#: help:mrp.repair,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Operations" +msgstr "Operācijas" + +#. module: mrp_repair +#: model:ir.actions.act_window,help:mrp_repair.action_repair_order_tree +msgid "" +"

\n" +" Click to create a reparation order. \n" +"

\n" +" In a repair order, you can detail the components you " +"remove,\n" +" add or replace and record the time you spent on the " +"different\n" +" operations.\n" +"

\n" +" The repair order uses the warranty date on the Serial Number " +"in\n" +" order to know if whether the repair should be invoiced to " +"the\n" +" customer or not.\n" +"

\n" +" " +msgstr "" + +#. module: mrp_repair +#: help:mrp.repair.line,state:0 +msgid "" +" * The 'Draft' status is set automatically as draft when repair order in " +"draft status. \n" +"* The 'Confirmed' status is set automatically as confirm when repair order " +"in confirm status. \n" +"* The 'Done' status is set automatically when repair order is completed. " +" \n" +"* The 'Cancelled' status is set automatically when user cancel repair order." +msgstr "" + +#. module: mrp_repair +#: field:mrp.repair,move_id:0 +msgid "Move" +msgstr "Kustība" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Tax" +msgstr "Nodoklis" + +#. module: mrp_repair +#: model:ir.actions.act_window,name:mrp_repair.action_repair_order_tree +#: model:ir.ui.menu,name:mrp_repair.menu_repair_order +msgid "Repair Orders" +msgstr "Labojumu orderi" + +#. module: mrp_repair +#: model:ir.actions.report.xml,name:mrp_repair.report_mrp_repair +msgid "Quotation / Order" +msgstr "Piedāvājums / Orderis" + +#. module: mrp_repair +#: help:mrp.repair,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Extra Info" +msgstr "Papildus informācija" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:336 +#: code:addons/mrp_repair/mrp_repair.py:349 +#: code:addons/mrp_repair/mrp_repair.py:435 +#: code:addons/mrp_repair/wizard/cancel_repair.py:49 +#, python-format +msgid "Warning!" +msgstr "Brīdinājums!" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "(update)" +msgstr "(atjaunināt)" + +#. module: mrp_repair +#: view:mrp.repair:0 +#: field:mrp.repair,partner_id:0 +msgid "Partner" +msgstr "Partneris" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:385 +#, python-format +msgid "No account defined for partner \"%s\"." +msgstr "Nav nodefinēt konts partnerim \"%s\"." + +#. module: mrp_repair +#: view:mrp.repair:0 +#: selection:mrp.repair,state:0 +#: selection:mrp.repair.line,state:0 +msgid "Confirmed" +msgstr "Apstiprināts" + +#. module: mrp_repair +#: help:mrp.repair,state:0 +msgid "" +" * The 'Draft' status is used when a user is encoding a new and unconfirmed " +"repair order. \n" +"* The 'Confirmed' status is used when a user confirms the repair order. " +" \n" +"* The 'Ready to Repair' status is used to start to repairing, user can start " +"repairing only after repair order is confirmed. \n" +"* The 'To be Invoiced' status is used to generate the invoice before or " +"after repairing done. \n" +"* The 'Done' status is set when repairing is completed. \n" +"* The 'Cancelled' status is used when user cancel repair order." +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Repairs order" +msgstr "Labojumu orderis" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:336 +#, python-format +msgid "Serial number is required for operation line with product '%s'" +msgstr "Sērijas numurs ir obligāts operācijas rindai ar produktu '%s'" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Repair Order N° :" +msgstr "Labojumu orderis Nr. :" + +#. module: mrp_repair +#: field:mrp.repair,prodlot_id:0 +#: field:mrp.repair.line,prodlot_id:0 +#: report:repair.order:0 +msgid "Lot Number" +msgstr "Partijas numurs" + +#. module: mrp_repair +#: field:mrp.repair,message_follower_ids:0 +msgid "Followers" +msgstr "Sekotāji" + +#. module: mrp_repair +#: field:mrp.repair,fees_lines:0 +msgid "Fees Lines" +msgstr "" + +#. module: mrp_repair +#: field:mrp.repair.line,type:0 +msgid "Type" +msgstr "Veids" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Fees Line(s)" +msgstr "Maksājumu rinda(s)" + +#. module: mrp_repair +#: selection:mrp.repair,state:0 +msgid "To be Invoiced" +msgstr "Tiks izrakstīts rēķins" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Shipping address :" +msgstr "Piegādes adrese:" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Total :" +msgstr "Kopā:" + +#. module: mrp_repair +#: view:mrp.repair.cancel:0 +msgid "" +"This operation will cancel the Repair process, but will not cancel it's " +"Invoice. Do you want to continue?" +msgstr "" +"Šī darbība atcels labojumu procesu, bet neatcels tā rēķinu. Vai vēlaties " +"turpināt?" + +#. module: mrp_repair +#: field:mrp.repair,pricelist_id:0 +msgid "Pricelist" +msgstr "Cenrādis" + +#. module: mrp_repair +#: field:mrp.repair,quotation_notes:0 +msgid "Quotation Notes" +msgstr "Piedāvājuma piezīmes" + +#. module: mrp_repair +#: view:mrp.repair:0 +#: field:mrp.repair,state:0 +#: field:mrp.repair.line,state:0 +msgid "Status" +msgstr "Statuss" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Search Reair Orders" +msgstr "Meklēt labojumu orderus" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "(Add)" +msgstr "(Pievienot)" + +#. module: mrp_repair +#: model:ir.model,name:mrp_repair.model_mrp_repair_line +#: view:mrp.repair:0 +msgid "Repair Line" +msgstr "Labojumu rinda" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "N° :" +msgstr "Nr. :" + +#. module: mrp_repair +#: field:mrp.repair,invoice_method:0 +msgid "Invoice Method" +msgstr "Rēķina metode" + +#. module: mrp_repair +#: field:mrp.repair,repaired:0 +#: selection:mrp.repair,state:0 +msgid "Repaired" +msgstr "Izlabots" + +#. module: mrp_repair +#: field:mrp.repair.fee,invoice_line_id:0 +#: field:mrp.repair.line,invoice_line_id:0 +msgid "Invoice Line" +msgstr "Rēķina rinda" + +#. module: mrp_repair +#: selection:mrp.repair,invoice_method:0 +msgid "Before Repair" +msgstr "Pirms labojumiem" + +#. module: mrp_repair +#: field:mrp.repair,location_id:0 +msgid "Current Location" +msgstr "Pašreizējā atrašanās vieta" + +#. module: mrp_repair +#: view:mrp.repair.cancel:0 +msgid "Yes" +msgstr "Jā" + +#. module: mrp_repair +#: view:mrp.repair.cancel:0 +#: view:mrp.repair.make_invoice:0 +msgid "or" +msgstr "vai" + +#. module: mrp_repair +#: view:mrp.repair:0 +#: field:mrp.repair,invoiced:0 +#: field:mrp.repair.fee,invoiced:0 +#: field:mrp.repair.line,invoiced:0 +msgid "Invoiced" +msgstr "Rēķins izrakstīts" + +#. module: mrp_repair +#: field:mrp.repair.fee,product_uom:0 +#: field:mrp.repair.line,product_uom:0 +msgid "Product Unit of Measure" +msgstr "Produkta mērvienība" + +#. module: mrp_repair +#: view:mrp.repair.make_invoice:0 +msgid "Create invoices" +msgstr "Izveidot rēķinus" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "(Remove)" +msgstr "(Noņemt)" + +#. module: mrp_repair +#: selection:mrp.repair.line,type:0 +msgid "Add" +msgstr "Pievienot" + +#. module: mrp_repair +#: selection:mrp.repair.line,state:0 +msgid "Draft" +msgstr "Melnraksts" + +#. module: mrp_repair +#: field:mrp.repair,name:0 +msgid "Repair Reference" +msgstr "Labojuma atsauce" + +#. module: mrp_repair +#: model:ir.model,name:mrp_repair.model_mrp_repair +#: view:mrp.repair:0 +msgid "Repair Order" +msgstr "Labojumu orderis" + +#. module: mrp_repair +#: selection:mrp.repair,state:0 +msgid "Under Repair" +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Ready To Repair" +msgstr "Gatavs labojumiem" + +#. module: mrp_repair +#: field:mrp.repair,amount_untaxed:0 +msgid "Untaxed Amount" +msgstr "Summa bez nodokļa" + +#. module: mrp_repair +#: help:mrp.repair,invoice_method:0 +msgid "" +"Selecting 'Before Repair' or 'After Repair' will allow you to generate " +"invoice before or after the repair is done respectively. 'No invoice' means " +"you don't want to generate invoice for this repair order." +msgstr "" + +#. module: mrp_repair +#: field:mrp.repair,guarantee_limit:0 +msgid "Warranty Expiration" +msgstr "Garantijas termiņš" + +#. module: mrp_repair +#: help:mrp.repair,pricelist_id:0 +msgid "Pricelist of the selected partner." +msgstr "Atzīmētā partnera cenrādis." + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Guarantee Limit" +msgstr "Garantijas limits" + +#. module: mrp_repair +#: field:mrp.repair,default_address_id:0 +msgid "unknown" +msgstr "nezināms" + +#. module: mrp_repair +#: field:mrp.repair,product_id:0 +#: report:repair.order:0 +msgid "Product to Repair" +msgstr "Produkts labojumam" + +#. module: mrp_repair +#: selection:mrp.repair,invoice_method:0 +msgid "After Repair" +msgstr "Pēc labojuma" + +#. module: mrp_repair +#: code:addons/mrp_repair/wizard/cancel_repair.py:41 +#, python-format +msgid "Active ID not Found" +msgstr "Aktīvs ID nav atrasts" + +#. module: mrp_repair +#: field:mrp.repair,message_is_follower:0 +msgid "Is a Follower" +msgstr "Ir sekotājs" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Date" +msgstr "Datums" + +#. module: mrp_repair +#: model:ir.model,name:mrp_repair.model_mrp_repair_fee +msgid "Repair Fees Line" +msgstr "Labojuma maksājumu rinda" + +#. module: mrp_repair +#: selection:mrp.repair,state:0 +msgid "Quotation" +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Confirm Repair" +msgstr "Apstiprināt labojumu" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Repair Quotation" +msgstr "Labojuma piedāvājums" + +#. module: mrp_repair +#: field:mrp.repair,message_summary:0 +msgid "Summary" +msgstr "Kopsavilkums" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "End Repair" +msgstr "Beigt labojumu" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:413 +#: code:addons/mrp_repair/mrp_repair.py:442 +#, python-format +msgid "No account defined for product \"%s\"." +msgstr "Produktam \"%s\" nav nodefinēts konts." + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Quotations" +msgstr "Piedāvājumi" + +#. module: mrp_repair +#: view:mrp.repair:0 +#: field:mrp.repair.fee,product_uom_qty:0 +#: field:mrp.repair.line,product_uom_qty:0 +#: report:repair.order:0 +msgid "Quantity" +msgstr "Daudzums" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Product Information" +msgstr "Produkta informācija" + +#. module: mrp_repair +#: model:ir.actions.act_window,name:mrp_repair.act_mrp_repair_invoice +#: model:ir.model,name:mrp_repair.model_mrp_repair_make_invoice +#: view:mrp.repair:0 +msgid "Make Invoice" +msgstr "Veidot rēķinu" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Start Repair" +msgstr "Sākt labojumu" + +#. module: mrp_repair +#: field:mrp.repair.fee,price_unit:0 +#: field:mrp.repair.line,price_unit:0 +#: report:repair.order:0 +msgid "Unit Price" +msgstr "Vienības cena" + +#. module: mrp_repair +#: selection:mrp.repair.line,state:0 +msgid "Done" +msgstr "Pabeigts" + +#. module: mrp_repair +#: field:mrp.repair,invoice_id:0 +msgid "Invoice" +msgstr "Rēķins" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Fees" +msgstr "Maksājumi" + +#. module: mrp_repair +#: view:mrp.repair.cancel:0 +#: view:mrp.repair.make_invoice:0 +msgid "Cancel" +msgstr "Atcelt" + +#. module: mrp_repair +#: field:mrp.repair.line,location_dest_id:0 +msgid "Dest. Location" +msgstr "Piegādes vieta" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Operation Line(s)" +msgstr "Operācijas rinda(s)" + +#. module: mrp_repair +#: field:mrp.repair,location_dest_id:0 +msgid "Delivery Location" +msgstr "Piegādes vieta" + +#. module: mrp_repair +#: help:mrp.repair,deliver_bool:0 +msgid "" +"Check this box if you want to manage the delivery once the product is " +"repaired and create a picking with selected product. Note that you can " +"select the locations in the Info tab, if you have the extended view." +msgstr "" + +#. module: mrp_repair +#: help:mrp.repair,guarantee_limit:0 +msgid "" +"The warranty expiration limit is computed as: last move date + warranty " +"defined on selected product. If the current date is below the warranty " +"expiration limit, each operation and fee you will add will be set as 'not to " +"invoiced' by default. Note that you can change manually afterwards." +msgstr "" + +#. module: mrp_repair +#: view:mrp.repair.make_invoice:0 +msgid "Create Invoice" +msgstr "Izveidot rēķinu" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Reair Orders" +msgstr "Labojumu orderi" + +#. module: mrp_repair +#: field:mrp.repair.fee,name:0 +#: field:mrp.repair.line,name:0 +#: report:repair.order:0 +msgid "Description" +msgstr "Apraksts" + +#. module: mrp_repair +#: field:mrp.repair,operations:0 +msgid "Operation Lines" +msgstr "Operāciju rindas" + +#. module: mrp_repair +#: view:mrp.repair:0 +#: field:mrp.repair.fee,product_id:0 +#: field:mrp.repair.line,product_id:0 +msgid "Product" +msgstr "Produkts" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Invoice Corrected" +msgstr "Rēķins izlabots" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Price" +msgstr "Cena" + +#. module: mrp_repair +#: field:mrp.repair,deliver_bool:0 +msgid "Deliver" +msgstr "Piegādāt" + +#. module: mrp_repair +#: field:mrp.repair,internal_notes:0 +msgid "Internal Notes" +msgstr "Iekšējās piezīmes" + +#. module: mrp_repair +#: report:repair.order:0 +msgid "Taxes:" +msgstr "Nodokļi:" + +#. module: mrp_repair +#: view:mrp.repair.make_invoice:0 +msgid "Do you really want to create the invoice(s)?" +msgstr "Vai Jūs tiešām vēlaties izveidot rēķinu(s)?" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:349 +#, python-format +msgid "Repair order is already invoiced." +msgstr "No labojumu ordera rēķins jau ir izveidots." + +#. module: mrp_repair +#: field:mrp.repair,picking_id:0 +msgid "Picking" +msgstr "Izsniegšana" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Untaxed amount" +msgstr "Summa bez nodokļiem" + +#. module: mrp_repair +#: field:mrp.repair.fee,repair_id:0 +#: field:mrp.repair.line,repair_id:0 +msgid "Repair Order Reference" +msgstr "Labojumu ordera atsauce" + +#. module: mrp_repair +#: code:addons/mrp_repair/wizard/cancel_repair.py:49 +#, python-format +msgid "Repair order is not invoiced." +msgstr "No labojumu ordera rēķins nav izveidots." + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Total amount" +msgstr "Summa kopā" + +#. module: mrp_repair +#: selection:mrp.repair.line,type:0 +msgid "Remove" +msgstr "Izņemt" + +#. module: mrp_repair +#: field:mrp.repair,partner_invoice_id:0 +msgid "Invoicing Address" +msgstr "Rēķina adrese" + +#. module: mrp_repair +#: help:mrp.repair,message_ids:0 +msgid "Messages and communication history" +msgstr "Ziņojumu un komunikāciju vēsture" + +#. module: mrp_repair +#: view:mrp.repair:0 +msgid "Invoicing" +msgstr "Rēķina izrakstīšana" + +#. module: mrp_repair +#: field:mrp.repair.line,location_id:0 +msgid "Source Location" +msgstr "Resursa novietojums" + +#. module: mrp_repair +#: model:ir.model,name:mrp_repair.model_mrp_repair_cancel +#: view:mrp.repair:0 +msgid "Cancel Repair" +msgstr "Atcelt labojumu" + +#. module: mrp_repair +#: selection:mrp.repair,invoice_method:0 +msgid "No Invoice" +msgstr "Nav rēķina" + +#. module: mrp_repair +#: field:mrp.repair,amount_total:0 +msgid "Total" +msgstr "Kopā" + +#. module: mrp_repair +#: selection:mrp.repair,state:0 +msgid "Ready to Repair" +msgstr "Gatavs labojumiem" + +#. module: mrp_repair +#: code:addons/mrp_repair/mrp_repair.py:371 +#, python-format +msgid "No partner !" +msgstr "Nav partnera!" diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index 6c3f0ce21e1..43ee34b0c05 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -699,7 +699,6 @@ class mrp_repair_line(osv.osv, ProductChangeMixin): 'location_dest_id': scrap_location_ids and scrap_location_ids[0] or False, }} -mrp_repair_line() class mrp_repair_fee(osv.osv, ProductChangeMixin): _name = 'mrp.repair.fee' @@ -741,5 +740,4 @@ class mrp_repair_fee(osv.osv, ProductChangeMixin): 'to_invoice': lambda *a: True, } -mrp_repair_fee() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml index d35a9ebcf1d..a4526b5b581 100644 --- a/addons/mrp_repair/mrp_repair_view.xml +++ b/addons/mrp_repair/mrp_repair_view.xml @@ -210,7 +210,7 @@ - + diff --git a/addons/mrp_repair/test/mrp_repair_report.yml b/addons/mrp_repair/test/mrp_repair_report.yml index 5d66064f61d..166ace684d3 100644 --- a/addons/mrp_repair/test/mrp_repair_report.yml +++ b/addons/mrp_repair/test/mrp_repair_report.yml @@ -3,7 +3,8 @@ - !python {model: mrp.repair}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.repair.order').create(cr, uid, [ref('mrp_repair.mrp_repair_rmrp0')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('mrp_repair.mrp_repair_rmrp0')], 'repair.order', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'mrp_repair-order_report.'+format), 'wb+').write(data) diff --git a/addons/mrp_repair/wizard/cancel_repair.py b/addons/mrp_repair/wizard/cancel_repair.py index 12b85efd202..4c60f6c3251 100644 --- a/addons/mrp_repair/wizard/cancel_repair.py +++ b/addons/mrp_repair/wizard/cancel_repair.py @@ -81,7 +81,6 @@ class repair_cancel(osv.osv_memory): """ return res -repair_cancel() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_repair/wizard/make_invoice.py b/addons/mrp_repair/wizard/make_invoice.py index 9442746d68e..f9c84cb7bdb 100644 --- a/addons/mrp_repair/wizard/make_invoice.py +++ b/addons/mrp_repair/wizard/make_invoice.py @@ -68,7 +68,6 @@ class make_invoice(osv.osv_memory): 'type': 'ir.actions.act_window' } -make_invoice() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/note/html/index.html b/addons/note/html/index.html new file mode 100644 index 00000000000..e282c65928c --- /dev/null +++ b/addons/note/html/index.html @@ -0,0 +1,115 @@ +
+
+

Notes

+

Getting Things Done with Notes

+
+
+ + + +   + +
+
+
+

+Organize yourself with efficient todo lists and notes. From personnal tasks to collaborative meeting minutes, increase your user's productivity by giving them the tools to prioritize their work, share their ideas and collaborate on documents. +

+ +
+
+
+ +
+
+
+

Personal to-do lists that works

+

+Quickly create to-dos, organize horizontally for the mid-term (today, this week, this month, ...), prioritize vertically for the short term and group by assigning colors. The kanban approach allows a simple visual organization of your to-dos. +

+
+
+ +
+
+

Beat Work Overload

+

+ Feel how good it is to rely on a structured way to organize your work instead of keeping everything in memory. Use notes to Get Things Done. +

+
+
+

Prioritize Efficiently

+

+ Most people are lost in the flow of urgent daily tasks and have difficulties to work on important, long-term tasks. Notes gives you a simple way to allocate time very day to do important, but less urgent tasks. +

+
+
+

Find Motivation to Close Tasks

+

+ People used to work on tasks they like and not on important tasks. Start feeling good by checking tasks as done. +

+
+
+
+
+
+

Adapts to Your Creative Process

+

Customize to your own workflow

+

+Everyone has their own way to organize activities. OpenERP Notes' smart kanban approach allows every user to customize their own steps to process it's to-dos and notes. +

+ + +
+

A Creative Person

+

+A creative person will organize notes based on idea's maturity level: Draft Ideas Mature Ideas Specified To Do

+
+
+

A Frequent Traveler

+

+ An employee travelling a lot can organize their tasks based on the context to perform the task: U.S. Office | London's Office | To Review during Flights | At Home +

+
+
+

A Manager

+

+ A manager will organize their high number of tasks based on prioritizations: Todo Today | This Week | This Month | Later +

+ +
+
+ +
+
+

Personnal Notes

+

Notes are private but can be shared

+
+
+ +
+
+
+

+Write down your ideas in pads, keep your notes at your finger tips, attach related documents and use tags and colors to organize the information. Once your ideas are mature, you can share them to others users, start discussing it and collaborate by improving the specification in the pad. +

+
+
+
+ +
+
+

Collaborative Meeting Minutes

+

Real-time sharing and edition of notes

+
+

+The real time collaborative writings on notes makes it the perfect tool to collaborate on meeting minutes. Attendees will be able to contribute to the minutes, attach important documents or discuss on the related thread. +

+
+
+ +
+
+
diff --git a/addons/note/html/notes_illu_01.png b/addons/note/html/notes_illu_01.png new file mode 100644 index 00000000000..a7d4197561d Binary files /dev/null and b/addons/note/html/notes_illu_01.png differ diff --git a/addons/note/html/notes_sc_00.png b/addons/note/html/notes_sc_00.png new file mode 100644 index 00000000000..7bb4f95a640 Binary files /dev/null and b/addons/note/html/notes_sc_00.png differ diff --git a/addons/note/html/notes_sc_01.png b/addons/note/html/notes_sc_01.png new file mode 100644 index 00000000000..ce9367abf9b Binary files /dev/null and b/addons/note/html/notes_sc_01.png differ diff --git a/addons/note/html/notes_sc_02.png b/addons/note/html/notes_sc_02.png new file mode 100644 index 00000000000..e47889b33fc Binary files /dev/null and b/addons/note/html/notes_sc_02.png differ diff --git a/addons/note/html/notes_sc_03.png b/addons/note/html/notes_sc_03.png new file mode 100644 index 00000000000..6d59d7e5df8 Binary files /dev/null and b/addons/note/html/notes_sc_03.png differ diff --git a/addons/note/i18n/cs.po b/addons/note/i18n/cs.po new file mode 100644 index 00000000000..9d4cc3a298a --- /dev/null +++ b/addons/note/i18n/cs.po @@ -0,0 +1,284 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-03-27 09:45+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-28 04:41+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: note +#: field:note.note,memo:0 +msgid "Note Content" +msgstr "" + +#. module: note +#: view:note.stage:0 +msgid "Stages of Notes" +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_04 +#: model:note.stage,name:note.note_stage_02 +msgid "This Week" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_base_config_settings +msgid "base.config.settings" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_note_tag +msgid "Note Tag" +msgstr "" + +#. module: note +#: model:res.groups,name:note.group_note_fancy +msgid "Notes / Fancy mode" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_note_note +#: view:note.note:0 +msgid "Note" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "Group By..." +msgstr "" + +#. module: note +#: field:note.note,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: note +#: model:ir.actions.act_window,help:note.action_note_note +msgid "" +"

\n" +" Click to add a personal note.\n" +"

\n" +" Use notes to organize personal tasks or notes. All\n" +" notes are private; no one else will be able to see them. " +"However\n" +" you can share some notes with other people by inviting " +"followers\n" +" on the note. (Useful for meeting minutes, especially if\n" +" you activate the pad feature for collaborative writings).\n" +"

\n" +" You can customize how you process your notes/tasks by adding,\n" +" removing or modifying columns.\n" +"

\n" +" " +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_01 +#: model:note.stage,name:note.note_stage_01 +msgid "Today" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_res_users +msgid "Users" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "í" +msgstr "" + +#. module: note +#: view:note.stage:0 +msgid "Stage of Notes" +msgstr "" + +#. module: note +#: field:note.note,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: note +#: field:note.note,current_partner_id:0 +msgid "unknown" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "By sticky note Category" +msgstr "" + +#. module: note +#: help:note.note,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: note +#: field:note.stage,name:0 +msgid "Stage Name" +msgstr "" + +#. module: note +#: field:note.note,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_02 +msgid "Tomorrow" +msgstr "" + +#. module: note +#: view:note.note:0 +#: field:note.note,open:0 +msgid "Active" +msgstr "" + +#. module: note +#: help:note.stage,user_id:0 +msgid "Owner of the note stage." +msgstr "" + +#. module: note +#: model:ir.ui.menu,name:note.menu_notes_stage +msgid "Categories" +msgstr "" + +#. module: note +#: view:note.note:0 +#: field:note.note,stage_id:0 +msgid "Stage" +msgstr "" + +#. module: note +#: field:note.tag,name:0 +msgid "Tag Name" +msgstr "" + +#. module: note +#: field:note.note,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: note +#: view:base.config.settings:0 +#: model:ir.actions.act_window,name:note.action_note_note +#: model:ir.ui.menu,name:note.menu_note_notes +#: view:note.note:0 +#: model:note.stage,name:note.note_stage_04 +msgid "Notes" +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_03 +#: model:note.stage,name:note.note_stage_03 +msgid "Later" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_note_stage +msgid "Note Stage" +msgstr "" + +#. module: note +#: field:note.note,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: note +#: field:note.note,stage_ids:0 +msgid "Stages of Users" +msgstr "" + +#. module: note +#: field:note.note,name:0 +msgid "Note Summary" +msgstr "" + +#. module: note +#: model:ir.actions.act_window,name:note.action_note_stage +#: view:note.note:0 +msgid "Stages" +msgstr "" + +#. module: note +#: help:note.note,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "Delete" +msgstr "" + +#. module: note +#: field:note.note,color:0 +msgid "Color Index" +msgstr "" + +#. module: note +#: field:note.note,sequence:0 +#: field:note.stage,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: note +#: view:note.note:0 +#: field:note.note,tag_ids:0 +msgid "Tags" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "Archive" +msgstr "" + +#. module: note +#: field:base.config.settings,module_note_pad:0 +msgid "Use collaborative pads (etherpad)" +msgstr "" + +#. module: note +#: help:note.note,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: note +#: field:base.config.settings,group_note_fancy:0 +msgid "Use fancy layouts for notes" +msgstr "" + +#. module: note +#: field:note.note,current_partner_id:0 +#: field:note.stage,user_id:0 +msgid "Owner" +msgstr "" + +#. module: note +#: help:note.stage,sequence:0 +msgid "Used to order the note stages" +msgstr "" + +#. module: note +#: field:note.note,date_done:0 +msgid "Date done" +msgstr "" + +#. module: note +#: field:note.stage,fold:0 +msgid "Folded by Default" +msgstr "" diff --git a/addons/note/i18n/lt.po b/addons/note/i18n/lt.po new file mode 100644 index 00000000000..3e030054520 --- /dev/null +++ b/addons/note/i18n/lt.po @@ -0,0 +1,284 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-04-29 15:23+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: note +#: field:note.note,memo:0 +msgid "Note Content" +msgstr "" + +#. module: note +#: view:note.stage:0 +msgid "Stages of Notes" +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_04 +#: model:note.stage,name:note.note_stage_02 +msgid "This Week" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_base_config_settings +msgid "base.config.settings" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_note_tag +msgid "Note Tag" +msgstr "" + +#. module: note +#: model:res.groups,name:note.group_note_fancy +msgid "Notes / Fancy mode" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_note_note +#: view:note.note:0 +msgid "Note" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "Group By..." +msgstr "" + +#. module: note +#: field:note.note,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: note +#: model:ir.actions.act_window,help:note.action_note_note +msgid "" +"

\n" +" Click to add a personal note.\n" +"

\n" +" Use notes to organize personal tasks or notes. All\n" +" notes are private; no one else will be able to see them. " +"However\n" +" you can share some notes with other people by inviting " +"followers\n" +" on the note. (Useful for meeting minutes, especially if\n" +" you activate the pad feature for collaborative writings).\n" +"

\n" +" You can customize how you process your notes/tasks by adding,\n" +" removing or modifying columns.\n" +"

\n" +" " +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_01 +#: model:note.stage,name:note.note_stage_01 +msgid "Today" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_res_users +msgid "Users" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "í" +msgstr "" + +#. module: note +#: view:note.stage:0 +msgid "Stage of Notes" +msgstr "" + +#. module: note +#: field:note.note,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: note +#: field:note.note,current_partner_id:0 +msgid "unknown" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "By sticky note Category" +msgstr "" + +#. module: note +#: help:note.note,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: note +#: field:note.stage,name:0 +msgid "Stage Name" +msgstr "" + +#. module: note +#: field:note.note,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_02 +msgid "Tomorrow" +msgstr "" + +#. module: note +#: view:note.note:0 +#: field:note.note,open:0 +msgid "Active" +msgstr "" + +#. module: note +#: help:note.stage,user_id:0 +msgid "Owner of the note stage." +msgstr "" + +#. module: note +#: model:ir.ui.menu,name:note.menu_notes_stage +msgid "Categories" +msgstr "" + +#. module: note +#: view:note.note:0 +#: field:note.note,stage_id:0 +msgid "Stage" +msgstr "" + +#. module: note +#: field:note.tag,name:0 +msgid "Tag Name" +msgstr "" + +#. module: note +#: field:note.note,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: note +#: view:base.config.settings:0 +#: model:ir.actions.act_window,name:note.action_note_note +#: model:ir.ui.menu,name:note.menu_note_notes +#: view:note.note:0 +#: model:note.stage,name:note.note_stage_04 +msgid "Notes" +msgstr "" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_03 +#: model:note.stage,name:note.note_stage_03 +msgid "Later" +msgstr "" + +#. module: note +#: model:ir.model,name:note.model_note_stage +msgid "Note Stage" +msgstr "" + +#. module: note +#: field:note.note,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: note +#: field:note.note,stage_ids:0 +msgid "Stages of Users" +msgstr "" + +#. module: note +#: field:note.note,name:0 +msgid "Note Summary" +msgstr "" + +#. module: note +#: model:ir.actions.act_window,name:note.action_note_stage +#: view:note.note:0 +msgid "Stages" +msgstr "" + +#. module: note +#: help:note.note,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "Delete" +msgstr "" + +#. module: note +#: field:note.note,color:0 +msgid "Color Index" +msgstr "" + +#. module: note +#: field:note.note,sequence:0 +#: field:note.stage,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: note +#: view:note.note:0 +#: field:note.note,tag_ids:0 +msgid "Tags" +msgstr "" + +#. module: note +#: view:note.note:0 +msgid "Archive" +msgstr "" + +#. module: note +#: field:base.config.settings,module_note_pad:0 +msgid "Use collaborative pads (etherpad)" +msgstr "" + +#. module: note +#: help:note.note,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: note +#: field:base.config.settings,group_note_fancy:0 +msgid "Use fancy layouts for notes" +msgstr "" + +#. module: note +#: field:note.note,current_partner_id:0 +#: field:note.stage,user_id:0 +msgid "Owner" +msgstr "" + +#. module: note +#: help:note.stage,sequence:0 +msgid "Used to order the note stages" +msgstr "" + +#. module: note +#: field:note.note,date_done:0 +msgid "Date done" +msgstr "" + +#. module: note +#: field:note.stage,fold:0 +msgid "Folded by Default" +msgstr "" diff --git a/addons/note/note.py b/addons/note/note.py index 2d95b15107a..eb9a6397d18 100644 --- a/addons/note/note.py +++ b/addons/note/note.py @@ -141,12 +141,19 @@ class note_note(osv.osv): #note without user's stage nb_notes_ws = self.search(cr,uid, domain+[('stage_ids', 'not in', current_stage_ids)], context=context, count=True) if nb_notes_ws: - result += [{ #notes for unknown stage and if stage_ids is not empty - '__context': {'group_by': groupby[1:]}, - '__domain': domain + [('stage_ids', 'not in', current_stage_ids)], - 'stage_id': (0, 'Unknown'), - 'stage_id_count':nb_notes_ws - }] + # add note to the first column if it's the first stage + dom_not_in = ('stage_ids', 'not in', current_stage_ids) + if result and result[0]['stage_id'][0] == current_stage_ids[0]: + dom_in = result[0]['__domain'].pop() + result[0]['__domain'] = domain + ['|', dom_in, dom_not_in] + else: + # add the first stage column + result = [{ + '__context': {'group_by': groupby[1:]}, + '__domain': domain + [dom_not_in], + 'stage_id': (current_stage_ids[0], stage_name[current_stage_ids[0]]), + 'stage_id_count':nb_notes_ws + }] + result else: # if stage_ids is empty @@ -156,7 +163,7 @@ class note_note(osv.osv): result = [{ #notes for unknown stage '__context': {'group_by': groupby[1:]}, '__domain': domain, - 'stage_id': (0, 'Unknown'), + 'stage_id': False, 'stage_id_count':nb_notes_ws }] else: @@ -187,9 +194,12 @@ class res_users(osv.Model): model_id = data_obj.get_object_reference(cr, uid, 'base', 'group_user') #Employee Group group_id = model_id and model_id[1] or False if group_id in [x.id for x in user.groups_id]: - for note_xml_id in ['note_stage_01','note_stage_02','note_stage_03','note_stage_04']: - data_id = data_obj._get_id(cr, uid, 'note', note_xml_id) + for note_xml_id in ['note_stage_00','note_stage_01','note_stage_02','note_stage_03','note_stage_04']: + try: + data_id = data_obj._get_id(cr, uid, 'note', note_xml_id) + except ValueError: + continue stage_id = data_obj.browse(cr, uid, data_id, context=context).res_id note_obj.copy(cr, uid, stage_id, default = { 'user_id': user_id}, context=context) - return user_id \ No newline at end of file + return user_id diff --git a/addons/note/note_data.xml b/addons/note/note_data.xml index 592292788b3..376b8e9053f 100644 --- a/addons/note/note_data.xml +++ b/addons/note/note_data.xml @@ -2,6 +2,12 @@ + + New + + + + Today 1 diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml index 49a154d10cc..68ec6bfc4f7 100644 --- a/addons/note/note_view.xml +++ b/addons/note/note_view.xml @@ -193,7 +193,7 @@ - + diff --git a/addons/note_pad/i18n/cs.po b/addons/note_pad/i18n/cs.po new file mode 100644 index 00000000000..bb2502ee2d1 --- /dev/null +++ b/addons/note_pad/i18n/cs.po @@ -0,0 +1,28 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-03-30 09:13+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-31 05:27+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: note_pad +#: model:ir.model,name:note_pad.model_note_note +msgid "Note" +msgstr "" + +#. module: note_pad +#: field:note.note,note_pad_url:0 +msgid "Pad Url" +msgstr "" diff --git a/addons/note_pad/i18n/lt.po b/addons/note_pad/i18n/lt.po new file mode 100644 index 00000000000..3c814e3f7eb --- /dev/null +++ b/addons/note_pad/i18n/lt.po @@ -0,0 +1,28 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-24 18:32+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: note_pad +#: model:ir.model,name:note_pad.model_note_note +msgid "Note" +msgstr "Užrašinė" + +#. module: note_pad +#: field:note.note,note_pad_url:0 +msgid "Pad Url" +msgstr "Nuorodą į užrašinę" diff --git a/addons/pad/pad.py b/addons/pad/pad.py index 90f5354054c..4cd9e91b76e 100644 --- a/addons/pad/pad.py +++ b/addons/pad/pad.py @@ -42,7 +42,7 @@ class pad_common(osv.osv_memory): myPad.createPad(path) #get attr on the field model - model = self.pool.get(context["model"]) + model = self.pool[context["model"]] field = model._all_columns[context['field_name']] real_field = field.column.pad_content_field diff --git a/addons/pad/py_etherpad/__init__.py b/addons/pad/py_etherpad/__init__.py index 6af310b48aa..0db607fe16f 100644 --- a/addons/pad/py_etherpad/__init__.py +++ b/addons/pad/py_etherpad/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python """Module to talk to EtherpadLite API.""" import json diff --git a/addons/pad/static/src/css/etherpad.css b/addons/pad/static/src/css/etherpad.css index ad47be32b02..a0002ebe97c 100644 --- a/addons/pad/static/src/css/etherpad.css +++ b/addons/pad/static/src/css/etherpad.css @@ -43,7 +43,7 @@ z-index: 1000; } -.oe_pad.oe_configured .oe_pad_content.oe_editing{ +.oe_pad .oe_pad_content.oe_editing{ border: solid 1px #c4c4c4; height:500px; -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.1); @@ -53,7 +53,7 @@ box-shadow: 0 5px 10px rgba(0,0,0,0.1); } -.oe_pad.oe_configured.oe_pad_fullscreen .oe_pad_content { +.oe_pad.oe_pad_fullscreen .oe_pad_content { height: 100%; border: none; -webkit-box-shadow: none; @@ -63,7 +63,7 @@ box-shadow: none; } -.oe_pad.oe_unconfigured > p { +.oe_pad .oe_unconfigured { text-align: center; opacity: 0.75; } diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js index b96047340ad..ba5ee3a3037 100644 --- a/addons/pad/static/src/js/pad.js +++ b/addons/pad/static/src/js/pad.js @@ -1,67 +1,64 @@ openerp.pad = function(instance) { - instance.web.form.FieldPad = instance.web.form.AbstractField.extend({ + instance.web.form.FieldPad = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeWidgetMixin, { template: 'FieldPad', - configured: false, content: "", - start: function() { - this._super(); - var self = this; - this.on('change:effective_readonly',this,function(){ - self.renderElement(); + init: function() { + this._super.apply(this, arguments); + this.set("configured", true); + this.on("change:configured", this, this.switch_configured); + }, + initialize_content: function() { + var self = this; + this.switch_configured(); + this.$('.oe_pad_switch').click(function() { + self.$el.toggleClass('oe_pad_fullscreen'); }); + this.render_value(); + }, + switch_configured: function() { + this.$(".oe_unconfigured").toggle(! this.get("configured")); + this.$(".oe_configured").toggle(this.get("configured")); }, render_value: function() { - var self = this; - var _super = _.bind(this._super, this); - if (this.get("value") === false || this.get("value") === "") { - self.view.dataset.call('pad_generate_url',{context:{ + var self = this; + if (this.get("configured") && ! this.get("value")) { + self.view.dataset.call('pad_generate_url', { + context: { model: self.view.model, field_name: self.name, object_id: self.view.datarecord.id - }}).done(function(data) { - if(data&&data.url){ - self.set({value: data.url}); - _super(data.url); - self.renderElement(); + }, + }).done(function(data) { + if (! data.url) { + self.set("configured", false); + } else { + self.set("value", data.url); } }); - } else { - self.renderElement(); } - this._dirty_flag = true; - }, - renderElement: function(){ - var self = this; + this.$('.oe_pad_content').html(""); var value = this.get('value'); if (this.pad_loading_request) { this.pad_loading_request.abort(); } - if(!_.str.startsWith(value,'http')){ - this.configured = false; - this.content = ""; - }else{ - this.configured = true; - if(!this.get('effective_readonly')){ - this.content = ''; - }else{ + if (_.str.startsWith(value, 'http')) { + if (! this.get('effective_readonly')) { + var content = ''; + this.$('.oe_pad_content').html(content); + this._dirty_flag = true; + } else { this.content = '
... Loading pad ...
'; - this.pad_loading_request = $.get(value+'/export/html') - .done(function(data){ + this.pad_loading_request = $.get(value + '/export/html').done(function(data) { groups = /\<\s*body\s*\>(.*?)\<\s*\/body\s*\>/.exec(data); data = (groups || []).length >= 2 ? groups[1] : ''; self.$('.oe_pad_content').html('
'); self.$('.oe_pad_readonly').html(data); - }).error(function(){ + }).fail(function() { self.$('.oe_pad_content').text('Unable to load pad'); }); } } - this._super(); - this.$('.oe_pad_content').html(this.content); - this.$('.oe_pad_switch').click(function(){ - self.$el.toggleClass('oe_pad_fullscreen'); - }); }, }); diff --git a/addons/pad/static/src/xml/pad.xml b/addons/pad/static/src/xml/pad.xml index bd3e296f9b3..f915e867b35 100644 --- a/addons/pad/static/src/xml/pad.xml +++ b/addons/pad/static/src/xml/pad.xml @@ -5,32 +5,25 @@ - -
-

- You must configure the etherpad through the menu Settings > Companies > Companies, in the configuration tab of your company. -

-
-
- - +
+

+ You must configure the etherpad through the menu Settings > Companies > Companies, in the configuration tab of your company. +

-
-
-
+
+ +
+ &Ntilde; +
+
+
+
+
+ + - -
-
- &Ntilde; -
-
-
-
-
-
diff --git a/addons/pad_project/i18n/lt.po b/addons/pad_project/i18n/lt.po new file mode 100644 index 00000000000..2f7340a36e2 --- /dev/null +++ b/addons/pad_project/i18n/lt.po @@ -0,0 +1,39 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-24 18:35+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: pad_project +#: constraint:project.task:0 +msgid "Error ! Task end-date must be greater then task start-date" +msgstr "" +"Klaida! Užduotės pabaigos data negali būti ankstesnė nei pradžios data" + +#. module: pad_project +#: field:project.task,description_pad:0 +msgid "Description PAD" +msgstr "" + +#. module: pad_project +#: model:ir.model,name:pad_project.model_project_task +msgid "Task" +msgstr "Užduotis" + +#. module: pad_project +#: constraint:project.task:0 +msgid "Error ! You cannot create recursive tasks." +msgstr "Klaida! Negalima sukurti rekursinių užduočių." diff --git a/addons/plugin/i18n/lt.po b/addons/plugin/i18n/lt.po new file mode 100644 index 00000000000..dc120cadcf2 --- /dev/null +++ b/addons/plugin/i18n/lt.po @@ -0,0 +1,23 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-24 18:14+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: plugin +#: model:ir.model,name:plugin.model_plugin_handler +msgid "plugin.handler" +msgstr "plugin.handler" diff --git a/addons/plugin/plugin_handler.py b/addons/plugin/plugin_handler.py index 0664af1c92e..fc6c874fab5 100644 --- a/addons/plugin/plugin_handler.py +++ b/addons/plugin/plugin_handler.py @@ -4,7 +4,8 @@ Created on 18 oct. 2011 @author: openerp ''' -from openerp.osv import fields, osv +from openerp.osv import osv +from openerp.tools.translate import _ class plugin_handler(osv.osv_memory): _name = 'plugin.handler' @@ -29,7 +30,7 @@ class plugin_handler(osv.osv_memory): partner_ids = partner_obj.search(cr, uid, [('email', 'like', address_email)]) res_id = partner_ids and partner_ids[0] or 0 url = self._make_url(cr, uid, res_id, 'res.partner') - return ('res.partner', res_id , url) + return ('res.partner', res_id, url) def document_get(self, cr, uid, email): """ @@ -48,7 +49,7 @@ class plugin_handler(osv.osv_memory): message_id = msg.get('message_id') msg_id = False if message_id: - msg_ids = mail_message_obj.search(cr, uid, [('message_id','=', message_id)]) + msg_ids = mail_message_obj.search(cr, uid, [('message_id', '=', message_id)]) msg_id = len(msg_ids) and msg_ids[0] or False if not msg_id and parent_id: msg_id = parent_id @@ -57,8 +58,8 @@ class plugin_handler(osv.osv_memory): res_id = msg.res_id model = msg.model url = self._make_url(cr, uid, res_id, model) - name = self.pool.get(model).name_get(cr, uid, [res_id])[0][1] - return (model,res_id, url,name) + name = self.pool[model].name_get(cr, uid, [res_id])[0][1] + return (model, res_id, url, name) def document_type(self, cr, uid, context=None): """ @@ -81,7 +82,7 @@ class plugin_handler(osv.osv_memory): @return : the result of name_search a list of tuple [(id, 'name')] """ - return self.pool.get(model).name_search(cr, uid, name) + return self.pool[model].name_search(cr, uid, name) def push_message(self, cr, uid, model, email, res_id=0): """ @@ -91,29 +92,28 @@ class plugin_handler(osv.osv_memory): @return Dictionary which contain model , url and resource id. """ mail_message = self.pool.get('mail.message') - model_obj = self.pool.get(model) + model_obj = self.pool[model] msg = self.pool.get('mail.thread').message_parse(cr, uid, email) message_id = msg.get('message-id') - mail_ids = mail_message.search(cr, uid, [('message_id','=',message_id),('res_id','=',res_id),('model','=',model)]) - - if message_id and mail_ids : + mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)]) + if message_id and mail_ids: mail_record = mail_message.browse(cr, uid, mail_ids)[0] res_id = mail_record.res_id - notify = "Email already pushed" + notify = _("Email already pushed") elif res_id == 0: if model == 'res.partner': - notify = 'User the Partner button to create a new partner' + notify = _('Use the Partner button to create a new partner') else: res_id = model_obj.message_process(cr, uid, model, email) - notify = "Mail successfully pushed, a new %s has been created " % model + notify = _("Mail successfully pushed, a new %s has been created.") % model else: model_obj.message_post(cr, uid, [res_id], - body= msg.get('body'), - subject= msg.get('subject'), - type= 'email', - parent_id= msg.get('parent_id'), - attachments= msg.get('attachments')) - notify = "Mail successfully pushed" + body=msg.get('body'), + subject=msg.get('subject'), + type='comment' if model == 'res.partner' else 'email', + parent_id=msg.get('parent_id'), + attachments=msg.get('attachments')) + notify = _("Mail successfully pushed") url = self._make_url(cr, uid, res_id, model) return (model, res_id, url, notify) @@ -154,16 +154,17 @@ class plugin_handler(osv.osv_memory): message_id = msg.get('message-id') push_mail = self.push_message(cr, uid, model, headers, res_id) res_id = push_mail[1] - model = push_mail[0] + model = push_mail[0] + notify = push_mail[3] for name in attachments.keys(): attachment_ids = ir_attachment_obj.search(cr, uid, [('res_model', '=', model), ('res_id', '=', res_id), ('datas_fname', '=', name)]) if attachment_ids: - attach_ids.append( attachment_ids[0]) + attach_ids.append(attachment_ids[0]) else: - vals = {"res_model": model, "res_id": res_id, "name": name, "datas" :attachments[name], "datas_fname" : name} + vals = {"res_model": model, "res_id": res_id, "name": name, "datas": attachments[name], "datas_fname": name} attach_ids.append(ir_attachment_obj.create(cr, uid, vals)) - mail_ids = mail_message.search(cr, uid, [('message_id','=',message_id),('res_id','=',res_id),('model','=',model)]) + mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)]) if mail_ids: - ids = mail_message.write(cr, uid, mail_ids[0], { 'attachment_ids': [(6, 0, attach_ids)],'body':body,'body_html':body_html}) + mail_message.write(cr, uid, mail_ids[0], {'attachment_ids': [(6, 0, attach_ids)], 'body': body, 'body_html': body_html}) url = self._make_url(cr, uid, res_id, model) - return (model, res_id, url) + return (model, res_id, url, notify) diff --git a/addons/plugin_outlook/i18n/cs.po b/addons/plugin_outlook/i18n/cs.po new file mode 100644 index 00000000000..b095bfb469c --- /dev/null +++ b/addons/plugin_outlook/i18n/cs.po @@ -0,0 +1,89 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-03-31 16:52+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: plugin_outlook +#: field:outlook.installer,plugin32:0 +msgid "Outlook Plug-in 32bits" +msgstr "" + +#. module: plugin_outlook +#: view:sale.config.settings:0 +msgid "Download and install the plug-in" +msgstr "" + +#. module: plugin_outlook +#: model:ir.model,name:plugin_outlook.model_outlook_installer +msgid "outlook.installer" +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "MS .Net Framework 3.5 or above." +msgstr "" + +#. module: plugin_outlook +#: model:ir.actions.act_window,name:plugin_outlook.action_outlook_installer +#: model:ir.actions.act_window,name:plugin_outlook.action_outlook_wizard +#: model:ir.ui.menu,name:plugin_outlook.menu_base_config_plugins_outlook +#: view:outlook.installer:0 +msgid "Install Outlook Plug-In" +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "System requirements:" +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "title" +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "" +"Click on the link above to download the installer for either 32 or 64 bits, " +"and execute it." +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "MS Outlook 2005 or above." +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "Close" +msgstr "" + +#. module: plugin_outlook +#: field:outlook.installer,plugin64:0 +msgid "Outlook Plug-in 64bits" +msgstr "" + +#. module: plugin_outlook +#: view:outlook.installer:0 +msgid "Installation and Configuration Steps" +msgstr "" + +#. module: plugin_outlook +#: help:outlook.installer,plugin32:0 +#: help:outlook.installer,plugin64:0 +msgid "Outlook plug-in file. Save this file and install it in Outlook." +msgstr "" diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj index 75fe271e5d6..f9ac3e31553 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj @@ -17,6 +17,7 @@ 3.5 + false publish\ true Disk @@ -29,7 +30,6 @@ true 0 1.0.0.%2a - false false true @@ -53,9 +53,8 @@ AllRules.ruleset - - False - ..\OpenERPOutlookPlugin\bin\Release\CookComputing.XmlRpcV2.dll + + ..\CookComputing.XmlRpcV2.dll @@ -81,7 +80,7 @@ False - .NET Framework 3.5 SP1 Client Profile + .NET Framework 3.5 SP1 Client Profile false @@ -91,7 +90,7 @@ False - Windows Installer 3.1 + Windows Installer 3.1 true diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln index f4705664cf4..ad53769e5b4 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin.sln @@ -1,6 +1,6 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenERPOutlookPlugin", "OpenERPOutlookPlugin\OpenERPOutlookPlugin.csproj", "{F4B2219B-F235-400F-81B4-92F15250BBA4}" EndProject Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "OpenERPOutlookPluginSetup", "OpenERPOutlookPluginSetup\OpenERPOutlookPluginSetup.vdproj", "{96333293-0156-4998-9065-42721CEB0368}" diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs index 1336c7f7695..dae4db88aa2 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/Connect.cs @@ -303,6 +303,7 @@ namespace OpenERPOutlookPlugin foreach (outlook.MailItem mailitem in Tools.MailItems()) { + Object[] contact = Cache.OpenERPOutlookPlugin.RedirectPartnerPage(mailitem); if ((int)contact[1] > 0) diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs index b057201b8d1..e1d45318ee4 100644 --- a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs +++ b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPlugin/OpenERPOutlookPlugin.cs @@ -95,7 +95,6 @@ namespace OpenERPOutlookPlugin /* * Will open the url into the web browser. */ - System.Diagnostics.Process.Start(web_url.ToString()); } @@ -163,9 +162,16 @@ namespace OpenERPOutlookPlugin args.Add(attachments); object push_mail = this.Connection.Execute("plugin.handler", "push_message_outlook", args.ToArray()); object[] push = (object[])push_mail; - this.RedirectWeb(push[2].ToString()); - return true; + if (Convert.ToInt32(push[1]) == 0) + { + MessageBox.Show(push[3].ToString()); + } + else + { + this.RedirectWeb(push[2].ToString()); + } + return true; } public long CreatePartnerRecord(string name) { diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi index a31471c28ba..9d9dd5d3ad3 100644 Binary files a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi and b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup32.msi differ diff --git a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi index 87cac88be70..0c2fa88bb24 100644 Binary files a/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi and b/addons/plugin_outlook/static/openerp-outlook-plugin/OpenERPOutlookPluginSetup64.msi differ diff --git a/addons/plugin_thunderbird/static/thunderbird_plugin/install.sh b/addons/plugin_thunderbird/static/thunderbird_plugin/install.sh index e1103b30acf..5ca7a5a934a 100755 --- a/addons/plugin_thunderbird/static/thunderbird_plugin/install.sh +++ b/addons/plugin_thunderbird/static/thunderbird_plugin/install.sh @@ -1,3 +1,4 @@ +#!/bin/sh make clean make cp ../openerp_plugin.xpi /home/openerp/ diff --git a/addons/point_of_sale/account_bank_statement.py b/addons/point_of_sale/account_bank_statement.py index 31415bb847c..9275b975d46 100644 --- a/addons/point_of_sale/account_bank_statement.py +++ b/addons/point_of_sale/account_bank_statement.py @@ -34,7 +34,6 @@ class account_journal(osv.osv): 'self_checkout_payment_method' : False, } -account_journal() class account_cash_statement(osv.osv): _inherit = 'account.bank.statement' @@ -42,6 +41,5 @@ class account_cash_statement(osv.osv): 'pos_session_id' : fields.many2one('pos.session'), } -account_cash_statement() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/html/index.html b/addons/point_of_sale/html/index.html new file mode 100644 index 00000000000..41f935d8ad9 --- /dev/null +++ b/addons/point_of_sale/html/index.html @@ -0,0 +1,245 @@ +
+
+
+

A very friendly Point of Sale

+

Set up in a minute, Sell in seconds

+
+
+
+ + + +   + +
+
+
+

+ OpenERP's Point of Sale introduces a super clean interface with no installation required + that runs online and offline on modern hardwares. +

+

+ It's full integration with the company inventory and accounting, gives you real time statistics and + consolidations amongst all shops without the hassle of integrating several applications. +

+ +
+
+
+ +
+
+
+

Work with the hardware you already have

+

Desktops, laptops, tablets, it runs on everything

+
+
+ +
+
+

In your web browser

+

+ OpenERP's POS is a web application that can run on any device that can + display websites with little to no setup required. +

+
+
+

Touchscreen or Keyboard ?

+

+ The Point of Sale works perfectly on any kind of touch enabled device, whether it's + multi-touch tablets like an iPad or keyboardless resistive touchscreen terminals. +

+
+
+

Scales and Printers

+

+ Barcode scanners and printers are supported out of the box with no setup required. + Scales, cashboxes, and other peripherals can be used with the + proxy API. +

+
+
+
+ +
+
+ +

Online and Offline

+

OpenERP's POS stays reliable even if your connection isn't

+ +
+
+ +
+
+
+

+ Deploy new stores with just an internet connection: + no installation, no specific hardware required. It works with any + iPad, Tablet PC, laptop or industrial POS machine. +

+ While an internet connection is required to start the Point of Sale, + it will stay operational even after a complete disconnection. +

+
+
+
+ +
+
+ +
+ Download our free E-book +
+ +
+
+

A super clean user interface

+

The point of sale software retailers love to use

+
+
+
+ +

Simple and beautifull

+

+ Say goodbye to ugly, outdated POS software and enjoy the OpenERP + web interface designed for modern retailer. +

+
+
+ +

Designed for Productivity

+

+ Whether it's for a restaurant or a shop, you can activate the multiple + tickets in parallel to not make your customers wait. +

+
+
+ +

Blasting fast search

+

+ Scan products, browse through hyerarchical categories, or get quick + information about products with the blasting fast filter accross + all your products. +

+
+
+
+ +
+
+

Integrated Inventory Management

+
+ +
+
+

+ Consolidate all your sales channel in real time: stores, ecommerce, sales teams. + Get real time control of the inventory and accurate forecasts to manage procurements. +

+

+ A full warehouse management system at your fingertips: get information + about products availabilities, trigger procurement requests, etc. +

+
+
+
+ +
+
+

Deliver in-store customer services

+

Repairs, warantees, deliveries, etc.

+
+

+ Give your shopper a strong experience by integrating in-store + customer services. Handle reparations, track warantees, follow + customer claims, plan delivery orders, etc. +

+
+
+ +
+
+
+ +
+
+

Invoicing & Accounting Integration

+
+ +
+
+

+ Produce customer invoices in just a few clicks. Control sales and + cash in real time and use OpenERP's powerful reporting to make + smarter decisions to improve your store's efficiency. +

+ No more hassle of having to integrate softwares: get all your sales + and inventory operations automatically posted in your G/L. +

+
+
+
+ +
+
+

Self-checkout Interface

+
+

+ Reduce costs by limitting the number of required cashiers. + The self-checkout mode allows customers to scan products and pay by + themselves with a dedicated and super easy user interface. +

+

+ Use lights and sounds to control the checkout distantly. +

+
+
+ +
+
+
+ + +
+
+

Unified Data Amongst All Shops

+

Sync products, prices, customers with no effort

+
+ +
+
+

+ Get new products, pricing strategies and promotions applied automatically to + selected stores. Work on a unified customer base. No complex interface is + required to pilot a global strategy amongst all your stores. +

+

+ With OpenERP as a backend, you have a system proven to be perfectly + suitable for small stores or large multinationals. +

+
+
+
+ +
+
+

Know your customers - in store and out

+
+

+ Successful brands integrates all their customer relationship accross all their + channels to develop accurate customer profile and communicate with shoppers + as they make buying decisions, in store or online. +

+

+ With OpenERP, you get a 360° customer view, including cross-channel sales, + interaction history, profiles, and more. +

+
+
+ +
+
+
diff --git a/addons/point_of_sale/html/pos_checkout.jpg b/addons/point_of_sale/html/pos_checkout.jpg new file mode 100644 index 00000000000..d87e5b8499d Binary files /dev/null and b/addons/point_of_sale/html/pos_checkout.jpg differ diff --git a/addons/point_of_sale/html/pos_customer_form.png b/addons/point_of_sale/html/pos_customer_form.png new file mode 100644 index 00000000000..4e89d43c4c3 Binary files /dev/null and b/addons/point_of_sale/html/pos_customer_form.png differ diff --git a/addons/point_of_sale/html/pos_customers.png b/addons/point_of_sale/html/pos_customers.png new file mode 100644 index 00000000000..6448074c3d9 Binary files /dev/null and b/addons/point_of_sale/html/pos_customers.png differ diff --git a/addons/point_of_sale/html/pos_devices.png b/addons/point_of_sale/html/pos_devices.png new file mode 100644 index 00000000000..a021a87bfac Binary files /dev/null and b/addons/point_of_sale/html/pos_devices.png differ diff --git a/addons/point_of_sale/html/pos_invoice.png b/addons/point_of_sale/html/pos_invoice.png new file mode 100644 index 00000000000..aae4f6d38a5 Binary files /dev/null and b/addons/point_of_sale/html/pos_invoice.png differ diff --git a/addons/point_of_sale/html/pos_offline.png b/addons/point_of_sale/html/pos_offline.png new file mode 100644 index 00000000000..764cda88e87 Binary files /dev/null and b/addons/point_of_sale/html/pos_offline.png differ diff --git a/addons/point_of_sale/html/pos_product_form.png b/addons/point_of_sale/html/pos_product_form.png new file mode 100644 index 00000000000..a25c85b6496 Binary files /dev/null and b/addons/point_of_sale/html/pos_product_form.png differ diff --git a/addons/point_of_sale/html/pos_products.png b/addons/point_of_sale/html/pos_products.png new file mode 100644 index 00000000000..cbfd054d72e Binary files /dev/null and b/addons/point_of_sale/html/pos_products.png differ diff --git a/addons/point_of_sale/html/pos_sc_01.jpg b/addons/point_of_sale/html/pos_sc_01.jpg new file mode 100644 index 00000000000..8fc97e00672 Binary files /dev/null and b/addons/point_of_sale/html/pos_sc_01.jpg differ diff --git a/addons/point_of_sale/html/pos_sc_02.jpg b/addons/point_of_sale/html/pos_sc_02.jpg new file mode 100644 index 00000000000..d26e0504933 Binary files /dev/null and b/addons/point_of_sale/html/pos_sc_02.jpg differ diff --git a/addons/point_of_sale/html/pos_sc_03.jpg b/addons/point_of_sale/html/pos_sc_03.jpg new file mode 100644 index 00000000000..8eb7e312791 Binary files /dev/null and b/addons/point_of_sale/html/pos_sc_03.jpg differ diff --git a/addons/point_of_sale/html/pos_ui_01.png b/addons/point_of_sale/html/pos_ui_01.png new file mode 100644 index 00000000000..1725f91d6f2 Binary files /dev/null and b/addons/point_of_sale/html/pos_ui_01.png differ diff --git a/addons/point_of_sale/html/pos_ui_02.png b/addons/point_of_sale/html/pos_ui_02.png new file mode 100644 index 00000000000..aa0eb51c0f1 Binary files /dev/null and b/addons/point_of_sale/html/pos_ui_02.png differ diff --git a/addons/point_of_sale/html/pos_ui_03.png b/addons/point_of_sale/html/pos_ui_03.png new file mode 100644 index 00000000000..f25f2a49c00 Binary files /dev/null and b/addons/point_of_sale/html/pos_ui_03.png differ diff --git a/addons/point_of_sale/i18n/pt_BR.po b/addons/point_of_sale/i18n/pt_BR.po index eac24526afc..4d4efabdec3 100644 --- a/addons/point_of_sale/i18n/pt_BR.po +++ b/addons/point_of_sale/i18n/pt_BR.po @@ -7,19 +7,19 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2012-10-17 00:01+0000\n" -"Last-Translator: Syllas F. de O. Neto \n" +"PO-Revision-Date: 2013-04-18 18:07+0000\n" +"Last-Translator: Thiago Tognoli \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: 2013-03-16 05:07+0000\n" -"X-Generator: Launchpad (build 16532)\n" +"X-Launchpad-Export-Date: 2013-04-19 05:24+0000\n" +"X-Generator: Launchpad (build 16567)\n" #. module: point_of_sale #: field:report.transaction.pos,product_nb:0 msgid "Product Nb." -msgstr "Produto No." +msgstr "Núm. Produto" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.action_trans_pos_tree_today @@ -286,7 +286,7 @@ msgstr "Desconto (%)" #: report:pos.details:0 #: report:pos.details_summary:0 msgid "Total discount" -msgstr "Total de Desconto" +msgstr "Desconto total" #. module: point_of_sale #. openerp-web @@ -354,6 +354,9 @@ msgid "" "Check this if this point of sale should open by default in a self checkout " "mode. If unchecked, OpenERP uses the normal cashier mode by default." msgstr "" +"Marque esta opção se este ponto de venda deve ser aberto por padrão em modo " +"de auto atendimento. Se não marcada, o OpenERP irá usar o modo normal por " +"padrão." #. module: point_of_sale #: model:ir.actions.report.xml,name:point_of_sale.pos_sales_user @@ -444,7 +447,7 @@ msgstr "Você precisa associar um Ponto de Vendas a sua sessão." #. module: point_of_sale #: view:pos.order.line:0 msgid "Total qty" -msgstr "Total de Qtd" +msgstr "Qtd Total" #. module: point_of_sale #: model:product.template,name:point_of_sale.fanta_orange_33cl_product_template @@ -460,6 +463,10 @@ msgid "" "close this session, you can update the 'Closing Cash Control' to avoid any " "difference." msgstr "" +"Por favor, defina suas contas de lucros e perdas no seu método de pagamento " +"'%s'. Isso permitirá o OpenERP colocar a diferença de %.2f em seu saldo " +"final. Para fechar a sessão, você pode atualizar o 'Fechando Controle de " +"Caixa'para evitar qualquer diferença." #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:315 @@ -777,7 +784,7 @@ msgstr "Imprimir Relatório" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_bolognese_product_template msgid "Dr. Oetker Ristorante Bolognese" -msgstr "" +msgstr "Dr. Oetker Ristorante Bolognese" #. module: point_of_sale #: model:pos.category,name:point_of_sale.pizza @@ -787,7 +794,7 @@ msgstr "Pizza" #. module: point_of_sale #: view:pos.session:0 msgid "= Theoretical Balance" -msgstr "" +msgstr "= Balanço Teórico" #. module: point_of_sale #: code:addons/point_of_sale/wizard/pos_return.py:85 @@ -974,7 +981,7 @@ msgstr "Lista de Caixas Registradoras" #. module: point_of_sale #: model:product.template,name:point_of_sale.maes_50cl_product_template msgid "Maes 50cl" -msgstr "" +msgstr "Maes 50cl" #. module: point_of_sale #: view:report.pos.order:0 @@ -1030,7 +1037,7 @@ msgstr "Spa Reine 33cl" #. module: point_of_sale #: model:ir.model,name:point_of_sale.model_pos_discount msgid "Add a Global Discount" -msgstr "Adicionar Desconto Global" +msgstr "Adicionar um Desconto Global" #. module: point_of_sale #: view:pos.config:0 @@ -1040,7 +1047,7 @@ msgstr "Diários" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_prosciutto_product_template msgid "Dr. Oetker Ristorante Prosciutto" -msgstr "" +msgstr "Dr. Oetker Ristorante Prosciutto" #. module: point_of_sale #: model:product.template,name:point_of_sale.lays_light_paprika_170g_product_template @@ -1126,7 +1133,7 @@ msgstr "Re-impressão" #. module: point_of_sale #: model:product.template,name:point_of_sale.chimay_bleu_75cl_product_template msgid "Chimay Bleu 75cl" -msgstr "" +msgstr "Chimay Bleu 75cl" #. module: point_of_sale #: report:pos.payment.report.user:0 @@ -1156,7 +1163,7 @@ msgstr "No. de Linhas" #: code:addons/point_of_sale/static/src/xml/pos.xml:89 #, python-format msgid "Disc" -msgstr "Disco" +msgstr "Desc." #. module: point_of_sale #: view:pos.order:0 @@ -1166,7 +1173,7 @@ msgstr "(atualizar)" #. module: point_of_sale #: model:product.template,name:point_of_sale.ijsboerke_vanille_2,5l_product_template msgid "IJsboerke Vanilla 2.5L" -msgstr "" +msgstr "IJsboerke Vanilla 2.5L" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.action_report_pos_details @@ -1177,7 +1184,7 @@ msgstr "Detalhes da Venda" #. module: point_of_sale #: model:product.template,name:point_of_sale.evian_2l_product_template msgid "2L Evian" -msgstr "" +msgstr "2L Evian" #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:373 @@ -1185,7 +1192,7 @@ msgstr "" #: code:addons/point_of_sale/wizard/pos_session_opening.py:34 #, python-format msgid "Start Point Of Sale" -msgstr "" +msgstr "Iniciar Ponto de Venda" #. module: point_of_sale #: model:pos.category,name:point_of_sale.pils @@ -1195,7 +1202,7 @@ msgstr "" #. module: point_of_sale #: help:pos.session,cash_register_balance_end_real:0 msgid "Computed using the cash control lines" -msgstr "" +msgstr "Calculado usando as linhas de controle de caixa" #. module: point_of_sale #: report:all.closed.cashbox.of.the.day:0 @@ -1217,7 +1224,7 @@ msgstr "ABC" #. module: point_of_sale #: model:product.template,name:point_of_sale.ijsboerke_dame_blanche_2,5l_product_template msgid "IJsboerke 2.5L White Lady" -msgstr "" +msgstr "IJsboerke 2.5L White Lady" #. module: point_of_sale #: field:pos.order,lines:0 @@ -1239,7 +1246,7 @@ msgstr "" #: code:addons/point_of_sale/static/src/xml/pos.xml:485 #, python-format msgid "Read Weighting Scale" -msgstr "" +msgstr "Lendo a Balança" #. module: point_of_sale #. openerp-web @@ -1302,7 +1309,7 @@ msgstr "Marcar como Obsoleto" #. module: point_of_sale #: model:product.template,name:point_of_sale.limon_product_template msgid "Stringers" -msgstr "" +msgstr "Limões" #. module: point_of_sale #: field:pos.order,pricelist_id:0 @@ -1369,19 +1376,19 @@ msgstr "Stella Artois 33cl" #. module: point_of_sale #: model:product.template,name:point_of_sale.lays_naturel_300g_product_template msgid "Lays Natural XXL 300g" -msgstr "" +msgstr "Lays Natural XXL 300g" #. module: point_of_sale #. openerp-web #: code:addons/point_of_sale/static/src/xml/pos.xml:479 #, python-format msgid "Scan Item Unrecognized" -msgstr "" +msgstr "item Escaneado não Reconhecido" #. module: point_of_sale #: report:all.closed.cashbox.of.the.day:0 msgid "Today's Closed Cashbox" -msgstr "Fechamento de Caixa do dia" +msgstr "Fechamento de Caixa do Dia" #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:897 @@ -1397,7 +1404,7 @@ msgstr "Fatura Provisória" #. module: point_of_sale #: model:product.template,name:point_of_sale.lays_paprika_oven_150g_product_template msgid "Oven Baked Lays Paprika 150g" -msgstr "" +msgstr "Oven Baked Lays Paprika 150g" #. module: point_of_sale #: report:pos.invoice:0 @@ -1449,7 +1456,7 @@ msgstr "Coca-Cola Light 2L" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_funghi_product_template msgid "Dr. Oetker Ristorante Funghi" -msgstr "" +msgstr "Dr. Oetker Ristorante Funghi" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.pos_category_action @@ -1477,7 +1484,7 @@ msgstr "Ean Inválido" #. module: point_of_sale #: model:product.template,name:point_of_sale.lindemans_kriek_37,5cl_product_template msgid "Lindemans Kriek 37.5cl" -msgstr "" +msgstr "Lindemans Kriek 37.5cl" #. module: point_of_sale #: view:pos.config:0 @@ -1494,7 +1501,7 @@ msgstr "Coca-Cola Zero 33cl" #: code:addons/point_of_sale/static/src/xml/pos.xml:405 #, python-format msgid "ä" -msgstr "" +msgstr "ä" #. module: point_of_sale #: report:pos.invoice:0 @@ -1523,7 +1530,7 @@ msgstr "Desconhecido" #. module: point_of_sale #: field:product.product,income_pdt:0 msgid "Point of Sale Cash In" -msgstr "" +msgstr "Colocar dinheiro no Ponto de Venda" #. module: point_of_sale #. openerp-web @@ -1608,7 +1615,7 @@ msgstr "" #. module: point_of_sale #: model:product.template,name:point_of_sale.boon_framboise_37,5cl_product_template msgid "Boon Framboise 37.5cl" -msgstr "" +msgstr "Boon Framboise 37.5cl" #. module: point_of_sale #: model:ir.model,name:point_of_sale.model_pos_config @@ -1627,7 +1634,7 @@ msgstr "" #. module: point_of_sale #: field:product.product,expense_pdt:0 msgid "Point of Sale Cash Out" -msgstr "" +msgstr "Sacar do Ponto de Venda" #. module: point_of_sale #: selection:report.pos.order,month:0 @@ -1639,7 +1646,7 @@ msgstr "Novembro" #: code:addons/point_of_sale/static/src/xml/pos.xml:267 #, python-format msgid "Please scan an item or your member card" -msgstr "" +msgstr "Por favor escaneie um item ou seu cartão de associado" #. module: point_of_sale #: model:product.template,name:point_of_sale.poivron_verts_product_template @@ -1649,7 +1656,7 @@ msgstr "Pimentões Verdes" #. module: point_of_sale #: model:product.template,name:point_of_sale.timmermans_faro_37,5cl_product_template msgid "Timmermans Faro 37.5cl" -msgstr "" +msgstr "Timmermans Faro 37.5cl" #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:410 @@ -1662,7 +1669,7 @@ msgstr "" #. module: point_of_sale #: view:pos.session:0 msgid "Validate Closing & Post Entries" -msgstr "" +msgstr "Validar Encerramento e Lançar Entradas" #. module: point_of_sale #: field:report.transaction.pos,no_trans:0 @@ -1705,7 +1712,7 @@ msgstr "Cancelar" #: code:addons/point_of_sale/static/src/xml/pos.xml:296 #, python-format msgid "Please put your product on the scale" -msgstr "" +msgstr "Por favor, coloque seu produto na balança" #. module: point_of_sale #: model:ir.actions.report.xml,name:point_of_sale.pos_details_summary @@ -1715,12 +1722,12 @@ msgstr "Vendas(Resumo)" #. module: point_of_sale #: model:product.template,name:point_of_sale.nectarine_product_template msgid "Peach" -msgstr "" +msgstr "Pêssego" #. module: point_of_sale #: model:product.template,name:point_of_sale.timmermans_kriek_37,5cl_product_template msgid "Timmermans Kriek 37.5cl" -msgstr "" +msgstr "Timmermans Kriek 37.5cl" #. module: point_of_sale #: field:pos.config,sequence_id:0 @@ -1753,7 +1760,7 @@ msgstr "fechar" #. module: point_of_sale #: model:ir.actions.report.xml,name:point_of_sale.report_user_label msgid "User Labels" -msgstr "" +msgstr "Etiquetas do Usuário" #. module: point_of_sale #: model:ir.model,name:point_of_sale.model_pos_order_line @@ -1897,6 +1904,9 @@ msgid "" "complete\n" " your purchase" msgstr "" +"Por favor, insira seu cartão no leitor e aguarde as instruções para " +"completar\n" +" sua compra" #. module: point_of_sale #: help:product.product,income_pdt:0 @@ -1935,6 +1945,8 @@ msgid "" "Unable to open the session. You have to assign a sale journal to your point " "of sale." msgstr "" +"Não é possível abrir a sessão. Você tem que atribuir um diário de venda para " +"o seu ponto de venda." #. module: point_of_sale #: view:report.pos.order:0 @@ -1988,7 +2000,7 @@ msgstr "Estabelecimento:" #. module: point_of_sale #: field:account.journal,self_checkout_payment_method:0 msgid "Self Checkout Payment Method" -msgstr "" +msgstr "Forma de Pagamento do Auto Atendimento" #. module: point_of_sale #: view:pos.order:0 @@ -2124,7 +2136,7 @@ msgstr "Produtos" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_4formaggi_product_template msgid "Dr. Oetker Ristorante Quattro Formaggi" -msgstr "" +msgstr "Dr. Oetker Ristorante Quattro Formaggi" #. module: point_of_sale #: model:product.template,name:point_of_sale.croky_naturel_45g_product_template @@ -2654,7 +2666,7 @@ msgstr "Fatura" #: code:addons/point_of_sale/static/src/xml/pos.xml:701 #, python-format msgid "shift" -msgstr "" +msgstr "shift" #. module: point_of_sale #: model:product.template,name:point_of_sale.rochefort_8_33cl_product_template @@ -2786,7 +2798,7 @@ msgstr "Produto" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_pollo_product_template msgid "Dr. Oetker Ristorante Pollo" -msgstr "" +msgstr "Dr. Oetker Ristorante Pollo" #. module: point_of_sale #: constraint:pos.session:0 @@ -2836,7 +2848,7 @@ msgstr "" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_margherita_product_template msgid "Dr. Oetker La Margherita" -msgstr "" +msgstr "Dr. Oetker La Margherita" #. module: point_of_sale #: view:pos.order:0 @@ -2936,7 +2948,7 @@ msgstr "Gerente" #. module: point_of_sale #: model:product.template,name:point_of_sale.lays_poivre_sel_oven_150g_product_template msgid "Lays Salt and Pepper Oven Baked 150g" -msgstr "" +msgstr "Lays Salt and Pepper Oven Baked 150g" #. module: point_of_sale #: field:pos.details,date_start:0 @@ -2993,7 +3005,7 @@ msgstr "Procurar Pedido de Venda" #. module: point_of_sale #: field:pos.config,iface_self_checkout:0 msgid "Self Checkout Mode" -msgstr "" +msgstr "Modo de Auto Atendimento" #. module: point_of_sale #: field:account.journal,journal_user:0 @@ -3027,7 +3039,7 @@ msgstr "Relatório de Pagamento" #. module: point_of_sale #: model:product.template,name:point_of_sale.fanta_orange_25cl_product_template msgid "Fanta Orange 25cl" -msgstr "" +msgstr "Fanta Laranja 25cl" #. module: point_of_sale #: view:pos.confirm:0 @@ -3063,7 +3075,7 @@ msgstr "Motivo" #. module: point_of_sale #: model:product.template,name:point_of_sale.orangina_33cl_product_template msgid "Orangina 33cl" -msgstr "" +msgstr "Orangina 33cl" #. module: point_of_sale #: view:pos.config:0 @@ -3073,7 +3085,7 @@ msgstr "Definir como Inativo" #. module: point_of_sale #: model:product.template,name:point_of_sale.chimay_bleu_33cl_product_template msgid "Chimay Bleu 33cl" -msgstr "" +msgstr "Chimay Bleu 33cl" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.action_account_journal_form @@ -3089,7 +3101,7 @@ msgstr "Fritas" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_spinaci_product_template msgid "Dr. Oetker Ristorante Spinaci" -msgstr "" +msgstr "Dr. Oetker Ristorante Spinaci" #. module: point_of_sale #. openerp-web @@ -3121,7 +3133,7 @@ msgstr "Colocar dinheiro em" #. module: point_of_sale #: model:product.template,name:point_of_sale.fanta_zero_orange_1,5l_product_template msgid "Fanta Orange Zero 1.5L" -msgstr "" +msgstr "Fanta Laranja Zero 1.5L" #. module: point_of_sale #: model:product.template,name:point_of_sale.boni_orange_product_template @@ -3234,7 +3246,7 @@ msgstr "Relatório do PDV" #. module: point_of_sale #: model:product.template,name:point_of_sale.chaudfontaine_1,5l_product_template msgid "Chaudfontaine 1.5l" -msgstr "" +msgstr "Chaudfontaine 1.5l" #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:1069 @@ -3304,7 +3316,7 @@ msgstr "Coca-Cola Zero 50cl" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_tonno_product_template msgid "Dr. Oetker Ristorante Tonno" -msgstr "" +msgstr "Dr. Oetker Ristorante Tonno" #. module: point_of_sale #: report:pos.invoice:0 @@ -3346,7 +3358,7 @@ msgstr "cash.box.out" #. module: point_of_sale #: model:product.template,name:point_of_sale.fanta_zero_orange_33cl_product_template msgid "Fanta Zero Orange 33cl" -msgstr "" +msgstr "Fanta Laranja Zero 33cl" #. module: point_of_sale #: help:product.product,available_in_pos:0 @@ -3361,7 +3373,7 @@ msgstr "Dia da data do pedido" #. module: point_of_sale #: model:product.template,name:point_of_sale.maes_33cl_product_template msgid "Maes 33cl" -msgstr "" +msgstr "Maes 33cl" #. module: point_of_sale #. openerp-web @@ -3378,7 +3390,7 @@ msgstr "Configuração" #. module: point_of_sale #: model:product.template,name:point_of_sale.orval_33cl_product_template msgid "Orval 33cl" -msgstr "" +msgstr "Orval 33cl" #. module: point_of_sale #. openerp-web @@ -3411,7 +3423,7 @@ msgstr "Frutas Frescas" #. module: point_of_sale #: model:product.template,name:point_of_sale.lindemans_pecheresse_37,,5cl_product_template msgid "Lindemans sinful 37.5cl" -msgstr "" +msgstr "Lindemans sinful 37.5cl" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.action_pos_invoice @@ -3431,7 +3443,7 @@ msgstr "Imagem" #. module: point_of_sale #: model:product.template,name:point_of_sale.spa_gazeuse_1,5l_product_template msgid "Spa Barisart 1.5l" -msgstr "" +msgstr "Spa Barisart 1.5l" #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:789 @@ -3443,7 +3455,7 @@ msgstr "Retornar Produtos" #. module: point_of_sale #: model:product.template,name:point_of_sale.jupiler_33cl_product_template msgid "Jupiler 33cl" -msgstr "" +msgstr "Jupiler 33cl" #. module: point_of_sale #. openerp-web @@ -3551,7 +3563,7 @@ msgstr "Balança Eletrônica" #. module: point_of_sale #: model:product.template,name:point_of_sale.spa_gazeuse_50cl_product_template msgid "Spa Barisart 50cl" -msgstr "" +msgstr "Spa Barisart 50cl" #. module: point_of_sale #: field:res.users,pos_config:0 @@ -3595,7 +3607,7 @@ msgstr "Pago" #: code:addons/point_of_sale/static/src/xml/pos.xml:464 #, python-format msgid "3.141Kg Oranges" -msgstr "" +msgstr "3.141Kg de Laranjas" #. module: point_of_sale #: report:pos.invoice:0 @@ -3611,7 +3623,7 @@ msgstr "Por favor informe um parceiro para a venda" #. module: point_of_sale #: model:pos.category,name:point_of_sale.fruity_beers msgid "Fruity Beers" -msgstr "" +msgstr "Cerveja de Frutas" #. module: point_of_sale #: view:pos.session:0 @@ -3623,7 +3635,7 @@ msgstr "" #: code:addons/point_of_sale/static/src/xml/pos.xml:463 #, python-format msgid "Soda 33cl" -msgstr "" +msgstr "Soda 33cl" #. module: point_of_sale #: help:pos.session,cash_register_balance_start:0 @@ -3644,7 +3656,7 @@ msgstr "Vendas do Usuário" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_hawaii_product_template msgid "Dr. Oetker Ristorante Hawaii" -msgstr "" +msgstr "Dr. Oetker Ristorante Hawaii" #. module: point_of_sale #. openerp-web @@ -3678,12 +3690,12 @@ msgstr "" #. module: point_of_sale #: model:product.template,name:point_of_sale.chaudfontaine_petillante_33cl_product_template msgid "Chaudfontaine Petillante 33cl" -msgstr "" +msgstr "Chaudfontaine Petillante 33cl" #. module: point_of_sale #: model:product.template,name:point_of_sale.pepsi_max_2l_product_template msgid "Pepsi Max 2L" -msgstr "" +msgstr "Pepsi Max 2L" #. module: point_of_sale #: field:pos.session,details_ids:0 @@ -3693,17 +3705,17 @@ msgstr "Controle de Caixa" #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_vegetale_product_template msgid "Dr. Oetker Ristorante Vegetable" -msgstr "" +msgstr "Dr. Oetker Ristorante Vegetable" #. module: point_of_sale #: model:pos.category,name:point_of_sale.soda msgid "Soda" -msgstr "" +msgstr "Soda" #. module: point_of_sale #: model:product.template,name:point_of_sale.lays_paprika_300g_product_template msgid "Lays Paprika XXL 300g" -msgstr "" +msgstr "Lays Paprika XXL 300g" #. module: point_of_sale #: report:pos.invoice:0 @@ -3715,7 +3727,7 @@ msgstr "Reembolso" #: code:addons/point_of_sale/static/src/xml/pos.xml:417 #, python-format msgid "Your shopping cart is empty" -msgstr "" +msgstr "Seu Carrinho de Compras está vazio" #. module: point_of_sale #: code:addons/point_of_sale/report/pos_invoice.py:46 @@ -3726,7 +3738,7 @@ msgstr "Por favor crie uma fatura para esta venda." #. module: point_of_sale #: model:product.template,name:point_of_sale.oetker_mozzarella_product_template msgid "Dr. Oetker Ristorante Mozzarella" -msgstr "" +msgstr "Dr. Oetker Ristorante Mozzarella" #. module: point_of_sale #: report:pos.details:0 @@ -3737,7 +3749,7 @@ msgstr "Desc(%)" #. module: point_of_sale #: view:pos.session.opening:0 msgid "The session" -msgstr "" +msgstr "A sessão" #. module: point_of_sale #: view:pos.order:0 @@ -3762,7 +3774,7 @@ msgstr "Ordem de Linhas" #. module: point_of_sale #: view:pos.session.opening:0 msgid "PoS Session Opening" -msgstr "" +msgstr "Abrindo Sessão do PDV" #. module: point_of_sale #: field:pos.order.line,price_subtotal:0 @@ -3780,7 +3792,7 @@ msgstr "excluir" #. module: point_of_sale #: model:product.template,name:point_of_sale.spa_50cl_product_template msgid "Spa Reine 50cl" -msgstr "" +msgstr "Spa Reine 50cl" #. module: point_of_sale #: model:product.template,name:point_of_sale.chicon_flandria_extra_product_template @@ -3791,22 +3803,22 @@ msgstr "" #: model:product.template,name:point_of_sale.lays_light_naturel_170g_product_template #: model:product.template,name:point_of_sale.lays_naturel_170g_product_template msgid "Lays Natural Light 170g" -msgstr "" +msgstr "Lays Natural Light 170g" #. module: point_of_sale #: model:product.template,name:point_of_sale.leffe_blonde_33cl_product_template msgid "Leffe Blonde 33cl" -msgstr "" +msgstr "Leffe Blonde 33cl" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.action_report_pos_payment msgid "Pyament Report" -msgstr "" +msgstr "Relatório de Pagamento" #. module: point_of_sale #: field:report.transaction.pos,jl_id:0 msgid "Cash Journals" -msgstr "" +msgstr "Diários de Dinheiro" #. module: point_of_sale #: view:pos.session:0 @@ -3816,12 +3828,12 @@ msgstr "Sessão:" #. module: point_of_sale #: field:pos.config,iface_print_via_proxy:0 msgid "Print via Proxy" -msgstr "" +msgstr "Imprimir via Proxy" #. module: point_of_sale #: report:pos.sales.user.today:0 msgid "Today's Sales By User" -msgstr "" +msgstr "Vendas de hoje por Usuário" #. module: point_of_sale #: report:pos.invoice:0 @@ -3858,7 +3870,7 @@ msgstr "Anotações Internas" #. module: point_of_sale #: model:product.template,name:point_of_sale.ijsboerke_chocolat_2,5l_product_template msgid "IJsboerke Chocolat 2.5L" -msgstr "" +msgstr "IJsboerke Chocolat 2.5L" #. module: point_of_sale #: help:pos.category,image_small:0 @@ -3871,7 +3883,7 @@ msgstr "" #. module: point_of_sale #: field:pos.session.opening,pos_state:0 msgid "Session Status" -msgstr "" +msgstr "Status da Sessão" #. module: point_of_sale #: field:pos.order,picking_id:0 @@ -3915,7 +3927,7 @@ msgstr "Editar" #. module: point_of_sale #: view:pos.session.opening:0 msgid "Click to continue the session." -msgstr "" +msgstr "Clique para continuar a sessão." #. module: point_of_sale #: view:pos.config:0 @@ -3930,7 +3942,7 @@ msgstr "" #. module: point_of_sale #: view:pos.session.opening:0 msgid "Start Selling" -msgstr "" +msgstr "Começar a Vender" #. module: point_of_sale #: selection:report.pos.order,month:0 @@ -3963,7 +3975,7 @@ msgstr "" #. module: point_of_sale #: model:product.template,name:point_of_sale.leffe_9_33cl_product_template msgid "Leffe Brune \"9\" 33cl" -msgstr "" +msgstr "Leffe Brune \"9\" 33cl" #. module: point_of_sale #: help:account.journal,journal_user:0 @@ -4011,7 +4023,7 @@ msgstr "" #: code:addons/point_of_sale/static/src/xml/pos.xml:351 #, python-format msgid "Sorry, we could not create a session for this user." -msgstr "" +msgstr "Desculpe, não podemos criar uma sessão para esse usuário." #. module: point_of_sale #: code:addons/point_of_sale/point_of_sale.py:98 @@ -4019,7 +4031,7 @@ msgstr "" #: selection:pos.session.opening,pos_state:0 #, python-format msgid "Opening Control" -msgstr "" +msgstr "Abrindo Controle" #. module: point_of_sale #: view:report.pos.order:0 diff --git a/addons/point_of_sale/i18n/zh_CN.po b/addons/point_of_sale/i18n/zh_CN.po index e4d914ae56e..23dc97f2376 100644 --- a/addons/point_of_sale/i18n/zh_CN.po +++ b/addons/point_of_sale/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2012-05-10 18:26+0000\n" -"Last-Translator: 开阖软件 Jeff Wang \n" +"PO-Revision-Date: 2013-04-24 06:41+0000\n" +"Last-Translator: viney \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: 2013-03-16 05:07+0000\n" -"X-Generator: Launchpad (build 16532)\n" +"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n" +"X-Generator: Launchpad (build 16580)\n" #. module: point_of_sale #: field:report.transaction.pos,product_nb:0 @@ -67,7 +67,7 @@ msgstr "" #. module: point_of_sale #: model:pos.category,name:point_of_sale.plain_water msgid "Plain Water" -msgstr "白开水" +msgstr "纯净水" #. module: point_of_sale #: model:product.template,name:point_of_sale.poire_conference_product_template @@ -2269,7 +2269,7 @@ msgstr "7月" #: model:ir.ui.menu,name:point_of_sale.menu_pos_config_pos #: view:pos.session:0 msgid "Point of Sales" -msgstr "" +msgstr "零售" #. module: point_of_sale #: report:pos.details:0 @@ -2303,7 +2303,7 @@ msgstr "打印数" #. module: point_of_sale #: model:ir.model,name:point_of_sale.model_pos_make_payment msgid "Point of Sale Payment" -msgstr "POS付款" +msgstr "付款" #. module: point_of_sale #: model:product.template,name:point_of_sale.coca_light_50cl_product_template @@ -2407,7 +2407,7 @@ msgstr "" #. module: point_of_sale #: model:ir.model,name:point_of_sale.model_pos_receipt msgid "Point of sale receipt" -msgstr "POS收银条" +msgstr "收银条" #. module: point_of_sale #: model:ir.actions.act_window,name:point_of_sale.action_report_sales_by_margin_pos_today diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 7e8487b2b2b..349ad8b4f81 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -50,7 +50,7 @@ class pos_config(osv.osv): required=True, help="An internal identification of the point of sale"), 'journal_ids' : fields.many2many('account.journal', 'pos_config_journal_rel', 'pos_config_id', 'journal_id', 'Available Payment Methods', - domain="[('journal_user', '=', True )]",), + domain="[('journal_user', '=', True ), ('type', 'in', ['bank', 'cash'])]",), 'shop_id' : fields.many2one('sale.shop', 'Shop', required=True), 'journal_id' : fields.many2one('account.journal', 'Sale Journal', @@ -408,6 +408,9 @@ class pos_session(osv.osv): if not self.pool.get('ir.model.access').check_groups(cr, uid, "point_of_sale.group_pos_manager"): raise osv.except_osv( _('Error!'), _("Your ending balance is too different from the theorical cash closing (%.2f), the maximum allowed is: %.2f. You can contact your manager to force it.") % (st.difference, st.journal_id.amount_authorized_diff)) + if (st.journal_id.type not in ['bank', 'cash']): + raise osv.except_osv(_('Error!'), + _("The type of the journal for your payment method should be bank or cash ")) if st.difference and st.journal_id.cash_control == True: if st.difference > 0.0: name= _('Point of Sale Profit') @@ -428,7 +431,6 @@ class pos_session(osv.osv): if st.journal_id.type == 'bank': st.write({'balance_end_real' : st.balance_end}) - getattr(st, 'button_confirm_%s' % st.journal_id.type)(context=context) self._confirm_orders(cr, uid, ids, context=context) self.write(cr, uid, ids, {'state' : 'closed'}, context=context) @@ -522,6 +524,24 @@ class pos_order(osv.osv): self.signal_paid(cr, uid, [order_id]) return order_ids + def write(self, cr, uid, ids, vals, context=None): + res = super(pos_order, self).write(cr, uid, ids, vals, context=context) + #If you change the partner of the PoS order, change also the partner of the associated bank statement lines + partner_obj = self.pool.get('res.partner') + bsl_obj = self.pool.get("account.bank.statement.line") + if 'partner_id' in vals: + for posorder in self.browse(cr, uid, ids, context=context): + if posorder.invoice_id: + raise osv.except_osv( _('Error!'), _("You cannot change the partner of a POS order for which an invoice has already been issued.")) + if vals['partner_id']: + p_id = partner_obj.browse(cr, uid, vals['partner_id'], context=context) + part_id = partner_obj._find_accounting_partner(p_id).id + else: + part_id = False + bsl_ids = [x.id for x in posorder.statement_ids] + bsl_obj.write(cr, uid, bsl_ids, {'partner_id': part_id}, context=context) + return res + def unlink(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): if rec.state not in ('draft','cancel'): @@ -886,6 +906,7 @@ class pos_order(osv.osv): account_tax_obj = self.pool.get('account.tax') user_proxy = self.pool.get('res.users') property_obj = self.pool.get('ir.property') + cur_obj = self.pool.get('res.currency') period = account_period_obj.find(cr, uid, context=context)[0] @@ -948,9 +969,9 @@ class pos_order(osv.osv): }) if data_type == 'product': - key = ('product', values['product_id'],) + key = ('product', values['partner_id'], values['product_id']) elif data_type == 'tax': - key = ('tax', values['tax_code_id'],) + key = ('tax', values['partner_id'], values['tax_code_id'],) elif data_type == 'counter_part': key = ('counter_part', values['partner_id'], values['account_id']) else: @@ -981,17 +1002,19 @@ class pos_order(osv.osv): #TOFIX: a deep refactoring of this method (and class!) is needed in order to get rid of this stupid hack assert order.lines, _('The POS order must have lines when calling this method') # Create an move for each order line + + cur = order.pricelist_id.currency_id for line in order.lines: tax_amount = 0 taxes = [t for t in line.product_id.taxes_id] computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit * (100.0-line.discount) / 100.0, line.qty)['taxes'] for tax in computed_taxes: - tax_amount += round(tax['amount'], 2) + tax_amount += cur_obj.round(cr, uid, cur, tax['amount']) group_key = (tax['tax_code_id'], tax['base_code_id'], tax['account_collected_id'], tax['id']) group_tax.setdefault(group_key, 0) - group_tax[group_key] += round(tax['amount'], 2) + group_tax[group_key] += cur_obj.round(cr, uid, cur, tax['amount']) amount = line.price_subtotal @@ -1026,7 +1049,7 @@ class pos_order(osv.osv): 'debit': ((amount<0) and -amount) or 0.0, 'tax_code_id': tax_code_id, 'tax_amount': tax_amount, - 'partner_id': order.partner_id and order.partner_id.id or False + 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False }) # For each remaining tax with a code, whe create a move line @@ -1044,6 +1067,7 @@ class pos_order(osv.osv): 'debit': 0.0, 'tax_code_id': tax_code_id, 'tax_amount': tax_amount, + 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False }) # Create a move for each tax group @@ -1060,6 +1084,7 @@ class pos_order(osv.osv): 'debit': ((tax_amount<0) and -tax_amount) or 0.0, 'tax_code_id': key[tax_code_pos], 'tax_amount': tax_amount, + 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False }) # counterpart @@ -1068,14 +1093,17 @@ class pos_order(osv.osv): 'account_id': order_account, 'credit': ((order.amount_total < 0) and -order.amount_total) or 0.0, 'debit': ((order.amount_total > 0) and order.amount_total) or 0.0, - 'partner_id': order.partner_id and order.partner_id.id or False + 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False }) order.write({'state':'done', 'account_move': move_id}) + all_lines = [] for group_key, group_data in grouped_data.iteritems(): for value in group_data: - account_move_line_obj.create(cr, uid, value, context=context) + all_lines.append((0, 0, value),) + if move_id: #In case no order was changed + self.pool.get("account.move").write(cr, uid, [move_id], {'line_id':all_lines}, context=context) return True @@ -1103,7 +1131,6 @@ class account_bank_statement(osv.osv): _defaults = { 'user_id': lambda self,cr,uid,c={}: uid } -account_bank_statement() class account_bank_statement_line(osv.osv): _inherit = 'account.bank.statement.line' @@ -1111,7 +1138,6 @@ class account_bank_statement_line(osv.osv): 'pos_statement_id': fields.many2one('pos.order', ondelete='cascade'), } -account_bank_statement_line() class pos_order_line(osv.osv): _name = "pos.order.line" @@ -1279,7 +1305,7 @@ class ean_wizard(osv.osv_memory): ean13 = openerp.addons.product.product.sanitize_ean13(r.ean13_pattern) m = context.get('active_model') m_id = context.get('active_id') - self.pool.get(m).write(cr,uid,[m_id],{'ean13':ean13}) + self.pool[m].write(cr,uid,[m_id],{'ean13':ean13}) return { 'type' : 'ir.actions.act_window_close' } class product_product(osv.osv): diff --git a/addons/point_of_sale/point_of_sale_demo.xml b/addons/point_of_sale/point_of_sale_demo.xml index 011c6d81bfc..1c61218a4cb 100644 --- a/addons/point_of_sale/point_of_sale_demo.xml +++ b/addons/point_of_sale/point_of_sale_demo.xml @@ -430,6 +430,7 @@ True 1.49 Coca-Cola Regular 1L + 5449000054227 /9j/4AAQSkZJRgABAAEBLAEsAAD/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9PjsBCwoKDg0OHBYWHCgoKCgoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAGQAIgMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APZqYHHfEPXNS0W3sjp0zRGUvvKqD0246g+tc+InKNrHqZVhaVdy5+ljlPCfjPxBf65aW1xevLFJOqOCi8gn6cVnGrPnSPRxuW4elRlJLWx65XWfNENusizXJcMFaUFMngjYo4+Y8ZB7L34/iKW7NKjTjG3b9X5L9fXopqozMPX9Kt9YvtPtp9+AZHbbj7oA9fcrUyipbmtGvOldxdjPPhPS9G1PT7q2EiKbkK3Ixkqdp4H97ApKnFO9jWpja1SNpSOsqzlCgAoArwx77mS6JyGUJH7KOSfxP8hSAW9thd2rRZ2tkMjf3WByp/AgUASROZIwxG1v4l9D3FAD6YHLeN/FqeHFsLSMj7VqMxRSULhEAyzFQRnqB17+1IaKUnjCyaBmHiSOHaMk+SqY/wC+gaGmBHY+NLCWUr/wlUE5AztAjb/0FaSuN2J7PxvAfFNnpj3Kzw3yskcyxFMSDkAknnIyBxT2EdnTEeQ/EzzW8eRSNG7Rw6avl4GQCXbd+PSlzJM1jRqShzJNo4TVZlawmRchihzuBH86pmRz+hXH2bUN57rjHryKSA7RLl7i805rdJfNivoJI2CHghx/TNKTRpCnOeyufQtMzPMvH8ck3jWyjQqubQl2Y4CqNxJPsAP0rlrrmkkfSZI4xw1RvuvvOQ1jRb2S58mGzmmQkKD5RBZiM4xzyKy5ZR0R69OthpQvNxKFt4fZIvtV1ss4wCy7kyzD1A9O2TjJ49cP3t2yFKgp8sIJv5HQabZJb+INMiNys7M+4IsZXCkcE5789O1OEUpIxxc+fC1Go2S8/P8AI9rrtPjThvFMFtc+Kmha4SC+axQ2pkfarne+VyQQD909OcVhUScj2MvlOFHmSvHm1t6b/mcnfalqOk2k8F9ptxb3e3y0meMMm3LHgjA6uemRwOOKxcnFao9inh6NealCacd7Xs+nr28iD/hINMnu/Mj0ySaNGjWNTCPljHDLwTzjAB7jPAycnPG+wLA1oxs5pb9evQ07RpNV8R6fcxyQxrEwHkyTqZXy3zPtHT6HFVH3pI5sRy0MJOLTd+ttF2V2epW/2jz7rzs+X5o8jgfc2Lnp/tbuvP4YrojzXd++n3L9bnztTk5Ycu9tfW7/AEtt+Z458X9Xaw8ZRwTQxvFLYIUZs5U73yQR9KmpT5zuy7M3hNLO1+hx8fim5ih2pqF1GmMbUnOPyBrH2NRdT2f7Wy+erhr5pFV9eS4bDzyyn/bJP86n2M2aRznBw2/I2YPFLat4u0JIIFidbi3t9qvnOJBzxxznpWypu6b6Hj1MypqjOnFN8zbu/P7z6Lrc8c8S/aBtNuoaLegf6yKWIn/dKkf+hGkB5ZkGIY9KBobH1pgdJ8NLM6h8SdJTGRHMZT7bFLD9QKQj6epgeQftAzxCy0W3JBmMkrj2UBQf1I/KkB44n+pH0oGgi5NAHafBiWKL4jQLKQGkglVM/wB7Gf5A0CPo6mB4P8ab42/jy286FZol09Aqt2y75IpDOEuZ7CaycwwBJCOMKP6UwKWnNCs5NwhdMdMZ7ikgOi8J3UMnjrQ/sNsIdt/EC4PJBYAj8iaGB9PUxHkXx50Ca4srDXYI2cWxaCcgZ2q3Kk+2cj8RSYHj39najb6d/aD2c62bSeWJmjIRm54DdCeDQncbTTG2lle6iJhY2k0/kx+ZL5SFiq5AycdByKLgdr8H9BuNS8ZwXJhb7PYjzpHK8A4+UZ9SSD9AaSdxuLW59F1RIjKrqVdQykYIIyDQBR1nRNP13SJdL1C3EtrKACg4xjkEEdCKTApeGPBuieEYpk0i2MZuGBkd3LscdBk9vb3oSA2Y4YoQwijSPcdzbVAyfU0wH0AA/9k= @@ -716,6 +717,7 @@ True 0.44 + 5449000111715 Chaudfontaine 50cl /9j/4AAQSkZJRgABAAEBLAEsAAD/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9PjsBCwoKDg0OHBYWHCgoKCgoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAGQAJAMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APZqYHnfj34gaj4a1xdPtYU8vyVkLkckkn1+ld2EwsKsbswq1XF2Oa/4XBqwmUxwqVHVWAwf6/rXQ8DTSIVeVz2KxuGurC3uGXa0sSuR6EjNeVJWbR0rYnpDCgDjvFfhCw8Qaul1PJIJEiEeF6dSR05712Yau6cLW6nLXg5S0ZjS/DLS127pJl7jk5/Umt/rjfQy9jJPc9Ht0WK3jjQ5VVAB9gK8x7neh9AEVxN5SD1PApxVxN2M6Kzja5EsjMxJyd2TWzm7GSpJu5NfWkE6qehHGRkVMJtDnTUh1o/kAQlmYE8Fj0pT11Kh7uheFZllG/fFzChHBBOffitILRkyeqEQ9xxTAVizD5jxRawEEj7GTC7jvUYzzyadrkt2NWsTQp34O6I4yMkGrh1JkInTjiqBDj065pAQMf38YC/xin0F1NIVkWUdVuBbQxOy5UyYJ/u8HmtKUeZsipLlRQj1WFpBGJV3HoCwAP0zWrpSS2M1VVy5HOZc8AAdwwNQ1YtSuRifddQBFMgdyCw6LgHn9KbjowUtUaorA0KGsqr2O1hkFhWtF+8Z1fhOM8Q38+lWEUtoUWR5QnIz8pB/wr08LSjVk1LscdRuK0LHhi9uzqd7b3dzHMsUalWRcA5J/wAKjFwhyRcVbU0otxk02dJFJvvIdvIyc4PHSuGStFnRF3ZrVgaFLVl3WWP9qtKPxGdX4Th/Elk11p8fzJEsEnms7HBAAPAHfqK9TCVFGb63VjkqQukL4fkeTxDqIJP3IhyMdvTJ/nRiElRh8xxbdRnWWg/02PA9ea86psdNPc2KwNSrqS7rNuM4NXS+Iip8JwvimSKKxhMi7gJRhcZ5wSMj0yK9XBpuTt2OOrbQk8NKy+JNRXbjbHFngZ6Z55NTiv4EPVl0v4jOsgx9uiA9D0rz5fCzoW5qViaFe9lSKEbj944qoK7Jk0jkvFGmTahZW4trbzylwruowCVwc9cZ/OvQwdZU5O7toc1aDklZdSPwxp99aahfXN5bvH5qxhS5zkgHOOTxVYurCUIqL2uFGMlJto6W3KLex5IBOQAK4ZX5WbppM1KxNDP1faYUDlQuTkscCtKZnUa6meiyKoUF9o7A5qxaj2LqNyll/wA+9AbDLfbFfRscb5HHfJNNq8WSnaR0Fc5uVdRhaa3wq7sHp61dN2ZM1dGBftLDAipByuemRg4rqppNnJVbtYjmYyuskI81VOMEkD8hjNacqWj0MeZ3utTWsIJXlVzEyqDksx61y1Gl1Oyld62NesDcOtAAQD1FAAFA6AUBYKACgAD/2Q== @@ -830,6 +832,7 @@ True 0.77 + 5410228142027 Jupiler 33cl /9j/4AAQSkZJRgABAAEBLAEsAAD/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9PjsBCwoKDg0OHBYWHCgoKCgoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAGQAPQMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APZqYGdqet2+myJE6tJK4yFXgAepNACJqrPD5reTEvbc+aVwKU2vyR7mDx7FOCxUj+dMC3Z61bzxF5LuFAOu4hcfnQBZmv444fNSSKVc4+Vuv40gH2l7Hdq20FXX7yt1FMCduq/X+hrCs7Tp6/a/9tf9df1TXUWtxHlnjvxjFDrotYbWG6jiUBw5Iyc+oNc1XEckrI9vA5OsRS5pNrsT6ZrM2q2izw6LdqgGP9HuQR+RIq41m1sYYjK1Slb2i+af/BM+58UwaTcukkWqW7scssipyfzxSdeK3TFDJ681eLi/n/wCH/hOLa/22wtbmY9gIkGfxzmhYiL2uOWT14q7cV/XoQax4pvbWJ3fT3O8/wDLWXp+A/xode3QKWVqb1kbPwv8YG/1G6sL3y0lmw0RGecdsk06VXm3IxuCVGKcT05vvJ9f6GprtKdP/F/7bLz/AM/TqvPWzKmsySQ6PdyRNtdYjg1tLYuik6kU+58838N4buSW5Us7sSWHIry5KV9T7yg6fIlE9M8JXsen+H4kKHcFy2EJH5gV2UmlE+fzCnKdZtHCeM9QF/rDPECwAxjpzWNWze56GB56VKzgzM0afyNRjlcbcHpmpgkpbmuIc50n7up0Wul9TtnjghZnK/KAh6/lW7SaPLp88HrZfMx9K8O+ILO4g1EW0losci/vJPl6kDp170owknew8RiqDg4tpu3Q+homZoYWJySASfXitat+aFv5v/bX56/j3t1Xz3cr60M6Ld/9cjWstmXQ/iR9TxS6P71vrXDI+upbGTqSkBJF4PQkVnJaHXRe6MwmoNGy3owDa7YqwyDcICD3+YVrRXvo4ce2qEj2Hw8Uj8L6YzFUBtYuTxztFejT+Beh8ljP48/8T/Mi190bTmQMCyzRbh6fOKU/hIpb/I7WH/UQf7o/lWVX46f+L/21+f8An6dVK6kGsDOkXQ/6ZGtpbF0vjXqeXaZ4f1K71CC7TTftNoJfnDFQrKDg9T9a5I05N3sfQVcZShTceazsdhqWhaBoqTakdKNwXQQpaxoH3seyqe5/kK6lSgnseJLHYiUbOTOZ8PQ21zo+owaX4PvLO8jjkMU2pxKMyH7qhm5wM+nQeppRpQjsgqY7EVLc02YGl/D3xDY6nZzSwR+XDKjM3nKTgEZNYRoz57nq1cwoPDezTbdkburo1z8MrAQW0106Jb/u4SQxKldwyBkdDz2rpirRR4uIkp1pNbNsWHUtW1Pw9LcarZRWZNxH5KRybyU3DknJ759OlKfwip7v0PUIR+4i/wB0fyqZptxt3/R+a/X06qSDVf8AkFXX/XI/yq5bFU/jXqeY6tPdJHYQQ3j2sCWrSyuHKqo8x8scdew9+BXM1JtJHuUp0qcJzmk9f0RVXSfEGsWC3OnWV89rIuY557tAz88OEJ4/M8d619k0tGcX1+M5WcUtdLLb17nHajNr2l3T292buKVeShmYE/nXLKLT1bR7sainDmjTjJeVv1sbPgDWLyfxbaRS3VwyP5iPHJITg7CeQT64rSkpRqJNnBjJUK+EnKEbNNdLNanRatb3E3w/ms4LaW4KX8kbwxEgui3DZGe3A611vY+e6lLw1Hcx+D5Eu3jEsd1FGIo5Ffy1XbgEgnBPJx71MvhNIbv0PYoT+4i91H8qUpNOPm/0ZJDqn/ILuf8Ark38qp7Dh8SPJ/EsTXel2VvE+17tUtwScLxLITk+nCn8Kzprr5HbjJWjy/3r/gjF/wCElN5pVroOq2Yc2JKQXK3PkFAOMHPB6Y5x0FanCVNZ8aXceiadp+o6ba3v+jbkmuA/nINzAHII4KhSCRzU1KfMjpweKeHldX+T/wCAxvw/lF740tLhE27mAK5zjbERn8cGs7WlFHWqiqUa89rtafM3NY0qLUXurlrPUrsxySukMEmyJs3Eg5O089z7YrZnlFvQ7c23hSbdY21mjXiYjgm80nkZ3NuPze3H0qJfCaQ+J+h69EMwxc9FB/SpnTcpRd9nf8GvluRfcS72/ZJdy7l2HK+taivY8f8AEjJNbQadE2xlvrhY+efu/uxn/eJH41nT6rzO3Gp+4+8UcncPZalCj30/2K8OS8phJSYdmOOQ3XoMHj3NaI4zIuYF1rWb+5UMIHaTyAeMsQxjTH0XAHtincVjp/hParFqF5qk3ENjAzsfQ4I/kT+VRb3jojLloyXdr/M63V4vtPw8s4xazXLS+TI0UOdzksGb6ZyeardGEo8smjI0611Kz0+7VtOj0/TmuIylv5xkkWT5Ov1HPOOtRPYunu/Q9oh/1Ef+6P5VZmNu/wDj0lz/AHDQB5JNHZ3Pis219lYnaZRMT/qpXOFb8MD8zWF46q+7PWUKzcJqN1GK+fcxNa0ud/EHkajClvDZKwIUZLrlm4Hc/Mfr+NNztp1M44duXtOW8fLr8vzMfyZ7283xwt9onYBIkB+QfwoBWdWbbsj08twsKdN1Zqzf4I7O/wDJ8MaTa6CRG2papKkt+V7LkcH3OMe/zHvW6fKknueNVjGtVnOCtFFzUvL/AOEBsvOe8SPyoQfsY/eNwOBVR+FHPW/iS9WZ+nW32XwpdqlhcWSNfRskdy2ZCMKMngdSD2qanwhT3foewwf6iP8A3R/KrM2Nuji0lPohoA8W17jVrv8A67P/AOhGuGp8TPrcD/Bj6I1LTV9L1uyjsPEJaOWJdsN8n3gPRvX/AD9auMozVpfec1bD1cPJzo6p7x/yIZfEPh7w0jjw7aSXt8wx9ruV+VPp0P5AfWrUqdPY55Ucbi/j91djlbFp9R8R29xeytLLNcKXYnk81EZ80zorYRUsO0tEdwNF1XVf7Nt4dWudP08aZE2Lfgu/RhnIxwR611Q+Feh4GI0qy9WR3nhyPw/bTrbSTSQTmAs0r7maQO2SfwIqanwipbv0PUrf/j2i/wBwfyqzNjpE3xsp/iGKAPHfEqyWus3aXNu2Gkcpu9CSQQT1riqpqTPp8DaVGPK+xjEQvKRuKR46kZNZna3NR7spSQQszE3IHJH3fyoKdSaXwk2kRxrq1kwlDN56ZXB45q6fxI5cbKToyTX9XPXNGH/Eh0//AK9Y/wD0EV2w+FHzGJ/jT/xP8yvr1jcajZx2tsm+Rpk/AZ5NE1dEUmk36HXRp5capnO0AZpkjqAKt/p1tqEJjuIY5R6SKGFJpMuFSUHeLaOUvvAmkuWJtJ4Ae9vJkfrmsnRh2O2nmuIj1T9TDn+H+kBj/p92nsyg/wBKn2MfM6Fndb+VDLXwZpFldxXC3t5K8ThgoQDJH4U404p31M6+bVasHFxSudbYwXn2WG1tLORYoY1jWS5O3gDAPv8AhWqemh5s5OcnJ9Wb9naC1j+Zt8h+82MfkPSqJLFABQAUAFAAQD1GaACgAoAKACgA/9k= diff --git a/addons/point_of_sale/report/pos_order_report.py b/addons/point_of_sale/report/pos_order_report.py index 62250f11e17..f4df5f0f5f6 100644 --- a/addons/point_of_sale/report/pos_order_report.py +++ b/addons/point_of_sale/report/pos_order_report.py @@ -84,6 +84,5 @@ class pos_order_report(osv.osv): having sum(l.qty * u.factor) != 0)""") -pos_order_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_receipt.py b/addons/point_of_sale/report/pos_receipt.py index 6272de95db7..bc9d1853f5b 100644 --- a/addons/point_of_sale/report/pos_receipt.py +++ b/addons/point_of_sale/report/pos_receipt.py @@ -21,7 +21,6 @@ import time from openerp.report import report_sxw -from openerp import pooler def titlize(journal_name): words = journal_name.split() @@ -34,7 +33,7 @@ class order(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): super(order, self).__init__(cr, uid, name, context=context) - user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid, context=context) + user = self.pool['res.users'].browse(cr, uid, uid, context=context) partner = user.company_id.partner_id self.localcontext.update({ diff --git a/addons/point_of_sale/report/pos_report.py b/addons/point_of_sale/report/pos_report.py index f0dbcfcad88..96b056fb0fc 100644 --- a/addons/point_of_sale/report/pos_report.py +++ b/addons/point_of_sale/report/pos_report.py @@ -21,7 +21,6 @@ from openerp.osv import fields, osv import time -from openerp import netsvc from openerp import tools class report_transaction_pos(osv.osv): @@ -75,7 +74,6 @@ class report_transaction_pos(osv.osv): """) #to_char(date_trunc('day',absl.create_date),'YYYY-MM-DD') #to_char(date_trunc('day',absl.create_date),'YYYY-MM-DD')::text as date_create, -report_transaction_pos() class report_sales_by_user_pos(osv.osv): _name = "report.sales.by.user.pos" @@ -108,7 +106,6 @@ class report_sales_by_user_pos(osv.osv): ) """) -report_sales_by_user_pos() class report_sales_by_user_pos_month(osv.osv): _name = "report.sales.by.user.pos.month" @@ -141,7 +138,6 @@ class report_sales_by_user_pos_month(osv.osv): ) """) -report_sales_by_user_pos_month() class report_sales_by_margin_pos(osv.osv): _name = "report.sales.by.margin.pos" @@ -188,7 +184,6 @@ class report_sales_by_margin_pos(osv.osv): ) """) -report_sales_by_margin_pos() class report_sales_by_margin_pos_month(osv.osv): _name = "report.sales.by.margin.pos.month" @@ -234,6 +229,5 @@ class report_sales_by_margin_pos_month(osv.osv): ) """) -report_sales_by_margin_pos_month() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/res_partner.py b/addons/point_of_sale/res_partner.py index 81a0f6083be..d7969b0e21a 100644 --- a/addons/point_of_sale/res_partner.py +++ b/addons/point_of_sale/res_partner.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import math diff --git a/addons/point_of_sale/res_users.py b/addons/point_of_sale/res_users.py index 05e49a5545d..ed2c6fae598 100644 --- a/addons/point_of_sale/res_users.py +++ b/addons/point_of_sale/res_users.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import math diff --git a/addons/point_of_sale/static/lib/mousewheel/jquery.mousewheel-3.0.6.js b/addons/point_of_sale/static/lib/mousewheel/jquery.mousewheel-3.0.6.js old mode 100755 new mode 100644 diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js index a79b111b5c5..e47ce66f648 100644 --- a/addons/point_of_sale/static/src/js/db.js +++ b/addons/point_of_sale/static/src/js/db.js @@ -204,8 +204,8 @@ function openerp_pos_db(instance, module){ this.packagings_by_product_id[pack.product_id[0]] = []; } this.packagings_by_product_id[pack.product_id[0]].push(pack); - if(pack.ean13){ - this.packagings_by_ean13[pack.ean13] = pack; + if(pack.ean){ + this.packagings_by_ean13[pack.ean] = pack; } } }, diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index d2cf15b54f3..13003bcf19f 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -1,24 +1,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sale var QWeb = instance.web.qweb; - // rounds a value with a fixed number of decimals. - // round(3.141492,2) -> 3.14 - function round(value,decimals){ - var mult = Math.pow(10,decimals || 0); - return Math.round(value*mult)/mult; - } - window.round = round; - - // rounds a value with decimal form precision - // round(3.141592,0.025) ->3.125 - function round_pr(value,precision){ - if(!precision || precision < 0){ - throw new Error('round_pr(): needs a precision greater than zero, got '+precision+' instead'); - } - return Math.round(value / precision) * precision; - } - window.round_pr = round_pr; - + var round_di = instance.web.round_decimals; + var round_pr = instance.web.round_precision // The PosModel contains the Point Of Sale's representation of the backend. // Since the PoS must work in standalone ( Without connection to the server ) @@ -295,7 +279,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal return; } //try to push an order to the server - (new instance.web.Model('pos.order')).get_func('create_from_ui')([order]) + // shadow : true is to prevent a spinner to appear in case of timeout + (new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{ shadow:true }) .fail(function(unused, event){ //don't show error popup if it fails event.preventDefault(); @@ -338,7 +323,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal module.Product = Backbone.Model.extend({ get_image_url: function(){ - return instance.session.url('/web/binary/image', {model: 'product.product', field: 'image', id: this.get('id')}); + return instance.session.url('/web/binary/image', {model: 'product.product', field: 'image_medium', id: this.get('id')}); }, }); @@ -390,7 +375,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal var quant = Math.max(parseFloat(quantity) || 0, 0); var unit = this.get_unit(); if(unit){ - this.quantity = Math.max(unit.rounding, Math.round(quant / unit.rounding) * unit.rounding); + this.quantity = Math.max(unit.rounding, round_pr(quant, unit.rounding)); this.quantityStr = this.quantity.toFixed(Math.max(0,Math.ceil(Math.log(1.0 / unit.rounding) / Math.log(10)))); }else{ this.quantity = quant; @@ -483,7 +468,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }, // changes the base price of the product for this orderline set_unit_price: function(price){ - this.price = round(parseFloat(price) || 0, 2); + this.price = round_di(parseFloat(price) || 0, 2); this.trigger('change'); }, get_unit_price: function(){ diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index eca4a3c5915..0bd399428ed 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -983,7 +983,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa } if(this.pos_widget.action_bar){ - this.pos_widget.action_bar.set_button_disabled('validation', remaining > 0); + this.pos_widget.action_bar.set_button_disabled('validation', remaining > 0.000001); } }, set_numpad_state: function(numpadState) { diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 874c387ea23..e4bf004c00f 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -498,7 +498,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }, get_image_url: function(category){ - return instance.session.url('/web/binary/image', {model: 'pos.category', field: 'image', id: category.id}); + return instance.session.url('/web/binary/image', {model: 'pos.category', field: 'image_medium', id: category.id}); }, renderElement: function(){ @@ -794,7 +794,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa renderElement: function() { var self = this; this._super(); - this.$('.oe_pos_synch-notification-button').click(function(){ + this.$el.click(function(){ self.pos.flush(); }); }, @@ -879,6 +879,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa instance.web.unblockUI(); self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').hide();}); + self.pos.flush(); + }).fail(function(){ // error when loading models data from the backend instance.web.unblockUI(); return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_session_opening']], ['res_id']) diff --git a/addons/point_of_sale/test/point_of_sale_report.yml b/addons/point_of_sale/test/point_of_sale_report.yml index 00a675ac152..af034c8f23e 100644 --- a/addons/point_of_sale/test/point_of_sale_report.yml +++ b/addons/point_of_sale/test/point_of_sale_report.yml @@ -3,8 +3,9 @@ - !python {model: pos.order}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.pos.details_summary').create(cr, uid, [ref('point_of_sale.pos_order_pos1')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos1')], 'pos.details_summary', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-details_summary report'+format), 'wb+').write(data) @@ -13,8 +14,9 @@ - !python {model: pos.order}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.pos.invoice').create(cr, uid, [ref('point_of_sale.pos_order_pos1')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos1')], 'pos.invoice', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-invoice report'+format), 'wb+').write(data) @@ -23,8 +25,9 @@ - !python {model: pos.order}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.pos.lines').create(cr, uid, [ref('point_of_sale.pos_order_pos1')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos1')], 'pos.lines', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-lines report'+format), 'wb+').write(data) @@ -33,8 +36,9 @@ - !python {model: pos.order}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.pos.receipt').create(cr, uid, [ref('point_of_sale.pos_order_pos1')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos1')], 'pos.receipt', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-receipt report'+format), 'wb+').write(data) @@ -54,9 +58,10 @@ - !python {model: pos.order}: | import os, time - from openerp import netsvc, tools + import openerp.report + from openerp import tools data_dict = {'model':'ir.ui.menu', 'form':{'date_start': time.strftime('%Y-%m-%d'), 'date_end': time.strftime('%Y-%m-%d'),'user_id':[ref('base.user_root')] }} - (data, format) = netsvc.LocalService('report.pos.sales.user').create(cr, uid, [ref('point_of_sale.pos_order_pos1')], data_dict, {}) + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos1')], 'pos.sales.user', data_dict, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-sales_user_report'+format), 'wb+').write(data) - @@ -64,8 +69,9 @@ - !python {model: pos.order}: | import os, time - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.pos.payment.report').create(cr, uid, [ref('point_of_sale.pos_order_pos0')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos0')], 'pos.payment.report', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-payment_report'+format), 'wb+').write(data) - @@ -73,8 +79,9 @@ - !python {model: pos.order}: | import os, time - from openerp import netsvc, tools + import openerp.report + from openerp import tools data_dict = {'model':'ir.ui.menu', 'form':{'user_id':[ref('base.user_root'),ref('base.user_demo')] }} - (data, format) = netsvc.LocalService('report.pos.payment.report.user').create(cr, uid, [ref('point_of_sale.pos_order_pos1')], data_dict, {}) + data, format = openerp.report.render_report(cr, uid, [ref('point_of_sale.pos_order_pos1')], 'pos.payment.report.user', data_dict, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-payment_user_report'+format), 'wb+').write(data) diff --git a/addons/point_of_sale/wizard/pos_box.py b/addons/point_of_sale/wizard/pos_box.py index 776d962a3a8..e1fa90844d7 100644 --- a/addons/point_of_sale/wizard/pos_box.py +++ b/addons/point_of_sale/wizard/pos_box.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python from openerp.osv import osv, fields from openerp.tools.translate import _ @@ -16,7 +15,7 @@ class PosBox(CashBox): active_ids = context.get('active_ids', []) or [] if active_model == 'pos.session': - records = self.pool.get(active_model).browse(cr, uid, active_ids, context=context) + records = self.pool[active_model].browse(cr, uid, active_ids, context=context) bank_statements = [record.cash_register_id for record in records if record.cash_register_id] if not bank_statements: @@ -41,7 +40,7 @@ class PosBoxIn(PosBox): active_ids = context.get('active_ids', []) or [] if active_model == 'pos.session': - session = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)[0] + session = self.pool[active_model].browse(cr, uid, active_ids, context=context)[0] values['ref'] = session.name return values @@ -57,7 +56,7 @@ class PosBoxOut(PosBox): active_ids = context.get('active_ids', []) or [] if active_model == 'pos.session': - session = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)[0] + session = self.pool[active_model].browse(cr, uid, active_ids, context=context)[0] values['ref'] = session.name return values diff --git a/addons/point_of_sale/wizard/pos_box_entries.py b/addons/point_of_sale/wizard/pos_box_entries.py index ff6af8e1f62..8ca4f01b006 100644 --- a/addons/point_of_sale/wizard/pos_box_entries.py +++ b/addons/point_of_sale/wizard/pos_box_entries.py @@ -141,7 +141,6 @@ class pos_box_entries(osv.osv_memory): bank_statement.create(cr, uid, vals, context=context) return {} -pos_box_entries() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_box_out.py b/addons/point_of_sale/wizard/pos_box_out.py index 6b0b9ee4755..51c3993183b 100644 --- a/addons/point_of_sale/wizard/pos_box_out.py +++ b/addons/point_of_sale/wizard/pos_box_out.py @@ -100,7 +100,6 @@ class pos_box_out(osv.osv_memory): statement_line_obj.create(cr, uid, vals, context=context) return {} -pos_box_out() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_confirm.py b/addons/point_of_sale/wizard/pos_confirm.py index f37bdd9f8b8..6a031f54f61 100644 --- a/addons/point_of_sale/wizard/pos_confirm.py +++ b/addons/point_of_sale/wizard/pos_confirm.py @@ -48,7 +48,6 @@ class pos_confirm(osv.osv_memory): data_lines += [x.id for x in move.line_id if x.account_id.id == invoice.account_id.id] self.pool.get('account.move.line').reconcile(cr, uid, data_lines, context=context) return {} -pos_confirm() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_details.py b/addons/point_of_sale/wizard/pos_details.py index 3f06dc57a46..bfd6e7c4ca7 100644 --- a/addons/point_of_sale/wizard/pos_details.py +++ b/addons/point_of_sale/wizard/pos_details.py @@ -60,7 +60,6 @@ class pos_details(osv.osv_memory): 'datas': datas, } -pos_details() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_discount.py b/addons/point_of_sale/wizard/pos_discount.py index d2703b21ad7..d60b2766644 100644 --- a/addons/point_of_sale/wizard/pos_discount.py +++ b/addons/point_of_sale/wizard/pos_discount.py @@ -68,6 +68,5 @@ class pos_discount(osv.osv_memory): order_line_ref.write(cr, uid, [x.id for x in order.lines], {'discount':this.discount}, context=context) return {} -pos_discount() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_open_statement.py b/addons/point_of_sale/wizard/pos_open_statement.py index 750a5519865..97ffad805b7 100644 --- a/addons/point_of_sale/wizard/pos_open_statement.py +++ b/addons/point_of_sale/wizard/pos_open_statement.py @@ -86,6 +86,5 @@ class pos_open_statement(osv.osv_memory): 'search_view_id': search_id, } -pos_open_statement() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_payment.py b/addons/point_of_sale/wizard/pos_payment.py index 47814761b20..02223153290 100644 --- a/addons/point_of_sale/wizard/pos_payment.py +++ b/addons/point_of_sale/wizard/pos_payment.py @@ -128,7 +128,6 @@ class pos_make_payment(osv.osv_memory): 'amount': _default_amount, } -pos_make_payment() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_payment.xml b/addons/point_of_sale/wizard/pos_payment.xml index 3b1cde3e488..2e828521757 100644 --- a/addons/point_of_sale/wizard/pos_payment.xml +++ b/addons/point_of_sale/wizard/pos_payment.xml @@ -15,7 +15,7 @@
diff --git a/addons/point_of_sale/wizard/pos_payment_report.py b/addons/point_of_sale/wizard/pos_payment_report.py index b28af5a3fff..a591fd4ce5f 100644 --- a/addons/point_of_sale/wizard/pos_payment_report.py +++ b/addons/point_of_sale/wizard/pos_payment_report.py @@ -43,7 +43,6 @@ class pos_payment_report(osv.osv_memory): 'datas': datas, } -pos_payment_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_payment_report_user.py b/addons/point_of_sale/wizard/pos_payment_report_user.py index 06e224f39bc..37a62783ed2 100644 --- a/addons/point_of_sale/wizard/pos_payment_report_user.py +++ b/addons/point_of_sale/wizard/pos_payment_report_user.py @@ -49,7 +49,6 @@ class pos_payment_report_user(osv.osv_memory): 'user_id': fields.many2many('res.users', 'res_user_sale', 'user_id', 'sale_id', 'Salesperson') } -pos_payment_report_user() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_receipt.py b/addons/point_of_sale/wizard/pos_receipt.py index 2a62b74bb30..3e6714f3ac7 100644 --- a/addons/point_of_sale/wizard/pos_receipt.py +++ b/addons/point_of_sale/wizard/pos_receipt.py @@ -55,6 +55,5 @@ class pos_receipt(osv.osv_memory): 'datas': datas, } -pos_receipt() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_return.py b/addons/point_of_sale/wizard/pos_return.py index b4e0e7b2041..f0624948ed5 100644 --- a/addons/point_of_sale/wizard/pos_return.py +++ b/addons/point_of_sale/wizard/pos_return.py @@ -171,7 +171,6 @@ class pos_return(osv.osv_memory): } return act -pos_return() class add_product(osv.osv_memory): _inherit = 'pos.add.product' @@ -321,5 +320,4 @@ class add_product(osv.osv_memory): } return True -add_product() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_sales_user.py b/addons/point_of_sale/wizard/pos_sales_user.py index f2f56d6e35c..e8ece7a7953 100644 --- a/addons/point_of_sale/wizard/pos_sales_user.py +++ b/addons/point_of_sale/wizard/pos_sales_user.py @@ -55,7 +55,6 @@ class pos_sale_user(osv.osv_memory): 'datas': datas, } -pos_sale_user() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_sales_user_current_user.py b/addons/point_of_sale/wizard/pos_sales_user_current_user.py index d3da6a9ad42..d6178ff6a50 100644 --- a/addons/point_of_sale/wizard/pos_sales_user_current_user.py +++ b/addons/point_of_sale/wizard/pos_sales_user_current_user.py @@ -53,7 +53,6 @@ class pos_sales_user_today_current_user(osv.osv_memory): 'datas': datas, } -pos_sales_user_today_current_user() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_sales_user_today.py b/addons/point_of_sale/wizard/pos_sales_user_today.py index dfc40c863b0..65e4182daed 100644 --- a/addons/point_of_sale/wizard/pos_sales_user_today.py +++ b/addons/point_of_sale/wizard/pos_sales_user_today.py @@ -52,7 +52,6 @@ class pos_sales_user_today(osv.osv_memory): 'datas': datas, } -pos_sales_user_today() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_session_opening.py b/addons/point_of_sale/wizard/pos_session_opening.py index e0135de0cdb..39e7c564831 100644 --- a/addons/point_of_sale/wizard/pos_session_opening.py +++ b/addons/point_of_sale/wizard/pos_session_opening.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python from openerp.osv import osv, fields from openerp.tools.translate import _ @@ -115,4 +114,3 @@ class pos_session_opening(osv.osv_memory): 'pos_config_id' : result, 'show_config' : show_config, } -pos_session_opening() diff --git a/addons/portal/__init__.py b/addons/portal/__init__.py index 0045a557a49..1f60accc83d 100644 --- a/addons/portal/__init__.py +++ b/addons/portal/__init__.py @@ -20,7 +20,9 @@ ############################################################################## import portal +import mail_thread import mail_mail +import mail_message import wizard import acquirer diff --git a/addons/portal/i18n/ko.po b/addons/portal/i18n/ko.po new file mode 100644 index 00000000000..b1d03cc0e7e --- /dev/null +++ b/addons/portal/i18n/ko.po @@ -0,0 +1,497 @@ +# Korean translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-05-14 01:12+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-15 05:15+0000\n" +"X-Generator: Launchpad (build 16617)\n" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "Mako" +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/share_wizard.py:50 +#, python-format +msgid "Please select at least one user to share with" +msgstr "" + +#. module: portal +#: view:portal.wizard:0 +msgid "" +"Select which contacts should belong to the portal in the list below.\n" +" The email address of each selected contact must be " +"valid and unique.\n" +" If necessary, you can fix any contact's email " +"address directly in the list." +msgstr "" + +#. module: portal +#: model:mail.group,name:portal.company_jobs +msgid "Company Jobs" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "amount: the total amount to pay, as a float" +msgstr "" + +#. module: portal +#: view:portal.wizard.user:0 +msgid "Contacts" +msgstr "연락처" + +#. module: portal +#: view:share.wizard:0 +#: field:share.wizard,group_ids:0 +msgid "Existing groups" +msgstr "기존 그룹" + +#. module: portal +#: view:res.groups:0 +msgid "Portal Groups" +msgstr "포털 그룹" + +#. module: portal +#: field:portal.wizard,welcome_message:0 +msgid "Invitation Message" +msgstr "초대 메시지" + +#. module: portal +#: view:res.groups:0 +msgid "Non-Portal Groups" +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/share_wizard.py:54 +#, python-format +msgid "Please select at least one group to share with" +msgstr "" + +#. module: portal +#: view:share.wizard:0 +msgid "Details" +msgstr "" + +#. module: portal +#: model:ir.ui.menu,name:portal.portal_orders +msgid "Quotations and Sales Orders" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "reference: the reference number of the document to pay" +msgstr "" + +#. module: portal +#: help:portal.payment.acquirer,visible:0 +msgid "" +"Make this payment acquirer available in portal forms (Customer invoices, " +"etc.)" +msgstr "" + +#. module: portal +#: model:ir.model,name:portal.model_share_wizard +msgid "Share Wizard" +msgstr "" + +#. module: portal +#: field:portal.wizard.user,email:0 +msgid "Email" +msgstr "" + +#. module: portal +#: model:ir.actions.client,help:portal.action_news +msgid "" +"

\n" +" Youd don't have unread company's news.\n" +"

\n" +" " +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/portal_wizard.py:194 +#, python-format +msgid "" +"You must have an email address in your User Preferences to send emails." +msgstr "" + +#. module: portal +#: model:ir.actions.client,name:portal.action_jobs +#: model:ir.ui.menu,name:portal.portal_jobs +msgid "Jobs" +msgstr "" + +#. module: portal +#: field:portal.wizard,user_ids:0 +msgid "Users" +msgstr "" + +#. module: portal +#: code:addons/portal/acquirer.py:82 +#, python-format +msgid "Pay safely online" +msgstr "" + +#. module: portal +#: code:addons/portal/acquirer.py:77 +#, python-format +msgid "No online payment acquirers configured" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +"kind: the kind of document on which the payment form is rendered (translated " +"to user language, e.g. \"Invoice\")" +msgstr "" + +#. module: portal +#: help:portal.wizard,portal_id:0 +msgid "The portal that users can be added in or removed from." +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/share_wizard.py:38 +#, python-format +msgid "Users you already shared with" +msgstr "" + +#. module: portal +#: model:ir.actions.client,help:portal.action_jobs +msgid "" +"

\n" +" Youd don't have unread job offers.\n" +"

\n" +" " +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +", so it may use Mako expressions.\n" +" The Mako evaluation context provides:" +msgstr "" + +#. module: portal +#: model:ir.ui.menu,name:portal.portal_menu +#: field:portal.wizard,portal_id:0 +#: field:res.groups,is_portal:0 +#: model:res.groups,name:portal.group_portal +msgid "Portal" +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/portal_wizard.py:34 +#, python-format +msgid "Your OpenERP account at %(company)s" +msgstr "" + +#. module: portal +#: model:res.groups,name:portal.group_anonymous +msgid "Anonymous" +msgstr "" + +#. module: portal +#: field:portal.wizard.user,in_portal:0 +msgid "In Portal" +msgstr "" + +#. module: portal +#: model:ir.actions.client,name:portal.action_news +#: model:ir.ui.menu,name:portal.portal_company_news +msgid "News" +msgstr "" + +#. module: portal +#: model:ir.ui.menu,name:portal.portal_after_sales +msgid "After Sale Services" +msgstr "" + +#. module: portal +#: model:res.groups,comment:portal.group_portal +msgid "" +"Portal members have specific access rights (such as record rules and " +"restricted menus).\n" +" They usually do not belong to the usual OpenERP groups." +msgstr "" + +#. module: portal +#: model:ir.actions.act_window,name:portal.action_acquirer_list +#: view:portal.payment.acquirer:0 +msgid "Payment Acquirers" +msgstr "" + +#. module: portal +#: model:ir.ui.menu,name:portal.portal_projects +msgid "Projects" +msgstr "" + +#. module: portal +#: model:ir.actions.client,name:portal.action_mail_inbox_feeds_portal +#: model:ir.ui.menu,name:portal.portal_inbox +msgid "Inbox" +msgstr "" + +#. module: portal +#: view:share.wizard:0 +#: field:share.wizard,user_ids:0 +msgid "Existing users" +msgstr "" + +#. module: portal +#: field:portal.wizard.user,wizard_id:0 +msgid "Wizard" +msgstr "" + +#. module: portal +#: field:portal.payment.acquirer,name:0 +msgid "Name" +msgstr "" + +#. module: portal +#: model:ir.model,name:portal.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "uid: the current user id" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +"quote(): a method to quote special string character to make them suitable " +"for inclusion in a URL" +msgstr "" + +#. module: portal +#: help:res.groups,is_portal:0 +msgid "If checked, this group is usable as a portal." +msgstr "" + +#. module: portal +#: field:portal.payment.acquirer,form_template:0 +msgid "Payment form template (HTML)" +msgstr "" + +#. module: portal +#: field:portal.wizard.user,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: portal +#: model:ir.model,name:portal.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/portal_wizard.py:193 +#, python-format +msgid "Email required" +msgstr "" + +#. module: portal +#: model:ir.ui.menu,name:portal.portal_messages +msgid "Messaging" +msgstr "" + +#. module: portal +#: model:res.groups,comment:portal.group_anonymous +msgid "" +"Anonymous users have specific access rights (such as record rules and " +"restricted menus).\n" +" They usually do not belong to the usual OpenERP groups." +msgstr "" + +#. module: portal +#: model:ir.model,name:portal.model_portal_payment_acquirer +msgid "Online Payment Acquirer" +msgstr "" + +#. module: portal +#: model:mail.group,name:portal.company_news_feed +msgid "Company News" +msgstr "" + +#. module: portal +#: code:addons/portal/acquirer.py:76 +#, python-format +msgid "" +"You can finish the configuration in the Bank&Cash settings" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "cr: the current database cursor" +msgstr "" + +#. module: portal +#: model:ir.actions.client,help:portal.action_mail_inbox_feeds_portal +msgid "" +"

\n" +" Good Job! Your inbox is empty.\n" +"

\n" +" Your inbox contains private messages or emails sent to " +"you\n" +" as well as information related to documents or people " +"you\n" +" follow.\n" +"

\n" +" " +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +"object: the document on which the payment form is rendered (usually an " +"invoice or sales order record)" +msgstr "" + +#. module: portal +#: help:portal.wizard,welcome_message:0 +msgid "This text is included in the email sent to new users of the portal." +msgstr "" + +#. module: portal +#: model:ir.ui.menu,name:portal.portal_company +msgid "About Us" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +"currency: the currency record in which the document is issued (e.g. " +"currency.name could be EUR)" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "Payment Acquirer" +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/portal_wizard.py:35 +#, python-format +msgid "" +"Dear %(name)s,\n" +"\n" +"You have been given access to %(portal)s.\n" +"\n" +"Your login account data is:\n" +"Database: %(db)s\n" +"Username: %(login)s\n" +"\n" +"In order to complete the signin process, click on the following url:\n" +"%(url)s\n" +"\n" +"%(welcome_message)s\n" +"\n" +"--\n" +"OpenERP - Open Source Business Applications\n" +"http://www.openerp.com\n" +msgstr "" + +#. module: portal +#: view:portal.wizard:0 +msgid "or" +msgstr "" + +#. module: portal +#: model:portal.payment.acquirer,form_template:portal.paypal_acquirer +msgid "" +"\n" +"% if object.company_id.paypal_account:\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"% endif\n" +" " +msgstr "" + +#. module: portal +#: model:ir.model,name:portal.model_portal_wizard_user +msgid "Portal User Config" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +"If the template renders to an empty result in a certain context it will be " +"ignored, as if it was inactive." +msgstr "" + +#. module: portal +#: field:portal.payment.acquirer,visible:0 +msgid "Visible" +msgstr "" + +#. module: portal +#: code:addons/portal/wizard/share_wizard.py:39 +#, python-format +msgid "Existing Groups (e.g Portal Groups)" +msgstr "" + +#. module: portal +#: view:portal.wizard:0 +msgid "Cancel" +msgstr "" + +#. module: portal +#: view:portal.wizard:0 +msgid "Apply" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "ctx: the current context dictionary" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "" +"This is an HTML form template to submit a payment through this acquirer.\n" +" The template will be rendered with" +msgstr "" + +#. module: portal +#: code:addons/portal/mail_mail.py:42 +#, python-format +msgid "" +"Access your personal documents through our Customer Portal" +msgstr "" + +#. module: portal +#: view:portal.payment.acquirer:0 +msgid "Form Template" +msgstr "" + +#. module: portal +#: model:ir.actions.act_window,name:portal.partner_wizard_action +#: model:ir.model,name:portal.model_portal_wizard +#: view:portal.wizard:0 +msgid "Portal Access Management" +msgstr "" diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py index 3810ddd2540..e412732fdc9 100644 --- a/addons/portal/mail_mail.py +++ b/addons/portal/mail_mail.py @@ -21,7 +21,6 @@ from openerp import SUPERUSER_ID from openerp.osv import osv -from openerp.osv.orm import except_orm from openerp.tools.translate import _ @@ -29,27 +28,19 @@ class mail_mail(osv.Model): """ Update of mail_mail class, to add the signin URL to notifications. """ _inherit = 'mail.mail' - def send_get_mail_body_footer(self, cr, uid, mail, partner=None, context=None): - """ add a signin link inside the body of a mail.mail - :param mail: mail.mail browse_record - :param partner: browse_record of the specific recipient partner - :return: the resulting body_html + def _get_partner_access_link(self, cr, uid, mail, partner=None, context=None): + """ Generate URLs for links in mails: + - partner is not an user: signup_url + - partner is an user: fallback on classic URL """ + if context is None: + context = {} partner_obj = self.pool.get('res.partner') - if partner: - contex_signup = dict(context or {}, signup_valid=True) - partner = partner_obj.browse(cr, SUPERUSER_ID, partner.id, context=contex_signup) - body_footer = _("""Access your messages and documents through our Customer Portal""") % partner.signup_url - # partner is an user: add a link to the document if read access - if partner.user_ids and mail.model and mail.res_id \ - and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False): - related_user = partner.user_ids[0] - try: - self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context) - url = partner_obj._get_signup_url_for_action(cr, related_user.id, [partner.id], action='', res_id=mail.res_id, model=mail.model, context=context)[partner.id] - text = _("""Access this document directly in OpenERP""") % url - except except_orm, e: - pass - return body_footer + if partner and not partner.user_ids: + contex_signup = dict(context, signup_valid=True) + signup_url = partner_obj._get_signup_url_for_action(cr, SUPERUSER_ID, [partner.id], + action='login', model=mail.model, res_id=mail.res_id, + context=contex_signup)[partner.id] + return _("""Access your messages and documents through our Customer Portal""") % signup_url else: - return super(mail_mail, self).send_get_mail_body_footer(cr, uid, mail, partner=partner, context=context) + return super(mail_mail, self)._get_partner_access_link(cr, uid, mail, partner=partner, context=context) diff --git a/addons/portal/mail_message.py b/addons/portal/mail_message.py new file mode 100644 index 00000000000..d6a38f27378 --- /dev/null +++ b/addons/portal/mail_message.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2011 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 . +# +############################################################################## + +from openerp.osv import osv, orm +from openerp.tools.translate import _ + + +class mail_message(osv.Model): + """ Update of mail_message class, to restrict mail access. """ + _inherit = 'mail.message' + + def _search(self, cr, uid, args, offset=0, limit=None, order=None, + context=None, count=False, access_rights_uid=None): + """ Override that adds specific access rights of mail.message, to remove + all internal notes if uid is a non-employee + """ + group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id + group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1] + if group_user_id not in [group.id for group in group_ids]: + args = ['&', '|', ('type', '!=', 'comment'), ('subtype_id', '!=', False)] + list(args) + + return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order, + context=context, count=False, access_rights_uid=access_rights_uid) + + def check_access_rule(self, cr, uid, ids, operation, context=None): + """ Add Access rules of mail.message for non-employee user: + - read: + - raise if the type is comment and subtype NULL (internal note) + """ + group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id + group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1] + if group_user_id not in [group.id for group in group_ids]: + cr.execute('SELECT DISTINCT id FROM "%s" WHERE type = %%s AND subtype_id IS NULL AND id = ANY (%%s)' % (self._table), ('comment', ids,)) + if cr.fetchall(): + raise orm.except_orm(_('Access Denied'), + _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \ + (self._description, operation)) + + return super(mail_message, self).check_access_rule(cr, uid, ids=ids, operation=operation, context=context) diff --git a/addons/portal/mail_thread.py b/addons/portal/mail_thread.py new file mode 100644 index 00000000000..44bc4d0bde8 --- /dev/null +++ b/addons/portal/mail_thread.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-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 . +# +############################################################################## + +from openerp import SUPERUSER_ID +from openerp.osv import osv + + +class mail_thread(osv.AbstractModel): + """ Update of mail_mail class, to add the signin URL to notifications. """ + _inherit = 'mail.thread' + + def _get_inbox_action_xml_id(self, cr, uid, context=None): + """ For a given message, return an action that either + - opens the form view of the related document if model, res_id, and + read access to the document + - opens the Inbox with a default search on the conversation if model, + res_id + - opens the Inbox with context propagated + """ + cur_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) + # if uid is a portal user -> action is different + if any(group.is_portal for group in cur_user.groups_id): + return ('portal', 'action_mail_inbox_feeds_portal') + else: + return super(mail_thread, self)._get_inbox_action_xml_id(cr, uid, context=context) diff --git a/addons/portal/portal_demo.xml b/addons/portal/portal_demo.xml index c05189fd2ab..3660754b4ad 100644 --- a/addons/portal/portal_demo.xml +++ b/addons/portal/portal_demo.xml @@ -40,7 +40,7 @@ Mr Demo Portal
mail.group - As your first portal member, I am very pleased to be able to be able to communicate directly with you. Be sure I'll read all news carefully!

]]>
+ As your first portal member, I am very pleased to be able to communicate directly with you. Be sure I'll read all news carefully!

]]>
comment diff --git a/addons/portal/portal_view.xml b/addons/portal/portal_view.xml index d56e277c3fb..1ff98bdc77f 100644 --- a/addons/portal/portal_view.xml +++ b/addons/portal/portal_view.xml @@ -21,7 +21,6 @@ To-do mail.wall @@ -67,6 +67,9 @@

+ + Archives @@ -84,7 +87,6 @@ 'show_compose_message': False, 'show_link': False, 'view_mailbox': True, - 'read_action': 'read' }""/>

@@ -98,8 +100,6 @@ - @@ -107,7 +107,7 @@ Create menu items that we'll leave empty for now - they'll be filled up by other portal modules. --> - + diff --git a/addons/portal/security/ir.model.access.csv b/addons/portal/security/ir.model.access.csv index 31bd7332c2f..26b0b4895e8 100644 --- a/addons/portal/security/ir.model.access.csv +++ b/addons/portal/security/ir.model.access.csv @@ -3,7 +3,7 @@ access_mail_message_portal,mail.message.portal,mail.model_mail_message,group_por access_mail_mail_portal,mail.mail.portal,mail.model_mail_mail,group_portal,1,1,1,0 access_mail_notification_portal,mail.notification.portal,mail.model_mail_notification,group_portal,1,1,1,0 access_mail_followers_portal,mail.followers.portal,mail.model_mail_followers,group_portal,1,1,0,0 -access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0 +access_res_partner_portal,res.partner.portal,base.model_res_partner,portal.group_portal,1,0,0,0 access_acquirer,portal.payment.acquirer,portal.model_portal_payment_acquirer,,1,0,0,0 access_acquirer_all,portal.payment.acquirer,portal.model_portal_payment_acquirer,base.group_system,1,1,1,1 access_ir_attachment_group_portal,ir.attachment group_portal,base.model_ir_attachment,portal.group_portal,1,0,1,0 \ No newline at end of file diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py index 07becf5cdd9..e2b66e65af6 100644 --- a/addons/portal/tests/test_portal.py +++ b/addons/portal/tests/test_portal.py @@ -40,7 +40,9 @@ class test_portal(TestMailBase): self.partner_chell_id = self.user_chell.partner_id.id # Create a PigsPortal group - self.group_port_id = self.mail_group.create(cr, uid, {'name': 'PigsPortal', 'public': 'groups', 'group_public_id': self.group_portal_id}) + self.group_port_id = self.mail_group.create(cr, uid, + {'name': 'PigsPortal', 'public': 'groups', 'group_public_id': self.group_portal_id}, + {'mail_create_nolog': True}) # Set an email address for the user running the tests, used as Sender for outgoing mails self.res_users.write(cr, uid, uid, {'email': 'test@localhost'}) @@ -130,3 +132,94 @@ class test_portal(TestMailBase): 'invite: body of invitation email is incorrect') self.assertTrue(partner_carine.signup_url in sent_email.get('body'), 'invite: body of invitation email does not contain signup url') + + def test_20_notification_url(self): + """ Tests designed to test the URL added in notification emails. """ + cr, uid, group_pigs = self.cr, self.uid, self.group_pigs + + # Partner data + partner_raoul = self.res_partner.browse(cr, uid, self.partner_raoul_id) + partner_bert_id = self.res_partner.create(cr, uid, {'name': 'bert'}) + partner_bert = self.res_partner.browse(cr, uid, partner_bert_id) + # Mail data + mail_mail_id = self.mail_mail.create(cr, uid, {'state': 'exception'}) + mail = self.mail_mail.browse(cr, uid, mail_mail_id) + + # Test: link for nobody -> None + url = self.mail_mail._get_partner_access_link(cr, uid, mail) + self.assertEqual(url, None, + 'notification email: mails not send to a specific partner should not have any URL') + + # Test: link for partner -> signup URL + url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_bert) + self.assertIn(partner_bert.signup_url, url, + 'notification email: mails send to a not-user partner should contain the signup URL') + + # Test: link for user -> signin + url = self.mail_mail._get_partner_access_link(cr, uid, mail, partner=partner_raoul) + self.assertIn('action=mail.action_mail_redirect', url, + 'notification email: link should contain the redirect action') + self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url, + 'notification email: link should contain the user login') + + @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm') + def test_21_inbox_redirection(self): + """ Tests designed to test the inbox redirection of emails notification URLs. """ + cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs + model, act_id = self.ir_model_data.get_object_reference(cr, uid, 'mail', 'action_mail_inbox_feeds') + model, port_act_id = self.ir_model_data.get_object_reference(cr, uid, 'portal', 'action_mail_inbox_feeds_portal') + # Data: post a message on pigs + msg_id = self.group_pigs.message_post(body='My body', partner_ids=[self.partner_bert_id, self.partner_chell_id], type='comment', subtype='mail.mt_comment') + + # No specific parameters -> should redirect to Inbox + action = self.mail_thread.message_redirect_action(cr, self.user_raoul_id, {'params': {}}) + self.assertEqual(action.get('type'), 'ir.actions.client', + 'URL redirection: action without parameters should redirect to client action Inbox') + self.assertEqual(action.get('id'), act_id, + 'URL redirection: action without parameters should redirect to client action Inbox') + + # Bert has read access to Pigs -> should redirect to form view of Pigs + action = self.mail_thread.message_redirect_action(cr, self.user_raoul_id, {'params': {'message_id': msg_id}}) + self.assertEqual(action.get('type'), 'ir.actions.act_window', + 'URL redirection: action with message_id for read-accredited user should redirect to Pigs') + self.assertEqual(action.get('res_id'), group_pigs.id, + 'URL redirection: action with message_id for read-accredited user should redirect to Pigs') + + # Bert has no read access to Pigs -> should redirect to Inbox + action = self.mail_thread.message_redirect_action(cr, self.user_bert_id, {'params': {'message_id': msg_id}}) + self.assertEqual(action.get('type'), 'ir.actions.client', + 'URL redirection: action without parameters should redirect to client action Inbox') + self.assertEqual(action.get('id'), act_id, + 'URL redirection: action without parameters should redirect to client action Inbox') + + # Chell has no read access to pigs -> should redirect to Portal Inbox + action = self.mail_thread.message_redirect_action(cr, self.user_chell_id, {'params': {'message_id': msg_id}}) + self.assertEqual(action.get('type'), 'ir.actions.client', + 'URL redirection: action without parameters should redirect to client action Inbox') + self.assertEqual(action.get('id'), port_act_id, + 'URL redirection: action without parameters should redirect to client action Inbox') + + def test_30_message_read(self): + cr, uid, group_port_id = self.cr, self.uid, self.group_port_id + + # Data: custom subtypes + mt_group_public_id = self.mail_message_subtype.create(cr, uid, {'name': 'group_public', 'description': 'Group changed'}) + self.ir_model_data.create(cr, uid, {'name': 'mt_group_public', 'model': 'mail.message.subtype', 'module': 'mail', 'res_id': mt_group_public_id}) + # Data: post messages with various subtypes + msg1_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body1', type='comment', subtype='mail.mt_comment') + msg2_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body2', type='comment', subtype='mail.mt_group_public') + msg3_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body3', type='comment', subtype='mail.mt_comment') + msg4_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body4', type='comment') + msg5_id = self.mail_group.message_post(cr, uid, group_port_id, body='Body5', type='notification') + + # Do: Chell search messages: should not see internal notes (comment without subtype) + msg_ids = self.mail_message.search(cr, self.user_chell_id, [('model', '=', 'mail.group'), ('res_id', '=', group_port_id)]) + self.assertEqual(set(msg_ids), set([msg1_id, msg2_id, msg3_id, msg5_id]), + 'mail_message: portal user has access to messages he should not read') + + # Do: Chell read messages she can read + self.mail_message.read(cr, self.user_chell_id, msg_ids, ['body', 'type', 'subtype_id']) + + # Do: Chell read a message she should not be able to read + with self.assertRaises(except_orm): + self.mail_message.read(cr, self.user_chell_id, [msg4_id], ['body', 'type', 'subtype_id']) diff --git a/addons/portal/wizard/share_wizard.py b/addons/portal/wizard/share_wizard.py index d983bf11ee1..0ffae804f07 100644 --- a/addons/portal/wizard/share_wizard.py +++ b/addons/portal/wizard/share_wizard.py @@ -179,7 +179,6 @@ class share_wizard_portal(osv.TransientModel): super(share_wizard_portal,self)._finish_result_lines(cr, uid, wizard_data, share_group_id, context=context) self.copy_share_group_access_and_delete(cr, wizard_data, share_group_id, context=context) -share_wizard_portal() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal_anonymous/i18n/lt.po b/addons/portal_anonymous/i18n/lt.po new file mode 100644 index 00000000000..60643c7f356 --- /dev/null +++ b/addons/portal_anonymous/i18n/lt.po @@ -0,0 +1,25 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-24 18:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: portal_anonymous +#. openerp-web +#: code:addons/portal_anonymous/static/src/xml/portal_anonymous.xml:8 +#, python-format +msgid "Login" +msgstr "Prisijungti" diff --git a/addons/portal_anonymous/i18n/ru.po b/addons/portal_anonymous/i18n/ru.po new file mode 100644 index 00000000000..5ae80dfe490 --- /dev/null +++ b/addons/portal_anonymous/i18n/ru.po @@ -0,0 +1,25 @@ +# Russian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-09 13:04+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Russian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-10 05:21+0000\n" +"X-Generator: Launchpad (build 16550)\n" + +#. module: portal_anonymous +#. openerp-web +#: code:addons/portal_anonymous/static/src/xml/portal_anonymous.xml:8 +#, python-format +msgid "Login" +msgstr "Вход" diff --git a/addons/portal_crm/i18n/cs.po b/addons/portal_crm/i18n/cs.po new file mode 100644 index 00000000000..985d487adbc --- /dev/null +++ b/addons/portal_crm/i18n/cs.po @@ -0,0 +1,546 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-03-29 18:40+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-30 05:27+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,type:0 +msgid "Lead" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,title:0 +msgid "Title" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,probability:0 +msgid "Success Rate (%)" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Contact us" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action:0 +msgid "Next Action Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,fax:0 +msgid "Fax" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,zip:0 +msgid "Zip" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_id:0 +msgid "Company" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,day_open:0 +msgid "Days to Open" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Thank you for your interest, we'll respond to your request shortly." +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Highest" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,mobile:0 +msgid "Mobile" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,description:0 +msgid "Notes" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,color:0 +msgid "Color Index" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_latitude:0 +msgid "Geo Latitude" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_name:0 +msgid "Customer Name" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Cancelled" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,channel_id:0 +msgid "Communication channel (mail, direct, phone, ...)" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,type_id:0 +msgid "Campaign" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,ref:0 +msgid "Reference" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action_next:0 +#: field:portal_crm.crm_contact_us,title_action:0 +msgid "Next Action" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: portal_crm +#: model:ir.actions.act_window,name:portal_crm.action_contact_us +msgid "Contact Us" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,name:0 +msgid "Subject" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,opt_out:0 +msgid "Opt-Out" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,priority:0 +msgid "Priority" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,state_id:0 +msgid "State" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_id:0 +msgid "Linked partner (optional). Usually created when converting the lead." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,payment_mode:0 +msgid "Payment Mode" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "New" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,type:0 +msgid "Type" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,email_from:0 +msgid "Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,channel_id:0 +msgid "Channel" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Name" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Lowest" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,create_date:0 +msgid "Creation Date" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Close" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Pending" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,type:0 +msgid "Type is used to separate Leads and Opportunities" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,categ_ids:0 +msgid "Categories" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,stage_id:0 +msgid "Stage" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_login:0 +msgid "User Login" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,opt_out:0 +msgid "" +"If opt-out is checked, this contact has refused to receive emails or " +"unsubscribed to a campaign." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,contact_name:0 +msgid "Contact Name" +msgstr "" + +#. module: portal_crm +#: model:ir.ui.menu,name:portal_crm.portal_company_contact +msgid "Contact" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_address_email:0 +msgid "Partner Contact Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,planned_revenue:0 +msgid "Expected Revenue" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,task_ids:0 +msgid "Tasks" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Contact form" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_currency:0 +msgid "Currency" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,write_date:0 +msgid "Update Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_deadline:0 +msgid "Expected Closing" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,ref2:0 +msgid "Reference 2" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_email:0 +msgid "User Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_open:0 +msgid "Opened" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "In Progress" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_name:0 +msgid "" +"The name of the future partner company that will be created while converting " +"the lead into opportunity" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,planned_cost:0 +msgid "Planned Costs" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,date_deadline:0 +msgid "Estimate of the date on which the opportunity will be won." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,email_cc:0 +msgid "" +"These email addresses will be added to the CC field of all inbound and " +"outbound emails for this record before being sent. Separate multiple email " +"addresses with a comma" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Low" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_closed:0 +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Closed" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_assign:0 +msgid "Assignation Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,state:0 +msgid "Status" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Normal" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,email_cc:0 +msgid "Global CC" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,street2:0 +msgid "Street2" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,id:0 +msgid "ID" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,phone:0 +msgid "Phone" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,active:0 +msgid "Active" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_id:0 +msgid "Salesperson" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,day_close:0 +msgid "Days to Close" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_ids:0 +msgid "Companies" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,section_id:0 +msgid "" +"When sending mails, the default email address is taken from the sales team." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_address_name:0 +msgid "Partner Contact Name" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_longitude:0 +msgid "Geo Longitude" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,date_assign:0 +msgid "Last date this case was forwarded/assigned to a partner" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,email_from:0 +msgid "Email address of the contact" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,city:0 +msgid "City" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Submit" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,function:0 +msgid "Function" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,referred:0 +msgid "Referred By" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_assigned_id:0 +msgid "Assigned Partner" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,type:0 +msgid "Opportunity" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_assigned_id:0 +msgid "Partner this case has been forwarded/assigned to." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,country_id:0 +msgid "Country" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Thank you" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,state:0 +msgid "" +"The Status is set to 'Draft', when a case is created. If the case is in " +"progress the Status is set to 'Open'. When the case is over, the Status is " +"set to 'Done'. If the case needs to be reviewed then the Status is set to " +"'Pending'." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,type_id:0 +msgid "" +"From which campaign (seminar, marketing campaign, mass mailing, ...) did " +"this contact come from?" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "High" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,section_id:0 +msgid "Sales Team" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,street:0 +msgid "Street" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action_last:0 +msgid "Last Action" +msgstr "" + +#. module: portal_crm +#: model:ir.model,name:portal_crm.model_portal_crm_crm_contact_us +msgid "Contact form for the portal" +msgstr "" diff --git a/addons/portal_crm/i18n/fr.po b/addons/portal_crm/i18n/fr.po new file mode 100644 index 00000000000..a0633c60306 --- /dev/null +++ b/addons/portal_crm/i18n/fr.po @@ -0,0 +1,546 @@ +# French translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-05-22 16:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: French \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-23 05:19+0000\n" +"X-Generator: Launchpad (build 16640)\n" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,type:0 +msgid "Lead" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,title:0 +msgid "Title" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,probability:0 +msgid "Success Rate (%)" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Contact us" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action:0 +msgid "Next Action Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,fax:0 +msgid "Fax" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,zip:0 +msgid "Zip" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_id:0 +msgid "Company" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,day_open:0 +msgid "Days to Open" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Thank you for your interest, we'll respond to your request shortly." +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Highest" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,mobile:0 +msgid "Mobile" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,description:0 +msgid "Notes" +msgstr "Notes" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,color:0 +msgid "Color Index" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_latitude:0 +msgid "Geo Latitude" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_name:0 +msgid "Customer Name" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Cancelled" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,channel_id:0 +msgid "Communication channel (mail, direct, phone, ...)" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,type_id:0 +msgid "Campaign" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,ref:0 +msgid "Reference" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action_next:0 +#: field:portal_crm.crm_contact_us,title_action:0 +msgid "Next Action" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: portal_crm +#: model:ir.actions.act_window,name:portal_crm.action_contact_us +msgid "Contact Us" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,name:0 +msgid "Subject" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,opt_out:0 +msgid "Opt-Out" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,priority:0 +msgid "Priority" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,state_id:0 +msgid "State" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_id:0 +msgid "Linked partner (optional). Usually created when converting the lead." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,payment_mode:0 +msgid "Payment Mode" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "New" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,type:0 +msgid "Type" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,email_from:0 +msgid "Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,channel_id:0 +msgid "Channel" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Name" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Lowest" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,create_date:0 +msgid "Creation Date" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Close" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Pending" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,type:0 +msgid "Type is used to separate Leads and Opportunities" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,categ_ids:0 +msgid "Categories" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,stage_id:0 +msgid "Stage" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_login:0 +msgid "User Login" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,opt_out:0 +msgid "" +"If opt-out is checked, this contact has refused to receive emails or " +"unsubscribed to a campaign." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,contact_name:0 +msgid "Contact Name" +msgstr "" + +#. module: portal_crm +#: model:ir.ui.menu,name:portal_crm.portal_company_contact +msgid "Contact" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_address_email:0 +msgid "Partner Contact Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,planned_revenue:0 +msgid "Expected Revenue" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,task_ids:0 +msgid "Tasks" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Contact form" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_currency:0 +msgid "Currency" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,write_date:0 +msgid "Update Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_deadline:0 +msgid "Expected Closing" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,ref2:0 +msgid "Reference 2" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_email:0 +msgid "User Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_open:0 +msgid "Opened" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "In Progress" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_name:0 +msgid "" +"The name of the future partner company that will be created while converting " +"the lead into opportunity" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,planned_cost:0 +msgid "Planned Costs" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,date_deadline:0 +msgid "Estimate of the date on which the opportunity will be won." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,email_cc:0 +msgid "" +"These email addresses will be added to the CC field of all inbound and " +"outbound emails for this record before being sent. Separate multiple email " +"addresses with a comma" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Low" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_closed:0 +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Closed" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_assign:0 +msgid "Assignation Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,state:0 +msgid "Status" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Normal" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,email_cc:0 +msgid "Global CC" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,street2:0 +msgid "Street2" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,id:0 +msgid "ID" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,phone:0 +msgid "Phone" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,active:0 +msgid "Active" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_id:0 +msgid "Salesperson" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,day_close:0 +msgid "Days to Close" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_ids:0 +msgid "Companies" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,section_id:0 +msgid "" +"When sending mails, the default email address is taken from the sales team." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_address_name:0 +msgid "Partner Contact Name" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_longitude:0 +msgid "Geo Longitude" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,date_assign:0 +msgid "Last date this case was forwarded/assigned to a partner" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,email_from:0 +msgid "Email address of the contact" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,city:0 +msgid "City" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Submit" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,function:0 +msgid "Function" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,referred:0 +msgid "Referred By" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_assigned_id:0 +msgid "Assigned Partner" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,type:0 +msgid "Opportunity" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_assigned_id:0 +msgid "Partner this case has been forwarded/assigned to." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,country_id:0 +msgid "Country" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Thank you" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,state:0 +msgid "" +"The Status is set to 'Draft', when a case is created. If the case is in " +"progress the Status is set to 'Open'. When the case is over, the Status is " +"set to 'Done'. If the case needs to be reviewed then the Status is set to " +"'Pending'." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,type_id:0 +msgid "" +"From which campaign (seminar, marketing campaign, mass mailing, ...) did " +"this contact come from?" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "High" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,section_id:0 +msgid "Sales Team" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,street:0 +msgid "Street" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action_last:0 +msgid "Last Action" +msgstr "" + +#. module: portal_crm +#: model:ir.model,name:portal_crm.model_portal_crm_crm_contact_us +msgid "Contact form for the portal" +msgstr "" diff --git a/addons/portal_crm/i18n/lt.po b/addons/portal_crm/i18n/lt.po new file mode 100644 index 00000000000..b2b223c6124 --- /dev/null +++ b/addons/portal_crm/i18n/lt.po @@ -0,0 +1,546 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-29 15:24+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,type:0 +msgid "Lead" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,title:0 +msgid "Title" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,probability:0 +msgid "Success Rate (%)" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Contact us" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action:0 +msgid "Next Action Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,fax:0 +msgid "Fax" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,zip:0 +msgid "Zip" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_id:0 +msgid "Company" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,day_open:0 +msgid "Days to Open" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Thank you for your interest, we'll respond to your request shortly." +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Highest" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,mobile:0 +msgid "Mobile" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,description:0 +msgid "Notes" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,color:0 +msgid "Color Index" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_latitude:0 +msgid "Geo Latitude" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_name:0 +msgid "Customer Name" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Cancelled" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,channel_id:0 +msgid "Communication channel (mail, direct, phone, ...)" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,type_id:0 +msgid "Campaign" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,ref:0 +msgid "Reference" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action_next:0 +#: field:portal_crm.crm_contact_us,title_action:0 +msgid "Next Action" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: portal_crm +#: model:ir.actions.act_window,name:portal_crm.action_contact_us +msgid "Contact Us" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,name:0 +msgid "Subject" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,opt_out:0 +msgid "Opt-Out" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,priority:0 +msgid "Priority" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,state_id:0 +msgid "State" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_id:0 +msgid "Linked partner (optional). Usually created when converting the lead." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,payment_mode:0 +msgid "Payment Mode" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "New" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,type:0 +msgid "Type" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,email_from:0 +msgid "Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,channel_id:0 +msgid "Channel" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Name" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Lowest" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,create_date:0 +msgid "Creation Date" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Close" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Pending" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,type:0 +msgid "Type is used to separate Leads and Opportunities" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,categ_ids:0 +msgid "Categories" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,stage_id:0 +msgid "Stage" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_login:0 +msgid "User Login" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,opt_out:0 +msgid "" +"If opt-out is checked, this contact has refused to receive emails or " +"unsubscribed to a campaign." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,contact_name:0 +msgid "Contact Name" +msgstr "" + +#. module: portal_crm +#: model:ir.ui.menu,name:portal_crm.portal_company_contact +msgid "Contact" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_address_email:0 +msgid "Partner Contact Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,planned_revenue:0 +msgid "Expected Revenue" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,task_ids:0 +msgid "Tasks" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Contact form" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_currency:0 +msgid "Currency" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,write_date:0 +msgid "Update Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_deadline:0 +msgid "Expected Closing" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,ref2:0 +msgid "Reference 2" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_email:0 +msgid "User Email" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_open:0 +msgid "Opened" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,state:0 +msgid "In Progress" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_name:0 +msgid "" +"The name of the future partner company that will be created while converting " +"the lead into opportunity" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,planned_cost:0 +msgid "Planned Costs" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,date_deadline:0 +msgid "Estimate of the date on which the opportunity will be won." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,email_cc:0 +msgid "" +"These email addresses will be added to the CC field of all inbound and " +"outbound emails for this record before being sent. Separate multiple email " +"addresses with a comma" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Low" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_closed:0 +#: selection:portal_crm.crm_contact_us,state:0 +msgid "Closed" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_assign:0 +msgid "Assignation Date" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,state:0 +msgid "Status" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "Normal" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,email_cc:0 +msgid "Global CC" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,street2:0 +msgid "Street2" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,id:0 +msgid "ID" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,phone:0 +msgid "Phone" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,active:0 +msgid "Active" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,user_id:0 +msgid "Salesperson" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,day_close:0 +msgid "Days to Close" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,company_ids:0 +msgid "Companies" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,section_id:0 +msgid "" +"When sending mails, the default email address is taken from the sales team." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_address_name:0 +msgid "Partner Contact Name" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_longitude:0 +msgid "Geo Longitude" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,date_assign:0 +msgid "Last date this case was forwarded/assigned to a partner" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,email_from:0 +msgid "Email address of the contact" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,city:0 +msgid "City" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Submit" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,function:0 +msgid "Function" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,referred:0 +msgid "Referred By" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,partner_assigned_id:0 +msgid "Assigned Partner" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,type:0 +msgid "Opportunity" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,partner_assigned_id:0 +msgid "Partner this case has been forwarded/assigned to." +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,country_id:0 +msgid "Country" +msgstr "" + +#. module: portal_crm +#: view:portal_crm.crm_contact_us:0 +msgid "Thank you" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,state:0 +msgid "" +"The Status is set to 'Draft', when a case is created. If the case is in " +"progress the Status is set to 'Open'. When the case is over, the Status is " +"set to 'Done'. If the case needs to be reviewed then the Status is set to " +"'Pending'." +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: portal_crm +#: help:portal_crm.crm_contact_us,type_id:0 +msgid "" +"From which campaign (seminar, marketing campaign, mass mailing, ...) did " +"this contact come from?" +msgstr "" + +#. module: portal_crm +#: selection:portal_crm.crm_contact_us,priority:0 +msgid "High" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,section_id:0 +msgid "Sales Team" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,street:0 +msgid "Street" +msgstr "" + +#. module: portal_crm +#: field:portal_crm.crm_contact_us,date_action_last:0 +msgid "Last Action" +msgstr "" + +#. module: portal_crm +#: model:ir.model,name:portal_crm.model_portal_crm_crm_contact_us +msgid "Contact form for the portal" +msgstr "" diff --git a/addons/portal_event/i18n/fr.po b/addons/portal_event/i18n/fr.po new file mode 100644 index 00000000000..81c0a603fc6 --- /dev/null +++ b/addons/portal_event/i18n/fr.po @@ -0,0 +1,59 @@ +# French translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-05-22 16:32+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: French \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-23 05:19+0000\n" +"X-Generator: Launchpad (build 16640)\n" + +#. module: portal_event +#: view:event.event:0 +msgid "Portal Settings" +msgstr "" + +#. module: portal_event +#: model:ir.actions.act_window,help:portal_event.action_event_view +msgid "There are no public events." +msgstr "" + +#. module: portal_event +#: selection:event.event,visibility:0 +msgid "Private" +msgstr "" + +#. module: portal_event +#: model:ir.model,name:portal_event.model_event_event +msgid "Event" +msgstr "" + +#. module: portal_event +#: model:ir.actions.act_window,name:portal_event.action_event_view +#: model:ir.ui.menu,name:portal_event.portal_company_events +msgid "Events" +msgstr "" + +#. module: portal_event +#: field:event.event,visibility:0 +msgid "Visibility" +msgstr "" + +#. module: portal_event +#: help:event.event,visibility:0 +msgid "Event's visibility in the portal's contact page" +msgstr "" + +#. module: portal_event +#: selection:event.event,visibility:0 +msgid "Public" +msgstr "" diff --git a/addons/portal_event/portal_event_view.xml b/addons/portal_event/portal_event_view.xml old mode 100755 new mode 100644 diff --git a/addons/portal_hr_employees/hr_employee_view.xml b/addons/portal_hr_employees/hr_employee_view.xml index a3182cd5b1c..ace0daaff87 100644 --- a/addons/portal_hr_employees/hr_employee_view.xml +++ b/addons/portal_hr_employees/hr_employee_view.xml @@ -35,11 +35,35 @@ HR - Employess Kanban hr.employee - - - - + + + + +

+
+ +
+
+

+ +

+
    +
  • +
  • +
  • Tel:
  • +
  • Mobile:
  • +
  • +
  • +
+
+
+ + + +
diff --git a/addons/portal_hr_employees/i18n/cs.po b/addons/portal_hr_employees/i18n/cs.po new file mode 100644 index 00000000000..367029b7a38 --- /dev/null +++ b/addons/portal_hr_employees/i18n/cs.po @@ -0,0 +1,95 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-03-30 09:15+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-31 05:28+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Coach" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.actions.act_window,name:portal_hr_employees.action_team +#: view:portal_crm.crm_contact_us:0 +msgid "Our Team" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Group By..." +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Company" +msgstr "" + +#. module: portal_hr_employees +#: selection:hr.employee,visibility:0 +msgid "Public" +msgstr "" + +#. module: portal_hr_employees +#: help:hr.employee,visibility:0 +msgid "Employee's visibility in the portal's contact page" +msgstr "" + +#. module: portal_hr_employees +#: selection:hr.employee,visibility:0 +msgid "Private" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Manager" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.model,name:portal_hr_employees.model_hr_employee +msgid "Employee" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Job" +msgstr "" + +#. module: portal_hr_employees +#: field:hr.employee,visibility:0 +msgid "Visibility" +msgstr "" + +#. module: portal_hr_employees +#: field:hr.employee,public_info:0 +msgid "Public Info" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.model,name:portal_hr_employees.model_portal_crm_crm_contact_us +msgid "Contact form for the portal" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Department" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +#: field:portal_crm.crm_contact_us,employee_ids:0 +msgid "Employees" +msgstr "" diff --git a/addons/portal_hr_employees/i18n/fr.po b/addons/portal_hr_employees/i18n/fr.po new file mode 100644 index 00000000000..3fdc48a35de --- /dev/null +++ b/addons/portal_hr_employees/i18n/fr.po @@ -0,0 +1,95 @@ +# French translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-05-22 16:29+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: French \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-23 05:19+0000\n" +"X-Generator: Launchpad (build 16640)\n" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Coach" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.actions.act_window,name:portal_hr_employees.action_team +#: view:portal_crm.crm_contact_us:0 +msgid "Our Team" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Group By..." +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Company" +msgstr "" + +#. module: portal_hr_employees +#: selection:hr.employee,visibility:0 +msgid "Public" +msgstr "" + +#. module: portal_hr_employees +#: help:hr.employee,visibility:0 +msgid "Employee's visibility in the portal's contact page" +msgstr "" + +#. module: portal_hr_employees +#: selection:hr.employee,visibility:0 +msgid "Private" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Manager" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.model,name:portal_hr_employees.model_hr_employee +msgid "Employee" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Job" +msgstr "" + +#. module: portal_hr_employees +#: field:hr.employee,visibility:0 +msgid "Visibility" +msgstr "" + +#. module: portal_hr_employees +#: field:hr.employee,public_info:0 +msgid "Public Info" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.model,name:portal_hr_employees.model_portal_crm_crm_contact_us +msgid "Contact form for the portal" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Department" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +#: field:portal_crm.crm_contact_us,employee_ids:0 +msgid "Employees" +msgstr "" diff --git a/addons/portal_hr_employees/i18n/lt.po b/addons/portal_hr_employees/i18n/lt.po new file mode 100644 index 00000000000..50a5a872eac --- /dev/null +++ b/addons/portal_hr_employees/i18n/lt.po @@ -0,0 +1,95 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-04-29 15:24+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Coach" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.actions.act_window,name:portal_hr_employees.action_team +#: view:portal_crm.crm_contact_us:0 +msgid "Our Team" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Group By..." +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Company" +msgstr "" + +#. module: portal_hr_employees +#: selection:hr.employee,visibility:0 +msgid "Public" +msgstr "" + +#. module: portal_hr_employees +#: help:hr.employee,visibility:0 +msgid "Employee's visibility in the portal's contact page" +msgstr "" + +#. module: portal_hr_employees +#: selection:hr.employee,visibility:0 +msgid "Private" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Manager" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.model,name:portal_hr_employees.model_hr_employee +msgid "Employee" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Job" +msgstr "" + +#. module: portal_hr_employees +#: field:hr.employee,visibility:0 +msgid "Visibility" +msgstr "" + +#. module: portal_hr_employees +#: field:hr.employee,public_info:0 +msgid "Public Info" +msgstr "" + +#. module: portal_hr_employees +#: model:ir.model,name:portal_hr_employees.model_portal_crm_crm_contact_us +msgid "Contact form for the portal" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +msgid "Department" +msgstr "" + +#. module: portal_hr_employees +#: view:hr.employee:0 +#: field:portal_crm.crm_contact_us,employee_ids:0 +msgid "Employees" +msgstr "" diff --git a/addons/portal_project/__init__.py b/addons/portal_project/__init__.py index 26c654db9dd..164c7826e47 100644 --- a/addons/portal_project/__init__.py +++ b/addons/portal_project/__init__.py @@ -19,3 +19,4 @@ # ############################################################################## +import project diff --git a/addons/portal_project/project.py b/addons/portal_project/project.py new file mode 100644 index 00000000000..fb783c8a531 --- /dev/null +++ b/addons/portal_project/project.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-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 . +# +############################################################################## + +from openerp.osv import osv + + +class portal_project(osv.Model): + """ Update of mail_mail class, to add the signin URL to notifications. """ + _inherit = 'project.project' + + def _get_visibility_selection(self, cr, uid, context=None): + """ Override to add portal option. """ + selection = super(portal_project, self)._get_visibility_selection(cr, uid, context=context) + idx = [item[0] for item in selection].index('public') + selection.insert((idx + 1), ('portal', 'Portal Users and Employees')) + return selection + # return [('public', 'All Users'), + # ('portal', 'Portal Users and Employees'), + # ('employees', 'Employees Only'), + # ('followers', 'Followers Only')] diff --git a/addons/portal_project/security/ir.model.access.csv b/addons/portal_project/security/ir.model.access.csv index 0e743050568..a999f5555d9 100644 --- a/addons/portal_project/security/ir.model.access.csv +++ b/addons/portal_project/security/ir.model.access.csv @@ -5,3 +5,9 @@ access_task_type,task_type,project.model_project_task_type,portal.group_portal,1 access_task_work,task_work,project.model_project_task_work,portal.group_portal,1,0,0,0 access_project_category,project_category,project.model_project_category,portal.group_portal,1,0,0,0 access_account_analytic_account,account_analytic_account,analytic.model_account_analytic_account,portal.group_portal,1,0,0,0 +access_project_anonymous,project,project.model_project_project,portal.group_anonymous,1,0,0,0 +access_task_anonymous,task,project.model_project_task,portal.group_anonymous,1,0,0,0 +access_task_type_anonymous,task_type,project.model_project_task_type,portal.group_anonymous,1,0,0,0 +access_task_work_anonymous,task_work,project.model_project_task_work,portal.group_anonymous,1,0,0,0 +access_project_category_anonymous,project_category,project.model_project_category,portal.group_anonymous,1,0,0,0 +access_account_analytic_account_anonymous,account_analytic_account,analytic.model_account_analytic_account,portal.group_anonymous,1,0,0,0 \ No newline at end of file diff --git a/addons/portal_project/security/portal_security.xml b/addons/portal_project/security/portal_security.xml index 0d995cfd70b..67e57766ebd 100644 --- a/addons/portal_project/security/portal_security.xml +++ b/addons/portal_project/security/portal_security.xml @@ -2,19 +2,67 @@ + + Project: employees: public, portal, employees or following + ['|', + ('privacy_visibility', 'in', ['public', 'portal', 'employees']), + '&', + ('privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] + + + - Portal Projects - - ['|', ('privacy_visibility', '=', 'public'), ('message_follower_ids', 'in', [user.partner_id.id])] + Project: portal users: public, portal or following + + ['|', + ('privacy_visibility', 'in', ['public', 'portal']), + '&', + ('privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] + + Project: anonymous users: public only + + [('privacy_visibility', '=', 'public')] + + + + + Project/Task: employees: public, portal, employee or (followers and following) + ['|', + ('project_id.privacy_visibility', 'in', ['public', 'portal', 'employees']), + '&', + ('project_id.privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] + + - Portal Tasks - - [('message_follower_ids','in', [user.partner_id.id])] + Project/Task: portal users: public or (portal and colleagues following) or (followers and following) + + ['|', '|', + ('project_id.privacy_visibility', 'in', ['public']), + '&', + ('project_id.privacy_visibility', '=', 'portal'), + ('message_follower_ids', 'child_of', [user.partner_id.commercial_partner_id.id]), + '&', + ('project_id.privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] + + Project/Task: anonymous users: public only + + [('project_id.privacy_visibility', '=', 'public')] + + + diff --git a/addons/crm_claim/res_config.py b/addons/portal_project/tests/__init__.py similarity index 63% rename from addons/crm_claim/res_config.py rename to addons/portal_project/tests/__init__.py index aa0cb7ffa20..c79181f7710 100644 --- a/addons/crm_claim/res_config.py +++ b/addons/portal_project/tests/__init__.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Business Applications -# Copyright (C) 2004-2012 OpenERP S.A. (). +# Copyright (c) 2012-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 @@ -19,14 +19,10 @@ # ############################################################################## -from openerp.osv import fields, osv +from . import test_access_rights -class crm_claim_settings(osv.osv_memory): - _name = 'sale.config.settings' - _inherit = ['sale.config.settings', 'fetchmail.config.settings'] +checks = [ + test_access_rights, +] - _columns = { - 'fetchmail_claim': fields.boolean("Create claims from incoming mails", - fetchmail_model='crm.claim', fetchmail_name='Incoming Claims', - help="""Allows you to configure your incoming mail server, and create claims from incoming emails."""), - } +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal_project/tests/test_access_rights.py b/addons/portal_project/tests/test_access_rights.py new file mode 100644 index 00000000000..a7d56cb3895 --- /dev/null +++ b/addons/portal_project/tests/test_access_rights.py @@ -0,0 +1,300 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (c) 2013-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 . +# +############################################################################## + +from openerp.osv.orm import except_orm +from openerp.tests import common +from openerp.tools import mute_logger + + +class TestPortalProject(common.TransactionCase): + + def setUp(self): + super(TestPortalProject, self).setUp() + cr, uid = self.cr, self.uid + + # Useful models + self.project_project = self.registry('project.project') + self.project_task = self.registry('project.task') + self.res_users = self.registry('res.users') + self.res_partner = self.registry('res.partner') + + # Find Employee group + group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user') + self.group_employee_id = group_employee_ref and group_employee_ref[1] or False + + # Find Project User group + group_project_user_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_user') + self.group_project_user_id = group_project_user_ref and group_project_user_ref[1] or False + + # Find Project Manager group + group_project_manager_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_manager') + self.group_project_manager_id = group_project_manager_ref and group_project_manager_ref[1] or False + + # Find Portal group + group_portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal') + self.group_portal_id = group_portal_ref and group_portal_ref[1] or False + + # Find Anonymous group + group_anonymous_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_anonymous') + self.group_anonymous_id = group_anonymous_ref and group_anonymous_ref[1] or False + + # Test users to use through the various tests + self.user_alfred_id = self.res_users.create(cr, uid, { + 'name': 'Alfred EmployeeUser', + 'login': 'alfred', + 'alias_name': 'alfred', + 'groups_id': [(6, 0, [self.group_employee_id, self.group_project_user_id])] + }) + self.user_bert_id = self.res_users.create(cr, uid, { + 'name': 'Bert Nobody', + 'login': 'bert', + 'alias_name': 'bert', + 'groups_id': [(6, 0, [])] + }) + self.user_chell_id = self.res_users.create(cr, uid, { + 'name': 'Chell Portal', + 'login': 'chell', + 'alias_name': 'chell', + 'groups_id': [(6, 0, [self.group_portal_id])] + }) + self.user_donovan_id = self.res_users.create(cr, uid, { + 'name': 'Donovan Anonymous', + 'login': 'donovan', + 'alias_name': 'donovan', + 'groups_id': [(6, 0, [self.group_anonymous_id])] + }) + self.user_ernest_id = self.res_users.create(cr, uid, { + 'name': 'Ernest Manager', + 'login': 'ernest', + 'alias_name': 'ernest', + 'groups_id': [(6, 0, [self.group_project_manager_id])] + }) + + # Test 'Pigs' project + self.project_pigs_id = self.project_project.create(cr, uid, + {'name': 'Pigs', 'privacy_visibility': 'public'}, + {'mail_create_nolog': True}) + # Various test tasks + self.task_1_id = self.project_task.create(cr, uid, + {'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.task_2_id = self.project_task.create(cr, uid, + {'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.task_3_id = self.project_task.create(cr, uid, + {'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.task_4_id = self.project_task.create(cr, uid, + {'name': 'Test4', 'user_id': self.user_alfred_id, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.task_5_id = self.project_task.create(cr, uid, + {'name': 'Test5', 'user_id': self.user_chell_id, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.task_6_id = self.project_task.create(cr, uid, + {'name': 'Test6', 'user_id': self.user_donovan_id, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + + @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm') + def test_00_project_access_rights(self): + """ Test basic project access rights, for project and portal_project """ + cr, uid, pigs_id = self.cr, self.uid, self.project_pigs_id + + # ---------------------------------------- + # CASE1: public project + # ---------------------------------------- + + # Do: Alfred reads project -> ok (employee ok public) + self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name']) + # Test: all project tasks visible + task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: project user cannot see all tasks of a public project') + # Test: all project tasks readable + self.project_task.read(cr, self.user_alfred_id, task_ids, ['name']) + # Test: all project tasks writable + self.project_task.write(cr, self.user_alfred_id, task_ids, {'description': 'TestDescription'}) + + # Do: Bert reads project -> crash, no group + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_bert_id, pigs_id, ['name']) + # Test: no project task visible + self.assertRaises(except_orm, self.project_task.search, + cr, self.user_bert_id, [('project_id', '=', pigs_id)]) + # Test: no project task readable + self.assertRaises(except_orm, self.project_task.read, + cr, self.user_bert_id, task_ids, ['name']) + # Test: no project task writable + self.assertRaises(except_orm, self.project_task.write, + cr, self.user_bert_id, task_ids, {'description': 'TestDescription'}) + + # Do: Chell reads project -> ok (portal ok public) + self.project_project.read(cr, self.user_chell_id, pigs_id, ['name']) + # Test: all project tasks visible + task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: project user cannot see all tasks of a public project') + # Test: all project tasks readable + self.project_task.read(cr, self.user_chell_id, task_ids, ['name']) + # Test: no project task writable + self.assertRaises(except_orm, self.project_task.write, + cr, self.user_chell_id, task_ids, {'description': 'TestDescription'}) + + # Do: Donovan reads project -> ok (anonymous ok public) + self.project_project.read(cr, self.user_donovan_id, pigs_id, ['name']) + # Test: all project tasks visible + task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: anonymous user cannot see all tasks of a public project') + # Test: all project tasks readable + self.project_task.read(cr, self.user_donovan_id, task_ids, ['name']) + # Test: no project task writable + self.assertRaises(except_orm, self.project_task.write, + cr, self.user_donovan_id, task_ids, {'description': 'TestDescription'}) + + # ---------------------------------------- + # CASE2: portal project + # ---------------------------------------- + self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'}) + + # Do: Alfred reads project -> ok (employee ok public) + self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name']) + # Test: all project tasks visible + task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: project user cannot see all tasks of a portal project') + + # Do: Bert reads project -> crash, no group + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_bert_id, pigs_id, ['name']) + # Test: no project task searchable + self.assertRaises(except_orm, self.project_task.search, + cr, self.user_bert_id, [('project_id', '=', pigs_id)]) + + # Data: task follower + self.project_task.message_subscribe_users(cr, self.user_alfred_id, [self.task_1_id, self.task_3_id], [self.user_chell_id]) + + # Do: Chell reads project -> ok (portal ok public) + self.project_project.read(cr, self.user_chell_id, pigs_id, ['name']) + # Test: only followed project tasks visible + assigned + task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_1_id, self.task_3_id, self.task_5_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: portal user should see the followed tasks of a portal project') + + # Do: Donovan reads project -> ko (anonymous ko portal) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_donovan_id, pigs_id, ['name']) + # Test: no project task visible + task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)]) + self.assertFalse(task_ids, 'access rights: anonymous user should not see tasks of a portal project') + + # Data: task follower cleaning + self.project_task.message_unsubscribe_users(cr, self.user_alfred_id, [self.task_1_id, self.task_3_id], [self.user_chell_id]) + + # ---------------------------------------- + # CASE3: employee project + # ---------------------------------------- + self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'}) + + # Do: Alfred reads project -> ok (employee ok employee) + self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name']) + # Test: all project tasks visible + task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: project user cannot see all tasks of an employees project') + + # Do: Bert reads project -> crash, no group + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_bert_id, pigs_id, ['name']) + + # Do: Chell reads project -> ko (portal ko employee) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_chell_id, pigs_id, ['name']) + # Test: no project task visible + assigned + task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + self.assertFalse(task_ids, 'access rights: portal user should not see tasks of an employees project, even if assigned') + + # Do: Donovan reads project -> ko (anonymous ko employee) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_donovan_id, pigs_id, ['name']) + # Test: no project task visible + task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)]) + self.assertFalse(task_ids, 'access rights: anonymous user should not see tasks of an employees project') + + # ---------------------------------------- + # CASE4: followers project + # ---------------------------------------- + self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'}) + + # Do: Alfred reads project -> ko (employee ko followers) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_alfred_id, pigs_id, ['name']) + # Test: no project task visible + task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_4_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: employee user should not see tasks of a not-followed followers project, only assigned') + + # Do: Bert reads project -> crash, no group + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_bert_id, pigs_id, ['name']) + + # Do: Chell reads project -> ko (portal ko employee) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_chell_id, pigs_id, ['name']) + # Test: no project task visible + task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_5_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: portal user should not see tasks of a not-followed followers project, only assigned') + + # Do: Donovan reads project -> ko (anonymous ko employee) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_donovan_id, pigs_id, ['name']) + # Test: no project task visible + task_ids = self.project_task.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)]) + self.assertFalse(task_ids, 'access rights: anonymous user should not see tasks of a followers project') + + # Data: subscribe Alfred, Chell and Donovan as follower + self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_alfred_id, self.user_chell_id, self.user_donovan_id]) + self.project_task.message_subscribe_users(cr, self.user_alfred_id, [self.task_1_id, self.task_3_id], [self.user_chell_id, self.user_alfred_id]) + + # Do: Alfred reads project -> ok (follower ok followers) + self.project_project.read(cr, self.user_alfred_id, pigs_id, ['name']) + # Test: followed + assigned tasks visible + task_ids = self.project_task.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_1_id, self.task_3_id, self.task_4_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: employee user should not see followed + assigned tasks of a follower project') + + # Do: Chell reads project -> ok (follower ok follower) + self.project_project.read(cr, self.user_chell_id, pigs_id, ['name']) + # Test: followed + assigned tasks visible + task_ids = self.project_task.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + test_task_ids = set([self.task_1_id, self.task_3_id, self.task_5_id]) + self.assertEqual(set(task_ids), test_task_ids, + 'access rights: employee user should not see followed + assigned tasks of a follower project') + + # Do: Donovan reads project -> ko (anonymous ko follower even if follower) + self.assertRaises(except_orm, self.project_project.read, + cr, self.user_donovan_id, pigs_id, ['name']) diff --git a/addons/portal_project_issue/i18n/fr.po b/addons/portal_project_issue/i18n/fr.po new file mode 100644 index 00000000000..48fc9e2ea59 --- /dev/null +++ b/addons/portal_project_issue/i18n/fr.po @@ -0,0 +1,40 @@ +# French translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-05-22 08:03+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: French \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-23 05:19+0000\n" +"X-Generator: Launchpad (build 16640)\n" + +#. module: portal_project_issue +#: view:project.issue:0 +msgid "Creation:" +msgstr "" + +#. module: portal_project_issue +#: model:ir.actions.act_window,help:portal_project_issue.project_issue_categ_act0 +msgid "" +"

\n" +" Click to create an issue.\n" +"

\n" +" You can track your issues from this menu and the action we\n" +" will take.\n" +"

\n" +" " +msgstr "" + +#. module: portal_project_issue +#: model:ir.actions.act_window,name:portal_project_issue.project_issue_categ_act0 +msgid "Issues" +msgstr "" diff --git a/addons/portal_project_issue/security/ir.model.access.csv b/addons/portal_project_issue/security/ir.model.access.csv index 80a38366b51..7355f7a9b1d 100644 --- a/addons/portal_project_issue/security/ir.model.access.csv +++ b/addons/portal_project_issue/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_issues,project_issue,project_issue.model_project_issue,portal.group_portal,1,0,0,0 access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal,1,0,0,0 +access_issues_anonymous,project_issue,project_issue.model_project_issue,portal.group_anonymous,1,0,0,0 \ No newline at end of file diff --git a/addons/portal_project_issue/security/portal_security.xml b/addons/portal_project_issue/security/portal_security.xml index a121eeb593e..598c1620a82 100644 --- a/addons/portal_project_issue/security/portal_security.xml +++ b/addons/portal_project_issue/security/portal_security.xml @@ -3,14 +3,35 @@ - Portal Personal Issues - - [('message_follower_ids','in', [user.partner_id.id])] + Project/Issue: portal users: public or (portal and colleagues following) or (followers and following) + + ['|', '|', + ('project_id.privacy_visibility', 'in', ['public']), + '&', + ('project_id.privacy_visibility', '=', 'portal'), + ('message_follower_ids', 'child_of', [user.partner_id.commercial_partner_id.id]), + '&', + ('project_id.privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] - - - - + + + + Project/Issue: employees: public, portal, employee or (followers and following) + ['|', + ('project_id.privacy_visibility', 'in', ['public', 'portal', 'employees']), + '&', + ('project_id.privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] + + + + Project/Issue: anonymous users: public only + + [('project_id.privacy_visibility', '=', 'public')] + diff --git a/addons/portal_project_issue/tests/__init__.py b/addons/portal_project_issue/tests/__init__.py new file mode 100644 index 00000000000..fa5b47ac535 --- /dev/null +++ b/addons/portal_project_issue/tests/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (c) 2013-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 . +# +############################################################################## + +from . import test_access_rights + +checks = [ + test_access_rights, +] + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal_project_issue/tests/test_access_rights.py b/addons/portal_project_issue/tests/test_access_rights.py new file mode 100644 index 00000000000..28d337a4965 --- /dev/null +++ b/addons/portal_project_issue/tests/test_access_rights.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (c) 2013-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 . +# +############################################################################## + +from openerp.addons.portal_project.tests.test_access_rights import TestPortalProject +from openerp.osv.orm import except_orm +from openerp.tools import mute_logger + + +class TestPortalIssueProject(TestPortalProject): + + def setUp(self): + super(TestPortalIssueProject, self).setUp() + cr, uid = self.cr, self.uid + + # Useful models + self.project_issue = self.registry('project.issue') + + # Various test issues + self.issue_1_id = self.project_issue.create(cr, uid, + {'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.issue_2_id = self.project_issue.create(cr, uid, + {'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.issue_3_id = self.project_issue.create(cr, uid, + {'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.issue_4_id = self.project_issue.create(cr, uid, + {'name': 'Test4', 'user_id': self.user_alfred_id, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.issue_5_id = self.project_issue.create(cr, uid, + {'name': 'Test5', 'user_id': self.user_chell_id, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + self.issue_6_id = self.project_issue.create(cr, uid, + {'name': 'Test6', 'user_id': self.user_donovan_id, 'project_id': self.project_pigs_id}, + {'mail_create_nolog': True}) + + @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm') + def test_00_project_access_rights(self): + """ Test basic project access rights, for project and portal_project """ + cr, uid, pigs_id = self.cr, self.uid, self.project_pigs_id + + # ---------------------------------------- + # CASE1: public project + # ---------------------------------------- + + # Do: Alfred reads project -> ok (employee ok public) + # Test: all project issues visible + issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_1_id, self.issue_2_id, self.issue_3_id, self.issue_4_id, self.issue_5_id, self.issue_6_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: project user cannot see all issues of a public project') + # Test: all project issues readable + self.project_issue.read(cr, self.user_alfred_id, issue_ids, ['name']) + # Test: all project issues writable + self.project_issue.write(cr, self.user_alfred_id, issue_ids, {'description': 'TestDescription'}) + + # Do: Bert reads project -> crash, no group + # Test: no project issue visible + self.assertRaises(except_orm, self.project_issue.search, + cr, self.user_bert_id, [('project_id', '=', pigs_id)]) + # Test: no project issue readable + self.assertRaises(except_orm, self.project_issue.read, + cr, self.user_bert_id, issue_ids, ['name']) + # Test: no project issue writable + self.assertRaises(except_orm, self.project_issue.write, + cr, self.user_bert_id, issue_ids, {'description': 'TestDescription'}) + + # Do: Chell reads project -> ok (portal ok public) + # Test: all project issues visible + issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: project user cannot see all issues of a public project') + # Test: all project issues readable + self.project_issue.read(cr, self.user_chell_id, issue_ids, ['name']) + # Test: no project issue writable + self.assertRaises(except_orm, self.project_issue.write, + cr, self.user_chell_id, issue_ids, {'description': 'TestDescription'}) + + # Do: Donovan reads project -> ok (anonymous ok public) + # Test: all project issues visible + issue_ids = self.project_issue.search(cr, self.user_donovan_id, [('project_id', '=', pigs_id)]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: project user cannot see all issues of a public project') + + # ---------------------------------------- + # CASE2: portal project + # ---------------------------------------- + self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'}) + + # Do: Alfred reads project -> ok (employee ok public) + # Test: all project issues visible + issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: project user cannot see all issues of a portal project') + + # Do: Bert reads project -> crash, no group + # Test: no project issue searchable + self.assertRaises(except_orm, self.project_issue.search, + cr, self.user_bert_id, [('project_id', '=', pigs_id)]) + + # Data: issue follower + self.project_issue.message_subscribe_users(cr, self.user_alfred_id, [self.issue_1_id, self.issue_3_id], [self.user_chell_id]) + + # Do: Chell reads project -> ok (portal ok public) + # Test: only followed project issues visible + assigned + issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_5_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: portal user should see the followed issues of a portal project') + + # Data: issue follower cleaning + self.project_issue.message_unsubscribe_users(cr, self.user_alfred_id, [self.issue_1_id, self.issue_3_id], [self.user_chell_id]) + + # ---------------------------------------- + # CASE3: employee project + # ---------------------------------------- + self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'}) + + # Do: Alfred reads project -> ok (employee ok employee) + # Test: all project issues visible + issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_1_id, self.issue_2_id, self.issue_3_id, self.issue_4_id, self.issue_5_id, self.issue_6_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: project user cannot see all issues of an employees project') + + # Do: Chell reads project -> ko (portal ko employee) + # Test: no project issue visible + assigned + issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + self.assertFalse(issue_ids, 'access rights: portal user should not see issues of an employees project, even if assigned') + + # ---------------------------------------- + # CASE4: followers project + # ---------------------------------------- + self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'}) + + # Do: Alfred reads project -> ko (employee ko followers) + # Test: no project issue visible + issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_4_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: employee user should not see issues of a not-followed followers project, only assigned') + + # Do: Chell reads project -> ko (portal ko employee) + # Test: no project issue visible + issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_5_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: portal user should not see issues of a not-followed followers project, only assigned') + + # Data: subscribe Alfred, Chell and Donovan as follower + self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_alfred_id, self.user_chell_id, self.user_donovan_id]) + self.project_issue.message_subscribe_users(cr, self.user_alfred_id, [self.issue_1_id, self.issue_3_id], [self.user_chell_id, self.user_alfred_id]) + + # Do: Alfred reads project -> ok (follower ok followers) + # Test: followed + assigned issues visible + issue_ids = self.project_issue.search(cr, self.user_alfred_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_4_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: employee user should not see followed + assigned issues of a follower project') + + # Do: Chell reads project -> ok (follower ok follower) + # Test: followed + assigned issues visible + issue_ids = self.project_issue.search(cr, self.user_chell_id, [('project_id', '=', pigs_id)]) + test_issue_ids = set([self.issue_1_id, self.issue_3_id, self.issue_5_id]) + self.assertEqual(set(issue_ids), test_issue_ids, + 'access rights: employee user should not see followed + assigned issues of a follower project') diff --git a/addons/portal_project_long_term/security/ir.model.access.csv b/addons/portal_project_long_term/security/ir.model.access.csv index 738c264a71c..efbc4fc2418 100644 --- a/addons/portal_project_long_term/security/ir.model.access.csv +++ b/addons/portal_project_long_term/security/ir.model.access.csv @@ -1,2 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_issues,project_phase,project_long_term.model_project_phase,portal.group_portal,1,0,0,0 +access_issues_anonymous,project_phase_anonymous,project_long_term.model_project_phase,portal.group_anonymous,1,0,0,0 diff --git a/addons/portal_project_long_term/security/portal_security.xml b/addons/portal_project_long_term/security/portal_security.xml index b46d277e4ee..d8aec542847 100644 --- a/addons/portal_project_long_term/security/portal_security.xml +++ b/addons/portal_project_long_term/security/portal_security.xml @@ -3,14 +3,17 @@ - Portal Personal Long term project - - ['|',('project_id.message_follower_ids','in', [user.partner_id.id]),('task_ids.message_follower_ids','in', [user.partner_id.id])] + Project/Phase: portal users: public or (portal and colleagues following) or (followers and following) + + [('project_id.privacy_visibility', 'in', ['public', 'portal'])] - - - - + + + + Project/Phase: anonymous users: public only + + [('project_id.privacy_visibility', '=', 'public')] + diff --git a/addons/portal_sale/i18n/es_MX.po b/addons/portal_sale/i18n/es_MX.po index 33a17839754..2852d1f6327 100644 --- a/addons/portal_sale/i18n/es_MX.po +++ b/addons/portal_sale/i18n/es_MX.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-03-22 04:57+0000\n" -"X-Generator: Launchpad (build 16532)\n" +"X-Launchpad-Export-Date: 2013-03-23 05:10+0000\n" +"X-Generator: Launchpad (build 16540)\n" #. module: portal_sale #: model:ir.model,name:portal_sale.model_account_config_settings diff --git a/addons/portal_sale/i18n/lt.po b/addons/portal_sale/i18n/lt.po new file mode 100644 index 00000000000..92db39babce --- /dev/null +++ b/addons/portal_sale/i18n/lt.po @@ -0,0 +1,344 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-04-29 15:25+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: portal_sale +#: model:ir.model,name:portal_sale.model_account_config_settings +msgid "account.config.settings" +msgstr "" + +#. module: portal_sale +#: model:ir.actions.act_window,help:portal_sale.portal_action_invoices +msgid "We haven't sent you any invoice." +msgstr "" + +#. module: portal_sale +#: model:email.template,report_name:portal_sale.email_template_edi_sale +msgid "" +"${(object.name or '').replace('/','_')}_${object.state == 'draft' and " +"'draft' or ''}" +msgstr "" + +#. module: portal_sale +#: model:res.groups,name:portal_sale.group_payment_options +msgid "View Online Payment Options" +msgstr "" + +#. module: portal_sale +#: field:account.config.settings,group_payment_options:0 +msgid "Show payment buttons to employees too" +msgstr "" + +#. module: portal_sale +#: model:email.template,subject:portal_sale.email_template_edi_sale +msgid "" +"${object.company_id.name} ${object.state in ('draft', 'sent') and " +"'Quotation' or 'Order'} (Ref ${object.name or 'n/a' })" +msgstr "" + +#. module: portal_sale +#: model:ir.actions.act_window,help:portal_sale.action_quotations_portal +msgid "We haven't sent you any quotation." +msgstr "" + +#. module: portal_sale +#: model:ir.ui.menu,name:portal_sale.portal_sales_orders +msgid "Sales Orders" +msgstr "" + +#. module: portal_sale +#: model:res.groups,comment:portal_sale.group_payment_options +msgid "" +"Members of this group see the online payment options\n" +"on Sale Orders and Customer Invoices. These options are meant for customers " +"who are accessing\n" +"their documents through the portal." +msgstr "" + +#. module: portal_sale +#: model:email.template,body_html:portal_sale.email_template_edi_sale +msgid "" +"\n" +"
\n" +"\n" +"

Hello ${object.partner_id.name},

\n" +" \n" +"

Here is your ${object.state in ('draft', 'sent') and 'quotation' or " +"'order confirmation'} from ${object.company_id.name}:

\n" +"\n" +"

\n" +"   REFERENCES
\n" +"   Order number: ${object.name}
\n" +"   Order total: ${object.amount_total} " +"${object.pricelist_id.currency_id.name}
\n" +"   Order date: ${object.date_order}
\n" +" % if object.origin:\n" +"   Order reference: ${object.origin}
\n" +" % endif\n" +" % if object.client_order_ref:\n" +"   Your reference: ${object.client_order_ref}
\n" +" % endif\n" +" % if object.user_id:\n" +"   Your contact: ${object.user_id.name}\n" +" % endif\n" +"

\n" +"\n" +" <% set signup_url = object.get_signup_url() %>\n" +" % if signup_url:\n" +"

\n" +" You can access this document and pay online via our Customer Portal:\n" +"

\n" +" View ${object.state in ('draft', 'sent') " +"and 'Quotation' or 'Order'}\n" +" % endif\n" +"\n" +" % if object.paypal_url:\n" +"
\n" +"

It is also possible to directly pay with Paypal:

\n" +" \n" +" \n" +" \n" +" % endif\n" +"\n" +"
\n" +"

If you have any question, do not hesitate to contact us.

\n" +"

Thank you for choosing ${object.company_id.name or 'us'}!

\n" +"
\n" +"
\n" +"
\n" +"

\n" +" ${object.company_id.name}

\n" +"
\n" +"
\n" +" \n" +" % if object.company_id.street:\n" +" ${object.company_id.street}
\n" +" % endif\n" +" % if object.company_id.street2:\n" +" ${object.company_id.street2}
\n" +" % endif\n" +" % if object.company_id.city or object.company_id.zip:\n" +" ${object.company_id.zip} ${object.company_id.city}
\n" +" % endif\n" +" % if object.company_id.country_id:\n" +" ${object.company_id.state_id and ('%s, ' % " +"object.company_id.state_id.name) or ''} ${object.company_id.country_id.name " +"or ''}
\n" +" % endif\n" +"
\n" +" % if object.company_id.phone:\n" +"
\n" +" Phone:  ${object.company_id.phone}\n" +"
\n" +" % endif\n" +" % if object.company_id.website:\n" +"
\n" +" Web : ${object.company_id.website}\n" +"
\n" +" % endif\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: portal_sale +#: model:email.template,report_name:portal_sale.email_template_edi_invoice +msgid "" +"Invoice_${(object.number or '').replace('/','_')}_${object.state == 'draft' " +"and 'draft' or ''}" +msgstr "" + +#. module: portal_sale +#: model:email.template,subject:portal_sale.email_template_edi_invoice +msgid "${object.company_id.name} Invoice (Ref ${object.number or 'n/a' })" +msgstr "" + +#. module: portal_sale +#: model:ir.model,name:portal_sale.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: portal_sale +#: model:ir.actions.act_window,name:portal_sale.action_quotations_portal +#: model:ir.ui.menu,name:portal_sale.portal_quotations +msgid "Quotations" +msgstr "" + +#. module: portal_sale +#: model:ir.model,name:portal_sale.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: portal_sale +#: field:account.invoice,portal_payment_options:0 +#: field:sale.order,portal_payment_options:0 +msgid "Portal Payment Options" +msgstr "" + +#. module: portal_sale +#: help:account.config.settings,group_payment_options:0 +msgid "" +"Show online payment options on Sale Orders and Customer Invoices to " +"employees. If not checked, these options are only visible to portal users." +msgstr "" + +#. module: portal_sale +#: model:ir.actions.act_window,name:portal_sale.portal_action_invoices +#: model:ir.ui.menu,name:portal_sale.portal_invoices +msgid "Invoices" +msgstr "" + +#. module: portal_sale +#: view:account.config.settings:0 +msgid "Configure payment acquiring methods" +msgstr "" + +#. module: portal_sale +#: model:email.template,body_html:portal_sale.email_template_edi_invoice +msgid "" +"\n" +"
\n" +"\n" +"

Hello ${object.partner_id.name},

\n" +"\n" +"

A new invoice is available for you:

\n" +" \n" +"

\n" +"   REFERENCES
\n" +"   Invoice number: ${object.number}
\n" +"   Invoice total: ${object.amount_total} " +"${object.currency_id.name}
\n" +"   Invoice date: ${object.date_invoice}
\n" +" % if object.origin:\n" +"   Order reference: ${object.origin}
\n" +" % endif\n" +" % if object.user_id:\n" +"   Your contact: ${object.user_id.name}\n" +" % endif\n" +"

\n" +"\n" +" <% set signup_url = object.get_signup_url() %>\n" +" % if signup_url:\n" +"

\n" +" You can access the invoice document and pay online via our Customer " +"Portal:\n" +"

\n" +" View Invoice\n" +" % endif\n" +" \n" +" % if object.paypal_url:\n" +"
\n" +"

It is also possible to directly pay with Paypal:

\n" +" \n" +" \n" +" \n" +" % endif\n" +" \n" +"
\n" +"

If you have any question, do not hesitate to contact us.

\n" +"

Thank you for choosing ${object.company_id.name or 'us'}!

\n" +"
\n" +"
\n" +"
\n" +"

\n" +" ${object.company_id.name}

\n" +"
\n" +"
\n" +" \n" +" % if object.company_id.street:\n" +" ${object.company_id.street}
\n" +" % endif\n" +" % if object.company_id.street2:\n" +" ${object.company_id.street2}
\n" +" % endif\n" +" % if object.company_id.city or object.company_id.zip:\n" +" ${object.company_id.zip} ${object.company_id.city}
\n" +" % endif\n" +" % if object.company_id.country_id:\n" +" ${object.company_id.state_id and ('%s, ' % " +"object.company_id.state_id.name) or ''} ${object.company_id.country_id.name " +"or ''}
\n" +" % endif\n" +"
\n" +" % if object.company_id.phone:\n" +"
\n" +" Phone:  ${object.company_id.phone}\n" +"
\n" +" % endif\n" +" % if object.company_id.website:\n" +"
\n" +" Web : ${object.company_id.website}\n" +"
\n" +" % endif\n" +"

\n" +"
\n" +"
\n" +" " +msgstr "" + +#. module: portal_sale +#: model:ir.actions.act_window,help:portal_sale.action_orders_portal +msgid "We haven't sent you any sales order." +msgstr "" + +#. module: portal_sale +#: model:ir.model,name:portal_sale.model_account_invoice +msgid "Invoice" +msgstr "" + +#. module: portal_sale +#: model:ir.actions.act_window,name:portal_sale.action_orders_portal +msgid "Sale Orders" +msgstr "" diff --git a/addons/portal_sale/portal_sale.py b/addons/portal_sale/portal_sale.py index a6ca616ad2f..07300c5d463 100644 --- a/addons/portal_sale/portal_sale.py +++ b/addons/portal_sale/portal_sale.py @@ -59,19 +59,8 @@ class sale_order(osv.Model): assert len(ids) == 1 document = self.browse(cr, uid, ids[0], context=context) partner = document.partner_id - # TDE note: this code should be improved: used a real invite wizard instead of an ugly email if partner.id not in document.message_follower_ids: self.message_subscribe(cr, uid, ids, [partner.id], context=context) - mail_values = { - 'recipient_ids': [(4, partner.id)], - 'subject': 'Invitation to follow %s' % document.name_get()[0][1], - 'body_html': 'You have been invited to follow %s' % document.name_get()[0][1], - 'auto_delete': True, - 'type': 'email', - } - mail_obj = self.pool.get('mail.mail') - mail_id = mail_obj.create(cr, uid, mail_values, context=context) - mail_obj.send(cr, uid, [mail_id], context=context) return super(sale_order, self).action_button_confirm(cr, uid, ids, context=context) def get_signup_url(self, cr, uid, ids, context=None): @@ -115,25 +104,6 @@ class account_invoice(osv.Model): pass return action_dict - def invoice_validate(self, cr, uid, ids, context=None): - # fetch the partner's id and subscribe the partner to the invoice - document = self.browse(cr, uid, ids[0], context=context) - partner = document.partner_id - # TDE note: this code should be improved: used a real invite wizard instead of an ugly email - if partner.id not in document.message_follower_ids: - self.message_subscribe(cr, uid, ids, [partner.id], context=context) - mail_values = { - 'recipient_ids': [(4, partner.id)], - 'subject': 'Invitation to follow %s' % document.name_get()[0][1], - 'body_html': 'You have been invited to follow %s' % document.name_get()[0][1], - 'auto_delete': True, - 'type': 'email', - } - mail_obj = self.pool.get('mail.mail') - mail_id = mail_obj.create(cr, uid, mail_values, context=context) - mail_obj.send(cr, uid, [mail_id], context=context) - return super(account_invoice, self).invoice_validate(cr, uid, ids, context=context) - def get_signup_url(self, cr, uid, ids, context=None): assert len(ids) == 1 document = self.browse(cr, uid, ids[0], context=context) diff --git a/addons/portal_stock/security/portal_security.xml b/addons/portal_stock/security/portal_security.xml index 154a7fc9ddd..c5587453e40 100644 --- a/addons/portal_stock/security/portal_security.xml +++ b/addons/portal_stock/security/portal_security.xml @@ -17,19 +17,5 @@
- - Portal Personal Stock Moves - - [('message_follower_ids','in',[user.partner_id.id])] - - - - - Portal Personal Stock Warehouse Orderpoints - - [('message_follower_ids','in',[user.partner_id.id])] - - - diff --git a/addons/process/process.py b/addons/process/process.py index 30b37a8b0e2..d6a72148fa6 100644 --- a/addons/process/process.py +++ b/addons/process/process.py @@ -19,7 +19,6 @@ # ############################################################################## -from openerp import pooler from openerp import tools from openerp.osv import fields, osv @@ -53,24 +52,23 @@ class process_process(osv.osv): } def search_by_model(self, cr, uid, res_model, context=None): - pool = pooler.get_pool(cr.dbname) - model_ids = (res_model or None) and pool.get('ir.model').search(cr, uid, [('model', '=', res_model)]) + model_ids = (res_model or None) and self.pool['ir.model'].search(cr, uid, [('model', '=', res_model)]) domain = (model_ids or []) and [('model_id', 'in', model_ids)] result = [] # search all processes - res = pool.get('process.process').search(cr, uid, domain) + res = self.pool['process.process'].search(cr, uid, domain) if res: - res = pool.get('process.process').browse(cr, uid, res, context=context) + res = self.pool['process.process'].browse(cr, uid, res, context=context) for process in res: result.append((process.id, process.name)) return result # else search process nodes - res = pool.get('process.node').search(cr, uid, domain) + res = self.pool['process.node'].search(cr, uid, domain) if res: - res = pool.get('process.node').browse(cr, uid, res, context=context) + res = self.pool['process.node'].browse(cr, uid, res, context=context) for node in res: if (node.process_id.id, node.process_id.name) not in result: result.append((node.process_id.id, node.process_id.name)) @@ -79,9 +77,8 @@ class process_process(osv.osv): def graph_get(self, cr, uid, id, res_model, res_id, scale, context=None): - pool = pooler.get_pool(cr.dbname) - process = pool.get('process.process').browse(cr, uid, id, context=context) + process = self.pool['process.process'].browse(cr, uid, id, context=context) name = process.name resource = False @@ -92,16 +89,16 @@ class process_process(osv.osv): perm = False if res_model: - states = dict(pool.get(res_model).fields_get(cr, uid, context=context).get('state', {}).get('selection', {})) + states = dict(self.pool[res_model].fields_get(cr, uid, context=context).get('state', {}).get('selection', {})) if res_id: - current_object = pool.get(res_model).browse(cr, uid, res_id, context=context) - current_user = pool.get('res.users').browse(cr, uid, uid, context=context) + current_object = self.pool[res_model].browse(cr, uid, res_id, context=context) + current_user = self.pool['res.users'].browse(cr, uid, uid, context=context) expr_context = Env(current_object, current_user) resource = current_object.name if 'state' in current_object: state = states.get(current_object.state, 'N/A') - perm = pool.get(res_model).perm_read(cr, uid, [res_id], context=context)[0] + perm = self.pool[res_model].perm_read(cr, uid, [res_id], context=context)[0] notes = process.note or "N/A" nodes = {} @@ -122,12 +119,12 @@ class process_process(osv.osv): # get assosiated workflow if data['model']: - wkf_ids = self.pool.get('workflow').search(cr, uid, [('osv', '=', data['model'])]) + wkf_ids = self.pool['workflow'].search(cr, uid, [('osv', '=', data['model'])]) data['workflow'] = (wkf_ids or False) and wkf_ids[0] if 'directory_id' in node and node.directory_id: data['directory_id'] = node.directory_id.id - data['directory'] = self.pool.get('document.directory').get_resource_path(cr, uid, data['directory_id'], data['model'], False) + data['directory'] = self.pool['document.directory'].get_resource_path(cr, uid, data['directory_id'], data['model'], False) if node.menu_id: data['menu'] = {'name': node.menu_id.complete_name, 'id': node.menu_id.id} @@ -189,15 +186,15 @@ class process_process(osv.osv): nodes[nid]['res'] = resource = {'id': ref_id, 'model': ref_model} - refobj = pool.get(ref_model).browse(cr, uid, ref_id, context=context) - fields = pool.get(ref_model).fields_get(cr, uid, context=context) + refobj = self.pool[ref_model].browse(cr, uid, ref_id, context=context) + fields = self.pool[ref_model].fields_get(cr, uid, context=context) # check for directory_id from inherited from document module if nodes[nid].get('directory_id', False): - resource['directory'] = self.pool.get('document.directory').get_resource_path(cr, uid, nodes[nid]['directory_id'], ref_model, ref_id) + resource['directory'] = self.pool['document.directory'].get_resource_path(cr, uid, nodes[nid]['directory_id'], ref_model, ref_id) - resource['name'] = pool.get(ref_model).name_get(cr, uid, [ref_id], context=context)[0][1] - resource['perm'] = pool.get(ref_model).perm_read(cr, uid, [ref_id], context=context)[0] + resource['name'] = self.pool[ref_model].name_get(cr, uid, [ref_id], context=context)[0][1] + resource['perm'] = self.pool[ref_model].perm_read(cr, uid, [ref_id], context=context)[0] ref_expr_context = Env(refobj, current_user) try: @@ -261,8 +258,7 @@ class process_process(osv.osv): if not default: default = {} - pool = pooler.get_pool(cr.dbname) - process = pool.get('process.process').browse(cr, uid, id, context=context) + process = self.pool['process.process'].browse(cr, uid, id, context=context) nodes = {} transitions = {} @@ -275,7 +271,7 @@ class process_process(osv.osv): for t in node.transition_out: tr = transitions.setdefault(t.id, {}) tr['source'] = node.id - nodes[node.id] = pool.get('process.node').copy(cr, uid, node.id, context=context) + nodes[node.id] = self.pool['process.node'].copy(cr, uid, node.id, context=context) # then copy transitions with new nodes for tid, tr in transitions.items(): @@ -283,7 +279,7 @@ class process_process(osv.osv): 'source_node_id': nodes[tr['source']], 'target_node_id': nodes[tr['target']] } - tr = pool.get('process.transition').copy(cr, uid, tid, default=vals, context=context) + tr = self.pool['process.transition'].copy(cr, uid, tid, default=vals, context=context) # and finally copy the process itself with new nodes default.update({ @@ -292,7 +288,6 @@ class process_process(osv.osv): }) return super(process_process, self).copy(cr, uid, id, default, context) -process_process() class process_node(osv.osv): _name = 'process.node' @@ -327,7 +322,6 @@ class process_node(osv.osv): }) return super(process_node, self).copy_data(cr, uid, id, default, context=context) -process_node() class process_node_condition(osv.osv): _name = 'process.condition' @@ -338,7 +332,6 @@ class process_node_condition(osv.osv): 'model_id': fields.many2one('ir.model', 'Object', ondelete='set null'), 'model_states': fields.char('Expression', required=True, size=128) } -process_node_condition() class process_transition(osv.osv): _name = 'process.transition' @@ -352,7 +345,6 @@ class process_transition(osv.osv): 'group_ids': fields.many2many('res.groups', 'process_transition_group_rel', 'tid', 'rid', string='Required Groups'), 'note': fields.text('Description', translate=True), } -process_transition() class process_transition_action(osv.osv): _name = 'process.transition.action' @@ -379,12 +371,11 @@ class process_transition_action(osv.osv): if not default: default = {} - state = self.pool.get('process.transition.action').browse(cr, uid, id, context=context).state + state = self.pool['process.transition.action'].browse(cr, uid, id, context=context).state if state: default['state'] = state return super(process_transition_action, self).copy_data(cr, uid, id, default, context) -process_transition_action() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/company.py b/addons/procurement/company.py index 60e2db873e2..1fd08d967f1 100644 --- a/addons/procurement/company.py +++ b/addons/procurement/company.py @@ -33,6 +33,5 @@ class company(osv.osv): 'schedule_range': 730.0, } -company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/i18n/lt.po b/addons/procurement/i18n/lt.po new file mode 100644 index 00000000000..6b2ac1a24be --- /dev/null +++ b/addons/procurement/i18n/lt.po @@ -0,0 +1,1005 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-04-29 15:26+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: procurement +#: model:ir.ui.menu,name:procurement.menu_stock_sched +msgid "Schedulers" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_make_procurement +msgid "Make Procurements" +msgstr "" + +#. module: procurement +#: help:procurement.order.compute.all,automatic:0 +msgid "" +"Triggers an automatic procurement for all products that have a virtual stock " +"under 0. You should probably not use this option, we suggest using a MTO " +"configuration on products." +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Group By..." +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,procurement_draft_ids:0 +msgid "Draft procurement of the product and location of that orderpoint" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "" +"required quantities are always\n" +" available" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "" +"If there are not enough quantities available, the delivery order\n" +" will wait for new products. To fulfill the " +"inventory, you should\n" +" create others rules like orderpoints." +msgstr "" + +#. module: procurement +#: field:procurement.order,procure_method:0 +#: field:product.template,procure_method:0 +msgid "Procurement Method" +msgstr "" + +#. module: procurement +#: selection:product.template,supply_method:0 +msgid "Manufacture" +msgstr "" + +#. module: procurement +#: model:process.process,name:procurement.process_process_serviceproductprocess0 +msgid "Service" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.action_procurement_compute +msgid "Compute Stock Minimum Rules Only" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Rules" +msgstr "" + +#. module: procurement +#: field:procurement.order,company_id:0 +#: field:stock.warehouse.orderpoint,company_id:0 +msgid "Company" +msgstr "" + +#. module: procurement +#: field:procurement.order,product_uos_qty:0 +msgid "UoS Quantity" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Reason" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute:0 +msgid "Compute Procurements" +msgstr "" + +#. module: procurement +#: field:procurement.order,message:0 +msgid "Latest error" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,product_min_qty:0 +msgid "Minimum Quantity" +msgstr "" + +#. module: procurement +#: help:mrp.property,composition:0 +msgid "Not used in computations, for information purpose only." +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,procurement_id:0 +msgid "Latest procurement" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,help:procurement.action_orderpoint_form +msgid "" +"You can define your minimum stock rules, so that OpenERP will automatically " +"create draft manufacturing orders or purchase quotations according to the " +"stock level. Once the virtual stock of a product (= stock on hand minus all " +"confirmed orders and reservations) is below the minimum quantity, OpenERP " +"will generate a procurement request to increase the stock up to the maximum " +"quantity." +msgstr "" + +#. module: procurement +#: field:procurement.order,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: procurement +#: help:procurement.order,message:0 +msgid "Exception occurred while computing procurement orders." +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "Products" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Cancelled" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Permanent Procurement Exceptions" +msgstr "" + +#. module: procurement +#: help:procurement.order,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: procurement +#: view:procurement.order.compute.all:0 +msgid "Scheduler Parameters" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "Stockable products" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:138 +#, python-format +msgid "Invalid Action!" +msgstr "" + +#. module: procurement +#: help:procurement.order,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Ready" +msgstr "" + +#. module: procurement +#: field:procurement.order.compute.all,automatic:0 +msgid "Automatic orderpoint" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,help:procurement.procurement_exceptions +msgid "" +"

\n" +" Procurement Orders represent the need for a certain quantity " +"of products, at a given time, in a given location. Sales Orders are one " +"typical source of Procurement Orders (but these are distinct documents). " +"Depending on the procurement parameters and the product configuration, the " +"procurement engine will attempt to satisfy the need by reserving products " +"from stock, ordering products from a supplier, or passing a manufacturing " +"order, etc. A Procurement Exception occurs when the system cannot find a way " +"to fulfill a procurement. Some exceptions will resolve themselves " +"automatically, but others require manual intervention (those are identified " +"by a specific error message).\n" +"

\n" +" " +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Confirmed" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Retry" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute:0 +#: view:procurement.orderpoint.compute:0 +msgid "Parameters" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Confirm" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Quantity Multiple" +msgstr "" + +#. module: procurement +#: help:procurement.order,origin:0 +msgid "" +"Reference of the document that created this Procurement.\n" +"This is automatically completed by OpenERP." +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Procurement Orders to Process" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_stock_warehouse_orderpoint +msgid "Minimum Inventory Rule" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:370 +#, python-format +msgid "Procurement '%s' is in exception: " +msgstr "" + +#. module: procurement +#: field:procurement.order,priority:0 +msgid "Priority" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Reordering Rules Search" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Waiting" +msgstr "" + +#. module: procurement +#: field:procurement.order,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: procurement +#: field:procurement.order,location_id:0 +#: view:stock.warehouse.orderpoint:0 +#: field:stock.warehouse.orderpoint,location_id:0 +msgid "Location" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_stock_picking +msgid "Picking List" +msgstr "" + +#. module: procurement +#: field:make.procurement,warehouse_id:0 +#: view:stock.warehouse.orderpoint:0 +#: field:stock.warehouse.orderpoint,warehouse_id:0 +msgid "Warehouse" +msgstr "" + +#. module: procurement +#: selection:stock.warehouse.orderpoint,logic:0 +msgid "Best price (not yet active!)" +msgstr "" + +#. module: procurement +#: code:addons/procurement/schedulers.py:110 +#, python-format +msgid "PROC %d: from stock - %3.2f %-5s - %s" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_order_compute +msgid "Compute Procurement" +msgstr "" + +#. module: procurement +#: field:res.company,schedule_range:0 +msgid "Scheduler Range Days" +msgstr "" + +#. module: procurement +#: view:make.procurement:0 +msgid "Ask New Products" +msgstr "" + +#. module: procurement +#: field:make.procurement,date_planned:0 +msgid "Planned Date" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Group By" +msgstr "" + +#. module: procurement +#: field:make.procurement,qty:0 +#: field:procurement.order,product_qty:0 +msgid "Quantity" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:365 +#, python-format +msgid "Not enough stock and no minimum orderpoint rule defined." +msgstr "" + +#. module: procurement +#: field:make.procurement,uom_id:0 +#: view:procurement.order:0 +msgid "Unit of Measure" +msgstr "" + +#. module: procurement +#: selection:procurement.order,procure_method:0 +#: selection:product.template,procure_method:0 +msgid "Make to Stock" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,help:procurement.procurement_action +msgid "" +"

\n" +" Click to create a procurement order. \n" +"

\n" +" A procurement order is used to record a need for a specific\n" +" product at a specific location. Procurement orders are " +"usually\n" +" created automatically from sales orders, pull logistic rules " +"or\n" +" minimum stock rules.\n" +"

\n" +" When the procurement order is confirmed, it automatically\n" +" creates the necessary operations to fullfil the need: " +"purchase\n" +" order proposition, manufacturing order, etc.\n" +"

\n" +" " +msgstr "" + +#. module: procurement +#: help:procurement.order,procure_method:0 +msgid "" +"If you encode manually a Procurement, you probably want to use a make to " +"order method." +msgstr "" + +#. module: procurement +#: model:ir.ui.menu,name:procurement.menu_stock_procurement +msgid "Automatic Procurements" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "" +"use the available\n" +" inventory" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_order +#: model:process.process,name:procurement.process_process_procurementprocess0 +#: view:procurement.order:0 +msgid "Procurement" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.procurement_action +msgid "Procurement Orders" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "To Fix" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Exceptions" +msgstr "" + +#. module: procurement +#: model:process.node,note:procurement.process_node_serviceonorder0 +msgid "Assignment from Production or Purchase Order." +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_mrp_property +msgid "Property" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.act_make_procurement +#: view:make.procurement:0 +msgid "Procurement Request" +msgstr "" + +#. module: procurement +#: view:procurement.orderpoint.compute:0 +msgid "Compute Stock" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,procurement_draft_ids:0 +msgid "Related Procurement Orders" +msgstr "" + +#. module: procurement +#: field:procurement.order,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: procurement +#: selection:mrp.property,composition:0 +msgid "plus" +msgstr "" + +#. module: procurement +#: help:procurement.order,state:0 +msgid "" +"When a procurement is created the status is set to 'Draft'.\n" +" If the procurement is confirmed, the status is set to 'Confirmed'. " +" \n" +"After confirming the status is set to 'Running'.\n" +" If any exception arises in the order then the status is set to " +"'Exception'.\n" +" Once the exception is removed the status becomes 'Ready'.\n" +" It is in 'Waiting'. status when the procurement is waiting for another one " +"to finish." +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,active:0 +msgid "" +"If the active field is set to False, it will allow you to hide the " +"orderpoint without removing it." +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "" +"When you sell this service, nothing special will be triggered\n" +" to deliver the customer, as you set the " +"procurement method as\n" +" 'Make to Stock'." +msgstr "" + +#. module: procurement +#: help:procurement.orderpoint.compute,automatic:0 +msgid "If the stock of a product is under 0, it will act like an orderpoint" +msgstr "" + +#. module: procurement +#: field:procurement.order,product_uom:0 +#: field:stock.warehouse.orderpoint,product_uom:0 +msgid "Product Unit of Measure" +msgstr "" + +#. module: procurement +#: constraint:stock.warehouse.orderpoint:0 +msgid "" +"You have to select a product unit of measure in the same category than the " +"default unit of measure of the product" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Procurement Lines" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "" +"as it's a consumable (as a result of this, the quantity\n" +" on hand may become negative)." +msgstr "" + +#. module: procurement +#: field:procurement.order,note:0 +msgid "Note" +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,product_min_qty:0 +msgid "" +"When the virtual stock goes below the Min Quantity specified for this field, " +"OpenERP generates a procurement to bring the forecasted quantity to the Max " +"Quantity." +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Draft" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.action_compute_schedulers +#: model:ir.ui.menu,name:procurement.menu_stock_proc_schedulers +#: view:procurement.order.compute.all:0 +msgid "Run Schedulers" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute:0 +msgid "This wizard will schedule procurements." +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +#: field:procurement.order,state:0 +msgid "Status" +msgstr "" + +#. module: procurement +#: selection:product.template,supply_method:0 +msgid "Buy" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "for the delivery order." +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Normal" +msgstr "" + +#. module: procurement +#: help:product.template,supply_method:0 +msgid "" +"Manufacture: When procuring the product, a manufacturing order or a task " +"will be generated, depending on the product type. \n" +"Buy: When procuring the product, a purchase order will be generated." +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,product_max_qty:0 +msgid "Maximum Quantity" +msgstr "" + +#. module: procurement +#: field:procurement.order,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:367 +#, python-format +msgid "Not enough stock." +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,active:0 +msgid "Active" +msgstr "" + +#. module: procurement +#: model:process.node,name:procurement.process_node_procureproducts0 +msgid "Procure Products" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:312 +#, python-format +msgid "" +"Please check the quantity in procurement order(s) for the product \"%s\", it " +"should not be 0 or less!" +msgstr "" + +#. module: procurement +#: field:procurement.order,date_planned:0 +msgid "Scheduled date" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Exception" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "" +"When you sell this product, a delivery order will be created.\n" +" OpenERP will consider that the" +msgstr "" + +#. module: procurement +#: code:addons/procurement/schedulers.py:133 +#, python-format +msgid "Automatic OP: %s" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_orderpoint_compute +msgid "Automatic Order Point" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,qty_multiple:0 +msgid "Qty Multiple" +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,qty_multiple:0 +msgid "The procurement quantity will be rounded up to this multiple." +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_res_company +msgid "Companies" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Extra Information" +msgstr "" + +#. module: procurement +#: field:procurement.order,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: procurement +#: sql_constraint:stock.warehouse.orderpoint:0 +msgid "Qty Multiple must be greater than zero." +msgstr "" + +#. module: procurement +#: selection:stock.warehouse.orderpoint,logic:0 +msgid "Order to Max" +msgstr "" + +#. module: procurement +#: field:procurement.order,date_close:0 +msgid "Date Closed" +msgstr "" + +#. module: procurement +#: view:res.company:0 +msgid "Logistics" +msgstr "" + +#. module: procurement +#: help:product.template,procure_method:0 +msgid "" +"Make to Stock: When needed, the product is taken from the stock or we wait " +"for replenishment. \n" +"Make to Order: When needed, the product is purchased or produced." +msgstr "" + +#. module: procurement +#: field:mrp.property,composition:0 +msgid "Properties composition" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:311 +#, python-format +msgid "Data Insufficient !" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_mrp_property_group +#: field:mrp.property,group_id:0 +#: field:mrp.property.group,name:0 +msgid "Property Group" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Misc" +msgstr "" + +#. module: procurement +#: field:stock.move,procurements:0 +msgid "Procurements" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Run Procurement" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Done" +msgstr "" + +#. module: procurement +#: view:make.procurement:0 +#: view:procurement.order.compute:0 +#: view:procurement.order.compute.all:0 +#: view:procurement.orderpoint.compute:0 +msgid "Cancel" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,logic:0 +msgid "Reordering Mode" +msgstr "" + +#. module: procurement +#: field:procurement.order,origin:0 +msgid "Source Document" +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Not urgent" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.product_open_orderpoint +#: view:product.product:0 +msgid "Orderpoints" +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,product_max_qty:0 +msgid "" +"When the virtual stock goes below the Min Quantity, OpenERP generates a " +"procurement to bring the forecasted quantity to the Quantity specified as " +"Max Quantity." +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_order_compute_all +msgid "Compute all schedulers" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Late" +msgstr "" + +#. module: procurement +#: view:board.board:0 +msgid "Procurements in Exception" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.procurement_action5 +#: model:ir.actions.act_window,name:procurement.procurement_action_board +#: model:ir.actions.act_window,name:procurement.procurement_exceptions +#: model:ir.ui.menu,name:procurement.menu_stock_procurement_action +#: view:procurement.order:0 +msgid "Procurement Exceptions" +msgstr "" + +#. module: procurement +#: field:product.product,orderpoint_ids:0 +msgid "Minimum Stock Rules" +msgstr "" + +#. module: procurement +#: view:make.procurement:0 +msgid "" +"Fill is this for to launch a procurement request for this\n" +" product. According to the product configuration, " +"this may\n" +" trigger a draft purchase order, a manufacturing " +"order or\n" +" a new task." +msgstr "" + +#. module: procurement +#: field:procurement.order,close_move:0 +msgid "Close Move at end" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Scheduled Date" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_product_product +#: field:make.procurement,product_id:0 +#: view:procurement.order:0 +#: field:procurement.order,product_id:0 +#: field:stock.warehouse.orderpoint,product_id:0 +msgid "Product" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Temporary" +msgstr "" + +#. module: procurement +#: field:mrp.property,description:0 +#: field:mrp.property.group,description:0 +#: field:procurement.order,name:0 +msgid "Description" +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Urgent" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Running" +msgstr "" + +#. module: procurement +#: model:process.node,name:procurement.process_node_serviceonorder0 +#: selection:procurement.order,procure_method:0 +#: selection:product.template,procure_method:0 +msgid "Make to Order" +msgstr "" + +#. module: procurement +#: field:product.template,supply_method:0 +msgid "Supply Method" +msgstr "" + +#. module: procurement +#: field:procurement.order,move_id:0 +msgid "Reservation" +msgstr "" + +#. module: procurement +#: model:process.node,note:procurement.process_node_procureproducts0 +msgid "The way to procurement depends on the product type." +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "When you sell this product, OpenERP will" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Temporary Procurement Exceptions" +msgstr "" + +#. module: procurement +#: field:mrp.property,name:0 +#: field:stock.warehouse.orderpoint,name:0 +msgid "Name" +msgstr "" + +#. module: procurement +#: selection:mrp.property,composition:0 +msgid "max" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.act_procurement_2_stock_warehouse_orderpoint +#: model:ir.actions.act_window,name:procurement.act_stock_warehouse_2_stock_warehouse_orderpoint +#: model:ir.actions.act_window,name:procurement.action_orderpoint_form +#: model:ir.ui.menu,name:procurement.menu_stock_order_points +#: view:stock.warehouse.orderpoint:0 +msgid "Reordering Rules" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:139 +#, python-format +msgid "Cannot delete Procurement Order(s) which are in %s state." +msgstr "" + +#. module: procurement +#: field:procurement.order,product_uos:0 +msgid "Product UoS" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_product_template +msgid "Product Template" +msgstr "" + +#. module: procurement +#: view:procurement.orderpoint.compute:0 +msgid "" +"Wizard checks all the stock minimum rules and generate procurement order." +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Search Procurement" +msgstr "" + +#. module: procurement +#: help:res.company,schedule_range:0 +msgid "" +"This is the time frame analysed by the scheduler when computing " +"procurements. All procurements that are not between today and today+range " +"are skipped for future computation." +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Very Urgent" +msgstr "" + +#. module: procurement +#: field:procurement.orderpoint.compute,automatic:0 +msgid "Automatic Orderpoint" +msgstr "" + +#. module: procurement +#: help:procurement.order,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Procurement started late" +msgstr "" + +#. module: procurement +#: selection:mrp.property,composition:0 +msgid "min" +msgstr "" + +#. module: procurement +#: view:make.procurement:0 +#: view:procurement.order.compute:0 +#: view:procurement.order.compute.all:0 +#: view:procurement.orderpoint.compute:0 +msgid "or" +msgstr "" + +#. module: procurement +#: code:addons/procurement/schedulers.py:134 +#, python-format +msgid "SCHEDULER" +msgstr "" + +#. module: procurement +#: view:product.product:0 +msgid "Request Procurement" +msgstr "" + +#. module: procurement +#: code:addons/procurement/schedulers.py:87 +#, python-format +msgid "PROC %d: on order - %3.2f %-5s - %s" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:339 +#, python-format +msgid "Products reserved from stock." +msgstr "" diff --git a/addons/procurement/i18n/pt_BR.po b/addons/procurement/i18n/pt_BR.po index 626e66dc827..9e425149ee3 100644 --- a/addons/procurement/i18n/pt_BR.po +++ b/addons/procurement/i18n/pt_BR.po @@ -8,15 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2012-12-21 00:27+0000\n" -"Last-Translator: Fábio Martinelli - http://zupy.com.br " -"\n" +"PO-Revision-Date: 2013-04-18 17:42+0000\n" +"Last-Translator: Thiago Tognoli \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: 2013-03-16 05:43+0000\n" -"X-Generator: Launchpad (build 16532)\n" +"X-Launchpad-Export-Date: 2013-04-19 05:24+0000\n" +"X-Generator: Launchpad (build 16567)\n" #. module: procurement #: model:ir.ui.menu,name:procurement.menu_stock_sched @@ -57,7 +56,7 @@ msgid "" " available" msgstr "" "quantidades necessárias estão sempre\n" -"                            disponíveis" +" disponíveis" #. module: procurement #: view:product.product:0 @@ -68,9 +67,9 @@ msgid "" " create others rules like orderpoints." msgstr "" "Se não houver quantidade suficiente disponível, a ordem de entrega\n" -"                            vai esperar por novos produtos. Para cumprir o " +" vai esperar por novos produtos. Para cumprir o " "inventário, você deve\n" -"                            criar outras regras como ponto de compra." +" criar outras regras como ponto de compra." #. module: procurement #: field:procurement.order,procure_method:0 @@ -632,7 +631,7 @@ msgstr "Provisório" #: model:ir.ui.menu,name:procurement.menu_stock_proc_schedulers #: view:procurement.order.compute.all:0 msgid "Run Schedulers" -msgstr "executar Agendadores" +msgstr "Executar Agendadores" #. module: procurement #: view:procurement.order.compute:0 diff --git a/addons/procurement/schedulers.py b/addons/procurement/schedulers.py index c09d9a22a16..7c9d5ec3290 100644 --- a/addons/procurement/schedulers.py +++ b/addons/procurement/schedulers.py @@ -21,8 +21,8 @@ from datetime import datetime from dateutil.relativedelta import relativedelta -from openerp import netsvc -from openerp import pooler + +import openerp from openerp.osv import osv from openerp.osv import fields from openerp.tools.translate import _ @@ -56,7 +56,7 @@ class procurement_order(osv.osv): context = {} try: if use_new_cursor: - cr = pooler.get_db(use_new_cursor).cursor() + cr = openerp.registry(use_new_cursor).db.cursor() procurement_obj = self.pool.get('procurement.order') if not ids: @@ -155,7 +155,7 @@ class procurement_order(osv.osv): warehouse_obj = self.pool.get('stock.warehouse') warehouse_ids = warehouse_obj.search(cr, uid, [], context=context) - products_ids = product_obj.search(cr, uid, [('purchase_ok', '=', True)], order='id', context=context) + products_ids = product_obj.search(cr, uid, [], order='id', context=context) for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context): context['warehouse'] = warehouse @@ -218,7 +218,7 @@ class procurement_order(osv.osv): if context is None: context = {} if use_new_cursor: - cr = pooler.get_db(use_new_cursor).cursor() + cr = openerp.registry(use_new_cursor).db.cursor() orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') procurement_obj = self.pool.get('procurement.order') diff --git a/addons/procurement/wizard/make_procurement_product.py b/addons/procurement/wizard/make_procurement_product.py index aab49bf8e80..bf83bc73f1a 100644 --- a/addons/procurement/wizard/make_procurement_product.py +++ b/addons/procurement/wizard/make_procurement_product.py @@ -126,6 +126,5 @@ class make_procurement(osv.osv_memory): return res -make_procurement() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/wizard/mrp_procurement.py b/addons/procurement/wizard/mrp_procurement.py index 56386bf234e..fd5a9b530b6 100644 --- a/addons/procurement/wizard/mrp_procurement.py +++ b/addons/procurement/wizard/mrp_procurement.py @@ -46,7 +46,6 @@ class procurement_compute(osv.osv_memory): threaded_calculation.start() return {} -procurement_compute() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/wizard/orderpoint_procurement.py b/addons/procurement/wizard/orderpoint_procurement.py index 8f5f373772d..afc8e2a721f 100644 --- a/addons/procurement/wizard/orderpoint_procurement.py +++ b/addons/procurement/wizard/orderpoint_procurement.py @@ -25,7 +25,6 @@ # import threading -from openerp import pooler from openerp.osv import fields,osv class procurement_compute(osv.osv_memory): @@ -50,7 +49,7 @@ class procurement_compute(osv.osv_memory): """ proc_obj = self.pool.get('procurement.order') #As this function is in a new thread, I need to open a new cursor, because the old one may be closed - new_cr = pooler.get_db(cr.dbname).cursor() + new_cr = self.pool.db.cursor() for proc in self.browse(new_cr, uid, ids, context=context): proc_obj._procure_orderpoint_confirm(new_cr, uid, automatic=proc.automatic, use_new_cursor=new_cr.dbname, context=context) #close the new cursor @@ -69,6 +68,5 @@ class procurement_compute(osv.osv_memory): threaded_calculation.start() return {'type': 'ir.actions.act_window_close'} -procurement_compute() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/procurement/wizard/schedulers_all.py b/addons/procurement/wizard/schedulers_all.py index 9311ffcd11d..aab9657ae5d 100644 --- a/addons/procurement/wizard/schedulers_all.py +++ b/addons/procurement/wizard/schedulers_all.py @@ -20,7 +20,6 @@ ############################################################################## import threading -from openerp import pooler from openerp.osv import fields, osv @@ -46,7 +45,7 @@ class procurement_compute_all(osv.osv_memory): """ proc_obj = self.pool.get('procurement.order') #As this function is in a new thread, i need to open a new cursor, because the old one may be closed - new_cr = pooler.get_db(cr.dbname).cursor() + new_cr = self.pool.db.cursor() for proc in self.browse(new_cr, uid, ids, context=context): proc_obj.run_scheduler(new_cr, uid, automatic=proc.automatic, use_new_cursor=new_cr.dbname,\ context=context) @@ -66,6 +65,5 @@ class procurement_compute_all(osv.osv_memory): threaded_calculation.start() return {'type': 'ir.actions.act_window_close'} -procurement_compute_all() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/partner.py b/addons/product/partner.py index 1d11e909346..fbfee76d0b2 100644 --- a/addons/product/partner.py +++ b/addons/product/partner.py @@ -36,7 +36,9 @@ class res_partner(osv.osv): help="This pricelist will be used, instead of the default one, for sales to the current partner"), } -res_partner() + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist'] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/partner_view.xml b/addons/product/partner_view.xml index acb087533ac..5117da6044e 100644 --- a/addons/product/partner_view.xml +++ b/addons/product/partner_view.xml @@ -8,9 +8,12 @@ - + +
+

Pricelists are managed on

diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index 73707e39807..6fc926980dd 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -64,7 +64,6 @@ class price_type(osv.osv): "currency_id": _get_currency } -price_type() #---------------------------------------------------------- # Price lists @@ -77,7 +76,6 @@ class product_pricelist_type(osv.osv): 'name': fields.char('Name',size=64, required=True, translate=True), 'key': fields.char('Key', size=64, required=True, help="Used in the code to select specific prices based on the context. Keep unchanged."), } -product_pricelist_type() class product_pricelist(osv.osv): @@ -236,7 +234,10 @@ class product_pricelist(osv.osv): qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True - price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) + price = currency_obj.compute(cr, uid, + ptype_src, res['currency_id'], + price_tmp, round=False, + context=context) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] @@ -305,7 +306,6 @@ class product_pricelist(osv.osv): res.update({'item_id': {ids[-1]: res_multi.get('item_id', ids[-1])}}) return res -product_pricelist() class product_pricelist_version(osv.osv): @@ -363,7 +363,6 @@ class product_pricelist_version(osv.osv): ['date_start', 'date_end']) ] -product_pricelist_version() class product_pricelist_item(osv.osv): def _price_field_get(self, cr, uid, context=None): @@ -374,7 +373,7 @@ class product_pricelist_item(osv.osv): result.append((line.id, line.name)) result.append((-1, _('Other Pricelist'))) - result.append((-2, _('Partner section of the product form'))) + result.append((-2, _('Supplier Prices on the product form'))) return result _name = "product.pricelist.item" @@ -443,7 +442,6 @@ class product_pricelist_item(osv.osv): if prod[0]['code']: return {'value': {'name': prod[0]['code']}} return {} -product_pricelist_item() diff --git a/addons/product/product.py b/addons/product/product.py index 33225c92c6f..518e455ddc1 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -84,7 +84,6 @@ class product_uom_categ(osv.osv): _columns = { 'name': fields.char('Name', size=64, required=True, translate=True), } -product_uom_categ() class product_uom(osv.osv): _name = 'product.uom' @@ -208,7 +207,6 @@ class product_uom(osv.osv): raise osv.except_osv(_('Warning!'),_("Cannot change the category of existing Unit of Measure '%s'.") % (uom.name,)) return super(product_uom, self).write(cr, uid, ids, vals, context=context) -product_uom() class product_ul(osv.osv): @@ -218,7 +216,6 @@ class product_ul(osv.osv): 'name' : fields.char('Name', size=64,select=True, required=True, translate=True), 'type' : fields.selection([('unit','Unit'),('pack','Pack'),('box', 'Box'), ('pallet', 'Pallet')], 'Type', required=True), } -product_ul() #---------------------------------------------------------- @@ -283,7 +280,6 @@ class product_category(osv.osv): def child_get(self, cr, uid, ids): return [ids] -product_category() #---------------------------------------------------------- @@ -401,7 +397,6 @@ class product_template(osv.osv): pass return super(product_template, self).name_get(cr, user, ids, context) -product_template() class product_product(osv.osv): def view_header_get(self, cr, uid, view_id, view_type, context=None): @@ -523,6 +518,13 @@ class product_product(osv.osv): def _set_image(self, cr, uid, id, name, value, args, context=None): return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) + def _get_name_template_ids(self, cr, uid, ids, context=None): + result = set() + template_ids = self.pool.get('product.product').search(cr, uid, [('product_tmpl_id', 'in', ids)]) + for el in template_ids: + result.add(el) + return list(result) + _defaults = { 'active': lambda *a: 1, 'price_extra': lambda *a: 0.0, @@ -554,7 +556,11 @@ class product_product(osv.osv): 'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Product Price')), 'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Product Price')), 'pricelist_id': fields.dummy(string='Pricelist', relation='product.pricelist', type='many2one'), - 'name_template': fields.related('product_tmpl_id', 'name', string="Template Name", type='char', size=128, store=True, select=True), + 'name_template': fields.related('product_tmpl_id', 'name', string="Template Name", type='char', size=128, store={ + 'product.template': (_get_name_template_ids, ['name'], 10), + 'product.product': (lambda self, cr, uid, ids, c=None: ids, [], 10), + + }, select=True), 'color': fields.integer('Color Index'), # image: all image fields are base64 encoded and PIL-supported 'image': fields.binary("Image", @@ -588,10 +594,13 @@ class product_product(osv.osv): # Check if the product is last product of this template other_product_ids = self.search(cr, uid, [('product_tmpl_id', '=', tmpl_id), ('id', '!=', product.id)], context=context) if not other_product_ids: - unlink_product_tmpl_ids.append(tmpl_id) + unlink_product_tmpl_ids.append(tmpl_id) unlink_ids.append(product.id) + res = super(product_product, self).unlink(cr, uid, unlink_ids, context=context) + # delete templates after calling super, as deleting template could lead to deleting + # products due to ondelete='cascade' self.pool.get('product.template').unlink(cr, uid, unlink_product_tmpl_ids, context=context) - return super(product_product, self).unlink(cr, uid, unlink_ids, context=context) + return res def onchange_uom(self, cursor, user, ids, uom_id, uom_po_id): if uom_id and uom_po_id: @@ -750,7 +759,6 @@ class product_product(osv.osv): args.append((('categ_id', 'child_of', context['search_default_categ_id']))) return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False) -product_product() class product_packaging(osv.osv): _name = "product.packaging" @@ -816,7 +824,6 @@ class product_packaging(osv.osv): return (10 - (sum % 10)) % 10 checksum = staticmethod(checksum) -product_packaging() class product_supplierinfo(osv.osv): @@ -890,7 +897,6 @@ class product_supplierinfo(osv.osv): res[supplier.id] = price return res _order = 'sequence' -product_supplierinfo() class pricelist_partnerinfo(osv.osv): @@ -902,7 +908,6 @@ class pricelist_partnerinfo(osv.osv): 'price': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Product Price'), help="This price will be considered as a price for the supplier Unit of Measure if any or the default Unit of Measure of the product otherwise"), } _order = 'min_quantity asc' -pricelist_partnerinfo() class res_currency(osv.osv): _inherit = 'res.currency' diff --git a/addons/product/product_report.xml b/addons/product/product_report.xml index 6135fe64bca..791063696c4 100644 --- a/addons/product/product_report.xml +++ b/addons/product/product_report.xml @@ -9,6 +9,7 @@ name="product.pricelist" rml="product/report/product_pricelist.rml" menu="False" - auto="False"/> + parser="product.report.product_pricelist.product_pricelist" + /> diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index ddb1ab3809f..bcc0ae838ae 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -88,6 +88,7 @@
+ @@ -581,6 +582,7 @@ +

The prices below will only be taken into account when your pricelist is set as based on supplier prices.

diff --git a/addons/product/report/product_label.xsl b/addons/product/report/product_label.xsl index 641db73ea7d..5dbb2d64a28 100644 --- a/addons/product/report/product_label.xsl +++ b/addons/product/report/product_label.xsl @@ -67,7 +67,7 @@
diff --git a/addons/product/report/product_pricelist.py b/addons/product/report/product_pricelist.py index 5e9f8cf0a8a..44433f39055 100644 --- a/addons/product/report/product_pricelist.py +++ b/addons/product/report/product_pricelist.py @@ -21,7 +21,6 @@ import time -from openerp import pooler from openerp.osv import osv from openerp.report import report_sxw from openerp.tools.translate import _ @@ -63,20 +62,17 @@ class product_pricelist(report_sxw.rml_parse): return True def _get_pricelist(self, pricelist_id): - pool = pooler.get_pool(self.cr.dbname) - pricelist = pool.get('product.pricelist').read(self.cr, self.uid, [pricelist_id], ['name'], context=self.localcontext)[0] + pricelist = self.pool.get('product.pricelist').read(self.cr, self.uid, [pricelist_id], ['name'], context=self.localcontext)[0] return pricelist['name'] def _get_currency(self, pricelist_id): - pool = pooler.get_pool(self.cr.dbname) - pricelist = pool.get('product.pricelist').read(self.cr, self.uid, [pricelist_id], ['currency_id'], context=self.localcontext)[0] + pricelist = self.pool.get('product.pricelist').read(self.cr, self.uid, [pricelist_id], ['currency_id'], context=self.localcontext)[0] return pricelist['currency_id'][1] # TODO 7.0 - remove this method, its unused def _get_currency_symbol(self, pricelist_id): - pool = pooler.get_pool(self.cr.dbname) - pricelist = pool.get('product.pricelist').read(self.cr, self.uid, [pricelist_id], ['currency_id'], context=self.localcontext)[0] - symbol = pool.get('res.currency').read(self.cr, self.uid, [pricelist['currency_id'][0]], ['symbol'], context=self.localcontext)[0] + pricelist = self.pool.get('product.pricelist').read(self.cr, self.uid, [pricelist_id], ['currency_id'], context=self.localcontext)[0] + symbol = self.pool.get('res.currency').read(self.cr, self.uid, [pricelist['currency_id'][0]], ['symbol'], context=self.localcontext)[0] return symbol['symbol'] or '' def _get_categories(self, products, form): @@ -84,20 +80,19 @@ class product_pricelist(report_sxw.rml_parse): res=[] self.pricelist = form['price_list'] self._set_quantity(form) - pool = pooler.get_pool(self.cr.dbname) pro_ids=[] for product in products: pro_ids.append(product.id) if product.categ_id.id not in cat_ids: cat_ids.append(product.categ_id.id) - cats = pool.get('product.category').name_get(self.cr, self.uid, cat_ids, context=self.localcontext) + cats = self.pool.get('product.category').name_get(self.cr, self.uid, cat_ids, context=self.localcontext) if not cats: return res for cat in cats: - product_ids=pool.get('product.product').search(self.cr, self.uid, [('id', 'in', pro_ids), ('categ_id', '=', cat[0])], context=self.localcontext) + product_ids=self.pool.get('product.product').search(self.cr, self.uid, [('id', 'in', pro_ids), ('categ_id', '=', cat[0])], context=self.localcontext) products = [] - for product in pool.get('product.product').read(self.cr, self.uid, product_ids, ['name', 'code'], context=self.localcontext): + for product in self.pool.get('product.product').read(self.cr, self.uid, product_ids, ['name', 'code'], context=self.localcontext): val = { 'id':product['id'], 'name':product['name'], @@ -116,16 +111,13 @@ class product_pricelist(report_sxw.rml_parse): def _get_price(self, pricelist_id, product_id, qty): sale_price_digits = self.get_digits(dp='Product Price') - pool = pooler.get_pool(self.cr.dbname) pricelist = self.pool.get('product.pricelist').browse(self.cr, self.uid, [pricelist_id], context=self.localcontext)[0] - price_dict = pool.get('product.pricelist').price_get(self.cr, self.uid, [pricelist_id], product_id, qty, context=self.localcontext) + price_dict = self.pool.get('product.pricelist').price_get(self.cr, self.uid, [pricelist_id], product_id, qty, context=self.localcontext) if price_dict[pricelist_id]: price = self.formatLang(price_dict[pricelist_id], digits=sale_price_digits, currency_obj=pricelist.currency_id) else: - res = pool.get('product.product').read(self.cr, self.uid, [product_id]) + res = self.pool.get('product.product').read(self.cr, self.uid, [product_id]) price = self.formatLang(res[0]['list_price'], digits=sale_price_digits, currency_obj=pricelist.currency_id) return price -report_sxw.report_sxw('report.product.pricelist','product.product','addons/product/report/product_pricelist.rml',parser=product_pricelist) - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product/wizard/product_price.py b/addons/product/wizard/product_price.py index 8989e97d656..5b5c4ccd834 100644 --- a/addons/product/wizard/product_price.py +++ b/addons/product/wizard/product_price.py @@ -60,6 +60,5 @@ class product_price_list(osv.osv_memory): 'report_name': 'product.pricelist', 'datas': datas, } -product_price_list() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product_expiry/product_expiry.py b/addons/product_expiry/product_expiry.py index e939e594437..4d8fd49ec4f 100644 --- a/addons/product_expiry/product_expiry.py +++ b/addons/product_expiry/product_expiry.py @@ -19,8 +19,9 @@ ############################################################################## import datetime + +import openerp from openerp.osv import fields, osv -from openerp import pooler class stock_production_lot(osv.osv): _inherit = 'stock.production.lot' @@ -34,7 +35,7 @@ class stock_production_lot(osv.osv): if not context.get('product_id', False): date = False else: - product = pooler.get_pool(cr.dbname).get('product.product').browse( + product = openerp.registry(cr.dbname)['product.product'].browse( cr, uid, context['product_id']) duration = getattr(product, dtype) # set date to False when no expiry time specified on the product @@ -73,7 +74,6 @@ class stock_production_lot(osv.osv): 'removal_date': _get_date('removal_time'), 'alert_date': _get_date('alert_time'), } -stock_production_lot() class product_product(osv.osv): _inherit = 'product.product' @@ -87,5 +87,4 @@ class product_product(osv.osv): 'alert_time': fields.integer('Product Alert Time', help='When a new a Serial Number is issued, this is the number of days before an alert should be notified.'), } -product_product() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product_manufacturer/product_manufacturer.py b/addons/product_manufacturer/product_manufacturer.py index fdd25133433..ea7acf66670 100644 --- a/addons/product_manufacturer/product_manufacturer.py +++ b/addons/product_manufacturer/product_manufacturer.py @@ -28,7 +28,6 @@ class product_product(osv.osv): 'manufacturer_pref' : fields.char('Manufacturer Product Code', size=64), 'attribute_ids': fields.one2many('product.manufacturer.attribute', 'product_id', 'Attributes'), } -product_product() class product_attribute(osv.osv): _name = "product.manufacturer.attribute" @@ -38,6 +37,5 @@ class product_attribute(osv.osv): 'value' : fields.char('Value', size=64), 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade'), } -product_attribute() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py index f9187647f35..1bbfe8c285b 100644 --- a/addons/product_margin/product_margin.py +++ b/addons/product_margin/product_margin.py @@ -128,6 +128,5 @@ class product_product(osv.osv): help="Expected margin * 100 / Expected Sale"), } -product_product() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product_margin/wizard/product_margin.py b/addons/product_margin/wizard/product_margin.py index 6c54bd72be3..7a56ed2e13d 100644 --- a/addons/product_margin/wizard/product_margin.py +++ b/addons/product_margin/wizard/product_margin.py @@ -81,6 +81,5 @@ class product_margin(osv.osv_memory): 'search_view_id': id['res_id'] } -product_margin() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/product_visible_discount/product_visible_discount.py b/addons/product_visible_discount/product_visible_discount.py index 3928c2e4676..4f8a7b0b9cc 100644 --- a/addons/product_visible_discount/product_visible_discount.py +++ b/addons/product_visible_discount/product_visible_discount.py @@ -33,7 +33,6 @@ class product_pricelist(osv.osv): 'visible_discount': True, } -product_pricelist() class sale_order_line(osv.osv): _inherit = "sale.order.line" @@ -95,7 +94,6 @@ class sale_order_line(osv.osv): result['discount'] = 0.0 return res -sale_order_line() class account_invoice_line(osv.osv): _inherit = "account.invoice.line" @@ -161,6 +159,5 @@ class account_invoice_line(osv.osv): result['discount']=0.0 return res -account_invoice_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/company.py b/addons/project/company.py index 459c24e7b8a..19f40436070 100644 --- a/addons/project/company.py +++ b/addons/project/company.py @@ -31,7 +31,6 @@ class res_company(osv.osv): "forget to setup the right unit of measure in your employees.", ), } -res_company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/html/Mario-Riva.png b/addons/project/html/Mario-Riva.png new file mode 100644 index 00000000000..35b030a4265 Binary files /dev/null and b/addons/project/html/Mario-Riva.png differ diff --git a/addons/project/html/Yoshi-Tashiro.png b/addons/project/html/Yoshi-Tashiro.png new file mode 100644 index 00000000000..f3457a9088e Binary files /dev/null and b/addons/project/html/Yoshi-Tashiro.png differ diff --git a/addons/project/html/index.html b/addons/project/html/index.html new file mode 100644 index 00000000000..21f4c93b0d2 --- /dev/null +++ b/addons/project/html/index.html @@ -0,0 +1,196 @@ +
+
+

Project Management

+

Infinitely flexible. Incredibly easy to use.

+
+
+ + + +   + +
+
+
+

+OpenERP's collaborative and realtime project management helps your team get +work done. Keep track of everything, from the big picture to the minute +details, from the customer contract to the billing. +

+ +
+
+
+ +
+
+

Designed to fit your own process

+
+

+Organize projects around your own processes. Work on tasks and issues using the kanban view, schedule tasks using the gantt chart +and control deadlines in the calendar view. Every project may have it's own stages +allowing teams to optimize their job. +

+
+
+

Kanban

+
+ +
+
+
+

Gantt Charts

+ +

+
+
+

Calendar

+ +
+
+
+ +
+
+

Easy to use

+
+ +
+
+

+Get organized as fast as you can think. The easy-to-use interface takes no time +to learn, and every action is instantaneous, so there’s nothing standing +between you and your sweet productive flow. +

+
+
+
+ +
+

Work Together

+

Real time chats, document sharing, email integration

+
+
+

+Use open chatter to communicate with your team or customers and share comments +and documents on tasks and issues. Integrate discussion fast with the email +integration. +

+Talk to others users or customers with the live chat feature. +

+
+
+ +
+
+
+ +
+
+

Collaborative Writing

+

The power of etherpad, inside your tasks

+
+ +
+
+

+Collaboratively edit the same specifications or meeting minutes right inside the +application. The incorporated etherpad feature allows several people to work +on the same tasks, at the same time. +

+

+This is very efficient for scrum meetings, meeting minutes or complex +specifications. Every user has their own color and you can replay the whole +creation of the content. +

+
+
+
+ +
+
+

Get Work Done

+
+

+Get alerts on followed events to stay up to date with what interests you. Use +instant green/red visual indicators to scan through what has been done and what +requires your attention. +

+
+
+ +
+
+
+ +
+
+

Timesheets, Contracts & Invoicing

+
+ +
+
+

+Projects are automatically integrated with customer contracts allowing you to +invoice based on time & materials and record timesheets easily. +

+
+
+
+ + +
+
+

Track Issues

+

Support services, helpdesk, bug tracker, etc.

+
+

+Single out the issues that arise in a project in order to have a better focus +on resolving them. Integrate customer interaction on every issue and get +accurate reports on your team's performance. +

+
+
+
+ +
+
+
+
+ +
+
+
+

Many companies already enjoy it

+

Hear what they have to say !

+
+
+
+ + OpenERP provides essential platform for our project management. + Things are better organized and much more visible with it. + + + +
Yoshi Tashiro
+
Managing Director, RoomsFor (Hong Kong)
+
+
+
+
+
+ + The possibility to link the Project Management to Sales and Manufacturing widely + extends the range of possible applications beyond the needs of service companies. + + + +
Mario Riva
+ +
+
+
+
+
diff --git a/addons/project/html/project_01.png b/addons/project/html/project_01.png new file mode 100644 index 00000000000..0c86a2965d5 Binary files /dev/null and b/addons/project/html/project_01.png differ diff --git a/addons/project/html/project_calendar.png b/addons/project/html/project_calendar.png new file mode 100644 index 00000000000..f8c8fca7662 Binary files /dev/null and b/addons/project/html/project_calendar.png differ diff --git a/addons/project/html/project_chat.png b/addons/project/html/project_chat.png new file mode 100644 index 00000000000..8cb771e876f Binary files /dev/null and b/addons/project/html/project_chat.png differ diff --git a/addons/project/html/project_easy.png b/addons/project/html/project_easy.png new file mode 100644 index 00000000000..4ffde14b42b Binary files /dev/null and b/addons/project/html/project_easy.png differ diff --git a/addons/project/html/project_etherpad.png b/addons/project/html/project_etherpad.png new file mode 100644 index 00000000000..038b210ee18 Binary files /dev/null and b/addons/project/html/project_etherpad.png differ diff --git a/addons/project/html/project_gantt.png b/addons/project/html/project_gantt.png new file mode 100644 index 00000000000..34486b98558 Binary files /dev/null and b/addons/project/html/project_gantt.png differ diff --git a/addons/project/html/project_illu_01.png b/addons/project/html/project_illu_01.png new file mode 100644 index 00000000000..4fff4837faa Binary files /dev/null and b/addons/project/html/project_illu_01.png differ diff --git a/addons/project/html/project_kanban.png b/addons/project/html/project_kanban.png new file mode 100644 index 00000000000..c541d3b5d08 Binary files /dev/null and b/addons/project/html/project_kanban.png differ diff --git a/addons/project/html/project_kpi.png b/addons/project/html/project_kpi.png new file mode 100644 index 00000000000..c58f8176098 Binary files /dev/null and b/addons/project/html/project_kpi.png differ diff --git a/addons/project/html/project_timesheet.png b/addons/project/html/project_timesheet.png new file mode 100644 index 00000000000..d06c3a924ec Binary files /dev/null and b/addons/project/html/project_timesheet.png differ diff --git a/addons/project/i18n/th.po b/addons/project/i18n/th.po new file mode 100644 index 00000000000..7dfd58eee63 --- /dev/null +++ b/addons/project/i18n/th.po @@ -0,0 +1,2109 @@ +# Thai translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-05-15 07:02+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Thai \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-16 05:12+0000\n" +"X-Generator: Launchpad (build 16626)\n" + +#. module: project +#: view:project.project:0 +msgid "Email Interface" +msgstr "" + +#. module: project +#: help:account.analytic.account,use_tasks:0 +msgid "" +"If checked, this contract will be available in the project menu and you will " +"be able to manage tasks or track issues" +msgstr "" + +#. module: project +#: field:project.project,progress_rate:0 +#: view:report.project.task.user:0 +#: field:report.project.task.user,progress:0 +msgid "Progress" +msgstr "" + +#. module: project +#: model:process.node,name:project.process_node_taskbydelegate0 +msgid "Task by delegate" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Parent" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.dblc_proj +msgid "Project's tasks" +msgstr "" + +#. module: project +#: field:project.task.type,name:0 +msgid "Stage Name" +msgstr "" + +#. module: project +#: model:process.transition.action,name:project.process_transition_action_openpendingtask0 +msgid "Set pending" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "New Project Based on Template" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,day:0 +msgid "Day" +msgstr "" + +#. module: project +#: model:project.task.type,name:project.project_tt_merge +msgid "Merge" +msgstr "" + +#. module: project +#: view:res.partner:0 +msgid "Start Task" +msgstr "" + +#. module: project +#: code:addons/project/project.py:932 +#, python-format +msgid "Warning !" +msgstr "" + +#. module: project +#: help:project.project,message_unread:0 +#: help:project.task,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: project +#: model:process.node,name:project.process_node_donetask0 +msgid "Done task" +msgstr "" + +#. module: project +#: model:process.node,note:project.process_node_donetask0 +msgid "Task is Completed" +msgstr "" + +#. module: project +#: view:res.partner:0 +msgid "False" +msgstr "" + +#. module: project +#: model:project.task.type,name:project.project_tt_testing +msgid "Testing" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_account_analytic_account +msgid "Analytic Account" +msgstr "" + +#. module: project +#: field:project.config.settings,group_time_work_estimation_tasks:0 +msgid "Manage time estimation on tasks" +msgstr "" + +#. module: project +#: help:project.project,message_summary:0 +#: help:project.task,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: project +#: code:addons/project/project.py:432 +#: code:addons/project/project.py:1318 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_res_partner +msgid "Partner" +msgstr "" + +#. module: project +#: field:project.config.settings,group_manage_delegation_task:0 +msgid "Allow task delegation" +msgstr "" + +#. module: project +#: field:project.task.delegate,planned_hours:0 +#: view:report.project.task.user:0 +#: field:report.project.task.user,hours_planned:0 +msgid "Planned Hours" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Reset as Project" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "In progress tasks" +msgstr "" + +#. module: project +#: help:project.project,progress_rate:0 +msgid "Percent of tasks closed according to the total of tasks todo." +msgstr "" + +#. module: project +#: model:ir.actions.client,name:project.action_client_project_menu +msgid "Open Project Menu" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,help:project.action_project_task_user_tree +msgid "" +"This report allows you to analyse the performance of your projects and " +"users. You can analyse the quantities of tasks, the hours spent compared to " +"the planned hours, the average number of days to open or close a task, etc." +msgstr "" + +#. module: project +#: view:project.task.delegate:0 +msgid "Validation Task Title" +msgstr "" + +#. module: project +#: model:res.groups,name:project.group_delegate_task +msgid "Task Delegation" +msgstr "" + +#. module: project +#: field:project.project,planned_hours:0 +#: field:project.task.history,planned_hours:0 +#: field:project.task.history.cumulative,planned_hours:0 +msgid "Planned Time" +msgstr "" + +#. module: project +#: selection:project.project,privacy_visibility:0 +msgid "Public" +msgstr "" + +#. module: project +#: model:project.category,name:project.project_category_01 +msgid "Contact's suggestion" +msgstr "" + +#. module: project +#: help:project.config.settings,group_time_work_estimation_tasks:0 +msgid "Allows you to compute Time Estimation on tasks." +msgstr "" + +#. module: project +#: field:report.project.task.user,user_id:0 +msgid "Assigned To" +msgstr "" + +#. module: project +#: model:mail.message.subtype,name:project.mt_project_task_closed +#: model:mail.message.subtype,name:project.mt_task_closed +msgid "Task Done" +msgstr "" + +#. module: project +#: view:project.project:0 +#: view:report.project.task.user:0 +#: field:report.project.task.user,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: project +#: model:process.transition,name:project.process_transition_delegate0 +#: view:project.task:0 +msgid "Delegate" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.open_view_template_project +#: view:project.project:0 +msgid "Templates of Projects" +msgstr "" + +#. module: project +#: field:project.project,analytic_account_id:0 +msgid "Contract/Analytic" +msgstr "" + +#. module: project +#: view:project.config.settings:0 +msgid "Project Management" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.action_project_task_delegate +#: view:project.task.delegate:0 +msgid "Project Task Delegate" +msgstr "" + +#. module: project +#: model:mail.message.subtype,name:project.mt_project_task_started +#: model:mail.message.subtype,name:project.mt_task_started +msgid "Task Started" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Very Important" +msgstr "" + +#. module: project +#: view:project.config.settings:0 +msgid "Support" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Member" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Cancel Task" +msgstr "" + +#. module: project +#: help:project.project,members:0 +msgid "" +"Project's members are users who can have an access to the tasks related to " +"this project." +msgstr "" + +#. module: project +#: view:project.project:0 +#: field:project.task,manager_id:0 +msgid "Project Manager" +msgstr "" + +#. module: project +#: field:project.project,state:0 +#: field:project.task,state:0 +#: field:project.task.history,state:0 +#: field:project.task.history.cumulative,state:0 +#: field:report.project.task.user,state:0 +msgid "Status" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "August" +msgstr "" + +#. module: project +#: view:project.project:0 +#: field:project.project,complete_name:0 +msgid "Project Name" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "June" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "October" +msgstr "" + +#. module: project +#: help:project.project,total_hours:0 +msgid "" +"Sum of total hours of all tasks related to this project and its child " +"projects." +msgstr "" + +#. module: project +#: help:project.project,active:0 +msgid "" +"If the active field is set to False, it will allow you to hide the project " +"without removing it." +msgstr "" + +#. module: project +#: model:process.transition,note:project.process_transition_opendonetask0 +msgid "When task is completed, it will come into the done state." +msgstr "" + +#. module: project +#: field:project.project,message_summary:0 +#: field:project.task,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Append this project to another one using analytic accounts hierarchy" +msgstr "" + +#. module: project +#: view:project.task:0 +#: view:project.task.history.cumulative:0 +msgid "In Progress Tasks" +msgstr "" + +#. module: project +#: help:res.company,project_time_mode_id:0 +msgid "" +"This will set the unit of measure used in projects and tasks.\n" +"If you use the timesheet linked to projects (project_timesheet module), " +"don't forget to setup the right unit of measure in your employees." +msgstr "" + +#. module: project +#: field:project.task,user_id:0 +#: view:report.project.task.user:0 +msgid "Assigned to" +msgstr "" + +#. module: project +#: code:addons/project/project.py:1021 +#, python-format +msgid "Delegated User should be specified" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Project(s) Manager" +msgstr "" + +#. module: project +#: selection:project.project,state:0 +#: view:project.task:0 +#: selection:project.task,state:0 +#: selection:project.task.history,state:0 +#: selection:project.task.history.cumulative,state:0 +#: selection:project.task.type,state:0 +#: selection:report.project.task.user,state:0 +msgid "In Progress" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Reactivate" +msgstr "" + +#. module: project +#: field:project.project,resource_calendar_id:0 +msgid "Working Time" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.action_project_task_reevaluate +msgid "Re-evaluate Task" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Validate planned time" +msgstr "" + +#. module: project +#: field:project.config.settings,module_pad:0 +msgid "Use integrated collaborative note pads on task" +msgstr "" + +#. module: project +#: model:mail.message.subtype,name:project.mt_project_task_blocked +#: model:mail.message.subtype,name:project.mt_task_blocked +msgid "Task Blocked" +msgstr "" + +#. module: project +#: model:process.node,note:project.process_node_opentask0 +msgid "Encode your working hours." +msgstr "" + +#. module: project +#: field:project.project,alias_id:0 +msgid "Alias" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "oe_kanban_text_red" +msgstr "" + +#. module: project +#: model:mail.message.subtype,description:project.mt_task_blocked +msgid "Task blocked" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Delegation" +msgstr "" + +#. module: project +#: field:project.task,create_date:0 +msgid "Create Date" +msgstr "" + +#. module: project +#: view:res.partner:0 +msgid "For changing to open state" +msgstr "" + +#. module: project +#: view:project.config.settings:0 +msgid "Apply" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_task_delegate +msgid "Task Delegate" +msgstr "" + +#. module: project +#: help:project.task.delegate,new_task_description:0 +msgid "Reinclude the description of the task in the task of the user" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Project Settings" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "My tasks" +msgstr "" + +#. module: project +#: model:process.transition,name:project.process_transition_opendonetask0 +msgid "Open Done Task" +msgstr "" + +#. module: project +#: field:project.task.delegate,planned_hours_me:0 +msgid "Hours to Validate" +msgstr "" + +#. module: project +#: help:project.task,remaining_hours:0 +msgid "" +"Total remaining time, can be re-estimated periodically by the assignee of " +"the task." +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "March" +msgstr "" + +#. module: project +#: view:board.board:0 +#: model:ir.actions.act_window,name:project.my_open_tasks_action +#: view:project.task:0 +#: view:project.task.history.cumulative:0 +msgid "My Tasks" +msgstr "" + +#. module: project +#: constraint:project.task:0 +msgid "Error ! You cannot create recursive tasks." +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "Pending tasks" +msgstr "" + +#. module: project +#: view:project.task.reevaluate:0 +msgid "_Evaluate" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,opening_days:0 +msgid "Days to Open" +msgstr "" + +#. module: project +#: selection:report.project.task.user,priority:0 +msgid "Very urgent" +msgstr "" + +#. module: project +#: help:project.task.delegate,project_id:0 +#: help:project.task.delegate,user_id:0 +msgid "User you want to delegate this task to" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Set as Template" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_task +#: view:project.config.settings:0 +#: view:project.project:0 +#: view:project.task:0 +#: field:project.task.history,task_id:0 +#: field:project.task.history.cumulative,task_id:0 +#: field:project.task.work,task_id:0 +#: view:report.project.task.user:0 +msgid "Task" +msgstr "" + +#. module: project +#: help:project.config.settings,group_tasks_work_on_tasks:0 +msgid "Allows you to compute work on tasks." +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Administration" +msgstr "" + +#. module: project +#: field:project.config.settings,group_tasks_work_on_tasks:0 +msgid "Log work activities on tasks" +msgstr "" + +#. module: project +#: model:project.task.type,name:project.project_tt_analysis +msgid "Analysis" +msgstr "" + +#. module: project +#: field:project.task,name:0 +#: field:report.project.task.user,name:0 +msgid "Task Summary" +msgstr "" + +#. module: project +#: field:project.task,active:0 +msgid "Not a Template Task" +msgstr "" + +#. module: project +#: field:project.task,planned_hours:0 +msgid "Initially Planned Hours" +msgstr "" + +#. module: project +#: model:process.transition,note:project.process_transition_delegate0 +msgid "Delegates tasks to the other user" +msgstr "" + +#. module: project +#: help:project.task,effective_hours:0 +msgid "Computed using the sum of the task work done." +msgstr "" + +#. module: project +#: model:ir.actions.act_window,help:project.open_view_project_all +msgid "" +"

\n" +" Click to start a new project.\n" +"

\n" +" Projects are used to organize your activities; plan\n" +" tasks, track issues, invoice timesheets. You can define\n" +" internal projects (R&D, Improve Sales Process),\n" +" private projects (My Todos) or customer ones.\n" +"

\n" +" You will be able collaborate with internal users on\n" +" projects or invite customers to share your activities.\n" +"

\n" +" " +msgstr "" + +#. module: project +#: view:project.config.settings:0 +msgid "Planning" +msgstr "" + +#. module: project +#: view:project.task:0 +#: field:project.task,date_deadline:0 +#: field:report.project.task.user,date_deadline:0 +msgid "Deadline" +msgstr "" + +#. module: project +#: view:project.task.history.cumulative:0 +msgid "Ready" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "New Tasks" +msgstr "" + +#. module: project +#: field:project.config.settings,module_project_issue_sheet:0 +msgid "Invoice working time on issues" +msgstr "" + +#. module: project +#: view:project.project:0 +#: view:project.task:0 +#: field:project.task.history,end_date:0 +#: field:project.task.history.cumulative,end_date:0 +msgid "End Date" +msgstr "" + +#. module: project +#: model:project.task.type,name:project.project_tt_specification +msgid "Specification" +msgstr "" + +#. module: project +#: model:process.transition,note:project.process_transition_draftopentask0 +msgid "From draft state, it will come into the open state." +msgstr "" + +#. module: project +#: view:project.task.history.cumulative:0 +msgid "Task's Analysis" +msgstr "" + +#. module: project +#: view:project.task.delegate:0 +#: field:project.task.delegate,new_task_description:0 +msgid "New Task Description" +msgstr "" + +#. module: project +#: field:report.project.task.user,delay_endings_days:0 +msgid "Overpassed Deadline" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "New tasks" +msgstr "" + +#. module: project +#: selection:project.task,priority:0 +#: selection:report.project.task.user,priority:0 +msgid "Medium" +msgstr "" + +#. module: project +#: field:project.project,total_hours:0 +msgid "Total Time" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "Creation Date" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Miscellaneous" +msgstr "" + +#. module: project +#: view:project.task:0 +#: field:project.task,stage_id:0 +#: field:project.task.history,type_id:0 +#: field:project.task.history.cumulative,type_id:0 +msgid "Stage" +msgstr "" + +#. module: project +#: model:process.transition,name:project.process_transition_draftopentask0 +msgid "Draft Open task" +msgstr "" + +#. module: project +#: field:project.project,alias_model:0 +msgid "Alias Model" +msgstr "" + +#. module: project +#: help:report.project.task.user,closing_days:0 +msgid "Number of Days to close the task" +msgstr "" + +#. module: project +#: view:board.board:0 +msgid "My Board" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.open_task_type_form +msgid "Stages" +msgstr "" + +#. module: project +#: view:project.project:0 +#: view:project.task:0 +msgid "Delete" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "In progress" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "September" +msgstr "" + +#. module: project +#: selection:report.project.task.user,priority:0 +msgid "Urgent" +msgstr "" + +#. module: project +#: model:project.category,name:project.project_category_02 +msgid "Feature request" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Delegated tasks" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_task_work +msgid "Project Task Work" +msgstr "" + +#. module: project +#: code:addons/project/wizard/project_task_delegate.py:81 +#, python-format +msgid "CHECK: %s" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Close Project" +msgstr "" + +#. module: project +#: field:project.project,tasks:0 +msgid "Task Activities" +msgstr "" + +#. module: project +#: field:project.project,effective_hours:0 +#: field:project.task.work,hours:0 +msgid "Time Spent" +msgstr "" + +#. module: project +#: view:project.project:0 +#: view:project.task:0 +msgid "í" +msgstr "" + +#. module: project +#: field:account.analytic.account,company_uom_id:0 +msgid "unknown" +msgstr "" + +#. module: project +#: field:project.project,message_is_follower:0 +#: field:project.task,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: project +#: field:project.task,work_ids:0 +msgid "Work done" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "Extended Filters..." +msgstr "" + +#. module: project +#: model:ir.ui.menu,name:project.menu_tasks_config +msgid "GTD" +msgstr "" + +#. module: project +#: help:project.task,state:0 +msgid "" +"The status is set to 'Draft', when a case is created. " +"If the case is in progress the status is set to 'Open'. " +"When the case is over, the status is set to 'Done'. If " +"the case needs to be reviewed then the status is set " +"to 'Pending'." +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_res_company +msgid "Companies" +msgstr "" + +#. module: project +#: field:project.task.type,fold:0 +msgid "Folded by Default" +msgstr "" + +#. module: project +#: field:project.task.history,date:0 +#: field:project.task.history.cumulative,date:0 +#: field:project.task.work,date:0 +msgid "Date" +msgstr "" + +#. module: project +#: help:project.config.settings,module_project_issue:0 +msgid "" +"Provides management of issues/bugs in projects.\n" +" This installs the module project_issue." +msgstr "" + +#. module: project +#: help:project.task,kanban_state:0 +msgid "" +"A task's kanban state indicates special situations affecting it:\n" +" * Normal is the default situation\n" +" * Blocked indicates something is preventing the progress of this task\n" +" * Ready for next stage indicates the task is ready to be pulled to the next " +"stage" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "10" +msgstr "" + +#. module: project +#: help:project.project,analytic_account_id:0 +msgid "" +"Link this project to an analytic account if you need financial management on " +"projects. It enables you to connect projects with budgets, planning, cost " +"and revenue analysis, timesheets on projects, etc." +msgstr "" + +#. module: project +#: model:process.transition.action,name:project.process_transition_action_draftcanceltask0 +#: model:process.transition.action,name:project.process_transition_action_opencanceltask0 +#: view:project.config.settings:0 +#: view:project.task.delegate:0 +#: view:project.task.reevaluate:0 +msgid "Cancel" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Other Info" +msgstr "" + +#. module: project +#: view:project.task.delegate:0 +msgid "_Delegate" +msgstr "" + +#. module: project +#: selection:project.task,priority:0 +#: selection:report.project.task.user,priority:0 +msgid "Very Low" +msgstr "" + +#. module: project +#: help:project.project,effective_hours:0 +msgid "" +"Sum of spent hours of all tasks related to this project and its child " +"projects." +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "" +"Follow this project to automatically track the events associated to tasks " +"and issues of this project." +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Users" +msgstr "" + +#. module: project +#: model:mail.message.subtype,name:project.mt_task_stage +msgid "Stage Changed" +msgstr "" + +#. module: project +#: view:project.project:0 +#: model:res.groups,name:project.group_project_manager +msgid "Manager" +msgstr "" + +#. module: project +#: selection:project.task,priority:0 +msgid "Important" +msgstr "" + +#. module: project +#: field:project.category,name:0 +msgid "Name" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "November" +msgstr "" + +#. module: project +#: view:project.task.reevaluate:0 +msgid "Reevaluate Task" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_task_type +#: view:project.task.type:0 +msgid "Task Stage" +msgstr "" + +#. module: project +#: view:project.task.type:0 +msgid "Common" +msgstr "" + +#. module: project +#: help:project.project,message_ids:0 +#: help:project.task,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "" +"To invoice or setup invoicing and renewal options, go to the related " +"contract:" +msgstr "" + +#. module: project +#: field:project.task.delegate,state:0 +msgid "Validation State" +msgstr "" + +#. module: project +#: field:project.task.work,name:0 +msgid "Work summary" +msgstr "" + +#. module: project +#: view:project.project:0 +#: view:project.task:0 +#: view:report.project.task.user:0 +msgid "Group By..." +msgstr "" + +#. module: project +#: view:project.project:0 +#: selection:project.project,state:0 +msgid "Template" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Re-open project" +msgstr "" + +#. module: project +#: help:project.project,priority:0 +msgid "Gives the sequence order when displaying the list of projects" +msgstr "" + +#. module: project +#: constraint:project.project:0 +msgid "Error! project start-date must be lower then project end-date." +msgstr "" + +#. module: project +#: field:project.project,members:0 +msgid "Project Members" +msgstr "" + +#. module: project +#: field:project.task,child_ids:0 +msgid "Delegated Tasks" +msgstr "" + +#. module: project +#: view:project.project:0 +#: field:project.project,message_unread:0 +#: view:project.task:0 +#: field:project.task,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: project +#: view:project.task:0 +#: field:project.task,parent_ids:0 +msgid "Parent Tasks" +msgstr "" + +#. module: project +#: model:process.node,name:project.process_node_opentask0 +msgid "Open task" +msgstr "" + +#. module: project +#: view:project.task.type:0 +msgid "Stages common to all projects" +msgstr "" + +#. module: project +#: model:process.node,name:project.process_node_drafttask0 +msgid "Draft task" +msgstr "" + +#. module: project +#: field:project.task,notes:0 +msgid "Notes" +msgstr "" + +#. module: project +#: view:project.task:0 +#: view:project.task.history.cumulative:0 +msgid "Pending Tasks" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Show only tasks having a deadline" +msgstr "" + +#. module: project +#: model:project.category,name:project.project_category_04 +msgid "Usability" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,hours_delay:0 +msgid "Avg. Plan.-Eff." +msgstr "" + +#. module: project +#: field:project.task.work,user_id:0 +msgid "Done by" +msgstr "" + +#. module: project +#: code:addons/project/project.py:181 +#, python-format +msgid "Invalid Action!" +msgstr "" + +#. module: project +#: help:project.task.type,state:0 +msgid "" +"The status of your document is automatically changed regarding the selected " +"stage. For example, if a stage is related to the status 'Close', when your " +"document reaches this stage, it is automatically closed." +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Extra Info" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Edit..." +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,nbr:0 +msgid "# of tasks" +msgstr "" + +#. module: project +#: field:project.project,doc_count:0 +msgid "Number of documents attached" +msgstr "" + +#. module: project +#: field:project.task,priority:0 +#: field:report.project.task.user,priority:0 +msgid "Priority" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Open Projects" +msgstr "" + +#. module: project +#: help:project.project,alias_id:0 +msgid "" +"Internal email associated with this project. Incoming emails are " +"automatically synchronizedwith Tasks (or optionally Issues if the Issue " +"Tracker module is installed)." +msgstr "" + +#. module: project +#: model:ir.actions.act_window,help:project.open_task_type_form +msgid "" +"

\n" +" Click to add a stage in the task pipeline.\n" +"

\n" +" Define the steps that will be used in the project from the\n" +" creation of the task, up to the closing of the task or " +"issue.\n" +" You will use these stages in order to track the progress in\n" +" solving a task or an issue.\n" +"

\n" +" " +msgstr "" + +#. module: project +#: help:project.task,total_hours:0 +msgid "Computed as: Time Spent + Remaining Time." +msgstr "" + +#. module: project +#: code:addons/project/project.py:356 +#: code:addons/project/project.py:377 +#: code:addons/project/project.py:709 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: project +#: model:mail.message.subtype,name:project.mt_project_task_stage +msgid "Task Stage Changed" +msgstr "" + +#. module: project +#: view:project.task:0 +#: field:project.task.history,remaining_hours:0 +#: field:project.task.history.cumulative,remaining_hours:0 +msgid "Remaining Time" +msgstr "" + +#. module: project +#: field:project.task.delegate,name:0 +msgid "Delegated Title" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "July" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_task_reevaluate +msgid "project.task.reevaluate" +msgstr "" + +#. module: project +#: field:project.task,delay_hours:0 +msgid "Delay Hours" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Team" +msgstr "" + +#. module: project +#: help:project.config.settings,time_unit:0 +msgid "This will set the unit of measure used in projects and tasks." +msgstr "" + +#. module: project +#: selection:project.task,priority:0 +msgid "Very important" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,month:0 +msgid "Month" +msgstr "" + +#. module: project +#: model:project.task.type,name:project.project_tt_design +msgid "Design" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Start Date" +msgstr "" + +#. module: project +#: view:project.task:0 +#: selection:project.task,kanban_state:0 +#: selection:project.task.history,kanban_state:0 +#: view:project.task.history.cumulative:0 +#: selection:project.task.history.cumulative,kanban_state:0 +msgid "Blocked" +msgstr "" + +#. module: project +#: help:project.task,progress:0 +msgid "" +"If the task has a progress of 99.99% you should close the task if it's " +"finished or reevaluate the time" +msgstr "" + +#. module: project +#: field:project.task,user_email:0 +msgid "User Email" +msgstr "" + +#. module: project +#: help:project.task.delegate,prefix:0 +msgid "Title for your validation task" +msgstr "" + +#. module: project +#: field:project.config.settings,time_unit:0 +msgid "Working time unit" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Projects in which I am a member." +msgstr "" + +#. module: project +#: selection:project.task,priority:0 +#: selection:report.project.task.user,priority:0 +msgid "Low" +msgstr "" + +#. module: project +#: selection:project.project,state:0 +msgid "Closed" +msgstr "" + +#. module: project +#: view:project.project:0 +#: selection:project.project,state:0 +#: view:project.task:0 +#: selection:project.task,state:0 +#: selection:project.task.delegate,state:0 +#: selection:project.task.history,state:0 +#: selection:project.task.history.cumulative,state:0 +#: selection:project.task.type,state:0 +#: view:report.project.task.user:0 +#: selection:report.project.task.user,state:0 +msgid "Pending" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.project_category_action +#: model:ir.ui.menu,name:project.menu_project_category_act +#: view:project.category:0 +#: field:project.task,categ_ids:0 +msgid "Tags" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_task_history +#: model:ir.model,name:project.model_project_task_history_cumulative +msgid "History of Tasks" +msgstr "" + +#. module: project +#: help:project.task.delegate,state:0 +msgid "" +"New state of your own task. Pending will be reopened automatically when the " +"delegated task is closed" +msgstr "" + +#. module: project +#: help:project.config.settings,group_manage_delegation_task:0 +msgid "Allows you to delegate tasks to other users." +msgstr "" + +#. module: project +#: field:project.project,active:0 +msgid "Active" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_category +msgid "Category of project's task, issue, ..." +msgstr "" + +#. module: project +#: help:project.project,resource_calendar_id:0 +msgid "Timetable working hours to adjust the gantt diagram report" +msgstr "" + +#. module: project +#: help:project.task,delay_hours:0 +msgid "" +"Computed as difference between planned hours by the project manager and the " +"total hours of the task." +msgstr "" + +#. module: project +#: view:project.config.settings:0 +msgid "Helpdesk & Support" +msgstr "" + +#. module: project +#: help:report.project.task.user,opening_days:0 +msgid "Number of Days to Open the task" +msgstr "" + +#. module: project +#: field:project.task,delegated_user_id:0 +msgid "Delegated To" +msgstr "" + +#. module: project +#: help:project.task,planned_hours:0 +msgid "" +"Estimated time to do the task, usually set by the project manager when the " +"task is in draft state." +msgstr "" + +#. module: project +#: code:addons/project/project.py:220 +#, python-format +msgid "Attachments" +msgstr "" + +#. module: project +#: view:project.task:0 +#: selection:project.task,state:0 +#: selection:project.task.delegate,state:0 +#: selection:project.task.history,state:0 +#: selection:project.task.history.cumulative,state:0 +#: model:project.task.type,name:project.project_tt_deployment +#: selection:project.task.type,state:0 +#: view:report.project.task.user:0 +#: selection:report.project.task.user,state:0 +#: view:res.partner:0 +msgid "Done" +msgstr "" + +#. module: project +#: code:addons/project/project.py:182 +#, python-format +msgid "" +"You cannot delete a project containing tasks. You can either delete all the " +"project's tasks and then delete the project or simply deactivate the project." +msgstr "" + +#. module: project +#: model:process.transition.action,name:project.process_transition_action_draftopentask0 +#: view:project.project:0 +msgid "Open" +msgstr "" + +#. module: project +#: field:project.project,privacy_visibility:0 +msgid "Privacy / Visibility" +msgstr "" + +#. module: project +#: view:project.task:0 +#: field:project.task,remaining_hours:0 +#: field:project.task.reevaluate,remaining_hours:0 +#: view:report.project.task.user:0 +#: field:report.project.task.user,remaining_hours:0 +msgid "Remaining Hours" +msgstr "" + +#. module: project +#: model:mail.message.subtype,description:project.mt_task_stage +msgid "Stage changed" +msgstr "" + +#. module: project +#: constraint:project.task:0 +msgid "Error ! Task end-date must be greater then task start-date" +msgstr "" + +#. module: project +#: field:project.task.history,user_id:0 +#: field:project.task.history.cumulative,user_id:0 +msgid "Responsible" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Search Project" +msgstr "" + +#. module: project +#: view:project.task.delegate:0 +msgid "Delegated Task" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,total_hours:0 +msgid "Total Hours" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_project_config_settings +msgid "project.config.settings" +msgstr "" + +#. module: project +#: model:project.task.type,name:project.project_tt_development +msgid "Development" +msgstr "" + +#. module: project +#: help:project.task,active:0 +msgid "" +"This field is computed automatically and have the same behavior than the " +"boolean 'active' field: if the task is linked to a template or unactivated " +"project, it will be hidden unless specifically asked." +msgstr "" + +#. module: project +#: model:res.request.link,name:project.req_link_task +msgid "Project task" +msgstr "" + +#. module: project +#: field:project.task,effective_hours:0 +msgid "Hours Spent" +msgstr "" + +#. module: project +#: help:project.config.settings,module_pad:0 +msgid "" +"Lets the company customize which Pad installation should be used to link to " +"new pads\n" +" (by default, http://ietherpad.com/).\n" +" This installs the module pad." +msgstr "" + +#. module: project +#: field:project.task,id:0 +msgid "ID" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.action_view_task_overpassed_draft +msgid "Overpassed Tasks" +msgstr "" + +#. module: project +#: code:addons/project/project.py:932 +#, python-format +msgid "" +"Child task still open.\n" +"Please cancel or complete child task first." +msgstr "" + +#. module: project +#: field:project.task.delegate,user_id:0 +msgid "Assign To" +msgstr "" + +#. module: project +#: model:res.groups,name:project.group_time_work_estimation_tasks +msgid "Time Estimation on Tasks" +msgstr "" + +#. module: project +#: field:project.task,total_hours:0 +msgid "Total" +msgstr "" + +#. module: project +#: model:process.node,note:project.process_node_taskbydelegate0 +msgid "Delegate your task to the other user" +msgstr "" + +#. module: project +#: model:mail.message.subtype,description:project.mt_task_started +msgid "Task started" +msgstr "" + +#. module: project +#: help:project.task.reevaluate,remaining_hours:0 +msgid "Put here the remaining hours required to close the task." +msgstr "" + +#. module: project +#: help:project.task.type,fold:0 +msgid "" +"This stage is not visible, for example in status bar or kanban view, when " +"there are no records in that stage to display." +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Deadlines" +msgstr "" + +#. module: project +#: code:addons/project/wizard/project_task_delegate.py:69 +#: code:addons/project/wizard/project_task_delegate.py:70 +#: code:addons/project/wizard/project_task_delegate.py:77 +#: code:addons/project/wizard/project_task_delegate.py:78 +#, python-format +msgid "CHECK: " +msgstr "" + +#. module: project +#: code:addons/project/project.py:432 +#, python-format +msgid "You must assign members on the project '%s' !" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Pending Projects" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Remaining" +msgstr "" + +#. module: project +#: field:project.task,progress:0 +msgid "Progress (%)" +msgstr "" + +#. module: project +#: field:project.task,company_id:0 +#: field:project.task.work,company_id:0 +#: view:report.project.task.user:0 +#: field:report.project.task.user,company_id:0 +msgid "Company" +msgstr "" + +#. module: project +#: help:project.config.settings,module_project_timesheet:0 +msgid "" +"This allows you to transfer the entries under tasks defined for Project " +"Management to\n" +" the timesheet line entries for particular date and user, " +"with the effect of creating,\n" +" editing and deleting either ways.\n" +" This installs the module project_timesheet." +msgstr "" + +#. module: project +#: field:project.config.settings,module_project_issue:0 +msgid "Track issues and bugs" +msgstr "" + +#. module: project +#: field:project.config.settings,module_project_mrp:0 +msgid "Generate tasks from sale orders" +msgstr "" + +#. module: project +#: model:ir.ui.menu,name:project.menu_task_types_view +msgid "Task Stages" +msgstr "" + +#. module: project +#: model:process.node,note:project.process_node_drafttask0 +msgid "Define the Requirements and Set Planned Hours." +msgstr "" + +#. module: project +#: field:project.project,message_ids:0 +#: field:project.task,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: project +#: field:project.project,color:0 +#: field:project.task,color:0 +msgid "Color Index" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.open_board_project +#: model:ir.model,name:project.model_project_project +#: model:ir.ui.menu,name:project.menu_project_dashboard +#: model:ir.ui.menu,name:project.menu_project_management +#: view:project.project:0 +#: view:project.task:0 +#: field:project.task,project_id:0 +#: field:project.task.delegate,project_id:0 +#: field:project.task.history.cumulative,project_id:0 +#: view:report.project.task.user:0 +#: field:report.project.task.user,project_id:0 +#: model:res.request.link,name:project.req_link_project +msgid "Project" +msgstr "" + +#. module: project +#: selection:project.project,state:0 +#: selection:project.task,state:0 +#: selection:project.task.history,state:0 +#: selection:project.task.history.cumulative,state:0 +#: model:project.task.type,name:project.project_tt_cancel +#: selection:project.task.type,state:0 +#: selection:report.project.task.user,state:0 +msgid "Cancelled" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,help:project.act_project_project_2_project_task_all +#: model:ir.actions.act_window,help:project.action_view_task +msgid "" +"

\n" +" Click to create a new task.\n" +"

\n" +" OpenERP's project management allows you to manage the " +"pipeline\n" +" of tasks in order to get things done efficiently. You can\n" +" track progress, discuss on tasks, attach documents, etc.\n" +"

\n" +" " +msgstr "" + +#. module: project +#: field:project.task,date_end:0 +#: field:report.project.task.user,date_end:0 +msgid "Ending Date" +msgstr "" + +#. module: project +#: field:project.task.type,state:0 +msgid "Related Status" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Documents" +msgstr "" + +#. module: project +#: model:mail.message.subtype,description:project.mt_task_new +msgid "Task created" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,no_of_days:0 +msgid "# of Days" +msgstr "" + +#. module: project +#: field:project.project,message_follower_ids:0 +#: field:project.task,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: project +#: selection:project.project,state:0 +#: view:project.task:0 +#: selection:project.task,state:0 +#: selection:project.task.history,state:0 +#: selection:project.task.history.cumulative,state:0 +#: selection:project.task.type,state:0 +#: view:report.project.task.user:0 +msgid "New" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.action_view_task_history_cumulative +#: model:ir.ui.menu,name:project.menu_action_view_task_history_cumulative +msgid "Cumulative Flow" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,hours_effective:0 +msgid "Effective Hours" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "OverPass delay" +msgstr "" + +#. module: project +#: view:project.task.delegate:0 +msgid "Validation Task" +msgstr "" + +#. module: project +#: field:project.config.settings,module_project_long_term:0 +msgid "Manage resources planning on gantt view" +msgstr "" + +#. module: project +#: view:project.task:0 +#: view:project.task.history.cumulative:0 +msgid "Unassigned Tasks" +msgstr "" + +#. module: project +#: help:project.project,planned_hours:0 +msgid "" +"Sum of planned hours of all tasks related to this project and its child " +"projects." +msgstr "" + +#. module: project +#: view:res.partner:0 +msgid "For changing to done state" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "My Task" +msgstr "" + +#. module: project +#: view:project.task:0 +#: view:project.task.history.cumulative:0 +#: view:report.project.task.user:0 +msgid "My Projects" +msgstr "" + +#. module: project +#: help:project.task,sequence:0 +msgid "Gives the sequence order when displaying a list of tasks." +msgstr "" + +#. module: project +#: field:project.task,date_start:0 +#: field:report.project.task.user,date_start:0 +msgid "Starting Date" +msgstr "" + +#. module: project +#: code:addons/project/project.py:398 +#: model:ir.actions.act_window,name:project.open_view_project_all +#: model:ir.ui.menu,name:project.menu_projects +#: view:project.project:0 +#: field:project.task.type,project_ids:0 +#: view:res.company:0 +#, python-format +msgid "Projects" +msgstr "" + +#. module: project +#: model:res.groups,name:project.group_tasks_work_on_tasks +msgid "Task's Work on Tasks" +msgstr "" + +#. module: project +#: help:project.task.delegate,name:0 +msgid "New title of the task delegated to the user" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.action_project_task_user_tree +#: model:ir.ui.menu,name:project.menu_project_task_user_tree +#: view:report.project.task.user:0 +msgid "Tasks Analysis" +msgstr "" + +#. module: project +#: view:project.task:0 +#: view:project.task.history.cumulative:0 +msgid "Project Tasks" +msgstr "" + +#. module: project +#: field:account.analytic.account,use_tasks:0 +#: model:ir.actions.act_window,name:project.act_project_project_2_project_task_all +#: model:ir.actions.act_window,name:project.action_view_task +#: model:ir.ui.menu,name:project.menu_action_view_task +#: model:process.process,name:project.process_process_tasksprocess0 +#: view:project.project:0 +#: view:project.task:0 +#: view:res.partner:0 +#: field:res.partner,task_ids:0 +msgid "Tasks" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "December" +msgstr "" + +#. module: project +#: view:project.config.settings:0 +#: view:project.task.delegate:0 +#: view:project.task.reevaluate:0 +msgid "or" +msgstr "" + +#. module: project +#: help:project.config.settings,module_project_mrp:0 +msgid "" +"This feature automatically creates project tasks from service products in " +"sale orders.\n" +" More precisely, tasks are created for procurement lines with " +"product of type 'Service',\n" +" procurement method 'Make to Order', and supply method " +"'Manufacture'.\n" +" This installs the module project_mrp." +msgstr "" + +#. module: project +#: help:project.task.delegate,planned_hours:0 +msgid "Estimated time to close this task by the delegated user" +msgstr "" + +#. module: project +#: model:project.category,name:project.project_category_03 +msgid "Experiment" +msgstr "" + +#. module: project +#: model:process.transition.action,name:project.process_transition_action_opendrafttask0 +#: selection:report.project.task.user,state:0 +msgid "Draft" +msgstr "" + +#. module: project +#: field:project.task,kanban_state:0 +#: field:project.task.history,kanban_state:0 +#: field:project.task.history.cumulative,kanban_state:0 +msgid "Kanban State" +msgstr "" + +#. module: project +#: field:project.config.settings,module_project_timesheet:0 +msgid "Record timesheet lines per tasks" +msgstr "" + +#. module: project +#: model:ir.model,name:project.model_report_project_task_user +msgid "Tasks by user and project" +msgstr "" + +#. module: project +#: field:res.company,project_time_mode_id:0 +msgid "Project Time Unit" +msgstr "" + +#. module: project +#: view:project.task:0 +#: selection:project.task,kanban_state:0 +#: selection:project.task.history,kanban_state:0 +#: selection:project.task.history.cumulative,kanban_state:0 +msgid "Normal" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,closing_days:0 +msgid "Days to Close" +msgstr "" + +#. module: project +#: model:res.groups,name:project.group_project_user +msgid "User" +msgstr "" + +#. module: project +#: help:project.project,alias_model:0 +msgid "" +"The kind of document created when an email is received on this project's " +"email alias" +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.action_config_settings +#: view:project.config.settings:0 +msgid "Configure Project" +msgstr "" + +#. module: project +#: view:project.task.history.cumulative:0 +msgid "Tasks's Cumulative Flow" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "January" +msgstr "" + +#. module: project +#: field:project.task.delegate,prefix:0 +msgid "Your Task Title" +msgstr "" + +#. module: project +#: view:project.task.reevaluate:0 +msgid "Reevaluation Task" +msgstr "" + +#. module: project +#: code:addons/project/project.py:1318 +#, python-format +msgid "Please delete the project linked with this account first." +msgstr "" + +#. module: project +#: model:mail.message.subtype,name:project.mt_project_task_new +#: model:mail.message.subtype,name:project.mt_task_new +msgid "Task Created" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +msgid "Non Assigned Tasks to users" +msgstr "" + +#. module: project +#: view:project.project:0 +msgid "Projects in which I am a manager" +msgstr "" + +#. module: project +#: view:project.task:0 +#: selection:project.task,kanban_state:0 +#: selection:project.task.history,kanban_state:0 +#: selection:project.task.history.cumulative,kanban_state:0 +msgid "Ready for next stage" +msgstr "" + +#. module: project +#: field:project.task.type,case_default:0 +msgid "Default for New Projects" +msgstr "" + +#. module: project +#: view:project.task:0 +#: field:project.task,description:0 +#: field:project.task.type,description:0 +msgid "Description" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "May" +msgstr "" + +#. module: project +#: help:project.task.type,case_default:0 +msgid "" +"If you check this field, this stage will be proposed by default on each new " +"project. It will not assign this stage to existing projects." +msgstr "" + +#. module: project +#: field:project.task,partner_id:0 +msgid "Customer" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "February" +msgstr "" + +#. module: project +#: help:project.config.settings,module_project_long_term:0 +msgid "" +"A long term project management module that tracks planning, scheduling, and " +"resource allocation.\n" +" This installs the module project_long_term." +msgstr "" + +#. module: project +#: model:mail.message.subtype,description:project.mt_task_closed +msgid "Task closed" +msgstr "" + +#. module: project +#: selection:report.project.task.user,month:0 +msgid "April" +msgstr "" + +#. module: project +#: view:project.task:0 +msgid "Spent Hours" +msgstr "" + +#. module: project +#: help:project.project,sequence:0 +msgid "Gives the sequence order when displaying a list of Projects." +msgstr "" + +#. module: project +#: model:ir.actions.act_window,name:project.act_res_users_2_project_task_opened +msgid "Assigned Tasks" +msgstr "" + +#. module: project +#: help:project.config.settings,module_project_issue_sheet:0 +msgid "" +"Provides timesheet support for the issues/bugs management in project.\n" +" This installs the module project_issue_sheet." +msgstr "" + +#. module: project +#: selection:project.project,privacy_visibility:0 +msgid "Followers Only" +msgstr "" + +#. module: project +#: view:board.board:0 +#: field:project.project,task_count:0 +msgid "Open Tasks" +msgstr "" + +#. module: project +#: field:project.project,priority:0 +#: field:project.project,sequence:0 +#: field:project.task,sequence:0 +#: field:project.task.type,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: project +#: view:project.task:0 +#: view:project.task.work:0 +msgid "Task Work" +msgstr "" + +#. module: project +#: help:project.task.delegate,planned_hours_me:0 +msgid "" +"Estimated time for you to validate the work done by the user to whom you " +"delegate this task" +msgstr "" + +#. module: project +#: view:report.project.task.user:0 +#: field:report.project.task.user,year:0 +msgid "Year" +msgstr "" + +#. module: project +#: field:project.project,type_ids:0 +#: view:project.task.type:0 +msgid "Tasks Stages" +msgstr "" diff --git a/addons/project/project.py b/addons/project/project.py index 0751865d9c4..5d5abce3066 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -198,8 +198,12 @@ class project(osv.osv): return res def _task_count(self, cr, uid, ids, field_name, arg, context=None): + if context is None: + context = {} res = dict.fromkeys(ids, 0) - task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)]) + ctx = context.copy() + ctx['active_test'] = False + task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)], context=ctx) for task in self.pool.get('project.task').browse(cr, uid, task_ids, context): res[task.project_id.id] += 1 return res @@ -208,6 +212,12 @@ class project(osv.osv): """Overriden in project_issue to offer more options""" return [('project.task', "Tasks")] + def _get_visibility_selection(self, cr, uid, context=None): + """ Overriden in portal_project to offer more options """ + return [('public', 'Public'), + ('employees', 'Employees Only'), + ('followers', 'Followers Only')] + def attachment_tree_view(self, cr, uid, ids, context): task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)]) domain = [ @@ -229,6 +239,8 @@ class project(osv.osv): } # Lambda indirection method to avoid passing a copy of the overridable method when declaring the field _alias_models = lambda self, *args, **kwargs: self._get_alias_models(*args, **kwargs) + _visibility_selection = lambda self, *args, **kwargs: self._get_visibility_selection(*args, **kwargs) + _columns = { 'complete_name': fields.function(_complete_name, string="Project Name", type='char', size=250), 'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the project without removing it."), @@ -267,7 +279,17 @@ class project(osv.osv): "with Tasks (or optionally Issues if the Issue Tracker module is installed)."), 'alias_model': fields.selection(_alias_models, "Alias Model", select=True, required=True, help="The kind of document created when an email is received on this project's email alias"), - 'privacy_visibility': fields.selection([('public','All Users'), ('followers','Followers Only')], 'Privacy / Visibility', required=True), + 'privacy_visibility': fields.selection(_visibility_selection, 'Privacy / Visibility', required=True, + help="Holds visibility of the tasks or issues that belong to the current project:\n" + "- Public: everybody sees everything; if portal is activated, portal users\n" + " see all tasks or issues; if anonymous portal is activated, visitors\n" + " see all tasks or issues\n" + "- Portal (only available if Portal is installed): employees see everything;\n" + " if portal is activated, portal users see the tasks or issues followed by\n" + " them or by someone of their company\n" + "- Employees Only: employees see all tasks or issues\n" + "- Followers Only: employees see only the followed tasks or issues; if portal\n" + " is activated, portal users see the followed tasks or issues."), 'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'), ('cancelled', 'Cancelled'),('pending','Pending'),('close','Closed')], 'Status', required=True,), 'doc_count':fields.function(_get_attached_docs, string="Number of documents attached", type='int') } @@ -285,8 +307,7 @@ class project(osv.osv): 'sequence': 10, 'type_ids': _get_type_common, 'alias_model': 'project.task', - 'privacy_visibility': 'public', - 'alias_domain': False, # always hide alias during creation + 'privacy_visibility': 'employees', } # TODO: Why not using a SQL contraints ? @@ -531,11 +552,11 @@ def Project(): context = dict(context, project_creation_in_progress=True) mail_alias = self.pool.get('mail.alias') if not vals.get('alias_id') and vals.get('name', False): - vals.pop('alias_name', None) # prevent errors during copy() + alias_name = vals.pop('alias_name', None) # prevent errors during copy() alias_id = mail_alias.create_unique_alias(cr, uid, # Using '+' allows using subaddressing for those who don't # have a catchall domain setup. - {'alias_name': "project+"+short_name(vals['name'])}, + {'alias_name': alias_name or "project+"+short_name(vals['name'])}, model_name=vals.get('alias_model', 'project.task'), context=context) vals['alias_id'] = alias_id @@ -732,7 +753,7 @@ class task(base_stage, osv.osv): 'priority': fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Important'), ('0','Very important')], 'Priority', select=True), 'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of tasks."), 'stage_id': fields.many2one('project.task.type', 'Stage', track_visibility='onchange', - domain="['&', ('fold', '=', False), ('project_ids', '=', project_id)]"), + domain="[('project_ids', '=', project_id)]"), 'state': fields.related('stage_id', 'state', type="selection", store=True, selection=_TASK_STATE, string="Status", readonly=True, help='The status is set to \'Draft\', when a case is created.\ @@ -889,6 +910,12 @@ class task(base_stage, osv.osv): res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm) return res + def get_empty_list_help(self, cr, uid, help, context=None): + context['empty_list_help_id'] = context.get('default_project_id') + context['empty_list_help_model'] = 'project.project' + context['empty_list_help_document_name'] = _("tasks") + return super(task, self).get_empty_list_help(cr, uid, help, context=context) + # ---------------------------------------- # Case management # ---------------------------------------- diff --git a/addons/project/project_data.xml b/addons/project/project_data.xml index 025327d70b3..7bf1a623a2c 100644 --- a/addons/project/project_data.xml +++ b/addons/project/project_data.xml @@ -21,6 +21,7 @@ Projects 3 + view diff --git a/addons/project/project_demo.xml b/addons/project/project_demo.xml index f5fbf878fd0..b7dcc2bdb83 100644 --- a/addons/project/project_demo.xml +++ b/addons/project/project_demo.xml @@ -62,7 +62,7 @@ E-Learning Integration project.task - public + employees @@ -76,6 +76,7 @@ Website Design Templates project.task + employees @@ -89,6 +90,7 @@ Data Import/Export Plugin project.task + followers diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml index 16dbe44ccc1..eb042e5f0c7 100644 --- a/addons/project/project_view.xml +++ b/addons/project/project_view.xml @@ -50,16 +50,18 @@ Tasks project.task kanban,tree,form,calendar,gantt,graph - {'search_default_project_id': [active_id], 'default_project_id': active_id} + { + 'search_default_project_id': [active_id], + 'default_project_id': active_id, + 'active_test': False, + } -

- Click to create a new task. -

- OpenERP's project management allows you to manage the pipeline - of tasks in order to get things done efficiently. You can - track progress, discuss on tasks, attach documents, etc. -

+

+ OpenERP's project management allows you to manage the pipeline + of tasks in order to get things done efficiently. You can + track progress, discuss on tasks, attach documents, etc. +

@@ -87,6 +89,17 @@

+
+
-

+
+ %% +
@@ -622,13 +630,11 @@ kanban,tree,form,calendar,gantt,graph -

- Click to create a new task. -

- OpenERP's project management allows you to manage the pipeline - of tasks in order to get things done efficiently. You can - track progress, discuss on tasks, attach documents, etc. -

+

+ OpenERP's project management allows you to manage the pipeline + of tasks in order to get things done efficiently. You can + track progress, discuss on tasks, attach documents, etc. +

diff --git a/addons/project/report/project_report.py b/addons/project/report/project_report.py index 8e7dca059f9..006aae1085c 100644 --- a/addons/project/report/project_report.py +++ b/addons/project/report/project_report.py @@ -117,5 +117,4 @@ class report_project_task_user(osv.osv): """) -report_project_task_user() diff --git a/addons/project/report/project_report_view.xml b/addons/project/report/project_report_view.xml index 10f3f4a8c7c..d9650e165ce 100644 --- a/addons/project/report/project_report_view.xml +++ b/addons/project/report/project_report_view.xml @@ -69,7 +69,7 @@ - + diff --git a/addons/project/res_partner.py b/addons/project/res_partner.py index 97fca8c459f..e4ca63d79d8 100644 --- a/addons/project/res_partner.py +++ b/addons/project/res_partner.py @@ -29,7 +29,6 @@ class res_partner(osv.osv): 'task_ids': fields.one2many('project.task', 'partner_id', 'Tasks'), } -res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/security/project_security.xml b/addons/project/security/project_security.xml index f1d8c7e760f..e674019443b 100644 --- a/addons/project/security/project_security.xml +++ b/addons/project/security/project_security.xml @@ -38,39 +38,60 @@ - Project multi-company + Project: multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|', + ('company_id', '=', False), + ('company_id', 'child_of', [user.company_id.id]), + ] + + + + Project: project manager: see all + + [(1, '=', 1)] + - Public Members + Project: employees: public, employees or followers - - ['|',('privacy_visibility','in',[False,'public']),('message_follower_ids','in',[user.partner_id.id])] + ['|', + ('privacy_visibility', 'in', ['public', 'employees']), + ('message_follower_ids', 'in', [user.partner_id.id]) + ] + - Task multi-company + Project/Task: multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|', + ('company_id', '=', False), + ('company_id', 'child_of', [user.company_id.id]), + ] - Tasks According to User and Project + Project/Task: employees: public or employee or (followers and following) - - ['|','|','|',('user_id','=',False),('user_id','=',user.id),('project_id.members','in', [user.id]),('project_id.user_id','=',user.id)] - + ['|', + ('project_id.privacy_visibility', 'in', ['public', 'employees']), + '&', + ('project_id.privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.partner_id.id]), + ] + - Project Managers: all tasks from all projects + Project/Task: project manager: see all - [(1,'=',1)] + [(1, '=', 1)] + diff --git a/addons/project/wizard/project_task_delegate.py b/addons/project/wizard/project_task_delegate.py index bb15c62db1f..6a26868557e 100644 --- a/addons/project/wizard/project_task_delegate.py +++ b/addons/project/wizard/project_task_delegate.py @@ -125,13 +125,12 @@ class project_task_delegate(osv.osv_memory): action_model, action_id = models_data.get_object_reference(cr, uid, 'project', 'action_view_task') view_model, task_view_form_id = models_data.get_object_reference(cr, uid, 'project', 'view_task_form2') view_model, task_view_tree_id = models_data.get_object_reference(cr, uid, 'project', 'view_task_tree2') - action = self.pool.get(action_model).read(cr, uid, action_id, context=context) + action = self.pool[action_model].read(cr, uid, action_id, context=context) action['res_id'] = delegated_tasks[task_id] action['view_id'] = False action['views'] = [(task_view_form_id, 'form'), (task_view_tree_id, 'tree')] action['help'] = False return action -project_task_delegate() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project/wizard/project_task_reevaluate.py b/addons/project/wizard/project_task_reevaluate.py index 1cbea397d5e..eeb8cccc5d2 100644 --- a/addons/project/wizard/project_task_reevaluate.py +++ b/addons/project/wizard/project_task_reevaluate.py @@ -80,6 +80,5 @@ class project_task_reevaluate(osv.osv_memory): if context.get('button_reactivate'): task_pool.do_reopen(cr, uid, [task_id], context=context) return {'type': 'ir.actions.act_window_close'} -project_task_reevaluate() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/project_gtd.py b/addons/project_gtd/project_gtd.py index 715544cf4fc..47569e863aa 100644 --- a/addons/project_gtd/project_gtd.py +++ b/addons/project_gtd/project_gtd.py @@ -37,7 +37,6 @@ class project_gtd_context(osv.osv): } _order = "sequence, name" -project_gtd_context() class project_gtd_timebox(osv.osv): @@ -49,7 +48,6 @@ class project_gtd_timebox(osv.osv): 'icon': fields.selection(tools.icons, 'Icon', size=64), } -project_gtd_timebox() class project_task(osv.osv): _inherit = "project.task" @@ -120,6 +118,5 @@ class project_task(osv.osv): return res -project_task() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/project_gtd_view.xml b/addons/project_gtd/project_gtd_view.xml index 1467ce55fab..4bfd5b783c7 100644 --- a/addons/project_gtd/project_gtd_view.xml +++ b/addons/project_gtd/project_gtd_view.xml @@ -106,6 +106,8 @@ + + diff --git a/addons/project_gtd/wizard/project_gtd_empty.py b/addons/project_gtd/wizard/project_gtd_empty.py index 26e438b789e..36c64cbc224 100644 --- a/addons/project_gtd/wizard/project_gtd_empty.py +++ b/addons/project_gtd/wizard/project_gtd_empty.py @@ -62,6 +62,5 @@ class project_timebox_empty(osv.osv_memory): obj_task.write(cr, uid, close, {'timebox_id':False}) return {} -project_timebox_empty() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_gtd/wizard/project_gtd_fill.py b/addons/project_gtd/wizard/project_gtd_fill.py index ae8fea61e1c..121bd7efdac 100644 --- a/addons/project_gtd/wizard/project_gtd_fill.py +++ b/addons/project_gtd/wizard/project_gtd_fill.py @@ -56,6 +56,5 @@ class project_timebox_fill(osv.osv_memory): self.pool.get('project.task').write(cr, uid, data[0]['task_ids'], {'timebox_id':data[0]['timebox_to_id'][0]}) return {'type': 'ir.actions.act_window_close'} -project_timebox_fill() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_issue/i18n/cs.po b/addons/project_issue/i18n/cs.po new file mode 100644 index 00000000000..cab9361dc60 --- /dev/null +++ b/addons/project_issue/i18n/cs.po @@ -0,0 +1,984 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-03-31 16:53+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: project_issue +#: model:project.category,name:project_issue.project_issue_category_03 +msgid "Deadly bug" +msgstr "" + +#. module: project_issue +#: help:project.config.settings,fetchmail_issue:0 +msgid "" +"Allows you to configure your incoming mail server, and create issues from " +"incoming emails." +msgstr "" + +#. module: project_issue +#: field:project.issue.report,delay_open:0 +msgid "Avg. Delay to Open" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: view:project.issue.report:0 +msgid "Group By..." +msgstr "" + +#. module: project_issue +#: field:project.issue,working_hours_open:0 +msgid "Working Hours to Open the Issue" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,description:project_issue.mt_issue_started +msgid "Issue started" +msgstr "" + +#. module: project_issue +#: field:project.issue,date_open:0 +msgid "Opened" +msgstr "" + +#. module: project_issue +#: field:project.issue.report,opening_date:0 +msgid "Date of Opening" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "March" +msgstr "" + +#. module: project_issue +#: field:project.issue,progress:0 +msgid "Progress (%)" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: project_issue +#: field:project.issue,company_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,company_id:0 +msgid "Company" +msgstr "" + +#. module: project_issue +#: field:project.issue,email_cc:0 +msgid "Watchers Emails" +msgstr "" + +#. module: project_issue +#: help:project.issue,kanban_state:0 +msgid "" +"A Issue's kanban state indicates special situations affecting it:\n" +" * Normal is the default situation\n" +" * Blocked indicates something is preventing the progress of this issue\n" +" * Ready for next stage indicates the issue is ready to be pulled to the " +"next stage" +msgstr "" + +#. module: project_issue +#: help:project.issue,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: project_issue +#: help:account.analytic.account,use_issues:0 +msgid "Check this field if this project manages issues" +msgstr "" + +#. module: project_issue +#: field:project.issue,day_open:0 +msgid "Days to Open" +msgstr "" + +#. module: project_issue +#: code:addons/project_issue/project_issue.py:473 +#, python-format +msgid "" +"You cannot escalate this issue.\n" +"The relevant Project has not configured the Escalation Project!" +msgstr "" + +#. module: project_issue +#: constraint:project.project:0 +msgid "Error! You cannot assign escalation to the same project!" +msgstr "" + +#. module: project_issue +#: selection:project.issue,priority:0 +#: selection:project.issue.report,priority:0 +msgid "Highest" +msgstr "" + +#. module: project_issue +#: help:project.issue,inactivity_days:0 +msgid "Difference in days between last action and current date" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +#: field:project.issue.report,day:0 +msgid "Day" +msgstr "" + +#. module: project_issue +#: field:project.issue,days_since_creation:0 +msgid "Days since creation date" +msgstr "" + +#. module: project_issue +#: field:project.issue,task_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,task_id:0 +msgid "Task" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,name:project_issue.mt_project_issue_stage +msgid "Issue Stage Changed" +msgstr "" + +#. module: project_issue +#: field:project.issue,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: project_issue +#: field:project.issue,inactivity_days:0 +msgid "Days since last action" +msgstr "" + +#. module: project_issue +#: model:ir.model,name:project_issue.model_project_project +#: view:project.issue:0 +#: field:project.issue,project_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,project_id:0 +msgid "Project" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,help:project_issue.project_issue_categ_act0 +msgid "" +"

\n" +" Click to report a new issue.\n" +"

\n" +" The OpenERP issues tacker allows you to efficiantly manage " +"things\n" +" like internal requests, software development bugs, customer\n" +" complaints, project troubles, material breakdowns, etc.\n" +"

\n" +" " +msgstr "" + +#. module: project_issue +#: selection:project.issue,state:0 +#: selection:project.issue.report,state:0 +msgid "Cancelled" +msgstr "" + +#. module: project_issue +#: field:project.issue,description:0 +msgid "Private Note" +msgstr "" + +#. module: project_issue +#: field:project.issue.report,date_closed:0 +msgid "Date of Closing" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Issue Tracker Search" +msgstr "" + +#. module: project_issue +#: field:project.issue,color:0 +msgid "Color Index" +msgstr "" + +#. module: project_issue +#: field:project.issue.report,working_hours_open:0 +msgid "Avg. Working Hours to Open" +msgstr "" + +#. module: project_issue +#: model:ir.model,name:project_issue.model_account_analytic_account +msgid "Analytic Account" +msgstr "" + +#. module: project_issue +#: help:project.issue,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: project_issue +#: help:project.project,project_escalation_id:0 +msgid "" +"If any issue is escalated from the current Project, it will be listed under " +"the project selected here." +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Extra Info" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,help:project_issue.action_project_issue_report +msgid "" +"This report on the project issues allows you to analyse the quality of your " +"support or after-sales services. You can track the issues per age. You can " +"analyse the time required to open or close an issue, the number of email to " +"exchange and the time spent on average by issues." +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Edit..." +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Responsible" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Statistics" +msgstr "" + +#. module: project_issue +#: field:project.issue,kanban_state:0 +msgid "Kanban State" +msgstr "" + +#. module: project_issue +#: code:addons/project_issue/project_issue.py:368 +#, python-format +msgid "Project issue converted to task." +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,priority:0 +#: view:project.issue.report:0 +#: field:project.issue.report,priority:0 +msgid "Priority" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,version_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,version_id:0 +msgid "Version" +msgstr "" + +#. module: project_issue +#: field:project.issue,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: selection:project.issue,state:0 +#: view:project.issue.report:0 +msgid "New" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,name:project_issue.project_issue_categ_action +msgid "Issue Categories" +msgstr "" + +#. module: project_issue +#: field:project.issue,email_from:0 +msgid "Email" +msgstr "" + +#. module: project_issue +#: field:project.issue,channel_id:0 +#: field:project.issue.report,channel_id:0 +msgid "Channel" +msgstr "" + +#. module: project_issue +#: selection:project.issue,priority:0 +#: selection:project.issue.report,priority:0 +msgid "Lowest" +msgstr "" + +#. module: project_issue +#: code:addons/project_issue/project_issue.py:390 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Unassigned Issues" +msgstr "" + +#. module: project_issue +#: field:project.issue,create_date:0 +#: view:project.issue.report:0 +#: field:project.issue.report,creation_date:0 +msgid "Creation Date" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,name:project_issue.project_issue_version_action +#: model:ir.ui.menu,name:project_issue.menu_project_issue_version_act +msgid "Versions" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "To Do Issues" +msgstr "" + +#. module: project_issue +#: model:ir.model,name:project_issue.model_project_issue_version +msgid "project.issue.version" +msgstr "" + +#. module: project_issue +#: field:project.config.settings,fetchmail_issue:0 +msgid "Create issues from an incoming email account " +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: selection:project.issue,state:0 +#: view:project.issue.report:0 +msgid "Done" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "July" +msgstr "" + +#. module: project_issue +#: model:ir.ui.menu,name:project_issue.menu_project_issue_category_act +msgid "Categories" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,stage_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,stage_id:0 +msgid "Stage" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,name:project_issue.action_project_issue_report +#: model:ir.ui.menu,name:project_issue.menu_project_issue_report_tree +#: view:project.issue.report:0 +msgid "Issues Analysis" +msgstr "" + +#. module: project_issue +#: code:addons/project_issue/project_issue.py:507 +#, python-format +msgid "No Subject" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,name:project_issue.action_view_my_project_issue_tree +msgid "My Project Issues" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,partner_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Delete" +msgstr "" + +#. module: project_issue +#: code:addons/project_issue/project_issue.py:373 +#, python-format +msgid "Tasks" +msgstr "" + +#. module: project_issue +#: field:project.issue.report,nbr:0 +msgid "# of Issues" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "September" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "December" +msgstr "" + +#. module: project_issue +#: field:project.issue,categ_ids:0 +msgid "Tags" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Issue Tracker Tree" +msgstr "" + +#. module: project_issue +#: model:project.category,name:project_issue.project_issue_category_01 +msgid "Little problem" +msgstr "" + +#. module: project_issue +#: view:project.project:0 +msgid "creates" +msgstr "" + +#. module: project_issue +#: model:crm.case.categ,name:project_issue.feature_request_categ +msgid "Feature Requests" +msgstr "" + +#. module: project_issue +#: field:project.issue,write_date:0 +msgid "Update Date" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Project:" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Open Features" +msgstr "" + +#. module: project_issue +#: field:project.issue,date_action_next:0 +msgid "Next Action" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: selection:project.issue,kanban_state:0 +msgid "Blocked" +msgstr "" + +#. module: project_issue +#: field:project.issue,user_email:0 +msgid "User Email" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +msgid "#Number of Project Issues" +msgstr "" + +#. module: project_issue +#: help:project.issue,channel_id:0 +msgid "Communication channel." +msgstr "" + +#. module: project_issue +#: help:project.issue,email_cc:0 +msgid "" +"These email addresses will be added to the CC field of all inbound and " +"outbound emails for this record before being sent. Separate multiple email " +"addresses with a comma" +msgstr "" + +#. module: project_issue +#: model:crm.case.categ,name:project_issue.bug_categ +msgid "Maintenance" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,state:0 +msgid "Draft" +msgstr "" + +#. module: project_issue +#: selection:project.issue,priority:0 +#: selection:project.issue.report,priority:0 +msgid "Low" +msgstr "" + +#. module: project_issue +#: field:project.issue,date_closed:0 +#: selection:project.issue.report,state:0 +msgid "Closed" +msgstr "" + +#. module: project_issue +#: field:project.issue.report,delay_close:0 +msgid "Avg. Delay to Close" +msgstr "" + +#. module: project_issue +#: selection:project.issue,state:0 +#: view:project.issue.report:0 +#: selection:project.issue.report,state:0 +msgid "Pending" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,state:0 +#: field:project.issue.report,state:0 +msgid "Status" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +msgid "#Project Issues" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "August" +msgstr "" + +#. module: project_issue +#: selection:project.issue,kanban_state:0 +#: selection:project.issue,priority:0 +#: selection:project.issue.report,priority:0 +msgid "Normal" +msgstr "" + +#. module: project_issue +#: field:project.project,issue_count:0 +msgid "unknown" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Category:" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "June" +msgstr "" + +#. module: project_issue +#: help:project.issue,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "New Issues" +msgstr "" + +#. module: project_issue +#: field:project.issue,day_close:0 +msgid "Days to Close" +msgstr "" + +#. module: project_issue +#: field:project.issue,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: project_issue +#: help:project.issue,state:0 +msgid "" +"The status is set to 'Draft', when a case is created. " +"If the case is in progress the status is set to 'Open'. " +"When the case is over, the status is set to 'Done'. If " +"the case needs to be reviewed then the status is set " +"to 'Pending'." +msgstr "" + +#. module: project_issue +#: field:project.issue,active:0 +#: field:project.issue.version,active:0 +msgid "Active" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "November" +msgstr "" + +#. module: project_issue +#: code:addons/project_issue/project_issue.py:473 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +msgid "Search" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "October" +msgstr "" + +#. module: project_issue +#: help:project.issue,days_since_creation:0 +msgid "Difference in days between creation date and current date" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "January" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Feature Tracker Tree" +msgstr "" + +#. module: project_issue +#: help:project.issue,email_from:0 +msgid "These people will receive email." +msgstr "" + +#. module: project_issue +#: field:project.issue,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: project_issue +#: field:project.issue,date:0 +msgid "Date" +msgstr "" + +#. module: project_issue +#: field:project.issue,user_id:0 +#: view:project.issue.report:0 +#: field:project.issue.report,user_id:0 +msgid "Assigned to" +msgstr "" + +#. module: project_issue +#: view:project.config.settings:0 +msgid "Configure" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,description:project_issue.mt_issue_closed +msgid "Issue closed" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Current Features" +msgstr "" + +#. module: project_issue +#: view:project.issue.version:0 +msgid "Issue Version" +msgstr "" + +#. module: project_issue +#: field:project.issue.version,name:0 +msgid "Version Number" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Cancel" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,state:0 +msgid "Open" +msgstr "" + +#. module: project_issue +#: field:account.analytic.account,use_issues:0 +#: model:ir.actions.act_window,name:project_issue.act_project_project_2_project_issue_all +#: model:ir.actions.act_window,name:project_issue.project_issue_categ_act0 +#: model:ir.ui.menu,name:project_issue.menu_project_confi +#: model:ir.ui.menu,name:project_issue.menu_project_issue_track +#: view:project.issue:0 +#: view:project.project:0 +msgid "Issues" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: selection:project.issue,state:0 +msgid "In Progress" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: view:project.issue.report:0 +msgid "To Do" +msgstr "" + +#. module: project_issue +#: model:ir.model,name:project_issue.model_project_issue +#: view:project.issue.report:0 +msgid "Project Issue" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Creation Month" +msgstr "" + +#. module: project_issue +#: help:project.issue,progress:0 +msgid "Computed as: Time Spent / Total Time." +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: selection:project.issue,kanban_state:0 +msgid "Ready for next stage" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +#: field:project.issue.report,section_id:0 +msgid "Sale Team" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: view:project.issue.report:0 +#: field:project.issue.report,month:0 +msgid "Month" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +#: field:project.issue,name:0 +#: view:project.project:0 +msgid "Issue" +msgstr "" + +#. module: project_issue +#: model:project.category,name:project_issue.project_issue_category_02 +msgid "PBCK" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Feature Tracker Search" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Description" +msgstr "" + +#. module: project_issue +#: field:project.issue,section_id:0 +msgid "Sales Team" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "May" +msgstr "" + +#. module: project_issue +#: model:ir.model,name:project_issue.model_project_config_settings +msgid "project.config.settings" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,name:project_issue.mt_issue_closed +#: model:mail.message.subtype,name:project_issue.mt_project_issue_closed +msgid "Issue Closed" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +#: field:project.issue.report,email:0 +msgid "# Emails" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,name:project_issue.mt_issue_new +#: model:mail.message.subtype,name:project_issue.mt_project_issue_new +msgid "Issue Created" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,name:project_issue.mt_issue_blocked +#: model:mail.message.subtype,name:project_issue.mt_project_issue_blocked +msgid "Issue Blocked" +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "February" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,description:project_issue.mt_issue_stage +#: model:mail.message.subtype,description:project_issue.mt_project_issue_stage +msgid "Stage changed" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "Feature description" +msgstr "" + +#. module: project_issue +#: field:project.project,project_escalation_id:0 +msgid "Project Escalation" +msgstr "" + +#. module: project_issue +#: model:ir.actions.act_window,help:project_issue.project_issue_version_action +msgid "" +"

\n" +" Click to add a new version.\n" +"

\n" +" Define here the different versions of your products on " +"which\n" +" you can work on issues.\n" +"

\n" +" " +msgstr "" + +#. module: project_issue +#: help:project.issue,section_id:0 +msgid "" +"Sales team to which Case belongs to. Define " +"Responsible user and Email account for mail gateway." +msgstr "" + +#. module: project_issue +#: view:board.board:0 +msgid "My Issues" +msgstr "" + +#. module: project_issue +#: help:project.issue.report,delay_open:0 +msgid "Number of Days to open the project issue." +msgstr "" + +#. module: project_issue +#: selection:project.issue.report,month:0 +msgid "April" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "⇒ Escalate" +msgstr "" + +#. module: project_issue +#: view:project.issue:0 +msgid "References" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,description:project_issue.mt_issue_new +msgid "Issue created" +msgstr "" + +#. module: project_issue +#: field:project.issue,working_hours_close:0 +msgid "Working Hours to Close the Issue" +msgstr "" + +#. module: project_issue +#: field:project.issue,id:0 +msgid "ID" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,description:project_issue.mt_issue_blocked +msgid "Issue blocked" +msgstr "" + +#. module: project_issue +#: model:ir.model,name:project_issue.model_project_issue_report +msgid "project.issue.report" +msgstr "" + +#. module: project_issue +#: help:project.issue.report,delay_close:0 +msgid "Number of Days to close the project issue" +msgstr "" + +#. module: project_issue +#: field:project.issue.report,working_hours_close:0 +msgid "Avg. Working Hours to Close" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,name:project_issue.mt_issue_stage +msgid "Stage Changed" +msgstr "" + +#. module: project_issue +#: selection:project.issue,priority:0 +#: selection:project.issue.report,priority:0 +msgid "High" +msgstr "" + +#. module: project_issue +#: field:project.issue,date_deadline:0 +msgid "Deadline" +msgstr "" + +#. module: project_issue +#: field:project.issue,date_action_last:0 +msgid "Last Action" +msgstr "" + +#. module: project_issue +#: view:project.issue.report:0 +#: field:project.issue.report,name:0 +msgid "Year" +msgstr "" + +#. module: project_issue +#: field:project.issue,duration:0 +msgid "Duration" +msgstr "" + +#. module: project_issue +#: model:mail.message.subtype,name:project_issue.mt_issue_started +#: model:mail.message.subtype,name:project_issue.mt_project_issue_started +msgid "Issue Started" +msgstr "" diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py index 01dab2962f3..a008c670138 100644 --- a/addons/project_issue/project_issue.py +++ b/addons/project_issue/project_issue.py @@ -40,7 +40,6 @@ class project_issue_version(osv.osv): _defaults = { 'active': 1, } -project_issue_version() class project_issue(base_stage, osv.osv): _name = "project.issue" @@ -137,6 +136,13 @@ class project_issue(base_stage, osv.osv): res = {} for issue in self.browse(cr, uid, ids, context=context): + + # if the working hours on the project are not defined, use default ones (8 -> 12 and 13 -> 17 * 5), represented by None + if not issue.project_id or not issue.project_id.resource_calendar_id: + working_hours = None + else: + working_hours = issue.project_id.resource_calendar_id.id + res[issue.id] = {} for field in fields: duration = 0 @@ -150,20 +156,24 @@ class project_issue(base_stage, osv.osv): ans = date_open - date_create date_until = issue.date_open #Calculating no. of working hours to open the issue - if issue.project_id.resource_calendar_id: - hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id, + hours = cal_obj._interval_hours_get(cr, uid, working_hours, date_create, - date_open) + date_open, + timezone_from_uid=issue.user_id.id or uid, + exclude_leaves=False, + context=context) elif field in ['working_hours_close','day_close']: if issue.date_closed: date_close = datetime.strptime(issue.date_closed, "%Y-%m-%d %H:%M:%S") date_until = issue.date_closed ans = date_close - date_create #Calculating no. of working hours to close the issue - if issue.project_id.resource_calendar_id: - hours = cal_obj.interval_hours_get(cr, uid, issue.project_id.resource_calendar_id.id, - date_create, - date_close) + hours = cal_obj._interval_hours_get(cr, uid, working_hours, + date_create, + date_close, + timezone_from_uid=issue.user_id.id or uid, + exclude_leaves=False, + context=context) elif field in ['days_since_creation']: if issue.create_date: days_since_creation = datetime.today() - datetime.strptime(issue.create_date, "%Y-%m-%d %H:%M:%S") @@ -182,27 +192,12 @@ class project_issue(base_stage, osv.osv): resource_ids = res_obj.search(cr, uid, [('user_id','=',issue.user_id.id)]) if resource_ids and len(resource_ids): resource_id = resource_ids[0] - duration = float(ans.days) - if issue.project_id and issue.project_id.resource_calendar_id: - duration = float(ans.days) * 24 - - new_dates = cal_obj.interval_min_get(cr, uid, - issue.project_id.resource_calendar_id.id, - date_create, - duration, resource=resource_id) - no_days = [] - date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S') - for in_time, out_time in new_dates: - if in_time.date not in no_days: - no_days.append(in_time.date) - if out_time > date_until: - break - duration = len(no_days) + duration = float(ans.days) + float(ans.seconds)/(24*3600) if field in ['working_hours_open','working_hours_close']: res[issue.id][field] = hours - else: - res[issue.id][field] = abs(float(duration)) + elif field in ['day_open','day_close']: + res[issue.id][field] = duration return res @@ -275,7 +270,7 @@ class project_issue(base_stage, osv.osv): 'version_id': fields.many2one('project.issue.version', 'Version'), 'stage_id': fields.many2one ('project.task.type', 'Stage', track_visibility='onchange', - domain="['&', ('fold', '=', False), ('project_ids', '=', project_id)]"), + domain="[('project_ids', '=', project_id)]"), 'project_id':fields.many2one('project.project', 'Project', track_visibility='onchange'), 'duration': fields.float('Duration'), 'task_id': fields.many2one('project.task', 'Task', domain="[('project_id','=',project_id)]"), @@ -420,6 +415,12 @@ class project_issue(base_stage, osv.osv): self.write(cr, uid, ids, {'date_open': False, 'date_closed': False}) return res + def get_empty_list_help(self, cr, uid, help, context=None): + context['empty_list_help_model'] = 'project.project' + context['empty_list_help_id'] = context.get('default_project_id') + context['empty_list_help_document_name'] = _("issues") + return super(project_issue, self).get_empty_list_help(cr, uid, help, context=context) + # ------------------------------------------------------- # Stage management # ------------------------------------------------------- @@ -494,10 +495,10 @@ class project_issue(base_stage, osv.osv): def message_get_suggested_recipients(self, cr, uid, ids, context=None): recipients = super(project_issue, self).message_get_suggested_recipients(cr, uid, ids, context=context) for issue in self.browse(cr, uid, ids, context=context): - if issue.partner_id: - self._message_add_suggested_recipient(cr, uid, recipients, issue, partner=issue.partner_id, reason=_('Customer')) - elif issue.email_from: + if issue.email_from: self._message_add_suggested_recipient(cr, uid, recipients, issue, email=issue.email_from, reason=_('Customer Email')) + elif issue.partner_id: + self._message_add_suggested_recipient(cr, uid, recipients, issue, partner=issue.partner_id, reason=_('Customer')) return recipients def message_new(self, cr, uid, msg, custom_values=None, context=None): @@ -567,7 +568,8 @@ class project_issue(base_stage, osv.osv): return res -class project(osv.osv): + +class project(osv.Model): _inherit = "project.project" def _get_alias_models(self, cr, uid, context=None): @@ -582,7 +584,9 @@ class project(osv.osv): return res _columns = { - 'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}), + 'project_escalation_id': fields.many2one('project.project', 'Project Escalation', + help='If any issue is escalated from the current Project, it will be listed under the project selected here.', + states={'close': [('readonly', True)], 'cancelled': [('readonly', True)]}), 'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues"), } @@ -597,14 +601,13 @@ class project(osv.osv): (_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id']) ] -project() -class account_analytic_account(osv.osv): +class account_analytic_account(osv.Model): _inherit = 'account.analytic.account' _description = 'Analytic Account' _columns = { - 'use_issues' : fields.boolean('Issues', help="Check this field if this project manages issues"), + 'use_issues': fields.boolean('Issues', help="Check this field if this project manages issues"), } def on_change_template(self, cr, uid, ids, template_id, context=None): @@ -615,16 +618,34 @@ class account_analytic_account(osv.osv): return res def _trigger_project_creation(self, cr, uid, vals, context=None): - if context is None: context = {} + if context is None: + context = {} res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context) return res or (vals.get('use_issues') and not 'project_creation_in_progress' in context) -account_analytic_account() -class project_project(osv.osv): +class project_project(osv.Model): _inherit = 'project.project' + _defaults = { 'use_issues': True } + def _check_create_write_values(self, cr, uid, vals, context=None): + """ Perform some check on values given to create or write. """ + # Handle use_tasks / use_issues: if only one is checked, alias should take the same model + if vals.get('use_tasks') and not vals.get('use_issues'): + vals['alias_model'] = 'project.task' + elif vals.get('use_issues') and not vals.get('use_tasks'): + vals['alias_model'] = 'project.issue' + + def create(self, cr, uid, vals, context=None): + self._check_create_write_values(cr, uid, vals, context=context) + return super(project_project, self).create(cr, uid, vals, context=context) + + def write(self, cr, uid, ids, vals, context=None): + self._check_create_write_values(cr, uid, vals, context=context) + return super(project_project, self).write(cr, uid, ids, vals, context=context) + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_issue/project_issue_menu.xml b/addons/project_issue/project_issue_menu.xml index 78841f56156..308b4884844 100644 --- a/addons/project_issue/project_issue_menu.xml +++ b/addons/project_issue/project_issue_menu.xml @@ -14,13 +14,11 @@ -

- Click to report a new issue. -

- The OpenERP issues tacker allows you to efficiantly manage things - like internal requests, software development bugs, customer - complaints, project troubles, material breakdowns, etc. -

+

+ The OpenERP issues tacker allows you to efficiantly manage things + like internal requests, software development bugs, customer + complaints, project troubles, material breakdowns, etc. +

diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index 500a1376422..f15355e9cc8 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -146,7 +146,7 @@ project.issue - + @@ -154,10 +154,11 @@ - + + @@ -302,7 +303,18 @@ form Issues kanban,tree,form,calendar,graph - {'search_default_project_id': [active_id], 'default_project_id': active_id} + { + 'search_default_project_id': [active_id], + 'default_project_id': active_id, + } + + +

+ The OpenERP issues tacker allows you to efficiantly manage things + like internal requests, software development bugs, customer + complaints, project troubles, material breakdowns, etc. +

+
@@ -324,9 +336,18 @@ - - diff --git a/addons/project_issue/report/project_issue_report.py b/addons/project_issue/report/project_issue_report.py index a5eb903a742..5cca0ff8689 100644 --- a/addons/project_issue/report/project_issue_report.py +++ b/addons/project_issue/report/project_issue_report.py @@ -63,9 +63,9 @@ class project_issue_report(osv.osv): 'project_id':fields.many2one('project.project', 'Project',readonly=True), 'version_id': fields.many2one('project.issue.version', 'Version'), 'user_id' : fields.many2one('res.users', 'Assigned to',readonly=True), - 'partner_id': fields.many2one('res.partner','Contact',domain="[('object_id.model', '=', 'project.issue')]"), + 'partner_id': fields.many2one('res.partner','Contact'), 'channel_id': fields.many2one('crm.case.channel', 'Channel',readonly=True), - 'task_id': fields.many2one('project.task', 'Task',domain="[('object_id.model', '=', 'project.issue')]" ), + 'task_id': fields.many2one('project.task', 'Task'), 'email': fields.integer('# Emails', size=128, readonly=True), } @@ -96,8 +96,8 @@ class project_issue_report(osv.osv): c.channel_id, c.task_id, date_trunc('day',c.create_date) as create_date, - extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open, - extract('epoch' from (c.date_closed-c.date_open))/(3600*24) as delay_close, + c.day_open as delay_open, + c.day_close as delay_close, (SELECT count(id) FROM mail_message WHERE model='project.issue' AND res_id=c.id) AS email FROM @@ -105,6 +105,5 @@ class project_issue_report(osv.osv): WHERE c.active= 'true' )""") -project_issue_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_issue/report/project_issue_report_view.xml b/addons/project_issue/report/project_issue_report_view.xml index 47ea91fad5f..a885dcd8a7f 100644 --- a/addons/project_issue/report/project_issue_report_view.xml +++ b/addons/project_issue/report/project_issue_report_view.xml @@ -14,7 +14,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/addons/project_issue/security/project_issue_security.xml b/addons/project_issue/security/project_issue_security.xml index c3119073a75..c8ed12086e4 100644 --- a/addons/project_issue/security/project_issue_security.xml +++ b/addons/project_issue/security/project_issue_security.xml @@ -1,5 +1,25 @@ + + + Project/Issue: project manager: see all + + [(1, '=', 1)] + + + + + Project/Issue: employees: public or employee or (followers and following) + + ['|', + ('project_id.privacy_visibility', 'in', ['public', 'employees']), + '&', + ('project_id.privacy_visibility', '=', 'followers'), + ('message_follower_ids', 'in', [user.id]), + ] + + + diff --git a/addons/project_issue/test/subscribe_issue.yml b/addons/project_issue/test/subscribe_issue.yml index 9f16dc80b97..af81ff4d295 100644 --- a/addons/project_issue/test/subscribe_issue.yml +++ b/addons/project_issue/test/subscribe_issue.yml @@ -2,8 +2,7 @@ In Order to test process of Issue in OpenERP, Custmer send the issue by email. - !python {model: mail.thread}: | - from openerp import addons - request_file = open(addons.get_module_resource('project_issue','test', 'issue.eml'),'rb') + request_file = open(openerp.modules.module.get_module_resource('project_issue','test', 'issue.eml'),'rb') request_message = request_file.read() self.message_process(cr, uid, 'project.issue', request_message) - @@ -14,4 +13,4 @@ assert issue_ids and len(issue_ids), "issue is not created after getting request" issue = self.browse(cr, uid, issue_ids[0], context=context) assert not issue.partner_id, "Customer should be a new" - assert issue.name == "Error in the account module", "Subject does not match" \ No newline at end of file + assert issue.name == "Error in the account module", "Subject does not match" diff --git a/addons/project_issue_sheet/i18n/cs.po b/addons/project_issue_sheet/i18n/cs.po new file mode 100644 index 00000000000..606e4246807 --- /dev/null +++ b/addons/project_issue_sheet/i18n/cs.po @@ -0,0 +1,72 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-31 16:53+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: project_issue_sheet +#: code:addons/project_issue_sheet/project_issue_sheet.py:57 +#, python-format +msgid "The Analytic Account is pending !" +msgstr "" + +#. module: project_issue_sheet +#: model:ir.model,name:project_issue_sheet.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + +#. module: project_issue_sheet +#: model:ir.model,name:project_issue_sheet.model_project_issue +msgid "Project Issue" +msgstr "" + +#. module: project_issue_sheet +#: model:ir.model,name:project_issue_sheet.model_hr_analytic_timesheet +msgid "Timesheet Line" +msgstr "" + +#. module: project_issue_sheet +#: view:project.issue:0 +msgid "on_change_project(project_id)" +msgstr "" + +#. module: project_issue_sheet +#: code:addons/project_issue_sheet/project_issue_sheet.py:57 +#: field:project.issue,analytic_account_id:0 +#, python-format +msgid "Analytic Account" +msgstr "" + +#. module: project_issue_sheet +#: view:project.issue:0 +msgid "Worklogs" +msgstr "" + +#. module: project_issue_sheet +#: field:account.analytic.line,create_date:0 +msgid "Create Date" +msgstr "" + +#. module: project_issue_sheet +#: view:project.issue:0 +#: field:project.issue,timesheet_ids:0 +msgid "Timesheets" +msgstr "" + +#. module: project_issue_sheet +#: field:hr.analytic.timesheet,issue_id:0 +msgid "Issue" +msgstr "" diff --git a/addons/project_issue_sheet/project_issue_sheet.py b/addons/project_issue_sheet/project_issue_sheet.py index 8fe645e19fe..551ef3c8194 100644 --- a/addons/project_issue_sheet/project_issue_sheet.py +++ b/addons/project_issue_sheet/project_issue_sheet.py @@ -58,7 +58,6 @@ class project_issue(osv.osv): return result -project_issue() class account_analytic_line(osv.osv): _inherit = 'account.analytic.line' @@ -67,7 +66,6 @@ class account_analytic_line(osv.osv): 'create_date' : fields.datetime('Create Date', readonly=True), } -account_analytic_line() class hr_analytic_issue(osv.osv): @@ -77,6 +75,5 @@ class hr_analytic_issue(osv.osv): 'issue_id' : fields.many2one('project.issue', 'Issue'), } -hr_analytic_issue() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_long_term/i18n/cs.po b/addons/project_long_term/i18n/cs.po new file mode 100644 index 00000000000..fb1fb15f3a2 --- /dev/null +++ b/addons/project_long_term/i18n/cs.po @@ -0,0 +1,502 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-31 16:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: project_long_term +#: help:project.phase,constraint_date_end:0 +msgid "force the phase to finish before this date" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: selection:project.phase,state:0 +msgid "In Progress" +msgstr "" + +#. module: project_long_term +#: field:account.analytic.account,use_phases:0 +#: model:ir.actions.act_window,name:project_long_term.act_project_phases +#: view:project.project:0 +msgid "Phases" +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,name:project_long_term.act_resouce_allocation +#: model:ir.ui.menu,name:project_long_term.menu_resouce_allocation +#: view:project.phase:0 +#: view:project.user.allocation:0 +msgid "Team Planning" +msgstr "" + +#. module: project_long_term +#: field:project.phase,user_ids:0 +msgid "Assigned Users" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: field:project.phase,next_phase_ids:0 +msgid "Next Phases" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_project_user_allocation +msgid "Phase User Allocation" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Project's Tasks" +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,help:project_long_term.action_project_compute_phases +msgid "" +"To schedule phases of all or a specified project. It then open a gantt " +"view.\n" +" " +msgstr "" + +#. module: project_long_term +#: field:project.phase,task_ids:0 +msgid "Project Tasks" +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,name:project_long_term.action_project_compute_phases +#: model:ir.ui.menu,name:project_long_term.menu_compute_phase +#: view:project.compute.phases:0 +msgid "Schedule Phases" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: field:project.phase,state:0 +msgid "Status" +msgstr "" + +#. module: project_long_term +#: field:project.compute.phases,target_project:0 +msgid "Action" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Start Phase" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_project_task +msgid "Task" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Draft" +msgstr "" + +#. module: project_long_term +#: view:project.compute.phases:0 +#: view:project.compute.tasks:0 +msgid "C_ompute" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: selection:project.phase,state:0 +msgid "New" +msgstr "" + +#. module: project_long_term +#: field:project.phase,product_uom:0 +msgid "Duration Unit of Measure" +msgstr "" + +#. module: project_long_term +#: model:ir.ui.menu,name:project_long_term.menu_view_resource_calendar_leaves +msgid "Resource Leaves" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: selection:project.phase,state:0 +msgid "Pending" +msgstr "" + +#. module: project_long_term +#: help:project.phase,progress:0 +msgid "Computed based on related tasks" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "In Progress Phases" +msgstr "" + +#. module: project_long_term +#: code:addons/project_long_term/project_long_term.py:140 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: project_long_term +#: code:addons/project_long_term/wizard/project_compute_phases.py:48 +#, python-format +msgid "Please specify a project to schedule." +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: view:project.user.allocation:0 +msgid "Group By..." +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Remaining Hours" +msgstr "" + +#. module: project_long_term +#: field:project.phase,constraint_date_start:0 +msgid "Minimum Start Date" +msgstr "" + +#. module: project_long_term +#: help:project.phase,product_uom:0 +msgid "" +"Unit of Measure (Unit of Measure) is the unit of measurement for Duration" +msgstr "" + +#. module: project_long_term +#: help:project.phase,user_ids:0 +msgid "" +"The resources on the project can be computed automatically by the scheduler." +msgstr "" + +#. module: project_long_term +#: field:project.phase,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: project_long_term +#: help:account.analytic.account,use_phases:0 +msgid "Check this field if you plan to use phase-based scheduling" +msgstr "" + +#. module: project_long_term +#: help:project.phase,state:0 +msgid "" +"If the phase is created the status 'Draft'.\n" +" If the phase is started, the status becomes 'In Progress'.\n" +" If review is needed the phase is in 'Pending' status. " +" \n" +" If the phase is over, the status is set to 'Done'." +msgstr "" + +#. module: project_long_term +#: field:project.phase,progress:0 +msgid "Progress" +msgstr "" + +#. module: project_long_term +#: model:ir.ui.menu,name:project_long_term.menu_pm_users_project1 +#: model:ir.ui.menu,name:project_long_term.menu_view_resource +msgid "Resources" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "My Projects" +msgstr "" + +#. module: project_long_term +#: view:project.project:0 +#: view:project.user.allocation:0 +msgid "Phase" +msgstr "" + +#. module: project_long_term +#: help:project.phase,duration:0 +msgid "By default in days" +msgstr "" + +#. module: project_long_term +#: model:ir.ui.menu,name:project_long_term.menu_view_resource_calendar +msgid "Working Time" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Pending Phases" +msgstr "" + +#. module: project_long_term +#: help:project.user.allocation,date_start:0 +msgid "Starting Date" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Related Tasks" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Start Month" +msgstr "" + +#. module: project_long_term +#: field:project.phase,date_end:0 +#: field:project.user.allocation,date_end:0 +msgid "End Date" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_project_compute_tasks +msgid "Project Compute Tasks" +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,help:project_long_term.act_project_phase +msgid "" +"A project can be split into the different phases. For each phase, you can " +"define your users allocation, describe different tasks and link your phase " +"to previous and next phases, add date constraints for the automated " +"scheduling. Use the long term planning in order to planify your available " +"users, convert your phases into a series of tasks when you start working on " +"the project." +msgstr "" + +#. module: project_long_term +#: selection:project.compute.phases,target_project:0 +msgid "Compute a Single Project" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: field:project.phase,previous_phase_ids:0 +msgid "Previous Phases" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "New Phases" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Tasks Details" +msgstr "" + +#. module: project_long_term +#: field:project.project,phase_count:0 +msgid "Open Phases" +msgstr "" + +#. module: project_long_term +#: help:project.phase,date_end:0 +msgid "" +" It's computed by the scheduler according to the start date and the duration." +msgstr "" + +#. module: project_long_term +#: constraint:project.phase:0 +msgid "Loops in phases not allowed" +msgstr "" + +#. module: project_long_term +#: view:project.user.allocation:0 +#: field:project.user.allocation,user_id:0 +msgid "User" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_project_project +#: field:project.compute.phases,project_id:0 +#: field:project.compute.tasks,project_id:0 +#: view:project.phase:0 +#: field:project.phase,project_id:0 +#: view:project.task:0 +#: view:project.user.allocation:0 +#: field:project.user.allocation,project_id:0 +msgid "Project" +msgstr "" + +#. module: project_long_term +#: view:project.compute.phases:0 +#: view:project.compute.tasks:0 +msgid "Cancel" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Project Users" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_project_phase +#: view:project.phase:0 +#: view:project.task:0 +#: field:project.task,phase_id:0 +#: field:project.user.allocation,phase_id:0 +msgid "Project Phase" +msgstr "" + +#. module: project_long_term +#: model:ir.ui.menu,name:project_long_term.menu_phase_schedule +msgid "Scheduling" +msgstr "" + +#. module: project_long_term +#: constraint:project.phase:0 +msgid "Phase start-date must be lower than phase end-date." +msgstr "" + +#. module: project_long_term +#: selection:project.phase,state:0 +msgid "Cancelled" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Total Hours" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_project_compute_phases +msgid "Project Compute Phases" +msgstr "" + +#. module: project_long_term +#: field:project.phase,date_start:0 +#: field:project.user.allocation,date_start:0 +msgid "Start Date" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Constraints" +msgstr "" + +#. module: project_long_term +#: help:project.phase,sequence:0 +msgid "Gives the sequence order when displaying a list of phases." +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,name:project_long_term.project_phase_task_list +msgid "Tasks" +msgstr "" + +#. module: project_long_term +#: help:project.user.allocation,date_end:0 +msgid "Ending Date" +msgstr "" + +#. module: project_long_term +#: code:addons/project_long_term/wizard/project_compute_phases.py:48 +#, python-format +msgid "Error!" +msgstr "" + +#. module: project_long_term +#: help:project.phase,date_start:0 +msgid "" +"It's computed by the scheduler according the project date or the end date of " +"the previous phase." +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,name:project_long_term.act_project_phase +#: model:ir.actions.act_window,name:project_long_term.act_project_phase_list +#: model:ir.ui.menu,name:project_long_term.menu_project_phase +#: model:ir.ui.menu,name:project_long_term.menu_project_phase_list +#: view:project.phase:0 +#: field:project.project,phase_ids:0 +msgid "Project Phases" +msgstr "" + +#. module: project_long_term +#: help:project.phase,constraint_date_start:0 +msgid "force the phase to start after this date" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +msgid "Month" +msgstr "" + +#. module: project_long_term +#: model:ir.model,name:project_long_term.model_account_analytic_account +msgid "Analytic Account" +msgstr "" + +#. module: project_long_term +#: field:project.phase,constraint_date_end:0 +msgid "Deadline" +msgstr "" + +#. module: project_long_term +#: view:project.user.allocation:0 +msgid "Project User Allocation" +msgstr "" + +#. module: project_long_term +#: model:ir.actions.act_window,name:project_long_term.action_project_compute_tasks +#: model:ir.ui.menu,name:project_long_term.menu_compute_tasks +#: view:project.compute.tasks:0 +msgid "Schedule Tasks" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: selection:project.phase,state:0 +msgid "Done" +msgstr "" + +#. module: project_long_term +#: selection:project.compute.phases,target_project:0 +msgid "Compute All My Projects" +msgstr "" + +#. module: project_long_term +#: field:project.phase,user_force_ids:0 +msgid "Force Assigned Users" +msgstr "" + +#. module: project_long_term +#: view:project.phase:0 +#: field:project.phase,duration:0 +msgid "Duration" +msgstr "" + +#. module: project_long_term +#: view:project.user.allocation:0 +msgid "Users" +msgstr "" + +#. module: project_long_term +#: field:project.phase,name:0 +msgid "Name" +msgstr "" + +#. module: project_long_term +#: view:project.compute.phases:0 +#: view:project.compute.tasks:0 +msgid "or" +msgstr "" diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py index e53ff9ed253..a950907fb69 100644 --- a/addons/project_long_term/project_long_term.py +++ b/addons/project_long_term/project_long_term.py @@ -198,7 +198,6 @@ class project_phase(osv.osv): result += "\n" return result -project_phase() class project_user_allocation(osv.osv): _name = 'project.user.allocation' @@ -211,7 +210,6 @@ class project_user_allocation(osv.osv): 'date_start': fields.datetime('Start Date', help="Starting Date"), 'date_end': fields.datetime('End Date', help="Ending Date"), } -project_user_allocation() class project(osv.osv): _inherit = "project.project" @@ -267,7 +265,6 @@ class project(osv.osv): 'date_end': p.end.strftime('%Y-%m-%d %H:%M:%S') }, context=context) return True -project() class account_analytic_account(osv.osv): _inherit = 'account.analytic.account' @@ -283,17 +280,17 @@ class account_analytic_account(osv.osv): res['value']['use_phases'] = template.use_phases return res - def _trigger_project_creation(self, cr, uid, vals, context=None): - res= super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context) - return res or vals.get('use_phases') -account_analytic_account() + def _trigger_project_creation(self, cr, uid, vals, context=None): + if context is None: context = {} + res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context) + return res or (vals.get('use_phases') and not 'project_creation_in_progress' in context) + class project_task(osv.osv): _inherit = "project.task" _columns = { 'phase_id': fields.many2one('project.phase', 'Project Phase', domain="[('project_id', '=', project_id)]"), } -project_task() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_long_term/wizard/project_compute_phases.py b/addons/project_long_term/wizard/project_compute_phases.py index c9aa7eb3573..5ac89e2def2 100644 --- a/addons/project_long_term/wizard/project_compute_phases.py +++ b/addons/project_long_term/wizard/project_compute_phases.py @@ -71,6 +71,5 @@ class project_compute_phases(osv.osv_memory): result['context'] = {"search_default_project_id":project_id, "default_project_id":project_id, "search_default_current": 1} return result -project_compute_phases() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_long_term/wizard/project_compute_tasks.py b/addons/project_long_term/wizard/project_compute_tasks.py index f21dab8a6d2..d442aee7790 100644 --- a/addons/project_long_term/wizard/project_compute_tasks.py +++ b/addons/project_long_term/wizard/project_compute_tasks.py @@ -59,6 +59,5 @@ class project_compute_tasks(osv.osv_memory): result['target'] = 'current' return result -project_compute_tasks() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_mrp/project_mrp.py b/addons/project_mrp/project_mrp.py index a6f0495a962..bb25b4aae24 100644 --- a/addons/project_mrp/project_mrp.py +++ b/addons/project_mrp/project_mrp.py @@ -45,14 +45,12 @@ class project_task(osv.osv): res = super(project_task, self).do_cancel(cr, uid, ids, *args, **kwargs) self._validate_subflows(cr, uid, ids) return res -project_task() class product_product(osv.osv): _inherit = "product.product" _columns = { 'project_id': fields.many2one('project.project', 'Project', ondelete='set null',) } -product_product() class sale_order(osv.osv): _inherit ='sale.order' @@ -108,5 +106,4 @@ class sale_order(osv.osv): 'picked_rate': fields.function(_picked_rate, method=True, string='Picked', type='float'), } -sale_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_mrp/project_procurement.py b/addons/project_mrp/project_procurement.py index 79228fe3285..f4b4a28db46 100644 --- a/addons/project_mrp/project_procurement.py +++ b/addons/project_mrp/project_procurement.py @@ -94,6 +94,5 @@ class procurement_order(osv.osv): if procurement.sale_line_id and procurement.sale_line_id.order_id: procurement.sale_line_id.order_id.message_post(body=body) -procurement_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_mrp/test/project_task_procurement.yml b/addons/project_mrp/test/project_task_procurement.yml index 8854ce20c80..967461ca30a 100644 --- a/addons/project_mrp/test/project_task_procurement.yml +++ b/addons/project_mrp/test/project_task_procurement.yml @@ -27,7 +27,7 @@ assert (not project and not account) or project.analytic_account_id == account, "Project does not correspond." planned_hours = self._convert_qty_company_hours(cr, uid, procurement, context=context) assert task.planned_hours == planned_hours, 'Planned Hours do not correspond.' - assert datetime.strptime(task.date_deadline, '%Y-%m-%d') == datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S'), 'Deadline does not correspond.' + assert datetime.strptime(task.date_deadline, '%Y-%m-%d') == datetime.strptime(procurement.date_planned[:10], '%Y-%m-%d'), 'Deadline does not correspond.' if procurement.product_id.product_manager: assert task.user_id.id == procurement.product_id.product_manager.id, 'Allocated Person does not correspond with Service Product Manager.' - diff --git a/addons/project_timesheet/project_timesheet.py b/addons/project_timesheet/project_timesheet.py index c1f8f6409a9..ffee600f5a7 100644 --- a/addons/project_timesheet/project_timesheet.py +++ b/addons/project_timesheet/project_timesheet.py @@ -22,7 +22,6 @@ import time import datetime from openerp.osv import fields, osv -from openerp import pooler from openerp import tools from openerp.tools.translate import _ @@ -70,7 +69,6 @@ class project_project(osv.osv): result['help'] = help return result -project_project() class project_work(osv.osv): _inherit = "project.task.work" @@ -219,7 +217,6 @@ class project_work(osv.osv): 'hr_analytic_timesheet_id':fields.many2one('hr.analytic.timesheet','Related Timeline Id', ondelete='set null'), } -project_work() class task(osv.osv): _inherit = "project.task" @@ -255,7 +252,6 @@ class task(osv.osv): hr_anlytic_timesheet.write(cr, uid, [line_id], vals_line, {}) return super(task,self).write(cr, uid, ids, vals, context) -task() class res_partner(osv.osv): _inherit = 'res.partner' @@ -267,7 +263,6 @@ class res_partner(osv.osv): return super(res_partner,self).unlink(cursor, user, ids, context=context) -res_partner() class account_analytic_line(osv.osv): _inherit = "account.analytic.line" @@ -294,6 +289,5 @@ class account_analytic_line(osv.osv): raise osv.except_osv(_('Invalid Analytic Account !'), _('You cannot select a Analytic Account which is in Close or Cancelled state.')) return res -account_analytic_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/project_timesheet/report/task_report.py b/addons/project_timesheet/report/task_report.py index c4945e942f6..3411a73a239 100644 --- a/addons/project_timesheet/report/task_report.py +++ b/addons/project_timesheet/report/task_report.py @@ -79,6 +79,5 @@ class report_timesheet_task_user(osv.osv): to_char(to_date(months.name, 'YYYY/MM/DD'),'MM') ) """) -report_timesheet_task_user() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/company.py b/addons/purchase/company.py index 275f5ea200d..cc98c200458 100644 --- a/addons/purchase/company.py +++ b/addons/purchase/company.py @@ -24,13 +24,16 @@ from openerp.osv import osv,fields class company(osv.osv): _inherit = 'res.company' _columns = { - 'po_lead': fields.float('Purchase Lead Time', required=True, - help="This is the leads/security time for each purchase order."), + 'po_lead': fields.float( + 'Purchase Lead Time', required=True, + help="Margin of error for supplier lead times. When the system"\ + "generates Purchase Orders for procuring products,"\ + "they will be scheduled that many days earlier "\ + "to cope with unexpected supplier delays."), } _defaults = { 'po_lead': lambda *a: 1.0, } -company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/html/index.html b/addons/purchase/html/index.html new file mode 100644 index 00000000000..9134c1ab9d2 --- /dev/null +++ b/addons/purchase/html/index.html @@ -0,0 +1,142 @@ +
+
+
+

Purchase Management

+

Automate requisition-to-pay, control invoicing

+
+
+
+ + + +   + +
+
+
+

+Automate procurement propositions, launch request for quotations, track purchase orders, manage suppliers' information, control products reception and check suppliers' invoices. +

+ +
+
+
+ +
+
+

Automated Procurement Propositions

+

Reduce inventory level with procurement rules

+
+

+Get the right purchase proposition at the right time to reduce your inventory level. Improve your purchase and inventory performance with procurement rules depending on stock levels, logistic rules, sales orders, forecasted manufacturing orders, etc. +

+Send requests for quotations or purchase orders to your supplier in one click. Get access to product receptions and invoices from your purchase order. +

+
+
+ +
+
+
+ +
+
+

Purchase Tenders

+

Get the best price by negotiating with several suppliers

+
+ +
+
+

+Launch purchase tenders, integrate supplier's answers in the process and compare propositions. Choose the best offer and send purchase orders easily. Use reporting to analyse the quality of your suppliers afterwards. +

+
+
+
+ +
+
+ +
+ Download our free E-book +
+ +
+
+

Email integrations

+
+

+Integrate all supplier's communications on the purchase orders (or RfQs) to get a strong traceability on the negotiation or after sales service issues. Use the claim management module to track issues related to suppliers. +

+
+
+ +
+
+
+ + +
+
+

Standard Price, Average Price, FIFO

+
+ +
+
+

+Use the costing method that reflects your business: standard price, average price, fifo or lifo. Get your accounting entries and the right inventory valuation in real-time; OpenERP manages everything for you, transparently. +

+
+
+
+ + +
+
+

Import Supplier Pricelists

+

Take smart purchase decisions using the best prices

+
+

+Easily import supplier's pricelists to make smarter purchase decisions based on promotions, prices depending on quantities and special contract conditions. You can even base your sales price depending on your supplier's prices. +

+
+
+ +
+
+
+ +
+
+

Control Products and Invoices

+
+
+ +
+
+
+

+No product or order is left behind, the inventory control allows you to manage back orders, refunds, product reception and quality control. Choose the right control method according to your need. +

+

+Control supplier invoices with no effort. Choose the right method according to your need: pre-generate draft invoices based on purchase orders, on products receptions, create invoices manually and import lines from purchase orders, etc. +

+
+
+
+ +
+
+

Get Statistics On Your Purchases

+
+

+Get accurate statistics on the performance of your suppliers through flexible reporting: delivery delays, negotiated discount on prices, quantities purchased, etc. Integrate purchases with the analytic accounting to analyse your contracts profitability. +

+
+
+ +
+
+
diff --git a/addons/purchase/html/purchase_compose.png b/addons/purchase/html/purchase_compose.png new file mode 100644 index 00000000000..22cbe1cb21c Binary files /dev/null and b/addons/purchase/html/purchase_compose.png differ diff --git a/addons/purchase/html/purchase_dashboard.png b/addons/purchase/html/purchase_dashboard.png new file mode 100644 index 00000000000..0939edea591 Binary files /dev/null and b/addons/purchase/html/purchase_dashboard.png differ diff --git a/addons/purchase/html/purchase_import.png b/addons/purchase/html/purchase_import.png new file mode 100644 index 00000000000..bd2a4d0c15e Binary files /dev/null and b/addons/purchase/html/purchase_import.png differ diff --git a/addons/purchase/html/purchase_incoming.png b/addons/purchase/html/purchase_incoming.png new file mode 100644 index 00000000000..02b82cead02 Binary files /dev/null and b/addons/purchase/html/purchase_incoming.png differ diff --git a/addons/purchase/html/purchase_po.png b/addons/purchase/html/purchase_po.png new file mode 100644 index 00000000000..d9cec9f5140 Binary files /dev/null and b/addons/purchase/html/purchase_po.png differ diff --git a/addons/purchase/html/purchase_procurement.png b/addons/purchase/html/purchase_procurement.png new file mode 100644 index 00000000000..cb315e08224 Binary files /dev/null and b/addons/purchase/html/purchase_procurement.png differ diff --git a/addons/purchase/html/purchase_product.png b/addons/purchase/html/purchase_product.png new file mode 100644 index 00000000000..cbfd054d72e Binary files /dev/null and b/addons/purchase/html/purchase_product.png differ diff --git a/addons/purchase/html/purchase_product_form.png b/addons/purchase/html/purchase_product_form.png new file mode 100644 index 00000000000..a25c85b6496 Binary files /dev/null and b/addons/purchase/html/purchase_product_form.png differ diff --git a/addons/purchase/html/purchase_tender.png b/addons/purchase/html/purchase_tender.png new file mode 100644 index 00000000000..33ef600b869 Binary files /dev/null and b/addons/purchase/html/purchase_tender.png differ diff --git a/addons/purchase/partner.py b/addons/purchase/partner.py index 56eaf288fe6..5e5af0815e3 100644 --- a/addons/purchase/partner.py +++ b/addons/purchase/partner.py @@ -43,6 +43,9 @@ class res_partner(osv.osv): super(res_partner, self).copy(cr, uid, id, default=default, context=context) + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist_purchase'] + _columns = { 'property_product_pricelist_purchase': fields.property( 'product.pricelist', @@ -55,7 +58,6 @@ class res_partner(osv.osv): 'purchase_order_count': fields.function(_purchase_order_count, string='# of Purchase Order', type='integer'), 'purchase_order_ids': fields.one2many('purchase.order','partner_id','Purchase Order') } -res_partner() diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 23f889b136f..849e558563a 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -20,12 +20,13 @@ ############################################################################## import time +import pytz +from openerp import SUPERUSER_ID from datetime import datetime from dateutil.relativedelta import relativedelta from operator import attrgetter from openerp.osv import fields, osv -from openerp import pooler from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp from openerp.osv.orm import browse_record, browse_null @@ -372,7 +373,7 @@ class purchase_order(osv.osv): pick_ids += [picking.id for picking in po.picking_ids] action_model, action_id = tuple(mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree4')) - action = self.pool.get(action_model).read(cr, uid, action_id, context=context) + action = self.pool[action_model].read(cr, uid, action_id, context=context) ctx = eval(action['context']) ctx.update({ 'search_default_purchase_id': ids[0] @@ -427,6 +428,7 @@ class purchase_order(osv.osv): 'default_composition_mode': 'comment', }) return { + 'name': _('Compose Email'), 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', @@ -592,11 +594,34 @@ class purchase_order(osv.osv): self.signal_purchase_cancel(cr, uid, ids) return True + def date_to_datetime(self, cr, uid, userdate, context=None): + """ Convert date values expressed in user's timezone to + server-side UTC timestamp, assuming a default arbitrary + time of 12:00 AM - because a time is needed. + + :param str userdate: date string in in user time zone + :return: UTC datetime string for server-side use + """ + # TODO: move to fields.datetime in server after 7.0 + user_date = datetime.strptime(userdate, DEFAULT_SERVER_DATE_FORMAT) + if context and context.get('tz'): + tz_name = context['tz'] + else: + tz_name = self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz'] + if tz_name: + utc = pytz.timezone('UTC') + context_tz = pytz.timezone(tz_name) + user_datetime = user_date + relativedelta(hours=12.0) + local_timestamp = context_tz.localize(user_datetime, is_dst=False) + user_datetime = local_timestamp.astimezone(utc) + return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + return user_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + def _prepare_order_picking(self, cr, uid, order, context=None): return { 'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.in'), 'origin': order.name + ((order.origin and (':' + order.origin)) or ''), - 'date': order.date_order, + 'date': self.date_to_datetime(cr, uid, order.date_order, context), 'partner_id': order.dest_address_id.id or order.partner_id.id, 'invoice_state': '2binvoiced' if order.invoice_method == 'picking' else 'none', 'type': 'in', @@ -614,8 +639,8 @@ class purchase_order(osv.osv): 'product_uos_qty': order_line.product_qty, 'product_uom': order_line.product_uom.id, 'product_uos': order_line.product_uom.id, - 'date': order_line.date_planned, - 'date_expected': order_line.date_planned, + 'date': self.date_to_datetime(cr, uid, order.date_order, context), + 'date_expected': self.date_to_datetime(cr, uid, order_line.date_planned, context), 'location_id': order.partner_id.property_stock_supplier.id, 'location_dest_id': order.location_id.id, 'picking_id': picking_id, @@ -927,7 +952,8 @@ class purchase_order_line(osv.osv): lang = res_partner.browse(cr, uid, partner_id).lang context_partner.update( {'lang': lang, 'partner_id': partner_id} ) product = product_product.browse(cr, uid, product_id, context=context_partner) - name = product.name + #call name_get() with partner in the context to eventually match name and description in the seller_ids field + dummy, name = product_product.name_get(cr, uid, product_id, context=context_partner)[0] if product.description_purchase: name += '\n' + product.description_purchase res['value'].update({'name': name}) @@ -990,7 +1016,6 @@ class purchase_order_line(osv.osv): self.write(cr, uid, ids, {'state': 'confirmed'}, context=context) return True -purchase_order_line() class procurement_order(osv.osv): _inherit = 'procurement.order' diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 056a06f0750..4432d2b3200 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -270,7 +270,7 @@ - + @@ -297,7 +297,7 @@ - + @@ -335,7 +335,7 @@ ir.actions.act_window purchase.order {} - [('state','in',('draft','sent','cancel'))] + [('state','in',('draft','sent','cancel', 'confirmed'))] tree,form,graph,calendar @@ -481,7 +481,7 @@ - + diff --git a/addons/purchase/report/order.py b/addons/purchase/report/order.py index e415af53434..68d92970aa0 100644 --- a/addons/purchase/report/order.py +++ b/addons/purchase/report/order.py @@ -21,8 +21,6 @@ import time from openerp.report import report_sxw -from openerp.osv import osv -from openerp import pooler class order(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/purchase/report/purchase_report.py b/addons/purchase/report/purchase_report.py index 1855ed173ca..5af74b23495 100644 --- a/addons/purchase/report/purchase_report.py +++ b/addons/purchase/report/purchase_report.py @@ -136,7 +136,6 @@ class purchase_report(osv.osv): u2.factor ) """) -purchase_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/report/request_quotation.py b/addons/purchase/report/request_quotation.py index 1179e704eb0..7be23113584 100644 --- a/addons/purchase/report/request_quotation.py +++ b/addons/purchase/report/request_quotation.py @@ -21,8 +21,6 @@ import time from openerp.report import report_sxw -from openerp.osv import osv -from openerp import pooler class request_quotation(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/purchase/res_config.py b/addons/purchase/res_config.py index 130247037a4..f5f2dfcdda5 100644 --- a/addons/purchase/res_config.py +++ b/addons/purchase/res_config.py @@ -20,7 +20,6 @@ ############################################################################## from openerp.osv import fields, osv -from openerp import pooler from openerp.tools.translate import _ class purchase_config_settings(osv.osv_memory): @@ -66,6 +65,11 @@ Example: Product: this product is deprecated, do not purchase more than 5. 'default_invoice_method': 'manual', } + def onchange_purchase_analytic_plans(self, cr, uid, ids, module_purchase_analytic_plans, context=None): + """ change group_analytic_account_for_purchases following module_purchase_analytic_plans """ + if not module_purchase_analytic_plans: + return {} + return {'value': {'group_analytic_account_for_purchases': module_purchase_analytic_plans}} @@ -82,6 +86,8 @@ class account_config_settings(osv.osv_memory): def onchange_purchase_analytic_plans(self, cr, uid, ids, module_purchase_analytic_plans, context=None): """ change group_analytic_account_for_purchases following module_purchase_analytic_plans """ + if not module_purchase_analytic_plans: + return {} return {'value': {'group_analytic_account_for_purchases': module_purchase_analytic_plans}} # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/res_config_view.xml b/addons/purchase/res_config_view.xml index 7f1cfc64f39..276dc892392 100644 --- a/addons/purchase/res_config_view.xml +++ b/addons/purchase/res_config_view.xml @@ -67,7 +67,7 @@
- +
@@ -109,7 +109,7 @@
- +
diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py index 60b439a2097..e64c12a2359 100644 --- a/addons/purchase/stock.py +++ b/addons/purchase/stock.py @@ -29,7 +29,6 @@ class stock_move(osv.osv): readonly=True), } -stock_move() # # Inherit of picking to add the link to the PO diff --git a/addons/purchase/test/ui/print_report.yml b/addons/purchase/test/ui/print_report.yml index c5a9448e497..94cf49655b6 100644 --- a/addons/purchase/test/ui/print_report.yml +++ b/addons/purchase/test/ui/print_report.yml @@ -3,8 +3,9 @@ - !python {model: purchase.order}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.purchase.quotation').create(cr, uid, [ref('purchase.purchase_order_1'),ref('purchase.purchase_order_2')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('purchase.purchase_order_1'), ref('purchase.purchase_order_2')], 'purchase.quotation', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'purchase-request_quotation'+format), 'wb+').write(data) - diff --git a/addons/purchase/wizard/purchase_line_invoice.py b/addons/purchase/wizard/purchase_line_invoice.py index 12dbf4a09f6..f97d82a8456 100644 --- a/addons/purchase/wizard/purchase_line_invoice.py +++ b/addons/purchase/wizard/purchase_line_invoice.py @@ -142,7 +142,6 @@ class purchase_line_invoice(osv.osv_memory): 'context': "{'type':'in_invoice', 'journal_type': 'purchase'}", 'type': 'ir.actions.act_window' } -purchase_line_invoice() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/wizard/purchase_order_group.py b/addons/purchase/wizard/purchase_order_group.py index b47f4e608a8..243f27efea4 100644 --- a/addons/purchase/wizard/purchase_order_group.py +++ b/addons/purchase/wizard/purchase_order_group.py @@ -21,9 +21,6 @@ import time from openerp.osv import fields, osv -from openerp import netsvc -from openerp import pooler -from openerp.osv.orm import browse_record, browse_null from openerp.tools.translate import _ class purchase_order_group(osv.osv_memory): @@ -86,6 +83,5 @@ class purchase_order_group(osv.osv_memory): 'search_view_id': id['res_id'] } -purchase_order_group() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase_analytic_plans/purchase_analytic_plans.py b/addons/purchase_analytic_plans/purchase_analytic_plans.py index c80beddd20f..a654de83253 100644 --- a/addons/purchase_analytic_plans/purchase_analytic_plans.py +++ b/addons/purchase_analytic_plans/purchase_analytic_plans.py @@ -29,7 +29,6 @@ class purchase_order_line(osv.osv): 'analytics_id':fields.many2one('account.analytic.plan.instance','Analytic Distribution'), } -purchase_order_line() class purchase_order(osv.osv): _name='purchase.order' @@ -40,6 +39,5 @@ class purchase_order(osv.osv): res['analytics_id'] = order_line.analytics_id.id return res -purchase_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml b/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml index bcc67a2a215..d1db411f68c 100644 --- a/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml +++ b/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml @@ -38,5 +38,22 @@
+ + + + + + + + account.invoice.supplier.form.inherit + account.invoice + + 2 + + + + + + diff --git a/addons/purchase_double_validation/i18n/cs.po b/addons/purchase_double_validation/i18n/cs.po new file mode 100644 index 00000000000..70256f5adc4 --- /dev/null +++ b/addons/purchase_double_validation/i18n/cs.po @@ -0,0 +1,49 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-31 16:54+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: purchase_double_validation +#: model:ir.model,name:purchase_double_validation.model_purchase_config_settings +msgid "purchase.config.settings" +msgstr "" + +#. module: purchase_double_validation +#: view:purchase.order:0 +msgid "Purchase orders which are not approved yet." +msgstr "" + +#. module: purchase_double_validation +#: field:purchase.config.settings,limit_amount:0 +msgid "limit to require a second approval" +msgstr "" + +#. module: purchase_double_validation +#: view:board.board:0 +#: model:ir.actions.act_window,name:purchase_double_validation.purchase_waiting +msgid "Purchase Orders Waiting Approval" +msgstr "" + +#. module: purchase_double_validation +#: view:purchase.order:0 +msgid "To Approve" +msgstr "" + +#. module: purchase_double_validation +#: help:purchase.config.settings,limit_amount:0 +msgid "Amount after which validation of purchase is required." +msgstr "" diff --git a/addons/purchase_double_validation/i18n/lt.po b/addons/purchase_double_validation/i18n/lt.po new file mode 100644 index 00000000000..7205a152f84 --- /dev/null +++ b/addons/purchase_double_validation/i18n/lt.po @@ -0,0 +1,49 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-04-29 15:27+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: purchase_double_validation +#: model:ir.model,name:purchase_double_validation.model_purchase_config_settings +msgid "purchase.config.settings" +msgstr "" + +#. module: purchase_double_validation +#: view:purchase.order:0 +msgid "Purchase orders which are not approved yet." +msgstr "" + +#. module: purchase_double_validation +#: field:purchase.config.settings,limit_amount:0 +msgid "limit to require a second approval" +msgstr "" + +#. module: purchase_double_validation +#: view:board.board:0 +#: model:ir.actions.act_window,name:purchase_double_validation.purchase_waiting +msgid "Purchase Orders Waiting Approval" +msgstr "" + +#. module: purchase_double_validation +#: view:purchase.order:0 +msgid "To Approve" +msgstr "" + +#. module: purchase_double_validation +#: help:purchase.config.settings,limit_amount:0 +msgid "Amount after which validation of purchase is required." +msgstr "" diff --git a/addons/purchase_double_validation/test/purchase_double_validation_test.yml b/addons/purchase_double_validation/test/purchase_double_validation_test.yml old mode 100755 new mode 100644 diff --git a/addons/purchase_requisition/i18n/cs.po b/addons/purchase_requisition/i18n/cs.po new file mode 100644 index 00000000000..ab1ba503fe7 --- /dev/null +++ b/addons/purchase_requisition/i18n/cs.po @@ -0,0 +1,473 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-31 16:55+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Request a Quotation" +msgstr "" + +#. module: purchase_requisition +#: selection:purchase.requisition,exclusive:0 +msgid "Multiple Requisitions" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition.line,product_uom_id:0 +msgid "Product Unit of Measure" +msgstr "" + +#. module: purchase_requisition +#: model:ir.actions.act_window,help:purchase_requisition.action_purchase_requisition +msgid "" +"

\n" +" Click to start a new purchase requisition process. \n" +"

\n" +" A purchase requisition is the step before a request for " +"quotation.\n" +" In a purchase requisition (or purchase tender), you can record " +"the\n" +" products you need to buy and trigger the creation of RfQs to\n" +" suppliers. After the negotiation, once you have reviewed all " +"the\n" +" supplier's offers, you can validate some and cancel others.\n" +"

\n" +" " +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: field:purchase.requisition,user_id:0 +msgid "Responsible" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: field:purchase.requisition,state:0 +msgid "Status" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Send to Suppliers" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Group By..." +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: selection:purchase.requisition,state:0 +msgid "Purchase Done" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Purchase Requisition in negociation" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition.partner,partner_id:0 +msgid "Supplier" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: selection:purchase.requisition,state:0 +msgid "New" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Product Detail" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Qty" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Type" +msgstr "" + +#. module: purchase_requisition +#: model:ir.actions.act_window,name:purchase_requisition.action_purchase_requisition_partner +#: model:ir.actions.report.xml,name:purchase_requisition.report_purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_requisition +#: model:ir.module.category,name:purchase_requisition.module_category_purchase_requisition +#: field:product.product,purchase_requisition:0 +#: field:purchase.order,requisition_id:0 +#: view:purchase.requisition:0 +#: field:purchase.requisition.line,requisition_id:0 +#: view:purchase.requisition.partner:0 +msgid "Purchase Requisition" +msgstr "" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_requisition_line +msgid "Purchase Requisition Line" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.order:0 +msgid "Purchase Orders with requisition" +msgstr "" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_product_product +#: field:purchase.requisition.line,product_id:0 +msgid "Product" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Quotations" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Terms and Conditions" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition,description:0 +msgid "Description" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,company_id:0 +#: field:purchase.requisition.line,company_id:0 +msgid "Company" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition.partner:0 +msgid "Create Quotation" +msgstr "" + +#. module: purchase_requisition +#: help:purchase.requisition,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Approved by Supplier" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition.partner:0 +msgid "or" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Reset to Draft" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Current Purchase Requisition" +msgstr "" + +#. module: purchase_requisition +#: model:res.groups,name:purchase_requisition.group_purchase_requisition_user +msgid "User" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Order Reference" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition.line,product_qty:0 +msgid "Quantity" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Unassigned Requisition" +msgstr "" + +#. module: purchase_requisition +#: model:ir.actions.act_window,name:purchase_requisition.action_purchase_requisition +#: model:ir.ui.menu,name:purchase_requisition.menu_purchase_requisition_pro_mgt +msgid "Purchase Requisitions" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Quotation Detail" +msgstr "" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/purchase_requisition.py:134 +#, python-format +msgid "" +"You have already one %s purchase order for this partner, you must cancel " +"this purchase order to create a new quotation." +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "End Date" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition,name:0 +msgid "Requisition Reference" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,line_ids:0 +msgid "Products to Purchase" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: selection:purchase.requisition,state:0 +msgid "Sent to Suppliers" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Search Purchase Requisition" +msgstr "" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/wizard/purchase_requisition_partner.py:41 +#, python-format +msgid "No Product in Tender." +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Date Ordered" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: purchase_requisition +#: help:purchase.requisition,exclusive:0 +msgid "" +"Purchase Requisition (exclusive): On the confirmation of a purchase order, " +"it cancels the remaining purchase order.\n" +"Purchase Requisition(Multiple): It allows to have multiple purchase " +"orders.On confirmation of a purchase order it does not cancel the remaining " +"orders" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Cancel Purchase Order" +msgstr "" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_order +#: view:purchase.requisition:0 +msgid "Purchase Order" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,origin:0 +msgid "Source Document" +msgstr "" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/wizard/purchase_requisition_partner.py:41 +#, python-format +msgid "Error!" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,exclusive:0 +msgid "Requisition Type" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "New Purchase Requisition" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Products" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Order Date" +msgstr "" + +#. module: purchase_requisition +#: selection:purchase.requisition,state:0 +msgid "Cancelled" +msgstr "" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_requisition_partner +msgid "Purchase Requisition Partner" +msgstr "" + +#. module: purchase_requisition +#: help:purchase.requisition,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Purchase for Requisitions" +msgstr "" + +#. module: purchase_requisition +#: model:ir.actions.act_window,name:purchase_requisition.act_res_partner_2_purchase_order +msgid "Purchase orders" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,date_end:0 +msgid "Requisition Deadline" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Reference" +msgstr "" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_procurement_order +msgid "Procurement" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: view:purchase.requisition:0 +msgid "Source" +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,warehouse_id:0 +msgid "Warehouse" +msgstr "" + +#. module: purchase_requisition +#: field:procurement.order,requisition_id:0 +msgid "Latest Requisition" +msgstr "" + +#. module: purchase_requisition +#: model:res.groups,name:purchase_requisition.group_purchase_requisition_manager +msgid "Manager" +msgstr "" + +#. module: purchase_requisition +#: selection:purchase.requisition,exclusive:0 +msgid "Purchase Requisition (exclusive)" +msgstr "" + +#. module: purchase_requisition +#: help:purchase.requisition,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Product UoM" +msgstr "" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/purchase_requisition.py:134 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Confirm Purchase Order" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition.partner:0 +msgid "Cancel" +msgstr "" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition,date_start:0 +msgid "Requisition Date" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Start Date" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Unassigned" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.order:0 +msgid "Requisition" +msgstr "" + +#. module: purchase_requisition +#: help:product.product,purchase_requisition:0 +msgid "" +"Check this box to generates purchase requisition instead of generating " +"requests for quotation from procurement." +msgstr "" + +#. module: purchase_requisition +#: field:purchase.requisition,purchase_ids:0 +msgid "Purchase Orders" +msgstr "" diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index b213f958736..c5d32136a7a 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -194,7 +194,6 @@ class purchase_requisition_line(osv.osv): _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'purchase.requisition.line', context=c), } -purchase_requisition_line() class purchase_order(osv.osv): _inherit = "purchase.order" @@ -216,7 +215,6 @@ class purchase_order(osv.osv): po.requisition_id.tender_done(context=context) return res -purchase_order() class product_product(osv.osv): _inherit = 'product.product' @@ -228,7 +226,6 @@ class product_product(osv.osv): 'purchase_requisition': False } -product_product() class procurement_order(osv.osv): @@ -261,6 +258,5 @@ class procurement_order(osv.osv): res = super(procurement_order, self).make_po(cr, uid, ids, context=context) return res -procurement_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase_requisition/report/requisition.py b/addons/purchase_requisition/report/requisition.py index 315a34d37e9..d7d38f2114e 100644 --- a/addons/purchase_requisition/report/requisition.py +++ b/addons/purchase_requisition/report/requisition.py @@ -21,8 +21,6 @@ import time from openerp.report import report_sxw -from openerp.osv import osv -from openerp import pooler class requisition(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/purchase_requisition/test/purchase_requisition.yml b/addons/purchase_requisition/test/purchase_requisition.yml index bb6daf9eec1..808b2eb5350 100644 --- a/addons/purchase_requisition/test/purchase_requisition.yml +++ b/addons/purchase_requisition/test/purchase_requisition.yml @@ -84,7 +84,8 @@ - !python {model: purchase.requisition}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.purchase.requisition').create(cr, uid, [ref('purchase_requisition.requisition1')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('purchase_requisition.requisition1')], 'purchase.requisition', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'purchase_requisition-purchase_requisition_report.'+format), 'wb+').write(data) diff --git a/addons/purchase_requisition/test/purchase_requisition_demo.yml b/addons/purchase_requisition/test/purchase_requisition_demo.yml old mode 100755 new mode 100644 diff --git a/addons/purchase_requisition/wizard/purchase_requisition_partner.py b/addons/purchase_requisition/wizard/purchase_requisition_partner.py index 58a72556b22..0fee8745931 100644 --- a/addons/purchase_requisition/wizard/purchase_requisition_partner.py +++ b/addons/purchase_requisition/wizard/purchase_requisition_partner.py @@ -47,7 +47,6 @@ class purchase_requisition_partner(osv.osv_memory): self.pool.get('purchase.requisition').make_purchase_order(cr, uid, active_ids, data.partner_id.id, context=context) return {'type': 'ir.actions.act_window_close'} -purchase_requisition_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/report_intrastat/report/invoice.py b/addons/report_intrastat/report/invoice.py index c1f3823c9d8..c38a62774ac 100644 --- a/addons/report_intrastat/report/invoice.py +++ b/addons/report_intrastat/report/invoice.py @@ -21,7 +21,6 @@ import time from openerp.report import report_sxw -from openerp import pooler class account_invoice_intrastat(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/report_intrastat/report_intrastat.py b/addons/report_intrastat/report_intrastat.py index 2d11151cb5b..003aaec8447 100644 --- a/addons/report_intrastat/report_intrastat.py +++ b/addons/report_intrastat/report_intrastat.py @@ -34,7 +34,6 @@ class res_country(osv.osv): 'intrastat': lambda *a: False, } -res_country() class report_intrastat_code(osv.osv): @@ -45,7 +44,6 @@ class report_intrastat_code(osv.osv): 'description': fields.char('Description', size=64), } -report_intrastat_code() class product_template(osv.osv): @@ -55,7 +53,6 @@ class product_template(osv.osv): 'intrastat_id': fields.many2one('report.intrastat.code', 'Intrastat code'), } -product_template() class report_intrastat(osv.osv): _name = "report.intrastat" @@ -122,6 +119,5 @@ class report_intrastat(osv.osv): group by to_char(inv.create_date, 'YYYY'), to_char(inv.create_date, 'MM'),intrastat.id,inv.type,pt.intrastat_id, inv_country.code,inv.number, inv.currency_id )""") -report_intrastat() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/report_intrastat/test/report_intrastat_report.yml b/addons/report_intrastat/test/report_intrastat_report.yml index e51bfbbe748..687f605b901 100644 --- a/addons/report_intrastat/test/report_intrastat_report.yml +++ b/addons/report_intrastat/test/report_intrastat_report.yml @@ -14,7 +14,8 @@ - !python {model: account.invoice}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.account.invoice.intrastat').create(cr, uid, [ref('test_invoice_1')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('test_invoice_1')], 'account.invoice.intrastat', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'report_intrastat-intrastat_report.'+format), 'wb+').write(data) diff --git a/addons/report_webkit/__init__.py b/addons/report_webkit/__init__.py index 2c23fd8ed90..e00289407d8 100644 --- a/addons/report_webkit/__init__.py +++ b/addons/report_webkit/__init__.py @@ -25,7 +25,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/report_webkit/__openerp__.py b/addons/report_webkit/__openerp__.py index d1640ab2f30..f4035a951de 100644 --- a/addons/report_webkit/__openerp__.py +++ b/addons/report_webkit/__openerp__.py @@ -25,7 +25,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## @@ -92,6 +92,9 @@ TODO: 'demo': [ "report/webkit_report_demo.xml", ], + 'test': [ + "test/print.yml", + ], 'installable': True, 'auto_install': False, 'images': ['images/companies_webkit.jpeg','images/header_html.jpeg','images/header_img.jpeg'], diff --git a/addons/report_webkit/company.py b/addons/report_webkit/company.py index f9ae4191528..b29354938de 100644 --- a/addons/report_webkit/company.py +++ b/addons/report_webkit/company.py @@ -25,7 +25,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/report_webkit/convert.py b/addons/report_webkit/convert.py index b4d42325bb6..e30209a77dc 100644 --- a/addons/report_webkit/convert.py +++ b/addons/report_webkit/convert.py @@ -25,7 +25,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/report_webkit/header.py b/addons/report_webkit/header.py index 71deb57c370..7a290662498 100644 --- a/addons/report_webkit/header.py +++ b/addons/report_webkit/header.py @@ -25,7 +25,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## @@ -87,7 +87,6 @@ class HeaderHTML(osv.osv): help="Select Proper Paper size" ) } -HeaderHTML() class HeaderImage(osv.osv): """Logo allows you to define multiple logo per company""" @@ -98,6 +97,5 @@ class HeaderImage(osv.osv): 'name' : fields.char('Name', size=128, required =True, help="Name of Image"), 'type' : fields.char('Type', size=32, required =True, help="Image type(png,gif,jpeg)") } -HeaderImage() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/report_webkit/i18n/cs.po b/addons/report_webkit/i18n/cs.po new file mode 100644 index 00000000000..bacda6d4bdf --- /dev/null +++ b/addons/report_webkit/i18n/cs.po @@ -0,0 +1,517 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-31 16:55+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-01 05:06+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: report_webkit +#: view:ir.actions.report.xml:0 +msgid "Webkit Template (used if Report File is not found)" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Tabloid 29 279.4 x 431.8 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Ledger 28 431.8 x 279.4 mm" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:233 +#, python-format +msgid "No header defined for this Webkit report!" +msgstr "" + +#. module: report_webkit +#: help:ir.header_img,type:0 +msgid "Image type(png,gif,jpeg)" +msgstr "" + +#. module: report_webkit +#: help:ir.actions.report.xml,precise_mode:0 +msgid "" +"This mode allow more precise element " +" position as each object is printed on a separate HTML. " +" but memory and disk " +"usage is wider" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Executive 4 7.5 x 10 inches, 190.5 x 254 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.header_img,company_id:0 +#: field:ir.header_webkit,company_id:0 +msgid "Company" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:234 +#, python-format +msgid "Please set a header in company settings." +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "DLE 26 110 x 220 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B7 21 88 x 125 mm" +msgstr "" + +#. module: report_webkit +#: view:res.company:0 +msgid "Headers" +msgstr "" + +#. module: report_webkit +#: help:ir.header_img,name:0 +msgid "Name of Image" +msgstr "" + +#. module: report_webkit +#: model:ir.actions.act_window,name:report_webkit.action_header_webkit +#: model:ir.ui.menu,name:report_webkit.menu_header_webkit +msgid "Webkit Headers/Footers" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Legal 3 8.5 x 14 inches, 215.9 x 355.6 mm" +msgstr "" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_ir_header_webkit +msgid "ir.header_webkit" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A4 0 210 x 297 mm, 8.26 x 11.69 inches" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:176 +#, python-format +msgid "Webkit error" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B2 17 500 x 707 mm" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:260 +#: code:addons/report_webkit/webkit_report.py:271 +#: code:addons/report_webkit/webkit_report.py:280 +#: code:addons/report_webkit/webkit_report.py:293 +#: code:addons/report_webkit/webkit_report.py:304 +#, python-format +msgid "Webkit render!" +msgstr "" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_ir_header_img +msgid "ir.header_img" +msgstr "" + +#. module: report_webkit +#: field:ir.actions.report.xml,precise_mode:0 +msgid "Precise Mode" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:96 +#, python-format +msgid "" +"Please install executable on your system (sudo apt-get install wkhtmltopdf) " +"or download it from here: " +"http://code.google.com/p/wkhtmltopdf/downloads/list and set the path in the " +"ir.config_parameter with the webkit_path key.Minimal version is 0.9.9" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A0 5 841 x 1189 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "C5E 24 163 x 229 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.header_img,type:0 +msgid "Type" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/wizard/report_webkit_actions.py:133 +#, python-format +msgid "Client Actions Connections" +msgstr "" + +#. module: report_webkit +#: field:res.company,header_image:0 +msgid "Available Images" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,html:0 +msgid "webkit header" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B1 15 707 x 1000 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A1 6 594 x 841 mm" +msgstr "" + +#. module: report_webkit +#: help:ir.actions.report.xml,webkit_header:0 +msgid "The header linked to the report" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:95 +#, python-format +msgid "Wkhtmltopdf library path is not set" +msgstr "" + +#. module: report_webkit +#: view:ir.actions.report.xml:0 +#: view:res.company:0 +msgid "Webkit" +msgstr "" + +#. module: report_webkit +#: help:ir.header_webkit,format:0 +msgid "Select Proper Paper size" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B5 1 176 x 250 mm, 6.93 x 9.84 inches" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A7 11 74 x 105 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A6 10 105 x 148 mm" +msgstr "" + +#. module: report_webkit +#: help:ir.actions.report.xml,report_webkit_data:0 +msgid "This template will be used if the main report file is not found" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Folio 27 210 x 330 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,margin_top:0 +msgid "Top Margin (mm)" +msgstr "" + +#. module: report_webkit +#: view:report.webkit.actions:0 +msgid "_Ok" +msgstr "" + +#. module: report_webkit +#: help:report.webkit.actions,print_button:0 +msgid "" +"Check this to add a Print action for this Report in the sidebar of the " +"corresponding document types" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B3 18 353 x 500 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.actions.report.xml,webkit_header:0 +msgid "Webkit Header" +msgstr "" + +#. module: report_webkit +#: help:ir.actions.report.xml,webkit_debug:0 +msgid "Enable the webkit engine debugger" +msgstr "" + +#. module: report_webkit +#: field:ir.header_img,img:0 +msgid "Image" +msgstr "" + +#. module: report_webkit +#: view:ir.header_img:0 +msgid "Header Image" +msgstr "" + +#. module: report_webkit +#: field:res.company,header_webkit:0 +msgid "Available html" +msgstr "" + +#. module: report_webkit +#: help:report.webkit.actions,open_action:0 +msgid "" +"Check this to view the newly added internal print action after creating it " +"(technical view) " +msgstr "" + +#. module: report_webkit +#: view:res.company:0 +msgid "Images" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,orientation:0 +msgid "Portrait" +msgstr "" + +#. module: report_webkit +#: view:report.webkit.actions:0 +msgid "or" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,orientation:0 +msgid "Landscape" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B8 22 62 x 88 mm" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:177 +#, python-format +msgid "The command 'wkhtmltopdf' failed with error code = %s. Message: %s" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A2 7 420 x 594 mm" +msgstr "" + +#. module: report_webkit +#: field:report.webkit.actions,print_button:0 +msgid "Add print button" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A9 13 37 x 52 mm" +msgstr "" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_res_company +msgid "Companies" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,margin_bottom:0 +msgid "Bottom Margin (mm)" +msgstr "" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_report_webkit_actions +msgid "Webkit Actions" +msgstr "" + +#. module: report_webkit +#: field:report.webkit.actions,open_action:0 +msgid "Open added action" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,margin_right:0 +msgid "Right Margin (mm)" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:228 +#, python-format +msgid "Webkit report template not found!" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,orientation:0 +msgid "Orientation" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B6 20 125 x 176 mm" +msgstr "" + +#. module: report_webkit +#: help:ir.header_webkit,html:0 +msgid "Set Webkit Report Header" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,format:0 +msgid "Paper size" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid ":B10 16 31 x 44 mm" +msgstr "" + +#. module: report_webkit +#: view:report.webkit.actions:0 +msgid "Cancel" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,css:0 +msgid "Header CSS" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B4 19 250 x 353 mm" +msgstr "" + +#. module: report_webkit +#: model:ir.actions.act_window,name:report_webkit.action_header_img +#: model:ir.ui.menu,name:report_webkit.menu_header_img +msgid "Webkit Logos" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:172 +#, python-format +msgid "No diagnosis message was provided" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A3 8 297 x 420 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.actions.report.xml,report_webkit_data:0 +msgid "Webkit Template" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,footer_html:0 +msgid "webkit footer" +msgstr "" + +#. module: report_webkit +#: field:ir.actions.report.xml,webkit_debug:0 +msgid "Webkit debug" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Letter 2 8.5 x 11 inches, 215.9 x 279.4 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B0 14 1000 x 1414 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.header_img,name:0 +#: field:ir.header_webkit,name:0 +msgid "Name" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A5 9 148 x 210 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A8 12 52 x 74 mm" +msgstr "" + +#. module: report_webkit +#: model:ir.actions.act_window,name:report_webkit.wizard_ofdo_report_actions +#: view:report.webkit.actions:0 +msgid "Add Print Buttons" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Comm10E 25 105 x 241 mm, U.S. Common 10 Envelope" +msgstr "" + +#. module: report_webkit +#: field:ir.header_webkit,margin_left:0 +msgid "Left Margin (mm)" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:228 +#, python-format +msgid "Error!" +msgstr "" + +#. module: report_webkit +#: help:ir.header_webkit,footer_html:0 +msgid "Set Webkit Report Footer." +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B9 23 33 x 62 mm" +msgstr "" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_ir_actions_report_xml +msgid "ir.actions.report.xml" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:174 +#, python-format +msgid "The following diagnosis message was provided:\n" +msgstr "" + +#. module: report_webkit +#: view:ir.header_webkit:0 +msgid "HTML Header" +msgstr "" diff --git a/addons/report_webkit/ir_report.py b/addons/report_webkit/ir_report.py index 8b8f99b8ebf..cea2b4e8329 100644 --- a/addons/report_webkit/ir_report.py +++ b/addons/report_webkit/ir_report.py @@ -25,117 +25,65 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## -from openerp.osv import fields, osv -import openerp.report.interface -from openerp.report.report_sxw import rml_parse +import openerp +from openerp.osv import fields, orm from webkit_report import WebKitParser -def register_report(name, model, tmpl_path, parser=rml_parse): - """Register the report into the services""" - name = 'report.%s' % name - if name in openerp.report.interface.report_int._reports: - service = openerp.report.interface.report_int._reports[name] - if isinstance(service, WebKitParser): - #already instantiated properly, skip it - return - if hasattr(service, 'parser'): - parser = service.parser - del openerp.report.interface.report_int._reports[name] - WebKitParser(name, model, tmpl_path, parser=parser) - - -class ReportXML(osv.osv): - - def __init__(self, pool, cr): - super(ReportXML, self).__init__(pool, cr) - - def register_all(self,cursor): - value = super(ReportXML, self).register_all(cursor) - cursor.execute("SELECT * FROM ir_act_report_xml WHERE report_type = 'webkit'") - records = cursor.dictfetchall() - for record in records: - register_report(record['report_name'], record['model'], record['report_rml']) - return value - - def unlink(self, cursor, user, ids, context=None): - """Delete report and unregister it""" - trans_obj = self.pool.get('ir.translation') - trans_ids = trans_obj.search( - cursor, - user, - [('type', '=', 'report'), ('res_id', 'in', ids)] - ) - trans_obj.unlink(cursor, user, trans_ids) - - # Warning: we cannot unregister the services at the moment - # because they are shared across databases. Calling a deleted - # report will fail so it's ok. - - res = super(ReportXML, self).unlink( - cursor, - user, - ids, - context - ) - return res - - def create(self, cursor, user, vals, context=None): - "Create report and register it" - res = super(ReportXML, self).create(cursor, user, vals, context) - if vals.get('report_type','') == 'webkit': - # I really look forward to virtual functions :S - register_report( - vals['report_name'], - vals['model'], - vals.get('report_rml', False) - ) - return res - - def write(self, cr, uid, ids, vals, context=None): - "Edit report and manage it registration" - if isinstance(ids, (int, long)): - ids = [ids,] - for rep in self.browse(cr, uid, ids, context=context): - if rep.report_type != 'webkit': - continue - if vals.get('report_name', False) and \ - vals['report_name'] != rep.report_name: - report_name = vals['report_name'] - else: - report_name = rep.report_name - - register_report( - report_name, - vals.get('model', rep.model), - vals.get('report_rml', rep.report_rml) - ) - res = super(ReportXML, self).write(cr, uid, ids, vals, context) - return res - - _name = 'ir.actions.report.xml' +class ir_actions_report_xml(orm.Model): _inherit = 'ir.actions.report.xml' _columns = { - 'webkit_header': fields.property( - 'ir.header_webkit', - type='many2one', - relation='ir.header_webkit', - string='Webkit Header', - help="The header linked to the report", - view_load=True, - required=True - ), - 'webkit_debug' : fields.boolean('Webkit debug', help="Enable the webkit engine debugger"), - 'report_webkit_data': fields.text('Webkit Template', help="This template will be used if the main report file is not found"), - 'precise_mode':fields.boolean('Precise Mode', help='This mode allow more precise element \ - position as each object is printed on a separate HTML.\ - but memory and disk usage is wider') + 'webkit_header': fields.property('ir.header_webkit', + type='many2one', relation='ir.header_webkit', + string='Webkit Header', help="The header linked to the report", + view_load=True, required=True), + 'webkit_debug': fields.boolean('Webkit debug', + help="Enable the webkit engine debugger"), + 'report_webkit_data': fields.text('Webkit Template', + help="This template will be used if the main report file is not found"), + 'precise_mode': fields.boolean('Precise Mode', + help="This mode allow more precise element position as each object" + " is printed on a separate HTML but memory and disk usage are wider.") } -ReportXML() + def _lookup_report(self, cr, name): + """ + Look up a report definition. + """ + import operator + import os + opj = os.path.join + + # First lookup in the deprecated place, because if the report definition + # has not been updated, it is more likely the correct definition is there. + # Only reports with custom parser specified in Python are still there. + if 'report.' + name in openerp.report.interface.report_int._reports: + new_report = openerp.report.interface.report_int._reports['report.' + name] + if not isinstance(new_report, WebKitParser): + new_report = None + else: + cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s and report_type=%s", (name, 'webkit')) + r = cr.dictfetchone() + if r: + if r['parser']: + parser = operator.attrgetter(r['parser'])(openerp.addons) + kwargs = { 'parser': parser } + else: + kwargs = {} + + new_report = WebKitParser('report.'+r['report_name'], + r['model'], opj('addons',r['report_rml'] or '/'), + header=r['header'], register=False, **kwargs) + else: + new_report = None + + if new_report: + return new_report + else: + return super(ir_actions_report_xml, self)._lookup_report(cr, name) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/report_webkit/report_helper.py b/addons/report_webkit/report_helper.py index bc2eb9397ec..83286dc59bd 100644 --- a/addons/report_webkit/report_helper.py +++ b/addons/report_webkit/report_helper.py @@ -25,11 +25,11 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## -from openerp import pooler +import openerp class WebKitHelper(object): """Set of usefull report helper""" @@ -37,7 +37,7 @@ class WebKitHelper(object): "constructor" self.cursor = cursor self.uid = uid - self.pool = pooler.get_pool(self.cursor.dbname) + self.pool = openerp.registry(self.cursor.dbname) self.report_id = report_id self.context = context diff --git a/addons/report_webkit/test/print.yml b/addons/report_webkit/test/print.yml new file mode 100644 index 00000000000..b201efa97de --- /dev/null +++ b/addons/report_webkit/test/print.yml @@ -0,0 +1,10 @@ +- + Print the report_webkit demo report. +- + !python {model: ir.actions.report.xml}: | + import os + from openerp import netsvc, tools + ids = self.pool['ir.actions.report.xml'].search(cr, uid, [], {}) + (data, format) = netsvc.LocalService('report.webkit.ir.actions.report.xml').create(cr, uid, ids, {}, {}) + if tools.config['test_report_directory']: + file(os.path.join(tools.config['test_report_directory'], 'report_webkit_demo_report.'+format), 'wb+').write(data) diff --git a/addons/report_webkit/webkit_report.py b/addons/report_webkit/webkit_report.py index f4f65e56596..82061daa758 100644 --- a/addons/report_webkit/webkit_report.py +++ b/addons/report_webkit/webkit_report.py @@ -26,7 +26,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## @@ -38,11 +38,10 @@ import tempfile import time import logging -from openerp import netsvc -from openerp import pooler from report_helper import WebKitHelper +import openerp +from openerp.modules.module import get_module_resource from openerp.report.report_sxw import * -from openerp import addons from openerp import tools from openerp.tools.translate import _ from openerp.osv.osv import except_osv @@ -117,16 +116,16 @@ class WebKitParser(report_sxw): """Custom class that use webkit to render HTML reports Code partially taken from report openoffice. Thanks guys :) """ - def __init__(self, name, table, rml=False, parser=False, - header=True, store=False): + def __init__(self, name, table, rml=False, parser=rml_parse, + header=True, store=False, register=True): self.parser_instance = False self.localcontext = {} report_sxw.__init__(self, name, table, rml, parser, - header, store) + header, store, register=register) def get_lib(self, cursor, uid): """Return the lib wkhtml path""" - proxy = self.pool.get('ir.config_parameter') + proxy = self.pool['ir.config_parameter'] webkit_path = proxy.get_param(cursor, uid, 'webkit_path') if not webkit_path: @@ -242,7 +241,7 @@ class WebKitParser(report_sxw): def translate_call(self, src): """Translate String.""" - ir_translation = self.pool.get('ir.translation') + ir_translation = self.pool['ir.translation'] res = ir_translation._get_source(self.parser_instance.cr, self.parser_instance.uid, None, 'report', self.parser_instance.localcontext.get('lang', 'en_US'), src) if not res : @@ -255,13 +254,12 @@ class WebKitParser(report_sxw): # just try to find an xml id for the report cr = cursor - import openerp.pooler as pooler - pool = pooler.get_pool(cr.dbname) - found_xml_ids = pool.get("ir.model.data").search(cr, uid, [["model", "=", "ir.actions.report.xml"], \ + pool = openerp.registry(cr.dbname) + found_xml_ids = pool["ir.model.data"].search(cr, uid, [["model", "=", "ir.actions.report.xml"], \ ["res_id", "=", report_xml.id]], context=context) xml_id = None if found_xml_ids: - xml_id = pool.get("ir.model.data").read(cr, uid, found_xml_ids[0], ["module", "name"]) + xml_id = pool["ir.model.data"].read(cr, uid, found_xml_ids[0], ["module", "name"]) xml_id = "%s.%s" % (xml_id["module"], xml_id["name"]) if context is None: @@ -275,14 +273,14 @@ class WebKitParser(report_sxw): self.name2, context=context) - self.pool = pooler.get_pool(cursor.dbname) + self.pool = pool objs = self.getObjects(cursor, uid, ids, context) self.parser_instance.set_context(objs, data, ids, report_xml.report_type) template = False if report_xml.report_file : - path = addons.get_module_resource(*report_xml.report_file.split(os.path.sep)) + path = get_module_resource(*report_xml.report_file.split(os.path.sep)) if path and os.path.exists(path) : template = file(path).read() if not template and report_xml.report_webkit_data : @@ -298,7 +296,7 @@ class WebKitParser(report_sxw): ) if not report_xml.header : header = '' - default_head = addons.get_module_resource('report_webkit', 'default_header.html') + default_head = get_module_resource('report_webkit', 'default_header.html') with open(default_head,'r') as f: header = f.read() css = report_xml.webkit_header.css @@ -367,8 +365,8 @@ class WebKitParser(report_sxw): def create(self, cursor, uid, ids, data, context=None): """We override the create function in order to handle generator Code taken from report openoffice. Thanks guys :) """ - pool = pooler.get_pool(cursor.dbname) - ir_obj = pool.get('ir.actions.report.xml') + pool = openerp.registry(cursor.dbname) + ir_obj = pool['ir.actions.report.xml'] report_xml_ids = ir_obj.search(cursor, uid, [('report_name', '=', self.name[7:])], context=context) if report_xml_ids: diff --git a/addons/report_webkit/wizard/__init__.py b/addons/report_webkit/wizard/__init__.py index e8ae8b79fc0..e95244cc7aa 100644 --- a/addons/report_webkit/wizard/__init__.py +++ b/addons/report_webkit/wizard/__init__.py @@ -25,7 +25,7 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## diff --git a/addons/report_webkit/wizard/report_webkit_actions.py b/addons/report_webkit/wizard/report_webkit_actions.py index b0e761752f6..e22e7948d59 100644 --- a/addons/report_webkit/wizard/report_webkit_actions.py +++ b/addons/report_webkit/wizard/report_webkit_actions.py @@ -25,13 +25,12 @@ # # 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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## from openerp.tools.translate import _ from openerp.osv import fields, osv -from openerp import pooler class report_webkit_actions(osv.osv_memory): _name = "report.webkit.actions" @@ -61,13 +60,13 @@ class report_webkit_actions(osv.osv_memory): if not record_id or (active_model and active_model != 'ir.actions.report.xml'): return res - report = self.pool.get('ir.actions.report.xml').browse( + report = self.pool['ir.actions.report.xml'].browse( cr, uid, context.get('active_id'), context=context ) - ir_values_obj = self.pool.get('ir.values') + ir_values_obj = self.pool['ir.values'] ids = ir_values_obj.search( cr, uid, @@ -93,7 +92,7 @@ class report_webkit_actions(osv.osv_memory): """ if context is None: context = {} - report_obj = self.pool.get('ir.actions.report.xml') + report_obj = self.pool['ir.actions.report.xml'] for current in self.browse(cr, uid, ids, context=context): report = report_obj.browse( cr, @@ -102,7 +101,7 @@ class report_webkit_actions(osv.osv_memory): context=context ) if current.print_button: - ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values') + ir_values_obj = self.pool['ir.values'] res = ir_values_obj.set( cr, uid, @@ -114,7 +113,7 @@ class report_webkit_actions(osv.osv_memory): isobject=True ) else: - ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values') + ir_values_obj = self.pool['ir.values'] res = ir_values_obj.set( cr, uid, @@ -139,6 +138,5 @@ class report_webkit_actions(osv.osv_memory): 'type': 'ir.actions.act_window', } -report_webkit_actions() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/resource/faces/observer.py b/addons/resource/faces/observer.py index 894345230ea..28ae58eb2b6 100644 --- a/addons/resource/faces/observer.py +++ b/addons/resource/faces/observer.py @@ -22,7 +22,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ #@-node:<< Copyright >> diff --git a/addons/resource/faces/pcalendar.py b/addons/resource/faces/pcalendar.py index c82c49d4816..24c974233d8 100644 --- a/addons/resource/faces/pcalendar.py +++ b/addons/resource/faces/pcalendar.py @@ -22,7 +22,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ #@-node:<< Copyright >> diff --git a/addons/resource/faces/plocale.py b/addons/resource/faces/plocale.py index 61bfa91917b..908fd1252e9 100644 --- a/addons/resource/faces/plocale.py +++ b/addons/resource/faces/plocale.py @@ -17,7 +17,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ import gettext diff --git a/addons/resource/faces/resource.py b/addons/resource/faces/resource.py index 3451806444e..faee8174994 100644 --- a/addons/resource/faces/resource.py +++ b/addons/resource/faces/resource.py @@ -22,7 +22,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ #@-node:<< Copyright >> diff --git a/addons/resource/faces/task.py b/addons/resource/faces/task.py index 7516f41db2a..961f6213d1d 100644 --- a/addons/resource/faces/task.py +++ b/addons/resource/faces/task.py @@ -22,7 +22,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ #@-node:<< Copyright >> diff --git a/addons/resource/faces/timescale.py b/addons/resource/faces/timescale.py index 3e7c3c1dc89..818c031b7d5 100644 --- a/addons/resource/faces/timescale.py +++ b/addons/resource/faces/timescale.py @@ -17,7 +17,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ import faces.pcalendar as pcal diff --git a/addons/resource/faces/utils.py b/addons/resource/faces/utils.py index 54985767613..6568c314fb5 100644 --- a/addons/resource/faces/utils.py +++ b/addons/resource/faces/utils.py @@ -17,7 +17,7 @@ # 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. +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################ import observer diff --git a/addons/resource/resource.py b/addons/resource/resource.py index 727ca93d7c9..449fa422ab4 100644 --- a/addons/resource/resource.py +++ b/addons/resource/resource.py @@ -19,10 +19,13 @@ # ############################################################################## +import pytz from datetime import datetime, timedelta +from dateutil import rrule import math from faces import * from openerp.osv import fields, osv +from openerp.tools.float_utils import float_compare from openerp.tools.translate import _ from itertools import groupby @@ -106,11 +109,11 @@ class resource_calendar(osv.osv): result = [] maxrecur = 100 current_hour = dt_from.hour - while (todo>0) and maxrecur: + while float_compare(todo, 0, 4) and maxrecur: cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from desc", (dt_from.weekday(),id)) for (hour_from,hour_to) in cr.fetchall(): leave_flag = False - if (hour_from0): + if (hour_fromtodo: hour_from = m-todo @@ -159,10 +162,10 @@ class resource_calendar(osv.osv): result = [] maxrecur = 100 current_hour = dt_from.hour - while (todo>0) and maxrecur: + while float_compare(todo, 0, 4) and maxrecur: for (hour_from,hour_to) in [(item['hour_from'], item['hour_to']) for item in hours_by_cal[id] if item['dayofweek'] == str(dt_from.weekday())]: leave_flag = False - if (hour_to>current_hour) and (todo>0): + if (hour_to>current_hour) and float_compare(todo, 0, 4): m = max(hour_from, current_hour) if (hour_to-m)>todo: hour_to = m+todo @@ -212,47 +215,109 @@ class resource_calendar(osv.osv): @return : Total number of working hours based dt_from and dt_end and resource if supplied. """ - if not id: - return 0.0 - dt_leave = self._get_leaves(cr, uid, id, resource) - hours = 0.0 + return self._interval_hours_get(cr, uid, id, dt_from, dt_to, resource_id=resource) - current_hour = dt_from.hour + def _interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource_id=False, timezone_from_uid=None, exclude_leaves=True, context=None): + """ Calculates the Total Working hours based on given start_date to + end_date, If resource id is supplied that it will consider the source + leaves also in calculating the hours. - while (dt_from <= dt_to): - cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.weekday(),id)) - der = cr.fetchall() - for (hour_from,hour_to) in der: - if hours != 0.0:#For first time of the loop only,hours will be 0 - current_hour = hour_from - leave_flag = False - if (hour_to>=current_hour): - dt_check = dt_from.strftime('%Y-%m-%d') - for leave in dt_leave: - if dt_check == leave: - dt_check = datetime.strptime(dt_check, "%Y-%m-%d") + timedelta(days=1) - leave_flag = True + @param dt_from : date start to calculate hours + @param dt_end : date end to calculate hours + @param resource_id: optional resource id, If given resource leave will be + considered. + @param timezone_from_uid: optional uid, if given we will considerer + working hours in that user timezone + @param exclude_leaves: optionnal, if set to True (default) we will exclude + resource leaves from working hours + @param context: current request context + @return : Total number of working hours based dt_from and dt_end and + resource if supplied. + """ + utc_tz = pytz.timezone('UTC') + local_tz = utc_tz - if leave_flag: - break - else: - d1 = dt_from - d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60)) + if timezone_from_uid: + users_obj = self.pool.get('res.users') + user_timezone = users_obj.browse(cr, uid, timezone_from_uid, context=context).partner_id.tz + if user_timezone: + try: + local_tz = pytz.timezone(user_timezone) + except pytz.UnknownTimeZoneError: + pass # fallback to UTC as local timezone - if hours != 0.0:#For first time of the loop only,hours will be 0 - d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60)) + def utc_to_local_zone(naive_datetime): + utc_dt = utc_tz.localize(naive_datetime, is_dst=False) + return utc_dt.astimezone(local_tz) - if dt_from.day == dt_to.day: - if hour_from <= dt_to.hour <= hour_to: - d2 = dt_to - dt_from = d2 - hours += (d2-d1).seconds - dt_from = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(current_hour)), int((current_hour%1) * 60)) + timedelta(days=1) - current_hour = 0.0 + def float_time_convert(float_val): + factor = float_val < 0 and -1 or 1 + val = abs(float_val) + return (factor * int(math.floor(val)), int(round((val % 1) * 60))) - return (hours/3600) + # Get slots hours per day + # {day_of_week: [(8, 12), (13, 17), ...], ...} + hours_range_per_weekday = {} + if id: + cr.execute("select dayofweek, hour_from,hour_to from resource_calendar_attendance where calendar_id=%s order by hour_from", (id,)) + for weekday, hour_from, hour_to in cr.fetchall(): + weekday = int(weekday) + hours_range_per_weekday.setdefault(weekday, []) + hours_range_per_weekday[weekday].append((hour_from, hour_to)) + else: + # considering default working hours (Monday -> Friday, 8 -> 12, 13 -> 17) + for weekday in range(5): + hours_range_per_weekday[weekday] = [(8, 12), (13, 17)] + + ## Interval between dt_from - dt_to + ## + ## dt_from dt_to + ## =============|==================|============ + ## [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] + ## + ## [ : start of range + ## ] : end of range + ## + ## case 1: range end before interval start (skip) + ## case 2: range overlap interval start (fit start to internal) + ## case 3: range within interval + ## case 4: range overlap interval end (fit end to interval) + ## case 5: range start after interval end (skip) + + interval_start = utc_to_local_zone(dt_from) + interval_end = utc_to_local_zone(dt_to) + hours_timedelta = timedelta() + + # Get leaves for requested resource + dt_leaves = set([]) + if exclude_leaves and id: + dt_leaves = set(self._get_leaves(cr, uid, id, resource=resource_id)) + + for day in rrule.rrule(rrule.DAILY, dtstart=interval_start, + until=interval_end+timedelta(days=1), + byweekday=hours_range_per_weekday.keys()): + if exclude_leaves and day.strftime('%Y-%m-%d') in dt_leaves: + # XXX: futher improve leave management to allow for partial day leave + continue + for (range_from, range_to) in hours_range_per_weekday.get(day.weekday(), []): + range_from_hour, range_from_min = float_time_convert(range_from) + range_to_hour, range_to_min = float_time_convert(range_to) + daytime_start = local_tz.localize(day.replace(hour=range_from_hour, minute=range_from_min, second=0, tzinfo=None)) + daytime_end = local_tz.localize(day.replace(hour=range_to_hour, minute=range_to_min, second=0, tzinfo=None)) + + # case 1 & 5: time range out of interval + if daytime_end < interval_start or daytime_start > interval_end: + continue + # case 2 & 4: adjust start, end to fit within interval + daytime_start = max(daytime_start, interval_start) + daytime_end = min(daytime_end, interval_end) + + # case 2+, 4+, 3 + hours_timedelta += (daytime_end - daytime_start) + + # return timedelta converted to hours + return (hours_timedelta.days * 24.0 + hours_timedelta.seconds / 3600.0) -resource_calendar() class resource_calendar_attendance(osv.osv): _name = "resource.calendar.attendance" @@ -272,7 +337,6 @@ class resource_calendar_attendance(osv.osv): _defaults = { 'dayofweek' : '0' } -resource_calendar_attendance() def hours_time_string(hours): """ convert a number of hours (float) into a string with format '%H:%M' """ @@ -410,7 +474,6 @@ class resource_resource(osv.osv): wktime_cal.append((non_working[:-1], time_range)) return wktime_cal -resource_resource() class resource_calendar_leaves(osv.osv): _name = "resource.calendar.leaves" @@ -443,6 +506,5 @@ class resource_calendar_leaves(osv.osv): return {'value': result} return {'value': {'calendar_id': []}} -resource_calendar_leaves() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/resource/test/resource.yml b/addons/resource/test/resource.yml index 5b7fa108101..28604518b7b 100644 --- a/addons/resource/test/resource.yml +++ b/addons/resource/test/resource.yml @@ -40,12 +40,13 @@ I check Actual working hours on resource 'Developer' from this week - !python {model: resource.calendar}: | - from datetime import datetime, timedelta + from datetime import datetime + from dateutil.relativedelta import relativedelta now = datetime.now() - dt_from = now - timedelta(days=now.weekday()) - dt_to = dt_from+ timedelta(days=6) + dt_from = now - relativedelta(days=now.weekday(), hour=8, minute=30) + dt_to = dt_from + relativedelta(days=6, hour=17) hours = self.interval_hours_get(cr, uid, ref('timesheet_group1'), dt_from, dt_to, resource=ref('resource_developer')) - assert hours > 27 , 'Invalid Total Week working hour calculated' + assert hours > 27 , 'Invalid Total Week working hour calculated, got %r, expected > 27' % hours - Project Analysis work is of 20 hours which will start from Week start so i will calculate working schedule for resource Analyst for the same. - diff --git a/addons/sale/html/Gunther-Rombouts.png b/addons/sale/html/Gunther-Rombouts.png new file mode 100644 index 00000000000..094eb7c764d Binary files /dev/null and b/addons/sale/html/Gunther-Rombouts.png differ diff --git a/addons/sale/html/Philippe-Leruth.png b/addons/sale/html/Philippe-Leruth.png new file mode 100644 index 00000000000..ee024149207 Binary files /dev/null and b/addons/sale/html/Philippe-Leruth.png differ diff --git a/addons/sale/html/index.html b/addons/sale/html/index.html new file mode 100644 index 00000000000..fa3ece43703 --- /dev/null +++ b/addons/sale/html/index.html @@ -0,0 +1,295 @@ +
+
+

Sales Management Made Easy

+

From quotes to invoices, in just a few clicks

+
+
+ + + +   + +
+
+
+

+Drive your sales operations from quotes to invoices with all the information +you need, easily accessible. Keep track of long term contracts, automate invoicing +and notify sales when they have things to do. +

+ +
+
+
+ +
+
+

Create Professional Quotations

+
+

+Create quotations in a matter of seconds. Send quotes by email or get a +professional PDF. Track quotations, and convert them to sales order in one click. +

+

+Spend the extra time focusing on selling, not recording data. +

+
+
+
+ +
+
+
+
+ +
+
+

Fully Integrated

+

The information your need, where you need it

+
+
+ +
+
+
+

+ Don't lose time looking for customers, products or contracts + related information; they are all conveniently accessible when + creating quotations. +

+ Get access to stock availabilities in the different warehouses, + to customer's specific prices, to the history of preceeding + offers for this prospect, etc. +

+
+
+
+ +
+
+ +
+ Download our free E-book +
+ +
+
+

Your Address Book

+

So many features, so easy to use

+
+

+Load customer data from LinkedIn, assign tags to your prospects, manage +relationships between contacts and store all customer's preferences including +pricing, billing conditions, addresses, payment terms, etc. +

+

+Navigate through all the documents related to a customer with the powerfull +breadcrumb: quotations, invoices, emails, meetings. +

+
+
+
+ +
+
+
+
+ +
+

Fully Integrated Invoicing

+

All the invoicing methods you need

+
+
+
+ +
+
+
+

+ Whether you invoice based on time and materials, on delivery + orders or fixed price; OpenERP supports all possible methods. +

+

+ Get recurring invoices produced automatically, create advances + in just a few clicks, re-invoices expenses easily, etc. +

+
+
+
+ +
+
+

Keep track of your contracts

+
+

+Get rid of wasted paper and record all your contracts in the application. Invoices +are generated automatically based on your contract conditions. Your account +managers get alerts before contracts have to be renewed. +

+
+
+
+ +
+
+ +
+
+ +
+
+

Communicate Efficiently With Customers

+
+
+ +
+
+
+

+The chatter feature enables you to communicate faster and more efficiently with +your customer. This takes place directly on a quotation or sale order from +within OpenERP or via email. +

+

+Get all the negotiations and discussions attached to the right document +and relevent managers notified on specific events. +

+
+
+
+ +
+
+

Fully Extensible

+

Activate features on demand

+
+

+By default, sales order are very simple, limited to a small number of features. +Don't be confused by features you don't need. +

+

+But you can activate options to fit your specific need: multi-warehouses, multi +unit of measures, manage customer specific prices with pricelists, control +margins on quotations, use different addresses for shipping and billing, etc. +

+
+
+
+ +
+
+
+
+ +
+
+

Built-in Customer Relationship Management

+
+
+ +
+
+
+

+Activate the CRM application to manage your funnel of opportunities, attract +leads, log calls, schedule meetings and launch marketing campaigns. +

+

+ Opportunities can be converted into quotations in just one click. +

+
+
+
+ +
+
+

Drive Engagement with Gamification

+

Align Sales On Clear Targets

+
+

+Define clear targets and commission plans. Get real time statistics on the +performance of individual sales or teams. Motivate your teams with challenges, +rewards and leaderboards. +

+
+
+
+ +
+
+
+
+ +
+
+

Have Clear Pricing Strategies

+
+
+ +
+
+
+

+Use pricelists to record special conditions for a specific customer or to +define prices for a segment of customers. Define promotions and have them +applied automatically for all your sales teams. +

+
+
+
+ +
+
+

Reporting and Dashboards

+

Get access to the right information to make smart decisions

+
+

+Get the insights you need to make smarter decisions. Design custom dashboards +to get a picture of your business at a glance. Dig deeper with real-time +reports that anyone can create and share. +

+
+
+
+ +
+
+
+
+ +
+
+
+

Many companies already enjoy it

+

Hear what they have to say !

+
+
+
+ + OpenERP proved to be an effective tool to sustain our operations + for the bright future. It's stable, robust and easy. + + + +
Philippe Leruth
+
Director of Singer France
+
+
+
+
+
+ + OpenERP is a great tool to drive sales. We manage our prospects in different stages + to get a proper overview of our success rate. + + + +
Ir Ing Gunther Rombouts
+
Indutrial Automation Specialist at HeW automation.
+
+
+
+
+
diff --git a/addons/sale/html/sale_invoice.png b/addons/sale/html/sale_invoice.png new file mode 100644 index 00000000000..396276e5f7a Binary files /dev/null and b/addons/sale/html/sale_invoice.png differ diff --git a/addons/sale/html/sale_sc_00.png b/addons/sale/html/sale_sc_00.png new file mode 100644 index 00000000000..8f1ff1e95fe Binary files /dev/null and b/addons/sale/html/sale_sc_00.png differ diff --git a/addons/sale/html/sale_sc_01.png b/addons/sale/html/sale_sc_01.png new file mode 100644 index 00000000000..ba068ab11c1 Binary files /dev/null and b/addons/sale/html/sale_sc_01.png differ diff --git a/addons/sale/html/sale_sc_02.png b/addons/sale/html/sale_sc_02.png new file mode 100644 index 00000000000..4e89d43c4c3 Binary files /dev/null and b/addons/sale/html/sale_sc_02.png differ diff --git a/addons/sale/html/sale_sc_03.png b/addons/sale/html/sale_sc_03.png new file mode 100644 index 00000000000..42abf28506c Binary files /dev/null and b/addons/sale/html/sale_sc_03.png differ diff --git a/addons/sale/html/sale_sc_04.png b/addons/sale/html/sale_sc_04.png new file mode 100644 index 00000000000..458c8280c26 Binary files /dev/null and b/addons/sale/html/sale_sc_04.png differ diff --git a/addons/sale/html/sale_sc_05.png b/addons/sale/html/sale_sc_05.png new file mode 100644 index 00000000000..ef41138976e Binary files /dev/null and b/addons/sale/html/sale_sc_05.png differ diff --git a/addons/sale/html/sale_sc_06.png b/addons/sale/html/sale_sc_06.png new file mode 100644 index 00000000000..483e5eec09b Binary files /dev/null and b/addons/sale/html/sale_sc_06.png differ diff --git a/addons/sale/html/sale_sc_07.png b/addons/sale/html/sale_sc_07.png new file mode 100644 index 00000000000..73fcfb3b083 Binary files /dev/null and b/addons/sale/html/sale_sc_07.png differ diff --git a/addons/sale/html/sale_sc_08.png b/addons/sale/html/sale_sc_08.png new file mode 100644 index 00000000000..e20c44836ba Binary files /dev/null and b/addons/sale/html/sale_sc_08.png differ diff --git a/addons/sale/html/sale_sc_10.png b/addons/sale/html/sale_sc_10.png new file mode 100644 index 00000000000..b71ce805250 Binary files /dev/null and b/addons/sale/html/sale_sc_10.png differ diff --git a/addons/sale/html/sales_illu_01.png b/addons/sale/html/sales_illu_01.png new file mode 100644 index 00000000000..66e680bc42e Binary files /dev/null and b/addons/sale/html/sales_illu_01.png differ diff --git a/addons/sale/html/sales_target.png b/addons/sale/html/sales_target.png new file mode 100644 index 00000000000..41042ce49ea Binary files /dev/null and b/addons/sale/html/sales_target.png differ diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py index 070e9c4336f..80143379247 100644 --- a/addons/sale/report/sale_report.py +++ b/addons/sale/report/sale_report.py @@ -110,6 +110,5 @@ class sale_report(osv.osv): s.project_id ) """) -sale_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py index 3fb8e049e8d..bfbaa5f0a6f 100644 --- a/addons/sale/res_config.py +++ b/addons/sale/res_config.py @@ -22,7 +22,6 @@ import logging from openerp.osv import fields, osv -from openerp import pooler from openerp.tools.translate import _ _logger = logging.getLogger(__name__) @@ -59,7 +58,7 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""), implied_group='product.group_product_variant', help="""Allow to manage several variants per product. As an example, if you sell T-Shirts, for the same "Linux T-Shirt", you may have variants on sizes or colors; S, M, L, XL, XXL."""), 'module_warning': fields.boolean("Allow configuring alerts by customer or products", - help="""Allow to configure notification on products and trigger them when a user wants to sale a given product or a given customer. + help="""Allow to configure notification on products and trigger them when a user wants to sell a given product or a given customer. Example: Product: this product is deprecated, do not purchase more than 5. Supplier: don't forget to ask for an express delivery."""), 'module_sale_margin': fields.boolean("Display margins on sales orders", @@ -144,6 +143,8 @@ class account_config_settings(osv.osv_memory): def onchange_sale_analytic_plans(self, cr, uid, ids, module_sale_analytic_plans, context=None): """ change group_analytic_account_for_sales following module_sale_analytic_plans """ + if not module_sale_analytic_plans: + return {} return {'value': {'group_analytic_account_for_sales': module_sale_analytic_plans}} # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/res_partner_view.xml b/addons/sale/res_partner_view.xml index 54a9813eea9..5107f0c17af 100644 --- a/addons/sale/res_partner_view.xml +++ b/addons/sale/res_partner_view.xml @@ -63,14 +63,22 @@ sale.group_delivery_invoice_address - - False False + sale.group_delivery_invoice_address - + + + False + sale.group_delivery_invoice_address + + + False sale.group_delivery_invoice_address diff --git a/addons/sale/sale.py b/addons/sale/sale.py index bf9e9484b9f..210e4dd3be6 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -22,7 +22,6 @@ from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta import time -from openerp import pooler from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare @@ -43,7 +42,6 @@ class sale_shop(osv.osv): 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'sale.shop', context=c), } -sale_shop() class sale_order(osv.osv): _name = "sale.order" @@ -212,8 +210,7 @@ class sale_order(osv.osv): 'order_policy': fields.selection([ ('manual', 'On Demand'), ], 'Create Invoice', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, - help="""This field controls how invoice and delivery operations are synchronized. - - With 'Before Delivery', a draft invoice is created, and it must be paid before delivery."""), + help="""This field controls how invoice and delivery operations are synchronized."""), 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="Pricelist for current sales order."), 'currency_id': fields.related('pricelist_id', 'currency_id', type="many2one", relation="res.currency", string="Currency", readonly=True, required=True), 'project_id': fields.many2one('account.analytic.account', 'Contract / Analytic', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="The analytic account related to a sales order."), @@ -323,10 +320,6 @@ class sale_order(osv.osv): return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, 'payment_term': False, 'fiscal_position': False}} part = self.pool.get('res.partner').browse(cr, uid, part, context=context) - #if the chosen partner is not a company and has a parent company, use the parent to choose the delivery, the - #invoicing addresses and all the fields related to the partner. - if part.parent_id and not part.is_company: - part = part.parent_id addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact']) pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False payment_term = part.property_payment_term and part.property_payment_term.id or False @@ -544,6 +537,9 @@ class sale_order(osv.osv): invoice_ref += o.name + '|' self.write(cr, uid, [o.id], {'state': 'progress'}) cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (o.id, res)) + #remove last '|' in invoice_ref + if len(invoice_ref) >= 1: + invoice_ref = invoice_ref[:-1] invoice.write(cr, uid, [res], {'origin': invoice_ref, 'name': invoice_ref}) else: for order, il in val: @@ -1024,4 +1020,16 @@ class account_invoice(osv.Model): sale_order_obj.message_post(cr, uid, so_ids, body=_("Invoice paid"), context=context) return res + def unlink(self, cr, uid, ids, context=None): + """ Overwrite unlink method of account invoice to send a trigger to the sale workflow upon invoice deletion """ + invoice_ids = self.search(cr, uid, [('id', 'in', ids), ('state', 'in', ['draft', 'cancel'])], context=context) + #if we can't cancel all invoices, do nothing + if len(invoice_ids) == len(ids): + #Cancel invoice(s) first before deleting them so that if any sale order is associated with them + #it will trigger the workflow to put the sale order in an 'invoice exception' state + wf_service = netsvc.LocalService("workflow") + for id in ids: + wf_service.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr) + return super(account_invoice, self).unlink(cr, uid, ids, context=context) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index e3a393666b4..e24a6e45fe0 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -156,7 +156,7 @@ - + @@ -308,7 +308,7 @@ - + @@ -328,19 +328,23 @@ form tree,form,calendar,graph - {'show_address': 1} - [('state','not in',('draft','sent','cancel'))] + { + 'search_default_my_sale_orders_filter': 1 + } + + [('state', 'not in', ('draft', 'sent', 'cancel'))] -

- Click to create a quotation that can be converted into a sales - order. -

- OpenERP will help you efficiently handle the complete sales flow: - quotation, sales order, delivery, invoicing and payment. -

+

+ Click to create a quotation that can be converted into a sales + order. +

+ OpenERP will help you efficiently handle the complete sales flow: + quotation, sales order, delivery, invoicing and payment. +

- + + Sales in Exception @@ -371,7 +375,7 @@ form tree,form,calendar,graph - {'show_address': 1} + {'search_default_my_sale_orders_filter': 1} [('state','in',('draft','sent','cancel'))] @@ -390,8 +394,8 @@ + action="action_quotations" parent="base.menu_sales" + sequence="5"/> Old Quotations @@ -472,7 +476,7 @@ - + @@ -498,7 +502,7 @@ - + diff --git a/addons/sale/wizard/sale_line_invoice.py b/addons/sale/wizard/sale_line_invoice.py index bed474728d7..3b04319f5c7 100644 --- a/addons/sale/wizard/sale_line_invoice.py +++ b/addons/sale/wizard/sale_line_invoice.py @@ -26,6 +26,7 @@ from openerp import netsvc class sale_order_line_make_invoice(osv.osv_memory): _name = "sale.order.line.make.invoice" _description = "Sale OrderLine Make_invoice" + def make_invoices(self, cr, uid, ids, context=None): """ To make invoices. @@ -80,36 +81,33 @@ class sale_order_line_make_invoice(osv.osv_memory): sales_order_line_obj = self.pool.get('sale.order.line') sales_order_obj = self.pool.get('sale.order') + wf_service = netsvc.LocalService('workflow') for line in sales_order_line_obj.browse(cr, uid, context.get('active_ids', []), context=context): if (not line.invoiced) and (line.state not in ('draft', 'cancel')): - if not line.order_id.id in invoices: - invoices[line.order_id.id] = [] - line_id = sales_order_line_obj.invoice_line_create(cr, uid, - [line.id]) + if not line.order_id in invoices: + invoices[line.order_id] = [] + line_id = sales_order_line_obj.invoice_line_create(cr, uid, [line.id]) for lid in line_id: - invoices[line.order_id.id].append((line, lid)) - for result in invoices.values(): - order = result[0][0].order_id - il = map(lambda x: x[1], result) + invoices[line.order_id].append(lid) + for order, il in invoices.items(): res = make_invoice(order, il) cr.execute('INSERT INTO sale_order_invoice_rel \ (order_id,invoice_id) values (%s,%s)', (order.id, res)) - flag = True - data_sale = sales_order_obj.browse(cr, uid, line.order_id.id, context=context) sales_order_obj.message_post(cr, uid, [order.id], body=_("Invoice created"), context=context) + data_sale = sales_order_obj.browse(cr, uid, order.id, context=context) for line in data_sale.order_line: if not line.invoiced: flag = False break if flag: - sales_order_obj.signal_manual_invoice(cr, uid, [line.order_id.id]) - sales_order_obj.write(cr, uid, [line.order_id.id], {'state': 'progress'}) + wf_service.trg_validate(uid, 'sale.order', order.id, 'manual_invoice', cr) + sales_order_obj.write(cr, uid, [order.id], {'state': 'progress'}) if not invoices: raise osv.except_osv(_('Warning!'), _('Invoice cannot be created for this Sales Order Line due to one of the following reasons:\n1.The state of this sales order line is either "draft" or "cancel"!\n2.The Sales Order Line is Invoiced!')) if context.get('open_invoices', False): - return self.open_invoices( cr, uid, ids, res, context=context) + return self.open_invoices(cr, uid, ids, res, context=context) return {'type': 'ir.actions.act_window_close'} def open_invoices(self, cr, uid, ids, invoice_ids, context=None): @@ -119,7 +117,7 @@ class sale_order_line_make_invoice(osv.osv_memory): form_id = form_res and form_res[1] or False tree_res = ir_model_data.get_object_reference(cr, uid, 'account', 'invoice_tree') tree_id = tree_res and tree_res[1] or False - + return { 'name': _('Invoice'), 'view_type': 'form', @@ -132,6 +130,5 @@ class sale_order_line_make_invoice(osv.osv_memory): 'type': 'ir.actions.act_window', } -sale_order_line_make_invoice() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/wizard/sale_make_invoice.py b/addons/sale/wizard/sale_make_invoice.py index 1b885998f83..3712feda20b 100644 --- a/addons/sale/wizard/sale_make_invoice.py +++ b/addons/sale/wizard/sale_make_invoice.py @@ -20,7 +20,6 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ -from openerp import netsvc class sale_make_invoice(osv.osv_memory): _name = "sale.make.invoice" @@ -40,7 +39,7 @@ class sale_make_invoice(osv.osv_memory): record_id = context and context.get('active_id', False) order = self.pool.get('sale.order').browse(cr, uid, record_id, context=context) if order.state == 'draft': - raise osv.except_osv(_('Warning!'),'You cannot create invoice when sales order is not confirmed.') + raise osv.except_osv(_('Warning!'), _('You cannot create invoice when sales order is not confirmed.')) return False def make_invoices(self, cr, uid, ids, context=None): @@ -51,8 +50,11 @@ class sale_make_invoice(osv.osv_memory): if context is None: context = {} data = self.read(cr, uid, ids)[0] - order_obj.action_invoice_create(cr, uid, context.get(('active_ids'), []), data['grouped'], date_invoice = data['invoice_date']) - order_obj.signal_manual_invoice(cr, uid, context.get(('active_ids'), [])) + for sale_order in order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context): + if sale_order.state != 'manual': + raise osv.except_osv(_('Warning!'), _("You shouldn't manually invoice the following sale order %s") % (sale_order.name)) + + order_obj.action_invoice_create(cr, uid, context.get(('active_ids'), []), data['grouped'], date_invoice=data['invoice_date']) for o in order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context): for i in o.invoice_ids: @@ -61,10 +63,9 @@ class sale_make_invoice(osv.osv_memory): result = mod_obj.get_object_reference(cr, uid, 'account', 'action_invoice_tree1') id = result and result[1] or False result = act_obj.read(cr, uid, [id], context=context)[0] - result['domain'] = "[('id','in', ["+','.join(map(str,newinv))+"])]" + result['domain'] = "[('id','in', [" + ','.join(map(str, newinv)) + "])]" return result -sale_make_invoice() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/wizard/sale_make_invoice.xml b/addons/sale/wizard/sale_make_invoice.xml index ced64a0f79d..de680feb049 100644 --- a/addons/sale/wizard/sale_make_invoice.xml +++ b/addons/sale/wizard/sale_make_invoice.xml @@ -6,16 +6,16 @@ sale.make.invoice
-
-
+
+
diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index 5d3cc165b46..4cb00245ade 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -210,6 +210,5 @@ class sale_advance_payment_inv(osv.osv_memory): 'type': 'ir.actions.act_window', } -sale_advance_payment_inv() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_analytic_plans/sale_analytic_plans.py b/addons/sale_analytic_plans/sale_analytic_plans.py index 2abbab7ab38..522f6b6f0fb 100644 --- a/addons/sale_analytic_plans/sale_analytic_plans.py +++ b/addons/sale_analytic_plans/sale_analytic_plans.py @@ -37,7 +37,6 @@ class sale_order_line(osv.osv): i = i + 1 return create_ids -sale_order_line() class sale_order(osv.osv): _inherit = "sale.order" diff --git a/addons/sale_analytic_plans/sale_analytic_plans_view.xml b/addons/sale_analytic_plans/sale_analytic_plans_view.xml index 6c788866520..121efbdf12e 100644 --- a/addons/sale_analytic_plans/sale_analytic_plans_view.xml +++ b/addons/sale_analytic_plans/sale_analytic_plans_view.xml @@ -38,5 +38,31 @@
+ + + + + account.invoice.line.form.inherit + account.invoice.line + + + + + + + + + + account.invoice.form.analytic.inherit + account.invoice + + + + + + + + + diff --git a/addons/sale_crm/report/sale_crm_account_invoice_report_view.xml b/addons/sale_crm/report/sale_crm_account_invoice_report_view.xml index 41166d56713..983701d9690 100644 --- a/addons/sale_crm/report/sale_crm_account_invoice_report_view.xml +++ b/addons/sale_crm/report/sale_crm_account_invoice_report_view.xml @@ -10,7 +10,7 @@ - + diff --git a/addons/sale_crm/sale_crm.py b/addons/sale_crm/sale_crm.py index 1f3f85d5ed1..3172999c545 100644 --- a/addons/sale_crm/sale_crm.py +++ b/addons/sale_crm/sale_crm.py @@ -19,8 +19,10 @@ # ############################################################################## +from datetime import datetime from openerp.osv import osv, fields + class sale_order(osv.osv): _inherit = 'sale.order' _columns = { @@ -29,6 +31,41 @@ class sale_order(osv.osv): domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]") } + def _prepare_invoice(self, cr, uid, order, lines, context=None): + invoice_vals = super(sale_order, self)._prepare_invoice(cr, uid, order, lines, context=context) + if order.section_id and order.section_id.id: + invoice_vals['section_id'] = order.section_id.id + return invoice_vals + + +class crm_case_section(osv.osv): + _inherit = 'crm.case.section' + + def _get_sum_month_invoice(self, cr, uid, ids, field_name, arg, context=None): + res = dict.fromkeys(ids, 0) + obj = self.pool.get('account.invoice.report') + when = datetime.today() + for section_id in ids: + invoice_ids = obj.search(cr, uid, [("section_id", "=", section_id), ('state', 'not in', ['draft', 'cancel']), ('year', '=', when.year), ('month', '=', when.month > 9 and when.month or "0%s" % when.month)], context=context) + for invoice in obj.browse(cr, uid, invoice_ids, context=context): + res[section_id] += invoice.price_total + return res + + _columns = { + 'quotation_ids': fields.one2many('sale.order', 'section_id', + string='Quotations', readonly=True, + domain=[('state', 'in', ['draft', 'sent', 'cancel'])]), + 'sale_order_ids': fields.one2many('sale.order', 'section_id', + string='Sale Orders', readonly=True, + domain=[('state', 'not in', ['draft', 'sent', 'cancel'])]), + 'invoice_ids': fields.one2many('account.invoice', 'section_id', + string='Invoices', readonly=True, + domain=[('state', 'not in', ['draft', 'cancel'])]), + 'sum_month_invoice': fields.function(_get_sum_month_invoice, + string='Total invoiced this month', + type='integer', readonly=True), + } + class res_users(osv.Model): _inherit = 'res.users' @@ -36,13 +73,29 @@ class res_users(osv.Model): 'default_section_id': fields.many2one('crm.case.section', 'Default Sales Team'), } + +class sale_crm_lead(osv.Model): + _inherit = 'crm.lead' + + def on_change_user(self, cr, uid, ids, user_id, context=None): + """ Override of on change user_id on lead/opportunity; when having sale + the new logic is : + - use user.default_section_id + - or fallback on previous behavior """ + if user_id: + user = self.pool.get('res.users').browse(cr, uid, user_id, context=context) + if user.default_section_id and user.default_section_id.id: + return {'value': {'section_id': user.default_section_id.id}} + return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context) + + class account_invoice(osv.osv): _inherit = 'account.invoice' _columns = { 'section_id': fields.many2one('crm.case.section', 'Sales Team'), } _defaults = { - 'section_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False, + 'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False, } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml index 0b5fce2f5cd..31c0317969a 100644 --- a/addons/sale_crm/sale_crm_view.xml +++ b/addons/sale_crm/sale_crm_view.xml @@ -16,13 +16,18 @@
+ + + {'stage_type': 'opportunity', 'default_type': 'opportunity', 'default_user_id': uid, 'needaction_menu_ref': 'sale.menu_sale_quotations'} + + sale.order.inherit sale.order - + @@ -41,7 +46,7 @@ help="My Sales Team(s)"/> - + @@ -53,18 +58,22 @@ - - + + + account.invoice.groupby account.invoice + + + @@ -79,7 +88,7 @@ - + @@ -106,12 +115,139 @@ - + + + + + Sales Orders + ir.actions.act_window + sale.order + form + tree,form,calendar,graph + + [('state','not in',('draft','sent','cancel'))] + { + 'search_default_section_id': [active_id], + 'default_section_id': active_id, + 'search_default_my_sale_orders_filter': 1, + } + + +

+ Click to create a quotation that can be converted into a sales + order. +

+ OpenERP will help you efficiently handle the complete sales flow: + quotation, sales order, delivery, invoicing and payment. +

+
+
+ + + Quotations + ir.actions.act_window + sale.order + form + + tree,form,calendar,graph + { + 'search_default_section_id': [active_id], + 'default_section_id': active_id, 'show_address': 1, + 'search_default_my_sale_orders_filter': 1 + } + + [('state','in',('draft','sent','cancel'))] + + +

+ Click to create a quotation, the first step of a new sale. +

+ OpenERP will help you handle efficiently the complete sale flow: + from the quotation to the sales order, the + delivery, the invoicing and the payment collection. +

+ The social feature helps you organize discussions on each sales + order, and allow your customers to keep track of the evolution + of the sales order. +

+
+
+ + + Invoices + account.invoice + form + tree,form,calendar,graph + + [ + ('state', 'not in', ['draft', 'cancel']), + ('type', '=', 'out_invoice')] + { + 'search_default_section_id': [active_id], + 'default_section_id': active_id}, + 'default_type':'out_invoice', + 'type':'out_invoice', + 'journal_type': 'sale', + } + + + + + + 1 + tree + + + + + 2 + form + + + + + + crm.case.section.kanban + crm.case.section + + + + + + + + + + + + Quotations + Quotation + + + + Sales Orders + Sales Order + + + + Invoices + Invoice + + + +
+
+
Invoiced this month
+
+
+
+
+
diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py index a052f47ca1f..6bea6286456 100644 --- a/addons/sale_crm/wizard/crm_make_sale.py +++ b/addons/sale_crm/wizard/crm_make_sale.py @@ -153,6 +153,5 @@ class crm_make_sale(osv.osv_memory): 'partner_id': _selectPartner, } -crm_make_sale() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_journal/sale_journal.py b/addons/sale_journal/sale_journal.py index 8463ab3f3bd..9e10c826898 100644 --- a/addons/sale_journal/sale_journal.py +++ b/addons/sale_journal/sale_journal.py @@ -34,7 +34,6 @@ class sale_journal_invoice_type(osv.osv): 'active': True, 'invoicing_method': 'simple' } -sale_journal_invoice_type() #============================================== # sale journal inherit @@ -52,28 +51,28 @@ class res_partner(osv.osv): group_name = "Accounting Properties", help = "This invoicing type will be used, by default, to invoice the current partner."), } -res_partner() + + def _commercial_fields(self, cr, uid, context=None): + return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_invoice_type'] + class picking(osv.osv): _inherit = "stock.picking" _columns = { 'invoice_type_id': fields.many2one('sale_journal.invoice.type', 'Invoice Type', readonly=True) } -picking() class stock_picking_in(osv.osv): _inherit = "stock.picking.in" _columns = { 'invoice_type_id': fields.many2one('sale_journal.invoice.type', 'Invoice Type', readonly=True) } -stock_picking_in() class stock_picking_out(osv.osv): _inherit = "stock.picking.out" _columns = { 'invoice_type_id': fields.many2one('sale_journal.invoice.type', 'Invoice Type', readonly=True) } -stock_picking_out() class sale(osv.osv): @@ -95,6 +94,5 @@ class sale(osv.osv): result['value']['invoice_type_id'] = itype.id return result -sale() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_journal/sale_journal_view.xml b/addons/sale_journal/sale_journal_view.xml index bcd83b5be84..9d41103252e 100644 --- a/addons/sale_journal/sale_journal_view.xml +++ b/addons/sale_journal/sale_journal_view.xml @@ -146,7 +146,7 @@ - + diff --git a/addons/sale_margin/i18n/cs.po b/addons/sale_margin/i18n/cs.po new file mode 100644 index 00000000000..dd01e0973bc --- /dev/null +++ b/addons/sale_margin/i18n/cs.po @@ -0,0 +1,46 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-30 12:41+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-31 05:27+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: sale_margin +#: field:sale.order.line,purchase_price:0 +msgid "Cost Price" +msgstr "" + +#. module: sale_margin +#: model:ir.model,name:sale_margin.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_margin +#: field:sale.order,margin:0 +#: field:sale.order.line,margin:0 +msgid "Margin" +msgstr "" + +#. module: sale_margin +#: model:ir.model,name:sale_margin.model_sale_order_line +msgid "Sales Order Line" +msgstr "" + +#. module: sale_margin +#: help:sale.order,margin:0 +msgid "" +"It gives profitability by calculating the difference between the Unit Price " +"and the cost price." +msgstr "" diff --git a/addons/sale_margin/sale_margin.py b/addons/sale_margin/sale_margin.py index dc8c4dfff3c..4c2e9ffc4f4 100644 --- a/addons/sale_margin/sale_margin.py +++ b/addons/sale_margin/sale_margin.py @@ -56,7 +56,6 @@ class sale_order_line(osv.osv): 'purchase_price': fields.float('Cost Price', digits=(16,2)) } -sale_order_line() class sale_order(osv.osv): _inherit = "sale.order" @@ -82,6 +81,5 @@ class sale_order(osv.osv): }), } -sale_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/sale_mrp/i18n/cs.po b/addons/sale_mrp/i18n/cs.po new file mode 100644 index 00000000000..78ae9292dbd --- /dev/null +++ b/addons/sale_mrp/i18n/cs.po @@ -0,0 +1,43 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-30 12:41+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-31 05:27+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: sale_mrp +#: model:ir.model,name:sale_mrp.model_mrp_production +msgid "Manufacturing Order" +msgstr "" + +#. module: sale_mrp +#: help:mrp.production,sale_name:0 +msgid "Indicate the name of sales order." +msgstr "" + +#. module: sale_mrp +#: help:mrp.production,sale_ref:0 +msgid "Indicate the Customer Reference from sales order." +msgstr "" + +#. module: sale_mrp +#: field:mrp.production,sale_ref:0 +msgid "Sale Reference" +msgstr "" + +#. module: sale_mrp +#: field:mrp.production,sale_name:0 +msgid "Sale Name" +msgstr "" diff --git a/addons/sale_mrp/i18n/lt.po b/addons/sale_mrp/i18n/lt.po new file mode 100644 index 00000000000..185753c3663 --- /dev/null +++ b/addons/sale_mrp/i18n/lt.po @@ -0,0 +1,43 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-04-29 15:30+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: sale_mrp +#: model:ir.model,name:sale_mrp.model_mrp_production +msgid "Manufacturing Order" +msgstr "" + +#. module: sale_mrp +#: help:mrp.production,sale_name:0 +msgid "Indicate the name of sales order." +msgstr "" + +#. module: sale_mrp +#: help:mrp.production,sale_ref:0 +msgid "Indicate the Customer Reference from sales order." +msgstr "" + +#. module: sale_mrp +#: field:mrp.production,sale_ref:0 +msgid "Sale Reference" +msgstr "" + +#. module: sale_mrp +#: field:mrp.production,sale_name:0 +msgid "Sale Name" +msgstr "" diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py index a5043d3b7d5..77a35972638 100644 --- a/addons/sale_mrp/sale_mrp.py +++ b/addons/sale_mrp/sale_mrp.py @@ -74,6 +74,5 @@ class mrp_production(osv.osv): 'sale_ref': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Reference', help='Indicate the Customer Reference from sales order.'), } -mrp_production() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_order_dates/i18n/cs.po b/addons/sale_order_dates/i18n/cs.po new file mode 100644 index 00000000000..a1583d48efe --- /dev/null +++ b/addons/sale_order_dates/i18n/cs.po @@ -0,0 +1,58 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-30 12:41+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-31 05:27+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: sale_order_dates +#: view:sale.order:0 +msgid "Dates" +msgstr "" + +#. module: sale_order_dates +#: field:sale.order,commitment_date:0 +msgid "Commitment Date" +msgstr "" + +#. module: sale_order_dates +#: field:sale.order,effective_date:0 +msgid "Effective Date" +msgstr "" + +#. module: sale_order_dates +#: help:sale.order,effective_date:0 +msgid "Date on which picking is created." +msgstr "" + +#. module: sale_order_dates +#: help:sale.order,requested_date:0 +msgid "Date requested by the customer for the sale." +msgstr "" + +#. module: sale_order_dates +#: field:sale.order,requested_date:0 +msgid "Requested Date" +msgstr "" + +#. module: sale_order_dates +#: model:ir.model,name:sale_order_dates.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_order_dates +#: help:sale.order,commitment_date:0 +msgid "Committed date for delivery." +msgstr "" diff --git a/addons/sale_order_dates/sale_order_dates.py b/addons/sale_order_dates/sale_order_dates.py index d54eca88ca5..64b939de088 100644 --- a/addons/sale_order_dates/sale_order_dates.py +++ b/addons/sale_order_dates/sale_order_dates.py @@ -59,6 +59,5 @@ class sale_order_dates(osv.osv): 'effective_date': fields.function(_get_effective_date, type='date', store=True, string='Effective Date',help="Date on which picking is created."), } -sale_order_dates() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_stock/company.py b/addons/sale_stock/company.py index 67440ed6c67..5be1dbd524d 100644 --- a/addons/sale_stock/company.py +++ b/addons/sale_stock/company.py @@ -24,13 +24,15 @@ from openerp.osv import fields, osv class company(osv.osv): _inherit = 'res.company' _columns = { - 'security_lead': fields.float('Security Days', required=True, - help="This is the days added to what you promise to customers "\ - "for security purpose"), + 'security_lead': fields.float( + 'Security Days', required=True, + help="Margin of error for dates promised to customers. "\ + "Products will be scheduled for procurement and delivery "\ + "that many days earlier than the actual promised date, to "\ + "cope with unexpected delays in the supply chain."), } _defaults = { 'security_lead': 0.0, } -company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_stock/process/sale_stock_process.xml b/addons/sale_stock/process/sale_stock_process.xml index 666f6ba6502..c10b34c8866 100644 --- a/addons/sale_stock/process/sale_stock_process.xml +++ b/addons/sale_stock/process/sale_stock_process.xml @@ -64,17 +64,6 @@ - - - - - - - - - @@ -106,7 +95,7 @@ - + diff --git a/addons/sale_stock/report/sale_report.py b/addons/sale_stock/report/sale_report.py index 1f1e4a625be..63641020d98 100644 --- a/addons/sale_stock/report/sale_report.py +++ b/addons/sale_stock/report/sale_report.py @@ -91,6 +91,5 @@ class sale_report(osv.osv): s.project_id ) """) -sale_report() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale_stock/res_config.py b/addons/sale_stock/res_config.py index 3a6dcb404dd..d06b6a81b32 100644 --- a/addons/sale_stock/res_config.py +++ b/addons/sale_stock/res_config.py @@ -20,7 +20,6 @@ ############################################################################## from openerp.osv import fields, osv -from openerp import pooler from openerp.tools.translate import _ class sale_configuration(osv.osv_memory): diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index bd4eb2b8256..e71fb92f842 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -24,6 +24,8 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FO from dateutil.relativedelta import relativedelta from openerp.osv import fields, osv from openerp.tools.translate import _ +import pytz +from openerp import SUPERUSER_ID class sale_shop(osv.osv): _inherit = "sale.shop" @@ -31,7 +33,6 @@ class sale_shop(osv.osv): 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'), } -sale_shop() class sale_order(osv.osv): _inherit = "sale.order" @@ -229,6 +230,29 @@ class sale_order(osv.osv): res.append(line.procurement_id.id) return res + def date_to_datetime(self, cr, uid, userdate, context=None): + """ Convert date values expressed in user's timezone to + server-side UTC timestamp, assuming a default arbitrary + time of 12:00 AM - because a time is needed. + + :param str userdate: date string in in user time zone + :return: UTC datetime string for server-side use + """ + # TODO: move to fields.datetime in server after 7.0 + user_date = datetime.strptime(userdate, DEFAULT_SERVER_DATE_FORMAT) + if context and context.get('tz'): + tz_name = context['tz'] + else: + tz_name = self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz'] + if tz_name: + utc = pytz.timezone('UTC') + context_tz = pytz.timezone(tz_name) + user_datetime = user_date + relativedelta(hours=12.0) + local_timestamp = context_tz.localize(user_datetime, is_dst=False) + user_datetime = local_timestamp.astimezone(utc) + return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + return user_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT) + # if mode == 'finished': # returns True if all lines are done, False otherwise # if mode == 'canceled': @@ -311,7 +335,7 @@ class sale_order(osv.osv): return { 'name': pick_name, 'origin': order.name, - 'date': order.date_order, + 'date': self.date_to_datetime(cr, uid, order.date_order, context), 'type': 'out', 'state': 'auto', 'move_type': order.picking_policy, @@ -345,7 +369,8 @@ class sale_order(osv.osv): return True def _get_date_planned(self, cr, uid, order, line, start_date, context=None): - date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=line.delay or 0.0) + start_date = self.date_to_datetime(cr, uid, start_date, context) + date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=line.delay or 0.0) date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) return date_planned @@ -605,11 +630,6 @@ class sale_advance_payment_inv(osv.osv_memory): sale_line_obj = self.pool.get('sale.order.line') wizard = self.browse(cr, uid, [result], context) sale = sale_obj.browse(cr, uid, sale_id, context=context) - if sale.order_policy == 'postpaid': - raise osv.except_osv( - _('Error!'), - _("You cannot make an advance on a sales order \ - that is defined as 'Automatic Invoice after delivery'.")) # If invoice on picking: add the cost on the SO # If not, the advance will be deduced when generating the final invoice diff --git a/addons/sale_stock/stock.py b/addons/sale_stock/stock.py index e1070998ae8..ad19684c4cf 100644 --- a/addons/sale_stock/stock.py +++ b/addons/sale_stock/stock.py @@ -54,7 +54,7 @@ class stock_picking(osv.osv): We select the partner of the sales order as the partner of the customer invoice """ if picking.sale_id: - return picking.sale_id.partner_id + return picking.sale_id.partner_invoice_id return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context) def _get_comment_invoice(self, cursor, user, picking): diff --git a/addons/sale_stock/stock_view.xml b/addons/sale_stock/stock_view.xml index d06526902fd..0f5b9c4f1e6 100644 --- a/addons/sale_stock/stock_view.xml +++ b/addons/sale_stock/stock_view.xml @@ -1,16 +1,6 @@ - - stock.picking.form - stock.picking - - - - - - - stock.move.form @@ -51,7 +41,7 @@ Outgoing picking Inherited - stock.picking + stock.picking.out diff --git a/addons/sale_stock/test/picking_order_policy.yml b/addons/sale_stock/test/picking_order_policy.yml index f761dfb65db..afffda1ef21 100644 --- a/addons/sale_stock/test/picking_order_policy.yml +++ b/addons/sale_stock/test/picking_order_policy.yml @@ -5,6 +5,12 @@ - !assert {model: sale.order, id: sale.sale_order_6, string: The amount of the Quotation is not correctly computed}: - sum([l.price_subtotal for l in order_line]) == amount_untaxed +- + I set an explicit invoicing partner that is different from the main SO Customer +- + !python {model: sale.order, id: sale.sale_order_6}: | + order = self.browse(cr, uid, ref("sale.sale_order_6")) + order.write({'partner_invoice_id': ref('base.res_partner_address_29')}) - I confirm the quotation with Invoice based on deliveries policy. - @@ -26,7 +32,8 @@ order = self.browse(cr, uid, ref("sale.sale_order_6")) for order_line in order.order_line: procurement = order_line.procurement_id - date_planned = datetime.strptime(order.date_order, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=order_line.delay or 0.0) + sale_order_date = self.date_to_datetime(cr, uid, order.date_order, context) + date_planned = datetime.strptime(sale_order_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=order_line.delay or 0.0) date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) assert procurement.date_planned == date_planned, "Scheduled date is not correspond." assert procurement.product_id.id == order_line.product_id.id, "Product is not correspond." @@ -60,7 +67,8 @@ output_id = sale_order.shop_id.warehouse_id.lot_output_id.id for move in picking.move_lines: order_line = move.sale_line_id - date_planned = datetime.strptime(sale_order.date_order, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=order_line.delay or 0.0) + sale_order_date = self.date_to_datetime(cr, uid, sale_order.date_order, context) + date_planned = datetime.strptime(sale_order_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=order_line.delay or 0.0) date_planned = (date_planned - timedelta(days=sale_order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) assert datetime.strptime(move.date_expected, DEFAULT_SERVER_DATETIME_FORMAT) == datetime.strptime(date_planned, DEFAULT_SERVER_DATETIME_FORMAT), "Excepted Date is not correspond with Planned Date." assert move.product_id.id == order_line.product_id.id,"Product is not correspond." @@ -108,13 +116,13 @@ !python {model: sale.order}: | order = self.browse(cr, uid, ref("sale.sale_order_6")) assert order.invoice_ids, "Invoice is not created." - ac = order.partner_id.property_account_receivable.id + ac = order.partner_invoice_id.property_account_receivable.id journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'sale'), ('company_id', '=', order.company_id.id)]) for invoice in order.invoice_ids: assert invoice.type == 'out_invoice',"Invoice should be Customer Invoice." assert invoice.account_id.id == ac,"Invoice account is not correspond." assert invoice.reference == order.client_order_ref or order.name,"Reference is not correspond." - assert invoice.partner_id.id == order.partner_id.id,"Customer is not correspond." + assert invoice.partner_id.id == order.partner_invoice_id.id,"Customer does not correspond." assert invoice.currency_id.id == order.pricelist_id.currency_id.id, "Currency is not correspond." assert invoice.comment == (order.note or ''),"Note is not correspond." assert invoice.journal_id.id in journal_ids,"Sales Journal is not link on Invoice." @@ -162,8 +170,9 @@ - !python {model: sale.order}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.sale.order').create(cr, uid, [ref('sale.sale_order_6')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('sale.sale_order_6')], 'sale.order', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'sale-sale_order.'+format), 'wb+').write(data) diff --git a/addons/share/i18n/lt.po b/addons/share/i18n/lt.po new file mode 100644 index 00000000000..497de8b405d --- /dev/null +++ b/addons/share/i18n/lt.po @@ -0,0 +1,617 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-04-29 15:32+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-30 05:29+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:841 +#, python-format +msgid "Invitation to collaborate about %s" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:779 +#, python-format +msgid "" +"The share engine has not been able to fetch a record_id for your invitation." +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Include an Optional Personal Message" +msgstr "" + +#. module: share +#: field:share.wizard,embed_option_title:0 +msgid "Display title" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Access granted!" +msgstr "" + +#. module: share +#: field:share.wizard,record_name:0 +msgid "Record name" +msgstr "" + +#. module: share +#: help:share.wizard,message:0 +msgid "" +"An optional personal message, to be included in the email notification." +msgstr "" + +#. module: share +#: field:share.wizard,user_type:0 +msgid "Sharing method" +msgstr "" + +#. module: share +#: field:share.wizard,name:0 +msgid "Share Title" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:847 +#: code:addons/share/wizard/share_wizard.py:876 +#, python-format +msgid "" +"The documents are not attached, you can view them online directly on my " +"OpenERP server at:\n" +" %s\n" +"\n" +msgstr "" + +#. module: share +#: model:ir.module.category,name:share.module_category_share +msgid "Sharing" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:842 +#: code:addons/share/wizard/share_wizard.py:874 +#, python-format +msgid "" +"Hello,\n" +"\n" +msgstr "" + +#. module: share +#: field:share.wizard,share_root_url:0 +msgid "Share Access URL" +msgstr "" + +#. module: share +#: field:share.wizard,email_1:0 +#: field:share.wizard,email_2:0 +#: field:share.wizard,email_3:0 +msgid "New user email" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:886 +#, python-format +msgid "You may use your current login (%s) and password to view them.\n" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:620 +#, python-format +msgid "(Modified)" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:664 +#, python-format +msgid "You must be a member of the Share/User group to use the share wizard." +msgstr "" + +#. module: share +#. openerp-web +#: code:addons/share/static/src/js/share.js:63 +#, python-format +msgid "Embed" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:598 +#, python-format +msgid "Sharing filter created by user %s (%s) for group %s" +msgstr "" + +#. module: share +#: field:share.wizard,embed_url:0 +#: field:share.wizard.result.line,share_url:0 +msgid "Share URL" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:848 +#: code:addons/share/wizard/share_wizard.py:880 +#, python-format +msgid "These are your credentials to access this protected area:\n" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Access info" +msgstr "" + +#. module: share +#. openerp-web +#: code:addons/share/static/src/js/share.js:60 +#: view:share.wizard:0 +#, python-format +msgid "Share" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:570 +#, python-format +msgid "(Duplicated for modified sharing permissions)" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:668 +#, python-format +msgid "" +"Please indicate the emails of the persons to share with, one per line." +msgstr "" + +#. module: share +#: help:share.wizard,domain:0 +msgid "Optional domain for further data filtering" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Next" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:661 +#, python-format +msgid "Action and Access Mode are required to create a shared access." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:849 +#: code:addons/share/wizard/share_wizard.py:881 +#, python-format +msgid "Username" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Sharing Options" +msgstr "" + +#. module: share +#. openerp-web +#: code:addons/share/static/src/xml/share.xml:9 +#, python-format +msgid "Invite" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Embedded code options" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Configuration" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "" +"Please select the action that opens the screen containing the data you want " +"to share." +msgstr "" + +#. module: share +#: field:res.groups,share:0 +msgid "Share Group" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:834 +#: code:addons/share/wizard/share_wizard.py:865 +#, python-format +msgid "Email required" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "" +"Optionally, you may specify an additional domain restriction that will be " +"applied to the shared data." +msgstr "" + +#. module: share +#: view:res.groups:0 +msgid "Non-Share Groups" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "" +"An email notification with instructions has been sent to the following " +"people:" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:77 +#, python-format +msgid "Direct link or embed code" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:855 +#: code:addons/share/wizard/share_wizard.py:889 +#, python-format +msgid "" +"OpenERP is a powerful and user-friendly suite of Business Applications (CRM, " +"Sales, HR, etc.)\n" +"It is open source and can be found on http://www.openerp.com." +msgstr "" + +#. module: share +#: field:share.wizard,action_id:0 +msgid "Action to share" +msgstr "" + +#. module: share +#: help:share.wizard,record_name:0 +msgid "Name of the shared record, if sharing a precise record" +msgstr "" + +#. module: share +#: field:res.users,share:0 +msgid "Share User" +msgstr "" + +#. module: share +#: field:share.wizard.result.line,user_id:0 +msgid "unknown" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:61 +#: code:addons/share/wizard/share_wizard.py:656 +#, python-format +msgid "Sharing access cannot be created." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:779 +#, python-format +msgid "Record id not found" +msgstr "" + +#. module: share +#: help:res.groups,share:0 +msgid "Group created to set access rights for sharing data with some users." +msgstr "" + +#. module: share +#: view:res.groups:0 +msgid "Share Groups" +msgstr "" + +#. module: share +#: help:share.wizard,action_id:0 +msgid "" +"The action that opens the screen containing the data you wish to share." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:545 +#, python-format +msgid "(Copy for sharing)" +msgstr "" + +#. module: share +#: field:share.wizard.result.line,newly_created:0 +msgid "Newly created" +msgstr "" + +#. module: share +#: help:share.wizard,name:0 +msgid "Title for the share (displayed to users as menu and shortcut name)" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:635 +#, python-format +msgid "Indirect sharing filter created by user %s (%s) for group %s" +msgstr "" + +#. module: share +#: help:share.wizard,share_root_url:0 +msgid "Main access page for users that are granted shared access" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:206 +#, python-format +msgid "" +"You must configure your email address in the user preferences before using " +"the Share button." +msgstr "" + +#. module: share +#: model:res.groups,name:share.group_share_user +msgid "User" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:657 +#, python-format +msgid "" +"Sorry, the current screen and filter you are trying to share are not " +"supported at the moment.\n" +"You may want to try a simpler filter." +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Use this link" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:851 +#: code:addons/share/wizard/share_wizard.py:883 +#, python-format +msgid "Database" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Share with these People (one email per line)" +msgstr "" + +#. module: share +#: field:share.wizard,domain:0 +msgid "Domain" +msgstr "" + +#. module: share +#: view:res.groups:0 +msgid "{'search_default_no_share':1}" +msgstr "" + +#. module: share +#: view:share.wizard:0 +#: field:share.wizard,result_line_ids:0 +msgid "Summary" +msgstr "" + +#. module: share +#: help:share.wizard,embed_code:0 +msgid "" +"Embed this code in your documents to provide a link to the shared document." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:512 +#, python-format +msgid "Copied access for sharing" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:816 +#, python-format +msgid "Invitation" +msgstr "" + +#. module: share +#: model:ir.actions.act_window,name:share.action_share_wizard_step1 +msgid "Share your documents" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Or insert the following code where you want to embed your documents" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:885 +#, python-format +msgid "" +"The documents have been automatically added to your current OpenERP " +"documents.\n" +msgstr "" + +#. module: share +#: model:ir.model,name:share.model_share_wizard_result_line +msgid "share.wizard.result.line" +msgstr "" + +#. module: share +#: field:share.wizard,embed_code:0 +msgid "Code" +msgstr "" + +#. module: share +#: help:share.wizard,user_type:0 +msgid "Select the type of user(s) you would like to share data with." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:843 +#, python-format +msgid "" +"I have shared %s (%s) with you!\n" +"\n" +msgstr "" + +#. module: share +#: field:share.wizard,view_type:0 +msgid "Current View Type" +msgstr "" + +#. module: share +#: selection:share.wizard,access_mode:0 +msgid "Can view" +msgstr "" + +#. module: share +#: selection:share.wizard,access_mode:0 +msgid "Can edit" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Cancel" +msgstr "" + +#. module: share +#: help:res.users,share:0 +msgid "" +"External user with limited access, created only for the purpose of sharing " +"data." +msgstr "" + +#. module: share +#: model:ir.actions.act_window,name:share.action_share_wizard +#: model:ir.model,name:share.model_share_wizard +#: field:share.wizard.result.line,share_wizard_id:0 +msgid "Share Wizard" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:792 +#, python-format +msgid "Shared access created!" +msgstr "" + +#. module: share +#: model:res.groups,comment:share.group_share_user +msgid "" +"\n" +"Members of this groups have access to the sharing wizard, which allows them " +"to invite external users to view or edit some of their documents." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:852 +#, python-format +msgid "" +"The documents have been automatically added to your subscriptions.\n" +"\n" +msgstr "" + +#. module: share +#: model:ir.model,name:share.model_res_users +msgid "Users" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:875 +#, python-format +msgid "" +"I've shared %s with you!\n" +"\n" +msgstr "" + +#. module: share +#: model:ir.model,name:share.model_res_groups +msgid "Access Groups" +msgstr "" + +#. module: share +#: field:share.wizard,invite:0 +msgid "Invite users to OpenSocial record" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:850 +#: code:addons/share/wizard/share_wizard.py:882 +#: field:share.wizard.result.line,password:0 +#, python-format +msgid "Password" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:77 +#: field:share.wizard,new_users:0 +#, python-format +msgid "Emails" +msgstr "" + +#. module: share +#: field:share.wizard,embed_option_search:0 +msgid "Display search view" +msgstr "" + +#. module: share +#: field:share.wizard,message:0 +msgid "Personal Message" +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:834 +#: code:addons/share/wizard/share_wizard.py:865 +#, python-format +msgid "" +"The current user must have an email address configured in User Preferences " +"to be able to send outgoing emails." +msgstr "" + +#. module: share +#: code:addons/share/wizard/share_wizard.py:205 +#, python-format +msgid "No email address configured" +msgstr "" + +#. module: share +#: field:share.wizard.result.line,login:0 +msgid "Login" +msgstr "" + +#. module: share +#: view:res.users:0 +msgid "Regular users only (no share user)" +msgstr "" + +#. module: share +#: field:share.wizard,access_mode:0 +msgid "Access Mode" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "Sharing: preparation" +msgstr "" + +#. module: share +#: model:ir.model,name:share.model_ir_model_access +msgid "ir.model.access" +msgstr "" + +#. module: share +#: view:share.wizard:0 +msgid "or" +msgstr "" + +#. module: share +#: help:share.wizard,access_mode:0 +msgid "Access rights to be granted on the shared documents." +msgstr "" diff --git a/addons/share/res_users.py b/addons/share/res_users.py index 25fd25c234f..30200133f8e 100644 --- a/addons/share/res_users.py +++ b/addons/share/res_users.py @@ -34,7 +34,6 @@ class res_groups(osv.osv): domain.append(('share', '=', False)) return super(res_groups, self).get_application_groups(cr, uid, domain=domain, context=context) -res_groups() class res_users(osv.osv): _name = 'res.users' @@ -43,6 +42,5 @@ class res_users(osv.osv): 'share': fields.boolean('Share User', readonly=True, help="External user with limited access, created only for the purpose of sharing data.") } -res_users() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/share/wizard/share_wizard.py b/addons/share/wizard/share_wizard.py index 429a1dc2f08..3a26dcb9e6b 100644 --- a/addons/share/wizard/share_wizard.py +++ b/addons/share/wizard/share_wizard.py @@ -205,7 +205,7 @@ class share_wizard(osv.TransientModel): raise osv.except_osv(_('No email address configured'), _('You must configure your email address in the user preferences before using the Share button.')) model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'share', 'action_share_wizard_step1') - action = self.pool.get(model).read(cr, uid, res_id, context=context) + action = self.pool[model].read(cr, uid, res_id, context=context) action['res_id'] = ids[0] action.pop('context', '') return action @@ -404,7 +404,7 @@ class share_wizard(osv.TransientModel): local_rel_fields = [] models = [x[1].model for x in relation_fields] model_obj = self.pool.get('ir.model') - model_osv = self.pool.get(model.model) + model_osv = self.pool[model.model] for colinfo in model_osv._all_columns.itervalues(): coldef = colinfo.column coltype = coldef._type @@ -412,7 +412,7 @@ class share_wizard(osv.TransientModel): if coltype in ttypes and colinfo.column._obj not in models: relation_model_id = model_obj.search(cr, UID_ROOT, [('model','=',coldef._obj)])[0] relation_model_browse = model_obj.browse(cr, UID_ROOT, relation_model_id, context=context) - relation_osv = self.pool.get(coldef._obj) + relation_osv = self.pool[coldef._obj] if coltype == 'one2many': # don't record reverse path if it's not a real m2o (that happens, but rarely) dest_model_ci = relation_osv._all_columns @@ -422,7 +422,7 @@ class share_wizard(osv.TransientModel): local_rel_fields.append((relation_field, relation_model_browse)) for parent in relation_osv._inherits: if parent not in models: - parent_model = self.pool.get(parent) + parent_model = self.pool[parent] parent_colinfos = parent_model._all_columns parent_model_browse = model_obj.browse(cr, UID_ROOT, model_obj.search(cr, UID_ROOT, [('model','=',parent)]))[0] @@ -458,7 +458,7 @@ class share_wizard(osv.TransientModel): """ # obj0 class and its parents obj0 = [(None, model)] - model_obj = self.pool.get(model.model) + model_obj = self.pool[model.model] ir_model_obj = self.pool.get('ir.model') for parent in model_obj._inherits: parent_model_browse = ir_model_obj.browse(cr, UID_ROOT, @@ -777,7 +777,7 @@ class share_wizard(osv.TransientModel): # Record id not found: issue if res_id <= 0: raise osv.except_osv(_('Record id not found'), _('The share engine has not been able to fetch a record_id for your invitation.')) - self.pool.get(model.model).message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context) + self.pool[model.model].message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context) # self.send_invite_email(cr, uid, wizard_data, context=context) # self.send_invite_note(cr, uid, model.model, res_id, wizard_data, context=context) @@ -823,7 +823,7 @@ class share_wizard(osv.TransientModel): elif tmp_idx == len(wizard_data.result_line_ids)-2: body += ' and' body += '.' - return self.pool.get(model_name).message_post(cr, uid, [res_id], body=body, context=context) + return self.pool[model_name].message_post(cr, uid, [res_id], body=body, context=context) def send_invite_email(self, cr, uid, wizard_data, context=None): # TDE Note: not updated because will disappear @@ -902,7 +902,6 @@ class share_wizard(osv.TransientModel): options = dict(title=opt_title, search=opt_search) return {'value': {'embed_code': self._generate_embedded_code(wizard, options)}} -share_wizard() class share_result_line(osv.osv_memory): _name = 'share.wizard.result.line' diff --git a/addons/share/wizard/share_wizard_view.xml b/addons/share/wizard/share_wizard_view.xml index 859245b46a9..e0e800ab150 100644 --- a/addons/share/wizard/share_wizard_view.xml +++ b/addons/share/wizard/share_wizard_view.xml @@ -96,6 +96,7 @@
+
diff --git a/addons/stock/html/Didier-Georgieff.jpg b/addons/stock/html/Didier-Georgieff.jpg new file mode 100644 index 00000000000..ccf3007b86e Binary files /dev/null and b/addons/stock/html/Didier-Georgieff.jpg differ diff --git a/addons/stock/html/Mario-Riva.png b/addons/stock/html/Mario-Riva.png new file mode 100644 index 00000000000..35b030a4265 Binary files /dev/null and b/addons/stock/html/Mario-Riva.png differ diff --git a/addons/stock/html/index.html b/addons/stock/html/index.html new file mode 100644 index 00000000000..7374dab4433 --- /dev/null +++ b/addons/stock/html/index.html @@ -0,0 +1,239 @@ +
+
+
+

Warehouse Management System

+

A revolutionary double entry inventory system

+
+
+
+ + + +   + +
+
+
+

+Decrease your process times, automate transactions, reduce your stock levels and get complete traceability on all operations with the OpenERP double entry inventory system. +

+ +
+
+
+ +
+
+

Double Entry Inventory Management

+

Nothing is lost, everything is moved

+
+

+Based on the concept of double entry that revolutionized accounting, OpenERP's +inventory management isn't about consumption, loss or missing products; +products are just moved from one location to another. +

+This allows full traceability (from customer to supplier, not limited to your +warehouse), advanced reporting (e.g. inventory valuation on manufacturing +counter-parts locations) and a very simple user interface. +

+
+
+
+ +
+
+
+
+ +
+
+

Decrease your process time

+
+ +
+
+

+OpenERP prepares all operations for you, according to your own logistic rules: +push rules, pull rules, make-to-order, minimum stock rules, etc. Optimizes the +planning and jobs with the scheduler to reduce your process time. +

+
+
+
+ +
+
+

Automate transactions

+
+

+Get your pickings, packings, receptions and internal moves scheduled +automatically by OpenERP using your own routing rules. Define push and pull +rules to organize a warehouse or to manage produts's moves between several +warehouses. +

+
+
+ +
+
+
+ +
+
+

Get Full Traceability

+
+
+ +
+
+
+

+Keep an eye on all your stock by tracing all your past and future inventory +transactions. Track in detail all stock moves, not only in your warehouse but +also in counter-parts of the double entry moves (customers, suppliers or +manufacturing locations). +

+ Browse through the upstream or downstream traceability flows to + have a clear vision to what happened to a specific product or lot. +

+
+
+
+ +
+
+ +
+ Download our free E-book +
+ +
+
+

Reduce your stock level

+

Fine-tune procurement methods according to your need

+
+

+Reduce your stock while always staying replenished! You can setup minimum stock +rules to have automatic procurements with the right quantities computed to get +to the optimum level specified. Get rid of the stress of your stock and let the +system help you with fullfilment propositions.  +

+
+
+
+ +
+
+
+
+ +
+
+

Fully Integrated with Operations

+

Sales, Purchases and Accounting integration

+
+
+ +
+
+
+

+Get your procurements accurate as the OpenERP WMS is fully integrated with +sales and purchases for accurate forecasts. The accounting integration allows +real time accounting valuation and deeper reporting on costs and revenues on +your inventory operations. +

+
+
+
+ +
+
+

Track Serial Numbers

+
+

+Assign serial numbers at every step of your reception or delivery flow. +OpenERP handles production lots (batches of identical products) or logistic +lots (pallets, boxes, etc) to help you get full upstream or downstream +traceability. +

+
+
+
+ +
+
+
+
+ +
+
+

Scale Your WMS easily

+
+
+ +
+
+
+

+Manage your own internal and external locations, customers, suppliers or +manufacturing inventories with the OpenERP multi-warehouse management system +based on a hierarchical location structure. +

+
+
+
+ +
+
+

Reporting and Dashboards

+

Analyse your warehouse efficiency to improve performance

+
+

+Get the insights you need to make smarter decisions. Design custom dashboards +to get a picture of your warehouse efficiency at a glance. Dig deeper with +real-time reports that anyone can create and share. +

+
+
+ +
+
+
+ +
+
+
+

Many companies already enjoy it

+

Hear what they have to say !

+
+
+
+ + We found the WMS apps to be a powerful tool for mid­size companies to better + organize the warehouse. It's simple and easily customizable. + + + +
Mario Riva
+ +
+
+
+
+
+ + We saved hundreds of thousands of dollars with OpenERP. + + + +
Didier Georgieff
+
Chief Technical Officer, ENA
+
+
+
+
+
+ diff --git a/addons/stock/html/stock_calendar.png b/addons/stock/html/stock_calendar.png new file mode 100644 index 00000000000..58fb2bb077a Binary files /dev/null and b/addons/stock/html/stock_calendar.png differ diff --git a/addons/stock/html/stock_integrate.png b/addons/stock/html/stock_integrate.png new file mode 100644 index 00000000000..92a0b0950d6 Binary files /dev/null and b/addons/stock/html/stock_integrate.png differ diff --git a/addons/stock/html/stock_main.png b/addons/stock/html/stock_main.png new file mode 100644 index 00000000000..b9b44c702aa Binary files /dev/null and b/addons/stock/html/stock_main.png differ diff --git a/addons/stock/html/stock_procurement.png b/addons/stock/html/stock_procurement.png new file mode 100644 index 00000000000..cb315e08224 Binary files /dev/null and b/addons/stock/html/stock_procurement.png differ diff --git a/addons/stock/html/stock_product.png b/addons/stock/html/stock_product.png new file mode 100644 index 00000000000..cbfd054d72e Binary files /dev/null and b/addons/stock/html/stock_product.png differ diff --git a/addons/stock/html/stock_product_form.png b/addons/stock/html/stock_product_form.png new file mode 100644 index 00000000000..a25c85b6496 Binary files /dev/null and b/addons/stock/html/stock_product_form.png differ diff --git a/addons/stock/html/stock_reporting.png b/addons/stock/html/stock_reporting.png new file mode 100644 index 00000000000..1ec54d18813 Binary files /dev/null and b/addons/stock/html/stock_reporting.png differ diff --git a/addons/stock/html/warehouse_illu_01.png b/addons/stock/html/warehouse_illu_01.png new file mode 100644 index 00000000000..60ccb3bf1ba Binary files /dev/null and b/addons/stock/html/warehouse_illu_01.png differ diff --git a/addons/stock/html/warehouse_illu_02.png b/addons/stock/html/warehouse_illu_02.png new file mode 100644 index 00000000000..1543e2e3ae1 Binary files /dev/null and b/addons/stock/html/warehouse_illu_02.png differ diff --git a/addons/stock/partner.py b/addons/stock/partner.py index f5f02b7cd19..b8bad4faf95 100644 --- a/addons/stock/partner.py +++ b/addons/stock/partner.py @@ -41,6 +41,5 @@ class res_partner(osv.osv): help="This stock location will be used, instead of the default one, as the source location for goods you receive from the current partner"), } -res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/product.py b/addons/stock/product.py index 1d56ce64988..29445f671ee 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -479,7 +479,6 @@ class product_product(osv.osv): res['fields']['qty_available']['string'] = _('Produced Qty') return res -product_product() class product_template(osv.osv): _name = 'product.template' @@ -528,7 +527,6 @@ class product_template(osv.osv): _defaults = { 'sale_delay': 7, } -product_template() class product_category(osv.osv): @@ -558,6 +556,5 @@ class product_category(osv.osv): help="When real-time inventory valuation is enabled on a product, this account will hold the current value of the products.",), } -product_category() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml index dc80c0f950a..e52a0181206 100644 --- a/addons/stock/product_view.xml +++ b/addons/stock/product_view.xml @@ -110,12 +110,11 @@
- - - - - - + + + + + diff --git a/addons/stock/report/lot_overview.py b/addons/stock/report/lot_overview.py index 9d6626bbd14..c8e80ac54b9 100644 --- a/addons/stock/report/lot_overview.py +++ b/addons/stock/report/lot_overview.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # ############################################################################## -from openerp import pooler import time from openerp.report import report_sxw @@ -35,7 +34,7 @@ class lot_overview(report_sxw.rml_parse): }) def process(self, location_id): - location_obj = pooler.get_pool(self.cr.dbname).get('stock.location') + location_obj = self.pool['stock.location'] data = location_obj._product_get_report(self.cr,self.uid, [location_id]) data['location_name'] = location_obj.read(self.cr, self.uid, [location_id],['complete_name'])[0]['complete_name'] diff --git a/addons/stock/report/lot_overview_all.py b/addons/stock/report/lot_overview_all.py index ca6611de89b..aba97fa6e1e 100644 --- a/addons/stock/report/lot_overview_all.py +++ b/addons/stock/report/lot_overview_all.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # ############################################################################## -from openerp import pooler import time from openerp.report import report_sxw @@ -35,7 +34,7 @@ class lot_overview_all(report_sxw.rml_parse): }) def process(self, location_id): - location_obj = pooler.get_pool(self.cr.dbname).get('stock.location') + location_obj = self.pool['stock.location'] data = location_obj._product_get_all_report(self.cr,self.uid, [location_id]) data['location_name'] = location_obj.read(self.cr, self.uid, [location_id],['complete_name'])[0]['complete_name'] self.price_total = 0.0 diff --git a/addons/stock/report/picking.py b/addons/stock/report/picking.py index a33ec28cb35..512d124ee0c 100644 --- a/addons/stock/report/picking.py +++ b/addons/stock/report/picking.py @@ -22,7 +22,6 @@ import time from openerp.report import report_sxw from openerp.osv import osv -from openerp import pooler class picking(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): diff --git a/addons/stock/report/product_stock.py b/addons/stock/report/product_stock.py index 9ccda54b693..d213db673dc 100644 --- a/addons/stock/report/product_stock.py +++ b/addons/stock/report/product_stock.py @@ -22,14 +22,15 @@ from datetime import datetime from dateutil.relativedelta import relativedelta +import openerp from openerp import osv import time from openerp.report.interface import report_int from openerp.report.render import render import stock_graph -from openerp import pooler import StringIO +import unicodedata class external_pdf(render): def __init__(self, pdf): @@ -45,24 +46,25 @@ class report_stock(report_int): def create(self, cr, uid, ids, datas, context=None): if context is None: context = {} + registry = openerp.registry(cr.dbname) product_ids = ids if 'location_id' in context: location_id = context['location_id'] else: - warehouse_id = pooler.get_pool(cr.dbname).get('stock.warehouse').search(cr, uid, [])[0] - location_id = pooler.get_pool(cr.dbname).get('stock.warehouse').browse(cr, uid, warehouse_id).lot_stock_id.id + warehouse_id = registry['stock.warehouse'].search(cr, uid, [])[0] + location_id = registry['stock.warehouse'].browse(cr, uid, warehouse_id).lot_stock_id.id - loc_ids = pooler.get_pool(cr.dbname).get('stock.location').search(cr, uid, [('location_id','child_of',[location_id])]) + loc_ids = registry['stock.location'].search(cr, uid, [('location_id','child_of',[location_id])]) now = time.strftime('%Y-%m-%d') dt_from = now dt_to = now - names = dict(pooler.get_pool(cr.dbname).get('product.product').name_get(cr, uid, product_ids)) + names = dict(registry['product.product'].name_get(cr, uid, product_ids)) for name in names: names[name] = names[name].encode('utf8') products = {} - prods = pooler.get_pool(cr.dbname).get('stock.location')._product_all_get(cr, uid, location_id, product_ids) + prods = registry['stock.location']._product_all_get(cr, uid, location_id, product_ids) for p in prods: products[p] = [(now,prods[p])] @@ -106,7 +108,12 @@ class report_stock(report_int): io = StringIO.StringIO() gt = stock_graph.stock_graph(io) for prod_id in products: - gt.add(prod_id, names.get(prod_id, 'Unknown'), products[prod_id]) + prod_name = names.get(prod_id,'Unknown') + if isinstance(prod_name, str): + prod_name = prod_name.decode('utf-8') + prod_name = unicodedata.normalize('NFKD',prod_name) + prod_name = prod_name.encode('ascii','replace') + gt.add(prod_id, prod_name, products[prod_id]) gt.draw() gt.close() self.obj = external_pdf(io.getvalue()) diff --git a/addons/stock/report/report_stock.py b/addons/stock/report/report_stock.py index 0aac0d6599b..d4bbb3ab127 100644 --- a/addons/stock/report/report_stock.py +++ b/addons/stock/report/report_stock.py @@ -77,7 +77,6 @@ class stock_report_prodlots(osv.osv): def unlink(self, cr, uid, ids, context=None): raise osv.except_osv(_('Error!'), _('You cannot delete any record!')) -stock_report_prodlots() class stock_report_tracklots(osv.osv): _name = "stock.report.tracklots" @@ -133,7 +132,6 @@ class stock_report_tracklots(osv.osv): def unlink(self, cr, uid, ids, context=None): raise osv.except_osv(_('Error!'), _('You cannot delete any record!')) -stock_report_tracklots() class report_stock_lines_date(osv.osv): _name = "report.stock.lines.date" @@ -162,6 +160,5 @@ class report_stock_lines_date(osv.osv): group by p.id )""") -report_stock_lines_date() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py index 39591021735..b8c22062fa5 100644 --- a/addons/stock/report/report_stock_move.py +++ b/addons/stock/report/report_stock_move.py @@ -142,7 +142,6 @@ class report_stock_move(osv.osv): ) """) -report_stock_move() class report_stock_inventory(osv.osv): @@ -193,6 +192,7 @@ CREATE OR REPLACE view report_stock_inventory AS ( LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id) LEFT JOIN product_uom u ON (m.product_uom=u.id) LEFT JOIN stock_location l ON (m.location_id=l.id) + WHERE m.state != 'cancel' GROUP BY m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id, m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM') @@ -216,13 +216,13 @@ CREATE OR REPLACE view report_stock_inventory AS ( LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id) LEFT JOIN product_uom u ON (m.product_uom=u.id) LEFT JOIN stock_location l ON (m.location_dest_id=l.id) + WHERE m.state != 'cancel' GROUP BY m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id, m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM') ) ); """) -report_stock_inventory() diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml index 4f3e256389c..fcf99f6e51e 100644 --- a/addons/stock/report/report_stock_move_view.xml +++ b/addons/stock/report/report_stock_move_view.xml @@ -149,7 +149,7 @@ - + diff --git a/addons/stock/report/stock_by_location.py b/addons/stock/report/stock_by_location.py index 7ca209c9ed2..153b92f077c 100644 --- a/addons/stock/report/stock_by_location.py +++ b/addons/stock/report/stock_by_location.py @@ -19,7 +19,7 @@ # ############################################################################## -from openerp import pooler +import openerp from openerp.report.interface import report_rml from openerp.report.interface import toxml @@ -47,16 +47,17 @@ class report_custom(report_rml): """ def process(location_id, level): + registry = openerp.registry(cr.dbname) xml = '' - location_name = pooler.get_pool(cr.dbname).get('stock.location').read(cr, uid, [location_id], ['name']) + location_name = registry['stock.location'].read(cr, uid, [location_id], ['name']) xml += "
" xml += location_name[0]['name'] + '' - prod_info = pooler.get_pool(cr.dbname).get('stock.location')._product_get(cr, uid, location_id) + prod_info = registry['stock.location']._product_get(cr, uid, location_id) xml += "" for prod_id in prod_info.keys(): if prod_info[prod_id] != 0.0: - prod_name = pooler.get_pool(cr.dbname).get('product.product').read(cr, uid, [prod_id], ['name']) + prod_name = registry['product.product'].read(cr, uid, [prod_id], ['name']) xml += prod_name[0]['name'] + '\n' xml += '' @@ -66,7 +67,7 @@ class report_custom(report_rml): xml += str(prod_info[prod_id]) + '\n' xml += '' - location_child = pooler.get_pool(cr.dbname).get('stock.location').read(cr, uid, [location_id], ['child_ids']) + location_child = registry['stock.location'].read(cr, uid, [location_id], ['child_ids']) for child_id in location_child[0]['child_ids']: xml += process(child_id, level+1) return xml diff --git a/addons/stock/stock.py b/addons/stock/stock.py index ba3db96ff68..db73bae3b6c 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -29,7 +29,7 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp import netsvc from openerp import tools -from openerp.tools import float_compare +from openerp.tools import float_compare, DEFAULT_SERVER_DATETIME_FORMAT import openerp.addons.decimal_precision as dp import logging _logger = logging.getLogger(__name__) @@ -49,7 +49,6 @@ class stock_incoterms(osv.osv): 'active': True, } -stock_incoterms() class stock_journal(osv.osv): _name = "stock.journal" @@ -62,7 +61,6 @@ class stock_journal(osv.osv): 'user_id': lambda s, c, u, ctx: u } -stock_journal() #---------------------------------------------------------- # Stock Location @@ -472,7 +470,6 @@ class stock_location(osv.osv): continue return False -stock_location() class stock_tracking(osv.osv): @@ -538,7 +535,6 @@ class stock_tracking(osv.osv): """ return self.pool.get('action.traceability').action_traceability(cr,uid,ids,context) -stock_tracking() #---------------------------------------------------------- # Stock Picking @@ -616,7 +612,7 @@ class stock_picking(osv.osv): return res def create(self, cr, user, vals, context=None): - if ('name' not in vals) or (vals.get('name')=='/'): + if ('name' not in vals) or (vals.get('name')=='/') or (vals.get('name') == False): seq_obj_name = self._name vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name) new_id = super(stock_picking, self).create(cr, user, vals, context) @@ -651,7 +647,7 @@ class stock_picking(osv.osv): ), 'min_date': fields.function(get_min_max_date, fnct_inv=_set_minimum_date, multi="min_max_date", store=True, type='datetime', string='Scheduled Time', select=1, help="Scheduled time for the shipment to be processed"), - 'date': fields.datetime('Time', help="Creation time, usually the time of the order.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), + 'date': fields.datetime('Creation Date', help="Creation date, usually the time of the order.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'date_done': fields.datetime('Date of Transfer', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'max_date': fields.function(get_min_max_date, fnct_inv=_set_maximum_date, multi="min_max_date", store=True, type='datetime', string='Max. Expected Date', select=2), @@ -1491,7 +1487,6 @@ class stock_production_lot(osv.osv): default.update(date=time.strftime('%Y-%m-%d %H:%M:%S'), move_ids=[]) return super(stock_production_lot, self).copy(cr, uid, id, default=default, context=context) -stock_production_lot() class stock_production_lot_revision(osv.osv): _name = 'stock.production.lot.revision' @@ -1512,7 +1507,6 @@ class stock_production_lot_revision(osv.osv): 'date': fields.date.context_today, } -stock_production_lot_revision() # ---------------------------------------------------- # Move @@ -2329,7 +2323,6 @@ class stock_move(osv.osv): 'line_id': move_lines, 'ref': move.picking_id and move.picking_id.name}) - def action_done(self, cr, uid, ids, context=None): """ Makes the move done and if all moves are done, it will finish the picking. @return: @@ -2375,7 +2368,7 @@ class stock_move(osv.osv): if todo: self.action_confirm(cr, uid, todo, context=context) - self.write(cr, uid, move_ids, {'state': 'done', 'date': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context) + self.write(cr, uid, move_ids, {'state': 'done', 'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context) for id in move_ids: wf_service.trg_trigger(uid, 'stock.move', id, cr) @@ -2418,14 +2411,14 @@ class stock_move(osv.osv): # or if it's the same as that of the secondary amount being posted. account_obj = self.pool.get('account.account') src_acct, dest_acct = account_obj.browse(cr, uid, [src_account_id, dest_account_id], context=context) - src_main_currency_id = src_acct.company_id.currency_id.id - dest_main_currency_id = dest_acct.company_id.currency_id.id + src_main_currency_id = src_acct.currency_id and src_acct.currency_id.id or src_acct.company_id.currency_id.id + dest_main_currency_id = dest_acct.currency_id and dest_acct.currency_id.id or dest_acct.company_id.currency_id.id cur_obj = self.pool.get('res.currency') if reference_currency_id != src_main_currency_id: # fix credit line: credit_line_vals['credit'] = cur_obj.compute(cr, uid, reference_currency_id, src_main_currency_id, reference_amount, context=context) if (not src_acct.currency_id) or src_acct.currency_id.id == reference_currency_id: - credit_line_vals.update(currency_id=reference_currency_id, amount_currency=reference_amount) + credit_line_vals.update(currency_id=reference_currency_id, amount_currency=-reference_amount) if reference_currency_id != dest_main_currency_id: # fix debit line: debit_line_vals['debit'] = cur_obj.compute(cr, uid, reference_currency_id, dest_main_currency_id, reference_amount, context=context) @@ -2737,7 +2730,6 @@ class stock_move(osv.osv): return [move.id for move in complete] -stock_move() class stock_inventory(osv.osv): _name = "stock.inventory" @@ -2860,7 +2852,6 @@ class stock_inventory(osv.osv): self.write(cr, uid, [inv.id], {'state': 'cancel'}, context=context) return True -stock_inventory() class stock_inventory_line(osv.osv): _name = "stock.inventory.line" @@ -2900,7 +2891,6 @@ class stock_inventory_line(osv.osv): result = {'product_qty': amount, 'product_uom': uom, 'prod_lot_id': False} return {'value': result} -stock_inventory_line() #---------------------------------------------------------- # Stock Warehouse @@ -2932,7 +2922,6 @@ class stock_warehouse(osv.osv): 'lot_output_id': _default_lot_output_id, } -stock_warehouse() #---------------------------------------------------------- # "Empty" Classes that are used to vary from the original stock.picking (that are dedicated to the internal pickings) @@ -2944,6 +2933,12 @@ class stock_picking_in(osv.osv): _table = "stock_picking" _description = "Incoming Shipments" + def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): + return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count) + + def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): + return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load) + def check_access_rights(self, cr, uid, operation, raise_exception=True): #override in order to redirect the check of acces rights on the stock.picking object return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception) @@ -2999,6 +2994,12 @@ class stock_picking_out(osv.osv): _table = "stock_picking" _description = "Delivery Orders" + def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): + return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count) + + def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): + return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load) + def check_access_rights(self, cr, uid, operation, raise_exception=True): #override in order to redirect the check of acces rights on the stock.picking object return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 6162d073fde..b1a1fa048be 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -817,7 +817,7 @@ - + @@ -944,6 +944,7 @@ + @@ -1069,6 +1070,7 @@ + @@ -1260,8 +1262,8 @@ - - + + @@ -1380,7 +1382,7 @@ - + diff --git a/addons/stock/test/stock_report.yml b/addons/stock/test/stock_report.yml index b1590a4d819..2b062742294 100644 --- a/addons/stock/test/stock_report.yml +++ b/addons/stock/test/stock_report.yml @@ -3,8 +3,9 @@ - !python {model: stock.location}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.lot.stock.overview').create(cr, uid, [ref('location_refrigerator')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('location_refrigerator')], 'lot.stock.overview', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'stock-overview'+format), 'wb+').write(data) - @@ -12,8 +13,9 @@ - !python {model: stock.location}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.lot.stock.overview_all').create(cr, uid, [ref('location_refrigerator')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('location_refrigerator')], 'lot.stock.overview_all', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'stock-overviewall'+format), 'wb+').write(data) - @@ -21,8 +23,9 @@ - !python {model: stock.inventory}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.stock.inventory.move').create(cr, uid, [ref('stock_inventory_icecream')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('stock_inventory_icecream')], 'stock.inventory.move', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'stock-stock_inventory_move.'+format), 'wb+').write(data) - @@ -30,8 +33,9 @@ - !python {model: stock.picking}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.stock.picking.list').create(cr, uid, [ref('outgoing_shipment')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('outgoing_shipment')], 'stock.picking.list', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'stock-picking_list'+format), 'wb+').write(data) - @@ -39,8 +43,9 @@ - !python {model: product.product}: | import os - from openerp import netsvc, tools - (data, format) = netsvc.LocalService('report.stock.product.history').create(cr, uid, [ref('product_icecream')], {}, {}) + import openerp.report + from openerp import tools + data, format = openerp.report.render_report(cr, uid, [ref('product_icecream')], 'stock.product.history', {}, {}) if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'stock-product_stock_report.'+format), 'wb+').write(data) diff --git a/addons/stock/wizard/stock_change_standard_price.py b/addons/stock/wizard/stock_change_standard_price.py index 881b5fd9af7..e6614724454 100644 --- a/addons/stock/wizard/stock_change_standard_price.py +++ b/addons/stock/wizard/stock_change_standard_price.py @@ -116,6 +116,5 @@ class change_standard_price(osv.osv_memory): prod_obj.do_change_standard_price(cr, uid, [rec_id], datas, context) return {'type': 'ir.actions.act_window_close'} -change_standard_price() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_fill_inventory.py b/addons/stock/wizard/stock_fill_inventory.py index 237033bb7b0..e3341bd6a80 100644 --- a/addons/stock/wizard/stock_fill_inventory.py +++ b/addons/stock/wizard/stock_fill_inventory.py @@ -143,6 +143,5 @@ class stock_fill_inventory(osv.osv_memory): return {'type': 'ir.actions.act_window_close'} -stock_fill_inventory() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_inventory_merge.py b/addons/stock/wizard/stock_inventory_merge.py index 171a193e173..e2b5cff513d 100644 --- a/addons/stock/wizard/stock_inventory_merge.py +++ b/addons/stock/wizard/stock_inventory_merge.py @@ -86,7 +86,6 @@ class stock_inventory_merge(osv.osv_memory): return {'type': 'ir.actions.act_window_close'} -stock_inventory_merge() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_invoice_onshipping.py b/addons/stock/wizard/stock_invoice_onshipping.py index 7c960c5e617..c95508cd71b 100644 --- a/addons/stock/wizard/stock_invoice_onshipping.py +++ b/addons/stock/wizard/stock_invoice_onshipping.py @@ -39,7 +39,7 @@ class stock_invoice_onshipping(osv.osv_memory): if not model or 'stock.picking' not in model: return [] - model_pool = self.pool.get(model) + model_pool = self.pool[model] journal_obj = self.pool.get('account.journal') res_ids = context and context.get('active_ids', []) vals = [] @@ -119,7 +119,7 @@ class stock_invoice_onshipping(osv.osv_memory): elif inv_type == "in_refund": action_model,action_id = data_pool.get_object_reference(cr, uid, 'account', "action_invoice_tree4") if action_model: - action_pool = self.pool.get(action_model) + action_pool = self.pool[action_model] action = action_pool.read(cr, uid, action_id, context=context) action['domain'] = "[('id','in', ["+','.join(map(str,invoice_ids))+"])]" return action @@ -146,6 +146,5 @@ class stock_invoice_onshipping(osv.osv_memory): context=context) return res -stock_invoice_onshipping() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_location_product.py b/addons/stock/wizard/stock_location_product.py index 59d99167e6a..ef7c9848160 100644 --- a/addons/stock/wizard/stock_location_product.py +++ b/addons/stock/wizard/stock_location_product.py @@ -57,6 +57,5 @@ class stock_location_product(osv.osv_memory): 'domain': [('type', '<>', 'service')], } -stock_location_product() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_move.py b/addons/stock/wizard/stock_move.py index 09f684aa691..a98d0ebda02 100644 --- a/addons/stock/wizard/stock_move.py +++ b/addons/stock/wizard/stock_move.py @@ -78,7 +78,6 @@ class stock_move_consume(osv.osv_memory): context=context) return {'type': 'ir.actions.act_window_close'} -stock_move_consume() class stock_move_scrap(osv.osv_memory): @@ -139,7 +138,6 @@ class stock_move_scrap(osv.osv_memory): context=context) return {'type': 'ir.actions.act_window_close'} -stock_move_scrap() class split_in_production_lot(osv.osv_memory): @@ -255,7 +253,6 @@ class split_in_production_lot(osv.osv_memory): return new_move -split_in_production_lot() class stock_move_split_lines_exist(osv.osv_memory): _name = "stock.move.split.lines" diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py index 4eb817e9c71..c51e1415249 100644 --- a/addons/stock/wizard/stock_return_picking.py +++ b/addons/stock/wizard/stock_return_picking.py @@ -19,7 +19,6 @@ # ############################################################################## -from openerp import netsvc import time from openerp.osv import osv,fields @@ -39,7 +38,6 @@ class stock_return_picking_memory(osv.osv_memory): } -stock_return_picking_memory() class stock_return_picking(osv.osv_memory): @@ -226,6 +224,5 @@ class stock_return_picking(osv.osv_memory): 'context':context, } -stock_return_picking() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_splitinto.py b/addons/stock/wizard/stock_splitinto.py index 3485a6e8264..76a80595be6 100644 --- a/addons/stock/wizard/stock_splitinto.py +++ b/addons/stock/wizard/stock_splitinto.py @@ -80,7 +80,6 @@ class stock_split_into(osv.osv_memory): return {'type': 'ir.actions.act_window_close'} -stock_split_into() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_traceability.py b/addons/stock/wizard/stock_traceability.py index 123a76acd43..c13fc1cf7a6 100644 --- a/addons/stock/wizard/stock_traceability.py +++ b/addons/stock/wizard/stock_traceability.py @@ -53,6 +53,7 @@ class action_traceability(osv.osv_memory): 'domain': "[('id','in',["+','.join(map(str, ids))+"])]", 'name': ((type1=='move_history_ids2') and _('Upstream Traceability')) or _('Downstream Traceability'), 'view_mode': 'tree', + 'view_type': 'tree', 'res_model': 'stock.move', 'field_parent': type1, 'view_id': (view_id,'View'), @@ -61,7 +62,6 @@ class action_traceability(osv.osv_memory): } return value -action_traceability() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock_invoice_directly/wizard/stock_invoice.py b/addons/stock_invoice_directly/wizard/stock_invoice.py index 5de6490dc0f..ba41de626da 100644 --- a/addons/stock_invoice_directly/wizard/stock_invoice.py +++ b/addons/stock_invoice_directly/wizard/stock_invoice.py @@ -45,6 +45,5 @@ class invoice_directly(osv.osv_memory): } return {'type': 'ir.actions.act_window_close'} -invoice_directly() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock_location/procurement_pull.py b/addons/stock_location/procurement_pull.py index 9f5dfb77375..5b030b5befe 100644 --- a/addons/stock_location/procurement_pull.py +++ b/addons/stock_location/procurement_pull.py @@ -19,7 +19,6 @@ ############################################################################## from openerp.osv import osv -from openerp import netsvc from openerp.tools.translate import _ class procurement_order(osv.osv): diff --git a/addons/stock_location/stock_location.py b/addons/stock_location/stock_location.py index 1258ddb529f..e22ccf80f8f 100644 --- a/addons/stock_location/stock_location.py +++ b/addons/stock_location/stock_location.py @@ -54,7 +54,6 @@ class stock_location_path(osv.osv): 'invoice_state': 'none', 'picking_type': 'internal', } -stock_location_path() class product_pulled_flow(osv.osv): _name = 'product.pulled.flow' @@ -85,7 +84,6 @@ class product_pulled_flow(osv.osv): 'invoice_state': 'none', 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'product.pulled.flow', context=c), } -product_pulled_flow() class product_product(osv.osv): _inherit = 'product.product' @@ -96,7 +94,6 @@ class product_product(osv.osv): help="These rules set the right path of the product in the "\ "whole location tree.") } -product_product() class stock_move(osv.osv): _inherit = 'stock.move' @@ -114,7 +111,6 @@ class stock_move(osv.osv): res = super(stock_move, self)._prepare_chained_picking(cr, uid, picking_name, picking, picking_type, moves_todo, context=context) res.update({'invoice_state': moves_todo[0][1][6] or 'none'}) return res -stock_move() class stock_location(osv.osv): _inherit = 'stock.location' @@ -124,5 +120,4 @@ class stock_location(osv.osv): if path.location_from_id.id == location.id: return path.location_dest_id, path.auto, path.delay, path.journal_id and path.journal_id.id or False, path.company_id and path.company_id.id or False, path.picking_type, path.invoice_state return super(stock_location, self).chained_location_get(cr, uid, location, partner, product, context) -stock_location() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock_no_autopicking/stock_no_autopicking.py b/addons/stock_no_autopicking/stock_no_autopicking.py index 904854f3533..dd8fb31f59f 100644 --- a/addons/stock_no_autopicking/stock_no_autopicking.py +++ b/addons/stock_no_autopicking/stock_no_autopicking.py @@ -29,12 +29,10 @@ class product(osv.osv): _defaults = { 'auto_pick': True } -product() class mrp_production(osv.osv): _inherit = "mrp.production" def _get_auto_picking(self, cr, uid, production): return production.product_id.auto_pick -mrp_production() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/subscription/subscription.py b/addons/subscription/subscription.py index 92bde135bc6..b7ae720c187 100644 --- a/addons/subscription/subscription.py +++ b/addons/subscription/subscription.py @@ -38,7 +38,6 @@ class subscription_document(osv.osv): _defaults = { 'active' : lambda *a: True, } -subscription_document() class subscription_document_fields(osv.osv): _name = "subscription.document.fields" @@ -50,7 +49,6 @@ class subscription_document_fields(osv.osv): 'document_id': fields.many2one('subscription.document', 'Subscription Document', ondelete='cascade'), } _defaults = {} -subscription_document_fields() def _get_document_types(self, cr, uid, context=None): cr.execute('select m.model, s.name from subscription_document s, ir_model m WHERE s.model = m.id order by s.name') @@ -115,7 +113,7 @@ class subscription_subscription(osv.osv): try: (model_name, id) = row['doc_source'].split(',') id = int(id) - model = self.pool.get(model_name) + model = self.pool[model_name] except: raise osv.except_osv(_('Wrong Source Document !'), _('Please provide another source document.\nThis one does not exist !')) @@ -136,7 +134,7 @@ class subscription_subscription(osv.osv): # the subscription is over and we mark it as being done if remaining == 1: state = 'done' - id = self.pool.get(model_name).copy(cr, uid, id, default, context) + id = self.pool[model_name].copy(cr, uid, id, default, context) self.pool.get('subscription.subscription.history').create(cr, uid, {'subscription_id': row['id'], 'date':time.strftime('%Y-%m-%d %H:%M:%S'), 'document_id': model_name+','+str(id)}) self.write(cr, uid, [row['id']], {'state':state}) return True @@ -157,7 +155,6 @@ class subscription_subscription(osv.osv): def set_draft(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state':'draft'}) return True -subscription_subscription() class subscription_subscription_history(osv.osv): _name = "subscription.subscription.history" @@ -168,7 +165,6 @@ class subscription_subscription_history(osv.osv): 'subscription_id': fields.many2one('subscription.subscription', 'Subscription', ondelete='cascade'), 'document_id': fields.reference('Source Document', required=True, selection=_get_document_types, size=128), } -subscription_subscription_history() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/report/survey_analysis_report.py b/addons/survey/report/survey_analysis_report.py index b4e7765346c..581f52d49be 100644 --- a/addons/survey/report/survey_analysis_report.py +++ b/addons/survey/report/survey_analysis_report.py @@ -22,15 +22,17 @@ import time -from openerp import pooler, tools +import openerp +from openerp import tools from openerp.report import report_sxw from openerp.report.interface import report_rml from openerp.tools import to_xml class survey_analysis(report_rml): def create(self, cr, uid, ids, datas, context): - surv_obj = pooler.get_pool(cr.dbname).get('survey') - user_obj = pooler.get_pool(cr.dbname).get('res.users') + registry = openerp.registry(cr.dbname) + surv_obj = registry['survey'] + user_obj = registry['res.users'] rml_obj=report_sxw.rml_parse(cr, uid, surv_obj._name,context) company=user_obj.browse(cr,uid,[uid],context)[0].company_id diff --git a/addons/survey/report/survey_browse_response.py b/addons/survey/report/survey_browse_response.py index f910140727d..4f2dd8544e0 100644 --- a/addons/survey/report/survey_browse_response.py +++ b/addons/survey/report/survey_browse_response.py @@ -22,7 +22,8 @@ import time -from openerp import pooler, tools +import openerp +from openerp import tools from openerp.report import report_sxw from openerp.report.interface import report_rml from openerp.tools import to_xml @@ -33,6 +34,8 @@ class survey_browse_response(report_rml): _display_ans_in_rows = 5 _pageSize = ('29.7cm','21.1cm') + registry = openerp.registry(cr.dbname) + if datas.has_key('form') and datas['form'].get('orientation','') == 'vertical': if datas['form'].get('paper_size','') == 'letter': _pageSize = ('21.6cm','27.9cm') @@ -187,7 +190,7 @@ class survey_browse_response(report_rml): """ - surv_resp_obj = pooler.get_pool(cr.dbname).get('survey.response') + surv_resp_obj = registry['survey.response'] rml_obj=report_sxw.rml_parse(cr, uid, surv_resp_obj._name,context) if datas.has_key('form') and datas['form'].has_key('response_ids'): response_id = datas['form']['response_ids'] @@ -196,8 +199,8 @@ class survey_browse_response(report_rml): else: response_id = surv_resp_obj.search(cr, uid, [('survey_id', 'in', ids)]) - surv_resp_line_obj = pooler.get_pool(cr.dbname).get('survey.response.line') - surv_obj = pooler.get_pool(cr.dbname).get('survey') + surv_resp_line_obj = registry['survey.response.line'] + surv_obj = registry['survey'] for response in surv_resp_obj.browse(cr, uid, response_id): for survey in surv_obj.browse(cr, uid, [response.survey_id.id]): @@ -261,7 +264,7 @@ class survey_browse_response(report_rml): elif que.type in ['table']: if len(answer) and answer[0].state == "done": - col_heading = pooler.get_pool(cr.dbname).get('survey.tbl.column.heading') + col_heading = registry['survey.tbl.column.heading'] cols_widhts = [] tbl_width = float(_tbl_widths.replace('cm', '')) for i in range(0, len(que.column_heading_ids)): diff --git a/addons/survey/report/survey_form.py b/addons/survey/report/survey_form.py index 8375df6acaf..1868faeee03 100644 --- a/addons/survey/report/survey_form.py +++ b/addons/survey/report/survey_form.py @@ -20,7 +20,8 @@ # ############################################################################## -from openerp import pooler, tools +import openerp +from openerp import tools from openerp.report.interface import report_rml from openerp.tools import to_xml @@ -146,7 +147,7 @@ class survey_form(report_rml): """ - surv_obj = pooler.get_pool(cr.dbname).get('survey') + surv_obj = openerp.registry(cr.dbname)['survey'] for survey in surv_obj.browse(cr,uid,ids): rml += """ diff --git a/addons/survey/survey.py b/addons/survey/survey.py index 241b9739016..ad96145741b 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -25,7 +25,7 @@ from dateutil.relativedelta import relativedelta from time import strftime import os -from openerp import netsvc, tools +from openerp import tools from openerp.osv import fields, osv from openerp.tools.translate import _ @@ -36,7 +36,6 @@ class survey_type(osv.osv): 'name': fields.char("Name", size=128, required=1, translate=True), 'code': fields.char("Code", size=64), } -survey_type() class survey(osv.osv): _name = 'survey' @@ -196,7 +195,6 @@ class survey(osv.osv): 'context': context } -survey() class survey_history(osv.osv): _name = 'survey.history' @@ -210,7 +208,6 @@ class survey_history(osv.osv): _defaults = { 'date': lambda * a: datetime.datetime.now() } -survey_history() class survey_page(osv.osv): _name = 'survey.page' @@ -260,7 +257,6 @@ class survey_page(osv.osv): vals.update({'title':title}) return super(survey_page, self).copy(cr, uid, ids, vals, context=context) -survey_page() class survey_question(osv.osv): _name = 'survey.question' @@ -561,7 +557,6 @@ class survey_question(osv.osv): data['page_id']= context.get('page_id', False) return data -survey_question() class survey_question_column_heading(osv.osv): @@ -594,7 +589,6 @@ class survey_question_column_heading(osv.osv): 'in_visible_rating_weight': _get_in_visible_rating_weight, 'in_visible_menu_choice': _get_in_visible_menu_choice, } -survey_question_column_heading() class survey_answer(osv.osv): _name = 'survey.answer' @@ -651,7 +645,6 @@ class survey_answer(osv.osv): data = super(survey_answer, self).default_get(cr, uid, fields, context) return data -survey_answer() class survey_response(osv.osv): _name = "survey.response" @@ -684,7 +677,6 @@ class survey_response(osv.osv): def copy(self, cr, uid, id, default=None, context=None): raise osv.except_osv(_('Warning!'),_('You cannot duplicate the resource!')) -survey_response() class survey_response_line(osv.osv): _name = 'survey.response.line' @@ -708,7 +700,6 @@ class survey_response_line(osv.osv): 'state' : lambda * a: "draft", } -survey_response_line() class survey_tbl_column_heading(osv.osv): _name = 'survey.tbl.column.heading' @@ -720,7 +711,6 @@ class survey_tbl_column_heading(osv.osv): 'response_table_id': fields.many2one('survey.response.line', 'Answer', ondelete='cascade'), } -survey_tbl_column_heading() class survey_response_answer(osv.osv): _name = 'survey.response.answer' @@ -736,7 +726,6 @@ class survey_response_answer(osv.osv): 'comment_field': fields.char('Comment', size = 255) } -survey_response_answer() class res_users(osv.osv): _inherit = "res.users" @@ -745,7 +734,6 @@ class res_users(osv.osv): 'survey_id': fields.many2many('survey', 'survey_users_rel', 'uid', 'sid', 'Groups'), } -res_users() class survey_request(osv.osv): _name = "survey.request" @@ -786,6 +774,5 @@ class survey_request(osv.osv): return {'value': {'email': user.email}} return {} -survey_request() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py index d935eb92ade..6d473754988 100644 --- a/addons/survey/wizard/survey_answer.py +++ b/addons/survey/wizard/survey_answer.py @@ -25,8 +25,10 @@ from lxml import etree import os from time import strftime -from openerp import addons, netsvc, tools +from openerp import tools +from openerp.modules.module import get_module_resource from openerp.osv import fields, osv +import openerp.report from openerp.tools import to_xml from openerp.tools.translate import _ from openerp.tools.safe_eval import safe_eval @@ -401,16 +403,17 @@ class survey_question_wiz(osv.osv_memory): sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'}) # mark the survey request as done; call 'survey_req_done' on its actual model - survey_req_obj = self.pool.get(context.get('active_model')) - if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'): - survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context) + if context.get('active_model') in self.pool: + survey_req_obj = self.pool[context.get('active_model')] + if hasattr(survey_req_obj, 'survey_req_done'): + survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context) if sur_rec.send_response: survey_data = survey_obj.browse(cr, uid, survey_id) response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response'] report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context) attachments = {} - pdf_filename = addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf" + pdf_filename = get_module_resource('survey', 'report') + survey_data.title + ".pdf" if os.path.exists(pdf_filename): file = open(pdf_filename) file_data = "" @@ -422,7 +425,7 @@ class survey_question_wiz(osv.osv_memory): attachments[survey_data.title + ".pdf"] = file_data file.close() - os.remove(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf") + os.remove(get_module_resource('survey', 'report') + survey_data.title + ".pdf") context.update({'response_id':response_id}) user_email = user_obj.browse(cr, uid, uid, context).email resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False @@ -463,9 +466,8 @@ class survey_question_wiz(osv.osv_memory): return (False, Exception('Report name and Resources ids are required !!!')) try: uid = 1 - service = netsvc.LocalService(report_name); - (result, format) = service.create(cr, uid, res_ids, {}, context) - ret_file_name = addons.get_module_resource('survey', 'report') + file_name + '.pdf' + result, format = openerp.report.render_report(cr, uid, res_ids, report_name[len('report.'):], {}, context) + ret_file_name = get_module_resource('survey', 'report') + file_name + '.pdf' fp = open(ret_file_name, 'wb+'); fp.write(result); fp.close(); @@ -609,10 +611,10 @@ class survey_question_wiz(osv.osv_memory): survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1}) if context.has_key('cur_id'): if context.has_key('request') and context.get('request',False): - self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id}) - self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context) + self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id}) + self.pool[context.get('object')].survey_req_done(cr, uid, [int(context.get('cur_id'))], context) else: - self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id}) + self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id}) if sur_name_read['store_ans'] and type(safe_eval(sur_name_read['store_ans'])) == dict: sur_name_read['store_ans'] = safe_eval(sur_name_read['store_ans']) for key,val in sur_name_read['store_ans'].items(): @@ -1252,6 +1254,5 @@ class survey_question_wiz(osv.osv_memory): 'context': context } -survey_question_wiz() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_browse_answer.py b/addons/survey/wizard/survey_browse_answer.py index a37a4e4f7ca..1b461761bb5 100644 --- a/addons/survey/wizard/survey_browse_answer.py +++ b/addons/survey/wizard/survey_browse_answer.py @@ -55,6 +55,5 @@ class survey_browse_answer(osv.osv_memory): 'context' : context } -survey_browse_answer() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_print.py b/addons/survey/wizard/survey_print.py index 9f0b21affa6..f0e39f99cb9 100644 --- a/addons/survey/wizard/survey_print.py +++ b/addons/survey/wizard/survey_print.py @@ -63,6 +63,5 @@ class survey_print(osv.osv_memory): 'report_name': 'survey.form', 'datas': datas, } -survey_print() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_print_answer.py b/addons/survey/wizard/survey_print_answer.py index 0cadd6bf832..417d1bb732f 100644 --- a/addons/survey/wizard/survey_print_answer.py +++ b/addons/survey/wizard/survey_print_answer.py @@ -68,6 +68,5 @@ class survey_print_answer(osv.osv_memory): 'datas': datas, } -survey_print_answer() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_print_statistics.py b/addons/survey/wizard/survey_print_statistics.py index f2e25eb8d53..d005dbee31a 100644 --- a/addons/survey/wizard/survey_print_statistics.py +++ b/addons/survey/wizard/survey_print_statistics.py @@ -45,6 +45,5 @@ class survey_print_statistics(osv.osv_memory): 'datas': datas, } -survey_print_statistics() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/survey/wizard/survey_send_invitation.py b/addons/survey/wizard/survey_send_invitation.py index 4913ca09eab..ca6a8e4b15d 100644 --- a/addons/survey/wizard/survey_send_invitation.py +++ b/addons/survey/wizard/survey_send_invitation.py @@ -26,8 +26,10 @@ import os import datetime import socket -from openerp import addons, netsvc, tools +from openerp import tools +from openerp.modules.module import get_module_resource from openerp.osv import fields, osv +import openerp.report from openerp.tools.translate import _ @@ -84,9 +86,8 @@ Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'we if not report_name or not res_ids: return (False, Exception('Report name and Resources ids are required !!!')) try: - ret_file_name = addons.get_module_resource('survey', 'report') + file_name + '.pdf' - service = netsvc.LocalService(report_name); - (result, format) = service.create(cr, uid, res_ids, {}, {}) + ret_file_name = get_module_resource('survey', 'report') + file_name + '.pdf' + result, format = openerp.report.render_report(cr, uid, res_ids, report_name[len('report.'):], {}, {}) fp = open(ret_file_name, 'wb+'); fp.write(result); fp.close(); @@ -128,7 +129,7 @@ Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'we new_user.append(use.id) for id in survey_ref.browse(cr, uid, survey_ids): report = self.create_report(cr, uid, [id.id], 'report.survey.form', id.title) - file = open(addons.get_module_resource('survey', 'report') + id.title +".pdf") + file = open(get_module_resource('survey', 'report') + id.title +".pdf") file_data = "" while 1: line = file.readline() @@ -137,7 +138,7 @@ Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'we break file.close() attachments[id.title +".pdf"] = file_data - os.remove(addons.get_module_resource('survey', 'report') + id.title +".pdf") + os.remove(get_module_resource('survey', 'report') + id.title +".pdf") for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids): if not partner.email: @@ -220,7 +221,6 @@ Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'we 'target': 'new', 'context': context } -survey_send_invitation() class survey_send_invitation_log(osv.osv_memory): _name = 'survey.send.invitation.log' @@ -235,6 +235,5 @@ class survey_send_invitation_log(osv.osv_memory): data['note'] = context.get('note', '') return data -survey_send_invitation_log() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/warning/i18n/th.po b/addons/warning/i18n/th.po new file mode 100644 index 00000000000..24ae791caae --- /dev/null +++ b/addons/warning/i18n/th.po @@ -0,0 +1,215 @@ +# Thai translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-05-15 07:12+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Thai \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-05-16 05:12+0000\n" +"X-Generator: Launchpad (build 16626)\n" + +#. module: warning +#: model:ir.model,name:warning.model_purchase_order_line +#: field:product.product,purchase_line_warn:0 +msgid "Purchase Order Line" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_stock_picking_in +msgid "Incoming Shipments" +msgstr "" + +#. module: warning +#: field:product.product,purchase_line_warn_msg:0 +msgid "Message for Purchase Order Line" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_stock_picking +msgid "Picking List" +msgstr "" + +#. module: warning +#: view:product.product:0 +msgid "Warning when Purchasing this Product" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_product_product +msgid "Product" +msgstr "" + +#. module: warning +#: view:product.product:0 +#: view:res.partner:0 +msgid "Warnings" +msgstr "" + +#. module: warning +#: selection:product.product,purchase_line_warn:0 +#: selection:product.product,sale_line_warn:0 +#: selection:res.partner,invoice_warn:0 +#: selection:res.partner,picking_warn:0 +#: selection:res.partner,purchase_warn:0 +#: selection:res.partner,sale_warn:0 +msgid "Blocking Message" +msgstr "" + +#. module: warning +#: view:res.partner:0 +msgid "Warning on the Invoice" +msgstr "" + +#. module: warning +#: selection:product.product,purchase_line_warn:0 +#: selection:product.product,sale_line_warn:0 +#: selection:res.partner,invoice_warn:0 +#: selection:res.partner,picking_warn:0 +#: selection:res.partner,purchase_warn:0 +#: selection:res.partner,sale_warn:0 +msgid "No Message" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_account_invoice +#: field:res.partner,invoice_warn:0 +msgid "Invoice" +msgstr "" + +#. module: warning +#: view:product.product:0 +msgid "Warning when Selling this Product" +msgstr "" + +#. module: warning +#: field:res.partner,picking_warn:0 +msgid "Stock Picking" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_purchase_order +#: field:res.partner,purchase_warn:0 +msgid "Purchase Order" +msgstr "" + +#. module: warning +#: field:res.partner,purchase_warn_msg:0 +msgid "Message for Purchase Order" +msgstr "" + +#. module: warning +#: code:addons/warning/warning.py:32 +#: help:product.product,purchase_line_warn:0 +#: help:product.product,sale_line_warn:0 +#: help:res.partner,invoice_warn:0 +#: help:res.partner,picking_warn:0 +#: help:res.partner,purchase_warn:0 +#: help:res.partner,sale_warn:0 +#, python-format +msgid "" +"Selecting the \"Warning\" option will notify user with the message, " +"Selecting \"Blocking Message\" will throw an exception with the message and " +"block the flow. The Message has to be written in the next field." +msgstr "" + +#. module: warning +#: code:addons/warning/warning.py:67 +#: code:addons/warning/warning.py:96 +#: code:addons/warning/warning.py:130 +#: code:addons/warning/warning.py:162 +#: code:addons/warning/warning.py:192 +#: code:addons/warning/warning.py:218 +#: code:addons/warning/warning.py:266 +#: code:addons/warning/warning.py:299 +#, python-format +msgid "Alert for %s !" +msgstr "" + +#. module: warning +#: view:res.partner:0 +msgid "Warning on the Sales Order" +msgstr "" + +#. module: warning +#: field:res.partner,invoice_warn_msg:0 +msgid "Message for Invoice" +msgstr "" + +#. module: warning +#: field:res.partner,sale_warn_msg:0 +msgid "Message for Sales Order" +msgstr "" + +#. module: warning +#: view:res.partner:0 +msgid "Warning on the Picking" +msgstr "" + +#. module: warning +#: view:res.partner:0 +msgid "Warning on the Purchase Order" +msgstr "" + +#. module: warning +#: code:addons/warning/warning.py:68 +#: code:addons/warning/warning.py:97 +#: code:addons/warning/warning.py:132 +#: code:addons/warning/warning.py:163 +#: code:addons/warning/warning.py:193 +#: code:addons/warning/warning.py:219 +#: code:addons/warning/warning.py:267 +#: code:addons/warning/warning.py:300 +#, python-format +msgid "Warning for %s" +msgstr "" + +#. module: warning +#: field:product.product,sale_line_warn_msg:0 +msgid "Message for Sales Order Line" +msgstr "" + +#. module: warning +#: selection:product.product,purchase_line_warn:0 +#: selection:product.product,sale_line_warn:0 +#: selection:res.partner,invoice_warn:0 +#: selection:res.partner,picking_warn:0 +#: selection:res.partner,purchase_warn:0 +#: selection:res.partner,sale_warn:0 +msgid "Warning" +msgstr "" + +#. module: warning +#: field:res.partner,picking_warn_msg:0 +msgid "Message for Stock Picking" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_res_partner +msgid "Partner" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_sale_order +#: field:res.partner,sale_warn:0 +msgid "Sales Order" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_stock_picking_out +msgid "Delivery Orders" +msgstr "" + +#. module: warning +#: model:ir.model,name:warning.model_sale_order_line +#: field:product.product,sale_line_warn:0 +msgid "Sales Order Line" +msgstr "" diff --git a/addons/warning/warning.py b/addons/warning/warning.py index 4bdada396bc..e9e9161bacb 100644 --- a/addons/warning/warning.py +++ b/addons/warning/warning.py @@ -50,7 +50,6 @@ class res_partner(osv.osv): 'invoice_warn' : 'no-message', } -res_partner() class sale_order(osv.osv): @@ -79,7 +78,6 @@ class sale_order(osv.osv): warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message'] return {'value': result.get('value',{}), 'warning':warning} -sale_order() class purchase_order(osv.osv): @@ -108,7 +106,6 @@ class purchase_order(osv.osv): return {'value': result.get('value',{}), 'warning':warning} -purchase_order() class account_invoice(osv.osv): @@ -145,7 +142,6 @@ class account_invoice(osv.osv): return {'value': result.get('value',{}), 'warning':warning} -account_invoice() class stock_picking(osv.osv): _inherit = 'stock.picking' @@ -173,7 +169,6 @@ class stock_picking(osv.osv): return {'value': result.get('value',{}), 'warning':warning} -stock_picking() # FIXME:(class stock_picking_in and stock_picking_out) this is a temporary workaround because of a framework bug (ref: lp:996816). # It should be removed as soon as the bug is fixed @@ -243,7 +238,6 @@ class product_product(osv.osv): 'purchase_line_warn' : 'no-message', } -product_product() class sale_order_line(osv.osv): _inherit = 'sale.order.line' @@ -279,7 +273,6 @@ class sale_order_line(osv.osv): return {'value': result.get('value',{}), 'warning':warning} -sale_order_line() class purchase_order_line(osv.osv): _inherit = 'purchase.order.line' @@ -311,7 +304,6 @@ class purchase_order_line(osv.osv): return {'value': result.get('value',{}), 'warning':warning} -purchase_order_line() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/web_linkedin/i18n/cs.po b/addons/web_linkedin/i18n/cs.po new file mode 100644 index 00000000000..6057606cdf4 --- /dev/null +++ b/addons/web_linkedin/i18n/cs.po @@ -0,0 +1,137 @@ +# Czech translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-03-30 21:01+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-03-31 05:28+0000\n" +"X-Generator: Launchpad (build 16546)\n" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "here:" +msgstr "" + +#. module: web_linkedin +#: field:sale.config.settings,api_key:0 +msgid "API Key" +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/js/linkedin.js:249 +#, python-format +msgid "No results found" +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/js/linkedin.js:84 +#, python-format +msgid "Ok" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "Log into LinkedIn." +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/xml/linkedin.xml:13 +#, python-format +msgid "People" +msgstr "" + +#. module: web_linkedin +#: model:ir.model,name:web_linkedin.model_sale_config_settings +msgid "sale.config.settings" +msgstr "" + +#. module: web_linkedin +#: field:sale.config.settings,server_domain:0 +msgid "unknown" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "https://www.linkedin.com/secure/developer" +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/xml/linkedin.xml:15 +#, python-format +msgid "Companies" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "API key" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "Copy the" +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/js/linkedin.js:181 +#, python-format +msgid "LinkedIn search" +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/xml/linkedin.xml:31 +#, python-format +msgid "" +"LinkedIn access was not enabled on this server.\n" +" Please ask your administrator to configure it in Settings > " +"Configuration > Sales > Social Network Integration." +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "" +"To use the LinkedIn module with this database, an API Key is required. " +"Please follow this procedure:" +msgstr "" + +#. module: web_linkedin +#. openerp-web +#: code:addons/web_linkedin/static/src/js/linkedin.js:82 +#, python-format +msgid "LinkedIn is not enabled" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "Add a new application and fill the form:" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "Go to this URL:" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "The programming tool is Javascript" +msgstr "" + +#. module: web_linkedin +#: view:sale.config.settings:0 +msgid "JavaScript API Domain:" +msgstr "" diff --git a/addons/web_shortcuts/i18n/lt.po b/addons/web_shortcuts/i18n/lt.po new file mode 100644 index 00000000000..70fc0a04b6c --- /dev/null +++ b/addons/web_shortcuts/i18n/lt.po @@ -0,0 +1,25 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:06+0000\n" +"PO-Revision-Date: 2013-04-24 18:29+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n" +"X-Generator: Launchpad (build 16580)\n" + +#. module: web_shortcuts +#. openerp-web +#: code:addons/web_shortcuts/static/src/xml/web_shortcuts.xml:21 +#, python-format +msgid "Add / Remove Shortcut..." +msgstr "Pridėti / pašalinti trumpinį..." diff --git a/addons/web_shortcuts/static/src/css/web_shortcuts.css b/addons/web_shortcuts/static/src/css/web_shortcuts.css index 8424e146d06..5d4e34f53b9 100644 --- a/addons/web_shortcuts/static/src/css/web_shortcuts.css +++ b/addons/web_shortcuts/static/src/css/web_shortcuts.css @@ -54,4 +54,7 @@ border-left: none; padding-left: 0; } - +.oe_systray_shortcuts_items > li > a:hover { + overflow:visible; + white-space: normal; +} \ No newline at end of file
- +