diff --git a/addons/account/account.py b/addons/account/account.py
index 1a44e480e03..3959799f1bb 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -132,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"
@@ -198,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')
@@ -212,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"
@@ -697,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"
@@ -849,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"
@@ -945,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"
@@ -1007,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']))
@@ -1016,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:
@@ -1071,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"
@@ -1128,7 +1120,6 @@ class account_journal_period(osv.osv):
}
_order = "period_id"
-account_journal_period()
class account_fiscalyear(osv.osv):
_inherit = "account.fiscalyear"
@@ -1145,7 +1136,6 @@ class account_fiscalyear(osv.osv):
})
return super(account_fiscalyear, self).copy(cr, uid, id, default=default, context=context)
-account_fiscalyear()
#----------------------------------------------------------
# Entries
#----------------------------------------------------------
@@ -1223,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]
@@ -1384,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):
@@ -1420,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({
@@ -1641,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"
@@ -1715,7 +1706,6 @@ class account_move_reconcile(osv.osv):
result.append((r.id,r.name))
return result
-account_move_reconcile()
#----------------------------------------------------------
# Tax
@@ -1795,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]
@@ -1863,7 +1853,6 @@ class account_tax_code(osv.osv):
]
_order = 'code'
-account_tax_code()
class account_tax(osv.osv):
"""
@@ -2271,7 +2260,6 @@ class account_tax(osv.osv):
total += r['amount']
return res
-account_tax()
# ---------------------------------------------------------
# Account Entries Models
@@ -2383,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"
@@ -2407,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
@@ -2481,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"
@@ -2510,7 +2495,6 @@ class account_subscription_line(osv.osv):
_rec_name = 'date'
-account_subscription_line()
# ---------------------------------------------------------------
# Account Templates: Account, Tax, Tax Code and chart. + Wizard
@@ -2518,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"
@@ -2646,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.
@@ -2700,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):
@@ -2772,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):
@@ -2805,7 +2785,6 @@ class account_chart_template(osv.osv):
'complete_tax_set': True,
}
-account_chart_template()
class account_tax_template(osv.osv):
@@ -2935,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
@@ -2983,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'
@@ -2996,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'
@@ -3008,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
@@ -3401,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:
@@ -3548,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'
@@ -3560,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 e8b58f61882..0c2e5845b89 100644
--- a/addons/account/account_financial_report.py
+++ b/addons/account/account_financial_report.py
@@ -138,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_invoice.py b/addons/account/account_invoice.py
index 222a0bebbb4..c47cf70b673 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -286,7 +286,10 @@ class account_invoice(osv.osv):
'payment_ids': fields.function(_compute_lines, relation='account.move.line', type="many2many", string='Payments'),
'move_name': fields.char('Journal Entry', size=64, readonly=True, states={'draft':[('readonly',False)]}),
'user_id': fields.many2one('res.users', 'Salesperson', readonly=True, track_visibility='onchange', states={'draft':[('readonly',False)]}),
- 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]})
+ 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]}),
+ 'commercial_partner_id': fields.related('partner_id', 'commercial_partner_id', string='Commercial Entity', type='many2one',
+ relation='res.partner', store=True, readonly=True,
+ help="The commercial entity that will be used on Journal Entries for this invoice")
}
_defaults = {
'type': _get_type,
@@ -313,7 +316,7 @@ class account_invoice(osv.osv):
context = {}
if context.get('active_model', '') in ['res.partner'] and context.get('active_ids', False) and context['active_ids']:
- partner = self.pool.get(context['active_model']).read(cr, uid, context['active_ids'], ['supplier','customer'])[0]
+ partner = self.pool[context['active_model']].read(cr, uid, context['active_ids'], ['supplier','customer'])[0]
if not view_type:
view_id = self.pool.get('ir.ui.view').search(cr, uid, [('name', '=', 'account.invoice.tree')])
view_type = 'tree'
@@ -367,18 +370,6 @@ class account_invoice(osv.osv):
context['view_id'] = view_id
return context
- def create(self, cr, uid, vals, context=None):
- if context is None:
- context = {}
- try:
- return super(account_invoice, self).create(cr, uid, vals, context)
- except Exception, e:
- if '"journal_id" viol' in e.args[0]:
- raise orm.except_orm(_('Configuration Error!'),
- _('There is no Sale/Purchase Journal(s) defined.'))
- else:
- raise orm.except_orm(_('Unknown Error!'), str(e))
-
def invoice_print(self, cr, uid, ids, context=None):
'''
This function prints the invoice and mark it as sent, so that we can see more easily the next step of the workflow
@@ -997,8 +988,7 @@ class account_invoice(osv.osv):
'narration':inv.comment
}
period_id = inv.period_id and inv.period_id.id or False
- ctx.update(company_id=inv.company_id.id,
- account_period_prefer_normal=True)
+ ctx.update(company_id=inv.company_id.id)
if not period_id:
period_ids = period_obj.find(cr, uid, inv.date_invoice, context=ctx)
period_id = period_ids and period_ids[0] or False
@@ -1274,9 +1264,7 @@ class account_invoice(osv.osv):
ref = invoice.reference
else:
ref = self._convert_ref(cr, uid, invoice.number)
- partner = invoice.partner_id
- if partner.parent_id and not partner.is_company:
- partner = partner.parent_id
+ partner = self.pool['res.partner']._find_accounting_partner(invoice.partner_id)
# Pay attention to the sign for both debit/credit AND amount_currency
l1 = {
'debit': direction * pay_amount>0 and direction * pay_amount,
@@ -1596,7 +1584,6 @@ class account_invoice_line(osv.osv):
unique_tax_ids = product_change_result['value']['invoice_line_tax_id']
return {'value':{'invoice_line_tax_id': unique_tax_ids}}
-account_invoice_line()
class account_invoice_tax(osv.osv):
_name = "account.invoice.tax"
@@ -1747,15 +1734,11 @@ class res_partner(osv.osv):
'invoice_ids': fields.one2many('account.invoice.line', 'partner_id', 'Invoices', readonly=True),
}
- def _find_accounting_partner(self, part):
+ def _find_accounting_partner(self, partner):
'''
Find the partner for which the accounting entries will be created
'''
- #if the chosen partner is not a company and has a parent company, use the parent for the journal entries
- #because you want to invoice 'Agrolait, accounting department' but the journal items are for 'Agrolait'
- if part.parent_id and not part.is_company:
- part = part.parent_id
- return part
+ return partner.commercial_partner_id
def copy(self, cr, uid, id, default=None, context=None):
default = default or {}
diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index c2f21c0d8bc..7469c38decb 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -117,6 +117,7 @@
+
@@ -320,7 +321,8 @@
+ options='{"always_reload": True}'
+ domain="[('customer', '=', True)]"/>
@@ -447,19 +449,20 @@
account.invoice
-
+
-
+
-
+
+
@@ -622,8 +625,6 @@
-
-
-
+
@@ -1194,7 +1194,12 @@
sequence="1"
groups="group_account_user"
/>
-
+
+ Journal Items
+ account.move.line
+ {'search_default_partner_id': [active_id], 'default_partner_id': active_id}
+
+ account.move.line
@@ -1288,7 +1293,7 @@
-
+
@@ -1352,7 +1357,7 @@
-
+
@@ -1771,23 +1776,6 @@
-
-
-
-
-
\n"
" "
msgstr ""
+"
\n"
+" Klik om een journaal toe te voegen.\n"
+"
\n"
+" Een journaal groepeert boekingen in functie\n"
+" van de dagelijkse bezigheden.\n"
+"
\n"
+" Een firma geruikt doorgaans een journaal per betaalmethode "
+"(kas,\n"
+" bankrekeningen, cheques), een aankoopdagboek, een "
+"verkoopdagboek\n"
+" en een diversendagboek.\n"
+"
\n"
+" "
#. module: account
#: model:ir.model,name:account.model_account_fiscalyear_close_state
@@ -9276,6 +9405,9 @@ msgid ""
"computed. Because it is space consuming, we do not allow to use it while "
"doing a comparison."
msgstr ""
+"Met deze optie krijgt u meer details over de manier waarop de saldi worden "
+"berekend. Omdat dit ruimte inneemt, is deze optie niet mogelijk bij "
+"vergelijkingen."
#. module: account
#: model:ir.model,name:account.model_account_fiscalyear_close
@@ -9292,6 +9424,8 @@ msgstr "De code van de rekening moet uniek zijn per firma."
#: help:product.template,property_account_expense:0
msgid "This account will be used to value outgoing stock using cost price."
msgstr ""
+"Deze rekening dient voor de voorraadwaardering van de uitgaande voorraad op "
+"basis van de kostprijs."
#. module: account
#: view:account.invoice:0
@@ -9354,6 +9488,17 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik als u een nieuwe recurrente boeking wilt maken.\n"
+"
\n"
+" Een terugkerende boeking wordt regelmatig op een bepaald "
+"tijdstip herhaald,\n"
+" vb. bij vervallen van een contract of overeenkomst met een\n"
+" klant of een leverancier. U kunt dergelijke boekingen "
+"voorbereiden\n"
+" zodat deze automatisch worden geboekt.\n"
+"
\n"
+" "
#. module: account
#: view:account.journal:0
@@ -9396,6 +9541,8 @@ msgid ""
"This allows you to check writing and printing.\n"
" This installs the module account_check_writing."
msgstr ""
+"Hiermee kunt u cheques schrijven en afdrukken.\n"
+" Hiermee wordt de module account_check_writing geïnstalleerd."
#. module: account
#: model:res.groups,name:account.group_account_invoice
@@ -9681,6 +9828,9 @@ msgid ""
"chart\n"
" of accounts."
msgstr ""
+"Bevestigde facturen kunnen niet meer\n"
+" worden gewijzigd. Facturen krijgen een uniek nummer\n"
+" en de boekingen worden gemaakt."
#. module: account
#: model:process.node,note:account.process_node_bankstatement0
@@ -9906,11 +10056,15 @@ msgid ""
"payments.\n"
" This installs the module account_payment."
msgstr ""
+"Hiermee kunt u betaalopdrachten maken\n"
+" * die als basis dienen voor verdere automatisering,\n"
+" * om efficiënter betalingen te kunnen uitvoeren.\n"
+" Hiermee wordt de module account_payment geïnstalleerd."
#. module: account
#: xsl:account.transfer:0
msgid "Document"
-msgstr ""
+msgstr "Document"
#. module: account
#: view:account.chart.template:0
@@ -10132,7 +10286,7 @@ msgstr "Kan geen boekingen maken tussen verschillende firma's."
#. module: account
#: model:ir.ui.menu,name:account.menu_finance_periodical_processing
msgid "Periodic Processing"
-msgstr ""
+msgstr "Periodieke verwerking"
#. module: account
#: view:account.invoice.report:0
@@ -10212,7 +10366,7 @@ msgstr "Vervaldatum"
#: model:account.payment.term,name:account.account_payment_term_immediate
#: model:account.payment.term,note:account.account_payment_term_immediate
msgid "Immediate Payment"
-msgstr ""
+msgstr "Contante betaling"
#. module: account
#: code:addons/account/account.py:1464
@@ -10424,11 +10578,16 @@ msgid ""
"analytic account.\n"
" This installs the module account_budget."
msgstr ""
+"Hiermee kunnen accountants budgetten beheren.\n"
+" Als de hoofdbudgetten zijn ingesteld, kunnen de "
+"projectleiders\n"
+" het geplande bedrag instellen per analytische rekening.\n"
+" Hiermee wordt de module account_budget geïnstalleerd."
#. module: account
#: field:account.bank.statement.line,name:0
msgid "OBI"
-msgstr ""
+msgstr "Omschrijving"
#. module: account
#: help:res.partner,property_account_payable:0
@@ -10915,6 +11074,8 @@ msgid ""
"If you unreconcile transactions, you must also verify all the actions that "
"are linked to those transactions because they will not be disable"
msgstr ""
+"Als u afgepunte transacties ongedaan maakt, moet u alle gekoppelde acties "
+"nakijken, want deze worden niet ongedaan gemaakt."
#. module: account
#: code:addons/account/account_move_line.py:1059
@@ -10949,6 +11110,9 @@ msgid ""
"customer. The tool search can also be used to personalise your Invoices "
"reports and so, match this analysis to your needs."
msgstr ""
+"Dit rapport biedt een overzicht van het bedrag gefactureerd aan uw klant. De "
+"zoekfunctie kan worden aangepast om het overzicht van uw facturen te "
+"personaliseren, zodat u de gewenste analyse krijgt."
#. module: account
#: view:account.partner.reconcile.process:0
@@ -11207,6 +11371,16 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik als u een nieuw btw-vak wilt toevoegen.\n"
+"
\n"
+" Afhankelijk van uw land, dient een btw-vak om uw btw-"
+"aangifte in te vullen.\n"
+" In OpenERP kunt u een btw-structuur instellen en elke btw-"
+"berekening\n"
+" kan in een of meer btw-vakken worden opgenomen.\n"
+"
\n"
+" Selecteer de periode en het journaal.\n"
+"
\n"
+" Hiermee kan de boekhouder in een sneltempo boekingen "
+"invoeren in\n"
+" OpenERP. Als u een aankoopfactuur wilt inboeken,\n"
+" begint u met de kostenrekening. OpenERP stelt automatisch\n"
+" de betrokken btw voor die is gekoppeld aan deze rekening, "
+"net\n"
+" als de centralisatierekening.\n"
+"
\n"
+" "
#. module: account
#: help:account.invoice.line,account_id:0
@@ -11403,7 +11589,7 @@ msgstr "Rekeningmodel"
#: code:addons/account/account_cash_statement.py:292
#, python-format
msgid "Loss"
-msgstr ""
+msgstr "Verlies"
#. module: account
#: selection:account.entries.report,month:0
@@ -11475,7 +11661,7 @@ msgstr "Kostenrekening van productsjabloon"
#. module: account
#: field:res.partner,property_payment_term:0
msgid "Customer Payment Term"
-msgstr ""
+msgstr "Betaaltermijn klant"
#. module: account
#: help:accounting.report,label_filter:0
diff --git a/addons/account/i18n/pt_BR.po b/addons/account/i18n/pt_BR.po
index ba985c5e0a8..d1816589139 100644
--- a/addons/account/i18n/pt_BR.po
+++ b/addons/account/i18n/pt_BR.po
@@ -7,15 +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-12-22 23:17+0000\n"
-"Last-Translator: Fábio Martinelli - http://zupy.com.br "
-"\n"
+"PO-Revision-Date: 2013-04-18 17:44+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:19+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: account
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
@@ -431,7 +430,7 @@ msgstr "Data de criação"
#. module: account
#: selection:account.journal,type:0
msgid "Purchase Refund"
-msgstr "Devolução da Venda"
+msgstr "Devolução de Compra"
#. module: account
#: selection:account.journal,type:0
@@ -12678,13 +12677,6 @@ msgstr ""
#~ msgid "This period is already closed !"
#~ msgstr "Este período já está fechado"
-#, python-format
-#~ msgid ""
-#~ "Selected Move lines does not have any account move enties in draft state"
-#~ msgstr ""
-#~ "As linhas do movimento selecionado nao tem nenhuma conta a ser movida para o "
-#~ "estado de esboço"
-
#~ msgid "Unpaid Customer Refunds"
#~ msgstr "Reembolsos a clientes não pagos"
@@ -13232,6 +13224,13 @@ msgstr ""
#~ msgid "Can not %s draft/proforma/cancel invoice."
#~ msgstr "Não pode %s provisório/proforma/cancelar fatura."
+#, python-format
+#~ msgid ""
+#~ "Selected Move lines does not have any account move enties in draft state"
+#~ msgstr ""
+#~ "As linhas de movimento selecionadas não tem nenhum movimento nesta conta no "
+#~ "modo provisório"
+
#, python-format
#~ msgid "Can not pay draft/proforma/cancel invoice."
#~ msgstr "Não se pode pagar uma fatura provisória/proforma/cancelada"
diff --git a/addons/account/i18n/zh_CN.po b/addons/account/i18n/zh_CN.po
index ff84dd866e8..0e216ddb68f 100644
--- a/addons/account/i18n/zh_CN.po
+++ b/addons/account/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: 2013-01-30 03:58+0000\n"
-"Last-Translator: Wei \"oldrev\" Li \n"
+"PO-Revision-Date: 2013-04-25 09:04+0000\n"
+"Last-Translator: Oliver Yuan \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:20+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-26 05:34+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
#. module: account
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
@@ -10748,7 +10748,7 @@ msgstr "手动的发票税(非主营业务纳税)"
#: code:addons/account/account_invoice.py:550
#, python-format
msgid "The payment term of supplier does not have a payment term line."
-msgstr ""
+msgstr "供应商付款条件没有包含付款条件行"
#. module: account
#: field:account.account,parent_right:0
diff --git a/addons/account/installer.py b/addons/account/installer.py
index c00b80071b8..537371d0f64 100644
--- a/addons/account/installer.py
+++ b/addons/account/installer.py
@@ -23,10 +23,16 @@ import datetime
from dateutil.relativedelta import relativedelta
import logging
from operator import itemgetter
-from os.path import join as opj
import time
+import urllib2
+import urlparse
-from openerp import tools
+try:
+ import simplejson as json
+except ImportError:
+ import json # noqa
+
+from openerp.release import serie
from openerp.tools.translate import _
from openerp.osv import fields, osv
@@ -38,13 +44,28 @@ class account_installer(osv.osv_memory):
def _get_charts(self, cr, uid, context=None):
modules = self.pool.get('ir.module.module')
+
+ # try get the list on apps server
+ try:
+ apps_server = self.pool.get('ir.config_parameter').get_param(cr, uid, 'apps.server', 'https://apps.openerp.com')
+
+ up = urlparse.urlparse(apps_server)
+ url = '{0.scheme}://{0.netloc}/apps/charts?serie={1}'.format(up, serie)
+
+ j = urllib2.urlopen(url, timeout=3).read()
+ apps_charts = json.loads(j)
+
+ charts = dict(apps_charts)
+ except Exception:
+ charts = dict()
+
# Looking for the module with the 'Account Charts' category
category_name, category_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'module_category_localization_account_charts')
ids = modules.search(cr, uid, [('category_id', '=', category_id)], context=context)
- charts = list(
- sorted(((m.name, m.shortdesc)
- for m in modules.browse(cr, uid, ids, context=context)),
- key=itemgetter(1)))
+ if ids:
+ charts.update((m.name, m.shortdesc) for m in modules.browse(cr, uid, ids, context=context))
+
+ charts = sorted(charts.items(), key=itemgetter(1))
charts.insert(0, ('configurable', _('Custom')))
return charts
@@ -57,9 +78,9 @@ class account_installer(osv.osv_memory):
"country."),
'date_start': fields.date('Start Date', required=True),
'date_stop': fields.date('End Date', required=True),
- 'period': fields.selection([('month', 'Monthly'), ('3months','3 Monthly')], 'Periods', required=True),
+ 'period': fields.selection([('month', 'Monthly'), ('3months', '3 Monthly')], 'Periods', required=True),
'company_id': fields.many2one('res.company', 'Company', required=True),
- 'has_default_company' : fields.boolean('Has Default Company', readonly=True),
+ 'has_default_company': fields.boolean('Has Default Company', readonly=True),
}
def _default_company(self, cr, uid, context=None):
@@ -78,30 +99,29 @@ class account_installer(osv.osv_memory):
'has_default_company': _default_has_default_company,
'charts': 'configurable'
}
-
+
def get_unconfigured_cmp(self, cr, uid, context=None):
""" get the list of companies that have not been configured yet
but don't care about the demo chart of accounts """
- cmp_select = []
company_ids = self.pool.get('res.company').search(cr, uid, [], context=context)
cr.execute("SELECT company_id FROM account_account WHERE active = 't' AND account_account.parent_id IS NULL AND name != %s", ("Chart For Automated Tests",))
configured_cmp = [r[0] for r in cr.fetchall()]
return list(set(company_ids)-set(configured_cmp))
-
+
def check_unconfigured_cmp(self, cr, uid, context=None):
""" check if there are still unconfigured companies """
if not self.get_unconfigured_cmp(cr, uid, context=context):
raise osv.except_osv(_('No unconfigured company !'), _("There is currently no company without chart of account. The wizard will therefore not be executed."))
-
+
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
- if context is None:context = {}
- res = super(account_installer, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
+ if context is None: context = {}
+ res = super(account_installer, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
cmp_select = []
# display in the widget selection only the companies that haven't been configured yet
unconfigured_cmp = self.get_unconfigured_cmp(cr, uid, context=context)
for field in res['fields']:
if field == 'company_id':
- res['fields'][field]['domain'] = [('id','in',unconfigured_cmp)]
+ res['fields'][field]['domain'] = [('id', 'in', unconfigured_cmp)]
res['fields'][field]['selection'] = [('', '')]
if unconfigured_cmp:
cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, unconfigured_cmp)]
@@ -117,7 +137,7 @@ class account_installer(osv.osv_memory):
def execute(self, cr, uid, ids, context=None):
self.execute_simple(cr, uid, ids, context)
- super(account_installer, self).execute(cr, uid, ids, context=context)
+ return super(account_installer, self).execute(cr, uid, ids, context=context)
def execute_simple(self, cr, uid, ids, context=None):
if context is None:
@@ -129,8 +149,8 @@ class account_installer(osv.osv_memory):
if not f_ids:
name = code = res['date_start'][:4]
if int(name) != int(res['date_stop'][:4]):
- name = res['date_start'][:4] +'-'+ res['date_stop'][:4]
- code = res['date_start'][2:4] +'-'+ res['date_stop'][2:4]
+ name = res['date_start'][:4] + '-' + res['date_stop'][:4]
+ code = res['date_start'][2:4] + '-' + res['date_stop'][2:4]
vals = {
'name': name,
'code': code,
@@ -150,8 +170,7 @@ class account_installer(osv.osv_memory):
chart = self.read(cr, uid, ids, ['charts'],
context=context)[0]['charts']
_logger.debug('Installing chart of accounts %s', chart)
- return modules | set([chart])
+ return (modules | set([chart])) - set(['has_default_company', 'configurable'])
-account_installer()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/ir_sequence.py b/addons/account/ir_sequence.py
index 56e1a4d0367..d3615a847b7 100644
--- a/addons/account/ir_sequence.py
+++ b/addons/account/ir_sequence.py
@@ -38,7 +38,6 @@ class ir_sequence_fiscalyear(osv.osv):
'Main Sequence must be different from current !'),
]
-ir_sequence_fiscalyear()
class ir_sequence(osv.osv):
_inherit = 'ir.sequence'
@@ -56,6 +55,5 @@ class ir_sequence(osv.osv):
return super(ir_sequence, self)._next(cr, uid, [line.sequence_id.id], context)
return super(ir_sequence, self)._next(cr, uid, seq_ids, context)
-ir_sequence()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/partner.py b/addons/account/partner.py
index ae8d2fc1871..f582da6b765 100644
--- a/addons/account/partner.py
+++ b/addons/account/partner.py
@@ -66,7 +66,6 @@ class account_fiscal_position(osv.osv):
break
return account_id
-account_fiscal_position()
class account_fiscal_position_tax(osv.osv):
_name = 'account.fiscal.position.tax'
@@ -84,7 +83,6 @@ class account_fiscal_position_tax(osv.osv):
'A tax fiscal position could be defined only once time on same taxes.')
]
-account_fiscal_position_tax()
class account_fiscal_position_account(osv.osv):
_name = 'account.fiscal.position.account'
@@ -102,7 +100,6 @@ class account_fiscal_position_account(osv.osv):
'An account fiscal position could be defined only once time on same accounts.')
]
-account_fiscal_position_account()
class res_partner(osv.osv):
_name = 'res.partner'
@@ -236,6 +233,10 @@ class res_partner(osv.osv):
'last_reconciliation_date': fields.datetime('Latest Full Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the last date where a reconciliation has been made for this partner, as here we depict the fact that nothing more was to be reconciled at this date. This can be achieved in 2 different ways: either the last unreconciled debit/credit entry of this partner was reconciled, either the user pressed the button "Nothing more to reconcile" during the manual reconciliation process.')
}
-res_partner()
+ def _commercial_fields(self, cr, uid, context=None):
+ return super(res_partner, self)._commercial_fields(cr, uid, context=context) + \
+ ['debit_limit', 'property_account_payable', 'property_account_receivable', 'property_account_position',
+ 'property_payment_term', 'property_supplier_payment_term', 'last_reconciliation_date']
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml
index 1267e20165b..b6fae3140b5 100644
--- a/addons/account/partner_view.xml
+++ b/addons/account/partner_view.xml
@@ -50,6 +50,29 @@
+
+ {'search_default_partner_id': [active_id], 'default_partner_id': active_id}
+ Contracts/Analytic Accounts
+ account.analytic.account
+ tree,form
+
+
+ partner.view.buttons
+ res.partner
+
+
+
+
+
+
+
+
+
+
+
Fiscal Positionsaccount.fiscal.position
@@ -73,7 +96,7 @@
-
+
@@ -103,20 +126,13 @@
+
+
+
Accounting-related settings are managed on
+
+
-
-
-
-
-
diff --git a/addons/account/product.py b/addons/account/product.py
index ce1ac83d6dd..3df3ad9bd17 100644
--- a/addons/account/product.py
+++ b/addons/account/product.py
@@ -39,7 +39,6 @@ class product_category(osv.osv):
view_load=True,
help="This account will be used for invoices to value expenses."),
}
-product_category()
#----------------------------------------------------------
# Products
@@ -70,6 +69,5 @@ class product_template(osv.osv):
help="This account will be used for invoices instead of the default one to value expenses for the current product."),
}
-product_template()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/project.py b/addons/account/project/project.py
index f4927331ca8..b4dcdde2d30 100644
--- a/addons/account/project/project.py
+++ b/addons/account/project/project.py
@@ -38,7 +38,6 @@ class account_analytic_journal(osv.osv):
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
}
-account_analytic_journal()
class account_journal(osv.osv):
_inherit="account.journal"
@@ -47,6 +46,5 @@ class account_journal(osv.osv):
'analytic_journal_id':fields.many2one('account.analytic.journal','Analytic Journal', help="Journal for analytic entries"),
}
-account_journal()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/project_view.xml b/addons/account/project/project_view.xml
index aa567d2fc79..79a1e76c7e7 100644
--- a/addons/account/project/project_view.xml
+++ b/addons/account/project/project_view.xml
@@ -31,7 +31,7 @@
-
+
diff --git a/addons/account/project/wizard/account_analytic_balance_report.py b/addons/account/project/wizard/account_analytic_balance_report.py
index 81d6c192962..02b2eb6e95d 100644
--- a/addons/account/project/wizard/account_analytic_balance_report.py
+++ b/addons/account/project/wizard/account_analytic_balance_report.py
@@ -52,7 +52,6 @@ class account_analytic_balance(osv.osv_memory):
'datas': datas,
}
-account_analytic_balance()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_chart.py b/addons/account/project/wizard/account_analytic_chart.py
index 01c606d5f08..4a26eec7c95 100644
--- a/addons/account/project/wizard/account_analytic_chart.py
+++ b/addons/account/project/wizard/account_analytic_chart.py
@@ -46,5 +46,4 @@ class account_analytic_chart(osv.osv_memory):
result['context'] = str(result_context)
return result
-account_analytic_chart()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py b/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
index fdb8eafb402..814cbb8cacc 100644
--- a/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
+++ b/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
@@ -52,5 +52,4 @@ class account_analytic_cost_ledger_journal_report(osv.osv_memory):
'datas': datas,
}
-account_analytic_cost_ledger_journal_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_cost_ledger_report.py b/addons/account/project/wizard/account_analytic_cost_ledger_report.py
index 1c74c61e31f..ffd56352382 100644
--- a/addons/account/project/wizard/account_analytic_cost_ledger_report.py
+++ b/addons/account/project/wizard/account_analytic_cost_ledger_report.py
@@ -52,5 +52,4 @@ class account_analytic_cost_ledger(osv.osv_memory):
'datas': datas,
}
-account_analytic_cost_ledger()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_inverted_balance_report.py b/addons/account/project/wizard/account_analytic_inverted_balance_report.py
index 10f97baf755..9e54f4f848d 100644
--- a/addons/account/project/wizard/account_analytic_inverted_balance_report.py
+++ b/addons/account/project/wizard/account_analytic_inverted_balance_report.py
@@ -51,5 +51,4 @@ class account_analytic_inverted_balance(osv.osv_memory):
'datas': datas,
}
-account_analytic_inverted_balance()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_journal_report.py b/addons/account/project/wizard/account_analytic_journal_report.py
index e70649cd406..61fe2cd318a 100644
--- a/addons/account/project/wizard/account_analytic_journal_report.py
+++ b/addons/account/project/wizard/account_analytic_journal_report.py
@@ -71,5 +71,4 @@ class account_analytic_journal_report(osv.osv_memory):
res.update({'analytic_account_journal_id': journal_ids})
return res
-account_analytic_journal_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/project_account_analytic_line.py b/addons/account/project/wizard/project_account_analytic_line.py
index c5a496527c1..40777f73e7d 100644
--- a/addons/account/project/wizard/project_account_analytic_line.py
+++ b/addons/account/project/wizard/project_account_analytic_line.py
@@ -53,6 +53,5 @@ class project_account_analytic_line(osv.osv_memory):
'search_view_id': id['res_id'],
}
-project_account_analytic_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_analytic_entries_report.py b/addons/account/report/account_analytic_entries_report.py
index dad0dedc9fc..f7d1177e3b0 100644
--- a/addons/account/report/account_analytic_entries_report.py
+++ b/addons/account/report/account_analytic_entries_report.py
@@ -81,6 +81,5 @@ class analytic_entries_report(osv.osv):
a.move_id,a.product_id,a.product_uom_id
)
""")
-analytic_entries_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_entries_report.py b/addons/account/report/account_entries_report.py
index d53e6153981..6060d97c182 100644
--- a/addons/account/report/account_entries_report.py
+++ b/addons/account/report/account_entries_report.py
@@ -81,7 +81,7 @@ class account_entries_report(osv.osv):
period_obj = self.pool.get('account.period')
for arg in args:
if arg[0] == 'period_id' and arg[2] == 'current_period':
- current_period = period_obj.find(cr, uid)[0]
+ current_period = period_obj.find(cr, uid, context=context)[0]
args.append(['period_id','in',[current_period]])
break
elif arg[0] == 'period_id' and arg[2] == 'current_year':
@@ -100,7 +100,7 @@ class account_entries_report(osv.osv):
fiscalyear_obj = self.pool.get('account.fiscalyear')
period_obj = self.pool.get('account.period')
if context.get('period', False) == 'current_period':
- current_period = period_obj.find(cr, uid)[0]
+ current_period = period_obj.find(cr, uid, context=context)[0]
domain.append(['period_id','in',[current_period]])
elif context.get('year', False) == 'current_year':
current_year = fiscalyear_obj.find(cr, uid)
@@ -152,6 +152,5 @@ class account_entries_report(osv.osv):
where l.state != 'draft'
)
""")
-account_entries_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py
index 31725a46b46..799b9b1c9fb 100644
--- a/addons/account/report/account_invoice_report.py
+++ b/addons/account/report/account_invoice_report.py
@@ -70,6 +70,7 @@ class account_invoice_report(osv.osv):
'categ_id': fields.many2one('product.category','Category of Product', readonly=True),
'journal_id': fields.many2one('account.journal', 'Journal', readonly=True),
'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
+ 'commercial_partner_id': fields.many2one('res.partner', 'Partner Company', help="Commercial Entity"),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'user_id': fields.many2one('res.users', 'Salesperson', readonly=True),
'price_total': fields.float('Total Without Tax', readonly=True),
@@ -108,7 +109,7 @@ class account_invoice_report(osv.osv):
sub.fiscal_position, sub.user_id, sub.company_id, sub.nbr, sub.type, sub.state,
sub.categ_id, sub.date_due, sub.account_id, sub.account_line_id, sub.partner_bank_id,
sub.product_qty, sub.price_total / cr.rate as price_total, sub.price_average /cr.rate as price_average,
- cr.rate as currency_rate, sub.residual / cr.rate as residual
+ cr.rate as currency_rate, sub.residual / cr.rate as residual, sub.commercial_partner_id as commercial_partner_id
"""
return select_str
@@ -170,7 +171,8 @@ class account_invoice_report(osv.osv):
LEFT JOIN account_invoice a ON a.id = l.invoice_id
WHERE a.id = ai.id)
ELSE 1::bigint
- END::numeric AS residual
+ END::numeric AS residual,
+ ai.commercial_partner_id as commercial_partner_id
"""
return select_str
@@ -193,7 +195,7 @@ class account_invoice_report(osv.osv):
ai.partner_id, ai.payment_term, ai.period_id, u.name, ai.currency_id, ai.journal_id,
ai.fiscal_position, ai.user_id, ai.company_id, ai.type, ai.state, pt.categ_id,
ai.date_due, ai.account_id, ail.account_id, ai.partner_bank_id, ai.residual,
- ai.amount_total, u.uom_type, u.category_id
+ ai.amount_total, u.uom_type, u.category_id, ai.commercial_partner_id
"""
return group_by_str
@@ -217,6 +219,5 @@ class account_invoice_report(osv.osv):
self._table,
self._select(), self._sub_select(), self._from(), self._group_by()))
-account_invoice_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_invoice_report_view.xml b/addons/account/report/account_invoice_report_view.xml
index dad70f695dc..96dc948b09a 100644
--- a/addons/account/report/account_invoice_report_view.xml
+++ b/addons/account/report/account_invoice_report_view.xml
@@ -14,6 +14,7 @@
+
@@ -65,7 +66,8 @@
-
+
+
diff --git a/addons/account/report/account_report.py b/addons/account/report/account_report.py
index 11a6374b24e..60b994dad07 100644
--- a/addons/account/report/account_report.py
+++ b/addons/account/report/account_report.py
@@ -66,7 +66,6 @@ class report_account_receivable(osv.osv):
group by
to_char(date,'YYYY:IW'), a.type
)""")
-report_account_receivable()
#a.type in ('receivable','payable')
class temp_range(osv.osv):
@@ -77,7 +76,6 @@ class temp_range(osv.osv):
'name': fields.char('Range',size=64)
}
-temp_range()
class report_aged_receivable(osv.osv):
_name = "report.aged.receivable"
@@ -147,7 +145,6 @@ class report_aged_receivable(osv.osv):
select id,name from temp_range
)""")
-report_aged_receivable()
class report_invoice_created(osv.osv):
_name = "report.invoice.created"
@@ -200,7 +197,6 @@ class report_invoice_created(osv.osv):
AND
(to_date(to_char(inv.create_date, 'YYYY-MM-dd'),'YYYY-MM-dd') > (CURRENT_DATE-15))
)""")
-report_invoice_created()
class report_account_type_sales(osv.osv):
_name = "report.account_type.sales"
@@ -241,7 +237,6 @@ class report_account_type_sales(osv.osv):
group by
to_char(inv.date_invoice, 'YYYY'),to_char(inv.date_invoice,'MM'),inv.currency_id, inv.period_id, inv_line.product_id, account.user_type
)""")
-report_account_type_sales()
class report_account_sales(osv.osv):
@@ -283,6 +278,5 @@ class report_account_sales(osv.osv):
group by
to_char(inv.date_invoice, 'YYYY'),to_char(inv.date_invoice,'MM'),inv.currency_id, inv.period_id, inv_line.product_id, account.id
)""")
-report_account_sales()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_treasury_report.py b/addons/account/report/account_treasury_report.py
index 1ee411708c7..f7785d0827b 100644
--- a/addons/account/report/account_treasury_report.py
+++ b/addons/account/report/account_treasury_report.py
@@ -78,6 +78,5 @@ class account_treasury_report(osv.osv):
group by p.id, p.fiscalyear_id, p.date_start, am.company_id
)
""")
-account_treasury_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/res_currency.py b/addons/account/res_currency.py
index 9564b4e57c6..a7d3e5bc345 100644
--- a/addons/account/res_currency.py
+++ b/addons/account/res_currency.py
@@ -43,6 +43,5 @@ class res_currency_account(osv.osv):
rate = float(tot2)/float(tot1)
return rate
-res_currency_account()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/static/src/js/account_move_reconciliation.js b/addons/account/static/src/js/account_move_reconciliation.js
index dbbfe3cc069..cbc0abc4f4d 100644
--- a/addons/account/static/src/js/account_move_reconciliation.js
+++ b/addons/account/static/src/js/account_move_reconciliation.js
@@ -26,7 +26,7 @@ openerp.account = function (instance) {
if (this.partners) {
this.$el.prepend(QWeb.render("AccountReconciliation", {widget: this}));
this.$(".oe_account_recon_previous").click(function() {
- self.current_partner = (self.current_partner - 1) % self.partners.length;
+ self.current_partner = (((self.current_partner - 1) % self.partners.length) + self.partners.length) % self.partners.length;
self.search_by_partner();
});
this.$(".oe_account_recon_next").click(function() {
diff --git a/addons/account/wizard/account_automatic_reconcile.py b/addons/account/wizard/account_automatic_reconcile.py
index 88d31b5b6c5..f6f0c90b1e2 100644
--- a/addons/account/wizard/account_automatic_reconcile.py
+++ b/addons/account/wizard/account_automatic_reconcile.py
@@ -246,6 +246,5 @@ class account_automatic_reconcile(osv.osv_memory):
'context': context,
}
-account_automatic_reconcile()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_change_currency.py b/addons/account/wizard/account_change_currency.py
index 73fd52b3fcb..c3726ece676 100644
--- a/addons/account/wizard/account_change_currency.py
+++ b/addons/account/wizard/account_change_currency.py
@@ -73,6 +73,5 @@ class account_change_currency(osv.osv_memory):
obj_inv.write(cr, uid, [invoice.id], {'currency_id': new_currency}, context=context)
return {'type': 'ir.actions.act_window_close'}
-account_change_currency()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_chart.py b/addons/account/wizard/account_chart.py
index 32b83a0a670..38df2f7484d 100644
--- a/addons/account/wizard/account_chart.py
+++ b/addons/account/wizard/account_chart.py
@@ -105,6 +105,5 @@ class account_chart(osv.osv_memory):
'fiscalyear': _get_fiscalyear,
}
-account_chart()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_financial_report.py b/addons/account/wizard/account_financial_report.py
index dde07eb7034..2ce7118335a 100644
--- a/addons/account/wizard/account_financial_report.py
+++ b/addons/account/wizard/account_financial_report.py
@@ -93,6 +93,5 @@ class accounting_report(osv.osv_memory):
'datas': data,
}
-accounting_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_fiscalyear_close.py b/addons/account/wizard/account_fiscalyear_close.py
index d4f7b3e6654..6ceb833816b 100644
--- a/addons/account/wizard/account_fiscalyear_close.py
+++ b/addons/account/wizard/account_fiscalyear_close.py
@@ -278,6 +278,5 @@ class account_fiscalyear_close(osv.osv_memory):
return {'type': 'ir.actions.act_window_close'}
-account_fiscalyear_close()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_fiscalyear_close_state.py b/addons/account/wizard/account_fiscalyear_close_state.py
index 746f1c47976..ed84ab65184 100644
--- a/addons/account/wizard/account_fiscalyear_close_state.py
+++ b/addons/account/wizard/account_fiscalyear_close_state.py
@@ -56,6 +56,5 @@ class account_fiscalyear_close_state(osv.osv_memory):
return {'type': 'ir.actions.act_window_close'}
-account_fiscalyear_close_state()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_invoice_refund.py b/addons/account/wizard/account_invoice_refund.py
index ba48dd34fe2..5be9ebc5c80 100644
--- a/addons/account/wizard/account_invoice_refund.py
+++ b/addons/account/wizard/account_invoice_refund.py
@@ -220,6 +220,5 @@ class account_invoice_refund(osv.osv_memory):
return self.compute_refund(cr, uid, ids, data_refund, context=context)
-account_invoice_refund()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_invoice_state.py b/addons/account/wizard/account_invoice_state.py
index 70d2984cef0..1aed2c6c477 100644
--- a/addons/account/wizard/account_invoice_state.py
+++ b/addons/account/wizard/account_invoice_state.py
@@ -42,7 +42,6 @@ class account_invoice_confirm(osv.osv_memory):
return {'type': 'ir.actions.act_window_close'}
-account_invoice_confirm()
class account_invoice_cancel(osv.osv_memory):
"""
@@ -64,6 +63,5 @@ class account_invoice_cancel(osv.osv_memory):
account_invoice_obj.signal_invoice_cancel(cr , uid, [record['id']])
return {'type': 'ir.actions.act_window_close'}
-account_invoice_cancel()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_journal_select.py b/addons/account/wizard/account_journal_select.py
index 7edd7923f4c..a4a1d4a6a9f 100644
--- a/addons/account/wizard/account_journal_select.py
+++ b/addons/account/wizard/account_journal_select.py
@@ -45,6 +45,5 @@ class account_journal_select(osv.osv_memory):
result['context'] = str({'journal_id': journal_id, 'period_id': period_id})
return result
-account_journal_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_move_bank_reconcile.py b/addons/account/wizard/account_move_bank_reconcile.py
index 283068ae693..0fb4633163b 100644
--- a/addons/account/wizard/account_move_bank_reconcile.py
+++ b/addons/account/wizard/account_move_bank_reconcile.py
@@ -59,6 +59,5 @@ the bank account\nin the journal definition for reconciliation.'))
'type': 'ir.actions.act_window'
}
-account_move_bank_reconcile()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_move_line_reconcile_select.py b/addons/account/wizard/account_move_line_reconcile_select.py
index 76af8538e05..658a6c5d503 100644
--- a/addons/account/wizard/account_move_line_reconcile_select.py
+++ b/addons/account/wizard/account_move_line_reconcile_select.py
@@ -50,6 +50,5 @@ class account_move_line_reconcile_select(osv.osv_memory):
'type': 'ir.actions.act_window'
}
-account_move_line_reconcile_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_move_line_select.py b/addons/account/wizard/account_move_line_select.py
index b56621f2114..630db9fd1d6 100644
--- a/addons/account/wizard/account_move_line_select.py
+++ b/addons/account/wizard/account_move_line_select.py
@@ -67,6 +67,5 @@ class account_move_line_select(osv.osv_memory):
result['domain']=result['domain'][0:-1]+','+domain+result['domain'][-1]
return result
-account_move_line_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_move_line_unreconcile_select.py b/addons/account/wizard/account_move_line_unreconcile_select.py
index f9009fc8199..31fbeddeea8 100644
--- a/addons/account/wizard/account_move_line_unreconcile_select.py
+++ b/addons/account/wizard/account_move_line_unreconcile_select.py
@@ -39,6 +39,5 @@ class account_move_line_unreconcile_select(osv.osv_memory):
'type': 'ir.actions.act_window'
}
-account_move_line_unreconcile_select()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_open_closed_fiscalyear.py b/addons/account/wizard/account_open_closed_fiscalyear.py
index 3b5d956d381..f4e90ae9f2f 100644
--- a/addons/account/wizard/account_open_closed_fiscalyear.py
+++ b/addons/account/wizard/account_open_closed_fiscalyear.py
@@ -43,6 +43,5 @@ class account_open_closed_fiscalyear(osv.osv_memory):
cr.execute('delete from account_move where id IN %s', (tuple(ids_move),))
return {'type': 'ir.actions.act_window_close'}
-account_open_closed_fiscalyear()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_period_close.py b/addons/account/wizard/account_period_close.py
index fad757c0ff9..a50861c65ef 100644
--- a/addons/account/wizard/account_period_close.py
+++ b/addons/account/wizard/account_period_close.py
@@ -55,6 +55,5 @@ class account_period_close(osv.osv_memory):
return {'type': 'ir.actions.act_window_close'}
-account_period_close()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_reconcile.py b/addons/account/wizard/account_reconcile.py
index 81609249fd7..0d5a3525af4 100644
--- a/addons/account/wizard/account_reconcile.py
+++ b/addons/account/wizard/account_reconcile.py
@@ -91,7 +91,6 @@ class account_move_line_reconcile(osv.osv_memory):
period_id, journal_id, context=context)
return {'type': 'ir.actions.act_window_close'}
-account_move_line_reconcile()
class account_move_line_reconcile_writeoff(osv.osv_memory):
"""
@@ -149,7 +148,6 @@ class account_move_line_reconcile_writeoff(osv.osv_memory):
context['analytic_id'] = data['analytic_id'][0]
if context['date_p']:
date = context['date_p']
-
ids = period_obj.find(cr, uid, dt=date, context=context)
if ids:
period_id = ids[0]
@@ -158,6 +156,5 @@ class account_move_line_reconcile_writeoff(osv.osv_memory):
period_id, journal_id, context=context)
return {'type': 'ir.actions.act_window_close'}
-account_move_line_reconcile_writeoff()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_reconcile_partner_process.py b/addons/account/wizard/account_reconcile_partner_process.py
index 1c317111888..bcbdb3fb5db 100644
--- a/addons/account/wizard/account_reconcile_partner_process.py
+++ b/addons/account/wizard/account_reconcile_partner_process.py
@@ -98,6 +98,5 @@ class account_partner_reconcile_process(osv.osv_memory):
'next_partner_id': _get_partner,
}
-account_partner_reconcile_process()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_account_balance.py b/addons/account/wizard/account_report_account_balance.py
index e883a59c102..fd3c966e306 100644
--- a/addons/account/wizard/account_report_account_balance.py
+++ b/addons/account/wizard/account_report_account_balance.py
@@ -38,6 +38,5 @@ class account_balance_report(osv.osv_memory):
data = self.pre_print_report(cr, uid, ids, data, context=context)
return {'type': 'ir.actions.report.xml', 'report_name': 'account.account.balance', 'datas': data}
-account_balance_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_aged_partner_balance.py b/addons/account/wizard/account_report_aged_partner_balance.py
index 1054e7fa285..c483487b78f 100644
--- a/addons/account/wizard/account_report_aged_partner_balance.py
+++ b/addons/account/wizard/account_report_aged_partner_balance.py
@@ -86,6 +86,5 @@ class account_aged_trial_balance(osv.osv_memory):
'datas': data
}
-account_aged_trial_balance()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_central_journal.py b/addons/account/wizard/account_report_central_journal.py
index da8be6d4735..a6bc111fa35 100644
--- a/addons/account/wizard/account_report_central_journal.py
+++ b/addons/account/wizard/account_report_central_journal.py
@@ -38,7 +38,6 @@ class account_central_journal(osv.osv_memory):
'datas': data,
}
-account_central_journal()
#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_common.py b/addons/account/wizard/account_report_common.py
index 52a35327845..c457140684a 100644
--- a/addons/account/wizard/account_report_common.py
+++ b/addons/account/wizard/account_report_common.py
@@ -178,6 +178,5 @@ class account_common_report(osv.osv_memory):
data['form']['used_context'] = used_context
return self._print_report(cr, uid, ids, data, context=context)
-account_common_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_common_account.py b/addons/account/wizard/account_report_common_account.py
index 7cedf427386..13b83c32958 100644
--- a/addons/account/wizard/account_report_common_account.py
+++ b/addons/account/wizard/account_report_common_account.py
@@ -41,7 +41,6 @@ class account_common_account_report(osv.osv_memory):
data['form'].update(self.read(cr, uid, ids, ['display_account'], context=context)[0])
return data
-account_common_account_report()
#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_common_journal.py b/addons/account/wizard/account_report_common_journal.py
index 609c2840ca6..a03315ecf7c 100644
--- a/addons/account/wizard/account_report_common_journal.py
+++ b/addons/account/wizard/account_report_common_journal.py
@@ -50,6 +50,5 @@ class account_common_journal_report(osv.osv_memory):
data['form']['active_ids'] = self.pool.get('account.journal.period').search(cr, uid, [('journal_id', 'in', data['form']['journal_ids']), ('period_id', 'in', period_list)], context=context)
return data
-account_common_journal_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_common_partner.py b/addons/account/wizard/account_report_common_partner.py
index 9779005b0de..d50a54ef32c 100644
--- a/addons/account/wizard/account_report_common_partner.py
+++ b/addons/account/wizard/account_report_common_partner.py
@@ -42,7 +42,6 @@ class account_common_partner_report(osv.osv_memory):
data['form'].update(self.read(cr, uid, ids, ['result_selection'], context=context)[0])
return data
-account_common_partner_report()
#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_general_journal.py b/addons/account/wizard/account_report_general_journal.py
index 4a170a84db1..e5e516b1f38 100644
--- a/addons/account/wizard/account_report_general_journal.py
+++ b/addons/account/wizard/account_report_general_journal.py
@@ -34,7 +34,6 @@ class account_general_journal(osv.osv_memory):
data = self.pre_print_report(cr, uid, ids, data, context=context)
return {'type': 'ir.actions.report.xml', 'report_name': 'account.general.journal', 'datas': data}
-account_general_journal()
#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_general_ledger.py b/addons/account/wizard/account_report_general_ledger.py
index a10ff624fee..fae60df63fb 100644
--- a/addons/account/wizard/account_report_general_ledger.py
+++ b/addons/account/wizard/account_report_general_ledger.py
@@ -58,6 +58,5 @@ class account_report_general_ledger(osv.osv_memory):
return { 'type': 'ir.actions.report.xml', 'report_name': 'account.general.ledger_landscape', 'datas': data}
return { 'type': 'ir.actions.report.xml', 'report_name': 'account.general.ledger', 'datas': data}
-account_report_general_ledger()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_partner_balance.py b/addons/account/wizard/account_report_partner_balance.py
index 33a7a42072c..fbe18f27d69 100644
--- a/addons/account/wizard/account_report_partner_balance.py
+++ b/addons/account/wizard/account_report_partner_balance.py
@@ -50,6 +50,5 @@ class account_partner_balance(osv.osv_memory):
'datas': data,
}
-account_partner_balance()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_partner_ledger.py b/addons/account/wizard/account_report_partner_ledger.py
index d1e6dd9809e..fdabe49ff17 100644
--- a/addons/account/wizard/account_report_partner_ledger.py
+++ b/addons/account/wizard/account_report_partner_ledger.py
@@ -67,6 +67,5 @@ class account_partner_ledger(osv.osv_memory):
'datas': data,
}
-account_partner_ledger()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_print_journal.py b/addons/account/wizard/account_report_print_journal.py
index b91fe04660a..3ad45268248 100644
--- a/addons/account/wizard/account_report_print_journal.py
+++ b/addons/account/wizard/account_report_print_journal.py
@@ -72,7 +72,6 @@ class account_print_journal(osv.osv_memory):
report_name = 'account.journal.period.print'
return {'type': 'ir.actions.report.xml', 'report_name': report_name, 'datas': data}
-account_print_journal()
#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_state_open.py b/addons/account/wizard/account_state_open.py
index 1351b8f0ac1..1950a139983 100644
--- a/addons/account/wizard/account_state_open.py
+++ b/addons/account/wizard/account_state_open.py
@@ -37,6 +37,5 @@ class account_state_open(osv.osv_memory):
obj_invoice.signal_open_test(cr, uid, context['active_ids'][0])
return {'type': 'ir.actions.act_window_close'}
-account_state_open()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_subscription_generate.py b/addons/account/wizard/account_subscription_generate.py
index f5babc4fd87..a61f3eee252 100644
--- a/addons/account/wizard/account_subscription_generate.py
+++ b/addons/account/wizard/account_subscription_generate.py
@@ -48,6 +48,5 @@ class account_subscription_generate(osv.osv_memory):
result['domain'] = str([('id','in',moves_created)])
return result
-account_subscription_generate()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_tax_chart.py b/addons/account/wizard/account_tax_chart.py
index 84859e2077c..3283d2ba6d1 100644
--- a/addons/account/wizard/account_tax_chart.py
+++ b/addons/account/wizard/account_tax_chart.py
@@ -38,7 +38,7 @@ class account_tax_chart(osv.osv_memory):
def _get_period(self, cr, uid, context=None):
"""Return default period value"""
- period_ids = self.pool.get('account.period').find(cr, uid)
+ period_ids = self.pool.get('account.period').find(cr, uid, context=context)
return period_ids and period_ids[0] or False
def account_tax_chart_open_window(self, cr, uid, ids, context=None):
@@ -73,6 +73,5 @@ class account_tax_chart(osv.osv_memory):
'target_move': 'posted'
}
-account_tax_chart()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_unreconcile.py b/addons/account/wizard/account_unreconcile.py
index ff592a329c7..425e549fec2 100644
--- a/addons/account/wizard/account_unreconcile.py
+++ b/addons/account/wizard/account_unreconcile.py
@@ -33,7 +33,6 @@ class account_unreconcile(osv.osv_memory):
obj_move_line._remove_move_reconcile(cr, uid, context['active_ids'], context=context)
return {'type': 'ir.actions.act_window_close'}
-account_unreconcile()
class account_unreconcile_reconcile(osv.osv_memory):
_name = "account.unreconcile.reconcile"
@@ -48,6 +47,5 @@ class account_unreconcile_reconcile(osv.osv_memory):
obj_move_reconcile.unlink(cr, uid, rec_ids, context=context)
return {'type': 'ir.actions.act_window_close'}
-account_unreconcile_reconcile()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_use_model.py b/addons/account/wizard/account_use_model.py
index 795284c8fef..06f02719065 100644
--- a/addons/account/wizard/account_use_model.py
+++ b/addons/account/wizard/account_use_model.py
@@ -71,6 +71,5 @@ class account_use_model(osv.osv_memory):
'type': 'ir.actions.act_window',
}
-account_use_model()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_validate_account_move.py b/addons/account/wizard/account_validate_account_move.py
index faf7f8e2ccd..324248284f1 100644
--- a/addons/account/wizard/account_validate_account_move.py
+++ b/addons/account/wizard/account_validate_account_move.py
@@ -40,7 +40,6 @@ class validate_account_move(osv.osv_memory):
obj_move.button_validate(cr, uid, ids_move, context=context)
return {'type': 'ir.actions.act_window_close'}
-validate_account_move()
class validate_account_move_lines(osv.osv_memory):
_name = "validate.account.move.lines"
@@ -61,7 +60,6 @@ class validate_account_move_lines(osv.osv_memory):
raise osv.except_osv(_('Warning!'), _('Selected Entry Lines does not have any account move enties in draft state.'))
obj_move.button_validate(cr, uid, move_ids, context)
return {'type': 'ir.actions.act_window_close'}
-validate_account_move_lines()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_vat.py b/addons/account/wizard/account_vat.py
index a60a7906e28..37bf4b029a6 100644
--- a/addons/account/wizard/account_vat.py
+++ b/addons/account/wizard/account_vat.py
@@ -59,6 +59,5 @@ class account_vat_declaration(osv.osv_memory):
'datas': datas,
}
-account_vat_declaration()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/pos_box.py b/addons/account/wizard/pos_box.py
index 49178dfd3ea..874a8e3b7c9 100644
--- a/addons/account/wizard/pos_box.py
+++ b/addons/account/wizard/pos_box.py
@@ -21,7 +21,7 @@ class CashBox(osv.osv_memory):
active_model = context.get('active_model', False) or False
active_ids = context.get('active_ids', []) or []
- 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)
return self._run(cr, uid, ids, records, context=None)
@@ -63,11 +63,12 @@ class CashBoxIn(CashBox):
'name' : box.name,
}
-CashBoxIn()
class CashBoxOut(CashBox):
_name = 'cash.box.out'
+ _columns = CashBox._columns.copy()
+
def _compute_values_for_statement_line(self, cr, uid, box, record, context=None):
amount = box.amount or 0.0
return {
@@ -78,4 +79,3 @@ class CashBoxOut(CashBox):
'name' : box.name,
}
-CashBoxOut()
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
index 97a4bb8fac2..d31746e7e70 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml
+++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
@@ -213,7 +213,7 @@
-
+
diff --git a/addons/account_analytic_default/account_analytic_default.py b/addons/account_analytic_default/account_analytic_default.py
index 9d7df0aa010..1696874f0f5 100644
--- a/addons/account_analytic_default/account_analytic_default.py
+++ b/addons/account_analytic_default/account_analytic_default.py
@@ -67,7 +67,6 @@ class account_analytic_default(osv.osv):
best_index = index
return res
-account_analytic_default()
class account_invoice_line(osv.osv):
_inherit = "account.invoice.line"
@@ -82,7 +81,6 @@ class account_invoice_line(osv.osv):
res_prod['value'].update({'account_analytic_id': False})
return res_prod
-account_invoice_line()
class stock_picking(osv.osv):
@@ -97,7 +95,6 @@ class stock_picking(osv.osv):
return super(stock_picking, self)._get_account_analytic_invoice(cursor, user, picking, move_line)
-stock_picking()
class sale_order_line(osv.osv):
_inherit = "sale.order.line"
@@ -118,6 +115,5 @@ class sale_order_line(osv.osv):
inv_line_obj.write(cr, uid, [line.id], {'account_analytic_id': rec.analytic_id.id}, context=context)
return create_ids
-sale_order_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_default/i18n/nl_BE.po b/addons/account_analytic_default/i18n/nl_BE.po
index 4d7b5295f16..86fed1b535a 100644
--- a/addons/account_analytic_default/i18n/nl_BE.po
+++ b/addons/account_analytic_default/i18n/nl_BE.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-11-27 13:19+0000\n"
+"PO-Revision-Date: 2013-04-15 15:56+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \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:28+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: account_analytic_default
#: model:ir.actions.act_window,name:account_analytic_default.analytic_rule_action_partner
@@ -40,6 +40,9 @@ msgid ""
"default (e.g. create new customer invoice or Sales order if we select this "
"product, it will automatically take this as an analytic account)"
msgstr ""
+"Kies een product voor de analytische rekening in analytische "
+"standaardrekening (vb. maak een nieuwe verkoopfactuur of verkooporder: als "
+"we dit product kiezen, wordt de analytische rekening voorgesteld)."
#. module: account_analytic_default
#: model:ir.model,name:account_analytic_default.model_stock_picking
@@ -64,6 +67,9 @@ msgid ""
"default (e.g. create new customer invoice or Sales order if we select this "
"partner, it will automatically take this as an analytic account)"
msgstr ""
+"Kies een relatie voor de analytische rekening in analytische "
+"standaardrekening (vb. maak een nieuwe verkoopfactuur of verkooporder: als "
+"we deze relatie kiezen, wordt de analytische rekening voorgesteld)."
#. module: account_analytic_default
#: view:account.analytic.default:0
@@ -118,6 +124,9 @@ msgid ""
"default (e.g. create new customer invoice or Sales order if we select this "
"company, it will automatically take this as an analytic account)"
msgstr ""
+"Kies een firma voor de analytische rekening in analytische standaardrekening "
+"(vb. maak een nieuwe verkoopfactuur of verkooporder: als we deze firma "
+"kiezen, wordt de analytische rekening voorgesteld)."
#. module: account_analytic_default
#: view:account.analytic.default:0
diff --git a/addons/account_analytic_plans/account_analytic_plans.py b/addons/account_analytic_plans/account_analytic_plans.py
index 5834db99cd3..54b15ad565b 100644
--- a/addons/account_analytic_plans/account_analytic_plans.py
+++ b/addons/account_analytic_plans/account_analytic_plans.py
@@ -40,10 +40,10 @@ class one2many_mod2(fields.one2many):
plan = journal.plan_id
if plan and len(plan.plan_ids) > pnum:
acc_id = plan.plan_ids[pnum].root_analytic_id.id
- ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids),('analytic_account_id','child_of',[acc_id])], limit=self._limit)
+ ids2 = obj.pool[self._obj].search(cr, user, [(self._fields_id,'in',ids),('analytic_account_id','child_of',[acc_id])], limit=self._limit)
if ids2 is None:
- ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
- for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
+ ids2 = obj.pool[self._obj].search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
+ for r in obj.pool[self._obj]._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
res[r[self._fields_id]].append( r['id'] )
return res
@@ -65,7 +65,6 @@ class account_analytic_line(osv.osv):
'percentage': fields.float('Percentage')
}
-account_analytic_line()
class account_analytic_plan(osv.osv):
_name = "account.analytic.plan"
@@ -75,7 +74,6 @@ class account_analytic_plan(osv.osv):
'plan_ids': fields.one2many('account.analytic.plan.line', 'plan_id', 'Analytic Plans'),
}
-account_analytic_plan()
class account_analytic_plan_line(osv.osv):
_name = "account.analytic.plan.line"
@@ -94,7 +92,6 @@ class account_analytic_plan_line(osv.osv):
'max_required': 100.0,
}
-account_analytic_plan_line()
class account_analytic_plan_instance(osv.osv):
_name = "account.analytic.plan.instance"
@@ -257,7 +254,6 @@ class account_analytic_plan_instance(osv.osv):
vals['code'] = this.code and (str(this.code)+'*') or "*"
return super(account_analytic_plan_instance, self).write(cr, uid, ids, vals, context=context)
-account_analytic_plan_instance()
class account_analytic_plan_instance_line(osv.osv):
_name = "account.analytic.plan.instance.line"
@@ -280,7 +276,6 @@ class account_analytic_plan_instance_line(osv.osv):
res.append((record['id'], record['analytic_account_id']))
return res
-account_analytic_plan_instance_line()
class account_journal(osv.osv):
_inherit = "account.journal"
@@ -289,7 +284,6 @@ class account_journal(osv.osv):
'plan_id': fields.many2one('account.analytic.plan', 'Analytic Plans'),
}
-account_journal()
class account_invoice_line(osv.osv):
_inherit = "account.invoice.line"
@@ -315,7 +309,6 @@ class account_invoice_line(osv.osv):
res_prod['value'].update({'analytics_id': rec.analytics_id.id})
return res_prod
-account_invoice_line()
class account_move_line(osv.osv):
@@ -370,7 +363,6 @@ class account_move_line(osv.osv):
result = super(account_move_line, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
return result
-account_move_line()
class account_invoice(osv.osv):
_name = "account.invoice"
@@ -425,14 +417,12 @@ class account_invoice(osv.osv):
il['analytic_lines'].append((0, 0, al_vals))
return iml
-account_invoice()
class account_analytic_plan(osv.osv):
_inherit = "account.analytic.plan"
_columns = {
'default_instance_id': fields.many2one('account.analytic.plan.instance', 'Default Entries'),
}
-account_analytic_plan()
class analytic_default(osv.osv):
_inherit = "account.analytic.default"
@@ -440,7 +430,6 @@ class analytic_default(osv.osv):
'analytics_id': fields.many2one('account.analytic.plan.instance', 'Analytic Distribution'),
}
-analytic_default()
class sale_order_line(osv.osv):
_inherit = "sale.order.line"
@@ -459,7 +448,6 @@ class sale_order_line(osv.osv):
inv_line_obj.write(cr, uid, [line.id], {'analytics_id': rec.analytics_id.id}, context=context)
return create_ids
-sale_order_line()
class account_bank_statement(osv.osv):
@@ -488,7 +476,6 @@ class account_bank_statement(osv.osv):
continue
return True
-account_bank_statement()
class account_bank_statement_line(osv.osv):
@@ -497,6 +484,5 @@ class account_bank_statement_line(osv.osv):
_columns = {
'analytics_id': fields.many2one('account.analytic.plan.instance', 'Analytic Distribution'),
}
-account_bank_statement_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_plans/account_analytic_plans_view.xml b/addons/account_analytic_plans/account_analytic_plans_view.xml
index 3dcbcda6952..be46b9a6923 100644
--- a/addons/account_analytic_plans/account_analytic_plans_view.xml
+++ b/addons/account_analytic_plans/account_analytic_plans_view.xml
@@ -64,30 +64,6 @@
-
-
-
- account.invoice.line.form.inherit
- account.invoice.line
-
-
-
-
-
-
-
-
-
- account.invoice.supplier.form.inherit
- account.invoice
-
- 2
-
-
-
-
-
-
diff --git a/addons/account_analytic_plans/wizard/account_crossovered_analytic.py b/addons/account_analytic_plans/wizard/account_crossovered_analytic.py
index 640443c8a0b..d3581d6c457 100644
--- a/addons/account_analytic_plans/wizard/account_crossovered_analytic.py
+++ b/addons/account_analytic_plans/wizard/account_crossovered_analytic.py
@@ -71,6 +71,5 @@ class account_crossovered_analytic(osv.osv_memory):
'datas': datas,
}
-account_crossovered_analytic()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_plans/wizard/analytic_plan_create_model.py b/addons/account_analytic_plans/wizard/analytic_plan_create_model.py
index 7038a6f1025..3a206aa227e 100644
--- a/addons/account_analytic_plans/wizard/analytic_plan_create_model.py
+++ b/addons/account_analytic_plans/wizard/analytic_plan_create_model.py
@@ -55,6 +55,5 @@ class analytic_plan_create_model(osv.osv_memory):
else:
return {'type': 'ir.actions.act_window_close'}
-analytic_plan_create_model()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_anglo_saxon/product.py b/addons/account_anglo_saxon/product.py
index 443642d048b..b52d9ed3bbd 100644
--- a/addons/account_anglo_saxon/product.py
+++ b/addons/account_anglo_saxon/product.py
@@ -48,7 +48,6 @@ class product_category(osv.osv):
help="This account will be used to value outgoing stock using cost price."),
}
-product_category()
class product_template(osv.osv):
_inherit = "product.template"
@@ -78,7 +77,6 @@ class product_template(osv.osv):
help="This account will be used to value outgoing stock using cost price."),
}
-product_template()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_anglo_saxon/purchase.py b/addons/account_anglo_saxon/purchase.py
index 959f8b7eb49..c10a2a97d80 100644
--- a/addons/account_anglo_saxon/purchase.py
+++ b/addons/account_anglo_saxon/purchase.py
@@ -37,6 +37,5 @@ class purchase_order(osv.osv):
new_account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, acc_id)
line.update({'account_id': new_account_id})
return line
-purchase_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_anglo_saxon/stock.py b/addons/account_anglo_saxon/stock.py
index 191249a6640..1cf3ecf21ef 100644
--- a/addons/account_anglo_saxon/stock.py
+++ b/addons/account_anglo_saxon/stock.py
@@ -57,7 +57,6 @@ class stock_picking(osv.osv):
self.pool.get('account.invoice.line').write(cr, uid, [ol.id], {'account_id': a})
return res
-stock_picking()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_asset/account_asset.py b/addons/account_asset/account_asset.py
index 5a22a888772..5c019155fdc 100644
--- a/addons/account_asset/account_asset.py
+++ b/addons/account_asset/account_asset.py
@@ -70,7 +70,6 @@ class account_asset_category(osv.osv):
res['value'] = {'account_depreciation_id': account_asset_id}
return res
-account_asset_category()
class account_asset_asset(osv.osv):
_name = 'account.asset.asset'
@@ -80,10 +79,10 @@ class account_asset_asset(osv.osv):
for asset in self.browse(cr, uid, ids, context=context):
if asset.account_move_line_ids:
raise osv.except_osv(_('Error!'), _('You cannot delete an asset that contains posted depreciation lines.'))
- return super(account_account, self).unlink(cr, uid, ids, context=context)
+ return super(account_asset_asset, self).unlink(cr, uid, ids, context=context)
def _get_period(self, cr, uid, context=None):
- periods = self.pool.get('account.period').find(cr, uid)
+ periods = self.pool.get('account.period').find(cr, uid, context=context)
if periods:
return periods[0]
else:
@@ -361,7 +360,6 @@ class account_asset_asset(osv.osv):
'context': context,
}
-account_asset_asset()
class account_asset_depreciation_line(osv.osv):
_name = 'account.asset.depreciation.line'
@@ -456,7 +454,6 @@ class account_asset_depreciation_line(osv.osv):
asset.write({'state': 'close'})
return created_move_ids
-account_asset_depreciation_line()
class account_move_line(osv.osv):
_inherit = 'account.move.line'
@@ -465,7 +462,6 @@ class account_move_line(osv.osv):
'entry_ids': fields.one2many('account.move.line', 'asset_id', 'Entries', readonly=True, states={'draft':[('readonly',False)]}),
}
-account_move_line()
class account_asset_history(osv.osv):
_name = 'account.asset.history'
@@ -490,6 +486,5 @@ class account_asset_history(osv.osv):
'user_id': lambda self, cr, uid, ctx: uid
}
-account_asset_history()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_asset/account_asset_invoice.py b/addons/account_asset/account_asset_invoice.py
index 7e2f24f0d0a..d5b1c298c0b 100644
--- a/addons/account_asset/account_asset_invoice.py
+++ b/addons/account_asset/account_asset_invoice.py
@@ -35,7 +35,6 @@ class account_invoice(osv.osv):
res['asset_id'] = x.get('asset_id', False)
return res
-account_invoice()
class account_invoice_line(osv.osv):
@@ -66,6 +65,5 @@ class account_invoice_line(osv.osv):
asset_obj.validate(cr, uid, [asset_id], context=context)
return True
-account_invoice_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_asset/account_asset_view.xml b/addons/account_asset/account_asset_view.xml
index c4cb17bded3..fe1fcf473ba 100644
--- a/addons/account_asset/account_asset_view.xml
+++ b/addons/account_asset/account_asset_view.xml
@@ -223,7 +223,7 @@
-
+
diff --git a/addons/account_asset/i18n/nl_BE.po b/addons/account_asset/i18n/nl_BE.po
index 5bee5f9bfd9..3413cf38ac8 100644
--- a/addons/account_asset/i18n/nl_BE.po
+++ b/addons/account_asset/i18n/nl_BE.po
@@ -8,14 +8,14 @@ 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: 2012-11-27 13:35+0000\n"
+"PO-Revision-Date: 2013-04-15 15:59+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Dutch (Belgium) \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:50+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: account_asset
#: view:account.asset.asset:0
@@ -148,7 +148,7 @@ msgstr "Dit is het bedrag dat u niet kunt afschrijven."
#. module: account_asset
#: help:account.asset.asset,method_period:0
msgid "The amount of time between two depreciations, in months"
-msgstr ""
+msgstr "De tijd tussen twee afschrijvingen, in maanden"
#. module: account_asset
#: field:account.asset.depreciation.line,depreciation_date:0
@@ -265,7 +265,7 @@ msgstr "Duur wijzigen"
#: help:account.asset.category,method_number:0
#: help:account.asset.history,method_number:0
msgid "The number of depreciations needed to depreciate your asset"
-msgstr ""
+msgstr "Het aantal keer dat er moet worden afgeschreven."
#. module: account_asset
#: view:account.asset.category:0
@@ -295,7 +295,7 @@ msgstr ""
#. module: account_asset
#: field:account.asset.depreciation.line,remaining_value:0
msgid "Next Period Depreciation"
-msgstr ""
+msgstr "Volgende afschrijvingsperiode"
#. module: account_asset
#: help:account.asset.history,method_period:0
@@ -346,7 +346,7 @@ msgstr "Investeringscategorie zoeken"
#. module: account_asset
#: view:asset.modify:0
msgid "months"
-msgstr ""
+msgstr "maanden"
#. module: account_asset
#: model:ir.model,name:account_asset.model_account_invoice_line
@@ -608,7 +608,7 @@ msgstr "Afschrijvingsmethode"
#. module: account_asset
#: field:account.asset.depreciation.line,amount:0
msgid "Current Depreciation"
-msgstr ""
+msgstr "Huidige afschrijving"
#. module: account_asset
#: field:account.asset.asset,name:0
@@ -653,6 +653,9 @@ msgid ""
" * Linear: Calculated on basis of: Gross Value / Number of Depreciations\n"
" * Degressive: Calculated on basis of: Residual Value * Degressive Factor"
msgstr ""
+"Kies de methode om het aantal afschrijvingsregels te berekenen.\n"
+" * Lineair: op basis van: brutowaarde / aantal afschrijvingen\n"
+" * Degressief: op basis van: restwaarde * degressieve factor"
#. module: account_asset
#: field:account.asset.depreciation.line,move_check:0
diff --git a/addons/account_asset/report/account_asset_report.py b/addons/account_asset/report/account_asset_report.py
index 1554880ac38..40ab1c778f0 100644
--- a/addons/account_asset/report/account_asset_report.py
+++ b/addons/account_asset/report/account_asset_report.py
@@ -82,6 +82,5 @@ class asset_asset_report(osv.osv):
a.purchase_value, a.id, a.salvage_value
)""")
-asset_asset_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_asset/report/account_asset_report_view.xml b/addons/account_asset/report/account_asset_report_view.xml
index 4865196c4a8..c772c6e4103 100644
--- a/addons/account_asset/report/account_asset_report_view.xml
+++ b/addons/account_asset/report/account_asset_report_view.xml
@@ -49,7 +49,7 @@
-
+
diff --git a/addons/account_asset/wizard/account_asset_change_duration.py b/addons/account_asset/wizard/account_asset_change_duration.py
index 19782c76367..f27507ac2b3 100755
--- a/addons/account_asset/wizard/account_asset_change_duration.py
+++ b/addons/account_asset/wizard/account_asset_change_duration.py
@@ -127,6 +127,5 @@ class asset_modify(osv.osv_memory):
asset_obj.compute_depreciation_board(cr, uid, [asset_id], context=context)
return {'type': 'ir.actions.act_window_close'}
-asset_modify()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_asset/wizard/wizard_asset_compute.py b/addons/account_asset/wizard/wizard_asset_compute.py
index cc870329840..f7cc6cf89c0 100755
--- a/addons/account_asset/wizard/wizard_asset_compute.py
+++ b/addons/account_asset/wizard/wizard_asset_compute.py
@@ -30,7 +30,7 @@ class asset_depreciation_confirmation_wizard(osv.osv_memory):
}
def _get_period(self, cr, uid, context=None):
- periods = self.pool.get('account.period').find(cr, uid)
+ periods = self.pool.get('account.period').find(cr, uid, context=context)
if periods:
return periods[0]
return False
@@ -55,6 +55,5 @@ class asset_depreciation_confirmation_wizard(osv.osv_memory):
'type': 'ir.actions.act_window',
}
-asset_depreciation_confirmation_wizard()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_bank_statement_extensions/account_bank_statement.py b/addons/account_bank_statement_extensions/account_bank_statement.py
index 60dcc6dfa25..b9e44ee8f9c 100644
--- a/addons/account_bank_statement_extensions/account_bank_statement.py
+++ b/addons/account_bank_statement_extensions/account_bank_statement.py
@@ -56,7 +56,6 @@ class account_bank_statement(osv.osv):
(tuple([x.id for x in st.line_ids]),))
return True
-account_bank_statement()
class account_bank_statement_line_global(osv.osv):
_name = 'account.bank.statement.line.global'
@@ -100,7 +99,6 @@ class account_bank_statement_line_global(osv.osv):
ids = self.search(cr, user, args, context=context, limit=limit)
return self.name_get(cr, user, ids, context=context)
-account_bank_statement_line_global()
class account_bank_statement_line(osv.osv):
_inherit = 'account.bank.statement.line'
@@ -130,6 +128,5 @@ class account_bank_statement_line(osv.osv):
Please go to the associated bank statement in order to delete and/or modify bank statement line.'))
return super(account_bank_statement_line, self).unlink(cr, uid, ids, context=context)
-account_bank_statement_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_bank_statement_extensions/res_partner_bank.py b/addons/account_bank_statement_extensions/res_partner_bank.py
index f866634a08c..22baa78d39f 100644
--- a/addons/account_bank_statement_extensions/res_partner_bank.py
+++ b/addons/account_bank_statement_extensions/res_partner_bank.py
@@ -35,5 +35,4 @@ class res_partner_bank(osv.osv):
ids = self.search(cr, user, args, context=context, limit=limit)
return self.name_get(cr, user, ids, context=context)
-res_partner_bank()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_bank_statement_extensions/wizard/cancel_statement_line.py b/addons/account_bank_statement_extensions/wizard/cancel_statement_line.py
index 46d71354d4b..15c242e9c33 100644
--- a/addons/account_bank_statement_extensions/wizard/cancel_statement_line.py
+++ b/addons/account_bank_statement_extensions/wizard/cancel_statement_line.py
@@ -32,6 +32,5 @@ class cancel_statement_line(osv.osv_memory):
line_obj.write(cr, uid, line_ids, {'state': 'draft'}, context=context)
return {}
-cancel_statement_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_bank_statement_extensions/wizard/confirm_statement_line.py b/addons/account_bank_statement_extensions/wizard/confirm_statement_line.py
index 3a887a52441..c330a2cc359 100644
--- a/addons/account_bank_statement_extensions/wizard/confirm_statement_line.py
+++ b/addons/account_bank_statement_extensions/wizard/confirm_statement_line.py
@@ -32,6 +32,5 @@ class confirm_statement_line(osv.osv_memory):
line_obj.write(cr, uid, line_ids, {'state': 'confirm'}, context=context)
return {}
-confirm_statement_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/account_budget.py b/addons/account_budget/account_budget.py
index a88c468fff1..e6fc3a29668 100644
--- a/addons/account_budget/account_budget.py
+++ b/addons/account_budget/account_budget.py
@@ -48,7 +48,6 @@ class account_budget_post(osv.osv):
}
_order = "name"
-account_budget_post()
class crossovered_budget(osv.osv):
@@ -104,7 +103,6 @@ class crossovered_budget(osv.osv):
})
return True
-crossovered_budget()
class crossovered_budget_lines(osv.osv):
@@ -202,7 +200,6 @@ class crossovered_budget_lines(osv.osv):
'company_id': fields.related('crossovered_budget_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True)
}
-crossovered_budget_lines()
class account_analytic_account(osv.osv):
_inherit = "account.analytic.account"
@@ -211,6 +208,5 @@ class account_analytic_account(osv.osv):
'crossovered_budget_line': fields.one2many('crossovered.budget.lines', 'analytic_account_id', 'Budget Lines'),
}
-account_analytic_account()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/wizard/account_budget_analytic.py b/addons/account_budget/wizard/account_budget_analytic.py
index 0cdb7504f75..90285b90d1e 100644
--- a/addons/account_budget/wizard/account_budget_analytic.py
+++ b/addons/account_budget/wizard/account_budget_analytic.py
@@ -50,6 +50,5 @@ class account_budget_analytic(osv.osv_memory):
'datas': datas,
}
-account_budget_analytic()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/wizard/account_budget_crossovered_report.py b/addons/account_budget/wizard/account_budget_crossovered_report.py
index 97fc43c8e9d..6f89a3cd95c 100644
--- a/addons/account_budget/wizard/account_budget_crossovered_report.py
+++ b/addons/account_budget/wizard/account_budget_crossovered_report.py
@@ -51,6 +51,5 @@ class account_budget_crossvered_report(osv.osv_memory):
'datas': datas,
}
-account_budget_crossvered_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/wizard/account_budget_crossovered_summary_report.py b/addons/account_budget/wizard/account_budget_crossovered_summary_report.py
index f42c39ec6ac..6e3131b584c 100644
--- a/addons/account_budget/wizard/account_budget_crossovered_summary_report.py
+++ b/addons/account_budget/wizard/account_budget_crossovered_summary_report.py
@@ -53,7 +53,6 @@ class account_budget_crossvered_summary_report(osv.osv_memory):
'datas': datas,
}
-account_budget_crossvered_summary_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/wizard/account_budget_report.py b/addons/account_budget/wizard/account_budget_report.py
index 5db6c68d508..54c3180ee0d 100644
--- a/addons/account_budget/wizard/account_budget_report.py
+++ b/addons/account_budget/wizard/account_budget_report.py
@@ -52,6 +52,5 @@ class account_budget_report(osv.osv_memory):
'datas': datas,
}
-account_budget_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_check_writing/account.py b/addons/account_check_writing/account.py
index 62b7336dc5f..035e3a710b0 100644
--- a/addons/account_check_writing/account.py
+++ b/addons/account_check_writing/account.py
@@ -29,7 +29,6 @@ class account_journal(osv.osv):
'use_preprint_check': fields.boolean('Use Preprinted Check'),
}
-account_journal()
class res_company(osv.osv):
_inherit = "res.company"
@@ -46,5 +45,4 @@ class res_company(osv.osv):
'check_layout' : lambda *a: 'top',
}
-res_company()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_check_writing/account_voucher.py b/addons/account_check_writing/account_voucher.py
index 7a5d12f5cff..8e1ad2e1fbf 100644
--- a/addons/account_check_writing/account_voucher.py
+++ b/addons/account_check_writing/account_voucher.py
@@ -97,4 +97,3 @@ class account_voucher(osv.osv):
res['arch'] = etree.tostring(doc)
return res
-account_voucher()
diff --git a/addons/account_check_writing/i18n/hu.po b/addons/account_check_writing/i18n/hu.po
new file mode 100644
index 00000000000..528cb4fed60
--- /dev/null
+++ b/addons/account_check_writing/i18n/hu.po
@@ -0,0 +1,247 @@
+# Hungarian 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-11 22:57+0000\n"
+"Last-Translator: krnkris \n"
+"Language-Team: Hungarian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2013-04-12 05:21+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
+
+#. module: account_check_writing
+#: selection:res.company,check_layout:0
+msgid "Check on Top"
+msgstr "Fennt lévő csekk"
+
+#. module: account_check_writing
+#: report:account.print.check.top:0
+msgid "Open Balance"
+msgstr "Nyitó egyenleg"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+#: view:account.voucher:0
+msgid "Print Check"
+msgstr "Csekk nyomtatása"
+
+#. module: account_check_writing
+#: selection:res.company,check_layout:0
+msgid "Check in middle"
+msgstr "Középen lévő csekk"
+
+#. module: account_check_writing
+#: help:res.company,check_layout:0
+msgid ""
+"Check on top is compatible with Quicken, QuickBooks and Microsoft Money. "
+"Check in middle is compatible with Peachtree, ACCPAC and DacEasy. Check on "
+"bottom is compatible with Peachtree, ACCPAC and DacEasy only"
+msgstr ""
+"Fennt lévő csekk kompatibilis a Quicken, QuickBooks és Microsoft Money "
+"csekkekekl. A középen lévő csekkek kompatibilisek a Peachtree, ACCPAC és "
+"DacEasy csekkekel. Az alul lévő csekkek kompatibilisek a Peachtree, ACCPAC "
+"és DacEasy only csekkekel."
+
+#. module: account_check_writing
+#: selection:res.company,check_layout:0
+msgid "Check on bottom"
+msgstr "Alul lévő csekkek"
+
+#. module: account_check_writing
+#: model:ir.actions.act_window,name:account_check_writing.action_account_check_write
+msgid "Print Check in Batch"
+msgstr "Csekkek kötegelt nyomtatása"
+
+#. module: account_check_writing
+#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
+#, python-format
+msgid "One of the printed check already got a number."
+msgstr "Egyik, már kinyomtatott csekk már el van látva számmal."
+
+#. module: account_check_writing
+#: help:account.journal,allow_check_writing:0
+msgid "Check this if the journal is to be used for writing checks."
+msgstr "Jelölje be ezt, ha naplót csekkírásra használja."
+
+#. module: account_check_writing
+#: field:account.journal,allow_check_writing:0
+msgid "Allow Check writing"
+msgstr "Csekk írás engedélyezése."
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Description"
+msgstr "Leírás"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_journal
+msgid "Journal"
+msgstr "Napló"
+
+#. module: account_check_writing
+#: model:ir.actions.act_window,name:account_check_writing.action_write_check
+#: model:ir.ui.menu,name:account_check_writing.menu_action_write_check
+msgid "Write Checks"
+msgstr "Csekkek írása"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Discount"
+msgstr "Kedvezmény"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Original Amount"
+msgstr "Eredeti összeg"
+
+#. module: account_check_writing
+#: field:res.company,check_layout:0
+msgid "Check Layout"
+msgstr "Csekk elrendezése"
+
+#. module: account_check_writing
+#: field:account.voucher,allow_check:0
+msgid "Allow Check Writing"
+msgstr "Csekk írás engedélyezése"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Payment"
+msgstr "Kifizetés"
+
+#. module: account_check_writing
+#: field:account.journal,use_preprint_check:0
+msgid "Use Preprinted Check"
+msgstr "Előre nyomtatott csekk használata"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_bottom
+msgid "Print Check (Bottom)"
+msgstr "Csekk nyomtatás (Alsó)"
+
+#. module: account_check_writing
+#: model:ir.actions.act_window,help:account_check_writing.action_write_check
+msgid ""
+"
\n"
+" Click to create a new check. \n"
+"
\n"
+" The check payment form allows you to track the payment you "
+"do\n"
+" to your suppliers using checks. When you select a supplier, "
+"the\n"
+" payment method and an amount for the payment, OpenERP will\n"
+" propose to reconcile your payment with the open supplier\n"
+" invoices or bills.\n"
+"
\n"
+" "
+msgstr ""
+"
\n"
+" Kattintson új csekk létrehozásához. \n"
+"
\n"
+" A csekk kifizetési lap lehetővé teszi a beszállítókhoz "
+"történt \n"
+" csekken történt kifizetések nyomon követését. Ha kiválaszt "
+"egy beszállítót,\n"
+" a fizetési módot és az összeget, OpenERP javasolni fogja \n"
+" a fizetés összeegyeztetését a még nyitott beszállítói "
+"számlákkal és\n"
+" fizetésekkel.\n"
+"
\n"
+" "
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Due Date"
+msgstr "Fizetési határidő"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
+msgid "Print Check (Middle)"
+msgstr "Csekk nyomtatás (Középső)"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_res_company
+msgid "Companies"
+msgstr "Vállalatok"
+
+#. module: account_check_writing
+#: code:addons/account_check_writing/wizard/account_check_batch_printing.py:59
+#, python-format
+msgid "Error!"
+msgstr "Hiba!"
+
+#. module: account_check_writing
+#: help:account.check.write,check_number:0
+msgid "The number of the next check number to be printed."
+msgstr "A következő csekkszám nyomtatása"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+msgid "Balance Due"
+msgstr "Esedékes egyenleg"
+
+#. module: account_check_writing
+#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
+msgid "Print Check (Top)"
+msgstr "Csekk nyomtatás (Felső)"
+
+#. module: account_check_writing
+#: report:account.print.check.bottom:0
+#: report:account.print.check.middle:0
+#: report:account.print.check.top:0
+msgid "Check Amount"
+msgstr "Csekk végösszege"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_voucher
+msgid "Accounting Voucher"
+msgstr "Könyvelési bizonylat"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "or"
+msgstr "vagy"
+
+#. module: account_check_writing
+#: field:account.voucher,amount_in_word:0
+msgid "Amount in Word"
+msgstr "Összeg szavakkal"
+
+#. module: account_check_writing
+#: model:ir.model,name:account_check_writing.model_account_check_write
+msgid "Prin Check in Batch"
+msgstr "Csekk kötegelt nyomtatása"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "Cancel"
+msgstr "Mégse"
+
+#. module: account_check_writing
+#: field:account.check.write,check_number:0
+msgid "Next Check Number"
+msgstr "Következő csekk száma"
+
+#. module: account_check_writing
+#: view:account.check.write:0
+msgid "Check"
+msgstr "Csekk"
diff --git a/addons/account_check_writing/wizard/account_check_batch_printing.py b/addons/account_check_writing/wizard/account_check_batch_printing.py
index afeb5de6445..c3a13e2c687 100644
--- a/addons/account_check_writing/wizard/account_check_batch_printing.py
+++ b/addons/account_check_writing/wizard/account_check_batch_printing.py
@@ -83,5 +83,4 @@ class account_check_write(osv.osv_memory):
'nodestroy': True
}
-account_check_write()
diff --git a/addons/account_followup/account_followup_customers.xml b/addons/account_followup/account_followup_customers.xml
index 6be11399b68..6893abe012e 100644
--- a/addons/account_followup/account_followup_customers.xml
+++ b/addons/account_followup/account_followup_customers.xml
@@ -10,7 +10,7 @@
-
+
@@ -29,7 +29,7 @@
res.partner
-
+
diff --git a/addons/account_followup/i18n/nl_BE.po b/addons/account_followup/i18n/nl_BE.po
index 1a92e60dfc9..64a73d776ef 100644
--- a/addons/account_followup/i18n/nl_BE.po
+++ b/addons/account_followup/i18n/nl_BE.po
@@ -1,20 +1,21 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
-# * account_followup
-#
+# * account_followup
+# Els Van Vossel , 2013.
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2010-12-17 09:57+0000\n"
-"Last-Translator: Niels Huylebroeck \n"
-"Language-Team: \n"
+"PO-Revision-Date: 2013-04-15 23:02+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Els Van Vossel\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:11+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-17 05:15+0000\n"
+"X-Generator: Launchpad (build 16567)\n"
+"Language: nl\n"
#. module: account_followup
#: model:email.template,subject:account_followup.email_template_account_followup_default
@@ -22,12 +23,12 @@ msgstr ""
#: model:email.template,subject:account_followup.email_template_account_followup_level1
#: model:email.template,subject:account_followup.email_template_account_followup_level2
msgid "${user.company_id.name} Payment Reminder"
-msgstr ""
+msgstr "${user.company_id.name} Aanmaning"
#. module: account_followup
#: help:res.partner,latest_followup_level_id:0
msgid "The maximum follow-up level"
-msgstr ""
+msgstr "Het maximale aanmaningsniveau"
#. module: account_followup
#: view:account_followup.stat:0
@@ -43,33 +44,33 @@ msgstr "Aanmanen"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(date)s"
-msgstr ""
+msgstr "%(date)s"
#. module: account_followup
#: field:res.partner,payment_next_action_date:0
msgid "Next Action Date"
-msgstr ""
+msgstr "Volgende actiedatum"
#. module: account_followup
#: view:account_followup.followup.line:0
#: field:account_followup.followup.line,manual_action:0
msgid "Manual Action"
-msgstr ""
+msgstr "Manuele actie"
#. module: account_followup
#: field:account_followup.sending.results,needprinting:0
msgid "Needs Printing"
-msgstr ""
+msgstr "Moet worden afgedrukt"
#. module: account_followup
#: view:res.partner:0
msgid "⇾ Mark as Done"
-msgstr ""
+msgstr "⇾ Als Gedaan markeren"
#. module: account_followup
#: field:account_followup.followup.line,manual_action_note:0
msgid "Action To Do"
-msgstr ""
+msgstr "Uit te voeren actie"
#. module: account_followup
#: field:account_followup.followup,company_id:0
@@ -89,39 +90,39 @@ msgstr "Factuurdatum"
#. module: account_followup
#: field:account_followup.print,email_subject:0
msgid "Email Subject"
-msgstr "E-mail onderwerp"
+msgstr "E-mailonderwerp"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(user_signature)s"
-msgstr ""
+msgstr "%(user_signature)s"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "days overdue, do the following actions:"
-msgstr ""
+msgstr "dagen vervallen, voer volgende acties uit:"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "Follow-up Steps"
-msgstr ""
+msgstr "Aanmaningsstappen"
#. module: account_followup
#: field:account_followup.print,email_body:0
msgid "Email Body"
-msgstr ""
+msgstr "E-mailbericht"
#. module: account_followup
#: model:ir.actions.act_window,name:account_followup.action_account_followup_print
msgid "Send Follow-Ups"
-msgstr ""
+msgstr "Aanmaningen versturen"
#. module: account_followup
#: report:account_followup.followup.print:0
#: code:addons/account_followup/account_followup.py:263
#, python-format
msgid "Amount"
-msgstr ""
+msgstr "Bedrag"
#. module: account_followup
#: help:res.partner,payment_next_action:0
@@ -129,11 +130,14 @@ msgid ""
"This is the next action to be taken. It will automatically be set when the "
"partner gets a follow-up level that requires a manual action. "
msgstr ""
+"Dit is de volgende actie die moet worden ondernomen. Deze wordt automatisch "
+"ingesteld als de relatie een aanmaningsniveau bereikt waarvoor een manuele "
+"actie is vereist. "
#. module: account_followup
#: view:res.partner:0
msgid "No Responsible"
-msgstr ""
+msgstr "Niemand verantwoordelijk"
#. module: account_followup
#: model:account_followup.followup.line,description:account_followup.demo_followup_line2
@@ -158,6 +162,24 @@ msgid ""
"\n"
"Best Regards,\n"
msgstr ""
+"\n"
+"Beste %(partner_name)s,\n"
+"\n"
+"Het spijt ons te moeten vaststellen dat, ondanks een eerdere aanmaning, u "
+"nog steeds een openstaand saldo hebt.\n"
+"\n"
+"Wij verzoeken u dringend het openstaande saldo te betalen. Bij gebrek aan "
+"betaling, zijn wij genoodzaakt de verdere levering van goederen en diensten "
+"stop te zetten.\n"
+"Gelieve de betalingen uit te voeren binnen de 8 dagen.\n"
+"\n"
+"Als er een probleem is rond de betaling waarvan wij niet op de hoogte zijn, "
+"kunt u steeds contact opnemen met onze boekhouding, zodat dit snel kan "
+"worden opgelost.\n"
+"\n"
+"Hierna vindt u een overzicht van de vervallen documenten.\n"
+"\n"
+"Hoogachtend,\n"
#. module: account_followup
#: model:email.template,body_html:account_followup.email_template_account_followup_level0
@@ -195,6 +217,38 @@ msgid ""
"\n"
" "
msgstr ""
+"\n"
+"
\n"
+"\n"
+"
Beste ${object.name},
\n"
+"
\n"
+" Volgens onze informatie, heeft u nog een openstaand saldo. Wij verzoeken "
+"u het nodige te doen om deze betaling binnen de 8 dagen over te schrijven op "
+"onze rekening.\n"
+"\n"
+"Indien uw betaling deze e-mail heeft gekruist, mag u dit bericht als "
+"onbestaand beschouwen. Neem gerust contact op met onze boekhouding mocht u "
+"nog vragen hebben.\n"
+"\n"
+"
\n"
+" "
#. module: account_followup
#: view:account_followup.stat.by.partner:0
@@ -209,17 +263,17 @@ msgstr "Totaal debet"
#. module: account_followup
#: field:res.partner,payment_next_action:0
msgid "Next Action"
-msgstr ""
+msgstr "Volgende actie"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid ": Partner Name"
-msgstr ""
+msgstr "Relatienaam"
#. module: account_followup
#: field:account_followup.followup.line,manual_action_responsible_id:0
msgid "Assign a Responsible"
-msgstr ""
+msgstr "Duid iemand aan die verantwoordelijk is"
#. module: account_followup
#: view:account_followup.followup:0
@@ -231,7 +285,7 @@ msgstr "Aanmaning"
#. module: account_followup
#: report:account_followup.followup.print:0
msgid "VAT:"
-msgstr "BTW:"
+msgstr "Btw:"
#. module: account_followup
#: view:account_followup.stat:0
@@ -255,11 +309,24 @@ msgid ""
" same customer, the actions of the most \n"
" overdue invoice will be executed."
msgstr ""
+"Om klanten aan te manen tot betaling, kunt u\n"
+" verschillende acties instellen in functie van de "
+"grootte\n"
+" van het openstaand bedrag. Deze acties worden "
+"samengevoegd\n"
+" in aanmaningsniveaus die worden aangesproken als de\n"
+" vervaldatum van een factuur een ingesteld aantal "
+"dagen\n"
+" overschrijdt. Als de klant ook andere openstaande "
+"facturen heeft,\n"
+" worden de acties uitgevoerd in functie van het "
+"langst \n"
+" openstaande document."
#. module: account_followup
#: report:account_followup.followup.print:0
msgid "Date :"
-msgstr "Datum :"
+msgstr "Datum:"
#. module: account_followup
#: field:account_followup.print,partner_ids:0
@@ -269,43 +336,43 @@ msgstr "Relaties"
#. module: account_followup
#: sql_constraint:account_followup.followup:0
msgid "Only one follow-up per company is allowed"
-msgstr ""
+msgstr "Per bedrijf is maar een aanmaningsniveau toegelaten."
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:254
#, python-format
msgid "Invoices Reminder"
-msgstr "Facturen aanmaning"
+msgstr "Aanmaning facturen"
#. module: account_followup
#: help:account_followup.followup.line,send_letter:0
msgid "When processing, it will print a letter"
-msgstr ""
+msgstr "Bij verwerking wordt een brief gemaakt"
#. module: account_followup
#: field:res.partner,payment_earliest_due_date:0
msgid "Worst Due Date"
-msgstr ""
+msgstr "Slechtste vervaldatum"
#. module: account_followup
#: view:account_followup.stat:0
msgid "Not Litigation"
-msgstr ""
+msgstr "Geen betwisting"
#. module: account_followup
#: view:account_followup.print:0
msgid "Send emails and generate letters"
-msgstr ""
+msgstr "Verstuur e-mails en maak brieven"
#. module: account_followup
#: model:ir.actions.act_window,name:account_followup.action_customer_followup
msgid "Manual Follow-Ups"
-msgstr ""
+msgstr "Manuele aanmaningen"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(partner_name)s"
-msgstr ""
+msgstr "%(partner_name)s"
#. module: account_followup
#: model:email.template,body_html:account_followup.email_template_account_followup_level1
@@ -347,6 +414,42 @@ msgid ""
"\n"
" "
msgstr ""
+"\n"
+"
\n"
+" \n"
+"
Beste ${object.name},
\n"
+"
\n"
+" Het spijt ons te moeten vaststellen dat, ondanks een eerdere aanmaning, "
+"u nog steeds een openstaand saldo hebt.\n"
+"Wij verzoeken u dringend het openstaande saldo te betalen. Bij gebrek aan "
+"betaling, zijn wij genoodzaakt de verdere levering van goederen en diensten "
+"stop te zetten.\n"
+"Gelieve de betalingen uit te voeren binnen de 8 dagen.\n"
+"\n"
+"Als er een probleem is rond de betaling waarvan wij niet op de hoogte zijn, "
+"kunt u steeds contact opnemen met onze boekhouding, zodat dit snel kan "
+"worden opgelost.\n"
+"\n"
+"Hierna vindt u een overzicht van de vervallen documenten.\n"
+"
\n"
+" "
#. module: account_followup
#: field:account_followup.stat,debit:0
@@ -356,49 +459,49 @@ msgstr "Debet"
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_followup_stat
msgid "Follow-up Statistics"
-msgstr ""
+msgstr "Aanmaningsstatistieken"
#. module: account_followup
#: view:res.partner:0
msgid "Send Overdue Email"
-msgstr ""
+msgstr "Aanmaningsmail sturen"
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_followup_followup_line
msgid "Follow-up Criteria"
-msgstr ""
+msgstr "Aanmaningscriteria"
#. module: account_followup
#: help:account_followup.followup.line,sequence:0
msgid "Gives the sequence order when displaying a list of follow-up lines."
-msgstr "Bepaalt de volgorde bij het afbeelden van de aanmaningregels"
+msgstr "Bepaalt de volgorde bij het weergeven van de aanmaningslijnen."
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:166
#, python-format
msgid " will be sent"
-msgstr ""
+msgstr " wordt verstuurd"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid ": User's Company Name"
-msgstr ""
+msgstr "Bedrijfsnaam van gebruiker"
#. module: account_followup
#: view:account_followup.followup.line:0
#: field:account_followup.followup.line,send_letter:0
msgid "Send a Letter"
-msgstr ""
+msgstr "Brief sturen"
#. module: account_followup
#: model:ir.actions.act_window,name:account_followup.action_account_followup_definition_form
msgid "Payment Follow-ups"
-msgstr ""
+msgstr "Aanmaningen"
#. module: account_followup
#: field:account_followup.followup.line,delay:0
msgid "Due Days"
-msgstr ""
+msgstr "Dagen vervallen"
#. module: account_followup
#: field:account.move.line,followup_line_id:0
@@ -414,48 +517,48 @@ msgstr "Laatste aanmaning"
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.menu_manual_reconcile_followup
msgid "Reconcile Invoices & Payments"
-msgstr ""
+msgstr "Facturen en betalingen afpunten"
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.account_followup_s
msgid "Do Manual Follow-Ups"
-msgstr ""
+msgstr "Manuele aanmaningen uitvoeren"
#. module: account_followup
#: report:account_followup.followup.print:0
msgid "Li."
-msgstr ""
+msgstr "Bt."
#. module: account_followup
#: field:account_followup.print,email_conf:0
msgid "Send Email Confirmation"
-msgstr ""
+msgstr "Bevestiging per e-mail sturen"
#. module: account_followup
#: view:account_followup.stat:0
msgid "Follow-up Entries with period in current year"
-msgstr ""
+msgstr "Aanmaningen met periode in huidig jaar"
#. module: account_followup
#: field:account_followup.stat.by.partner,date_followup:0
msgid "Latest follow-up"
-msgstr ""
+msgstr "Laatste aanmaning"
#. module: account_followup
#: field:account_followup.print,partner_lang:0
msgid "Send Email in Partner Language"
-msgstr "Stuur email-bericht in taal relatie"
+msgstr "Stuur e-mail in taal relatie"
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:169
#, python-format
msgid " email(s) sent"
-msgstr ""
+msgstr " e-mail(s) verstuurd"
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_followup_print
msgid "Print Follow-up & Send Mail to Customers"
-msgstr ""
+msgstr "Aanmaningen afdrukken & mail sturen naar klanten"
#. module: account_followup
#: field:account_followup.followup.line,description:0
@@ -466,12 +569,12 @@ msgstr "Afgedrukt bericht"
#: code:addons/account_followup/wizard/account_followup_print.py:155
#, python-format
msgid "Anybody"
-msgstr ""
+msgstr "Iedereen"
#. module: account_followup
#: help:account_followup.followup.line,send_email:0
msgid "When processing, it will send an email"
-msgstr ""
+msgstr "Bij verwerking wordt een e-mail verstuurd"
#. module: account_followup
#: view:account_followup.stat.by.partner:0
@@ -481,7 +584,7 @@ msgstr "Relatie voor aanmaning"
#. module: account_followup
#: view:res.partner:0
msgid "Print Overdue Payments"
-msgstr ""
+msgstr "Vervallen documenten afdrukken"
#. module: account_followup
#: field:account_followup.followup.line,followup_id:0
@@ -494,11 +597,13 @@ msgstr "Aanmaningen"
#, python-format
msgid "Email not sent because of email address of partner not filled in"
msgstr ""
+"E-mail is niet verstuurd, omdat er voor de relatie geen e-mailadres is "
+"ingevuld."
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_followup_followup
msgid "Account Follow-up"
-msgstr ""
+msgstr "Aanmaningen"
#. module: account_followup
#: help:res.partner,payment_responsible_id:0
@@ -506,11 +611,13 @@ msgid ""
"Optionally you can assign a user to this field, which will make him "
"responsible for the action."
msgstr ""
+"U kunt eventueel een gebruiker toewijzen aan dit veld. Dit betekent dat hij "
+"verantwoordelijk is voor deze actie."
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_followup_sending_results
msgid "Results from the sending of the different letters and emails"
-msgstr ""
+msgstr "Resultaten van het versturen van brieven en e-mails"
#. module: account_followup
#: constraint:account_followup.followup.line:0
@@ -518,43 +625,45 @@ msgid ""
"Your description is invalid, use the right legend or %% if you want to use "
"the percent character."
msgstr ""
+"Uw beschrijving is niet geldig. Gebruik de juiste parameter of %% als u het "
+"percentageteken wilt gebruiken."
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:172
#, python-format
msgid " manual action(s) assigned:"
-msgstr ""
+msgstr " manuele actie(s) toegewezen"
#. module: account_followup
#: view:res.partner:0
msgid "Search Partner"
-msgstr ""
+msgstr "Relatie zoeken"
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.account_followup_print_menu
msgid "Send Letters and Emails"
-msgstr ""
+msgstr "Brieven en e-mails sturen"
#. module: account_followup
#: view:account_followup.followup:0
msgid "Search Follow-up"
-msgstr ""
+msgstr "Aanmaningen zoeken"
#. module: account_followup
#: view:res.partner:0
msgid "Account Move line"
-msgstr ""
+msgstr "Boeking"
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:237
#, python-format
msgid "Send Letters and Emails: Actions Summary"
-msgstr ""
+msgstr "Brieven en e-mails sturen: overzicht acties"
#. module: account_followup
#: view:account_followup.print:0
msgid "or"
-msgstr ""
+msgstr "of"
#. module: account_followup
#: view:res.partner:0
@@ -562,21 +671,23 @@ msgid ""
"If not specified by the latest follow-up level, it will send from the "
"default email template"
msgstr ""
+"Indien dit niet is ingesteld via de laatste aanmaning, dan wordt de "
+"standaard e-mailsjabloon gebruikt."
#. module: account_followup
#: sql_constraint:account_followup.followup.line:0
msgid "Days of the follow-up levels must be different"
-msgstr ""
+msgstr "De dagen moeten verschillen per aanmaningsniveau."
#. module: account_followup
#: view:res.partner:0
msgid "Click to mark the action as done."
-msgstr ""
+msgstr "Klik om de actie als Gedaan te markeren."
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.menu_action_followup_stat_follow
msgid "Follow-Ups Analysis"
-msgstr ""
+msgstr "Aanmaningsanalyse"
#. module: account_followup
#: help:res.partner,payment_next_action_date:0
@@ -586,11 +697,15 @@ msgid ""
"action. Can be practical to set manually e.g. to see if he keeps his "
"promises."
msgstr ""
+"Dit is als er manuele opvolging nodig is. De datum wordt ingesteld op de "
+"huidige datum als de relatie een aanmaningsniveau bereikt waarvoor een "
+"manuele handeling nodig is. Kan handig zijn om dit als manueel in te "
+"stellen, vb. om na te gaan of beloften worden nagekomen."
#. module: account_followup
#: view:res.partner:0
msgid "Print overdue payments report independent of follow-up line"
-msgstr ""
+msgstr "Aanmaningen afdrukken onafgezien van de aanmaningslijn."
#. module: account_followup
#: help:account_followup.print,date:0
@@ -609,7 +724,7 @@ msgstr "Verzenddatum aanmaning"
#: view:res.partner:0
#: field:res.partner,payment_responsible_id:0
msgid "Follow-up Responsible"
-msgstr ""
+msgstr "Verantwoordelijk voor aanmaning"
#. module: account_followup
#: model:email.template,body_html:account_followup.email_template_account_followup_level2
@@ -646,16 +761,48 @@ msgid ""
"\n"
" "
msgstr ""
+"\n"
+"
\n"
+" \n"
+"
Beste ${object.name},
\n"
+"
\n"
+" Ondanks het feit dat wij u meerdere aanmaningen hebben gestuurd, is uw "
+"openstaand saldo nog steeds niet betaald.\n"
+"Indien de betaling ervan niet binnen de 8 dagen op onze rekening staat, "
+"schakelen wij een advocaat in om het verschuldigde saldo bij u te innen. U "
+"ontvangt hierover geen verdere communicatie.\n"
+"Wij gaan ervan uit dat deze stap niet nodig zal zijn. De details van de "
+"openstaande betalingen vindt u hierna.\n"
+"Aarzel niet contact op te nemen met onze boekhouding als u nog vragen "
+"heeft.\n"
+"
\n"
+" "
#. module: account_followup
#: report:account_followup.followup.print:0
msgid "Document : Customer account statement"
-msgstr ""
+msgstr "Document: Rekeninguittreksel"
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.account_followup_menu
msgid "Follow-up Levels"
-msgstr ""
+msgstr "Aanmaningsniveaus"
#. module: account_followup
#: model:account_followup.followup.line,description:account_followup.demo_followup_line4
@@ -678,11 +825,27 @@ msgid ""
"Best Regards,\n"
" "
msgstr ""
+"\n"
+"Beste %(partner_name)s,\n"
+"\n"
+"Ondanks meerdere aanmaningen, merken wij dat uw saldo nog steeds openstaat.\n"
+"\n"
+"Indien het openstaande saldo niet binnen 8 dagen op onze rekening is gestort "
+", zullen wij een advocaat inschakelen. Wij sturen in dat verband geen "
+"bericht meer.\n"
+"\n"
+"Wij gaan ervan uit dat deze actie niet nodig zal zijn. Details van de "
+"openstaande documenten vindt u hierbij.\n"
+"\n"
+"Aarzel niet contact op te nemen met de boekhouding als u nog vragen heeft.\n"
+"\n"
+"Hoogachtend,\n"
+" "
#. module: account_followup
#: field:res.partner,payment_amount_due:0
msgid "Amount Due"
-msgstr ""
+msgstr "Vervallen bedrag"
#. module: account_followup
#: field:account.move.line,followup_date:0
@@ -692,19 +855,19 @@ msgstr "Laatste aanmaning"
#. module: account_followup
#: view:account_followup.sending.results:0
msgid "Download Letters"
-msgstr ""
+msgstr "Brieven downloaden"
#. module: account_followup
#: field:account_followup.print,company_id:0
#: field:res.partner,unreconciled_aml_ids:0
msgid "unknown"
-msgstr ""
+msgstr "onbekend"
#. module: account_followup
#: code:addons/account_followup/account_followup.py:314
#, python-format
msgid "Printed overdue payments report"
-msgstr ""
+msgstr "Afgedrukt aanmaningsrapport"
#. module: account_followup
#: help:account_followup.followup.line,manual_action:0
@@ -712,6 +875,7 @@ msgid ""
"When processing, it will set the manual action to be taken for that "
"customer. "
msgstr ""
+"Bij verwerking zal de manuele actie voor die klant worden ingesteld. "
#. module: account_followup
#: view:res.partner:0
@@ -721,18 +885,25 @@ msgid ""
" order to exclude it from the next follow-up "
"actions."
msgstr ""
+"Hieronder vindt u een overzicht van de transacties voor deze\n"
+" klant. U kunt \"Stuur geen aanmaning\" kiezen "
+"om\n"
+" de factuur uit te sluiten van volgende "
+"aanmaningsacties."
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:171
#, python-format
msgid " email(s) should have been sent, but "
-msgstr ""
+msgstr " e-mail(s) zouden moeten zijn verstuurd, maar "
#. module: account_followup
#: help:account_followup.print,test_print:0
msgid ""
"Check if you want to print follow-ups without changing follow-ups level."
msgstr ""
+"Schakel dit veld in als u aanmaningen wilt afdrukken zonder het niveau te "
+"veranderen."
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_move_line
@@ -742,23 +913,23 @@ msgstr "Boekingen"
#. module: account_followup
#: report:account_followup.followup.print:0
msgid "Total:"
-msgstr ""
+msgstr "Totaal:"
#. module: account_followup
#: field:account_followup.followup.line,email_template_id:0
msgid "Email Template"
-msgstr ""
+msgstr "E-mailsjabloon"
#. module: account_followup
#: field:account_followup.print,summary:0
msgid "Summary"
-msgstr ""
+msgstr "Overzicht"
#. module: account_followup
#: view:account_followup.followup.line:0
#: field:account_followup.followup.line,send_email:0
msgid "Send an Email"
-msgstr ""
+msgstr "E-mail versturen"
#. module: account_followup
#: field:account_followup.stat,credit:0
@@ -768,7 +939,7 @@ msgstr "Krediet"
#. module: account_followup
#: field:res.partner,payment_amount_overdue:0
msgid "Amount Overdue"
-msgstr ""
+msgstr "Vervallen bedrag"
#. module: account_followup
#: help:res.partner,latest_followup_level_id_without_lit:0
@@ -776,12 +947,14 @@ msgid ""
"The maximum follow-up level without taking into account the account move "
"lines with litigation"
msgstr ""
+"Het maximale aanmaningsniveau, zonder rekening te houden met boekingen die "
+"worden betwist."
#. module: account_followup
#: view:account_followup.stat:0
#: field:res.partner,latest_followup_date:0
msgid "Latest Follow-up Date"
-msgstr ""
+msgstr "Datum laatste aanmaning"
#. module: account_followup
#: model:email.template,body_html:account_followup.email_template_account_followup_default
@@ -814,6 +987,33 @@ msgid ""
"\n"
" "
msgstr ""
+"\n"
+"
\n"
+" \n"
+"
Beste ${object.name},
\n"
+"
\n"
+" Volgens onze administratie hebben wij het onderstaande bedrag nog niet "
+"ontvangen. Wij verzoeken\n"
+"u het verschuldigde bedrag uiterlijk binnen 8 dagen over te maken.\n"
+"Indien dit schrijven uw betaling heeft gekruist, kunt u deze herinnering als "
+"niet verzonden beschouwen.\n"
+"Voor meer info kunt u steeds contact opnemen met onze boekhouding.\n"
+"
\n"
+" "
#. module: account_followup
#: field:account.move.line,result:0
@@ -826,17 +1026,17 @@ msgstr "Saldo"
#. module: account_followup
#: help:res.partner,payment_note:0
msgid "Payment Note"
-msgstr ""
+msgstr "Betalingsbewijs"
#. module: account_followup
#: view:res.partner:0
msgid "My Follow-ups"
-msgstr ""
+msgstr "Mijn aanmaningen"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "%(company_name)s"
-msgstr ""
+msgstr "%(company_name)s"
#. module: account_followup
#: model:account_followup.followup.line,description:account_followup.demo_followup_line1
@@ -854,28 +1054,40 @@ msgid ""
"\n"
"Best Regards,\n"
msgstr ""
+"\n"
+"Beste %(partner_name)s,\n"
+"\n"
+"Volgens onze administratie hebben wij het onderstaande bedrag nog niet "
+"ontvangen. Wij verzoeken u het verschuldigde bedrag binnen 8 dagen over te "
+"maken.\n"
+"\n"
+"Indien dit schrijven uw betaling heeft gekruist, kunt u deze herinnering als "
+"niet verzonden beschouwen.\n"
+"Voor meer info kunt u steeds contact opnemen met onze boekhouding.\n"
+"\n"
+"Hoogachtend,\n"
#. module: account_followup
#: field:account_followup.stat,date_move_last:0
#: field:account_followup.stat.by.partner,date_move_last:0
msgid "Last move"
-msgstr ""
+msgstr "Laatste boeking"
#. module: account_followup
#: field:account_followup.stat,period_id:0
msgid "Period"
-msgstr ""
+msgstr "Periode"
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:228
#, python-format
msgid "%s partners have no credits and as such the action is cleared"
-msgstr ""
+msgstr "%s relaties hebben geen schulden en de actie wordt gewist"
#. module: account_followup
#: model:ir.actions.report.xml,name:account_followup.account_followup_followup_report
msgid "Follow-up Report"
-msgstr ""
+msgstr "Aanmaningsrapport"
#. module: account_followup
#: view:res.partner:0
@@ -883,48 +1095,50 @@ msgid ""
", the latest payment follow-up\n"
" was:"
msgstr ""
+", het laatste aanmaningsniveau\n"
+" was:"
#. module: account_followup
#: view:account_followup.print:0
msgid "Cancel"
-msgstr ""
+msgstr "Annuleren"
#. module: account_followup
#: view:account_followup.sending.results:0
msgid "Close"
-msgstr ""
+msgstr "Afsluiten"
#. module: account_followup
#: view:account_followup.stat:0
msgid "Litigation"
-msgstr ""
+msgstr "Betwist"
#. module: account_followup
#: field:account_followup.stat.by.partner,max_followup_id:0
msgid "Max Follow Up Level"
-msgstr ""
+msgstr "Max. aanmaningsniveau"
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:171
#, python-format
msgid " had unknown email address(es)"
-msgstr ""
+msgstr " had een onbekend e-mailadres"
#. module: account_followup
#: view:res.partner:0
msgid "Responsible"
-msgstr ""
+msgstr "Verantwoordelijke"
#. module: account_followup
#: model:ir.ui.menu,name:account_followup.menu_finance_followup
#: view:res.partner:0
msgid "Payment Follow-up"
-msgstr ""
+msgstr "Aanmaningen"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid ": Current Date"
-msgstr ""
+msgstr ": Huidige datum"
#. module: account_followup
#: view:account_followup.print:0
@@ -933,16 +1147,19 @@ msgid ""
" set the manual actions per customer, according to "
"the follow-up levels defined."
msgstr ""
+"Met deze actie stuurt u aanmaningsmails, kunt u brieven afdrukken en\n"
+" manuele acties instellen per klant, in functie van "
+"de ingestelde aanmaningsniveaus."
#. module: account_followup
#: field:account_followup.followup.line,name:0
msgid "Follow-Up Action"
-msgstr ""
+msgstr "Aanmaningsactie"
#. module: account_followup
#: view:account_followup.stat:0
msgid "Including journal entries marked as a litigation"
-msgstr ""
+msgstr "Inclusief betwiste boekingen"
#. module: account_followup
#: report:account_followup.followup.print:0
@@ -955,7 +1172,7 @@ msgstr "Omschrijving"
#. module: account_followup
#: view:account_followup.sending.results:0
msgid "Summary of actions"
-msgstr ""
+msgstr "Overzicht van acties"
#. module: account_followup
#: report:account_followup.followup.print:0
@@ -965,17 +1182,17 @@ msgstr "Ref"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid "After"
-msgstr ""
+msgstr "Na"
#. module: account_followup
#: view:account_followup.stat:0
msgid "This Fiscal year"
-msgstr ""
+msgstr "Dit boekjaar"
#. module: account_followup
#: field:res.partner,latest_followup_level_id_without_lit:0
msgid "Latest Follow-up Level without litigation"
-msgstr ""
+msgstr "Laatste aanmaningsniveau met betwisting"
#. module: account_followup
#: model:ir.actions.act_window,help:account_followup.action_account_manual_reconcile_receivable
@@ -985,16 +1202,20 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Geen boekingen gevonden.\n"
+"
\n"
+" "
#. module: account_followup
#: view:account.move.line:0
msgid "Partner entries"
-msgstr ""
+msgstr "Relatieboekingen"
#. module: account_followup
#: view:account_followup.stat:0
msgid "Follow-up lines"
-msgstr ""
+msgstr "Aanmaningsregels"
#. module: account_followup
#: model:account_followup.followup.line,description:account_followup.demo_followup_line3
@@ -1015,6 +1236,21 @@ msgid ""
"\n"
"Best Regards,\n"
msgstr ""
+"\n"
+"Beste %(partner_name)s,\n"
+"\n"
+"Ondanks eerdere aanmaningen, heeft u nog steeds een openstaand saldo.\n"
+"\n"
+"Als uw betaling binnen de 8 dagen opnieuw uitblijft, zijn wij genoodzaakt de "
+"vordering definitief uit handen te geven.\n"
+"\n"
+"Wij vertrouwen erop dat u het niet zover zult laten komen. Details van hety "
+"openstaande saldo vindt u hierna.\n"
+"\n"
+"Indien u nog vragen heeft, kunt u steeds contact opnemen met onze "
+"boekhouding.\n"
+"\n"
+"Hoogachtend,\n"
#. module: account_followup
#: help:account_followup.print,partner_lang:0
@@ -1022,6 +1258,8 @@ msgid ""
"Do not change message text, if you want to send email in partner language, "
"or configure from company"
msgstr ""
+"Wijzig de tekst niet als u de e-mail in de taal van de relatie wilt sturen, "
+"of stel de tekst in op firma."
#. module: account_followup
#: view:account_followup.followup.line:0
@@ -1034,12 +1272,18 @@ msgid ""
"installed\n"
" using to top right icon."
msgstr ""
+"Schrijf hier de inleiding van uw brief,\n"
+" in functie van het aanmaningsniveau. U kunt\n"
+" de volgende parameters in de tekst gebruiken. "
+"Vergeet\n"
+" niet all geïnstalleerde talen te vertalen via "
+"het pictogram in de rechterbovenhoek."
#. module: account_followup
#: view:account_followup.stat:0
#: model:ir.actions.act_window,name:account_followup.action_followup_stat
msgid "Follow-ups Sent"
-msgstr ""
+msgstr "Verstuurde aanmaningen"
#. module: account_followup
#: field:account_followup.followup,name:0
@@ -1049,34 +1293,34 @@ msgstr "Naam:"
#. module: account_followup
#: field:res.partner,latest_followup_level_id:0
msgid "Latest Follow-up Level"
-msgstr ""
+msgstr "Laatste aanmaningsniveau"
#. module: account_followup
#: field:account_followup.stat,date_move:0
#: field:account_followup.stat.by.partner,date_move:0
msgid "First move"
-msgstr ""
+msgstr "Eerste boeking"
#. module: account_followup
#: model:ir.model,name:account_followup.model_account_followup_stat_by_partner
msgid "Follow-up Statistics by Partner"
-msgstr ""
+msgstr "Aanmaningsstatistieken per relatie"
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:172
#, python-format
msgid " letter(s) in report"
-msgstr ""
+msgstr " brieven in rapport"
#. module: account_followup
#: view:res.partner:0
msgid "Partners with Overdue Credits"
-msgstr ""
+msgstr "Klanten met openstaande facturen"
#. module: account_followup
#: view:res.partner:0
msgid "Customer Followup"
-msgstr ""
+msgstr "Aanmaningen"
#. module: account_followup
#: model:ir.actions.act_window,help:account_followup.action_account_followup_definition_form
@@ -1092,42 +1336,52 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik als u de aanmaningsniveaus wilt instellen met de "
+"daaraan gekoppelde acties.\n"
+"
\n"
+" Per stap kunt u de acties opgeven en ook de dagen vervallen. "
+"U kunt\n"
+" brieven en e-mailsjablonen maken om specifieke berichten "
+"naar de klant te sturen.\n"
+"
\n"
+" "
#. module: account_followup
#: code:addons/account_followup/wizard/account_followup_print.py:166
#, python-format
msgid "Follow-up letter of "
-msgstr ""
+msgstr "Aanmaningsbrief van "
#. module: account_followup
#: view:res.partner:0
msgid "The"
-msgstr ""
+msgstr "De"
#. module: account_followup
#: view:account_followup.print:0
msgid "Send follow-ups"
-msgstr ""
+msgstr "Aanmaningen versturen"
#. module: account_followup
#: view:account.move.line:0
msgid "Total credit"
-msgstr ""
+msgstr "Totaal credit"
#. module: account_followup
#: field:account_followup.followup.line,sequence:0
msgid "Sequence"
-msgstr ""
+msgstr "Volgorde"
#. module: account_followup
#: view:res.partner:0
msgid "Follow-ups To Do"
-msgstr ""
+msgstr "Te versturen aanmaningen"
#. module: account_followup
#: report:account_followup.followup.print:0
msgid "Customer Ref :"
-msgstr ""
+msgstr "Klantenref.:"
#. module: account_followup
#: report:account_followup.followup.print:0
@@ -1141,26 +1395,30 @@ msgid ""
"the reminder. Could be negative if you want to send a polite alert "
"beforehand."
msgstr ""
+"Het aantal dagen dat de vervaldatum van de factuur moet zijn overschreden "
+"voordat een aanmaning wordt verstuurd. Kan negatief zijn als u vooraf een "
+"vriendelijk bericht wilt sturen."
#. module: account_followup
#: help:res.partner,latest_followup_date:0
msgid "Latest date that the follow-up level of the partner was changed"
msgstr ""
+"Laatste datum waarop het aanmaningsniveau van de relatie is gewijzigd."
#. module: account_followup
#: field:account_followup.print,test_print:0
msgid "Test Print"
-msgstr ""
+msgstr "Testafdruk"
#. module: account_followup
#: view:account_followup.followup.line:0
msgid ": User Name"
-msgstr ""
+msgstr ": Gberuikersnaam"
#. module: account_followup
#: view:res.partner:0
msgid "Accounting"
-msgstr ""
+msgstr "Boekhouding"
#. module: account_followup
#: field:account_followup.stat,blocked:0
@@ -1170,7 +1428,7 @@ msgstr "Geblokkeerd"
#. module: account_followup
#: field:res.partner,payment_note:0
msgid "Customer Payment Promise"
-msgstr ""
+msgstr "Betalingsbelofte klant"
#~ msgid "All payable entries"
#~ msgstr "Alle crediteuren"
diff --git a/addons/account_followup/report/account_followup_report.py b/addons/account_followup/report/account_followup_report.py
index 9ca8d3c2332..8d120cb88ba 100644
--- a/addons/account_followup/report/account_followup_report.py
+++ b/addons/account_followup/report/account_followup_report.py
@@ -91,6 +91,5 @@ class account_followup_stat(osv.osv):
GROUP BY
l.id, l.partner_id, l.company_id, l.blocked, l.period_id
)""")
-account_followup_stat()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py
index 37b4300b03f..c14b5c071f6 100644
--- a/addons/account_followup/wizard/account_followup_print.py
+++ b/addons/account_followup/wizard/account_followup_print.py
@@ -72,7 +72,6 @@ class account_followup_stat_by_partner(osv.osv):
GROUP BY
l.partner_id, l.company_id
)""") #Blocked is to take into account litigation
-account_followup_stat_by_partner()
class account_followup_sending_results(osv.osv_memory):
@@ -106,7 +105,6 @@ class account_followup_sending_results(osv.osv_memory):
'description':_get_description,
}
-account_followup_sending_results()
class account_followup_print(osv.osv_memory):
@@ -315,6 +313,5 @@ class account_followup_print(osv.osv_memory):
to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': stat_line_id}
return {'partner_ids': partner_list, 'to_update': to_update}
-account_followup_print()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/account_invoice.py b/addons/account_payment/account_invoice.py
index bcce77a54ce..8fa98780c83 100644
--- a/addons/account_payment/account_invoice.py
+++ b/addons/account_payment/account_invoice.py
@@ -42,6 +42,5 @@ class Invoice(osv.osv):
raise osv.except_osv(_('Error!'), _("You cannot cancel an invoice which has already been imported in a payment order. Remove it from the following payment order : %s."%(payment_order_name)))
return super(Invoice, self).action_cancel(cr, uid, ids, context=context)
-Invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/account_move_line.py b/addons/account_payment/account_move_line.py
index c601d9e8da3..266876db95f 100644
--- a/addons/account_payment/account_move_line.py
+++ b/addons/account_payment/account_move_line.py
@@ -57,6 +57,5 @@ class account_move_line(osv.osv):
raise osv.except_osv(_('Error!'), _('There is no partner defined on the entry line.'))
return line2bank
-account_move_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/account_payment.py b/addons/account_payment/account_payment.py
index 2b0fe1271d2..dc001e2e2a3 100644
--- a/addons/account_payment/account_payment.py
+++ b/addons/account_payment/account_payment.py
@@ -62,7 +62,6 @@ class payment_mode(osv.osv):
return {'value': result}
-payment_mode()
class payment_order(osv.osv):
_name = 'payment.order'
@@ -170,7 +169,6 @@ class payment_order(osv.osv):
payment_line_obj.write(cr, uid, payment_line_ids, {'date': False}, context=context)
return super(payment_order, self).write(cr, uid, ids, vals, context=context)
-payment_order()
class payment_line(osv.osv):
_name = 'payment.line'
@@ -417,6 +415,5 @@ class payment_line(osv.osv):
res['communication2']['states']['normal'] = [('readonly', False)]
return res
-payment_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/report/order.rml b/addons/account_payment/report/order.rml
index ca2315d81b1..02675baf0b2 100644
--- a/addons/account_payment/report/order.rml
+++ b/addons/account_payment/report/order.rml
@@ -253,10 +253,10 @@
[[ get_invoice_name(line.ml_inv_ref.id) or '-' ]]
- [[line.date=='False' and '-' or formatLang(line.date,date=True) ]]
+ [[not line.date and '-' or formatLang(line.date,date=True) ]]
- [[ formatLang(line.amount or '-', currency_obj=line.company_currency) ]]
+ [[ formatLang(line.amount or 0.0, currency_obj=line.company_currency) ]]
[[ formatLang(line.amount_currency, currency_obj=line.currency) ]]
diff --git a/addons/account_payment/wizard/account_payment_order.py b/addons/account_payment/wizard/account_payment_order.py
index 4bd969726fe..08d36c45eff 100644
--- a/addons/account_payment/wizard/account_payment_order.py
+++ b/addons/account_payment/wizard/account_payment_order.py
@@ -118,6 +118,5 @@ class payment_order_create(osv.osv_memory):
'target': 'new',
}
-payment_order_create()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/wizard/account_payment_pay.py b/addons/account_payment/wizard/account_payment_pay.py
index 03ff46125f5..5e2dc652068 100644
--- a/addons/account_payment/wizard/account_payment_pay.py
+++ b/addons/account_payment/wizard/account_payment_pay.py
@@ -54,6 +54,5 @@ class account_payment_make_payment(osv.osv_memory):
# id = obj_model.read(cr, uid, [result], ['res_id'])[0]['res_id']
# return obj_act.read(cr, uid, [id])[0]
-account_payment_make_payment()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/wizard/account_payment_populate_statement.py b/addons/account_payment/wizard/account_payment_populate_statement.py
index edd47065e3a..92b1b1452f5 100644
--- a/addons/account_payment/wizard/account_payment_populate_statement.py
+++ b/addons/account_payment/wizard/account_payment_populate_statement.py
@@ -118,6 +118,5 @@ class account_payment_populate_statement(osv.osv_memory):
line_obj.write(cr, uid, [line.id], {'bank_statement_line_id': st_line_id})
return {'type': 'ir.actions.act_window_close'}
-account_payment_populate_statement()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_sequence/account_sequence.py b/addons/account_sequence/account_sequence.py
index 5b344600599..3b8b2335068 100644
--- a/addons/account_sequence/account_sequence.py
+++ b/addons/account_sequence/account_sequence.py
@@ -40,7 +40,6 @@ class account_move(osv.osv):
self.write(cr, uid, [move.id], {'internal_sequence_number': seq_no})
return res
-account_move()
class account_journal(osv.osv):
_inherit = "account.journal"
@@ -49,7 +48,6 @@ class account_journal(osv.osv):
'internal_sequence_id': fields.many2one('ir.sequence', 'Internal Sequence', help="This sequence will be used to maintain the internal number for the journal entries related to this journal."),
}
-account_journal()
class account_move_line(osv.osv):
_inherit = "account.move.line"
@@ -58,6 +56,5 @@ class account_move_line(osv.osv):
'internal_sequence_number': fields.related('move_id','internal_sequence_number', type='char', relation='account.move', help='Internal Sequence Number', string='Internal Number'),
}
-account_move_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_sequence/account_sequence_installer.py b/addons/account_sequence/account_sequence_installer.py
index e800bbad7ee..91316a61962 100644
--- a/addons/account_sequence/account_sequence_installer.py
+++ b/addons/account_sequence/account_sequence_installer.py
@@ -79,6 +79,5 @@ class account_sequence_installer(osv.osv_memory):
ir_values_obj.set(cr, uid, key='default', key2=False, name='internal_sequence_id', models =[('account.journal', False)], value=ir_seq)
return res
-account_sequence_installer()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_test/account_test.py b/addons/account_test/account_test.py
index da7bb8e308d..98e27380837 100644
--- a/addons/account_test/account_test.py
+++ b/addons/account_test/account_test.py
@@ -56,5 +56,4 @@ class accounting_assert_test(osv.osv):
'sequence': 10,
}
-accounting_assert_test()
diff --git a/addons/account_voucher/account_voucher.py b/addons/account_voucher/account_voucher.py
index c6f754ed18f..b176c3b8fd9 100644
--- a/addons/account_voucher/account_voucher.py
+++ b/addons/account_voucher/account_voucher.py
@@ -40,7 +40,6 @@ class res_company(osv.osv):
domain="[('type', '=', 'other')]",),
}
-res_company()
class account_config_settings(osv.osv_memory):
_inherit = 'account.config.settings'
@@ -85,7 +84,7 @@ class account_voucher(osv.osv):
if context is None: context = {}
if context.get('period_id', False):
return context.get('period_id')
- periods = self.pool.get('account.period').find(cr, uid)
+ periods = self.pool.get('account.period').find(cr, uid, context=context)
return periods and periods[0] or False
def _make_journal_search(self, cr, uid, ttype, context=None):
@@ -1488,7 +1487,6 @@ class account_voucher_line(osv.osv):
'type':ttype
})
return values
-account_voucher_line()
class account_bank_statement(osv.osv):
_inherit = 'account.bank.statement'
@@ -1540,7 +1538,6 @@ class account_bank_statement(osv.osv):
raise osv.except_osv(_('Unable to change journal !'), _('You can not change the journal as you already reconciled some statement lines!'))
return super(account_bank_statement, self).write(cr, uid, ids, vals, context=context)
-account_bank_statement()
class account_bank_statement_line(osv.osv):
_inherit = 'account.bank.statement.line'
@@ -1594,7 +1591,6 @@ class account_bank_statement_line(osv.osv):
voucher_obj.unlink(cr, uid, unlink_ids, context=context)
return super(account_bank_statement_line, self).unlink(cr, uid, ids, context=context)
-account_bank_statement_line()
def resolve_o2m_operations(cr, uid, target_osv, operations, fields, context):
results = []
diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml
index f429480f656..4674d62b6a0 100644
--- a/addons/account_voucher/account_voucher_view.xml
+++ b/addons/account_voucher/account_voucher_view.xml
@@ -129,7 +129,7 @@
-
+
diff --git a/addons/account_voucher/i18n/nl_BE.po b/addons/account_voucher/i18n/nl_BE.po
index 0cdc8cd8399..a58e655aec6 100644
--- a/addons/account_voucher/i18n/nl_BE.po
+++ b/addons/account_voucher/i18n/nl_BE.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-12-19 18:04+0000\n"
+"PO-Revision-Date: 2013-04-26 16:01+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Els Van Vossel\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:33+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-27 05:44+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
"Language: nl\n"
#. module: account_voucher
@@ -138,6 +138,8 @@ msgid ""
"You can not change the journal as you already reconciled some statement "
"lines!"
msgstr ""
+"U kunt het journaal niet veranderen, omdat er al uittreksellijnen zijn "
+"afgepunt."
#. module: account_voucher
#: view:account.voucher:0
@@ -148,7 +150,7 @@ msgstr "Goedkeuren"
#: model:ir.actions.act_window,name:account_voucher.action_vendor_payment
#: model:ir.ui.menu,name:account_voucher.menu_action_vendor_payment
msgid "Supplier Payments"
-msgstr ""
+msgstr "Leveranciersbetalingen"
#. module: account_voucher
#: model:ir.actions.act_window,help:account_voucher.action_purchase_receipt
@@ -223,7 +225,7 @@ msgstr "Berichten"
#: model:ir.actions.act_window,name:account_voucher.action_purchase_receipt
#: model:ir.ui.menu,name:account_voucher.menu_action_purchase_receipt
msgid "Purchase Receipts"
-msgstr ""
+msgstr "Aankoopbewijzen"
#. module: account_voucher
#: field:account.voucher.line,move_line_id:0
@@ -431,7 +433,7 @@ msgstr "Debet"
#: code:addons/account_voucher/account_voucher.py:1547
#, python-format
msgid "Unable to change journal !"
-msgstr ""
+msgstr "Het dagboek kan niet worden gewijzigd"
#. module: account_voucher
#: view:sale.receipt.report:0
@@ -745,7 +747,7 @@ msgstr "Augustus"
#. module: account_voucher
#: view:account.voucher:0
msgid "Validate Payment"
-msgstr ""
+msgstr "Betaling bevestigen"
#. module: account_voucher
#: help:account.voucher,audit:0
@@ -786,7 +788,7 @@ msgstr "Betaald"
#: model:ir.actions.act_window,name:account_voucher.action_sale_receipt
#: model:ir.ui.menu,name:account_voucher.menu_action_sale_receipt
msgid "Sales Receipts"
-msgstr ""
+msgstr "Verkoopbewijzen"
#. module: account_voucher
#: field:account.voucher,message_is_follower:0
@@ -834,7 +836,7 @@ msgstr "Onmiddellijk betalen"
#. module: account_voucher
#: field:account.voucher.line,type:0
msgid "Dr/Cr"
-msgstr ""
+msgstr "Db/Cr"
#. module: account_voucher
#: field:account.voucher,pre_line:0
@@ -845,7 +847,7 @@ msgstr "Vorige betalingen?"
#: code:addons/account_voucher/account_voucher.py:1112
#, python-format
msgid "The invoice you are willing to pay is not valid anymore."
-msgstr ""
+msgstr "De factuur die u wilt betalen, is niet meer geldig."
#. module: account_voucher
#: selection:sale.receipt.report,month:0
@@ -884,7 +886,7 @@ msgstr "Gelieve een reeks in te stellen voor het journaal."
#: model:ir.actions.act_window,name:account_voucher.action_vendor_receipt
#: model:ir.ui.menu,name:account_voucher.menu_action_vendor_receipt
msgid "Customer Payments"
-msgstr ""
+msgstr "Klantenbetalingen"
#. module: account_voucher
#: model:ir.actions.act_window,name:account_voucher.action_sale_receipt_report_all
@@ -938,7 +940,7 @@ msgstr "Nummer"
#. module: account_voucher
#: selection:account.voucher.line,type:0
msgid "Credit"
-msgstr ""
+msgstr "Credit"
#. module: account_voucher
#: model:ir.model,name:account_voucher.model_account_bank_statement
@@ -1279,7 +1281,7 @@ msgstr "Openstaand saldo"
#. module: account_voucher
#: model:mail.message.subtype,description:account_voucher.mt_voucher_state_change
msgid "Status changed"
-msgstr ""
+msgstr "Status vgewijzigd"
#. module: account_voucher
#: code:addons/account_voucher/account_voucher.py:1014
diff --git a/addons/account_voucher/invoice.py b/addons/account_voucher/invoice.py
index c0584ddbd52..03a3e5fab67 100644
--- a/addons/account_voucher/invoice.py
+++ b/addons/account_voucher/invoice.py
@@ -52,6 +52,5 @@ class invoice(osv.osv):
}
}
-invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_voucher/report/account_voucher_sales_receipt.py b/addons/account_voucher/report/account_voucher_sales_receipt.py
index 2ab76c252f5..246cd8b47e8 100644
--- a/addons/account_voucher/report/account_voucher_sales_receipt.py
+++ b/addons/account_voucher/report/account_voucher_sales_receipt.py
@@ -126,6 +126,5 @@ class sale_receipt_report(osv.osv):
)
""")
-sale_receipt_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_voucher/voucher_payment_receipt_view.xml b/addons/account_voucher/voucher_payment_receipt_view.xml
index de873c9195c..109c2f9aec9 100644
--- a/addons/account_voucher/voucher_payment_receipt_view.xml
+++ b/addons/account_voucher/voucher_payment_receipt_view.xml
@@ -11,7 +11,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml
index 05b783dd339..6a84a09d5e6 100644
--- a/addons/account_voucher/voucher_sales_purchase_view.xml
+++ b/addons/account_voucher/voucher_sales_purchase_view.xml
@@ -10,7 +10,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
diff --git a/addons/account_voucher/wizard/account_statement_from_invoice.py b/addons/account_voucher/wizard/account_statement_from_invoice.py
index fce251df175..de5121a819b 100644
--- a/addons/account_voucher/wizard/account_statement_from_invoice.py
+++ b/addons/account_voucher/wizard/account_statement_from_invoice.py
@@ -123,6 +123,5 @@ class account_statement_from_invoice_lines(osv.osv_memory):
}, context=context)
return {'type': 'ir.actions.act_window_close'}
-account_statement_from_invoice_lines()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py
index 42651acb0c6..ac298713b04 100644
--- a/addons/analytic/analytic.py
+++ b/addons/analytic/analytic.py
@@ -171,9 +171,9 @@ class account_analytic_account(osv.osv):
return result
_columns = {
- 'name': fields.char('Account/Contract Name', size=128, required=True),
+ 'name': fields.char('Account/Contract Name', size=128, required=True, track_visibility='onchange'),
'complete_name': fields.function(_get_full_name, type='char', string='Full Name'),
- 'code': fields.char('Reference', select=True),
+ 'code': fields.char('Reference', select=True, track_visibility='onchange'),
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Contract')], 'Type of Account', required=True,
help="If you select the View Type, it means you won\'t allow to create journal entries using that account.\n"\
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
@@ -191,10 +191,10 @@ class account_analytic_account(osv.osv):
'quantity': fields.function(_debit_credit_bal_qtty, type='float', string='Quantity', multi='debit_credit_bal_qtty'),
'quantity_max': fields.float('Prepaid Service Units', help='Sets the higher limit of time to work on the contract, based on the timesheet. (for instance, number of hours in a limited support contract.)'),
'partner_id': fields.many2one('res.partner', 'Customer'),
- 'user_id': fields.many2one('res.users', 'Project Manager'),
- 'manager_id': fields.many2one('res.users', 'Account Manager'),
+ 'user_id': fields.many2one('res.users', 'Project Manager', track_visibility='onchange'),
+ 'manager_id': fields.many2one('res.users', 'Account Manager', track_visibility='onchange'),
'date_start': fields.date('Start Date'),
- 'date': fields.date('End Date', select=True),
+ 'date': fields.date('End Date', select=True, track_visibility='onchange'),
'company_id': fields.many2one('res.company', 'Company', required=False), #not required because we want to allow different companies to use the same chart of account, except for leaf accounts.
'state': fields.selection([('template', 'Template'),('draft','New'),('open','In Progress'),('pending','To Renew'),('close','Closed'),('cancelled', 'Cancelled')], 'Status', required=True, track_visibility='onchange'),
'currency_id': fields.function(_currency, fnct_inv=_set_company_currency, #the currency_id field is readonly except if it's a view account and if there is no company
diff --git a/addons/analytic/i18n/lt.po b/addons/analytic/i18n/lt.po
new file mode 100644
index 00000000000..d9073313307
--- /dev/null
+++ b/addons/analytic/i18n/lt.po
@@ -0,0 +1,388 @@
+# 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:10+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: analytic
+#: field:account.analytic.account,child_ids:0
+msgid "Child Accounts"
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,state:0
+msgid "In Progress"
+msgstr ""
+
+#. module: analytic
+#: code:addons/analytic/analytic.py:229
+#, python-format
+msgid "Contract: "
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,state:0
+msgid "Template"
+msgstr ""
+
+#. module: analytic
+#: view:account.analytic.account:0
+msgid "End Date"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.line,unit_amount:0
+msgid "Specifies the amount of quantity to count."
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,debit:0
+msgid "Debit"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.account,type:0
+msgid ""
+"If you select the View Type, it means you won't allow to create journal "
+"entries using that account.\n"
+"The type 'Analytic account' stands for usual accounts that you only want to "
+"use in accounting.\n"
+"If you select Contract or Project, it offers you the possibility to manage "
+"the validity and the invoicing options for this account.\n"
+"The special type 'Template of Contract' allows you to define a template with "
+"default data that you can reuse easily."
+msgstr ""
+
+#. module: analytic
+#: view:account.analytic.account:0
+msgid ""
+"Once the end date of the contract is\n"
+" passed or the maximum number of "
+"service\n"
+" units (e.g. support contract) is\n"
+" reached, the account manager is "
+"notified \n"
+" by email to renew the contract with "
+"the\n"
+" customer."
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,type:0
+msgid "Contract or Project"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,name:0
+msgid "Account/Contract Name"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,manager_id:0
+msgid "Account Manager"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,message_follower_ids:0
+msgid "Followers"
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,state:0
+msgid "Closed"
+msgstr ""
+
+#. module: analytic
+#: model:mail.message.subtype,name:analytic.mt_account_pending
+msgid "Contract to Renew"
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,state:0
+msgid "New"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,user_id:0
+msgid "Project Manager"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,state:0
+msgid "Status"
+msgstr ""
+
+#. module: analytic
+#: code:addons/analytic/analytic.py:271
+#, python-format
+msgid "%s (copy)"
+msgstr ""
+
+#. module: analytic
+#: model:ir.model,name:analytic.model_account_analytic_line
+msgid "Analytic Line"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,description:0
+#: field:account.analytic.line,name:0
+msgid "Description"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: analytic
+#: constraint:account.analytic.account:0
+msgid "Error! You cannot create recursive analytic accounts."
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,company_id:0
+#: field:account.analytic.line,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: analytic
+#: view:account.analytic.account:0
+msgid "Renewal"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.account,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
+
+#. module: analytic
+#: model:mail.message.subtype,description:analytic.mt_account_opened
+msgid "Stage opened"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.account,quantity_max:0
+msgid ""
+"Sets the higher limit of time to work on the contract, based on the "
+"timesheet. (for instance, number of hours in a limited support contract.)"
+msgstr ""
+
+#. module: analytic
+#: code:addons/analytic/analytic.py:160
+#, python-format
+msgid ""
+"If you set a company, the currency selected has to be the same as it's "
+"currency. \n"
+"You can remove the company belonging, and thus change the currency, only on "
+"analytic account of type 'view'. This can be really usefull for "
+"consolidation purposes of several companies charts with different "
+"currencies, for example."
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.line,user_id:0
+msgid "User"
+msgstr ""
+
+#. module: analytic
+#: model:mail.message.subtype,description:analytic.mt_account_pending
+msgid "Contract pending"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.line,date:0
+msgid "Date"
+msgstr ""
+
+#. module: analytic
+#: model:mail.message.subtype,name:analytic.mt_account_closed
+msgid "Contract Finished"
+msgstr ""
+
+#. module: analytic
+#: view:account.analytic.account:0
+msgid "Terms and Conditions"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.line,amount:0
+msgid ""
+"Calculated by multiplying the quantity and the price given in the Product's "
+"cost price. Always expressed in the company main currency."
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,partner_id:0
+msgid "Customer"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,child_complete_ids:0
+msgid "Account Hierarchy"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,parent_id:0
+msgid "Parent Analytic Account"
+msgstr ""
+
+#. module: analytic
+#: view:account.analytic.account:0
+msgid "Contract Information"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,template_id:0
+#: selection:account.analytic.account,type:0
+msgid "Template of Contract"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,message_summary:0
+msgid "Summary"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,quantity_max:0
+msgid "Prepaid Service Units"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,credit:0
+msgid "Credit"
+msgstr ""
+
+#. module: analytic
+#: model:mail.message.subtype,name:analytic.mt_account_opened
+msgid "Contract Opened"
+msgstr ""
+
+#. module: analytic
+#: model:mail.message.subtype,description:analytic.mt_account_closed
+msgid "Contract closed"
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,type:0
+msgid "Analytic View"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,balance:0
+msgid "Balance"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.account,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: analytic
+#: selection:account.analytic.account,state:0
+msgid "To Renew"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,quantity:0
+#: field:account.analytic.line,unit_amount:0
+msgid "Quantity"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,date:0
+msgid "Date End"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,code:0
+msgid "Reference"
+msgstr ""
+
+#. module: analytic
+#: code:addons/analytic/analytic.py:160
+#, python-format
+msgid "Error!"
+msgstr ""
+
+#. module: analytic
+#: model:res.groups,name:analytic.group_analytic_accounting
+msgid "Analytic Accounting"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.line,amount:0
+msgid "Amount"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,complete_name:0
+msgid "Full Account Name"
+msgstr ""
+
+#. module: analytic
+#: view:account.analytic.account:0
+#: selection:account.analytic.account,type:0
+#: field:account.analytic.line,account_id:0
+#: model:ir.model,name:analytic.model_account_analytic_account
+msgid "Analytic Account"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,currency_id:0
+msgid "Currency"
+msgstr ""
+
+#. module: analytic
+#: help:account.analytic.account,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: analytic
+#: field:account.analytic.account,type:0
+msgid "Type of Account"
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,date_start:0
+msgid "Start Date"
+msgstr ""
+
+#. module: analytic
+#: constraint:account.analytic.line:0
+msgid "You cannot create analytic line on view account."
+msgstr ""
+
+#. module: analytic
+#: field:account.analytic.account,line_ids:0
+msgid "Analytic Entries"
+msgstr ""
diff --git a/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py b/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py
index 8b10381434d..a1bf43714ce 100644
--- a/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py
+++ b/addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py
@@ -152,6 +152,5 @@ class account_analytic_account(osv.osv):
'nodestroy': True,
}
-account_analytic_account()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/analytic_contract_hr_expense/i18n/nl_BE.po b/addons/analytic_contract_hr_expense/i18n/nl_BE.po
new file mode 100644
index 00000000000..4bc0cc559e5
--- /dev/null
+++ b/addons/analytic_contract_hr_expense/i18n/nl_BE.po
@@ -0,0 +1,72 @@
+# Dutch (Belgium) 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-15 16:33+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Dutch (Belgium) \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-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
+
+#. module: analytic_contract_hr_expense
+#: view:account.analytic.account:0
+msgid "or view"
+msgstr "of bekijk"
+
+#. module: analytic_contract_hr_expense
+#: view:account.analytic.account:0
+msgid "Nothing to invoice, create"
+msgstr "Niets te factureren, aanmaken"
+
+#. module: analytic_contract_hr_expense
+#: view:account.analytic.account:0
+msgid "expenses"
+msgstr "onkosten"
+
+#. module: analytic_contract_hr_expense
+#: model:ir.model,name:analytic_contract_hr_expense.model_account_analytic_account
+msgid "Analytic Account"
+msgstr "Analytische rekening"
+
+#. module: analytic_contract_hr_expense
+#: code:addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py:129
+#, python-format
+msgid "Expenses to Invoice of %s"
+msgstr "Te factureren onkosten van %s"
+
+#. module: analytic_contract_hr_expense
+#: code:addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py:121
+#, python-format
+msgid "Expenses of %s"
+msgstr "Onkosten van %s"
+
+#. module: analytic_contract_hr_expense
+#: field:account.analytic.account,expense_invoiced:0
+#: field:account.analytic.account,expense_to_invoice:0
+#: field:account.analytic.account,remaining_expense:0
+msgid "unknown"
+msgstr "onbekend"
+
+#. module: analytic_contract_hr_expense
+#: field:account.analytic.account,est_expenses:0
+msgid "Estimation of Expenses to Invoice"
+msgstr "Te verwachten te factureren onkosten"
+
+#. module: analytic_contract_hr_expense
+#: field:account.analytic.account,charge_expenses:0
+msgid "Charge Expenses"
+msgstr "Onkosten doorrekenen"
+
+#. module: analytic_contract_hr_expense
+#: view:account.analytic.account:0
+msgid "⇒ Invoice"
+msgstr "⇒ Factuur"
diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py
index de46e2e8d03..025f1f79f70 100644
--- a/addons/anonymization/anonymization.py
+++ b/addons/anonymization/anonymization.py
@@ -411,7 +411,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
model_name = field.model_id.model
field_name = field.field_id.name
field_type = field.field_id.ttype
- table_name = self.pool.get(model_name)._table
+ table_name = self.pool[model_name]._table
# get the current value
sql = "select id, %s from %s" % (field_name, table_name)
@@ -543,7 +543,7 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory):
fixes = group(fixes, ('model_name', 'field_name'))
for line in data:
- table_name = self.pool.get(line['model_id'])._table if self.pool.get(line['model_id']) else None
+ table_name = self.pool[line['model_id']]._table if line['model_id'] in self.pool else None
# check if custom sql exists:
key = (line['model_id'], line['field_id'])
diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py
index 811c5387697..159baf3a9e7 100644
--- a/addons/audittrail/audittrail.py
+++ b/addons/audittrail/audittrail.py
@@ -70,8 +70,7 @@ class audittrail_rule(osv.osv):
obj_model = self.pool.get('ir.model.data')
#start Loop
for thisrule in self.browse(cr, uid, ids):
- obj = self.pool.get(thisrule.object_id.model)
- if not obj:
+ if thisrule.object_id.model not in self.pool:
raise osv.except_osv(
_('WARNING: audittrail is not part of the pool'),
_('Change audittrail depends -- Setting rule as DRAFT'))
@@ -131,7 +130,7 @@ class audittrail_log(osv.osv):
model_object = resname.object_id
res_id = resname.res_id
if model_object and res_id:
- model_pool = self.pool.get(model_object.model)
+ model_pool = self.pool[model_object.model]
res = model_pool.read(cr, uid, res_id, ['name'])
data[resname.id] = res['name']
else:
@@ -190,7 +189,7 @@ def get_value_text(cr, uid, pool, resource_pool, method, field, value):
field_obj = (resource_pool._all_columns.get(field)).column
if field_obj._type in ('one2many','many2many'):
- data = pool.get(field_obj._obj).name_get(cr, uid, value)
+ data = pool[field_obj._obj].name_get(cr, uid, value)
#return the modifications on x2many fields as a list of names
res = map(lambda x:x[1], data)
elif field_obj._type == 'many2one':
@@ -212,7 +211,7 @@ def create_log_line(cr, uid, log_id, model, lines=None):
if lines is None:
lines = []
pool = openerp.registry(cr.dbname)
- obj_pool = pool.get(model.model)
+ obj_pool = pool[model.model]
model_pool = pool.get('ir.model')
field_pool = pool.get('ir.model.fields')
log_line_pool = pool.get('audittrail.log.line')
@@ -251,7 +250,7 @@ def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw):
@return: Returns result as per method of Object proxy
"""
pool = openerp.registry(cr.dbname)
- resource_pool = pool.get(model)
+ resource_pool = pool[model]
model_pool = pool.get('ir.model')
model_ids = model_pool.search(cr, SUPERUSER_ID, [('model', '=', model)])
model_id = model_ids and model_ids[0] or False
@@ -321,7 +320,7 @@ def get_data(cr, uid, pool, res_ids, model, method):
}
"""
data = {}
- resource_pool = pool.get(model.model)
+ resource_pool = pool[model.model]
# read all the fields of the given resources in super admin mode
for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids):
values = {}
@@ -390,7 +389,7 @@ def prepare_audittrail_log_line(cr, uid, pool, model, resource_id, method, old_v
key: []
}
# loop on all the fields
- for field_name, field_definition in pool.get(model.model)._all_columns.items():
+ for field_name, field_definition in pool[model.model]._all_columns.items():
if field_name in ('__last_update', 'id'):
continue
#if the field_list param is given, skip all the fields not in that list
@@ -457,7 +456,7 @@ def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_val
# if at least one modification has been found
for model_id, resource_id in lines:
- name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1]
+ name = pool[model.model].name_get(cr, uid, [resource_id])[0][1]
vals = {
'method': method,
'object_id': model_id,
diff --git a/addons/audittrail/wizard/audittrail_view_log.py b/addons/audittrail/wizard/audittrail_view_log.py
index d06da281933..4385970f8d9 100644
--- a/addons/audittrail/wizard/audittrail_view_log.py
+++ b/addons/audittrail/wizard/audittrail_view_log.py
@@ -61,6 +61,5 @@ class audittrail_view_log(osv.osv_memory):
#End Loop
return result
-audittrail_view_log()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/auth_crypt/i18n/lt.po b/addons/auth_crypt/i18n/lt.po
new file mode 100644
index 00000000000..03f0bd5249f
--- /dev/null
+++ b/addons/auth_crypt/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: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-25 05:20+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
+
+#. module: auth_crypt
+#: field:res.users,password_crypt:0
+msgid "Encrypted Password"
+msgstr "Užšifruotas slaptažodis"
+
+#. module: auth_crypt
+#: model:ir.model,name:auth_crypt.model_res_users
+msgid "Users"
+msgstr "Naudotojai"
diff --git a/addons/auth_crypt/i18n/nl_BE.po b/addons/auth_crypt/i18n/nl_BE.po
index b9477ece5dc..abb65c8700f 100644
--- a/addons/auth_crypt/i18n/nl_BE.po
+++ b/addons/auth_crypt/i18n/nl_BE.po
@@ -1,42 +1,28 @@
# Dutch (Belgium) translation for openobject-addons
-# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2012.
+# FIRST AUTHOR , 2013.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2012-12-03 16:03+0000\n"
-"PO-Revision-Date: 2012-07-26 17:52+0000\n"
-"Last-Translator: FULL NAME \n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-04-15 16:02+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Dutch (Belgium) \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2012-12-04 05:53+0000\n"
-"X-Generator: Launchpad (build 16335)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
-#. module: base_crypt
-#: model:ir.model,name:base_crypt.model_res_users
+#. module: auth_crypt
+#: field:res.users,password_crypt:0
+msgid "Encrypted Password"
+msgstr "Geëncrypteerd wachtwoord"
+
+#. module: auth_crypt
+#: model:ir.model,name:auth_crypt.model_res_users
msgid "Users"
-msgstr ""
-
-#~ msgid "You can not have two users with the same login !"
-#~ msgstr "U kunt geen twee gebruikers met dezelfde login maken."
-
-#, python-format
-#~ msgid "Please specify the password !"
-#~ msgstr "Gelieve een wachtwoord op te geven"
-
-#~ msgid "The chosen company is not in the allowed companies for this user"
-#~ msgstr ""
-#~ "De gekozen firma behoort niet tot de toegelaten bedrijven voor deze "
-#~ "gebruiker."
-
-#~ msgid "res.users"
-#~ msgstr "res.users"
-
-#, python-format
-#~ msgid "Error"
-#~ msgstr "Fout"
+msgstr "Gebruikers"
diff --git a/addons/auth_ldap/users_ldap.py b/addons/auth_ldap/users_ldap.py
index e8778449da5..8e7128ca91e 100644
--- a/addons/auth_ldap/users_ldap.py
+++ b/addons/auth_ldap/users_ldap.py
@@ -227,7 +227,6 @@ class CompanyLDAP(osv.osv):
'create_user': True,
}
-CompanyLDAP()
class res_company(osv.osv):
@@ -236,7 +235,6 @@ class res_company(osv.osv):
'ldaps': fields.one2many(
'res.company.ldap', 'company', 'LDAP Parameters'),
}
-res_company()
class users(osv.osv):
@@ -282,5 +280,4 @@ class users(osv.osv):
cr.close()
raise openerp.exceptions.AccessDenied()
-users()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/auth_oauth_signup/i18n/lt.po b/addons/auth_oauth_signup/i18n/lt.po
new file mode 100644
index 00000000000..27fb83e6a4f
--- /dev/null
+++ b/addons/auth_oauth_signup/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:21+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: auth_oauth_signup
+#: model:ir.model,name:auth_oauth_signup.model_res_users
+msgid "Users"
+msgstr "Naudotojai"
diff --git a/addons/auth_oauth_signup/i18n/nl_BE.po b/addons/auth_oauth_signup/i18n/nl_BE.po
new file mode 100644
index 00000000000..04d5034d029
--- /dev/null
+++ b/addons/auth_oauth_signup/i18n/nl_BE.po
@@ -0,0 +1,23 @@
+# Dutch (Belgium) 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-15 16:01+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Dutch (Belgium) \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-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
+
+#. module: auth_oauth_signup
+#: model:ir.model,name:auth_oauth_signup.model_res_users
+msgid "Users"
+msgstr "Gebruikers"
diff --git a/addons/auth_openid/res_users.py b/addons/auth_openid/res_users.py
index feea2d8d396..47e119f2a1e 100644
--- a/addons/auth_openid/res_users.py
+++ b/addons/auth_openid/res_users.py
@@ -91,7 +91,6 @@ class res_users(osv.osv):
raise
self._uid_cache.setdefault(db, {})[uid] = passwd
-res_users()
diff --git a/addons/auth_signup/i18n/lt.po b/addons/auth_signup/i18n/lt.po
new file mode 100644
index 00000000000..7ae419856e6
--- /dev/null
+++ b/addons/auth_signup/i18n/lt.po
@@ -0,0 +1,279 @@
+# 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:13+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: auth_signup
+#: field:res.partner,signup_type:0
+msgid "Signup Token Type"
+msgstr ""
+
+#. module: auth_signup
+#: field:base.config.settings,auth_signup_uninvited:0
+msgid "Allow external users to sign up"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:16
+#, python-format
+msgid "Confirm Password"
+msgstr ""
+
+#. module: auth_signup
+#: help:base.config.settings,auth_signup_uninvited:0
+msgid "If unchecked, only invited users may sign up."
+msgstr ""
+
+#. module: auth_signup
+#: model:ir.model,name:auth_signup.model_base_config_settings
+msgid "base.config.settings"
+msgstr ""
+
+#. module: auth_signup
+#: code:addons/auth_signup/res_users.py:265
+#, python-format
+msgid "Cannot send email: user has no email address."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:24
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:28
+#, python-format
+msgid "Reset password"
+msgstr ""
+
+#. module: auth_signup
+#: field:base.config.settings,auth_signup_template_user_id:0
+msgid "Template user for new users created through signup"
+msgstr ""
+
+#. module: auth_signup
+#: model:email.template,subject:auth_signup.reset_password_email
+msgid "Password reset"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:117
+#, python-format
+msgid "Please enter a password and confirm it."
+msgstr ""
+
+#. module: auth_signup
+#: view:res.users:0
+msgid "Send an email to the user to (re)set their password."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:23
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:26
+#, python-format
+msgid "Sign Up"
+msgstr ""
+
+#. module: auth_signup
+#: selection:res.users,state:0
+msgid "New"
+msgstr ""
+
+#. module: auth_signup
+#: code:addons/auth_signup/res_users.py:258
+#, python-format
+msgid "Mail sent to:"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.users,state:0
+msgid "Status"
+msgstr ""
+
+#. module: auth_signup
+#: model:email.template,body_html:auth_signup.reset_password_email
+msgid ""
+"\n"
+"
A password reset was requested for the OpenERP account linked to this "
+"email.
\n"
+"\n"
+"
You may change your password by following this link.
\n"
+"\n"
+"
Note: If you do not expect this, you can safely ignore this email.
"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:111
+#, python-format
+msgid "Please enter a name."
+msgstr ""
+
+#. module: auth_signup
+#: model:ir.model,name:auth_signup.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_url:0
+msgid "Signup URL"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:114
+#, python-format
+msgid "Please enter a username."
+msgstr ""
+
+#. module: auth_signup
+#: selection:res.users,state:0
+msgid "Active"
+msgstr ""
+
+#. module: auth_signup
+#: code:addons/auth_signup/res_users.py:269
+#, python-format
+msgid ""
+"Cannot send email: no outgoing email server configured.\n"
+"You can configure it under Settings/General Settings."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:12
+#, python-format
+msgid "Username"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:8
+#, python-format
+msgid "Name"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:170
+#, python-format
+msgid "Please enter a username or email address."
+msgstr ""
+
+#. module: auth_signup
+#: selection:res.users,state:0
+msgid "Resetting Password"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:13
+#, python-format
+msgid "Username (Email)"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_expiration:0
+msgid "Signup Expiration"
+msgstr ""
+
+#. module: auth_signup
+#: help:base.config.settings,auth_signup_reset_password:0
+msgid "This allows users to trigger a password reset from the Login page."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:22
+#, python-format
+msgid "Log in"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_valid:0
+msgid "Signup Token is Valid"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:108
+#: code:addons/auth_signup/static/src/js/auth_signup.js:111
+#: code:addons/auth_signup/static/src/js/auth_signup.js:114
+#: code:addons/auth_signup/static/src/js/auth_signup.js:117
+#: code:addons/auth_signup/static/src/js/auth_signup.js:120
+#: code:addons/auth_signup/static/src/js/auth_signup.js:167
+#: code:addons/auth_signup/static/src/js/auth_signup.js:170
+#, python-format
+msgid "Login"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:94
+#, python-format
+msgid "Invalid signup token"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:120
+#, python-format
+msgid "Passwords do not match; please retype them."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:108
+#: code:addons/auth_signup/static/src/js/auth_signup.js:167
+#, python-format
+msgid "No database selected !"
+msgstr ""
+
+#. module: auth_signup
+#: view:res.users:0
+msgid "Reset Password"
+msgstr ""
+
+#. module: auth_signup
+#: field:base.config.settings,auth_signup_reset_password:0
+msgid "Enable password reset from Login page"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:27
+#, python-format
+msgid "Back to Login"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:22
+#, python-format
+msgid "Sign up"
+msgstr ""
+
+#. module: auth_signup
+#: model:ir.model,name:auth_signup.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_token:0
+msgid "Signup Token"
+msgstr ""
diff --git a/addons/auth_signup/i18n/zh_CN.po b/addons/auth_signup/i18n/zh_CN.po
index 333dd1be2dc..aa8d9f952c1 100644
--- a/addons/auth_signup/i18n/zh_CN.po
+++ b/addons/auth_signup/i18n/zh_CN.po
@@ -8,14 +8,14 @@ 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: 2012-12-04 20:16+0000\n"
-"Last-Translator: 盈通 ccdos \n"
+"PO-Revision-Date: 2013-04-16 04:33+0000\n"
+"Last-Translator: Key \n"
"Language-Team: Chinese (Simplified) \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-03-16 05:52+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-17 05:15+0000\n"
+"X-Generator: Launchpad (build 16567)\n"
#. module: auth_signup
#: field:res.partner,signup_type:0
@@ -73,7 +73,7 @@ msgstr "重置密码"
#: code:addons/auth_signup/static/src/js/auth_signup.js:117
#, python-format
msgid "Please enter a password and confirm it."
-msgstr ""
+msgstr "请输入密码并确认。"
#. module: auth_signup
#: view:res.users:0
diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py
index b5383e41775..f4a985280ac 100644
--- a/addons/auth_signup/res_users.py
+++ b/addons/auth_signup/res_users.py
@@ -200,6 +200,9 @@ class res_users(osv.Model):
'partner_id': partner.id,
'email': values.get('email') or values.get('login'),
})
+ if partner.company_id:
+ values['company_id'] = partner.company_id.id
+ values['company_ids'] = [(6,0,[partner.company_id.id])]
self._signup_create_user(cr, uid, values, context=context)
else:
# no token, sign up an external user
diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index 62c808ed556..9d7d4d34ac4 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -96,7 +96,7 @@ class base_action_rule(osv.osv):
""" filter the list record_ids that satisfy the action filter """
if record_ids and action_filter:
assert action.model == action_filter.model_id, "Filter model different from action rule model"
- model = self.pool.get(action_filter.model_id)
+ model = self.pool[action_filter.model_id]
domain = [('id', 'in', record_ids)] + eval(action_filter.domain)
ctx = dict(context or {})
ctx.update(eval(action_filter.context))
@@ -106,7 +106,7 @@ class base_action_rule(osv.osv):
def _process(self, cr, uid, action, record_ids, context=None):
""" process the given action on the records """
# execute server actions
- model = self.pool.get(action.model_id.model)
+ model = self.pool[action.model_id.model]
if action.server_action_ids:
server_action_ids = map(int, action.server_action_ids)
for record in model.browse(cr, uid, record_ids, context):
@@ -195,7 +195,7 @@ class base_action_rule(osv.osv):
ids = self.search(cr, SUPERUSER_ID, [])
for action_rule in self.browse(cr, SUPERUSER_ID, ids):
model = action_rule.model_id.model
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
if not hasattr(model_obj, 'base_action_ruled'):
model_obj.create = self._wrap_create(model_obj.create, model)
model_obj.write = self._wrap_write(model_obj.write, model)
@@ -232,7 +232,7 @@ class base_action_rule(osv.osv):
last_run = get_datetime(action.last_run) if action.last_run else False
# retrieve all the records that satisfy the action's condition
- model = self.pool.get(action.model_id.model)
+ model = self.pool[action.model_id.model]
domain = []
ctx = dict(context)
if action.filter_id:
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index ca75c9e20fc..896349ec5e6 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -591,7 +591,7 @@ property or property parameter."),
for vals in self.browse(cr, uid, ids, context=context):
if vals.ref and vals.ref.user_id:
- mod_obj = self.pool.get(vals.ref._name)
+ mod_obj = self.pool[vals.ref._name]
res=mod_obj.read(cr,uid,[vals.ref.id],['duration','class'],context)
defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id,'duration':res[0]['duration'],'class':res[0]['class']}
mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
@@ -632,7 +632,6 @@ property or property parameter."),
res = super(calendar_attendee, self).create(cr, uid, vals, context=context)
return res
-calendar_attendee()
class res_alarm(osv.osv):
"""Resource Alarm """
@@ -684,7 +683,7 @@ true, it will allow you to hide the event alarm information without removing it.
ir_obj = self.pool.get('ir.model')
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
for data in model_obj.browse(cr, uid, ids, context=context):
basic_alarm = data.alarm_id
@@ -754,7 +753,7 @@ true, it will allow you to hide the event alarm information without removing it.
alarm_obj = self.pool.get('calendar.alarm')
ir_obj = self.pool.get('ir.model')
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
for data in model_obj.browse(cr, uid, ids, context=context):
alarm_ids = alarm_obj.search(cr, uid, [('model_id', '=', model_id), ('res_id', '=', data.id)])
if alarm_ids:
@@ -763,7 +762,6 @@ true, it will allow you to hide the event alarm information without removing it.
where id=%%s' % model_obj._table,(data.id,))
return True
-res_alarm()
class calendar_alarm(osv.osv):
_name = 'calendar.alarm'
@@ -853,13 +851,15 @@ class calendar_alarm(osv.osv):
for alarm in self.browse(cr, uid, alarm_ids, context=context):
next_trigger_date = None
update_vals = {}
- model_obj = self.pool.get(alarm.model_id.model)
+ model_obj = self.pool[alarm.model_id.model]
res_obj = model_obj.browse(cr, uid, alarm.res_id, context=context)
re_dates = []
if hasattr(res_obj, 'rrule') and res_obj.rrule:
event_date = datetime.strptime(res_obj.date, '%Y-%m-%d %H:%M:%S')
- recurrent_dates = get_recurrent_dates(res_obj.rrule, res_obj.exdate, event_date, res_obj.exrule)
+ #exdate is a string and we need a list
+ exdate = res_obj.exdate and res_obj.exdate.split(',') or []
+ recurrent_dates = get_recurrent_dates(res_obj.rrule, exdate, event_date, res_obj.exrule)
trigger_interval = alarm.trigger_interval
if trigger_interval == 'days':
@@ -916,7 +916,6 @@ From:
self.write(cr, uid, [alarm.id], update_vals)
return True
-calendar_alarm()
class calendar_event(osv.osv):
@@ -1608,7 +1607,6 @@ rule or repeating pattern of time to exclude from the recurring rule."),
"""
return self.write(cr, uid, ids, {'state': 'confirmed'}, context)
-calendar_event()
class calendar_todo(osv.osv):
""" Calendar Task """
@@ -1657,7 +1655,6 @@ class calendar_todo(osv.osv):
__attribute__ = {}
-calendar_todo()
class ir_values(osv.osv):
@@ -1702,7 +1699,6 @@ class ir_values(osv.osv):
return super(ir_values, self).get(cr, uid, key, key2, new_model, \
meta, context, res_id_req, without_user, key2_req)
-ir_values()
class ir_model(osv.osv):
@@ -1728,7 +1724,6 @@ class ir_model(osv.osv):
val['id'] = base_calendar_id2real_id(val['id'])
return isinstance(ids, (str, int, long)) and data[0] or data
-ir_model()
original_exp_report = openerp.service.report.exp_report
diff --git a/addons/base_calendar/base_calendar_data.xml b/addons/base_calendar/base_calendar_data.xml
index 727a0703db2..64aa7ba59b6 100644
--- a/addons/base_calendar/base_calendar_data.xml
+++ b/addons/base_calendar/base_calendar_data.xml
@@ -126,7 +126,7 @@
Run Event Reminder
- 1
+ 5minutes-1
diff --git a/addons/base_calendar/crm_meeting.py b/addons/base_calendar/crm_meeting.py
index 6010f5ccfca..aa476002abc 100644
--- a/addons/base_calendar/crm_meeting.py
+++ b/addons/base_calendar/crm_meeting.py
@@ -135,7 +135,7 @@ class mail_message(osv.osv):
def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None):
if doc_model == 'crm.meeting':
- for virtual_id in self.pool.get(doc_model).get_recurrent_ids(cr, uid, doc_dict.keys(), [], context=context):
+ for virtual_id in self.pool[doc_model].get_recurrent_ids(cr, uid, doc_dict.keys(), [], context=context):
doc_dict.setdefault(virtual_id, doc_dict[get_real_ids(virtual_id)])
return super(mail_message, self)._find_allowed_model_wise(cr, uid, doc_model, doc_dict, context=context)
diff --git a/addons/base_calendar/i18n/es_MX.po b/addons/base_calendar/i18n/es_MX.po
index fcb00c6d478..9a2fe449d37 100644
--- a/addons/base_calendar/i18n/es_MX.po
+++ b/addons/base_calendar/i18n/es_MX.po
@@ -1,929 +1,879 @@
-# Spanish translation for openobject-addons
-# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
+# 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 , 2010.
+# FIRST AUTHOR , 2013.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2011-01-11 11:14+0000\n"
-"PO-Revision-Date: 2011-01-18 01:17+0000\n"
-"Last-Translator: Jordi Esteve (www.zikzakmedia.com) "
-"\n"
-"Language-Team: Spanish \n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2013-04-24 15:25+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 05:52+0000\n"
-"X-Generator: Launchpad (build 13830)\n"
+"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
#. module: base_calendar
#: selection:calendar.alarm,trigger_related:0
#: selection:res.alarm,trigger_related:0
msgid "The event starts"
-msgstr "El evento comienza"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-msgid "Hourly"
-msgstr "Cada hora"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Required to Join"
-msgstr "Requerido para unirse"
+#: view:calendar.event:0
+msgid "My Events"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,exdate:0
#: help:calendar.todo,exdate:0
+#: help:crm.meeting,exdate:0
msgid ""
"This property defines the list of date/time exceptions for a recurring "
"calendar component."
msgstr ""
-"Esta propiedad define la lista de excepciones de fecha/hora para un evento "
-"de calendario recurrente."
#. module: base_calendar
-#: constraint:res.users:0
-msgid "The chosen company is not in the allowed companies for this user"
-msgstr ""
-"La compañía seleccionada no está en las compañías permitidas para este "
-"usuario"
-
-#. module: base_calendar
-#: field:calendar.event.edit.all,name:0
-msgid "Title"
-msgstr "Título"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
#: selection:calendar.event,rrule_type:0
#: selection:calendar.todo,rrule_type:0
-msgid "Monthly"
-msgstr "Mensual"
+#: selection:crm.meeting,rrule_type:0
+msgid "Week(s)"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Invited User"
-msgstr "Usuario invitado"
+#: field:calendar.event,we:0
+#: field:calendar.todo,we:0
+#: field:crm.meeting,we:0
+msgid "Wed"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Invitation"
-msgstr "Invitación"
+#: selection:calendar.attendee,cutype:0
+msgid "Unknown"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,recurrency:0
#: help:calendar.todo,recurrency:0
+#: help:crm.meeting,recurrency:0
msgid "Recurrent Meeting"
-msgstr "Reunión periódica"
+msgstr ""
+
+#. module: base_calendar
+#: model:crm.meeting.type,name:base_calendar.categ_meet5
+msgid "Feedback Meeting"
+msgstr ""
#. module: base_calendar
#: model:ir.actions.act_window,name:base_calendar.action_res_alarm_view
#: model:ir.ui.menu,name:base_calendar.menu_crm_meeting_avail_alarm
msgid "Alarms"
-msgstr "Alarmas"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
#: selection:calendar.event,week_list:0
#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
msgid "Sunday"
-msgstr "Domingo"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: field:calendar.attendee,role:0
msgid "Role"
-msgstr "Rol"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: view:calendar.event:0
+#: view:crm.meeting:0
msgid "Invitation details"
-msgstr "Detalles de la invitación"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,byday:0
#: selection:calendar.event,byday:0
#: selection:calendar.todo,byday:0
+#: selection:crm.meeting,byday:0
msgid "Fourth"
-msgstr "Cuarto"
+msgstr ""
#. module: base_calendar
-#: field:calendar.event,show_as:0
-#: field:calendar.todo,show_as:0
-msgid "Show as"
-msgstr "Mostrar como"
+#: model:ir.model,name:base_calendar.model_res_users
+msgid "Users"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,day:0
-#: selection:base.calendar.set.exrule,select1:0
#: field:calendar.event,day:0
#: selection:calendar.event,select1:0
#: field:calendar.todo,day:0
#: selection:calendar.todo,select1:0
+#: field:crm.meeting,day:0
+#: selection:crm.meeting,select1:0
msgid "Date of month"
-msgstr "Día del mes"
+msgstr ""
#. module: base_calendar
#: selection:calendar.event,class:0
#: selection:calendar.todo,class:0
+#: selection:crm.meeting,class:0
msgid "Public"
-msgstr "Público"
+msgstr ""
#. module: base_calendar
-#: view:calendar.event:0
-msgid " "
-msgstr " "
+#: selection:calendar.alarm,trigger_interval:0
+#: selection:res.alarm,trigger_interval:0
+msgid "Hours"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "March"
-msgstr "Marzo"
+msgstr ""
#. module: base_calendar
-#: code:addons/base_calendar/base_calendar.py:414
-#: code:addons/base_calendar/wizard/base_calendar_set_exrule.py:90
-#, python-format
-msgid "Warning !"
-msgstr "¡Aviso!"
+#: help:calendar.attendee,cutype:0
+msgid "Specify the type of Invitation"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+#: field:crm.meeting,message_unread:0
+msgid "Unread Messages"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
#: selection:calendar.event,week_list:0
#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
msgid "Friday"
-msgstr "Viernes"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,allday:0
#: field:calendar.todo,allday:0
+#: field:crm.meeting,allday:0
msgid "All Day"
-msgstr "Todo el día"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,select1:0
-#: field:calendar.event,select1:0
-#: field:calendar.todo,select1:0
-msgid "Option"
-msgstr "Opción"
+#: field:calendar.event,vtimezone:0
+#: field:calendar.todo,vtimezone:0
+#: field:crm.meeting,vtimezone:0
+msgid "Timezone"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,availability:0
#: selection:calendar.event,show_as:0
#: selection:calendar.todo,show_as:0
-#: selection:res.users,availability:0
+#: selection:crm.meeting,show_as:0
msgid "Free"
-msgstr "Libre"
+msgstr ""
+
+#. module: base_calendar
+#: help:crm.meeting,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,rsvp:0
msgid "Indicats whether the favor of a reply is requested"
-msgstr "Indica si es requerida la confirmación de una respuesta."
+msgstr ""
#. module: base_calendar
-#: model:ir.model,name:base_calendar.model_ir_attachment
-msgid "ir.attachment"
-msgstr "ir.adjunto"
+#: field:calendar.alarm,alarm_id:0
+msgid "Basic Alarm"
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,delegated_to:0
msgid "The users that the original request was delegated to"
-msgstr "Los usuarios a los que les fue delegado la petición original"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,ref:0
msgid "Event Ref"
-msgstr "Ref. evento"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,we:0
-#: field:calendar.event,we:0
-#: field:calendar.todo,we:0
-msgid "Wed"
-msgstr "Mié"
-
-#. module: base_calendar
-#: view:calendar.event:0
-msgid "Show Time as"
-msgstr "Mostrar hora como"
-
-#. module: base_calendar
-#: field:base.calendar.set.exrule,tu:0
#: field:calendar.event,tu:0
#: field:calendar.todo,tu:0
+#: field:crm.meeting,tu:0
msgid "Tue"
-msgstr "Mar"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-#: selection:calendar.event,rrule_type:0
-#: selection:calendar.todo,rrule_type:0
-msgid "Yearly"
-msgstr "Anualmente"
+#: selection:calendar.event,byday:0
+#: selection:calendar.todo,byday:0
+#: selection:crm.meeting,byday:0
+msgid "Third"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,trigger_related:0
#: selection:res.alarm,trigger_related:0
msgid "The event ends"
-msgstr "El evento finaliza"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,byday:0
#: selection:calendar.event,byday:0
#: selection:calendar.todo,byday:0
+#: selection:crm.meeting,byday:0
msgid "Last"
-msgstr "Última"
+msgstr ""
#. module: base_calendar
-#: help:calendar.attendee,state:0
-msgid "Status of the attendee's participation"
-msgstr "Estado de la participación de los asistentes"
+#: help:crm.meeting,message_ids:0
+msgid "Messages and communication history"
+msgstr ""
#. module: base_calendar
-#: selection:calendar.attendee,cutype:0
-msgid "Room"
-msgstr "Sala"
+#: field:crm.meeting,message_ids:0
+msgid "Messages"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,trigger_interval:0
-#: selection:calendar.event,freq:0
-#: selection:calendar.todo,freq:0
#: selection:res.alarm,trigger_interval:0
msgid "Days"
-msgstr "Días"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: view:calendar.event:0
-msgid "Invitation Detail"
-msgstr "Detalle de la invitación"
+msgid "To"
+msgstr ""
#. module: base_calendar
-#: code:addons/base_calendar/base_calendar.py:1355
-#: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:96
-#: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:143
-#: code:addons/base_calendar/wizard/base_calendar_set_exrule.py:128
-#: code:addons/base_calendar/wizard/base_calendar_set_exrule.py:136
+#: code:addons/base_calendar/base_calendar.py:1260
#, python-format
msgid "Error!"
-msgstr "¡Error!"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,role:0
msgid "Chair Person"
-msgstr "Presidente"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+msgid "My Meetings"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,action:0
msgid "Procedure"
-msgstr "Procedimiento"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.event,recurrent_id:0
+#: field:calendar.todo,recurrent_id:0
+#: field:crm.meeting,recurrent_id:0
+msgid "Recurrent ID"
+msgstr ""
#. module: base_calendar
#: selection:calendar.event,state:0
#: selection:calendar.todo,state:0
msgid "Cancelled"
-msgstr "Cancelada"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,trigger_interval:0
#: selection:res.alarm,trigger_interval:0
msgid "Minutes"
-msgstr "Minutos"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,action:0
msgid "Display"
-msgstr "Mostrar"
+msgstr ""
#. module: base_calendar
-#: view:calendar.event.edit.all:0
-msgid "Edit all Occurrences"
-msgstr "Editar todas las ocurrencias"
+#: help:calendar.attendee,state:0
+msgid "Status of the attendee's participation"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Invitation type"
-msgstr "Tipo de invitación"
+#: view:crm.meeting:0
+msgid "Mail To"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-msgid "Secondly"
-msgstr "En segundo lugar"
+#: field:crm.meeting,name:0
+msgid "Meeting Subject"
+msgstr ""
#. module: base_calendar
-#: field:calendar.alarm,event_date:0
-#: field:calendar.attendee,event_date:0
#: view:calendar.event:0
-msgid "Event Date"
-msgstr "Fecha evento"
+msgid "End of Recurrence"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: view:calendar.event:0
msgid "Group By..."
-msgstr "Agrupar por..."
-
-#. module: base_calendar
-#: help:base_calendar.invite.attendee,email:0
-msgid "Provide external email address who will receive this invitation."
msgstr ""
-"Proporcione las direcciones de correo externas de quienes recibiran esta "
-"invitacion."
#. module: base_calendar
-#: model:ir.module.module,description:base_calendar.module_meta_information
-msgid ""
-"Full featured calendar system that supports:\n"
-" - Calendar of events\n"
-" - Alerts (create requests)\n"
-" - Recurring events\n"
-" - Invitations to people"
+#: view:calendar.event:0
+msgid "Recurrency Option"
msgstr ""
-"Completo sistema de calendario que soporta:\n"
-" - Calendario de eventos\n"
-" - Alertas (crea peticiones)\n"
-" - Eventos recursivos\n"
-" - Invitación de personas"
#. module: base_calendar
-#: help:calendar.attendee,cutype:0
-msgid "Specify the type of Invitation"
-msgstr "Especifique el tipo de invitación"
+#: view:calendar.event:0
+msgid "Choose day where repeat the meeting"
+msgstr ""
#. module: base_calendar
-#: selection:calendar.event,freq:0
-#: selection:calendar.todo,freq:0
-msgid "Years"
-msgstr "Años"
+#: view:crm.meeting:0
+#: model:ir.actions.act_window,name:base_calendar.action_crm_meeting
+msgid "Meetings"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.event,recurrent_id_date:0
+#: field:calendar.todo,recurrent_id_date:0
+#: field:crm.meeting,recurrent_id_date:0
+msgid "Recurrent ID date"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,event_end_date:0
#: field:calendar.attendee,event_end_date:0
msgid "Event End Date"
-msgstr "Fecha del final del evento"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,role:0
msgid "Optional Participation"
-msgstr "Participación opcional"
+msgstr ""
#. module: base_calendar
-#: field:calendar.event,date_deadline:0
-#: field:calendar.todo,date_deadline:0
-msgid "Deadline"
-msgstr "Fecha límite"
+#: help:crm.meeting,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: base_calendar
-#: code:addons/base_calendar/base_calendar.py:385
-#: code:addons/base_calendar/base_calendar.py:1088
-#: code:addons/base_calendar/base_calendar.py:1090
+#: code:addons/base_calendar/base_calendar.py:399
+#: code:addons/base_calendar/base_calendar.py:441
+#: code:addons/base_calendar/base_calendar.py:1013
+#: code:addons/base_calendar/base_calendar.py:1015
+#: code:addons/base_calendar/base_calendar.py:1460
#, python-format
msgid "Warning!"
-msgstr "¡Aviso!"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,active:0
#: help:calendar.todo,active:0
+#: help:crm.meeting,active:0
msgid ""
"If the active field is set to true, it will allow you to hide the "
"event alarm information without removing it."
msgstr ""
-"Si el campo activo se establece a verdadero, se omitirá la alarma del "
-"evento, sin embargo no se eliminará."
#. module: base_calendar
-#: model:ir.module.module,shortdesc:base_calendar.module_meta_information
-msgid "Basic Calendar Functionality"
-msgstr "Funcionalidad básica del calendario"
+#: field:calendar.alarm,repeat:0
+#: field:calendar.event,count:0
+#: field:calendar.todo,count:0
+#: field:crm.meeting,count:0
+#: field:res.alarm,repeat:0
+msgid "Repeat"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,organizer:0
#: field:calendar.event,organizer_id:0
#: field:calendar.todo,organizer:0
#: field:calendar.todo,organizer_id:0
+#: field:crm.meeting,organizer:0
+#: field:crm.meeting,organizer_id:0
msgid "Organizer"
-msgstr "Organizador"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: view:calendar.event:0
#: field:calendar.event,user_id:0
#: field:calendar.todo,user_id:0
+#: field:crm.meeting,user_id:0
msgid "Responsible"
-msgstr "Responsable"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
-#: model:res.request.link,name:base_calendar.request_link_meeting
+#: model:res.request.link,name:base_calendar.request_link_event
msgid "Event"
-msgstr "Evento"
-
-#. module: base_calendar
-#: help:calendar.event,edit_all:0
-#: help:calendar.todo,edit_all:0
-msgid "Edit all Occurrences of recurrent Meeting."
-msgstr "Editar todas las ocurrencias de la reunión recurrente."
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,trigger_occurs:0
#: selection:res.alarm,trigger_occurs:0
msgid "Before"
-msgstr "Antes de"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
#: selection:calendar.event,state:0
#: selection:calendar.todo,state:0
+#: field:crm.meeting,date_open:0
+#: selection:crm.meeting,state:0
msgid "Confirmed"
-msgstr "Confirmada"
-
-#. module: base_calendar
-#: model:ir.actions.act_window,name:base_calendar.action_calendar_event_edit_all
-msgid "Edit all events"
-msgstr "Editar todos los eventos"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,attendee_ids:0
#: field:calendar.event,attendee_ids:0
+#: field:calendar.event,partner_ids:0
#: field:calendar.todo,attendee_ids:0
+#: field:calendar.todo,partner_ids:0
+#: field:crm.meeting,attendee_ids:0
+#: field:crm.meeting,partner_ids:0
msgid "Attendees"
-msgstr "Asistentes"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
msgid "Confirm"
-msgstr "Confirmar"
+msgstr ""
#. module: base_calendar
#: model:ir.model,name:base_calendar.model_calendar_todo
msgid "Calendar Task"
-msgstr "Calendario de tareas"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,su:0
#: field:calendar.event,su:0
#: field:calendar.todo,su:0
+#: field:crm.meeting,su:0
msgid "Sun"
-msgstr "Dom"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,cutype:0
msgid "Invite Type"
-msgstr "Tipo de invitación"
-
-#. module: base_calendar
-#: help:calendar.attendee,partner_id:0
-msgid "Partner related to contact"
-msgstr "Partner relacionado con el contacto"
+msgstr ""
#. module: base_calendar
#: view:res.alarm:0
msgid "Reminder details"
-msgstr "Detalles del recordatorio"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,parent_ids:0
msgid "Delegrated From"
-msgstr "Delegado desde"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,select1:0
#: selection:calendar.event,select1:0
#: selection:calendar.todo,select1:0
+#: selection:crm.meeting,select1:0
msgid "Day of month"
-msgstr "Día del mes"
-
-#. module: base_calendar
-#: view:calendar.event:0
-#: field:calendar.event,location:0
-#: field:calendar.event.edit.all,location:0
-#: field:calendar.todo,location:0
-msgid "Location"
-msgstr "Lugar"
-
-#. module: base_calendar
-#: field:base_calendar.invite.attendee,send_mail:0
-msgid "Send mail?"
-msgstr "¿Enviar email?"
-
-#. module: base_calendar
-#: field:base_calendar.invite.attendee,email:0
-#: selection:calendar.alarm,action:0
-#: field:calendar.attendee,email:0
-msgid "Email"
-msgstr "Correo electrónico"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Event Detail"
-msgstr "Detalles del evento"
-
-#. module: base_calendar
-#: selection:calendar.alarm,state:0
-msgid "Run"
-msgstr "Ejecutar"
-
-#. module: base_calendar
-#: field:calendar.event,exdate:0
-#: field:calendar.todo,exdate:0
-msgid "Exception Date/Times"
-msgstr "Fecha/horas excepción"
-
-#. module: base_calendar
-#: selection:calendar.event,class:0
-#: selection:calendar.todo,class:0
-msgid "Confidential"
-msgstr "Confidencial"
-
-#. module: base_calendar
-#: field:base.calendar.set.exrule,end_date:0
-#: field:calendar.event,end_date:0
-#: field:calendar.todo,end_date:0
-msgid "Repeat Until"
-msgstr "Repetir hasta"
-
-#. module: base_calendar
-#: model:ir.actions.act_window,help:base_calendar.action_res_alarm_view
-msgid ""
-"Create specific calendar alarms that may be assigned to calendar events or "
-"meetings."
msgstr ""
-"Crear alarmas específicas que puedan ser asignadas a eventos de calendario o "
-"reuniones."
#. module: base_calendar
-#: view:calendar.event:0
-msgid "Visibility"
-msgstr "Visibilidad"
+#: field:crm.meeting,message_follower_ids:0
+msgid "Followers"
+msgstr ""
#. module: base_calendar
-#: field:calendar.attendee,rsvp:0
-msgid "Required Reply?"
-msgstr "¿Respuesta requerida?"
-
-#. module: base_calendar
-#: field:calendar.event,base_calendar_url:0
-#: field:calendar.todo,base_calendar_url:0
-msgid "Caldav URL"
-msgstr "URL de caldav"
-
-#. module: base_calendar
-#: view:base.calendar.set.exrule:0
-msgid "Select range to Exclude"
-msgstr "Elija el rango a excluir"
-
-#. module: base_calendar
-#: field:calendar.event,recurrent_uid:0
-#: field:calendar.todo,recurrent_uid:0
-msgid "Recurrent ID"
-msgstr "ID recurrente"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
-#: selection:calendar.event,month_list:0
-#: selection:calendar.todo,month_list:0
-msgid "July"
-msgstr "Julio"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-#: selection:calendar.attendee,state:0
-msgid "Accepted"
-msgstr "Aceptada"
-
-#. module: base_calendar
-#: field:base.calendar.set.exrule,th:0
-#: field:calendar.event,th:0
-#: field:calendar.todo,th:0
-msgid "Thu"
-msgstr "Jue"
-
-#. module: base_calendar
-#: field:calendar.attendee,child_ids:0
-msgid "Delegrated To"
-msgstr "Delegada en"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Required Reply"
-msgstr "Respuesta requerida"
-
-#. module: base_calendar
-#: selection:calendar.event,end_type:0
-#: selection:calendar.todo,end_type:0
-msgid "Forever"
-msgstr "Siempre"
+#: field:calendar.event,location:0
+#: field:calendar.todo,location:0
+#: field:crm.meeting,location:0
+msgid "Location"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,role:0
msgid "Participation required"
-msgstr "Participación requerida"
+msgstr ""
#. module: base_calendar
-#: view:base.calendar.set.exrule:0
-msgid "_Cancel"
-msgstr "_Cancelar"
+#: view:calendar.event:0
+#: field:calendar.event,show_as:0
+#: field:calendar.todo,show_as:0
+#: field:crm.meeting,show_as:0
+msgid "Show Time as"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.alarm,action:0
+#: field:calendar.attendee,email:0
+msgid "Email"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.attendee,cutype:0
+msgid "Room"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.alarm,state:0
+msgid "Run"
+msgstr ""
+
+#. module: base_calendar
+#: model:ir.model,name:base_calendar.model_calendar_alarm
+msgid "Event alarm information"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/base_calendar.py:1015
+#, python-format
+msgid "Count cannot be negative or 0."
+msgstr ""
+
+#. module: base_calendar
+#: field:crm.meeting,create_date:0
+msgid "Creation Date"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+#: model:ir.model,name:base_calendar.model_crm_meeting
+#: model:res.request.link,name:base_calendar.request_link_meeting
+msgid "Meeting"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.event,rrule_type:0
+#: selection:calendar.todo,rrule_type:0
+#: selection:crm.meeting,rrule_type:0
+msgid "Month(s)"
+msgstr ""
+
+#. module: base_calendar
+#: view:calendar.event:0
+msgid "Visibility"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.attendee,rsvp:0
+msgid "Required Reply?"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.event,base_calendar_url:0
+#: field:calendar.todo,base_calendar_url:0
+#: field:crm.meeting,base_calendar_url:0
+msgid "Caldav URL"
+msgstr ""
+
+#. module: base_calendar
+#: model:ir.model,name:base_calendar.model_mail_wizard_invite
+msgid "Invite wizard"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.event,month_list:0
+#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
+msgid "July"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.attendee,state:0
+msgid "Accepted"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.event,th:0
+#: field:calendar.todo,th:0
+#: field:crm.meeting,th:0
+msgid "Thu"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+msgid "Meeting Details"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.attendee,child_ids:0
+msgid "Delegrated To"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/crm_meeting.py:102
+#, python-format
+msgid "The following contacts have no email address :"
+msgstr ""
+
+#. module: base_calendar
+#: selection:calendar.event,rrule_type:0
+#: selection:calendar.todo,rrule_type:0
+#: selection:crm.meeting,rrule_type:0
+msgid "Year(s)"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting.type:0
+#: model:ir.actions.act_window,name:base_calendar.action_crm_meeting_type
+#: model:ir.ui.menu,name:base_calendar.menu_crm_meeting_type
+msgid "Meeting Types"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,create_date:0
#: field:calendar.todo,create_date:0
msgid "Created"
-msgstr "Creada"
+msgstr ""
#. module: base_calendar
#: selection:calendar.event,class:0
#: selection:calendar.todo,class:0
-msgid "Private"
-msgstr "Privada"
+#: selection:crm.meeting,class:0
+msgid "Public for Employees"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-#: selection:calendar.event,rrule_type:0
-#: selection:calendar.todo,rrule_type:0
-msgid "Daily"
-msgstr "Diariamente"
+#: view:crm.meeting:0
+msgid "hours"
+msgstr ""
#. module: base_calendar
-#: code:addons/base_calendar/base_calendar.py:385
-#, python-format
-msgid "Can not Duplicate"
-msgstr "No se puede duplicar"
-
-#. module: base_calendar
-#: field:calendar.event,class:0
-#: field:calendar.todo,class:0
-msgid "Mark as"
-msgstr "Marcar como"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-#: field:calendar.attendee,partner_address_id:0
-msgid "Contact"
-msgstr "Contacto"
-
-#. module: base_calendar
-#: help:calendar.event,rrule_type:0
-#: help:calendar.todo,rrule_type:0
-msgid "Let the event automatically repeat at that interval"
-msgstr "Permite que el evento se repita automáticamente en ese intervalo"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-#: view:calendar.event:0
-msgid "Delegate"
-msgstr "Delegar"
-
-#. module: base_calendar
-#: field:base_calendar.invite.attendee,partner_id:0
-#: view:calendar.attendee:0
#: field:calendar.attendee,partner_id:0
-msgid "Partner"
-msgstr "Empresa"
+msgid "Contact"
+msgstr ""
#. module: base_calendar
-#: view:base_calendar.invite.attendee:0
-#: selection:base_calendar.invite.attendee,type:0
-msgid "Partner Contacts"
-msgstr "Contactos de la empresa"
+#: field:calendar.attendee,language:0
+msgid "Language"
+msgstr ""
#. module: base_calendar
-#: view:base.calendar.set.exrule:0
-msgid "_Ok"
-msgstr "_Aceptar"
+#: field:calendar.event,end_date:0
+#: field:calendar.todo,end_date:0
+#: field:crm.meeting,end_date:0
+msgid "Repeat Until"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+msgid "Options"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,byday:0
#: selection:calendar.event,byday:0
#: selection:calendar.todo,byday:0
+#: selection:crm.meeting,byday:0
msgid "First"
-msgstr "Primera"
-
-#. module: base_calendar
-#: view:calendar.event:0
-msgid "Privacy"
-msgstr "Privacidad"
-
-#. module: base_calendar
-#: field:calendar.event,vtimezone:0
-#: field:calendar.todo,vtimezone:0
-msgid "Timezone"
-msgstr "Zona horaria"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
+#: view:crm.meeting:0
msgid "Subject"
-msgstr "Asunto"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "September"
-msgstr "Septiembre"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "December"
-msgstr "Diciembre"
+msgstr ""
#. module: base_calendar
-#: help:base_calendar.invite.attendee,send_mail:0
-msgid "Check this if you want to send an Email to Invited Person"
-msgstr "Marque aquí si quiere enviar un correo a la persona invitada"
+#: selection:calendar.event,week_list:0
+#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
+msgid "Tuesday"
+msgstr ""
+
+#. module: base_calendar
+#: field:crm.meeting,categ_ids:0
+msgid "Tags"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
msgid "Availability"
-msgstr "Disponibilidad"
-
-#. module: base_calendar
-#: view:calendar.event.edit.all:0
-msgid "_Save"
-msgstr "_Guardar"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,cutype:0
msgid "Individual"
-msgstr "Individual"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,count:0
#: help:calendar.todo,count:0
+#: help:crm.meeting,count:0
msgid "Repeat x times"
-msgstr "Repetir x veces"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,user_id:0
msgid "Owner"
-msgstr "Dueño"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Delegation Info"
-msgstr "Información delegación"
+#: help:calendar.event,rrule_type:0
+#: help:calendar.todo,rrule_type:0
+#: help:crm.meeting,rrule_type:0
+msgid "Let the event automatically repeat at that interval"
+msgstr ""
#. module: base_calendar
-#: view:calendar.event:0
-#: field:calendar.event.edit.all,date:0
-msgid "Start Date"
-msgstr "Fecha inicio"
+#: model:ir.ui.menu,name:base_calendar.mail_menu_calendar
+msgid "Calendar"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,cn:0
msgid "Common name"
-msgstr "Nombre común"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: selection:calendar.attendee,state:0
msgid "Declined"
-msgstr "Rechazada"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "My Role"
-msgstr "Mi rol"
+#: code:addons/base_calendar/base_calendar.py:1460
+#, python-format
+msgid "Group by date is not supported, use the calendar view instead."
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
-msgid "My Events"
-msgstr "Mis eventos"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-#: view:calendar.event:0
+#: view:crm.meeting:0
msgid "Decline"
-msgstr "Rechazar"
-
-#. module: base_calendar
-#: selection:calendar.event,freq:0
-#: selection:calendar.todo,freq:0
-msgid "Weeks"
-msgstr "Semanas"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,cutype:0
msgid "Group"
-msgstr "Grupo"
+msgstr ""
#. module: base_calendar
-#: field:calendar.event,edit_all:0
-#: field:calendar.todo,edit_all:0
-msgid "Edit All"
-msgstr "Editar todo"
+#: selection:calendar.event,class:0
+#: selection:calendar.todo,class:0
+#: selection:crm.meeting,class:0
+msgid "Private"
+msgstr ""
#. module: base_calendar
-#: field:base_calendar.invite.attendee,contact_ids:0
-msgid "Contacts"
-msgstr "Contactos"
+#: view:calendar.event:0
+#: field:calendar.event,class:0
+#: field:calendar.todo,class:0
+#: field:crm.meeting,class:0
+msgid "Privacy"
+msgstr ""
#. module: base_calendar
#: model:ir.model,name:base_calendar.model_res_alarm
msgid "Basic Alarm Information"
-msgstr "Información sobre la alarma básica"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,fr:0
#: field:calendar.event,fr:0
#: field:calendar.todo,fr:0
+#: field:crm.meeting,fr:0
msgid "Fri"
-msgstr "Vie"
+msgstr ""
#. module: base_calendar
-#: selection:calendar.alarm,trigger_interval:0
-#: selection:calendar.event,freq:0
-#: selection:calendar.todo,freq:0
-#: selection:res.alarm,trigger_interval:0
-msgid "Hours"
-msgstr "Horas"
-
-#. module: base_calendar
-#: code:addons/base_calendar/base_calendar.py:1090
-#, python-format
-msgid "Count can not be Negative"
-msgstr "La cuenta no puede ser negativa"
+#: view:calendar.event:0
+msgid "Invitation Detail"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,member:0
msgid "Member"
-msgstr "Miembro"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,location:0
#: help:calendar.todo,location:0
+#: help:crm.meeting,location:0
msgid "Location of Event"
-msgstr "Ubicación del evento"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,rrule:0
#: field:calendar.todo,rrule:0
+#: field:crm.meeting,rrule:0
msgid "Recurrent Rule"
-msgstr "Regla recurrente"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,state:0
msgid "Draft"
-msgstr "Borrador"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,attach:0
msgid "Attachment"
-msgstr "Adjunto"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Invitation From"
-msgstr "Invitación desde"
+#: field:crm.meeting,date_closed:0
+msgid "Closed"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
-msgid "End of Recurrency"
-msgstr "Fin de recurrencia"
+msgid "From"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
-#: field:calendar.event.edit.all,alarm_id:0
+#: field:calendar.event,alarm_id:0
+#: field:calendar.todo,alarm_id:0
+#: field:crm.meeting,alarm_id:0
msgid "Reminder"
-msgstr "Recordatorio"
+msgstr ""
#. module: base_calendar
-#: view:base.calendar.set.exrule:0
-#: model:ir.model,name:base_calendar.model_base_calendar_set_exrule
-msgid "Set Exrule"
-msgstr "Establecer Exregla"
+#: selection:calendar.event,end_type:0
+#: selection:calendar.todo,end_type:0
+#: selection:crm.meeting,end_type:0
+msgid "Number of repetitions"
+msgstr ""
+
+#. module: base_calendar
+#: model:crm.meeting.type,name:base_calendar.categ_meet2
+msgid "Internal Meeting"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
#: model:ir.actions.act_window,name:base_calendar.action_view_event
#: model:ir.ui.menu,name:base_calendar.menu_events
msgid "Events"
-msgstr "Eventos"
+msgstr ""
#. module: base_calendar
-#: model:ir.actions.act_window,name:base_calendar.action_view_calendar_invite_attendee_wizard
-#: model:ir.model,name:base_calendar.model_base_calendar_invite_attendee
-msgid "Invite Attendees"
-msgstr "Invitar asistentes"
+#: field:calendar.alarm,state:0
+#: field:calendar.attendee,state:0
+#: view:calendar.event:0
+#: field:calendar.event,state:0
+#: field:calendar.todo,state:0
+#: field:crm.meeting,state:0
+msgid "Status"
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,email:0
msgid "Email of Invited Person"
-msgstr "Email del invitado"
+msgstr ""
#. module: base_calendar
-#: field:calendar.alarm,repeat:0
-#: field:calendar.event,count:0
-#: field:calendar.todo,count:0
-#: field:res.alarm,repeat:0
-msgid "Repeat"
-msgstr "Repetir"
+#: model:crm.meeting.type,name:base_calendar.categ_meet1
+msgid "Customer Meeting"
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,dir:0
@@ -931,186 +881,193 @@ msgid ""
"Reference to the URIthat points to the directory information corresponding "
"to the attendee."
msgstr ""
-"La referencia a la URI que apunta a la información del directorio "
-"correspondiente al participante."
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "August"
-msgstr "Agosto"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
#: selection:calendar.event,week_list:0
#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
msgid "Monday"
-msgstr "Lunes"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,byday:0
-#: selection:calendar.event,byday:0
-#: selection:calendar.todo,byday:0
-msgid "Third"
-msgstr "Tercero"
+#: model:crm.meeting.type,name:base_calendar.categ_meet4
+msgid "Open Discussion"
+msgstr ""
+
+#. module: base_calendar
+#: model:ir.model,name:base_calendar.model_ir_model
+msgid "Models"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "June"
-msgstr "Junio"
+msgstr ""
#. module: base_calendar
-#: field:calendar.alarm,alarm_id:0
-msgid "Basic Alarm"
-msgstr "Alarma básica"
-
-#. module: base_calendar
-#: view:base.calendar.set.exrule:0
+#: field:calendar.alarm,event_date:0
+#: field:calendar.attendee,event_date:0
#: view:calendar.event:0
-msgid "The"
-msgstr "El"
+msgid "Event Date"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+msgid "Invitations"
+msgstr ""
+
+#. module: base_calendar
+#: view:calendar.event:0
+#: view:crm.meeting:0
+msgid "The"
+msgstr ""
+
+#. module: base_calendar
+#: field:crm.meeting,write_date:0
+msgid "Write Date"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: field:calendar.attendee,delegated_from:0
msgid "Delegated From"
-msgstr "Delegado desde"
+msgstr ""
+
+#. module: base_calendar
+#: field:crm.meeting,message_is_follower:0
+msgid "Is a Follower"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,user_id:0
msgid "User"
-msgstr "Usuario"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
#: field:calendar.event,date:0
+#: field:crm.meeting,date:0
msgid "Date"
-msgstr "Fecha"
+msgstr ""
+
+#. module: base_calendar
+#: view:calendar.event:0
+msgid "Start Date"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "November"
-msgstr "Noviembre"
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,member:0
msgid "Indicate the groups that the attendee belongs to"
-msgstr "Indicar los grupos a los que pertenece el asistente"
+msgstr ""
#. module: base_calendar
-#: view:base_calendar.invite.attendee:0
-msgid "Data"
-msgstr "Datos"
-
-#. module: base_calendar
-#: field:base.calendar.set.exrule,mo:0
#: field:calendar.event,mo:0
#: field:calendar.todo,mo:0
+#: field:crm.meeting,mo:0
msgid "Mon"
-msgstr "Lun"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,count:0
-msgid "Count"
-msgstr "Total"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-#: selection:calendar.event,freq:0
-#: selection:calendar.todo,freq:0
-msgid "No Repeat"
-msgstr "No repetir"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "October"
-msgstr "Octubre"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
+#: selection:calendar.attendee,state:0
#: view:calendar.event:0
+#: selection:calendar.event,state:0
+#: selection:calendar.todo,state:0
+#: view:crm.meeting:0
msgid "Uncertain"
-msgstr "Incierto"
+msgstr ""
#. module: base_calendar
-#: field:calendar.attendee,language:0
-msgid "Language"
-msgstr "Idioma"
+#: constraint:calendar.event:0
+#: constraint:calendar.todo:0
+#: constraint:crm.meeting:0
+msgid "Error ! End date cannot be set before start date."
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,trigger_occurs:0
#: field:res.alarm,trigger_occurs:0
msgid "Triggers"
-msgstr "Disparadores"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "January"
-msgstr "Enero"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,trigger_related:0
#: field:res.alarm,trigger_related:0
msgid "Related to"
-msgstr "Relacionado con"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,interval:0
#: field:calendar.alarm,trigger_interval:0
#: field:res.alarm,trigger_interval:0
msgid "Interval"
-msgstr "Intervalo"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
#: selection:calendar.event,week_list:0
#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
msgid "Wednesday"
-msgstr "Miércoles"
-
-#. module: base_calendar
-#: code:addons/base_calendar/base_calendar.py:1088
-#, python-format
-msgid "Interval can not be Negative"
-msgstr "El intervalo no puede ser negativo"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,name:0
#: view:calendar.event:0
+#: field:crm.meeting,message_summary:0
msgid "Summary"
-msgstr "Resumen"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,active:0
#: field:calendar.event,active:0
#: field:calendar.todo,active:0
+#: field:crm.meeting,active:0
#: field:res.alarm,active:0
msgid "Active"
-msgstr "Activo"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/base_calendar.py:399
+#, python-format
+msgid "You cannot duplicate a calendar attendee."
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
msgid "Choose day in the month where repeat the meeting"
-msgstr "Elija el día del mes en que se repetirá la reunión"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,action:0
msgid "Action"
-msgstr "Acción"
-
-#. module: base_calendar
-#: help:base_calendar.invite.attendee,type:0
-msgid "Select whom you want to Invite"
-msgstr "Seleccione a quien quiere invitar"
+msgstr ""
#. module: base_calendar
#: help:calendar.alarm,duration:0
@@ -1119,52 +1076,38 @@ msgid ""
"Duration' and 'Repeat' are both optional, but if one occurs, so MUST the "
"other"
msgstr ""
-"Duración' y 'Repetir' son ambos opcionales, pero si uno está activo también "
-"debe estarlo el otro"
-
-#. module: base_calendar
-#: model:ir.model,name:base_calendar.model_calendar_event_edit_all
-msgid "Calendar Edit all event"
-msgstr "Editar todos los eventos del calendario"
#. module: base_calendar
#: help:calendar.attendee,role:0
msgid "Participation role for the calendar user"
-msgstr "Rol de participación para el usuario del calendario."
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: field:calendar.attendee,delegated_to:0
msgid "Delegated To"
-msgstr "Delegado a"
+msgstr ""
#. module: base_calendar
#: help:calendar.alarm,action:0
msgid "Defines the action to be invoked when an alarm is triggered"
-msgstr "Define la acción a invocar cuando salte la alarma"
+msgstr ""
+
+#. module: base_calendar
+#: view:crm.meeting:0
+msgid "Starting at"
+msgstr ""
#. module: base_calendar
#: selection:calendar.event,end_type:0
#: selection:calendar.todo,end_type:0
+#: selection:crm.meeting,end_type:0
msgid "End date"
-msgstr "Fecha de fin"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
msgid "Search Events"
-msgstr "Buscar eventos"
-
-#. module: base_calendar
-#: view:calendar.event:0
-msgid "Recurrency Option"
-msgstr "Opción de recurrencia"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-#: selection:calendar.event,rrule_type:0
-#: selection:calendar.todo,rrule_type:0
-msgid "Weekly"
-msgstr "Semanal"
+msgstr ""
#. module: base_calendar
#: help:calendar.alarm,active:0
@@ -1173,87 +1116,70 @@ msgid ""
"If the active field is set to true, it will allow you to hide the event "
"alarm information without removing it."
msgstr ""
-"Si el campo activo es verdadero, le permitirá ocultar la notificación de "
-"aviso del evento sin eliminarlo."
#. module: base_calendar
-#: field:calendar.event,recurrent_id:0
-#: field:calendar.todo,recurrent_id:0
-msgid "Recurrent ID date"
-msgstr "ID fecha recurrente"
+#: field:calendar.event,end_type:0
+#: field:calendar.todo,end_type:0
+#: field:crm.meeting,end_type:0
+msgid "Recurrence Termination"
+msgstr ""
#. module: base_calendar
-#: sql_constraint:res.users:0
-msgid "You can not have two users with the same login !"
-msgstr "¡No puede tener dos usuarios con el mismo identificador de usuario!"
-
-#. module: base_calendar
-#: field:calendar.alarm,state:0
-#: view:calendar.attendee:0
-#: field:calendar.attendee,state:0
-#: view:calendar.event:0
-#: field:calendar.event,state:0
-#: field:calendar.todo,state:0
-msgid "State"
-msgstr "Estado"
+#: view:crm.meeting:0
+msgid "Until"
+msgstr ""
#. module: base_calendar
#: view:res.alarm:0
msgid "Reminder Details"
-msgstr "Detalles del recordatorio"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "To Review"
-msgstr "A revisar"
+#: model:crm.meeting.type,name:base_calendar.categ_meet3
+msgid "Off-site Meeting"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,freq:0
-#: field:calendar.event,freq:0
-#: field:calendar.todo,freq:0
-msgid "Frequency"
-msgstr "Frecuencia"
+#: view:crm.meeting:0
+msgid "Day of Month"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,state:0
msgid "Done"
-msgstr "Hecho"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,interval:0
#: help:calendar.todo,interval:0
+#: help:crm.meeting,interval:0
msgid "Repeat every (Days/Week/Month/Year)"
-msgstr "Repetir cada (días/semana/mes/año)"
+msgstr ""
#. module: base_calendar
-#: view:base_calendar.invite.attendee:0
-#: field:base_calendar.invite.attendee,user_ids:0
-msgid "Users"
-msgstr "Usuarios"
+#: view:crm.meeting:0
+msgid "All Day?"
+msgstr ""
#. module: base_calendar
-#: view:base.calendar.set.exrule:0
-msgid "of"
-msgstr "de"
-
-#. module: base_calendar
-#: view:base_calendar.invite.attendee:0
#: view:calendar.event:0
-#: view:calendar.event.edit.all:0
msgid "Cancel"
-msgstr "Cancelar"
+msgstr ""
#. module: base_calendar
-#: model:ir.model,name:base_calendar.model_res_users
-msgid "res.users"
-msgstr "res.usuarios"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
-#: selection:calendar.event,week_list:0
-#: selection:calendar.todo,week_list:0
-msgid "Tuesday"
-msgstr "Martes"
+#: model:ir.actions.act_window,help:base_calendar.action_crm_meeting
+msgid ""
+"
\n"
+" Click to schedule a new meeting.\n"
+"
\n"
+" The calendar is shared between employees and fully integrated "
+"with\n"
+" other applications such as the employee holidays or the "
+"business\n"
+" opportunities.\n"
+"
\n"
+" "
+msgstr ""
#. module: base_calendar
#: help:calendar.alarm,description:0
@@ -1262,129 +1188,103 @@ msgid ""
"calendar component, than that provided by the "
"\"SUMMARY\" property"
msgstr ""
-"Facilita una descripción más completa del componente del calendario que la "
-"facilitada por la propiedad \"RESUMEN\""
#. module: base_calendar
#: view:calendar.event:0
msgid "Responsible User"
-msgstr "Usuario responsable"
+msgstr ""
#. module: base_calendar
+#: view:crm.meeting:0
+msgid "Select Weekdays"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/base_calendar.py:1519
#: selection:calendar.attendee,availability:0
#: selection:calendar.event,show_as:0
#: selection:calendar.todo,show_as:0
-#: selection:res.users,availability:0
+#: selection:crm.meeting,show_as:0
+#, python-format
msgid "Busy"
-msgstr "Ocupado"
+msgstr ""
#. module: base_calendar
#: model:ir.model,name:base_calendar.model_calendar_event
msgid "Calendar Event"
-msgstr "Evento de calendario"
-
-#. module: base_calendar
-#: selection:calendar.attendee,state:0
-#: selection:calendar.event,state:0
-#: selection:calendar.todo,state:0
-msgid "Tentative"
-msgstr "Provisional"
-
-#. module: base_calendar
-#: field:calendar.event,interval:0
-#: field:calendar.todo,interval:0
-msgid "Repeat every"
-msgstr "Repetir cada"
-
-#. module: base_calendar
-#: selection:calendar.event,end_type:0
-#: selection:calendar.todo,end_type:0
-msgid "Fix amout of times"
-msgstr "Cantidad fija de veces"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,recurrency:0
#: field:calendar.todo,recurrency:0
+#: field:crm.meeting,recurrency:0
msgid "Recurrent"
-msgstr "Recurrente"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,rrule_type:0
#: field:calendar.todo,rrule_type:0
+#: field:crm.meeting,rrule_type:0
msgid "Recurrency"
-msgstr "Recurrencia"
+msgstr ""
#. module: base_calendar
-#: model:ir.actions.act_window,name:base_calendar.action_view_attendee_form
-#: model:ir.ui.menu,name:base_calendar.menu_attendee_invitations
-msgid "Event Invitations"
-msgstr "Invitaciones al evento"
-
-#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
#: selection:calendar.event,week_list:0
#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
msgid "Thursday"
-msgstr "Jueves"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,exrule:0
#: field:calendar.todo,exrule:0
+#: field:crm.meeting,exrule:0
msgid "Exception Rule"
-msgstr "Regla de excepción"
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,language:0
msgid ""
"To specify the language for text values in aproperty or property parameter."
msgstr ""
-"Para indicar el idioma de los valores de texto en una propiedad o parámetro "
-"de propiedad."
#. module: base_calendar
#: view:calendar.event:0
msgid "Details"
-msgstr "Detalles"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,exrule:0
#: help:calendar.todo,exrule:0
+#: help:crm.meeting,exrule:0
msgid ""
"Defines a rule or repeating pattern of time to exclude from the recurring "
"rule."
msgstr ""
-"Define una regla o patrón de repetición de tiempo a excluir de la regla "
-"recurrente."
#. module: base_calendar
-#: field:base.calendar.set.exrule,month_list:0
#: field:calendar.event,month_list:0
#: field:calendar.todo,month_list:0
+#: field:crm.meeting,month_list:0
msgid "Month"
-msgstr "Mes"
-
-#. module: base_calendar
-#: view:base_calendar.invite.attendee:0
-#: view:calendar.event:0
-msgid "Invite People"
-msgstr "Invitar personas"
-
-#. module: base_calendar
-#: help:calendar.event,rrule:0
-#: help:calendar.todo,rrule:0
-msgid ""
-"Defines a rule or repeating pattern for recurring events\n"
-"e.g.: Every other month on the last Sunday of the month for 10 occurrences: "
-" FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=-1SU"
msgstr ""
-"Define una regla o patrón repetitivo para eventos recurrentes.\n"
-"Por ejemplo: Para 10 ocurrencias cada último domingo de cada dos meses : "
-"FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=-1SU"
+
+#. module: base_calendar
+#: selection:calendar.event,rrule_type:0
+#: selection:calendar.todo,rrule_type:0
+#: selection:crm.meeting,rrule_type:0
+msgid "Day(s)"
+msgstr ""
+
+#. module: base_calendar
+#: view:calendar.event:0
+msgid "Confirmed Events"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,dir:0
msgid "URI Reference"
-msgstr "Referencia URI"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,description:0
@@ -1393,110 +1293,115 @@ msgstr "Referencia URI"
#: field:calendar.event,name:0
#: field:calendar.todo,description:0
#: field:calendar.todo,name:0
+#: field:crm.meeting,description:0
msgid "Description"
-msgstr "Descripción"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "May"
-msgstr "Mayo"
-
-#. module: base_calendar
-#: field:base_calendar.invite.attendee,type:0
-#: view:calendar.attendee:0
-msgid "Type"
-msgstr "Tipo"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Search Invitations"
-msgstr "Buscar invitaciones"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,trigger_occurs:0
#: selection:res.alarm,trigger_occurs:0
msgid "After"
-msgstr "Después de"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,state:0
msgid "Stop"
-msgstr "Parar"
+msgstr ""
#. module: base_calendar
#: model:ir.model,name:base_calendar.model_ir_values
msgid "ir.values"
-msgstr "ir.valores"
+msgstr ""
#. module: base_calendar
-#: model:ir.model,name:base_calendar.model_ir_model
-msgid "Objects"
-msgstr "Objetos"
+#: view:crm.meeting:0
+msgid "Search Meetings"
+msgstr ""
+
+#. module: base_calendar
+#: model:ir.model,name:base_calendar.model_ir_attachment
+msgid "ir.attachment"
+msgstr ""
+
+#. module: base_calendar
+#: model:ir.model,name:base_calendar.model_crm_meeting_type
+msgid "Meeting Type"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
#: selection:calendar.attendee,state:0
msgid "Delegated"
-msgstr "Delegada"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,sa:0
#: field:calendar.event,sa:0
#: field:calendar.todo,sa:0
+#: field:crm.meeting,sa:0
msgid "Sat"
-msgstr "Sáb"
+msgstr ""
#. module: base_calendar
-#: view:calendar.event:0
-msgid "Choose day where repeat the meeting"
-msgstr "Eligir día en el que repetir la cita"
+#: model:ir.actions.act_window,help:base_calendar.action_res_alarm_view
+msgid ""
+"
\n"
+" Click to setup a new alarm type.\n"
+"
\n"
+" You can define a customized type of calendar alarm that may "
+"be\n"
+" assigned to calendar events or meetings.\n"
+"
\n"
+" "
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,freq:0
-msgid "Minutely"
-msgstr "Cada minuto"
+#: selection:crm.meeting,state:0
+msgid "Unconfirmed"
+msgstr ""
#. module: base_calendar
#: help:calendar.attendee,sent_by:0
msgid "Specify the user that is acting on behalf of the calendar user"
msgstr ""
-"Indique el usuario que está actuando en nombre del usuario del calendario."
#. module: base_calendar
#: view:calendar.event:0
-#: field:calendar.event.edit.all,date_deadline:0
+#: field:calendar.event,date_deadline:0
+#: field:calendar.todo,date_deadline:0
+#: field:crm.meeting,date_deadline:0
msgid "End Date"
-msgstr "Fecha final"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "February"
-msgstr "Febrero"
-
-#. module: base_calendar
-#: selection:calendar.event,freq:0
-#: selection:calendar.todo,freq:0
-msgid "Months"
-msgstr "Meses"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,cutype:0
msgid "Resource"
-msgstr "Recurso"
+msgstr ""
#. module: base_calendar
+#: field:crm.meeting.type,name:0
#: field:res.alarm,name:0
msgid "Name"
-msgstr "Nombre"
+msgstr ""
#. module: base_calendar
-#: model:ir.model,name:base_calendar.model_calendar_alarm
-msgid "Event alarm information"
-msgstr "Información del aviso del evento"
+#: field:calendar.event,exdate:0
+#: field:calendar.todo,exdate:0
+#: field:crm.meeting,exdate:0
+msgid "Exception Date/Times"
+msgstr ""
#. module: base_calendar
#: help:calendar.alarm,name:0
@@ -1504,154 +1409,162 @@ msgid ""
"Contains the text to be used as the message subject for "
"email or contains the text to be used for display"
msgstr ""
-"Contiene el texto a usar como asunto del mensaje para correos electrónicos, "
-"o contiene el texto a mostrar"
#. module: base_calendar
-#: field:calendar.event,alarm_id:0
-#: field:calendar.event,base_calendar_alarm_id:0
-#: field:calendar.todo,alarm_id:0
-#: field:calendar.todo,base_calendar_alarm_id:0
-msgid "Alarm"
-msgstr "Alarma"
-
-#. module: base_calendar
-#: code:addons/base_calendar/wizard/base_calendar_set_exrule.py:90
-#, python-format
-msgid "Please Apply Recurrency before applying Exception Rule."
+#: model:ir.model,name:base_calendar.model_mail_message
+msgid "Message"
+msgstr ""
+
+#. module: base_calendar
+#: field:calendar.event,base_calendar_alarm_id:0
+#: field:calendar.todo,base_calendar_alarm_id:0
+#: field:crm.meeting,base_calendar_alarm_id:0
+msgid "Alarm"
msgstr ""
-"Por favor, aplique la repetición antes de aplicar la excepción de la regla"
#. module: base_calendar
#: field:calendar.attendee,sent_by_uid:0
msgid "Sent By User"
-msgstr "Enviado por usuario"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,month_list:0
#: selection:calendar.event,month_list:0
#: selection:calendar.todo,month_list:0
+#: selection:crm.meeting,month_list:0
msgid "April"
-msgstr "Abril"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/crm_meeting.py:106
+#, python-format
+msgid "Email addresses not found"
+msgstr ""
#. module: base_calendar
#: view:calendar.event:0
msgid "Recurrency period"
-msgstr "Periodo de recurrencia"
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,week_list:0
#: field:calendar.event,week_list:0
#: field:calendar.todo,week_list:0
+#: field:crm.meeting,week_list:0
msgid "Weekday"
-msgstr "Día de la semana"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/base_calendar.py:1013
+#, python-format
+msgid "Interval cannot be negative."
+msgstr ""
#. module: base_calendar
-#: field:base.calendar.set.exrule,byday:0
#: field:calendar.event,byday:0
#: field:calendar.todo,byday:0
+#: field:crm.meeting,byday:0
msgid "By day"
-msgstr "Por día"
+msgstr ""
+
+#. module: base_calendar
+#: code:addons/base_calendar/base_calendar.py:441
+#, python-format
+msgid "First you have to specify the date of the invitation."
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,model_id:0
msgid "Model"
-msgstr "Modelo"
+msgstr ""
#. module: base_calendar
#: selection:calendar.alarm,action:0
msgid "Audio"
-msgstr "Audio"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,id:0
#: field:calendar.todo,id:0
+#: field:crm.meeting,id:0
msgid "ID"
-msgstr "ID"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,role:0
msgid "For information Purpose"
-msgstr "Con propósito informativo"
+msgstr ""
#. module: base_calendar
-#: view:base_calendar.invite.attendee:0
-msgid "Invite"
-msgstr "Invitar"
+#: field:calendar.event,select1:0
+#: field:calendar.todo,select1:0
+#: field:crm.meeting,select1:0
+msgid "Option"
+msgstr ""
#. module: base_calendar
#: model:ir.model,name:base_calendar.model_calendar_attendee
msgid "Attendee information"
-msgstr "Información asistentes"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,res_id:0
msgid "Resource ID"
-msgstr "ID del registro"
+msgstr ""
#. module: base_calendar
#: selection:calendar.attendee,state:0
msgid "Needs Action"
-msgstr "Necesita acción"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,sent_by:0
msgid "Sent By"
-msgstr "Enviado por"
+msgstr ""
#. module: base_calendar
#: field:calendar.event,sequence:0
#: field:calendar.todo,sequence:0
+#: field:crm.meeting,sequence:0
msgid "Sequence"
-msgstr "Secuencia"
+msgstr ""
#. module: base_calendar
#: help:calendar.event,alarm_id:0
#: help:calendar.todo,alarm_id:0
+#: help:crm.meeting,alarm_id:0
msgid "Set an alarm at this time, before the event occurs"
-msgstr "Configure una alarma en este momento, antes de que ocurra el evento"
+msgstr ""
#. module: base_calendar
-#: selection:base_calendar.invite.attendee,type:0
-msgid "Internal User"
-msgstr "Usuario interno"
-
-#. module: base_calendar
-#: view:calendar.attendee:0
#: view:calendar.event:0
+#: view:crm.meeting:0
msgid "Accept"
-msgstr "Aceptar"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,week_list:0
#: selection:calendar.event,week_list:0
#: selection:calendar.todo,week_list:0
+#: selection:crm.meeting,week_list:0
msgid "Saturday"
-msgstr "Sábado"
+msgstr ""
#. module: base_calendar
-#: view:calendar.attendee:0
-msgid "Invitation To"
-msgstr "Invitación a"
+#: field:calendar.event,interval:0
+#: field:calendar.todo,interval:0
+#: field:crm.meeting,interval:0
+msgid "Repeat Every"
+msgstr ""
#. module: base_calendar
-#: selection:base.calendar.set.exrule,byday:0
#: selection:calendar.event,byday:0
#: selection:calendar.todo,byday:0
+#: selection:crm.meeting,byday:0
msgid "Second"
-msgstr "Segundo"
+msgstr ""
#. module: base_calendar
#: field:calendar.attendee,availability:0
-#: field:res.users,availability:0
msgid "Free/Busy"
-msgstr "Libre/Ocupado"
-
-#. module: base_calendar
-#: field:calendar.event,end_type:0
-#: field:calendar.todo,end_type:0
-msgid "Way to end reccurency"
-msgstr "Forma de terminar recurrencia"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,duration:0
@@ -1659,20 +1572,16 @@ msgstr "Forma de terminar recurrencia"
#: field:calendar.event,duration:0
#: field:calendar.todo,date:0
#: field:calendar.todo,duration:0
+#: field:crm.meeting,duration:0
#: field:res.alarm,duration:0
#: field:res.alarm,trigger_duration:0
msgid "Duration"
-msgstr "Duración"
-
-#. module: base_calendar
-#: selection:base_calendar.invite.attendee,type:0
-msgid "External Email"
-msgstr "Email externo"
+msgstr ""
#. module: base_calendar
#: field:calendar.alarm,trigger_date:0
msgid "Trigger Date"
-msgstr "Fecha activación"
+msgstr ""
#. module: base_calendar
#: help:calendar.alarm,attach:0
@@ -1684,19 +1593,10 @@ msgid ""
" * Points to a procedure resource, which is invoked when "
" the alarm is triggered for procedure."
msgstr ""
-"* Apunta a un recurso de sonido, que se escucha cuando la alarma se activa "
-"por audio.\n"
-"* El archivo que está intentando ser enviado como adjunto en el correo "
-"electrónico.\n"
-"* Apunta a un recurso de procedimiento, que se invoca cuando la alarma se "
-"activa por procedimiento."
#. module: base_calendar
-#: selection:base.calendar.set.exrule,byday:0
#: selection:calendar.event,byday:0
#: selection:calendar.todo,byday:0
+#: selection:crm.meeting,byday:0
msgid "Fifth"
-msgstr "Quinto"
-
-#~ msgid "Set Exclude range"
-#~ msgstr "Fijar el rango de exclusión"
+msgstr ""
diff --git a/addons/base_crypt/i18n/nl_BE.po b/addons/base_crypt/i18n/nl_BE.po
index 7ad3faa1ef5..d77a3f14b47 100644
--- a/addons/base_crypt/i18n/nl_BE.po
+++ b/addons/base_crypt/i18n/nl_BE.po
@@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
-"PO-Revision-Date: 2012-07-26 17:52+0000\n"
-"Last-Translator: FULL NAME \n"
+"PO-Revision-Date: 2013-04-15 16:02+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Dutch (Belgium) \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:49+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: base_crypt
#: model:ir.model,name:base_crypt.model_res_users
msgid "Users"
-msgstr ""
+msgstr "Gebruikers"
#~ msgid "You can not have two users with the same login !"
#~ msgstr "U kunt geen twee gebruikers met dezelfde login maken."
diff --git a/addons/base_iban/base_iban.py b/addons/base_iban/base_iban.py
index 0872af2d0f3..d50ca33ff15 100644
--- a/addons/base_iban/base_iban.py
+++ b/addons/base_iban/base_iban.py
@@ -181,6 +181,5 @@ class res_partner_bank(osv.osv):
(_check_bank, '\nPlease define BIC/Swift code on bank for bank type IBAN Account to make valid payments', ['bic'])
]
-res_partner_bank()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_report_designer/base_report_designer.py b/addons/base_report_designer/base_report_designer.py
index cdfc7112d09..bc7959a17df 100644
--- a/addons/base_report_designer/base_report_designer.py
+++ b/addons/base_report_designer/base_report_designer.py
@@ -20,12 +20,13 @@
##############################################################################
import base64
+from StringIO import StringIO
+
+from openerp.modules.module import get_module_resource
import openerp.modules.registry
from openerp.osv import osv
from openerp_sxw2rml import sxw2rml
-from StringIO import StringIO
-from openerp import addons
-
+
class report_xml(osv.osv):
_inherit = 'ir.actions.report.xml'
@@ -36,9 +37,9 @@ class report_xml(osv.osv):
'''
sxwval = StringIO(base64.decodestring(file_sxw))
if file_type=='sxw':
- fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_oo2rml.xsl'),'rb')
+ fp = open(get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_oo2rml.xsl'),'rb')
if file_type=='odt':
- fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_odt2rml.xsl'),'rb')
+ fp = open(get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_odt2rml.xsl'),'rb')
return {'report_rml_content': str(sxw2rml(sxwval, xsl=fp.read()))}
def upload_report(self, cr, uid, report_id, file_sxw, file_type, context=None):
@@ -47,9 +48,9 @@ class report_xml(osv.osv):
'''
sxwval = StringIO(base64.decodestring(file_sxw))
if file_type=='sxw':
- fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_oo2rml.xsl'),'rb')
+ fp = open(get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_oo2rml.xsl'),'rb')
if file_type=='odt':
- fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_odt2rml.xsl'),'rb')
+ fp = open(get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_odt2rml.xsl'),'rb')
report = self.pool['ir.actions.report.xml'].write(cr, uid, [report_id], {
'report_sxw_content': base64.decodestring(file_sxw),
'report_rml_content': str(sxw2rml(sxwval, xsl=fp.read())),
@@ -75,7 +76,6 @@ class report_xml(osv.osv):
'report_rml_content': rml_data and base64.encodestring(rml_data) or False
}
-report_xml()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_report_designer/base_report_designer_installer.xml b/addons/base_report_designer/base_report_designer_installer.xml
index 657eae8fd63..99898f5a703 100644
--- a/addons/base_report_designer/base_report_designer_installer.xml
+++ b/addons/base_report_designer/base_report_designer_installer.xml
@@ -20,7 +20,7 @@
-
+
diff --git a/addons/base_report_designer/installer.py b/addons/base_report_designer/installer.py
index bfda6e7a30f..7fddc27f037 100644
--- a/addons/base_report_designer/installer.py
+++ b/addons/base_report_designer/installer.py
@@ -23,7 +23,6 @@ from openerp.osv import fields
from openerp.osv import osv
import base64
from openerp.tools.translate import _
-from openerp import addons
class base_report_designer_installer(osv.osv_memory):
_name = 'base_report_designer.installer'
@@ -31,13 +30,13 @@ class base_report_designer_installer(osv.osv_memory):
def default_get(self, cr, uid, fields, context=None):
data = super(base_report_designer_installer, self).default_get(cr, uid, fields, context=context)
- plugin_file = open(addons.get_module_resource('base_report_designer','plugin', 'openerp_report_designer.zip'),'rb')
- data['plugin_file'] = base64.encodestring(plugin_file.read())
+ base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
+ data['plugin_file'] = base_url + '/base_report_designer/static/base-report-designer-plugin/openerp_report_designer.zip'
return data
_columns = {
'name':fields.char('File name', size=34),
- 'plugin_file':fields.binary('OpenObject Report Designer Plug-in', readonly=True, help="OpenObject Report Designer plug-in file. Save as this file and install this plug-in in OpenOffice."),
+ 'plugin_file':fields.char('OpenObject Report Designer Plug-in', size=256, readonly=True, help="OpenObject Report Designer plug-in file. Save as this file and install this plug-in in OpenOffice."),
'description':fields.text('Description', readonly=True)
}
@@ -58,6 +57,5 @@ class base_report_designer_installer(osv.osv_memory):
4. if your connection success, A message appears like 'You can start creating your report in current document.'.
"""
}
-base_report_designer_installer()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl b/addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl
index 50ffb3d81be..9f9e5050d69 100644
--- a/addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl
+++ b/addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl
@@ -414,7 +414,7 @@
- .
+
diff --git a/addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl b/addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl
index 66ef0b5b53c..ae68ae1ed1b 100644
--- a/addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl
+++ b/addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl
@@ -414,7 +414,7 @@
- .
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer.zip b/addons/base_report_designer/static/base-report-designer-plugin/openerp_report_designer.zip
similarity index 100%
rename from addons/base_report_designer/plugin/openerp_report_designer.zip
rename to addons/base_report_designer/static/base-report-designer-plugin/openerp_report_designer.zip
diff --git a/addons/base_report_designer/wizard/base_report_designer_modify.py b/addons/base_report_designer/wizard/base_report_designer_modify.py
index 838f591a2f4..e8ed45e7ce1 100644
--- a/addons/base_report_designer/wizard/base_report_designer_modify.py
+++ b/addons/base_report_designer/wizard/base_report_designer_modify.py
@@ -54,7 +54,6 @@ class base_report_sxw(osv.osv_memory):
'target': 'new',
}
-base_report_sxw()
class base_report_file_sxw(osv.osv_memory):
"""Base Report File sxw """
@@ -116,7 +115,6 @@ class base_report_file_sxw(osv.osv_memory):
'type': 'ir.actions.act_window',
'target': 'new',
}
-base_report_file_sxw()
class base_report_rml_save(osv.osv_memory):
"""Base Report file Save"""
@@ -146,6 +144,5 @@ class base_report_rml_save(osv.osv_memory):
'file_rml':fields.binary('Save As'),
}
-base_report_rml_save()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_setup/i18n/nl_BE.po b/addons/base_setup/i18n/nl_BE.po
index f22fd2c8adc..518ada07a5c 100644
--- a/addons/base_setup/i18n/nl_BE.po
+++ b/addons/base_setup/i18n/nl_BE.po
@@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-10-01 11:22+0000\n"
+"PO-Revision-Date: 2013-04-26 16:24+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \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:12+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-27 05:44+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
#. module: base_setup
#: view:sale.config.settings:0
msgid "Emails Integration"
-msgstr ""
+msgstr "E-mailintegratie"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
@@ -29,18 +29,19 @@ msgstr "Gast"
#. module: base_setup
#: view:sale.config.settings:0
msgid "Contacts"
-msgstr ""
+msgstr "Contactpersonen"
#. module: base_setup
#: model:ir.model,name:base_setup.model_base_config_settings
msgid "base.config.settings"
-msgstr ""
+msgstr "base.config.settings"
#. module: base_setup
#: field:base.config.settings,module_auth_oauth:0
msgid ""
"Use external authentication providers, sign in with google, facebook, ..."
msgstr ""
+"Gebruik externe verificatieproviders. Meld aan met Google, Facebook, ..."
#. module: base_setup
#: view:sale.config.settings:0
@@ -54,11 +55,19 @@ msgid ""
"OpenERP using specific\n"
" plugins for your preferred email application."
msgstr ""
+"OpenERP maakt het mogelijk om automatisch leads (of andere documenten)\n"
+" aan te maken op basis van inkomende e-mails. U "
+"kunt automatisch e-mails synchroniseren met OpenERP\n"
+" met behulp van reguliere POP / IMAP-accounts, "
+"via een direct e-mailintegratiescript voor uw\n"
+" e-mailserver, of door zelf uw e-mails naar "
+"OpenERP te sturen met behulp van specifieke\n"
+" plug-ins voor uw favoriete e-mailprogramma."
#. module: base_setup
#: field:sale.config.settings,module_sale:0
msgid "SALE"
-msgstr ""
+msgstr "VERKOOP"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
@@ -68,24 +77,24 @@ msgstr "Lid"
#. module: base_setup
#: view:base.config.settings:0
msgid "Portal access"
-msgstr ""
+msgstr "Portaaltoegang"
#. module: base_setup
#: view:base.config.settings:0
msgid "Authentication"
-msgstr ""
+msgstr "Verificatie"
#. module: base_setup
#: view:sale.config.settings:0
msgid "Quotations and Sales Orders"
-msgstr ""
+msgstr "Offertes en verkooporders"
#. module: base_setup
#: view:base.config.settings:0
#: model:ir.actions.act_window,name:base_setup.action_general_configuration
#: model:ir.ui.menu,name:base_setup.menu_general_configuration
msgid "General Settings"
-msgstr ""
+msgstr "Algemeen"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
@@ -95,12 +104,12 @@ msgstr "Donor"
#. module: base_setup
#: view:base.config.settings:0
msgid "Email"
-msgstr ""
+msgstr "E-mail"
#. module: base_setup
#: field:sale.config.settings,module_crm:0
msgid "CRM"
-msgstr ""
+msgstr "Relatiebeheer"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
@@ -110,32 +119,32 @@ msgstr "Patiënt"
#. module: base_setup
#: field:base.config.settings,module_base_import:0
msgid "Allow users to import data from CSV files"
-msgstr ""
+msgstr "Gebruikers mogen gegevens importeren uit csv-bestanden"
#. module: base_setup
#: field:base.config.settings,module_multi_company:0
msgid "Manage multiple companies"
-msgstr ""
+msgstr "Meerdere bedrijven beheren"
#. module: base_setup
#: view:sale.config.settings:0
msgid "On Mail Client"
-msgstr ""
+msgstr "Op e-mailclient"
#. module: base_setup
#: view:base.config.settings:0
msgid "--db-filter=YOUR_DATABAE"
-msgstr ""
+msgstr "--db-filter=UW_DATABASE"
#. module: base_setup
#: field:sale.config.settings,module_web_linkedin:0
msgid "Get contacts automatically from linkedIn"
-msgstr ""
+msgstr "Haal contactpersonen op uit LinkedIn"
#. module: base_setup
#: field:sale.config.settings,module_plugin_thunderbird:0
msgid "Enable Thunderbird plug-in"
-msgstr ""
+msgstr "Activeer de Thunderbirdplug-in"
#. module: base_setup
#: view:base.setup.terminology:0
@@ -145,22 +154,22 @@ msgstr "res_config_contents"
#. module: base_setup
#: view:sale.config.settings:0
msgid "Customer Features"
-msgstr ""
+msgstr "Klantenopties"
#. module: base_setup
#: view:base.config.settings:0
msgid "Import / Export"
-msgstr ""
+msgstr "Import / Export"
#. module: base_setup
#: view:sale.config.settings:0
msgid "Sale Features"
-msgstr ""
+msgstr "Verkoopopties"
#. module: base_setup
#: field:sale.config.settings,module_plugin_outlook:0
msgid "Enable Outlook plug-in"
-msgstr ""
+msgstr "Activeer de Outlookplug-in"
#. module: base_setup
#: view:base.setup.terminology:0
@@ -179,7 +188,7 @@ msgstr "Huurder"
#. module: base_setup
#: help:base.config.settings,module_share:0
msgid "Share or embbed any screen of openerp."
-msgstr ""
+msgstr "Gelijk welk scherm van OpenERP delen of insluiten"
#. module: base_setup
#: selection:base.setup.terminology,partner:0
@@ -192,6 +201,8 @@ msgid ""
"When you create a new contact (person or company), you will be able to load "
"all the data from LinkedIn (photos, address, etc)."
msgstr ""
+"Als u een nieuwe contactpersoon maakt (persoon of bedrijf), kunt u alle "
+"gegevens van LinkedIn laden (foto, adres, enz.)"
#. module: base_setup
#: help:base.config.settings,module_multi_company:0
@@ -200,6 +211,9 @@ msgid ""
"companies.\n"
" This installs the module multi_company."
msgstr ""
+"Werken in omgevingen met meerdere bedrijven, met de nodige "
+"toegangsbeveiliging tussen de bedrijven.\n"
+" Hiermee installeert u de module multi_company."
#. module: base_setup
#: view:base.config.settings:0
@@ -208,6 +222,9 @@ msgid ""
"You can\n"
" launch the OpenERP Server with the option"
msgstr ""
+"Het openbare portaal is alleen toegankelijk als u zich in een enkele "
+"databasemodus bevindt. U kunt\n"
+" de OpenERP-server starten met de optie"
#. module: base_setup
#: view:base.config.settings:0
@@ -215,11 +232,13 @@ msgid ""
"You will find more options in your company details: address for the header "
"and footer, overdue payments texts, etc."
msgstr ""
+"U vindt meer opties bij de bedrijfsgegevens: adres voor de kop- en "
+"voettekst, teksten voor achterstallige betalingen, enz."
#. module: base_setup
#: model:ir.model,name:base_setup.model_sale_config_settings
msgid "sale.config.settings"
-msgstr ""
+msgstr "sale.config.settings"
#. module: base_setup
#: field:base.setup.terminology,partner:0
@@ -238,6 +257,12 @@ msgid ""
"projects,\n"
" etc."
msgstr ""
+"Wanneer u een document naar een klant stuurt,\n"
+" (offerte, factuur), kan uw klant\n"
+" aanmelden en zijn documenten bekijken,\n"
+" uw bedrijfsnieuws lezen, zijn projecten "
+"controleren,\n"
+" enz."
#. module: base_setup
#: model:ir.model,name:base_setup.model_base_setup_terminology
@@ -253,6 +278,8 @@ msgstr "Cliënt"
#: help:base.config.settings,module_portal_anonymous:0
msgid "Enable the public part of openerp, openerp becomes a public website."
msgstr ""
+"Activeer het openbare deel van OpenERP; OpenERP wordt hiermee een openbare "
+"website."
#. module: base_setup
#: help:sale.config.settings,module_plugin_thunderbird:0
@@ -265,6 +292,13 @@ msgid ""
" Partner from the selected emails.\n"
" This installs the module plugin_thunderbird."
msgstr ""
+"Met de plug-in kunt u e-mails met bijlagen koppelen aan de geselecteerde\n"
+" OpenERP-objecten. U kunt een relatie of een lead kiezen en\n"
+" de gekozen e-mail koppelen als een .eml-bestand als bijlage\n"
+" aan het geselecteerde record. U kunt documenten aanmaken "
+"voor CRM-lead\n"
+" en relaties vanuit de geselecteerde e-mails. Hiermee "
+"installeert u de module plugin_thunderbird."
#. module: base_setup
#: selection:base.setup.terminology,partner:0
@@ -280,7 +314,7 @@ msgstr "Gebruik een andere benaming voor Klant"
#: model:ir.actions.act_window,name:base_setup.action_sale_config
#: view:sale.config.settings:0
msgid "Configure Sales"
-msgstr ""
+msgstr "Verkoop instellen"
#. module: base_setup
#: help:sale.config.settings,module_plugin_outlook:0
@@ -293,16 +327,23 @@ msgid ""
" email into an OpenERP mail message with attachments.\n"
" This installs the module plugin_outlook."
msgstr ""
+"Met de Outlookplug-in kunt u een object selecteren dat u wilt toevoegen\n"
+" aan uw e-mail en de bijlagen van MS Outlook. U kunt een "
+"relatie \n"
+" of een lead kiezen en de geselecteerde e-mail archiveren in "
+"een\n"
+" OpenERP-mailbericht met bijlagen.\n"
+" Hiermee installeert u de module plugin_outlook."
#. module: base_setup
#: view:base.config.settings:0
msgid "Options"
-msgstr ""
+msgstr "Opties"
#. module: base_setup
#: field:base.config.settings,module_portal:0
msgid "Activate the customer portal"
-msgstr ""
+msgstr "Klantenportaal activeren"
#. module: base_setup
#: view:base.config.settings:0
@@ -311,36 +352,37 @@ msgid ""
" Once activated, the login page will be "
"replaced by the public website."
msgstr ""
+"Na activering zal de aanmeldpagina worden vervangen door de openbare website."
#. module: base_setup
#: field:base.config.settings,module_share:0
msgid "Allow documents sharing"
-msgstr ""
+msgstr "Sta het delen van documenten toe"
#. module: base_setup
#: view:base.config.settings:0
msgid "(company news, jobs, contact form, etc.)"
-msgstr ""
+msgstr "(bedrijfsnieuws, vacatures, contactformulier, enz.)"
#. module: base_setup
#: field:base.config.settings,module_portal_anonymous:0
msgid "Activate the public portal"
-msgstr ""
+msgstr "Openbare portaal activeren"
#. module: base_setup
#: view:base.config.settings:0
msgid "Configure outgoing email servers"
-msgstr ""
+msgstr "Uitgaande e-mailservers instellen"
#. module: base_setup
#: view:sale.config.settings:0
msgid "Social Network Integration"
-msgstr ""
+msgstr "Integratie sociale netwerken"
#. module: base_setup
#: help:base.config.settings,module_portal:0
msgid "Give your customers access to their documents."
-msgstr ""
+msgstr "Geef uw klanten toegang tot hun documenten."
#. module: base_setup
#: view:base.config.settings:0
@@ -352,7 +394,7 @@ msgstr "Afbreken"
#: view:base.config.settings:0
#: view:sale.config.settings:0
msgid "Apply"
-msgstr ""
+msgstr "Toepassen"
#. module: base_setup
#: view:base.setup.terminology:0
@@ -363,12 +405,12 @@ msgstr "Kies uw terminologie"
#: view:base.config.settings:0
#: view:sale.config.settings:0
msgid "or"
-msgstr ""
+msgstr "of"
#. module: base_setup
#: view:base.config.settings:0
msgid "Configure your company data"
-msgstr ""
+msgstr "Uw bedrijfsgegevens instellen"
#~ msgid "Logo"
#~ msgstr "Logo"
diff --git a/addons/base_status/i18n/lt.po b/addons/base_status/i18n/lt.po
new file mode 100644
index 00000000000..cdaf9b0db37
--- /dev/null
+++ b/addons/base_status/i18n/lt.po
@@ -0,0 +1,76 @@
+# 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:17+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: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid "Error !"
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:166
+#, python-format
+msgid "%s has been opened."
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:199
+#, python-format
+msgid "%s has been renewed."
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid "Error!"
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid ""
+"You can not escalate, you are already at the top level regarding your sales-"
+"team category."
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:193
+#, python-format
+msgid "%s is now pending."
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:187
+#, python-format
+msgid "%s has been canceled."
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid ""
+"You are already at the top level of your sales-team category.\n"
+"Therefore you cannot escalate furthermore."
+msgstr ""
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:181
+#, python-format
+msgid "%s has been closed."
+msgstr ""
diff --git a/addons/base_status/i18n/nl_BE.po b/addons/base_status/i18n/nl_BE.po
new file mode 100644
index 00000000000..6a3c2d83fc7
--- /dev/null
+++ b/addons/base_status/i18n/nl_BE.po
@@ -0,0 +1,80 @@
+# Dutch (Belgium) 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-15 16:40+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Dutch (Belgium) \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-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid "Error !"
+msgstr "Fout"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:166
+#, python-format
+msgid "%s has been opened."
+msgstr "%s is geopend."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:199
+#, python-format
+msgid "%s has been renewed."
+msgstr "%s is vernieuwd."
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid "Error!"
+msgstr "Fout"
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:107
+#, python-format
+msgid ""
+"You can not escalate, you are already at the top level regarding your sales-"
+"team category."
+msgstr ""
+"U kunt niet escaleren; u heeft het hoogste niveau in de verkoopteams al "
+"bereikt."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:193
+#, python-format
+msgid "%s is now pending."
+msgstr "%s is wachtend."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:187
+#, python-format
+msgid "%s has been canceled."
+msgstr "%s is geannuleerd."
+
+#. module: base_status
+#: code:addons/base_status/base_stage.py:210
+#, python-format
+msgid ""
+"You are already at the top level of your sales-team category.\n"
+"Therefore you cannot escalate furthermore."
+msgstr ""
+"U bent al op het hoogste niveau van uw verkoopteam.\n"
+"U kunt dus niet verder escaleren."
+
+#. module: base_status
+#: code:addons/base_status/base_state.py:181
+#, python-format
+msgid "%s has been closed."
+msgstr "%s is gesloten."
diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py
index 616333e3b47..e7501334997 100644
--- a/addons/base_vat/base_vat.py
+++ b/addons/base_vat/base_vat.py
@@ -134,6 +134,9 @@ class res_partner(osv.osv):
'vat_subjected': fields.boolean('VAT Legal Statement', help="Check this box if the partner is subjected to the VAT. It will be used for the VAT legal statement.")
}
+ def _commercial_fields(self, cr, uid, context=None):
+ return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['vat_subjected']
+
def _construct_constraint_msg(self, cr, uid, ids, context=None):
def default_vat_check(cn, vn):
# by default, a VAT number is valid if:
@@ -243,6 +246,5 @@ class res_partner(osv.osv):
return False
return check == int(vat[8])
-res_partner()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_vat/i18n/nl_BE.po b/addons/base_vat/i18n/nl_BE.po
index 39966dc58ef..a2fe05c5705 100644
--- a/addons/base_vat/i18n/nl_BE.po
+++ b/addons/base_vat/i18n/nl_BE.po
@@ -7,19 +7,19 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
-"PO-Revision-Date: 2012-10-01 11:23+0000\n"
+"PO-Revision-Date: 2013-04-15 16:03+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \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:10+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: base_vat
#: view:res.partner:0
msgid "Check Validity"
-msgstr ""
+msgstr "Geldigheid controleren"
#. module: base_vat
#: code:addons/base_vat/base_vat.py:147
@@ -45,7 +45,7 @@ msgstr "Bedrijven"
#: code:addons/base_vat/base_vat.py:111
#, python-format
msgid "Error!"
-msgstr ""
+msgstr "Fout"
#. module: base_vat
#: help:res.partner,vat_subjected:0
diff --git a/addons/claim_from_delivery/i18n/nl_BE.po b/addons/claim_from_delivery/i18n/nl_BE.po
index a8793109b5f..38aab39e523 100644
--- a/addons/claim_from_delivery/i18n/nl_BE.po
+++ b/addons/claim_from_delivery/i18n/nl_BE.po
@@ -8,29 +8,29 @@ 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: 2012-10-01 11:24+0000\n"
+"PO-Revision-Date: 2013-04-15 16:38+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Dutch (Belgium) \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:41+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: claim_from_delivery
#: view:stock.picking.out:0
msgid "Claims"
-msgstr ""
+msgstr "Klachten"
#. module: claim_from_delivery
#: model:res.request.link,name:claim_from_delivery.request_link_claim_from_delivery
msgid "Delivery Order"
-msgstr ""
+msgstr "Leveringsorder"
#. module: claim_from_delivery
#: model:ir.actions.act_window,name:claim_from_delivery.action_claim_from_delivery
msgid "Claim From Delivery"
-msgstr ""
+msgstr "Klachten van levering"
#~ msgid "Claim"
#~ msgstr "Klacht"
diff --git a/addons/contacts/i18n/lt.po b/addons/contacts/i18n/lt.po
new file mode 100644
index 00000000000..f785a308009
--- /dev/null
+++ b/addons/contacts/i18n/lt.po
@@ -0,0 +1,45 @@
+# 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:20+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: contacts
+#: model:ir.actions.act_window,help:contacts.action_contacts
+msgid ""
+"
\n"
+" Click to add a contact in your address book.\n"
+"
\n"
+" OpenERP helps you easily track all activities related to\n"
+" a customer; discussions, history of business opportunities,\n"
+" documents, etc.\n"
+"
\n"
+" "
+msgstr ""
+"
\n"
+"Spauskite, kad sukurtumėte kontaktą adresų knygoje.\n"
+"
\n"
+"OpenERP pagalba galima stebėti visus veiksmus susijusius su\n"
+"kontaktu; bendravimas, pardavimų galimybių istorija,\n"
+"dokumentai, ir t.t.\n"
+"
\n"
+" "
+
+#. module: contacts
+#: model:ir.actions.act_window,name:contacts.action_contacts
+#: model:ir.ui.menu,name:contacts.menu_contacts
+msgid "Contacts"
+msgstr "Kontaktai"
diff --git a/addons/contacts/i18n/nl_BE.po b/addons/contacts/i18n/nl_BE.po
new file mode 100644
index 00000000000..78fdb540ad6
--- /dev/null
+++ b/addons/contacts/i18n/nl_BE.po
@@ -0,0 +1,46 @@
+# Dutch (Belgium) 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-15 16:01+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Dutch (Belgium) \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-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
+
+#. module: contacts
+#: model:ir.actions.act_window,help:contacts.action_contacts
+msgid ""
+"
\n"
+" Click to add a contact in your address book.\n"
+"
\n"
+" OpenERP helps you easily track all activities related to\n"
+" a customer; discussions, history of business opportunities,\n"
+" documents, etc.\n"
+"
\n"
+" "
+msgstr ""
+"
\n"
+" Klik hier om een contactpersoon toe te voegen aan het "
+"adresboek.\n"
+"
\n"
+" Met OpenERP kunt u eenvoudig alle activiteiten registreren met "
+"betrekking tot \n"
+" een klant, discussies, opportuniteiten, documenten, enz. \n"
+"
\n"
+" "
+
+#. module: contacts
+#: model:ir.actions.act_window,name:contacts.action_contacts
+#: model:ir.ui.menu,name:contacts.menu_contacts
+msgid "Contacts"
+msgstr "Contactpersonen"
diff --git a/addons/crm/__init__.py b/addons/crm/__init__.py
index d78fb09eae7..4e3a704d5f3 100644
--- a/addons/crm/__init__.py
+++ b/addons/crm/__init__.py
@@ -28,6 +28,7 @@ import report
import wizard
import res_partner
import res_config
+import base_partner_merge
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index 4b88fc13d6d..8bd87db35b1 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -95,8 +95,8 @@ Dashboard for CRM will include:
'board_crm_view.xml',
'res_config_view.xml',
-
'crm_case_section_view.xml',
+ 'base_partner_merge_view.xml',
],
'demo': [
'crm_demo.xml',
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
new file mode 100644
index 00000000000..b2645e7fb79
--- /dev/null
+++ b/addons/crm/base_partner_merge.py
@@ -0,0 +1,760 @@
+#!/usr/bin/env python
+from __future__ import absolute_import
+from email.utils import parseaddr
+import functools
+import htmlentitydefs
+import itertools
+import logging
+import operator
+import re
+from ast import literal_eval
+from openerp.tools import mute_logger
+
+# Validation Library https://pypi.python.org/pypi/validate_email/1.1
+from .validate_email import validate_email
+
+from openerp.osv import osv, orm
+from openerp.osv import fields
+from openerp.osv.orm import browse_record
+from openerp.tools.translate import _
+
+pattern = re.compile("&(\w+?);")
+
+_logger = logging.getLogger('base.partner.merge')
+
+
+# http://www.php2python.com/wiki/function.html-entity-decode/
+def html_entity_decode_char(m, defs=htmlentitydefs.entitydefs):
+ try:
+ return defs[m.group(1)]
+ except KeyError:
+ return m.group(0)
+
+
+def html_entity_decode(string):
+ return pattern.sub(html_entity_decode_char, string)
+
+
+def sanitize_email(email):
+ assert isinstance(email, basestring) and email
+
+ result = re.subn(r';|/|:', ',',
+ html_entity_decode(email or ''))[0].split(',')
+
+ emails = [parseaddr(email)[1]
+ for item in result
+ for email in item.split()]
+
+ return [email.lower()
+ for email in emails
+ if validate_email(email)]
+
+
+def is_integer_list(ids):
+ return all(isinstance(i, (int, long)) for i in ids)
+
+
+class ResPartner(osv.Model):
+ _inherit = 'res.partner'
+
+ _columns = {
+ 'id': fields.integer('Id', readonly=True),
+ 'create_date': fields.datetime('Create Date', readonly=True),
+ }
+
+class MergePartnerLine(osv.TransientModel):
+ _name = 'base.partner.merge.line'
+
+ _columns = {
+ 'wizard_id': fields.many2one('base.partner.merge.automatic.wizard',
+ 'Wizard'),
+ 'min_id': fields.integer('MinID'),
+ 'aggr_ids': fields.char('Ids', required=True),
+ }
+
+ _order = 'min_id asc'
+
+
+class MergePartnerAutomatic(osv.TransientModel):
+ """
+ The idea behind this wizard is to create a list of potential partners to
+ merge. We use two objects, the first one is the wizard for the end-user.
+ And the second will contain the partner list to merge.
+ """
+ _name = 'base.partner.merge.automatic.wizard'
+
+ _columns = {
+ # Group by
+ 'group_by_email': fields.boolean('Email'),
+ 'group_by_name': fields.boolean('Name'),
+ 'group_by_is_company': fields.boolean('Is Company'),
+ 'group_by_vat': fields.boolean('VAT'),
+ 'group_by_parent_id': fields.boolean('Parent Company'),
+
+ 'state': fields.selection([('option', 'Option'),
+ ('selection', 'Selection'),
+ ('finished', 'Finished')],
+ 'State',
+ readonly=True,
+ required=True),
+ 'number_group': fields.integer("Group of Contacts", readonly=True),
+ 'current_line_id': fields.many2one('base.partner.merge.line', 'Current Line'),
+ 'line_ids': fields.one2many('base.partner.merge.line', 'wizard_id', 'Lines'),
+ 'partner_ids': fields.many2many('res.partner', string='Contacts'),
+
+ 'exclude_contact': fields.boolean('A user associated to the contact'),
+ 'exclude_journal_item': fields.boolean('Journal Items associated to the contact'),
+ 'maximum_group': fields.integer("Maximum of Group of Contacts"),
+ }
+
+ _defaults = {
+ 'state': 'option',
+ }
+
+ def get_fk_on(self, cr, table):
+ q = """ SELECT cl1.relname as table,
+ att1.attname as column
+ FROM pg_constraint as con, pg_class as cl1, pg_class as cl2,
+ pg_attribute as att1, pg_attribute as att2
+ WHERE con.conrelid = cl1.oid
+ AND con.confrelid = cl2.oid
+ AND array_lower(con.conkey, 1) = 1
+ AND con.conkey[1] = att1.attnum
+ AND att1.attrelid = cl1.oid
+ AND cl2.relname = %s
+ AND att2.attname = 'id'
+ AND array_lower(con.confkey, 1) = 1
+ AND con.confkey[1] = att2.attnum
+ AND att2.attrelid = cl2.oid
+ AND con.contype = 'f'
+ """
+ return cr.execute(q, (table,))
+
+ def _update_foreign_keys(self, cr, uid, src_partners, dst_partner, context=None):
+ _logger.debug('_update_foreign_keys for dst_partner: %s for src_partners: %r', dst_partner.id, list(map(operator.attrgetter('id'), src_partners)))
+
+ # find the many2one relation to a partner
+ proxy = self.pool.get('res.partner')
+ self.get_fk_on(cr, 'res_partner')
+
+ # ignore two tables
+
+ for table, column in cr.fetchall():
+ if 'base_partner_merge_' in table:
+ continue
+ partner_ids = tuple(map(int, src_partners))
+
+ query = "SELECT column_name FROM information_schema.columns WHERE table_name LIKE '%s'" % (table)
+ cr.execute(query, ())
+ columns = []
+ for data in cr.fetchall():
+ if data[0] != column:
+ columns.append(data[0])
+
+ query_dic = {
+ 'table': table,
+ 'column': column,
+ 'value': columns[0],
+ }
+ if len(columns) <= 1:
+ # unique key treated
+ query = """
+ UPDATE "%(table)s" as ___tu
+ SET %(column)s = %%s
+ WHERE
+ %(column)s = %%s AND
+ NOT EXISTS (
+ SELECT 1
+ FROM "%(table)s" as ___tw
+ WHERE
+ %(column)s = %%s AND
+ ___tu.%(value)s = ___tw.%(value)s
+ )""" % query_dic
+ for partner_id in partner_ids:
+ cr.execute(query, (dst_partner.id, partner_id, dst_partner.id))
+ else:
+ cr.execute("SAVEPOINT recursive_partner_savepoint")
+ try:
+ query = 'UPDATE "%(table)s" SET %(column)s = %%s WHERE %(column)s IN %%s' % query_dic
+ cr.execute(query, (dst_partner.id, partner_ids,))
+
+ if column == proxy._parent_name and table == 'res_partner':
+ query = """
+ WITH RECURSIVE cycle(id, parent_id) AS (
+ SELECT id, parent_id FROM res_partner
+ UNION
+ SELECT cycle.id, res_partner.parent_id
+ FROM res_partner, cycle
+ WHERE res_partner.id = cycle.parent_id AND
+ cycle.id != cycle.parent_id
+ )
+ SELECT id FROM cycle WHERE id = parent_id AND id = %s
+ """
+ cr.execute(query, (dst_partner.id,))
+ if cr.fetchall():
+ cr.execute("ROLLBACK TO SAVEPOINT recursive_partner_savepoint")
+ finally:
+ cr.execute("RELEASE SAVEPOINT recursive_partner_savepoint")
+
+ def _update_reference_fields(self, cr, uid, src_partners, dst_partner, context=None):
+ _logger.debug('_update_reference_fields for dst_partner: %s for src_partners: %r', dst_partner.id, list(map(operator.attrgetter('id'), src_partners)))
+
+ def update_records(model, src, field_model='model', field_id='res_id', context=None):
+ proxy = self.pool.get(model)
+ if proxy is None:
+ return
+ domain = [(field_model, '=', 'res.partner'), (field_id, '=', src.id)]
+ ids = proxy.search(cr, uid, domain, context=context)
+ return proxy.write(cr, uid, ids, {field_id: dst_partner.id}, context=context)
+
+ update_records = functools.partial(update_records, context=context)
+
+ for partner in src_partners:
+ update_records('base.calendar', src=partner, field_model='model_id.model')
+ update_records('ir.attachment', src=partner, field_model='res_model')
+ update_records('mail.followers', src=partner, field_model='res_model')
+ update_records('mail.message', src=partner)
+ update_records('marketing.campaign.workitem', src=partner, field_model='object_id.model')
+ update_records('ir.model.data', src=partner)
+
+ proxy = self.pool['ir.model.fields']
+ domain = [('ttype', '=', 'reference')]
+ record_ids = proxy.search(cr, uid, domain, context=context)
+
+ for record in proxy.browse(cr, uid, record_ids, context=context):
+ proxy_model = self.pool[record.model]
+
+ field_type = proxy_model._columns.get(record.name).__class__._type
+
+ if field_type == 'function':
+ continue
+
+ for partner in src_partners:
+ domain = [
+ (record.name, '=', 'res.partner,%d' % partner.id)
+ ]
+ model_ids = proxy_model.search(cr, uid, domain, context=context)
+ values = {
+ record.name: 'res.partner,%d' % dst_partner.id,
+ }
+ proxy_model.write(cr, uid, model_ids, values, context=context)
+
+ def _update_values(self, cr, uid, src_partners, dst_partner, context=None):
+ _logger.debug('_update_values for dst_partner: %s for src_partners: %r', dst_partner.id, list(map(operator.attrgetter('id'), src_partners)))
+
+ columns = dst_partner._columns
+ def write_serializer(column, item):
+ if isinstance(item, browse_record):
+ return item.id
+ else:
+ return item
+
+ values = dict()
+ for column, field in columns.iteritems():
+ if field._type not in ('many2many', 'one2many', 'function'):
+ for item in itertools.chain(src_partners, [dst_partner]):
+ if item[column]:
+ values[column] = write_serializer(column, item[column])
+
+ values.pop('id', None)
+ parent_id = values.pop('parent_id', None)
+ dst_partner.write(values)
+ if parent_id and parent_id != dst_partner.id:
+ try:
+ dst_partner.write({'parent_id': parent_id})
+ except (osv.except_osv, orm.except_orm):
+ _logger.info('Skip recursive partner hierarchies for parent_id %s of partner: %s', parent_id, dst_partner.id)
+
+ @mute_logger('openerp.osv.expression', 'openerp.osv.orm')
+ def _merge(self, cr, uid, partner_ids, context=None):
+ proxy = self.pool.get('res.partner')
+
+ partner_ids = proxy.exists(cr, uid, list(partner_ids), context=context)
+ if len(partner_ids) < 2:
+ return
+
+ partners = proxy.browse(cr, uid, list(partner_ids), context=context)
+ ordered_partners = sorted(sorted(partners,
+ key=operator.attrgetter('create_date'), reverse=True),
+ key=operator.attrgetter('active'), reverse=True)
+
+ dst_partner = ordered_partners[-1]
+ src_partners = ordered_partners[:-1]
+ _logger.info("dst_partner: %s", dst_partner.id)
+
+ call_it = lambda function: function(cr, uid, src_partners, dst_partner,
+ context=context)
+
+ call_it(self._update_foreign_keys)
+ call_it(self._update_reference_fields)
+ call_it(self._update_values)
+
+ _logger.info("---merged---")
+
+ for partner in src_partners:
+ partner.unlink()
+
+
+ def clean_emails(self, cr, uid, context=None):
+ """
+ Clean the email address of the partner, if there is an email field with
+ a mimum of two addresses, the system will create a new partner, with the
+ information of the previous one and will copy the new cleaned email into
+ the email field.
+ """
+ if context is None:
+ context = {}
+
+ proxy_model = self.pool['ir.model.fields']
+ field_ids = proxy_model.search(cr, uid, [('model', '=', 'res.partner'),
+ ('ttype', 'like', '%2many')],
+ context=context)
+ fields = proxy_model.read(cr, uid, field_ids, context=context)
+ reset_fields = dict((field['name'], []) for field in fields)
+
+ proxy_partner = self.pool['res.partner']
+ context['active_test'] = False
+ ids = proxy_partner.search(cr, uid, [], context=context)
+
+ fields = ['name', 'var' 'partner_id' 'is_company', 'email']
+ partners = proxy_partner.read(cr, uid, ids, fields, context=context)
+
+ partners.sort(key=operator.itemgetter('id'))
+ partners_len = len(partners)
+
+ _logger.info('partner_len: %r', partners_len)
+
+ for idx, partner in enumerate(partners):
+ if not partner['email']:
+ continue
+
+ percent = (idx / float(partners_len)) * 100.0
+ _logger.info('idx: %r', idx)
+ _logger.info('percent: %r', percent)
+ try:
+ emails = sanitize_email(partner['email'])
+ head, tail = emails[:1], emails[1:]
+ email = head[0] if head else False
+
+ proxy_partner.write(cr, uid, [partner['id']],
+ {'email': email}, context=context)
+
+ for email in tail:
+ values = dict(reset_fields, email=email)
+ proxy_partner.copy(cr, uid, partner['id'], values,
+ context=context)
+
+ except Exception:
+ _logger.exception("There is a problem with this partner: %r", partner)
+ raise
+ return True
+
+ def close_cb(self, cr, uid, ids, context=None):
+ return {'type': 'ir.actions.act_window_close'}
+
+ def _generate_query(self, fields, maximum_group=100):
+ group_fields = ', '.join(fields)
+
+ filters = []
+ for field in fields:
+ if field in ['email', 'name']:
+ filters.append((field, 'IS NOT', 'NULL'))
+
+ criteria = ' AND '.join('%s %s %s' % (field, operator, value)
+ for field, operator, value in filters)
+
+ text = [
+ "SELECT min(id), array_agg(id)",
+ "FROM res_partner",
+ ]
+
+ if criteria:
+ text.append('WHERE %s' % criteria)
+
+ text.extend([
+ "GROUP BY %s" % group_fields,
+ "HAVING COUNT(*) >= 2",
+ "ORDER BY min(id)",
+ ])
+
+ if maximum_group:
+ text.extend([
+ "LIMIT %s" % maximum_group,
+ ])
+
+ return ' '.join(text)
+
+ def _compute_selected_groupby(self, this):
+ group_by_str = 'group_by_'
+ group_by_len = len(group_by_str)
+
+ fields = [
+ key[group_by_len:]
+ for key in self._columns.keys()
+ if key.startswith(group_by_str)
+ ]
+
+ groups = [
+ field
+ for field in fields
+ if getattr(this, '%s%s' % (group_by_str, field), False)
+ ]
+
+ if not groups:
+ raise osv.except_osv(_('Error'),
+ _("You have to specify a filter for your selection"))
+
+ return groups
+
+ def next_cb(self, cr, uid, ids, context=None):
+ """
+ Don't compute any thing
+ """
+ context = dict(context or {}, active_test=False)
+ this = self.browse(cr, uid, ids[0], context=context)
+ if this.current_line_id:
+ this.current_line_id.unlink()
+ return self._next_screen(this)
+
+ def _next_screen(self, this):
+ this.refresh()
+ values = {}
+ if this.line_ids:
+ # in this case, we try to find the next record.
+ current_line = this.line_ids[0]
+ current_partner_ids = literal_eval(current_line.aggr_ids)
+ values.update({
+ 'current_line_id': current_line.id,
+ 'partner_ids': [(6, 0, current_partner_ids)],
+ 'state': 'selection',
+ })
+ else:
+ values.update({
+ 'current_line_id': False,
+ 'partner_ids': [],
+ 'state': 'finished',
+ })
+
+ this.write(values)
+
+ return {
+ 'type': 'ir.actions.act_window',
+ 'res_model': this._name,
+ 'res_id': this.id,
+ 'view_mode': 'form',
+ 'target': 'new',
+ }
+
+ def _model_is_installed(self, cr, uid, model, context=None):
+ proxy = self.pool.get('ir.model')
+ domain = [('model', '=', model)]
+ return proxy.search_count(cr, uid, domain, context=context) > 0
+
+ def _partner_use_in(self, cr, uid, aggr_ids, models, context=None):
+ """
+ Check if there is no occurence of this group of partner in the selected
+ model
+ """
+ for model, field in models.iteritems():
+ proxy = self.pool.get(model)
+ domain = [(field, 'in', aggr_ids)]
+ if proxy.search_count(cr, uid, domain, context=context):
+ return True
+ return False
+
+ def compute_models(self, cr, uid, ids, context=None):
+ """
+ Compute the different models needed by the system if you want to exclude
+ some partners.
+ """
+ assert is_integer_list(ids)
+
+ this = self.browse(cr, uid, ids[0], context=context)
+
+ models = {}
+ if this.exclude_contact:
+ models['res.users'] = 'partner_id'
+
+ if self._model_is_installed(cr, uid, 'account.move.line', context=context) and this.exclude_journal_item:
+ models['account.move.line'] = 'partner_id'
+
+ return models
+
+ def _process_query(self, cr, uid, ids, query, context=None):
+ """
+ Execute the select request and write the result in this wizard
+ """
+ proxy = self.pool.get('base.partner.merge.line')
+ this = self.browse(cr, uid, ids[0], context=context)
+ models = self.compute_models(cr, uid, ids, context=context)
+ cr.execute(query)
+
+ counter = 0
+ for min_id, aggr_ids in cr.fetchall():
+ if models and self._partner_use_in(cr, uid, aggr_ids, models, context=context):
+ continue
+ values = {
+ 'wizard_id': this.id,
+ 'min_id': min_id,
+ 'aggr_ids': aggr_ids,
+ }
+
+ proxy.create(cr, uid, values, context=context)
+ counter += 1
+
+ values = {
+ 'state': 'selection',
+ 'number_group': counter,
+ }
+
+ this.write(values)
+
+ _logger.info("counter: %s", counter)
+
+ def start_process_cb(self, cr, uid, ids, context=None):
+ """
+ Start the process.
+ * Compute the selected groups (with duplication)
+ * If the user has selected the 'exclude_XXX' fields, avoid the partners.
+ """
+ assert is_integer_list(ids)
+
+ context = dict(context or {}, active_test=False)
+ this = self.browse(cr, uid, ids[0], context=context)
+ groups = self._compute_selected_groupby(this)
+ query = self._generate_query(groups, this.maximum_group)
+ self._process_query(cr, uid, ids, query, context=context)
+
+ return self._next_screen(this)
+
+ def automatic_process_cb(self, cr, uid, ids, context=None):
+ assert is_integer_list(ids)
+ this = self.browse(cr, uid, ids[0], context=context)
+ this.start_process_cb()
+ this.refresh()
+
+ for line in this.line_ids:
+ partner_ids = literal_eval(line.aggr_ids)
+ self._merge(cr, uid, partner_ids, context=context)
+ line.unlink()
+ cr.commit()
+
+ this.write({'state': 'finished'})
+ return {
+ 'type': 'ir.actions.act_window',
+ 'res_model': this._name,
+ 'res_id': this.id,
+ 'view_mode': 'form',
+ 'target': 'new',
+ }
+
+ def parent_migration_process_cb(self, cr, uid, ids, context=None):
+ assert is_integer_list(ids)
+
+ context = dict(context or {}, active_test=False)
+ this = self.browse(cr, uid, ids[0], context=context)
+
+ query = """
+ SELECT
+ min(p1.id),
+ array_agg(DISTINCT p1.id)
+ FROM
+ res_partner as p1
+ INNER join
+ res_partner as p2
+ ON
+ p1.email = p2.email AND
+ p1.name = p2.name AND
+ (p1.parent_id = p2.id OR p1.id = p2.parent_id)
+ WHERE
+ p2.id IS NOT NULL
+ GROUP BY
+ p1.email,
+ p1.name,
+ CASE WHEN p1.parent_id = p2.id THEN p2.id
+ ELSE p1.id
+ END
+ HAVING COUNT(*) >= 2
+ ORDER BY
+ min(p1.id)
+ """
+
+ self._process_query(cr, uid, ids, query, context=context)
+
+ for line in this.line_ids:
+ partner_ids = literal_eval(line.aggr_ids)
+ self._merge(cr, uid, partner_ids, context=context)
+ line.unlink()
+ cr.commit()
+
+ this.write({'state': 'finished'})
+
+ cr.execute("""
+ UPDATE
+ res_partner
+ SET
+ is_company = NULL,
+ parent_id = NULL
+ WHERE
+ parent_id = id
+ """)
+
+ return {
+ 'type': 'ir.actions.act_window',
+ 'res_model': this._name,
+ 'res_id': this.id,
+ 'view_mode': 'form',
+ 'target': 'new',
+ }
+
+ def update_all_process_cb(self, cr, uid, ids, context=None):
+ assert is_integer_list(ids)
+
+ # WITH RECURSIVE cycle(id, parent_id) AS (
+ # SELECT id, parent_id FROM res_partner
+ # UNION
+ # SELECT cycle.id, res_partner.parent_id
+ # FROM res_partner, cycle
+ # WHERE res_partner.id = cycle.parent_id AND
+ # cycle.id != cycle.parent_id
+ # )
+ # UPDATE res_partner
+ # SET parent_id = NULL
+ # WHERE id in (SELECT id FROM cycle WHERE id = parent_id);
+
+ this = self.browse(cr, uid, ids[0], context=context)
+
+ self.parent_migration_process_cb(cr, uid, ids, context=None)
+
+ list_merge = [
+ {'group_by_vat': True, 'group_by_email': True, 'group_by_name': True},
+ # {'group_by_name': True, 'group_by_is_company': True, 'group_by_parent_id': True},
+ # {'group_by_email': True, 'group_by_is_company': True, 'group_by_parent_id': True},
+ # {'group_by_name': True, 'group_by_vat': True, 'group_by_is_company': True, 'exclude_journal_item': True},
+ # {'group_by_email': True, 'group_by_vat': True, 'group_by_is_company': True, 'exclude_journal_item': True},
+ # {'group_by_email': True, 'group_by_is_company': True, 'exclude_contact': True, 'exclude_journal_item': True},
+ # {'group_by_name': True, 'group_by_is_company': True, 'exclude_contact': True, 'exclude_journal_item': True}
+ ]
+
+ for merge_value in list_merge:
+ id = self.create(cr, uid, merge_value, context=context)
+ self.automatic_process_cb(cr, uid, [id], context=context)
+
+ cr.execute("""
+ UPDATE
+ res_partner
+ SET
+ is_company = NULL
+ WHERE
+ parent_id IS NOT NULL AND
+ is_company IS NOT NULL
+ """)
+
+ # cr.execute("""
+ # UPDATE
+ # res_partner as p1
+ # SET
+ # is_company = NULL,
+ # parent_id = (
+ # SELECT p2.id
+ # FROM res_partner as p2
+ # WHERE p2.email = p1.email AND
+ # p2.parent_id != p2.id
+ # LIMIT 1
+ # )
+ # WHERE
+ # p1.parent_id = p1.id
+ # """)
+
+ return self._next_screen(this)
+
+ def merge_cb(self, cr, uid, ids, context=None):
+ assert is_integer_list(ids)
+
+ context = dict(context or {}, active_test=False)
+ this = self.browse(cr, uid, ids[0], context=context)
+
+ partner_ids = set(map(int, this.partner_ids))
+ if not partner_ids:
+ this.write({'state': 'finished'})
+ return {
+ 'type': 'ir.actions.act_window',
+ 'res_model': this._name,
+ 'res_id': this.id,
+ 'view_mode': 'form',
+ 'target': 'new',
+ }
+
+ self._merge(cr, uid, partner_ids, context=context)
+
+ this.current_line_id.unlink()
+
+ return self._next_screen(this)
+
+ def merge_multi(self, cr, uid, ids, context=None):
+
+ active_model = context.get('active_model')
+ if active_model != 'res.partner':
+ raise osv.except_osv(
+ _('Error'),
+ _('This wizard can only used with the Partners')
+ )
+
+ partner_ids = context.get('active_ids', [])
+
+ MINIMAL_NUMBER = 2
+ if len(partner_ids) < MINIMAL_NUMBER:
+ raise osv.except_osv(
+ _('Error'),
+ _("You can't use this wizard with only one Partner")
+ )
+
+ self._merge(cr, uid, partner_ids, context=context)
+
+ return True
+
+ def auto_set_parent_id(self, cr, uid, ids, context=None):
+ assert is_integer_list(ids)
+
+ # select partner who have one least invoice
+ partner_treated = ['@gmail.com']
+ cr.execute(""" SELECT p.id, p.email
+ FROM res_partner as p
+ LEFT JOIN account_invoice as a
+ ON p.id = a.partner_id AND a.state in ('open','paid')
+ WHERE p.grade_id is NOT NULL
+ GROUP BY p.id
+ ORDER BY COUNT(a.id) DESC
+ """)
+ re_email = re.compile(r".*@")
+ for id, email in cr.fetchall():
+ # check email domain
+ email = re_email.sub("@", email or "")
+ if not email or email in partner_treated:
+ continue
+ partner_treated.append(email)
+
+ # don't update the partners if they are more of one who have invoice
+ cr.execute(""" SELECT *
+ FROM res_partner as p
+ WHERE p.id != %s AND p.email LIKE '%%%s' AND
+ EXISTS (SELECT * FROM account_invoice as a WHERE p.id = a.partner_id AND a.state in ('open','paid'))
+ """ % (id, email))
+
+ if len(cr.fetchall()) > 1:
+ _logger.info("%s MORE OF ONE COMPANY", email)
+ continue
+
+ # to display changed values
+ cr.execute(""" SELECT id,email
+ FROM res_partner
+ WHERE parent_id != %s AND id != %s AND email LIKE '%%%s'
+ """ % (id, id, email))
+ _logger.info("%r", cr.fetchall())
+
+ # upgrade
+ cr.execute(""" UPDATE res_partner
+ SET parent_id = %s
+ WHERE id != %s AND email LIKE '%%%s'
+ """ % (id, id, email))
+ return False
diff --git a/addons/crm/base_partner_merge_view.xml b/addons/crm/base_partner_merge_view.xml
new file mode 100644
index 00000000000..74e7a72d7a8
--- /dev/null
+++ b/addons/crm/base_partner_merge_view.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+ Deduplicate Contacts
+ base.partner.merge.automatic.wizard
+ form
+ form
+ new
+ {'active_test': False}
+
+
+
+
+
+ base.partner.merge.automatic.wizard.form
+ base.partner.merge.automatic.wizard
+
+
+
+
+
+
+ pool.get('base.partner.merge.automatic.wizard').merge_multi(cr, uid, None, context)
+ True
+
+ Automatic Merge
+
+ code
+ ir.actions.server
+
+
+
+
+ res.partner
+ Automatic Merge
+
+
+
+
+
+
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 6d195fec383..61e8c75cea8 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -92,15 +92,6 @@ class crm_lead(base_stage, format_address, osv.osv):
context['empty_list_help_document_name'] = _("leads")
return super(crm_lead, self).get_empty_list_help(cr, uid, help, context=context)
- def onchange_user_id(self, cr, uid, ids, section_id, user_id, context=None):
- """ When changing the user, also set a section_id or restrict section id
- to the ones user_id is member of. """
- if user_id:
- section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
- if len(section_ids) > 0 and section_id not in section_ids:
- section_id = section_ids[0]
- return {'value': {'section_id': section_id}}
-
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}
@@ -372,6 +363,16 @@ class crm_lead(base_stage, format_address, osv.osv):
}
return {'value' : values}
+ def on_change_user(self, cr, uid, ids, user_id, context=None):
+ """ When changing the user, also set a section_id or restrict section id
+ to the ones user_id is member of. """
+ section_id = False
+ if user_id:
+ section_ids = self.pool.get('crm.case.section').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
+ if section_ids:
+ section_id = section_ids[0]
+ return {'value': {'section_id': section_id}}
+
def _check(self, cr, uid, ids=False, context=None):
""" Override of the base.stage method.
Function called by the scheduler to process cases for date actions
@@ -1052,6 +1053,14 @@ class crm_lead(base_stage, format_address, osv.osv):
message = _("%s a call for %s.%s") % (prefix, phonecall.date, suffix)
return self.message_post(cr, uid, ids, body=message, context=context)
+ def log_meeting(self, cr, uid, ids, meeting_subject, meeting_date, duration, context=None):
+ if not duration:
+ duration = _('unknown')
+ else:
+ duration = str(duration)
+ message = _("Meeting scheduled at '%s' Subject: %s Duration: %s hour(s)") % (meeting_date, meeting_subject, duration)
+ return self.message_post(cr, uid, ids, body=message, context=context)
+
def onchange_state(self, cr, uid, ids, state_id, context=None):
if state_id:
country_id=self.pool.get('res.country.state').browse(cr, uid, state_id, context).country_id.id
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 3001e8b1d88..8c22a0a2e1c 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -152,7 +152,7 @@
-->
-
@@ -330,7 +330,7 @@
-
+
@@ -429,7 +429,7 @@
-
+
@@ -548,7 +548,7 @@
-
+
diff --git a/addons/crm/crm_meeting.py b/addons/crm/crm_meeting.py
index 14b69ed0e11..c31907bebe2 100644
--- a/addons/crm/crm_meeting.py
+++ b/addons/crm/crm_meeting.py
@@ -34,6 +34,13 @@ class crm_meeting(osv.Model):
'opportunity_id': fields.many2one ('crm.lead', 'Opportunity', domain="[('type', '=', 'opportunity')]"),
}
+ def create(self, cr, uid, vals, context=None):
+ res = super(crm_meeting, self).create(cr, uid, vals, context=context)
+ obj = self.browse(cr, uid, res, context=context)
+ if obj.opportunity_id:
+ self.pool.get('crm.lead').log_meeting(cr, uid, [obj.opportunity_id.id], obj.name, obj.date, obj.duration, context=context)
+ return res
+
class calendar_attendee(osv.osv):
""" Calendar Attendee """
diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 3efb54f98b8..6c1b31180be 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -186,7 +186,7 @@
-
+
diff --git a/addons/crm/crm_segmentation.py b/addons/crm/crm_segmentation.py
index b11fac31dcf..6e596b5fb9c 100644
--- a/addons/crm/crm_segmentation.py
+++ b/addons/crm/crm_segmentation.py
@@ -108,7 +108,6 @@ added to partners that match the segmentation criterions after computation.'),
self.write(cr, uid, ids, {'state':'running', 'partner_id':0})
return self.process_continue(cr, uid, ids, start=True)
-crm_segmentation()
class crm_segmentation_line(osv.osv):
""" Segmentation line """
@@ -180,7 +179,6 @@ class crm_segmentation_line(osv.osv):
return True
return True
-crm_segmentation_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/i18n/hu.po b/addons/crm/i18n/hu.po
index 193fbdfc6cb..98313efb4f3 100644
--- a/addons/crm/i18n/hu.po
+++ b/addons/crm/i18n/hu.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: 2013-03-17 23:22+0000\n"
+"PO-Revision-Date: 2013-04-13 08:42+0000\n"
"Last-Translator: krnkris \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-19 05:33+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-14 05:12+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: crm
#: view:crm.lead.report:0
msgid "# Leads"
-msgstr "Érdeklődők száma"
+msgstr "# Érdeklődések"
#. module: crm
#: help:sale.config.settings,fetchmail_lead:0
@@ -2688,7 +2688,7 @@ msgstr "Telefonhívásaim"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead3
msgid "Qualification"
-msgstr "Végzettség"
+msgstr "Besorolás"
#. module: crm
#: field:crm.lead2opportunity.partner,name:0
@@ -2993,7 +2993,7 @@ msgstr "ekkor"
#: selection:crm.lead,state:0
#: view:crm.lead.report:0
msgid "New"
-msgstr "új"
+msgstr "Új"
#. module: crm
#: field:crm.lead,function:0
diff --git a/addons/crm/i18n/nl_BE.po b/addons/crm/i18n/nl_BE.po
index 697c7c4f083..a22d1f605a6 100644
--- a/addons/crm/i18n/nl_BE.po
+++ b/addons/crm/i18n/nl_BE.po
@@ -1,20 +1,20 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * crm
-# Els Van Vossel , 2012.
+# Els Van Vossel , 2012, 2013.
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-10-02 07:29+0000\n"
+"PO-Revision-Date: 2013-04-26 23:39+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Els Van Vossel\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:09+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-27 05:44+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
"Language: nl\n"
#. module: crm
@@ -28,6 +28,8 @@ msgid ""
"Allows you to configure your incoming mail server, and create leads from "
"incoming emails."
msgstr ""
+"Hiermee kunt u de inkomende mailserver instellen en leads laten maken van "
+"binnenkomende e-mails."
#. module: crm
#: code:addons/crm/crm_lead.py:881
@@ -76,7 +78,7 @@ msgstr "Opportuniteiten kiezen"
#: model:res.groups,name:crm.group_fund_raising
#: field:sale.config.settings,group_fund_raising:0
msgid "Manage Fund Raising"
-msgstr ""
+msgstr "Fondsenwerving"
#. module: crm
#: view:crm.lead.report:0
@@ -96,7 +98,7 @@ msgstr "Fasenaam"
#: view:crm.lead.report:0
#: view:crm.phonecall.report:0
msgid "Salesperson"
-msgstr ""
+msgstr "Verkoper"
#. module: crm
#: model:ir.model,name:crm.model_crm_lead_report
@@ -113,18 +115,18 @@ msgstr "Dag"
#. module: crm
#: view:crm.lead:0
msgid "Company Name"
-msgstr ""
+msgstr "Bedrijfsnaam"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor6
msgid "Training"
-msgstr ""
+msgstr "Training"
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_lead_categ_action
#: model:ir.ui.menu,name:crm.menu_crm_lead_categ
msgid "Sales Tags"
-msgstr ""
+msgstr "Verkooplabels"
#. module: crm
#: view:crm.lead.report:0
@@ -137,6 +139,7 @@ msgstr "Verw. sluiting"
#: help:crm.phonecall,message_unread:0
msgid "If checked new messages require your attention."
msgstr ""
+"Als dit is ingeschakeld, zijn er nieuwe berichten die uw aandacht vragen."
#. module: crm
#: help:crm.lead.report,creation_day:0
@@ -182,6 +185,8 @@ msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
msgstr ""
+"Bevat de Chatsamenvatting (aantal berichten, ...). Deze samenvatting is in "
+"html-formaat, zodat ze in de kanbanweergave kan worden gebruikt."
#. module: crm
#: code:addons/crm/crm_lead.py:624
@@ -189,7 +194,7 @@ msgstr ""
#: code:addons/crm/crm_phonecall.py:280
#, python-format
msgid "Warning!"
-msgstr ""
+msgstr "Waarschuwing"
#. module: crm
#: view:crm.lead:0
@@ -238,7 +243,7 @@ msgstr ""
#. module: crm
#: model:ir.actions.server,name:crm.action_email_reminder_lead
msgid "Reminder to User"
-msgstr ""
+msgstr "Herinnering voor gebruiker"
#. module: crm
#: field:crm.segmentation,segmentation_line:0
@@ -266,7 +271,7 @@ msgstr "Leadanalyse"
#: code:addons/crm/crm_lead.py:1010
#, python-format
msgid "%s a call for the %s."
-msgstr ""
+msgstr "%s een gesprek voor %s."
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_case_resource_type_act
@@ -328,6 +333,16 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik als u een nieuwe klantensegmentering wilt instellen.\n"
+"
\n"
+" Maak specifiieke categorieën en ken deze toe aan uw\n"
+" contactpersonen voor een betere interactie. Via\n"
+" segmentering kunt u categorieën toekennen aan "
+"contactpersonen\n"
+" volgens de door u ingestelde criteria.\n"
+"
\n"
+" "
#. module: crm
#: field:crm.opportunity2phonecall,contact_name:0
@@ -341,6 +356,7 @@ msgstr "Contactpersoon"
msgid ""
"When escalating to this team override the salesman with the team leader."
msgstr ""
+"Bij escaleren naar dit team, wordt de verkoper vervangen door de teamleider."
#. module: crm
#: model:process.transition,name:crm.process_transition_opportunitymeeting0
@@ -380,12 +396,25 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik om een opportuniteit voor deze klant te maken.\n"
+"
\n"
+" Met opportuniteiten kunt u uw verkooppijplijn en uw "
+"mogelijke verkopen opvolgen,\n"
+" voor een beter zicht op te verwachten inkomsten.\n"
+"
\n"
+" U kunt vergaderingen en telefoongesprekken plannen\n"
+" voor opportuniteiten. U kunt van een opportuniteit een "
+"offerte maken, documenten\n"
+" toevoegen, discussies volgen, en nog veel meer.\n"
+"
\n"
+" "
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead7
#: view:crm.lead:0
msgid "Dead"
-msgstr ""
+msgstr "Dood"
#. module: crm
#: field:crm.case.section,message_unread:0
@@ -393,7 +422,7 @@ msgstr ""
#: field:crm.lead,message_unread:0
#: field:crm.phonecall,message_unread:0
msgid "Unread Messages"
-msgstr ""
+msgstr "Ongelezen berichten"
#. module: crm
#: view:crm.segmentation:0
@@ -407,7 +436,7 @@ msgstr "Segmentering"
#: selection:crm.lead2opportunity.partner.mass,action:0
#: selection:crm.partner.binding,action:0
msgid "Link to an existing customer"
-msgstr ""
+msgstr "Koppelen aan een bestaande relatie"
#. module: crm
#: field:crm.lead,write_date:0
@@ -425,8 +454,8 @@ msgid ""
"This percentage depicts the default/average probability of the Case for this "
"stage to be a success"
msgstr ""
-"Dit percentage drukt de standaard/gemiddelde slaagkans uit voor de zaak in "
-"deze fase."
+"Dit percentage drukt de standaard/gemiddelde slagingskans uit voor de zaak "
+"in deze fase."
#. module: crm
#: view:crm.lead:0
@@ -454,6 +483,7 @@ msgstr ""
#: view:crm.lead:0
msgid "Leads that are assigned to one of the sale teams I manage, or to me"
msgstr ""
+"Leads toegewezen aan een van de verkoopteams onder mijn beheer, of aan mij"
#. module: crm
#: field:crm.lead,partner_address_email:0
@@ -472,6 +502,15 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik als u een nieuw verkoopteam wilt maken.\n"
+"
\n"
+" Met verkoopteams organiseert u meerdere verkopers of "
+"afdelingen in\n"
+" aparte teams. Elk team werkt op zijn eigen\n"
+" opportuniteitenlijst.\n"
+"
\n"
+" "
#. module: crm
#: model:process.transition,note:crm.process_transition_opportunitymeeting0
@@ -485,7 +524,7 @@ msgstr "Gewone of telefonische vergadering over opportuniteit"
#: view:crm.phonecall.report:0
#: field:crm.phonecall.report,state:0
msgid "Status"
-msgstr ""
+msgstr "Status"
#. module: crm
#: view:crm.lead2opportunity.partner:0
@@ -495,7 +534,7 @@ msgstr "Opportuniteit maken"
#. module: crm
#: view:sale.config.settings:0
msgid "Configure"
-msgstr ""
+msgstr "Instellen"
#. module: crm
#: view:crm.lead:0
@@ -555,18 +594,26 @@ msgid ""
" If the call needs to be done then the status is set "
"to 'Not Held'."
msgstr ""
+"De status wordt op 'Uit te voeren' gezet als er een zaak wordt gemaakt. "
+" \n"
+"Als de zaak lopende is, wordt de status op 'Open' gezet. "
+" \n"
+"Als het gesprek is gevoerd, wordt de status op 'Uitgevoerd' gezet. "
+" \n"
+"Als het gesprek nog moet worden uitgevoerd, gaat de status naar 'Niet "
+"uitgevoerd'."
#. module: crm
#: field:crm.case.section,message_summary:0
#: field:crm.lead,message_summary:0
#: field:crm.phonecall,message_summary:0
msgid "Summary"
-msgstr "Samenvatting"
+msgstr "Overzicht"
#. module: crm
#: view:crm.merge.opportunity:0
msgid "Merge"
-msgstr ""
+msgstr "Samenvoegen"
#. module: crm
#: model:email.template,subject:crm.email_template_opportunity_mail
@@ -589,6 +636,8 @@ msgid ""
"Reminder on Lead: [[object.id ]] [[object.partner_id and 'of ' "
"+object.partner_id.name or '']]"
msgstr ""
+"Herinnering voor Lead: [[object.id ]] [[object.partner_id and 'van ' "
+"+object.partner_id.name or '']]"
#. module: crm
#: view:crm.segmentation:0
@@ -608,7 +657,7 @@ msgstr "De code van het verkoopteam moet uniek zijn"
#. module: crm
#: help:crm.lead,email_from:0
msgid "Email address of the contact"
-msgstr ""
+msgstr "E-mailadres van de contactpersoon"
#. module: crm
#: selection:crm.case.stage,state:0
@@ -629,6 +678,13 @@ msgid ""
" \n"
" "
msgstr ""
+"
\n"
+" Klik als u een nieuwe categorie wilt maken.\n"
+"
\n"
+" Maak specifieke telefooncategorieën om beter de gesprekstypen\n"
+" op te volgen in het systeem.\n"
+"
\n"
+" "
#. module: crm
#: help:crm.case.section,reply_to:0
@@ -734,12 +790,12 @@ msgstr "Televisie"
#. module: crm
#: model:ir.actions.act_window,name:crm.action_crm_send_mass_convert
msgid "Convert to opportunities"
-msgstr ""
+msgstr "Omzetten naar opportuniteit"
#. module: crm
#: model:ir.model,name:crm.model_sale_config_settings
msgid "sale.config.settings"
-msgstr ""
+msgstr "sale.config.settings"
#. module: crm
#: view:crm.segmentation:0
@@ -749,7 +805,7 @@ msgstr "Verwerking stoppen"
#. module: crm
#: field:crm.case.section,alias_id:0
msgid "Alias"
-msgstr ""
+msgstr "Alias"
#. module: crm
#: view:crm.phonecall:0
@@ -761,6 +817,8 @@ msgstr "Telefoongesprekken zoeken"
msgid ""
"Leads/Opportunities that are assigned to one of the sale teams I manage"
msgstr ""
+"Leads/Opportuniteiten die zijn toegewezen aan een van de verkoopteams onder "
+"mijn beheer"
#. module: crm
#: field:calendar.attendee,categ_id:0
@@ -781,7 +839,7 @@ msgstr "Van %s : %s"
#. module: crm
#: view:crm.lead2opportunity.partner.mass:0
msgid "Convert to Opportunities"
-msgstr ""
+msgstr "Omzetten naar opportuniteit"
#. module: crm
#: view:crm.lead2opportunity.partner:0
@@ -790,7 +848,7 @@ msgstr ""
#: view:crm.opportunity2phonecall:0
#: view:crm.phonecall2phonecall:0
msgid "or"
-msgstr ""
+msgstr "of"
#. module: crm
#: field:crm.lead.report,create_date:0
@@ -809,6 +867,8 @@ msgid ""
"Link between stages and sales teams. When set, this limitate the current "
"stage to the selected sales teams."
msgstr ""
+"Koppeling tussen fasen en verkoopteams. Deze maken de huidige fase enkel "
+"toegankelijk voor de gekozen verkoopteams."
#. module: crm
#: view:crm.case.stage:0
@@ -847,7 +907,7 @@ msgstr "Relatiecategorie"
#. module: crm
#: field:crm.lead,probability:0
msgid "Success Rate (%)"
-msgstr ""
+msgstr "Slagingskans (%)"
#. module: crm
#: field:crm.segmentation,sales_purchase_active:0
@@ -889,7 +949,7 @@ msgstr "Maart"
#. module: crm
#: view:crm.lead:0
msgid "Send Email"
-msgstr ""
+msgstr "E-mail verzenden"
#. module: crm
#: code:addons/crm/wizard/crm_lead_to_opportunity.py:89
@@ -919,6 +979,8 @@ msgid ""
"Opportunities that are assigned to either me or one of the sale teams I "
"manage"
msgstr ""
+"Opportuniteiten die zijn toegewezen aan een van de verkoopteams onder mijn "
+"beheer of aan mij"
#. module: crm
#: help:crm.case.section,resource_calendar_id:0
@@ -984,6 +1046,9 @@ msgid ""
"Allows you to track your customers/suppliers claims and grievances.\n"
" This installs the module crm_claim."
msgstr ""
+"Hiermee kunt u klachten en problemen van klanten/ aan leveranciers "
+"opvolgen.\n"
+" Hiermee installeert u de module crm_claim."
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead6
@@ -1058,7 +1123,7 @@ msgstr "Fase"
#. module: crm
#: view:crm.phonecall.report:0
msgid "Phone Calls that are assigned to me"
-msgstr ""
+msgstr "Aan mij toegewezen telefoongesprekken"
#. module: crm
#: field:crm.lead,user_login:0
@@ -1086,11 +1151,13 @@ msgid ""
"Allows you to communicate with Customer, process Customer query, and "
"provide better help and support. This installs the module crm_helpdesk."
msgstr ""
+"Hiermee kunt u met de klant communiceren, vragen beantwoorden en betere "
+"ondersteuning verlenen. Hiermee installeert u de module crm_helpdesk."
#. module: crm
#: view:crm.lead:0
msgid "Delete"
-msgstr ""
+msgstr "Verwijderen"
#. module: crm
#: model:mail.message.subtype,description:crm.mt_lead_create
@@ -1100,7 +1167,7 @@ msgstr ""
#. module: crm
#: view:crm.lead:0
msgid "í"
-msgstr ""
+msgstr "í"
#. module: crm
#: selection:crm.lead.report,creation_month:0
@@ -1141,12 +1208,12 @@ msgstr ""
#. module: crm
#: view:crm.lead:0
msgid "oe_kanban_text_red"
-msgstr ""
+msgstr "oe_kanban_text_red"
#. module: crm
#: model:ir.ui.menu,name:crm.menu_crm_payment_mode_act
msgid "Payment Modes"
-msgstr ""
+msgstr "Betalingswijzen"
#. module: crm
#: field:crm.lead.report,opening_date:0
@@ -1193,6 +1260,9 @@ msgid ""
"This field is used to distinguish stages related to Leads from stages "
"related to Opportunities, or to specify stages available for both types."
msgstr ""
+"Dit veld dient om een onderscheid te maken tussen de fasen voor leads en die "
+"voor opportuniteiten, of om fasen in te stellen die voor beide typen van "
+"toepassing zijn."
#. module: crm
#: model:mail.message.subtype,name:crm.mt_lead_create
@@ -1234,7 +1304,7 @@ msgstr "onbekend"
#: field:crm.lead,message_is_follower:0
#: field:crm.phonecall,message_is_follower:0
msgid "Is a Follower"
-msgstr ""
+msgstr "Is een volger"
#. module: crm
#: field:crm.opportunity2phonecall,date:0
@@ -1247,7 +1317,7 @@ msgstr "Datum"
#. module: crm
#: model:crm.case.section,name:crm.crm_case_section_4
msgid "Online Support"
-msgstr ""
+msgstr "Onlineondersteuning"
#. module: crm
#: view:crm.lead.report:0
@@ -1273,6 +1343,10 @@ msgid ""
"set to 'Done'. If the case needs to be reviewed then the Status is set to "
"'Pending'."
msgstr ""
+"De status wordt op 'Voorlopig' gezet als de zaak wordt gemaakt. Als de zaak "
+"lopende is, wordt de status op 'Open' gezet. Als de zaak is behandeld, wordt "
+"de status op 'Gereed' gezet. Als de zaak moet worden bekeken, wordt de "
+"status op 'Wachtend' gezet."
#. module: crm
#: model:crm.case.section,name:crm.crm_case_section_1
@@ -1306,7 +1380,7 @@ msgstr "Segmenteringsomschrijving"
#. module: crm
#: view:crm.lead:0
msgid "Lead Description"
-msgstr ""
+msgstr "Leadomschrijving"
#. module: crm
#: code:addons/crm/crm_lead.py:565
@@ -1317,7 +1391,7 @@ msgstr "Samengevoegde opportuniteiten"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor7
msgid "Consulting"
-msgstr ""
+msgstr "Consulting"
#. module: crm
#: field:crm.case.section,code:0
@@ -1327,7 +1401,7 @@ msgstr "Code"
#. module: crm
#: view:sale.config.settings:0
msgid "Features"
-msgstr ""
+msgstr "Opties"
#. module: crm
#: field:crm.case.section,child_ids:0
@@ -1342,7 +1416,7 @@ msgstr "Telefoongesprekken in status Uit te voeren en Open."
#. module: crm
#: field:crm.lead2opportunity.partner.mass,user_ids:0
msgid "Salesmen"
-msgstr ""
+msgstr "Verkopers"
#. module: crm
#: view:crm.lead:0
@@ -1362,12 +1436,12 @@ msgstr "Annuleren"
#. module: crm
#: view:crm.lead:0
msgid "Opportunities Assigned to Me or My Team(s)"
-msgstr ""
+msgstr "Opportuniteiten voor mij of mijn team(s)"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor4
msgid "Information"
-msgstr ""
+msgstr "Informatie"
#. module: crm
#: view:crm.lead.report:0
@@ -1389,7 +1463,7 @@ msgstr ""
#: field:crm.lead2opportunity.partner.mass,action:0
#: field:crm.partner.binding,action:0
msgid "Related Customer"
-msgstr ""
+msgstr "Gekoppelde klant"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor8
@@ -1406,12 +1480,12 @@ msgstr "Lead/opportuniteit"
#: model:ir.actions.act_window,name:crm.action_merge_opportunities
#: model:ir.actions.act_window,name:crm.merge_opportunity_act
msgid "Merge leads/opportunities"
-msgstr ""
+msgstr "Leads/opportuniteiten samenvoegen"
#. module: crm
#: help:crm.case.stage,sequence:0
msgid "Used to order stages. Lower is better."
-msgstr ""
+msgstr "WOrdt gebruikt om fasen te rangschikken. Lager is beter."
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_phonecall_categ_action
@@ -1426,7 +1500,7 @@ msgstr "Leads/opportuniteiten in status Open."
#. module: crm
#: model:ir.model,name:crm.model_res_users
msgid "Users"
-msgstr ""
+msgstr "Gebruikers"
#. module: crm
#: model:mail.message.subtype,name:crm.mt_lead_stage
@@ -1484,7 +1558,7 @@ msgstr "Naam"
#. module: crm
#: view:crm.lead.report:0
msgid "Leads/Opportunities that are assigned to me"
-msgstr ""
+msgstr "Leads/opportuniteiten die aan mij zijn toegekend"
#. module: crm
#: field:crm.lead.report,date_closed:0
@@ -1502,12 +1576,12 @@ msgstr "Mijn zaken"
#: help:crm.lead,message_ids:0
#: help:crm.phonecall,message_ids:0
msgid "Messages and communication history"
-msgstr ""
+msgstr "Berichten en communicatiehistoriek"
#. module: crm
#: view:crm.lead:0
msgid "Show Countries"
-msgstr ""
+msgstr "Landen tonen"
#. module: crm
#: view:crm.lead:0
@@ -1531,7 +1605,7 @@ msgstr "Prospect omzetten naar relatie"
#. module: crm
#: model:ir.model,name:crm.model_crm_payment_mode
msgid "CRM Payment Mode"
-msgstr ""
+msgstr "CRM betalingswijze"
#. module: crm
#: view:crm.lead.report:0
@@ -1554,7 +1628,7 @@ msgstr "Groeperen op..."
#. module: crm
#: view:crm.merge.opportunity:0
msgid "Merge Leads/Opportunities"
-msgstr ""
+msgstr "Leads/opportuniteiten samenvoegen"
#. module: crm
#: field:crm.case.section,parent_id:0
@@ -1566,7 +1640,7 @@ msgstr "Hoofdteam"
#: selection:crm.lead2opportunity.partner.mass,action:0
#: selection:crm.partner.binding,action:0
msgid "Do not link to a customer"
-msgstr ""
+msgstr "Geen relatie koppelen"
#. module: crm
#: field:crm.lead,date_action:0
@@ -1580,11 +1654,14 @@ msgid ""
"stage. For example, if a stage is related to the status 'Close', when your "
"document reaches this stage, it is automatically closed."
msgstr ""
+"De status van uw document wordt automatisch gewijzigd in de functie van de "
+"gekozen fase. Als een fase gekoppeld is aan de status 'Gesloten', dan wordt "
+"het document automatisch gesloten als het in deze status komt."
#. module: crm
#: view:crm.lead2opportunity.partner.mass:0
msgid "Assign opportunities to"
-msgstr ""
+msgstr "Opportuniteiten toewijzen aan"
#. module: crm
#: model:crm.case.categ,name:crm.categ_phone1
@@ -1600,12 +1677,12 @@ msgstr "Maand van gesprek"
#: code:addons/crm/crm_phonecall.py:290
#, python-format
msgid "Partner has been created."
-msgstr ""
+msgstr "Relatie is gemaakt."
#. module: crm
#: field:sale.config.settings,module_crm_claim:0
msgid "Manage Customer Claims"
-msgstr ""
+msgstr "Klachten van klanten opvolgen"
#. module: crm
#: model:ir.actions.act_window,help:crm.action_report_crm_lead
@@ -1618,7 +1695,7 @@ msgstr ""
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor3
msgid "Services"
-msgstr ""
+msgstr "Diensten"
#. module: crm
#: selection:crm.lead,priority:0
@@ -1657,7 +1734,7 @@ msgstr "Antwoord aan"
#. module: crm
#: view:crm.lead:0
msgid "Display"
-msgstr ""
+msgstr "Weergeven"
#. module: crm
#: view:board.board:0
@@ -1693,12 +1770,12 @@ msgstr "Extra informatie"
#. module: crm
#: view:crm.lead:0
msgid "Fund Raising"
-msgstr ""
+msgstr "Fondsenwerving"
#. module: crm
#: view:crm.lead:0
msgid "Edit..."
-msgstr ""
+msgstr "Bewerken…"
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead5
@@ -1730,13 +1807,15 @@ msgstr "Lead naar opportuniteit / relatie"
#: help:crm.lead,partner_id:0
msgid "Linked partner (optional). Usually created when converting the lead."
msgstr ""
+"Gekoppelde relatie (optioneel). Doorgaans gemaakt bij het omzetten van de "
+"lead."
#. module: crm
#: field:crm.lead,payment_mode:0
#: view:crm.payment.mode:0
#: model:ir.actions.act_window,name:crm.action_crm_payment_mode
msgid "Payment Mode"
-msgstr ""
+msgstr "Betalingswijze"
#. module: crm
#: model:ir.model,name:crm.model_crm_lead2opportunity_partner_mass
@@ -1746,19 +1825,19 @@ msgstr "Vele leads naar opportuniteit / relatie"
#. module: crm
#: view:sale.config.settings:0
msgid "On Mail Server"
-msgstr ""
+msgstr "Op mailserver"
#. module: crm
#: model:ir.actions.act_window,name:crm.open_board_statistical_dash
#: model:ir.ui.menu,name:crm.menu_board_statistics_dash
msgid "CRM"
-msgstr ""
+msgstr "CRM"
#. module: crm
#: model:ir.actions.act_window,name:crm.crm_segmentation_tree-act
#: model:ir.ui.menu,name:crm.menu_crm_segmentation-act
msgid "Contacts Segmentation"
-msgstr ""
+msgstr "Contactpersoonsegmentering"
#. module: crm
#: model:process.node,note:crm.process_node_meeting0
@@ -1773,7 +1852,7 @@ msgstr "Televerkoop"
#. module: crm
#: view:crm.lead:0
msgid "Leads Assigned to Me or My Team(s)"
-msgstr ""
+msgstr "Leads voor mij of mijn team(s)"
#. module: crm
#: model:ir.model,name:crm.model_crm_segmentation_line
@@ -1817,7 +1896,7 @@ msgstr "Lead / klant"
#. module: crm
#: model:crm.case.section,name:crm.crm_case_section_2
msgid "Support Department"
-msgstr ""
+msgstr "Supportafdeling"
#. module: crm
#: view:crm.lead.report:0
@@ -1881,13 +1960,13 @@ msgstr ""
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor5
msgid "Design"
-msgstr ""
+msgstr "Ontwerp"
#. module: crm
#: selection:crm.lead2opportunity.partner,name:0
#: selection:crm.lead2opportunity.partner.mass,name:0
msgid "Merge with existing opportunities"
-msgstr ""
+msgstr "Samenvoegen met bestaande opportuniteiten"
#. module: crm
#: view:crm.phonecall.report:0
@@ -1912,6 +1991,8 @@ msgid ""
"The name of the future partner company that will be created while converting "
"the lead into opportunity"
msgstr ""
+"De naam van de toekomstige relatie die zal worden gemaakt als van de lead "
+"een opportuniteit wordt gemaakt."
#. module: crm
#: field:crm.opportunity2phonecall,note:0
@@ -1945,7 +2026,7 @@ msgstr "Openstaande opportuniteiten"
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead2
msgid "Email Campaign - Services"
-msgstr ""
+msgstr "E-mailcampagne - Diensten"
#. module: crm
#: selection:crm.case.stage,state:0
@@ -2018,7 +2099,7 @@ msgstr ""
#: selection:crm.lead2opportunity.partner.mass,action:0
#: selection:crm.partner.binding,action:0
msgid "Create a new customer"
-msgstr ""
+msgstr "Een nieuwe klant maken"
#. module: crm
#: field:crm.lead.report,deadline_day:0
@@ -2028,7 +2109,7 @@ msgstr "Verw. sluiting"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor2
msgid "Software"
-msgstr ""
+msgstr "Software"
#. module: crm
#: field:crm.case.section,change_responsible:0
@@ -2063,12 +2144,12 @@ msgstr "Plaats"
#. module: crm
#: selection:crm.case.stage,type:0
msgid "Both"
-msgstr ""
+msgstr "Beide"
#. module: crm
#: view:crm.phonecall:0
msgid "Call Done"
-msgstr ""
+msgstr "Gesprek uitgevoerd"
#. module: crm
#: view:crm.phonecall:0
@@ -2079,12 +2160,12 @@ msgstr "Verantwoordelijke"
#. module: crm
#: model:crm.case.section,name:crm.crm_case_section_3
msgid "Direct Marketing"
-msgstr ""
+msgstr "Direct Marketing"
#. module: crm
#: model:crm.case.categ,name:crm.categ_oppor1
msgid "Product"
-msgstr ""
+msgstr "Product"
#. module: crm
#: field:crm.lead.report,creation_year:0
@@ -2094,7 +2175,7 @@ msgstr "Creatiejaar"
#. module: crm
#: view:crm.lead2opportunity.partner.mass:0
msgid "Conversion Options"
-msgstr ""
+msgstr "Conversieopties"
#. module: crm
#: view:crm.case.section:0
@@ -2106,7 +2187,7 @@ msgstr ""
#. module: crm
#: view:crm.lead:0
msgid "Address"
-msgstr ""
+msgstr "Adres"
#. module: crm
#: help:crm.case.section,alias_id:0
@@ -2114,6 +2195,8 @@ msgid ""
"The email address associated with this team. New emails received will "
"automatically create new leads assigned to the team."
msgstr ""
+"Het e-mailadres van het team. Nieuwe e-mails worden automatisch als lead "
+"gemaakt en toegekend aan dit team."
#. module: crm
#: view:crm.lead:0
@@ -2172,7 +2255,7 @@ msgstr "Verder verwerken"
#: selection:crm.lead2opportunity.partner.mass,name:0
#: model:ir.actions.act_window,name:crm.action_crm_lead2opportunity_partner
msgid "Convert to opportunity"
-msgstr ""
+msgstr "Omzetten naar opportuniteit"
#. module: crm
#: field:crm.opportunity2phonecall,user_id:0
@@ -2214,6 +2297,8 @@ 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 ""
+"Deze fase is niet zichtbaar, vb. in statusbalk of kanbanweergave, als er "
+"zich geen records in deze fase bevinden."
#. module: crm
#: field:crm.lead.report,nbr:0
@@ -2229,12 +2314,12 @@ msgstr "Verkoopteam aan wie de zaak toebehoort"
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead6
msgid "Banner Ads"
-msgstr ""
+msgstr "Kopadvertenties"
#. module: crm
#: field:crm.merge.opportunity,opportunity_ids:0
msgid "Leads/Opportunities"
-msgstr ""
+msgstr "Leads/opportuniteiten"
#. module: crm
#: field:crm.lead,fax:0
@@ -2279,17 +2364,17 @@ msgstr "Objectnaam"
#. module: crm
#: view:crm.phonecall:0
msgid "Phone Calls Assigned to Me or My Team(s)"
-msgstr ""
+msgstr "Telefoongesprekken voor mij of mijn team(s)"
#. module: crm
#: view:crm.lead:0
msgid "Reset"
-msgstr ""
+msgstr "Herstellen"
#. module: crm
#: view:sale.config.settings:0
msgid "After-Sale Services"
-msgstr ""
+msgstr "Klantenservice"
#. module: crm
#: field:crm.case.section,message_ids:0
@@ -2344,7 +2429,7 @@ msgstr ""
#. module: crm
#: field:crm.case.stage,state:0
msgid "Related Status"
-msgstr ""
+msgstr "Gekoppelde status"
#. module: crm
#: field:crm.phonecall,name:0
@@ -2365,7 +2450,7 @@ msgstr "Een gesprek plannen/noteren"
#. module: crm
#: view:crm.merge.opportunity:0
msgid "Select Leads/Opportunities"
-msgstr ""
+msgstr "Leads/opportuniteiten kiezen"
#. module: crm
#: selection:crm.phonecall,state:0
@@ -2390,7 +2475,7 @@ msgstr "Bevestigen"
#. module: crm
#: view:crm.lead:0
msgid "Unread messages"
-msgstr ""
+msgstr "Ongelezen berichten"
#. module: crm
#: field:crm.phonecall.report,section_id:0
@@ -2407,7 +2492,7 @@ msgstr "Optionele expressie"
#: field:crm.lead,message_follower_ids:0
#: field:crm.phonecall,message_follower_ids:0
msgid "Followers"
-msgstr ""
+msgstr "Volgers"
#. module: crm
#: model:ir.actions.act_window,help:crm.crm_case_category_act_leads_all
@@ -2430,7 +2515,7 @@ msgstr ""
#. module: crm
#: field:sale.config.settings,fetchmail_lead:0
msgid "Create leads from incoming mails"
-msgstr ""
+msgstr "Leads maken van binnenkomende mails"
#. module: crm
#: view:crm.lead:0
@@ -2481,7 +2566,7 @@ msgstr "Opportuniteiten maken van leads"
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead3
msgid "Email Campaign - Products"
-msgstr ""
+msgstr "E-mailcampagne - Producten"
#. module: crm
#: model:ir.actions.act_window,help:crm.crm_case_categ_phone_incoming0
@@ -2509,7 +2594,7 @@ msgstr "Allereerste contact met een nieuwe prospect"
#. module: crm
#: view:res.partner:0
msgid "Calls"
-msgstr ""
+msgstr "Gesprekken"
#. module: crm
#: field:crm.case.stage,on_change:0
@@ -2519,7 +2604,7 @@ msgstr "Kans automatisch wijzigen"
#. module: crm
#: view:crm.phonecall.report:0
msgid "My Phone Calls"
-msgstr ""
+msgstr "Mijn telefoongesprekken"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead3
@@ -2530,7 +2615,7 @@ msgstr "Kwalificatie"
#: field:crm.lead2opportunity.partner,name:0
#: field:crm.lead2opportunity.partner.mass,name:0
msgid "Conversion Action"
-msgstr ""
+msgstr "Conversieactie"
#. module: crm
#: model:ir.actions.act_window,help:crm.crm_lead_categ_action
@@ -2606,7 +2691,7 @@ msgstr "Verw. sluitingsjaar"
#. module: crm
#: model:ir.actions.client,name:crm.action_client_crm_menu
msgid "Open Sale Menu"
-msgstr ""
+msgstr "Het verkoopmenu openen"
#. module: crm
#: field:crm.lead,date_open:0
@@ -2629,12 +2714,12 @@ msgstr "Een gesprek plannen/noteren"
#. module: crm
#: field:crm.lead,planned_cost:0
msgid "Planned Costs"
-msgstr ""
+msgstr "Geplande kosten"
#. module: crm
#: help:crm.lead,date_deadline:0
msgid "Estimate of the date on which the opportunity will be won."
-msgstr ""
+msgstr "Verwachte datum waarop de opportuniteit kan worden gerealiseerd."
#. module: crm
#: help:crm.lead,email_cc:0
@@ -2698,7 +2783,7 @@ msgstr "Straat 2"
#. module: crm
#: field:sale.config.settings,module_crm_helpdesk:0
msgid "Manage Helpdesk and Support"
-msgstr ""
+msgstr "Helpdesk en ondersteuning"
#. module: crm
#: field:crm.lead.report,delay_open:0
@@ -2785,7 +2870,7 @@ msgstr "Gesprek noteren"
#. module: crm
#: help:sale.config.settings,group_fund_raising:0
msgid "Allows you to trace and manage your activities for fund raising."
-msgstr ""
+msgstr "Hiermee kunt u activiteiten voor fondsenwerving beheren"
#. module: crm
#: field:crm.meeting,phonecall_id:0
@@ -2797,6 +2882,8 @@ msgstr "Telefoongesprek"
#: view:crm.phonecall.report:0
msgid "Phone calls that are assigned to one of the sale teams I manage"
msgstr ""
+"Telefoongesprekken die zijn toegewezen aan een van de verkoopteams onder "
+"mijn beheer"
#. module: crm
#: view:crm.lead:0
@@ -2806,7 +2893,7 @@ msgstr "Creatiedatum"
#. module: crm
#: view:crm.lead:0
msgid "at"
-msgstr ""
+msgstr "bij"
#. module: crm
#: model:crm.case.stage,name:crm.stage_lead1
@@ -2875,7 +2962,7 @@ msgstr ""
#. module: crm
#: view:crm.lead:0
msgid "Internal Notes"
-msgstr ""
+msgstr "Interne notities"
#. module: crm
#: view:crm.lead:0
@@ -2895,7 +2982,7 @@ msgstr "Straat"
#. module: crm
#: field:crm.lead,referred:0
msgid "Referred By"
-msgstr ""
+msgstr "Doorverwezen via"
#. module: crm
#: view:crm.phonecall:0
@@ -2940,6 +3027,7 @@ msgstr "Verloren"
#, python-format
msgid "Closed/Cancelled leads cannot be converted into opportunities."
msgstr ""
+"Gesloten/geannuleerde leads kunnen niet in een opportuniteit worden omgezet"
#. module: crm
#: view:crm.lead:0
@@ -4199,3 +4287,6 @@ msgstr ""
#~ msgid "Recurrent"
#~ msgstr "Recurrent"
+
+#~ msgid "Conditions on Case Fields"
+#~ msgstr "Voorwaardevelden"
diff --git a/addons/crm/report/crm_lead_report.py b/addons/crm/report/crm_lead_report.py
index 323d6e4c3d6..d12facd66a0 100644
--- a/addons/crm/report/crm_lead_report.py
+++ b/addons/crm/report/crm_lead_report.py
@@ -145,6 +145,5 @@ class crm_lead_report(osv.osv):
WHERE c.active = 'true'
)""")
-crm_lead_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/report/crm_lead_report_view.xml b/addons/crm/report/crm_lead_report_view.xml
index 1009e1c376d..759063b3c1d 100644
--- a/addons/crm/report/crm_lead_report_view.xml
+++ b/addons/crm/report/crm_lead_report_view.xml
@@ -82,7 +82,7 @@
groups="base.group_multi_salesteams"/>
-
+
diff --git a/addons/crm/report/crm_phonecall_report.py b/addons/crm/report/crm_phonecall_report.py
index c4b014bb86f..77195097965 100644
--- a/addons/crm/report/crm_phonecall_report.py
+++ b/addons/crm/report/crm_phonecall_report.py
@@ -98,6 +98,5 @@ class crm_phonecall_report(osv.osv):
from
crm_phonecall c
)""")
-crm_phonecall_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/report/crm_phonecall_report_view.xml b/addons/crm/report/crm_phonecall_report_view.xml
index c27d876ddd7..070d574e0cd 100644
--- a/addons/crm/report/crm_phonecall_report_view.xml
+++ b/addons/crm/report/crm_phonecall_report_view.xml
@@ -64,7 +64,7 @@
groups="base.group_multi_salesteams"/>
-
+
diff --git a/addons/crm/res_partner.py b/addons/crm/res_partner.py
index 2fdccda2e06..f25b1303c02 100644
--- a/addons/crm/res_partner.py
+++ b/addons/crm/res_partner.py
@@ -92,7 +92,6 @@ class res_partner(osv.osv):
}, context=context)
opportunity_ids[partner_id] = opportunity_id
return opportunity_ids
-res_partner()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv
index f3c6bdf5c1f..cadb8c24550 100644
--- a/addons/crm/security/ir.model.access.csv
+++ b/addons/crm/security/ir.model.access.csv
@@ -35,3 +35,5 @@ access_crm_lead_partner_manager,crm.lead.partner.manager,model_crm_lead,base.gro
access_crm_phonecall_partner_manager,crm.phonecall.partner.manager,model_crm_phonecall,base.group_partner_manager,1,1,1,1
access_crm_payment_mode_user,crm.payment.mode,model_crm_payment_mode,base.group_sale_salesman,1,0,0,0
access_crm_payment_mode,crm.payment.mode,model_crm_payment_mode,base.group_sale_manager,1,1,1,1
+access_base_partner_merge_line_manager,base_partner_merge_line.manager,model_base_partner_merge_line,base.group_system,1,1,1,1
+access_base_partner_merge_manager,base_partner_merge.manager,model_base_partner_merge_automatic_wizard,base.group_system,1,1,1,1
diff --git a/addons/crm/test/crm_lead_message.yml b/addons/crm/test/crm_lead_message.yml
index 221a4ab634f..0f7d4655398 100644
--- a/addons/crm/test/crm_lead_message.yml
+++ b/addons/crm/test/crm_lead_message.yml
@@ -4,8 +4,7 @@
Mail script will fetch his request from mail server. Then I process that mail after read EML file.
-
!python {model: mail.thread}: |
- from openerp import addons
- request_file = open(addons.get_module_resource('crm','test', 'customer_request.eml'),'rb')
+ request_file = open(openerp.modules.module.get_module_resource('crm','test', 'customer_request.eml'),'rb')
request_message = request_file.read()
self.message_process(cr, uid, 'crm.lead', request_message)
-
diff --git a/addons/crm/validate_email.py b/addons/crm/validate_email.py
new file mode 100644
index 00000000000..38de5743fca
--- /dev/null
+++ b/addons/crm/validate_email.py
@@ -0,0 +1,123 @@
+# RFC 2822 - style email validation for Python
+# (c) 2012 Syrus Akbary
+# Extended from (c) 2011 Noel Bush
+# for support of mx and user check
+# This code is made available to you under the GNU LGPL v3.
+#
+# This module provides a single method, valid_email_address(),
+# which returns True or False to indicate whether a given address
+# is valid according to the 'addr-spec' part of the specification
+# given in RFC 2822. Ideally, we would like to find this
+# in some other library, already thoroughly tested and well-
+# maintained. The standard Python library email.utils
+# contains a parse_addr() function, but it is not sufficient
+# to detect many malformed addresses.
+#
+# This implementation aims to be faithful to the RFC, with the
+# exception of a circular definition (see comments below), and
+# with the omission of the pattern components marked as "obsolete".
+
+import re
+import smtplib
+import socket
+
+try:
+ import DNS
+ ServerError = DNS.ServerError
+except:
+ DNS = None
+ class ServerError(Exception): pass
+# All we are really doing is comparing the input string to one
+# gigantic regular expression. But building that regexp, and
+# ensuring its correctness, is made much easier by assembling it
+# from the "tokens" defined by the RFC. Each of these tokens is
+# tested in the accompanying unit test file.
+#
+# The section of RFC 2822 from which each pattern component is
+# derived is given in an accompanying comment.
+#
+# (To make things simple, every string below is given as 'raw',
+# even when it's not strictly necessary. This way we don't forget
+# when it is necessary.)
+#
+WSP = r'[ \t]' # see 2.2.2. Structured Header Field Bodies
+CRLF = r'(?:\r\n)' # see 2.2.3. Long Header Fields
+NO_WS_CTL = r'\x01-\x08\x0b\x0c\x0f-\x1f\x7f' # see 3.2.1. Primitive Tokens
+QUOTED_PAIR = r'(?:\\.)' # see 3.2.2. Quoted characters
+FWS = r'(?:(?:' + WSP + r'*' + CRLF + r')?' + \
+ WSP + r'+)' # see 3.2.3. Folding white space and comments
+CTEXT = r'[' + NO_WS_CTL + \
+ r'\x21-\x27\x2a-\x5b\x5d-\x7e]' # see 3.2.3
+CCONTENT = r'(?:' + CTEXT + r'|' + \
+ QUOTED_PAIR + r')' # see 3.2.3 (NB: The RFC includes COMMENT here
+ # as well, but that would be circular.)
+COMMENT = r'\((?:' + FWS + r'?' + CCONTENT + \
+ r')*' + FWS + r'?\)' # see 3.2.3
+CFWS = r'(?:' + FWS + r'?' + COMMENT + ')*(?:' + \
+ FWS + '?' + COMMENT + '|' + FWS + ')' # see 3.2.3
+ATEXT = r'[\w!#$%&\'\*\+\-/=\?\^`\{\|\}~]' # see 3.2.4. Atom
+ATOM = CFWS + r'?' + ATEXT + r'+' + CFWS + r'?' # see 3.2.4
+DOT_ATOM_TEXT = ATEXT + r'+(?:\.' + ATEXT + r'+)*' # see 3.2.4
+DOT_ATOM = CFWS + r'?' + DOT_ATOM_TEXT + CFWS + r'?' # see 3.2.4
+QTEXT = r'[' + NO_WS_CTL + \
+ r'\x21\x23-\x5b\x5d-\x7e]' # see 3.2.5. Quoted strings
+QCONTENT = r'(?:' + QTEXT + r'|' + \
+ QUOTED_PAIR + r')' # see 3.2.5
+QUOTED_STRING = CFWS + r'?' + r'"(?:' + FWS + \
+ r'?' + QCONTENT + r')*' + FWS + \
+ r'?' + r'"' + CFWS + r'?'
+LOCAL_PART = r'(?:' + DOT_ATOM + r'|' + \
+ QUOTED_STRING + r')' # see 3.4.1. Addr-spec specification
+DTEXT = r'[' + NO_WS_CTL + r'\x21-\x5a\x5e-\x7e]' # see 3.4.1
+DCONTENT = r'(?:' + DTEXT + r'|' + \
+ QUOTED_PAIR + r')' # see 3.4.1
+DOMAIN_LITERAL = CFWS + r'?' + r'\[' + \
+ r'(?:' + FWS + r'?' + DCONTENT + \
+ r')*' + FWS + r'?\]' + CFWS + r'?' # see 3.4.1
+DOMAIN = r'(?:' + DOT_ATOM + r'|' + \
+ DOMAIN_LITERAL + r')' # see 3.4.1
+ADDR_SPEC = LOCAL_PART + r'@' + DOMAIN # see 3.4.1
+
+# A valid address will match exactly the 3.4.1 addr-spec.
+VALID_ADDRESS_REGEXP = '^' + ADDR_SPEC + '$'
+
+def validate_email(email, check_mx=False,verify=False):
+
+ """Indicate whether the given string is a valid email address
+ according to the 'addr-spec' portion of RFC 2822 (see section
+ 3.4.1). Parts of the spec that are marked obsolete are *not*
+ included in this test, and certain arcane constructions that
+ depend on circular definitions in the spec may not pass, but in
+ general this should correctly identify any email address likely
+ to be in use as of 2011."""
+ try:
+ assert re.match(VALID_ADDRESS_REGEXP, email) is not None
+ check_mx |= verify
+ if check_mx:
+ if not DNS: raise Exception('For check the mx records or check if the email exists you must have installed pyDNS python package')
+ DNS.DiscoverNameServers()
+ hostname = email[email.find('@')+1:]
+ mx_hosts = DNS.mxlookup(hostname)
+ for mx in mx_hosts:
+ try:
+ smtp = smtplib.SMTP()
+ smtp.connect(mx[1])
+ if not verify: return True
+ status, _ = smtp.helo()
+ if status != 250: continue
+ smtp.mail('')
+ status, _ = smtp.rcpt(email)
+ if status != 250: return False
+ break
+ except smtplib.SMTPServerDisconnected: #Server not permits verify user
+ break
+ except smtplib.SMTPConnectError:
+ continue
+ except (AssertionError, ServerError):
+ return False
+ return True
+
+# import sys
+
+# sys.modules[__name__],sys.modules['validate_email_module'] = validate_email,sys.modules[__name__]
+# from validate_email_module import *
diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall.py b/addons/crm/wizard/crm_opportunity_to_phonecall.py
index ee7ed1fc31f..bb1ac2fdce6 100644
--- a/addons/crm/wizard/crm_opportunity_to_phonecall.py
+++ b/addons/crm/wizard/crm_opportunity_to_phonecall.py
@@ -73,6 +73,5 @@ class crm_opportunity2phonecall(osv.osv_memory):
action=data.action, context=context)
return {'type': 'ir.actions.act_window_close'}
-crm_opportunity2phonecall()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/crm_phonecall_to_meeting.py b/addons/crm/wizard/crm_phonecall_to_meeting.py
index 4e21e01b834..105ab113a71 100644
--- a/addons/crm/wizard/crm_phonecall_to_meeting.py
+++ b/addons/crm/wizard/crm_phonecall_to_meeting.py
@@ -59,6 +59,5 @@ class crm_phonecall2meeting(osv.osv_memory):
}
return res
-crm_phonecall2meeting()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/crm_phonecall_to_phonecall.py b/addons/crm/wizard/crm_phonecall_to_phonecall.py
index d0bcd12dbb7..7e1da41a29f 100644
--- a/addons/crm/wizard/crm_phonecall_to_phonecall.py
+++ b/addons/crm/wizard/crm_phonecall_to_phonecall.py
@@ -96,6 +96,5 @@ class crm_phonecall2phonecall(osv.osv_memory):
res.update({'partner_id': phonecall.partner_id and phonecall.partner_id.id or False})
return res
-crm_phonecall2phonecall()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml
index 78e467a7ba8..e295bfdd250 100644
--- a/addons/crm_claim/crm_claim_view.xml
+++ b/addons/crm_claim/crm_claim_view.xml
@@ -201,7 +201,7 @@
-
+
diff --git a/addons/crm_claim/report/crm_claim_report.py b/addons/crm_claim/report/crm_claim_report.py
index ad56fa5e34e..2ed87505d9c 100644
--- a/addons/crm_claim/report/crm_claim_report.py
+++ b/addons/crm_claim/report/crm_claim_report.py
@@ -114,6 +114,5 @@ class crm_claim_report(osv.osv):
c.priority,c.type_action,c.date_deadline,c.date_closed,c.id
)""")
-crm_claim_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_claim/report/crm_claim_report_view.xml b/addons/crm_claim/report/crm_claim_report_view.xml
index febf9cafd73..530eb6061a3 100644
--- a/addons/crm_claim/report/crm_claim_report_view.xml
+++ b/addons/crm_claim/report/crm_claim_report_view.xml
@@ -65,7 +65,7 @@
-
+
diff --git a/addons/crm_claim/test/process/claim.yml b/addons/crm_claim/test/process/claim.yml
index bacb073b4b9..a843372956e 100644
--- a/addons/crm_claim/test/process/claim.yml
+++ b/addons/crm_claim/test/process/claim.yml
@@ -4,8 +4,7 @@
Mail script will be fetched him request from mail server. so I process that mail after read EML file
-
!python {model: mail.thread}: |
- from openerp import addons
- request_file = open(addons.get_module_resource('crm_claim','test', 'customer_claim.eml'),'rb')
+ request_file = open(openerp.modules.module.get_module_resource('crm_claim','test', 'customer_claim.eml'),'rb')
request_message = request_file.read()
self.message_process(cr, uid, 'crm.claim', request_message)
-
diff --git a/addons/crm_helpdesk/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml
index 6769b42a7f8..6e3521be6f2 100644
--- a/addons/crm_helpdesk/crm_helpdesk_view.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_view.xml
@@ -152,7 +152,7 @@
-
+
diff --git a/addons/crm_helpdesk/report/crm_helpdesk_report.py b/addons/crm_helpdesk/report/crm_helpdesk_report.py
index 8d535fa07a0..8b54e30ddd3 100644
--- a/addons/crm_helpdesk/report/crm_helpdesk_report.py
+++ b/addons/crm_helpdesk/report/crm_helpdesk_report.py
@@ -108,6 +108,5 @@ class crm_helpdesk_report(osv.osv):
c.categ_id,c.channel_id,c.planned_cost,c.id
)""")
-crm_helpdesk_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
index 795ae210d8d..6ce2c60093f 100644
--- a/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
+++ b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
@@ -62,6 +62,7 @@
+
diff --git a/addons/crm_helpdesk/test/process/help-desk.yml b/addons/crm_helpdesk/test/process/help-desk.yml
index e2be4a64ca3..95536b1c8dd 100644
--- a/addons/crm_helpdesk/test/process/help-desk.yml
+++ b/addons/crm_helpdesk/test/process/help-desk.yml
@@ -4,8 +4,7 @@
Mail script will be fetched him request from mail server. so I process that mail after read EML file
-
!python {model: mail.thread}: |
- from openerp import addons
- request_file = open(addons.get_module_resource('crm_helpdesk','test', 'customer_question.eml'),'rb')
+ request_file = open(openerp.modules.module.get_module_resource('crm_helpdesk','test', 'customer_question.eml'),'rb')
request_message = request_file.read()
self.message_process(cr, uid, 'crm.helpdesk', request_message)
-
diff --git a/addons/crm_partner_assign/report/crm_lead_report.py b/addons/crm_partner_assign/report/crm_lead_report.py
index 2c208131b3a..676a8536b74 100644
--- a/addons/crm_partner_assign/report/crm_lead_report.py
+++ b/addons/crm_partner_assign/report/crm_lead_report.py
@@ -118,6 +118,5 @@ class crm_lead_report_assign(osv.osv):
left join res_partner p on (c.partner_assigned_id=p.id)
)""")
-crm_lead_report_assign()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_partner_assign/report/crm_partner_report.py b/addons/crm_partner_assign/report/crm_partner_report.py
index 4611fdd06e4..6f07a8ce03a 100644
--- a/addons/crm_partner_assign/report/crm_partner_report.py
+++ b/addons/crm_partner_assign/report/crm_partner_report.py
@@ -67,6 +67,5 @@ class crm_partner_report_assign(osv.osv):
on (i.partner_id=p.id and i.type in ('out_invoice','out_refund') and i.state in ('open','paid'))
)""")
-crm_partner_report_assign()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
index 81cc09d9717..91d462de015 100644
--- a/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
+++ b/addons/crm_partner_assign/wizard/crm_forward_to_partner.py
@@ -86,7 +86,7 @@ class crm_lead_forward_to_partner(osv.TransientModel):
if context is None:
context = {}
if model and model == 'crm.lead' and res_id:
- lead = self.pool.get(model).browse(cr, uid, res_id, context=context)
+ lead = self.pool[model].browse(cr, uid, res_id, context=context)
context['history_mode'] = history_mode
body = self.get_record_data(cr, uid, 'crm.lead', res_id, context=context)['body']
return {'value': {'body': body}}
@@ -110,7 +110,7 @@ class crm_lead_forward_to_partner(osv.TransientModel):
if wizard.model not in ('crm.lead'):
return res
- lead = self.pool.get(wizard.model)
+ lead = self.pool[wizard.model]
lead_ids = wizard.res_id and [wizard.res_id] or []
if wizard.composition_mode == 'mass_mail':
diff --git a/addons/crm_profiling/crm_profiling.py b/addons/crm_profiling/crm_profiling.py
index 8ea08601c9a..7ae9d146bdd 100644
--- a/addons/crm_profiling/crm_profiling.py
+++ b/addons/crm_profiling/crm_profiling.py
@@ -150,7 +150,6 @@ class question(osv.osv):
'answers_ids': fields.one2many("crm_profiling.answer","question_id","Avalaible Answers",),
}
-question()
class questionnaire(osv.osv):
@@ -166,7 +165,6 @@ class questionnaire(osv.osv):
'questionnaire', 'question', "Questions"),
}
-questionnaire()
class answer(osv.osv):
@@ -176,7 +174,6 @@ class answer(osv.osv):
"name": fields.char("Answer",size=128, required=True),
"question_id": fields.many2one('crm_profiling.question',"Question"),
}
-answer()
class partner(osv.osv):
@@ -214,7 +211,6 @@ class partner(osv.osv):
vals['category_id']=[[6, 0, _recompute_categ(self, cr, uid, ids[0], vals['answers_ids'][0][2])]]
return super(partner, self).write(cr, uid, ids, vals, context=context)
-partner()
class crm_segmentation(osv.osv):
@@ -289,7 +285,6 @@ class crm_segmentation(osv.osv):
self.write(cr, uid, [id], {'state':'not running', 'partner_id':0})
return True
-crm_segmentation()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_profiling/wizard/open_questionnaire.py b/addons/crm_profiling/wizard/open_questionnaire.py
index cb7ad220e3f..979e9809d09 100644
--- a/addons/crm_profiling/wizard/open_questionnaire.py
+++ b/addons/crm_profiling/wizard/open_questionnaire.py
@@ -31,7 +31,6 @@ class open_questionnaire_line(osv.osv_memory):
'wizard_id': fields.many2one('open.questionnaire', 'Questionnaire'),
}
-open_questionnaire_line()
class open_questionnaire(osv.osv_memory):
_name = 'open.questionnaire'
@@ -61,7 +60,7 @@ class open_questionnaire(osv.osv_memory):
for d in data.question_ans_ids:
if d.answer_id:
answers.append(d.answer_id.id)
- self.pool.get(model)._questionnaire_compute(cr, uid, answers, context=context)
+ self.pool[model]._questionnaire_compute(cr, uid, answers, context=context)
return {'type': 'ir.actions.act_window_close'}
@@ -84,6 +83,5 @@ class open_questionnaire(osv.osv_memory):
'context': context
}
-open_questionnaire()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/decimal_precision/decimal_precision.py b/addons/decimal_precision/decimal_precision.py
index ab0979291bd..b237f053ebb 100644
--- a/addons/decimal_precision/decimal_precision.py
+++ b/addons/decimal_precision/decimal_precision.py
@@ -63,7 +63,6 @@ class decimal_precision(osv.osv):
col.digits_change(cr)
return res
-decimal_precision()
def get_precision(application):
def change_digit(cr):
diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py
index 15a17b36775..76750212edd 100644
--- a/addons/delivery/delivery.py
+++ b/addons/delivery/delivery.py
@@ -166,7 +166,6 @@ class delivery_carrier(osv.osv):
self.create_grid_lines(cr, uid, [res_id], vals, context=context)
return res_id
-delivery_carrier()
class delivery_grid(osv.osv):
_name = "delivery.grid"
@@ -223,7 +222,6 @@ class delivery_grid(osv.osv):
return price
-delivery_grid()
class delivery_grid_line(osv.osv):
_name = "delivery.grid.line"
@@ -249,6 +247,5 @@ class delivery_grid_line(osv.osv):
}
_order = 'list_price'
-delivery_grid_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/delivery/partner.py b/addons/delivery/partner.py
index e4b0ba204ac..477315dfc9b 100644
--- a/addons/delivery/partner.py
+++ b/addons/delivery/partner.py
@@ -32,7 +32,6 @@ class res_partner(osv.osv):
view_load=True,
help="This delivery method will be used when invoicing from picking."),
}
-res_partner()
diff --git a/addons/delivery/sale.py b/addons/delivery/sale.py
index 98229f13c36..86a518ebca9 100644
--- a/addons/delivery/sale.py
+++ b/addons/delivery/sale.py
@@ -76,7 +76,6 @@ class sale_order(osv.osv):
return self.write(cr, uid, ids, {'carrier_id': False}, context=context)
#return {'type': 'ir.actions.act_window_close'} action reload?
-sale_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py
index 95b17a8ba68..95e87eb45ab 100644
--- a/addons/delivery/stock.py
+++ b/addons/delivery/stock.py
@@ -140,7 +140,6 @@ class stock_picking(osv.osv):
'weight_uom_id': lambda self,cr,uid,c: self._get_default_uom(cr,uid,c)
}
-stock_picking()
class stock_move(osv.osv):
_inherit = 'stock.move'
@@ -184,7 +183,6 @@ class stock_move(osv.osv):
_defaults = {
'weight_uom_id': lambda self,cr,uid,c: self._get_default_uom(cr,uid,c)
}
-stock_move()
# Redefinition of the new fields in order to update the model stock.picking.out in the orm
# FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
@@ -215,7 +213,6 @@ class stock_picking_out(osv.osv):
'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32),
'number_of_packages': fields.integer('Number of Packages'),
}
-stock_picking_out()
class stock_picking_in(osv.osv):
_inherit = 'stock.picking.in'
@@ -238,7 +235,6 @@ class stock_picking_in(osv.osv):
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
}),
}
-stock_picking_in()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document/document.py b/addons/document/document.py
index 9b1fdc1d66b..54f12e204fe 100644
--- a/addons/document/document.py
+++ b/addons/document/document.py
@@ -137,7 +137,7 @@ class document_file(osv.osv):
It is a hack that will try to discover if the mentioned record is
clearly associated with a partner record.
"""
- obj_model = self.pool.get(res_model)
+ obj_model = self.pool[res_model]
if obj_model._name == 'res.partner':
return res_id
elif 'partner_id' in obj_model._columns and obj_model._columns['partner_id']._obj == 'res.partner':
@@ -422,7 +422,6 @@ class document_directory_content(osv.osv):
tname = ''
if content.include_name:
record_name = node.displayname or ''
- # obj = node.context._dirobj.pool.get(model)
if record_name:
tname = (content.prefix or '') + record_name + (content.suffix or '') + (content.extension or '')
else:
@@ -1296,9 +1295,9 @@ class node_res_dir(node_class):
Note that many objects use NULL for a name, so we should
better call the name_search(),name_get() set of methods
"""
- obj = self.context._dirobj.pool.get(self.res_model)
- if not obj:
+ if self.res_model not in self.context._dirobj.pool:
return []
+ obj = self.context._dirobj.pool[self.res_model]
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
@@ -1333,7 +1332,7 @@ class node_res_dir(node_class):
if self.ressource_tree:
object2 = False
if self.resm_id:
- object2 = dirobj.pool.get(self.res_model).browse(cr, uid, self.resm_id) or False
+ object2 = dirobj.pool[self.res_model].browse(cr, uid, self.resm_id) or False
if obj._parent_name in obj.fields_get(cr, uid):
where.append((obj._parent_name,'=',object2 and object2.id or False))
@@ -1504,7 +1503,7 @@ class node_res_obj(node_class):
ctx = self.context.context.copy()
ctx.update(self.dctx)
directory = dirobj.browse(cr, uid, self.dir_id)
- obj = dirobj.pool.get(self.res_model)
+ obj = dirobj.pool[self.res_model]
where = []
res = []
if name:
@@ -1590,7 +1589,7 @@ class node_res_obj(node_class):
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
- res_obj = dirobj.pool.get(self.res_model)
+ res_obj = dirobj.pool[self.res_model]
object2 = res_obj.browse(cr, uid, self.res_id) or False
diff --git a/addons/document/wizard/document_configuration.py b/addons/document/wizard/document_configuration.py
index aec7f9b75a4..c846f288112 100644
--- a/addons/document/wizard/document_configuration.py
+++ b/addons/document/wizard/document_configuration.py
@@ -109,6 +109,5 @@ class document_configuration(osv.osv_memory):
'domain': '[]',
'ressource_tree': 1
})
-document_configuration()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_ftp/wizard/ftp_browse.py b/addons/document_ftp/wizard/ftp_browse.py
index ceb7d1a60e5..ee8f897ca20 100644
--- a/addons/document_ftp/wizard/ftp_browse.py
+++ b/addons/document_ftp/wizard/ftp_browse.py
@@ -60,6 +60,5 @@ class document_ftp_browse(osv.osv_memory):
'target': 'new'
}
-document_ftp_browse()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_ftp/wizard/ftp_configuration.py b/addons/document_ftp/wizard/ftp_configuration.py
index 87aaa2331b4..1dee9495a95 100644
--- a/addons/document_ftp/wizard/ftp_configuration.py
+++ b/addons/document_ftp/wizard/ftp_configuration.py
@@ -47,6 +47,5 @@ class document_ftp_configuration(osv.osv_memory):
self.pool.get('ir.actions.act_url').write(cr, uid, [aid],
{'url': 'ftp://'+(conf.host or 'localhost:8021')+'/' + cr.dbname+'/'})
-document_ftp_configuration()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/document_webdav/nodes.py b/addons/document_webdav/nodes.py
index 5e819e01754..9a35f3cfe1b 100644
--- a/addons/document_webdav/nodes.py
+++ b/addons/document_webdav/nodes.py
@@ -67,7 +67,7 @@ class node_acl_mixin(object):
"""
ret = par_class.get_dav_props(self, cr)
if prop_model:
- propobj = self.context._dirobj.pool.get(prop_model)
+ propobj = self.context._dirobj.pool[prop_model]
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
@@ -105,7 +105,7 @@ class node_acl_mixin(object):
if ret is not None:
return ret
if prop_model:
- propobj = self.context._dirobj.pool.get(prop_model)
+ propobj = self.context._dirobj.pool[prop_model]
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
@@ -151,7 +151,7 @@ class node_acl_mixin(object):
assert prop_model
assert res_id
assert isinstance(lock_data, dict), '%r' % lock_data
- propobj = self.context._dirobj.pool.get(prop_model)
+ propobj = self.context._dirobj.pool[prop_model]
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
diff --git a/addons/document_webdav/test/webdav_test1.yml b/addons/document_webdav/test/webdav_test1.yml
index 82236f63846..ae91d7cd4a8 100644
--- a/addons/document_webdav/test/webdav_test1.yml
+++ b/addons/document_webdav/test/webdav_test1.yml
@@ -47,10 +47,9 @@
-
!python {model: ir.attachment}: |
from document_webdav import test_davclient as te
- import addons
dc = te.DAVClient()
dc.get_creds(self, cr, uid)
- tdp = addons.get_module_resource('document_webdav', 'test_davclient.py')
+ tdp = openerp.modules.module.get_module_resource('document_webdav', 'test_davclient.py')
res = dc.gd_put(path=cr.dbname+'/Documents/test_davclient.py', srcpath=tdp)
-
I will try to get the file from the root
@@ -60,5 +59,5 @@
import addons
dc = te.DAVClient()
dc.get_creds(self, cr, uid)
- tdp = addons.get_module_resource('document_webdav', 'test_davclient.py')
+ tdp = openerp.modules.module.get_module_resource('document_webdav', 'test_davclient.py')
res = dc.gd_get(path=cr.dbname+'/Documents/test_davclient.py', crange=(4,508), compare=tdp)
diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py
index 1804b9bfdb2..f67de272e29 100644
--- a/addons/document_webdav/webdav_server.py
+++ b/addons/document_webdav/webdav_server.py
@@ -608,7 +608,7 @@ try:
if base_path and base_path == '/':
dir_path = config.get_misc('static-http', 'dir_path', False)
else:
- dir_path = openerp.addons.get_module_resource('document_webdav','public_html')
+ dir_path = openerp.modules.module.get_module_resource('document_webdav','public_html')
# an _ugly_ hack: we put that dir back in tools.config.misc, so that
# the StaticHttpHandler can find its dir_path.
config.misc.setdefault('static-http',{})['dir_path'] = dir_path
diff --git a/addons/edi/i18n/lt.po b/addons/edi/i18n/lt.po
new file mode 100644
index 00000000000..4c00a1dc6d6
--- /dev/null
+++ b/addons/edi/i18n/lt.po
@@ -0,0 +1,87 @@
+# 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:19+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: edi
+#. openerp-web
+#: code:addons/edi/static/src/js/edi.js:67
+#, python-format
+msgid "Reason:"
+msgstr ""
+
+#. module: edi
+#. openerp-web
+#: code:addons/edi/static/src/js/edi.js:60
+#, python-format
+msgid "The document has been successfully imported!"
+msgstr ""
+
+#. module: edi
+#. openerp-web
+#: code:addons/edi/static/src/js/edi.js:65
+#, python-format
+msgid "Sorry, the document could not be imported."
+msgstr ""
+
+#. module: edi
+#: model:ir.model,name:edi.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: edi
+#: model:ir.model,name:edi.model_res_currency
+msgid "Currency"
+msgstr ""
+
+#. module: edi
+#. openerp-web
+#: code:addons/edi/static/src/js/edi.js:71
+#, python-format
+msgid "Document Import Notification"
+msgstr ""
+
+#. module: edi
+#: code:addons/edi/models/edi.py:130
+#, python-format
+msgid "Missing application."
+msgstr ""
+
+#. module: edi
+#: code:addons/edi/models/edi.py:131
+#, python-format
+msgid ""
+"The document you are trying to import requires the OpenERP `%s` application. "
+"You can install it by connecting as the administrator and opening the "
+"configuration assistant."
+msgstr ""
+
+#. module: edi
+#: code:addons/edi/models/edi.py:47
+#, python-format
+msgid "'%s' is an invalid external ID"
+msgstr ""
+
+#. module: edi
+#: model:ir.model,name:edi.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: edi
+#: model:ir.model,name:edi.model_edi_edi
+msgid "EDI Subsystem"
+msgstr ""
diff --git a/addons/edi/i18n/nl_BE.po b/addons/edi/i18n/nl_BE.po
index f5fc80a6fcc..aa96f26d13b 100644
--- a/addons/edi/i18n/nl_BE.po
+++ b/addons/edi/i18n/nl_BE.po
@@ -8,35 +8,35 @@ 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: 2012-10-02 08:10+0000\n"
+"PO-Revision-Date: 2013-04-15 16:04+0000\n"
"Last-Translator: Els Van Vossel (Agaplan) \n"
"Language-Team: Dutch (Belgium) \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:50+0000\n"
-"X-Generator: Launchpad (build 16532)\n"
+"X-Launchpad-Export-Date: 2013-04-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
#. module: edi
#. openerp-web
#: code:addons/edi/static/src/js/edi.js:67
#, python-format
msgid "Reason:"
-msgstr ""
+msgstr "Reden:"
#. module: edi
#. openerp-web
#: code:addons/edi/static/src/js/edi.js:60
#, python-format
msgid "The document has been successfully imported!"
-msgstr ""
+msgstr "Het document is met succes geïmporteerd"
#. module: edi
#. openerp-web
#: code:addons/edi/static/src/js/edi.js:65
#, python-format
msgid "Sorry, the document could not be imported."
-msgstr ""
+msgstr "Sorry, het document kan niet worden geïmporteerd"
#. module: edi
#: model:ir.model,name:edi.model_res_company
@@ -53,13 +53,13 @@ msgstr "Munt"
#: code:addons/edi/static/src/js/edi.js:71
#, python-format
msgid "Document Import Notification"
-msgstr ""
+msgstr "Documentimportbericht"
#. module: edi
#: code:addons/edi/models/edi.py:130
#, python-format
msgid "Missing application."
-msgstr ""
+msgstr "Ontbrekend programma"
#. module: edi
#: code:addons/edi/models/edi.py:131
@@ -87,7 +87,7 @@ msgstr "Relatie"
#. module: edi
#: model:ir.model,name:edi.model_edi_edi
msgid "EDI Subsystem"
-msgstr ""
+msgstr "EDI-subsysteem"
#~ msgid "The currency code must be unique per company!"
#~ msgstr "De munt moet uniek zijn per firma."
diff --git a/addons/edi/models/edi.py b/addons/edi/models/edi.py
index 239b543e194..bfd59dae15a 100644
--- a/addons/edi/models/edi.py
+++ b/addons/edi/models/edi.py
@@ -106,8 +106,8 @@ class edi(osv.AbstractModel):
"""
edi_list = []
for record in records:
- record_model_obj = self.pool.get(record._name)
- edi_list += record_model_obj.edi_export(cr, uid, [record], context=context)
+ record_model = record._model
+ edi_list += record_model.edi_export(cr, uid, [record], context=context)
return self.serialize(edi_list)
def load_edi(self, cr, uid, edi_documents, context=None):
@@ -131,9 +131,9 @@ class edi(osv.AbstractModel):
"You can install it by connecting as the administrator and opening the configuration assistant.")%(module,))
model = edi_document.get('__import_model') or edi_document.get('__model')
assert model, 'a `__model` or `__import_model` attribute is required in each EDI document.'
- model_obj = self.pool.get(model)
- assert model_obj, 'model `%s` cannot be found, despite module `%s` being available - '\
+ assert model in self.pool, 'model `%s` cannot be found, despite module `%s` being available - '\
'this EDI document seems invalid or unsupported.' % (model,module)
+ model_obj = self.pool[model]
record_id = model_obj.edi_import(cr, uid, edi_document, context=context)
record_action = model_obj._edi_record_display_action(cr, uid, record_id, context=context)
res.append((model, record_id, record_action))
@@ -400,7 +400,7 @@ class EDIMixin(object):
return results
def _edi_get_object_by_name(self, cr, uid, name, model_name, context=None):
- model = self.pool.get(model_name)
+ model = self.pool[model_name]
search_results = model.name_search(cr, uid, name, operator='=', context=context)
if len(search_results) == 1:
return model.browse(cr, uid, search_results[0][0], context=context)
@@ -483,7 +483,7 @@ class EDIMixin(object):
('name','=',ext_id),
('module','in',modules)])
if data_ids:
- model = self.pool.get(model)
+ model = self.pool[model]
data = ir_model_data.browse(cr, uid, data_ids[0], context=context)
if model.exists(cr, uid, [data.res_id]):
return model.browse(cr, uid, data.res_id, context=context)
@@ -519,7 +519,7 @@ class EDIMixin(object):
_logger.debug("%s: Importing EDI relationship [%r,%r] - name not found, creating it.",
self._name, external_id, value)
# also need_new_ext_id here, but already been set above
- model = self.pool.get(model)
+ model = self.pool[model]
res_id, _ = model.name_create(cr, uid, value, context=context)
target = model.browse(cr, uid, res_id, context=context)
else:
@@ -592,7 +592,7 @@ class EDIMixin(object):
# process o2m values, connecting them to their parent on-the-fly
for o2m_field, o2m_value in o2m_todo.iteritems():
field = self._all_columns[o2m_field].column
- dest_model = self.pool.get(field._obj)
+ dest_model = self.pool[field._obj]
for o2m_line in o2m_value:
# link to parent record: expects an (ext_id, name) pair
o2m_line[field._fields_id] = (ext_id_members['full'], record_display[1])
diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py
index ed76b69901c..00285ebcd91 100644
--- a/addons/email_template/email_template.py
+++ b/addons/email_template/email_template.py
@@ -89,7 +89,7 @@ class email_template(osv.osv):
template = tools.ustr(template)
record = None
if res_id:
- record = self.pool.get(model).browse(cr, uid, res_id, context=context)
+ record = self.pool[model].browse(cr, uid, res_id, context=context)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
variables = {
'object': record,
@@ -297,8 +297,7 @@ class email_template(osv.osv):
'copyvalue': self.build_expression(field_value.name, False, null_value or False),
'null_value': null_value or False
})
- return {'value':result}
-
+ return {'value': result}
def generate_email(self, cr, uid, template_id, res_id, context=None):
"""Generates an email from the template for given (model, res_id) pair.
@@ -350,11 +349,13 @@ class email_template(osv.osv):
report_name += ext
attachments.append((report_name, result))
+ attachment_ids = []
# Add template attachments
for attach in template.attachment_ids:
- attachments.append((attach.datas_fname, attach.datas))
+ attachment_ids.append(attach.id)
values['attachments'] = attachments
+ values['attachment_ids'] = attachment_ids
return values
def send_mail(self, cr, uid, template_id, res_id, force_send=False, context=None):
@@ -369,28 +370,34 @@ class email_template(osv.osv):
was executed for this message only.
:returns: id of the mail.message that was created
"""
- if context is None: context = {}
+ if context is None:
+ context = {}
mail_mail = self.pool.get('mail.mail')
ir_attachment = self.pool.get('ir.attachment')
+
+ # create a mail_mail based on values, without attachments
values = self.generate_email(cr, uid, template_id, res_id, context=context)
- assert 'email_from' in values, 'email_from is missing or empty after template rendering, send_mail() cannot proceed'
- attachments = values.pop('attachments') or {}
- del values['partner_to'] # TODO Properly use them.
+ assert values.get('email_from'), 'email_from is missing or empty after template rendering, send_mail() cannot proceed'
+ del values['partner_to'] # TODO Properly use them.
+ attachment_ids = values.pop('attachment_ids', [])
+ attachments = values.pop('attachments', [])
msg_id = mail_mail.create(cr, uid, values, context=context)
- # link attachments
- attachment_ids = []
- for fname, fcontent in attachments.iteritems():
+
+ # manage attachments
+ for attachment in attachments:
attachment_data = {
- 'name': fname,
- 'datas_fname': fname,
- 'datas': fcontent,
- 'res_model': mail_mail._name,
+ 'name': attachment[0],
+ 'datas_fname': attachment[0],
+ 'datas': attachment[1],
+ 'res_model': 'mail.message',
'res_id': msg_id,
}
context.pop('default_type', None)
attachment_ids.append(ir_attachment.create(cr, uid, attachment_data, context=context))
if attachment_ids:
+ values['attachment_ids'] = [(6, 0, attachment_ids)]
mail_mail.write(cr, uid, msg_id, {'attachment_ids': [(6, 0, attachment_ids)]}, context=context)
+
if force_send:
mail_mail.send(cr, uid, [msg_id], context=context)
return msg_id
diff --git a/addons/email_template/i18n/lt.po b/addons/email_template/i18n/lt.po
new file mode 100644
index 00000000000..20c2c5e0e5d
--- /dev/null
+++ b/addons/email_template/i18n/lt.po
@@ -0,0 +1,488 @@
+# 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:19+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: email_template
+#: field:email.template,email_from:0
+#: field:email_template.preview,email_from:0
+msgid "From"
+msgstr ""
+
+#. module: email_template
+#: field:mail.compose.message,template_id:0
+msgid "Template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,ref_ir_value:0
+#: help:email_template.preview,ref_ir_value:0
+msgid "Sidebar button to open the sidebar action"
+msgstr ""
+
+#. module: email_template
+#: field:res.partner,opt_out:0
+msgid "Opt-Out"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,email_to:0
+#: field:email_template.preview,email_to:0
+msgid "To (Emails)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,mail_server_id:0
+#: field:email_template.preview,mail_server_id:0
+msgid "Outgoing Mail Server"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,ref_ir_act_window:0
+#: help:email_template.preview,ref_ir_act_window:0
+msgid ""
+"Sidebar action to make this template available on records of the related "
+"document model"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,model_object_field:0
+#: field:email_template.preview,model_object_field:0
+msgid "Field"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_from:0
+#: help:email_template.preview,email_from:0
+msgid "Sender address (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Remove context action"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,mail_server_id:0
+#: help:email_template.preview,mail_server_id:0
+msgid ""
+"Optional preferred server for outgoing mails. If not set, the highest "
+"priority one will be used."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,report_name:0
+#: field:email_template.preview,report_name:0
+msgid "Report Filename"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Preview"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,reply_to:0
+#: field:email_template.preview,reply_to:0
+msgid "Reply-To"
+msgstr ""
+
+#. module: email_template
+#: view:mail.compose.message:0
+msgid "Use template"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,body_html:0
+#: field:email_template.preview,body_html:0
+msgid "Body"
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:244
+#, python-format
+msgid "%s (copy)"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,user_signature:0
+#: help:email_template.preview,user_signature:0
+msgid ""
+"If checked, the user's signature will be appended to the text version of the "
+"message"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "SMTP Server"
+msgstr ""
+
+#. module: email_template
+#: view:mail.compose.message:0
+msgid "Save as new template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,sub_object:0
+#: help:email_template.preview,sub_object:0
+msgid ""
+"When a relationship field is selected as first field, this field shows the "
+"document model the relationship goes to."
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_email_template
+msgid "Email Templates"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,report_name:0
+#: help:email_template.preview,report_name:0
+msgid ""
+"Name to use for the generated report file (may contain placeholders)\n"
+"The extension can be omitted and will then come from the report type."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,ref_ir_act_window:0
+#: field:email_template.preview,ref_ir_act_window:0
+msgid "Sidebar action"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,lang:0
+#: help:email_template.preview,lang:0
+msgid ""
+"Optional translation language (ISO code) to select when sending out an "
+"email. If not set, the english version will be used. This should usually be "
+"a placeholder expression that provides the appropriate language code, e.g. "
+"${object.partner_id.lang.code}."
+msgstr ""
+
+#. module: email_template
+#: field:email_template.preview,res_id:0
+msgid "Sample Document"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,model_object_field:0
+#: help:email_template.preview,model_object_field:0
+msgid ""
+"Select target field from the related document model.\n"
+"If it is a relationship field you will be able to select a target field at "
+"the destination of the relationship."
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Dynamic Value Builder"
+msgstr ""
+
+#. module: email_template
+#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
+msgid "Template Preview"
+msgstr ""
+
+#. module: email_template
+#: view:mail.compose.message:0
+msgid "Save as a new template"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid ""
+"Display an option on related documents to open a composition wizard with "
+"this template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_cc:0
+#: help:email_template.preview,email_cc:0
+msgid "Carbon copy recipients (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_to:0
+#: help:email_template.preview,email_to:0
+msgid "Comma-separated recipient addresses (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Advanced"
+msgstr ""
+
+#. module: email_template
+#: view:email_template.preview:0
+msgid "Preview of"
+msgstr ""
+
+#. module: email_template
+#: view:email_template.preview:0
+msgid "Using sample document"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+#: model:ir.actions.act_window,name:email_template.action_email_template_tree_all
+#: model:ir.ui.menu,name:email_template.menu_email_templates
+msgid "Templates"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,name:0
+#: field:email_template.preview,name:0
+msgid "Name"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,lang:0
+#: field:email_template.preview,lang:0
+msgid "Language"
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_email_template_preview
+msgid "Email Template Preview"
+msgstr ""
+
+#. module: email_template
+#: view:email_template.preview:0
+msgid "Email Preview"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid ""
+"Remove the contextual action to use this template on related documents"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,copyvalue:0
+#: field:email_template.preview,copyvalue:0
+msgid "Placeholder Expression"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,sub_object:0
+#: field:email_template.preview,sub_object:0
+msgid "Sub-model"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,subject:0
+#: help:email_template.preview,subject:0
+msgid "Subject (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,reply_to:0
+#: help:email_template.preview,reply_to:0
+msgid "Preferred response address (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,ref_ir_value:0
+#: field:email_template.preview,ref_ir_value:0
+msgid "Sidebar Button"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,report_template:0
+#: field:email_template.preview,report_template:0
+msgid "Optional report to print and attach"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,null_value:0
+#: help:email_template.preview,null_value:0
+msgid "Optional value to use if the target field is empty"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Model"
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_mail_compose_message
+msgid "Email composition wizard"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Add context action"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,model_id:0
+#: help:email_template.preview,model_id:0
+msgid "The kind of document with with this template can be used"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,email_recipients:0
+#: field:email_template.preview,email_recipients:0
+msgid "To (Partners)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,auto_delete:0
+#: field:email_template.preview,auto_delete:0
+msgid "Auto Delete"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,copyvalue:0
+#: help:email_template.preview,copyvalue:0
+msgid ""
+"Final placeholder expression, to be copy-pasted in the desired template "
+"field."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,model:0
+#: field:email_template.preview,model:0
+msgid "Related Document Model"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Addressing"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_recipients:0
+#: help:email_template.preview,email_recipients:0
+msgid ""
+"Comma-separated ids of recipient partners (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,attachment_ids:0
+#: field:email_template.preview,attachment_ids:0
+msgid "Attachments"
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:231
+#, python-format
+msgid "Deletion of the action record failed."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,email_cc:0
+#: field:email_template.preview,email_cc:0
+msgid "Cc"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,model_id:0
+#: field:email_template.preview,model_id:0
+msgid "Applies to"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,sub_model_object_field:0
+#: field:email_template.preview,sub_model_object_field:0
+msgid "Sub-field"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Email Details"
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:196
+#, python-format
+msgid "Send Mail (%s)"
+msgstr ""
+
+#. module: email_template
+#: help:res.partner,opt_out:0
+msgid ""
+"If checked, this partner will not receive any automated email notifications, "
+"such as the availability of invoices."
+msgstr ""
+
+#. module: email_template
+#: help:email.template,auto_delete:0
+#: help:email_template.preview,auto_delete:0
+msgid "Permanently delete this email after sending it, to save space"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Group by..."
+msgstr ""
+
+#. module: email_template
+#: help:email.template,sub_model_object_field:0
+#: help:email_template.preview,sub_model_object_field:0
+msgid ""
+"When a relationship field is selected as first field, this field lets you "
+"select the target field within the destination document model (sub-model)."
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:231
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,user_signature:0
+#: field:email_template.preview,user_signature:0
+msgid "Add Signature"
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,null_value:0
+#: field:email_template.preview,null_value:0
+msgid "Default Value"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,attachment_ids:0
+#: help:email_template.preview,attachment_ids:0
+msgid ""
+"You may attach files to this template, to be added to all emails created "
+"from this template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,body_html:0
+#: help:email_template.preview,body_html:0
+msgid "Rich-text/HTML version of the message (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Contents"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,subject:0
+#: field:email_template.preview,subject:0
+msgid "Subject"
+msgstr ""
diff --git a/addons/email_template/i18n/nl_BE.po b/addons/email_template/i18n/nl_BE.po
new file mode 100644
index 00000000000..5e7ddeec587
--- /dev/null
+++ b/addons/email_template/i18n/nl_BE.po
@@ -0,0 +1,489 @@
+# Dutch (Belgium) 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-26 16:28+0000\n"
+"Last-Translator: Els Van Vossel (Agaplan) \n"
+"Language-Team: Dutch (Belgium) \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-27 05:44+0000\n"
+"X-Generator: Launchpad (build 16580)\n"
+
+#. module: email_template
+#: field:email.template,email_from:0
+#: field:email_template.preview,email_from:0
+msgid "From"
+msgstr "Van"
+
+#. module: email_template
+#: field:mail.compose.message,template_id:0
+msgid "Template"
+msgstr "Sjabloon"
+
+#. module: email_template
+#: help:email.template,ref_ir_value:0
+#: help:email_template.preview,ref_ir_value:0
+msgid "Sidebar button to open the sidebar action"
+msgstr ""
+
+#. module: email_template
+#: field:res.partner,opt_out:0
+msgid "Opt-Out"
+msgstr "Uitschrijven"
+
+#. module: email_template
+#: field:email.template,email_to:0
+#: field:email_template.preview,email_to:0
+msgid "To (Emails)"
+msgstr "Naar (E-mails)"
+
+#. module: email_template
+#: field:email.template,mail_server_id:0
+#: field:email_template.preview,mail_server_id:0
+msgid "Outgoing Mail Server"
+msgstr "Uitgaande mailserver"
+
+#. module: email_template
+#: help:email.template,ref_ir_act_window:0
+#: help:email_template.preview,ref_ir_act_window:0
+msgid ""
+"Sidebar action to make this template available on records of the related "
+"document model"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,model_object_field:0
+#: field:email_template.preview,model_object_field:0
+msgid "Field"
+msgstr "Veld"
+
+#. module: email_template
+#: help:email.template,email_from:0
+#: help:email_template.preview,email_from:0
+msgid "Sender address (placeholders may be used here)"
+msgstr ""
+"Adres van de afzender (variabele aanduidingen kunnen hier worden gebruikt)"
+
+#. module: email_template
+#: view:email.template:0
+msgid "Remove context action"
+msgstr "Contextactie verwijderen"
+
+#. module: email_template
+#: help:email.template,mail_server_id:0
+#: help:email_template.preview,mail_server_id:0
+msgid ""
+"Optional preferred server for outgoing mails. If not set, the highest "
+"priority one will be used."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,report_name:0
+#: field:email_template.preview,report_name:0
+msgid "Report Filename"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Preview"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,reply_to:0
+#: field:email_template.preview,reply_to:0
+msgid "Reply-To"
+msgstr ""
+
+#. module: email_template
+#: view:mail.compose.message:0
+msgid "Use template"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,body_html:0
+#: field:email_template.preview,body_html:0
+msgid "Body"
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:244
+#, python-format
+msgid "%s (copy)"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,user_signature:0
+#: help:email_template.preview,user_signature:0
+msgid ""
+"If checked, the user's signature will be appended to the text version of the "
+"message"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "SMTP Server"
+msgstr ""
+
+#. module: email_template
+#: view:mail.compose.message:0
+msgid "Save as new template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,sub_object:0
+#: help:email_template.preview,sub_object:0
+msgid ""
+"When a relationship field is selected as first field, this field shows the "
+"document model the relationship goes to."
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_email_template
+msgid "Email Templates"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,report_name:0
+#: help:email_template.preview,report_name:0
+msgid ""
+"Name to use for the generated report file (may contain placeholders)\n"
+"The extension can be omitted and will then come from the report type."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,ref_ir_act_window:0
+#: field:email_template.preview,ref_ir_act_window:0
+msgid "Sidebar action"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,lang:0
+#: help:email_template.preview,lang:0
+msgid ""
+"Optional translation language (ISO code) to select when sending out an "
+"email. If not set, the english version will be used. This should usually be "
+"a placeholder expression that provides the appropriate language code, e.g. "
+"${object.partner_id.lang.code}."
+msgstr ""
+
+#. module: email_template
+#: field:email_template.preview,res_id:0
+msgid "Sample Document"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,model_object_field:0
+#: help:email_template.preview,model_object_field:0
+msgid ""
+"Select target field from the related document model.\n"
+"If it is a relationship field you will be able to select a target field at "
+"the destination of the relationship."
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Dynamic Value Builder"
+msgstr ""
+
+#. module: email_template
+#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
+msgid "Template Preview"
+msgstr ""
+
+#. module: email_template
+#: view:mail.compose.message:0
+msgid "Save as a new template"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid ""
+"Display an option on related documents to open a composition wizard with "
+"this template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_cc:0
+#: help:email_template.preview,email_cc:0
+msgid "Carbon copy recipients (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_to:0
+#: help:email_template.preview,email_to:0
+msgid "Comma-separated recipient addresses (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Advanced"
+msgstr ""
+
+#. module: email_template
+#: view:email_template.preview:0
+msgid "Preview of"
+msgstr ""
+
+#. module: email_template
+#: view:email_template.preview:0
+msgid "Using sample document"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+#: model:ir.actions.act_window,name:email_template.action_email_template_tree_all
+#: model:ir.ui.menu,name:email_template.menu_email_templates
+msgid "Templates"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,name:0
+#: field:email_template.preview,name:0
+msgid "Name"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,lang:0
+#: field:email_template.preview,lang:0
+msgid "Language"
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_email_template_preview
+msgid "Email Template Preview"
+msgstr ""
+
+#. module: email_template
+#: view:email_template.preview:0
+msgid "Email Preview"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid ""
+"Remove the contextual action to use this template on related documents"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,copyvalue:0
+#: field:email_template.preview,copyvalue:0
+msgid "Placeholder Expression"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,sub_object:0
+#: field:email_template.preview,sub_object:0
+msgid "Sub-model"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,subject:0
+#: help:email_template.preview,subject:0
+msgid "Subject (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,reply_to:0
+#: help:email_template.preview,reply_to:0
+msgid "Preferred response address (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,ref_ir_value:0
+#: field:email_template.preview,ref_ir_value:0
+msgid "Sidebar Button"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,report_template:0
+#: field:email_template.preview,report_template:0
+msgid "Optional report to print and attach"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,null_value:0
+#: help:email_template.preview,null_value:0
+msgid "Optional value to use if the target field is empty"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Model"
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_mail_compose_message
+msgid "Email composition wizard"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Add context action"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,model_id:0
+#: help:email_template.preview,model_id:0
+msgid "The kind of document with with this template can be used"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,email_recipients:0
+#: field:email_template.preview,email_recipients:0
+msgid "To (Partners)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,auto_delete:0
+#: field:email_template.preview,auto_delete:0
+msgid "Auto Delete"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,copyvalue:0
+#: help:email_template.preview,copyvalue:0
+msgid ""
+"Final placeholder expression, to be copy-pasted in the desired template "
+"field."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,model:0
+#: field:email_template.preview,model:0
+msgid "Related Document Model"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Addressing"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,email_recipients:0
+#: help:email_template.preview,email_recipients:0
+msgid ""
+"Comma-separated ids of recipient partners (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,attachment_ids:0
+#: field:email_template.preview,attachment_ids:0
+msgid "Attachments"
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:231
+#, python-format
+msgid "Deletion of the action record failed."
+msgstr ""
+
+#. module: email_template
+#: field:email.template,email_cc:0
+#: field:email_template.preview,email_cc:0
+msgid "Cc"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,model_id:0
+#: field:email_template.preview,model_id:0
+msgid "Applies to"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,sub_model_object_field:0
+#: field:email_template.preview,sub_model_object_field:0
+msgid "Sub-field"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Email Details"
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:196
+#, python-format
+msgid "Send Mail (%s)"
+msgstr ""
+
+#. module: email_template
+#: help:res.partner,opt_out:0
+msgid ""
+"If checked, this partner will not receive any automated email notifications, "
+"such as the availability of invoices."
+msgstr ""
+
+#. module: email_template
+#: help:email.template,auto_delete:0
+#: help:email_template.preview,auto_delete:0
+msgid "Permanently delete this email after sending it, to save space"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Group by..."
+msgstr ""
+
+#. module: email_template
+#: help:email.template,sub_model_object_field:0
+#: help:email_template.preview,sub_model_object_field:0
+msgid ""
+"When a relationship field is selected as first field, this field lets you "
+"select the target field within the destination document model (sub-model)."
+msgstr ""
+
+#. module: email_template
+#: code:addons/email_template/email_template.py:231
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,user_signature:0
+#: field:email_template.preview,user_signature:0
+msgid "Add Signature"
+msgstr ""
+
+#. module: email_template
+#: model:ir.model,name:email_template.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,null_value:0
+#: field:email_template.preview,null_value:0
+msgid "Default Value"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,attachment_ids:0
+#: help:email_template.preview,attachment_ids:0
+msgid ""
+"You may attach files to this template, to be added to all emails created "
+"from this template"
+msgstr ""
+
+#. module: email_template
+#: help:email.template,body_html:0
+#: help:email_template.preview,body_html:0
+msgid "Rich-text/HTML version of the message (placeholders may be used here)"
+msgstr ""
+
+#. module: email_template
+#: view:email.template:0
+msgid "Contents"
+msgstr ""
+
+#. module: email_template
+#: field:email.template,subject:0
+#: field:email_template.preview,subject:0
+msgid "Subject"
+msgstr ""
diff --git a/addons/email_template/tests/test_mail.py b/addons/email_template/tests/test_mail.py
index 56abe6a0fef..d5feea9ebc4 100644
--- a/addons/email_template/tests/test_mail.py
+++ b/addons/email_template/tests/test_mail.py
@@ -48,8 +48,8 @@ class test_message_compose(TestMailBase):
_body_html1 = 'Fans of Pigs, unite !'
_body_html2 = 'I am angry !'
_attachments = [
- {'name': 'First', 'datas_fname': 'first.txt', 'datas': base64.b64encode('My first attachment')},
- {'name': 'Second', 'datas_fname': 'second.txt', 'datas': base64.b64encode('My second attachment')}
+ {'name': 'First', 'datas_fname': 'first.txt', 'datas': base64.b64encode('My first attachment'), 'res_model': 'res.partner', 'res_id': self.partner_admin_id},
+ {'name': 'Second', 'datas_fname': 'second.txt', 'datas': base64.b64encode('My second attachment'), 'res_model': 'res.partner', 'res_id': self.partner_admin_id},
]
_attachments_test = [('first.txt', 'My first attachment'), ('second.txt', 'My second attachment')]
@@ -115,12 +115,20 @@ class test_message_compose(TestMailBase):
self.assertEqual(compose.subject, _subject1, 'mail.compose.message subject incorrect')
self.assertIn(_body_html1, compose.body, 'mail.compose.message body incorrect')
self.assertEqual(set(message_pids), set(partner_ids), 'mail.compose.message partner_ids incorrect')
- # Test: mail.compose.message: attachments
- # Test: mail.message: attachments
+ # Test: mail.compose.message: attachments (owner has not been modified)
for attach in compose.attachment_ids:
- self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
- self.assertEqual(attach.res_id, self.group_pigs_id, 'mail.message attachment res_id incorrect')
- self.assertIn((attach.name, base64.b64decode(attach.datas)), _attachments_test,
+ self.assertEqual(attach.res_model, 'res.partner', 'mail.compose.message attachment res_model through templat was overriden')
+ self.assertEqual(attach.res_id, self.partner_admin_id, 'mail.compose.message attachment res_id incorrect')
+ self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
+ 'mail.message attachment name / data incorrect')
+ # Test: mail.message: attachments
+ mail_compose.send_mail(cr, uid, [compose_id])
+ group_pigs.refresh()
+ message_pigs = group_pigs.message_ids[0]
+ for attach in message_pigs.attachment_ids:
+ self.assertEqual(attach.res_model, 'mail.group', 'mail.compose.message attachment res_model through templat was overriden')
+ self.assertEqual(attach.res_id, self.group_pigs_id, 'mail.compose.message attachment res_id incorrect')
+ self.assertIn((attach.datas_fname, base64.b64decode(attach.datas)), _attachments_test,
'mail.message attachment name / data incorrect')
# ----------------------------------------
diff --git a/addons/email_template/wizard/email_template_preview.py b/addons/email_template/wizard/email_template_preview.py
index c6518122d02..5fee415a75e 100644
--- a/addons/email_template/wizard/email_template_preview.py
+++ b/addons/email_template/wizard/email_template_preview.py
@@ -40,7 +40,7 @@ class email_template_preview(osv.osv_memory):
email_template = self.pool.get('email.template')
template = email_template.browse(cr, uid, int(template_id), context=context)
template_object = template.model_id
- model = self.pool.get(template_object.model)
+ model = self.pool[template_object.model]
record_ids = model.search(cr, uid, [], 0, 10, 'id', context=context)
default_id = context.get('default_res_id')
diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py
index f3b03d16a2f..7f44828ce15 100644
--- a/addons/email_template/wizard/mail_compose_message.py
+++ b/addons/email_template/wizard/mail_compose_message.py
@@ -49,26 +49,44 @@ class mail_compose_message(osv.TransientModel):
help="Carbon copy recipients (placeholders may be used here)"),
}
+ def send_mail(self, cr, uid, ids, context=None):
+ """ Override of send_mail to duplicate attachments linked to the email.template.
+ Indeed, basic mail.compose.message wizard duplicates attachments in mass
+ mailing mode. But in 'single post' mode, attachments of an email template
+ also have to be duplicated to avoid changing their ownership. """
+ for wizard in self.browse(cr, uid, ids, context=context):
+ if not wizard.attachment_ids or wizard.composition_mode == 'mass_mail' or not wizard.template_id:
+ continue
+ template = self.pool.get('email.template').browse(cr, uid, wizard.template_id.id, context=context)
+ new_attachment_ids = []
+ for attachment in wizard.attachment_ids:
+ if attachment in template.attachment_ids:
+ new_attachment_ids.append(self.pool.get('ir.attachment').copy(cr, uid, attachment.id, {'res_model': 'mail.compose.message', 'res_id': wizard.id}, context=context))
+ else:
+ new_attachment_ids.append(attachment.id)
+ self.write(cr, uid, wizard.id, {'attachment_ids': [(6, 0, new_attachment_ids)]}, context=context)
+ return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context)
+
def onchange_template_id(self, cr, uid, ids, template_id, composition_mode, model, res_id, context=None):
""" - mass_mailing: we cannot render, so return the template values
- normal mode: return rendered values """
if template_id and composition_mode == 'mass_mail':
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to']
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids']
template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context)
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
elif template_id:
- # FIXME odo: change the mail generation to avoid attachment duplication
values = self.generate_email_for_composer(cr, uid, template_id, res_id, context=context)
- # transform attachments into attachment_ids
- values['attachment_ids'] = []
+ # transform attachments into attachment_ids; not attached to the document because this will
+ # be done further in the posting process, allowing to clean database if email not send
+ values['attachment_ids'] = values.pop('attachment_ids', [])
ir_attach_obj = self.pool.get('ir.attachment')
for attach_fname, attach_datas in values.pop('attachments', []):
data_attach = {
'name': attach_fname,
'datas': attach_datas,
'datas_fname': attach_fname,
- 'res_model': model,
- 'res_id': res_id,
+ 'res_model': 'mail.compose.message',
+ 'res_id': 0,
'type': 'binary', # override default_type from context, possibly meant for another model!
}
values['attachment_ids'].append(ir_attach_obj.create(cr, uid, data_attach, context=context))
@@ -128,7 +146,7 @@ class mail_compose_message(osv.TransientModel):
mail.compose.message, transform email_cc and email_to into partner_ids """
template_values = self.pool.get('email.template').generate_email(cr, uid, template_id, res_id, context=context)
# filter template values
- fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachments']
+ fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'attachments']
values = dict((field, template_values[field]) for field in fields if template_values.get(field))
values['body'] = values.pop('body_html', '')
@@ -145,9 +163,11 @@ class mail_compose_message(osv.TransientModel):
""" Override to handle templates. """
# generate the composer email
if wizard.template_id:
- values = self.generate_email_for_composer(cr, uid, wizard.template_id, res_id, context=context)
+ values = self.generate_email_for_composer(cr, uid, wizard.template_id.id, res_id, context=context)
else:
values = {}
+ # remove attachments as they should not be rendered
+ values.pop('attachment_ids', None)
# get values to return
email_dict = super(mail_compose_message, self).render_message(cr, uid, wizard, res_id, context)
# those values are not managed; they are readonly
diff --git a/addons/event/event.py b/addons/event/event.py
index 9e50128c592..eb18afd747c 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -41,7 +41,6 @@ class event_type(osv.osv):
'default_registration_max': 0,
}
-event_type()
class event_event(osv.osv):
"""Event"""
diff --git a/addons/event/report/report_event_registration.py b/addons/event/report/report_event_registration.py
index 481b86f032c..0e33e892432 100644
--- a/addons/event/report/report_event_registration.py
+++ b/addons/event/report/report_event_registration.py
@@ -99,6 +99,5 @@ class report_event_registration(osv.osv):
)
""")
-report_event_registration()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/event/res_partner.py b/addons/event/res_partner.py
index 88249c5a7cd..fc4afa56e69 100644
--- a/addons/event/res_partner.py
+++ b/addons/event/res_partner.py
@@ -31,6 +31,5 @@ class res_partner(osv.osv):
}
-res_partner()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/event/wizard/event_confirm.py b/addons/event/wizard/event_confirm.py
index 8611a066801..5fb2cd67c87 100644
--- a/addons/event/wizard/event_confirm.py
+++ b/addons/event/wizard/event_confirm.py
@@ -32,6 +32,5 @@ class event_confirm(osv.osv_memory):
self.pool.get('event.event').do_confirm(cr, uid, context.get('event_ids', []), context=context)
return {'type': 'ir.actions.act_window_close'}
-event_confirm()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/event_moodle/event_moodle.py b/addons/event_moodle/event_moodle.py
index 5c7373d1adb..44d2de4bdd5 100644
--- a/addons/event_moodle/event_moodle.py
+++ b/addons/event_moodle/event_moodle.py
@@ -150,7 +150,6 @@ class event_moodle(osv.osv):
name_user = "moodle_" + "%d" % (response_courses,) + "%d" % (random.randint(1,999999),)
return name_user
-event_moodle()
class event_event(osv.osv):
_inherit = "event.event"
@@ -221,7 +220,6 @@ class event_event(osv.osv):
moodle_pool.moodle_enrolled(cr, uid, moodle_config_wiz_id, enrolled, context=context)
return res
-event_event()
class event_registration(osv.osv):
@@ -286,4 +284,3 @@ class event_registration(osv.osv):
'city': reg.city,
'street': reg.street}}
return res
-event_registration()
diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py
index 4f32620e667..ec583a58cbf 100644
--- a/addons/event_sale/event_sale.py
+++ b/addons/event_sale/event_sale.py
@@ -32,7 +32,6 @@ class product(osv.osv):
def onchange_event_ok(self, cr, uid, ids, event_ok, context=None):
return {'value': {'type': event_ok and 'service' or False}}
-product()
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
diff --git a/addons/fetchmail/fetchmail.py b/addons/fetchmail/fetchmail.py
index 397ca893bae..cce1f77856e 100644
--- a/addons/fetchmail/fetchmail.py
+++ b/addons/fetchmail/fetchmail.py
@@ -89,7 +89,6 @@ class fetchmail_server(osv.osv):
'script': '/mail/static/scripts/openerp_mailgate.py',
}
-
def onchange_server_type(self, cr, uid, ids, server_type=False, ssl=False, object_id=False):
port = 0
values = {}
@@ -175,13 +174,14 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
def _fetch_mails(self, cr, uid, ids=False, context=None):
if not ids:
- ids = self.search(cr, uid, [('state','=','done')])
+ ids = self.search(cr, uid, [('state','=','done'),('type','in',['pop','imap'])])
return self.fetch_mail(cr, uid, ids, context=context)
def fetch_mail(self, cr, uid, ids, context=None):
"""WARNING: meant for cron usage only - will commit() after each email!"""
if context is None:
context = {}
+ context['fetchmail_cron_running'] = True
mail_thread = self.pool.get('mail.thread')
action_pool = self.pool.get('ir.actions.server')
for server in self.browse(cr, uid, ids, context=context):
@@ -240,6 +240,29 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
server.write({'date': time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)})
return True
+ def cron_update(self, cr, uid, context=None):
+ if context is None:
+ context = {}
+ if not context.get('fetchmail_cron_running'):
+ # Enabled/Disable cron based on the number of 'done' server of type pop or imap
+ ids = self.search(cr, uid, [('state','=','done'),('type','in',['pop','imap'])])
+ try:
+ cron_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fetchmail', 'ir_cron_mail_gateway_action')[1]
+ self.pool.get('ir.cron').write(cr, 1, [cron_id], {'active': bool(ids)})
+ except ValueError:
+ # Nevermind if default cron cannot be found
+ pass
+
+ def create(self, cr, uid, values, context=None):
+ res = super(fetchmail_server, self).create(cr, uid, values, context=context)
+ self.cron_update(cr, uid, context=context)
+ return res
+
+ def write(self, cr, uid, ids, values, context=None):
+ res = super(fetchmail_server, self).write(cr, uid, ids, values, context=context)
+ self.cron_update(cr, uid, context=context)
+ return res
+
class mail_mail(osv.osv):
_inherit = "mail.mail"
_columns = {
diff --git a/addons/fetchmail/fetchmail_data.xml b/addons/fetchmail/fetchmail_data.xml
index d77aadc12de..3f6592b340f 100644
--- a/addons/fetchmail/fetchmail_data.xml
+++ b/addons/fetchmail/fetchmail_data.xml
@@ -10,6 +10,8 @@
fetchmail.server_fetch_mails()
+
+
diff --git a/addons/fleet/i18n/nl_BE.po b/addons/fleet/i18n/nl_BE.po
new file mode 100644
index 00000000000..380de8a945e
--- /dev/null
+++ b/addons/fleet/i18n/nl_BE.po
@@ -0,0 +1,1912 @@
+# Dutch (Belgium) 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-15 16:40+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Dutch (Belgium) \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-16 04:37+0000\n"
+"X-Generator: Launchpad (build 16564)\n"
+
+#. module: fleet
+#: selection:fleet.vehicle,fuel_type:0
+msgid "Hybrid"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.vehicle.tag,name:fleet.vehicle_tag_compact
+msgid "Compact"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_1
+msgid "A/C Compressor Replacement"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,vin_sn:0
+msgid "Unique number written on the vehicle motor (VIN/SN number)"
+msgstr ""
+
+#. module: fleet
+#: selection:fleet.service.type,category:0
+#: view:fleet.vehicle.log.contract:0
+#: view:fleet.vehicle.log.services:0
+msgid "Service"
+msgstr ""
+
+#. module: fleet
+#: selection:fleet.vehicle.log.contract,cost_frequency:0
+msgid "Monthly"
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:62
+#, python-format
+msgid "Unknown"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_20
+msgid "Engine/Drive Belt(s) Replacement"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.cost:0
+msgid "Vehicle costs"
+msgstr ""
+
+#. module: fleet
+#: selection:fleet.vehicle,fuel_type:0
+msgid "Diesel"
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:421
+#, python-format
+msgid "License Plate: from '%s' to '%s'"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_38
+msgid "Resurface Rotors"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.cost:0
+#: view:fleet.vehicle.model:0
+msgid "Group By..."
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_32
+msgid "Oil Pump Replacement"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_18
+msgid "Engine Belt Inspection"
+msgstr ""
+
+#. module: fleet
+#: selection:fleet.vehicle.log.contract,cost_frequency:0
+msgid "No"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,power:0
+msgid "Power in kW of the vehicle"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_service_2
+msgid "Depreciation and Interests"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle.log.contract,insurer_id:0
+#: field:fleet.vehicle.log.fuel,vendor_id:0
+#: field:fleet.vehicle.log.services,vendor_id:0
+msgid "Supplier"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_35
+msgid "Power Steering Hose Replacement"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.contract:0
+msgid "Odometer details"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle:0
+msgid "Has Alert(s)"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle.log.fuel,liter:0
+msgid "Liter"
+msgstr ""
+
+#. module: fleet
+#: model:ir.actions.client,name:fleet.action_fleet_menu
+msgid "Open Fleet Menu"
+msgstr ""
+
+#. module: fleet
+#: view:board.board:0
+msgid "Fuel Costs"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_9
+msgid "Battery Inspection"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.contract:0
+msgid "Invoice Date"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.fuel:0
+msgid "Refueling Details"
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:669
+#, python-format
+msgid "%s contract(s) need(s) to be renewed and/or closed!"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.cost:0
+msgid "Indicative Costs"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_16
+msgid "Charging System Diagnosis"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,car_value:0
+msgid "Value of the bought vehicle"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_44
+msgid "Tie Rod End Replacement"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_24
+msgid "Head Gasket(s) Replacement"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle:0
+#: selection:fleet.vehicle.cost,cost_type:0
+msgid "Services"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,odometer:0
+#: help:fleet.vehicle.cost,odometer:0
+#: help:fleet.vehicle.cost,odometer_id:0
+msgid "Odometer measure of the vehicle at the moment of this log"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.contract:0
+#: field:fleet.vehicle.log.contract,notes:0
+msgid "Terms and Conditions"
+msgstr ""
+
+#. module: fleet
+#: model:ir.actions.act_window,name:fleet.action_fleet_vehicle_kanban
+msgid "Vehicles with alerts"
+msgstr ""
+
+#. module: fleet
+#: model:ir.actions.act_window,name:fleet.fleet_vehicle_costs_act
+#: model:ir.ui.menu,name:fleet.fleet_vehicle_costs_menu
+msgid "Vehicle Costs"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.cost:0
+msgid "Total Cost"
+msgstr ""
+
+#. module: fleet
+#: selection:fleet.service.type,category:0
+msgid "Both"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle.log.contract,cost_id:0
+#: field:fleet.vehicle.log.fuel,cost_id:0
+#: field:fleet.vehicle.log.services,cost_id:0
+msgid "Automatically created field to link to parent fleet.vehicle.cost"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.contract:0
+msgid "Terminate Contract"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.cost,parent_id:0
+msgid "Parent cost to this current cost"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.log.contract,cost_frequency:0
+msgid "Frequency of the recuring cost"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_service_1
+msgid "Calculation Benefit In Kind"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.log.contract,expiration_date:0
+msgid ""
+"Date when the coverage of the contract expirates (by default, one year after "
+"begin date)"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.fuel:0
+#: field:fleet.vehicle.log.fuel,notes:0
+#: view:fleet.vehicle.log.services:0
+#: field:fleet.vehicle.log.services,notes:0
+msgid "Notes"
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:47
+#, python-format
+msgid "Operation not allowed!"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle,message_ids:0
+msgid "Messages"
+msgstr ""
+
+#. module: fleet
+#: model:res.groups,name:fleet.group_fleet_user
+msgid "User"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.cost,vehicle_id:0
+msgid "Vehicle concerned by this log"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle.log.contract,cost_amount:0
+#: field:fleet.vehicle.log.fuel,cost_amount:0
+#: field:fleet.vehicle.log.services,cost_amount:0
+msgid "Amount"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle,message_unread:0
+msgid "Unread Messages"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_6
+msgid "Air Filter Replacement"
+msgstr ""
+
+#. module: fleet
+#: model:ir.model,name:fleet.model_fleet_vehicle_tag
+msgid "fleet.vehicle.tag"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle:0
+msgid "show the services logs for this vehicle"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle,contract_renewal_name:0
+msgid "Name of contract to renew soon"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.vehicle.tag,name:fleet.vehicle_tag_senior
+msgid "Senior"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.log.contract,state:0
+msgid "Choose wheter the contract is still valid or not"
+msgstr ""
+
+#. module: fleet
+#: selection:fleet.vehicle,transmission:0
+msgid "Automatic"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,message_unread:0
+msgid "If checked new messages require your attention."
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:414
+#, python-format
+msgid "Driver: from '%s' to '%s'"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle:0
+msgid "and"
+msgstr ""
+
+#. module: fleet
+#: field:fleet.vehicle.model.brand,image_medium:0
+msgid "Medium-sized photo"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_34
+msgid "Oxygen Sensor Replacement"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.services:0
+msgid "Service Type"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,transmission:0
+msgid "Transmission Used by the vehicle"
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:740
+#: view:fleet.vehicle.log.contract:0
+#: model:ir.actions.act_window,name:fleet.act_renew_contract
+#, python-format
+msgid "Renew Contract"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle:0
+msgid "show the odometer logs for this vehicle"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,odometer_unit:0
+msgid "Unit of the odometer "
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.services:0
+msgid "Services Costs Per Month"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.cost:0
+msgid "Effective Costs"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_service_8
+msgid "Repair and maintenance"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.log.contract,purchaser_id:0
+msgid "Person to which the contract is signed for"
+msgstr ""
+
+#. module: fleet
+#: model:ir.actions.act_window,help:fleet.fleet_vehicle_log_contract_act
+msgid ""
+"
\n"
+" Click to create a new contract. \n"
+"
\n"
+" Manage all your contracts (leasing, insurances, etc.) with\n"
+" their related services, costs. OpenERP will automatically "
+"warn\n"
+" you when some contracts have to be renewed.\n"
+"
\n"
+" Each contract (e.g.: leasing) may include several services\n"
+" (reparation, insurances, periodic maintenance).\n"
+"
\n"
+" OpenERP helps you managing the costs for your different\n"
+" vehicles. Costs are created automatically from services,\n"
+" contracts (fixed or recurring) and fuel logs.\n"
+"
\n"
+" Here you can add refuelling entries for all vehicles. You "
+"can\n"
+" also filter logs of a particular vehicle using the search\n"
+" field.\n"
+"
\n"
+" You will be able to manage your fleet by keeping track of "
+"the\n"
+" contracts, services, fixed and recurring costs, odometers "
+"and\n"
+" fuel logs associated to each vehicle.\n"
+"
\n"
+" OpenERP will warn you when services or contract have to be\n"
+" renewed.\n"
+"
\n"
+" To add your first report into this dashboard, go to any\n"
+" menu, switch to list or graph view, and click 'Add "
+"to\n"
+" Dashboard' in the extended search options.\n"
+"
\n"
+" You can filter and group data before inserting into the\n"
+" dashboard using the search options.\n"
+"
\n"
+" OpenERP helps you managing the costs for your different vehicles\n"
+" Costs are generally created from services and contract and appears "
+"here.\n"
+"
\n"
+"
\n"
+" Thanks to the different filters, OpenERP can only print the "
+"effective\n"
+" costs, sort them by type and by vehicle.\n"
+"
\n"
+" Here you can add various odometer entries for all vehicles.\n"
+" You can also show odometer value for a particular vehicle "
+"using\n"
+" the search field.\n"
+"
\n"
+" Here are displayed vehicles for which one or more contracts need "
+"to be renewed. If you see this message, then there is no contracts to "
+"renew.\n"
+"
\n"
+" Click to create a new service entry. \n"
+"
\n"
+" OpenERP helps you keeping track of all the services done\n"
+" on your vehicle. Services can be of many type: occasional\n"
+" repair, fixed maintenance, etc.\n"
+"
\n"
+" Click to create a new type of service.\n"
+"
\n"
+" Each service can used in contracts, as a standalone service "
+"or both.\n"
+"
\n"
+" "
+msgstr ""
+
+#. module: fleet
+#: view:board.board:0
+msgid "Services Costs"
+msgstr ""
+
+#. module: fleet
+#: code:addons/fleet/fleet.py:47
+#, python-format
+msgid "Emptying the odometer value of a vehicle is not allowed."
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,seats:0
+msgid "Number of seats of the vehicle"
+msgstr ""
+
+#. module: fleet
+#: model:res.groups,name:fleet.group_fleet_manager
+msgid "Manager"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.services:0
+msgid "Cost"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_39
+msgid "Rotate Tires"
+msgstr ""
+
+#. module: fleet
+#: model:fleet.service.type,name:fleet.type_service_42
+msgid "Starter Replacement"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.cost:0
+#: field:fleet.vehicle.cost,year:0
+msgid "Year"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle,license_plate:0
+msgid "License plate number of the vehicle (ie: plate number for a car)"
+msgstr ""
+
+#. module: fleet
+#: model:ir.model,name:fleet.model_fleet_contract_state
+msgid "Contains the different possible status of a leasing contract"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle:0
+msgid "show the contract for this vehicle"
+msgstr ""
+
+#. module: fleet
+#: view:fleet.vehicle.log.services:0
+msgid "Total"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.service.type,category:0
+msgid ""
+"Choose wheter the service refer to contracts, vehicle services or both"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.cost,cost_type:0
+msgid "For internal purpose only"
+msgstr ""
+
+#. module: fleet
+#: help:fleet.vehicle.state,sequence:0
+msgid "Used to order the note stages"
+msgstr ""
diff --git a/addons/google_base_account/google_base_account.py b/addons/google_base_account/google_base_account.py
index 46b1757a7b3..06e5643344c 100644
--- a/addons/google_base_account/google_base_account.py
+++ b/addons/google_base_account/google_base_account.py
@@ -27,7 +27,6 @@ class res_users(osv.osv):
'gmail_user': fields.char('Username', size=64,),
'gmail_password': fields.char('Password', size=64),
}
-res_users()
# vim:expandtab:smartindent:toabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/google_base_account/wizard/google_login.py b/addons/google_base_account/wizard/google_login.py
index f4464976aee..1771d99b51e 100644
--- a/addons/google_base_account/wizard/google_login.py
+++ b/addons/google_base_account/wizard/google_login.py
@@ -81,6 +81,5 @@ class google_login(osv.osv_memory):
def _get_next_action(self, cr, uid, context=None):
return {'type': 'ir.actions.act_window_close'}
-google_login()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/google_docs/google_docs.py b/addons/google_docs/google_docs.py
index cdb14de1de3..2fd1976ae3b 100644
--- a/addons/google_docs/google_docs.py
+++ b/addons/google_docs/google_docs.py
@@ -155,7 +155,7 @@ class google_docs_ir_attachment(osv.osv):
pool_ir_attachment = self.pool.get('ir.attachment')
pool_gdoc_config = self.pool.get('google.docs.config')
name_gdocs = ''
- model_fields_dic = self.pool.get(res_model).read(cr, uid, res_id, [], context=context)
+ model_fields_dic = self.pool[res_model].read(cr, uid, res_id, [], context=context)
# check if a model is configured with a template
google_docs_config = pool_gdoc_config.search(cr, uid, [('model_id', '=', res_model)], context=context)
@@ -191,4 +191,3 @@ This is the id of the template document, on google side. You can find it thanks
_defaults = {
'name_template': 'gdoc_%(name)s',
}
-config()
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index 467f34f708b..585e5ce81a4 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -19,10 +19,12 @@
#
##############################################################################
-from openerp import addons
import logging
+
+from openerp.modules.module import get_module_resource
from openerp.osv import fields, osv
from openerp import tools
+
_logger = logging.getLogger(__name__)
class hr_employee_category(osv.osv):
@@ -67,7 +69,6 @@ class hr_employee_category(osv.osv):
(_check_recursion, 'Error! You cannot create recursive Categories.', ['parent_id'])
]
-hr_employee_category()
class hr_job(osv.osv):
@@ -144,7 +145,6 @@ class hr_job(osv.osv):
self.write(cr, uid, ids, {'state': 'open', 'no_of_recruitment': 0})
return True
-hr_job()
class hr_employee(osv.osv):
_name = "hr.employee"
@@ -221,7 +221,7 @@ class hr_employee(osv.osv):
(model, mail_group_id) = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'group_all_employees')
employee = self.browse(cr, uid, employee_id, context=context)
self.pool.get('mail.group').message_post(cr, uid, [mail_group_id],
- body='Welcome to %s! Please help them take the first steps with OpenERP!' % (employee.name),
+ body='Welcome to %s! Please help him/her take the first steps with OpenERP!' % (employee.name),
subtype='mail.mt_comment', context=context)
except:
pass # group deleted: do not push a message
@@ -261,7 +261,7 @@ class hr_employee(osv.osv):
return {'value': {'work_email' : work_email}}
def _get_default_image(self, cr, uid, context=None):
- image_path = addons.get_module_resource('hr', 'static/src/img', 'default_image.png')
+ image_path = get_module_resource('hr', 'static/src/img', 'default_image.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
_defaults = {
@@ -284,7 +284,6 @@ class hr_employee(osv.osv):
(_check_recursion, 'Error! You cannot create recursive hierarchy of Employee(s).', ['parent_id']),
]
-hr_employee()
class hr_department(osv.osv):
_description = "Department"
@@ -326,7 +325,6 @@ class res_users(osv.osv):
'employee_ids': fields.one2many('hr.employee', 'user_id', 'Related employees'),
}
-res_users()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr/hr_demo.xml b/addons/hr/hr_demo.xml
index 3f34a703475..641d5b272cf 100644
--- a/addons/hr/hr_demo.xml
+++ b/addons/hr/hr_demo.xml
@@ -235,5 +235,99 @@
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
+
+ Hans Anders
+
+
+ Grand-Rosière
+ +3282823500
+ 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
+
+
+
+ Jan Van Eyck
+
+
+ Auderghem
+ +3282823500
+ jve@openerp.com
+ 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
+
+
+
+ Jean Pierre
+
+
+ Grand-Rosière
+ +3282823500
+ jep@openerp.com
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBhQPDw8PEBAUDxAUFRUQFhUUFBAUEBQUFBAXFhUVFRQXGyYfFxkjGhUUHy8gJCcpLCwsFR4xNTAqNSYrLCkBCQoKDgwOGg8PGiwkHCQpKSwpKSwpLCkqLCksKSwqKSksKSwsLCwsLCwsKSkpLCwpKSksKSwsLCwsLCwtLCkpKf/AABEIANUA7QMBIgACEQEDEQH/xAAcAAACAgMBAQAAAAAAAAAAAAAAAQIDBQYHBAj/xABAEAABBAAEAwUFBQYFBAMAAAABAAIDEQQSITEFBkETUWFxgQciMpGhFEJSscEjYnKC0fAWM0Ph8SSSosIVNGP/xAAZAQEAAwEBAAAAAAAAAAAAAAAAAQIDBAX/xAAnEQEBAAICAgIBAgcAAAAAAAAAAQIRAyExQRJRMiJhBBNCcZHB8P/aAAwDAQACEQMRAD8A6zlTpSpFKyiNIpTpFII0ilKkUiUKRSnSKRCFIpTpKkEKRSnSqxD8rbGtEfK9VCTKofi2DQuG5HqN/ktf5g5m+ztlcCHsADQb0LnC7ae8dQfQ9Fz3Gc4vdAyP78d6jfUkk2b6n6KmWemmOG3ZGzNJoEHroR0JH6FT0XFuGc2SQ4d3Z0XNa7X71uGt/iJNG/Bb3h+Nsgw8FPzsyMzm7db2AyO882/naTMvHY26kqUMDjGzRskYQWuFivyV9LRkqpIhWZUiFIqLUiFZSRaoFJCRCtIUSEFRCiWq0hRIQVFqgWq8tUS1ShQWKstXoLVGkSzdJ0pUilCUaTpSpFKBGkUpUikEaRSlSKQRpKlOlF7qBJ0A1QRcta575njwOFdmd+3kFRMGri4EHNXRrTRJ9Oq8POXPUcDWsie1zz7zqOgH3QT4nXyC4zxnFyYmd75JHSvNDM49wHwjo3wHeq2+mmOHt7puMPmZb3W0lzyB8Id4DuFLAYnEErI49+RjIma0Ghx8dyse3Ck616Kk01sr18Nxfu11/RZpuLIaCw2B02Ow6m73KwOG4c8H4TrsFlMLwyS6H9hVti+OOVbLyfzi7BFwzdpE7V0ZBBYb+Jvf10G665w7GsmjD45BK065h1sA+m+y+f8AHcLkYA7K4gb9a8uqyfKfM8mGeKccl5XN+6b667OG/jSvjl9M+Tj+3dqSIWP4BxhuKjL29Dl8DosnS0c9mlRakQrCEiFKFRCRarC1RIUiohItVpCiWoKiFEhWkKJCCotUSFcQo0gzFJ0mhVWKkUpIpAqRSdIpBGkUpUikEaWu87cxDBYZ7y0vJGUNAFHN0JvRbJS4D7RuYX4vGye8exiJZG0E5RrRfW2Ym9fJRVsZutZe6TFShjRrsBewvqt04RycxrRfvP6k7elry8o8KppkrV3XuHct0w7KpcPJnd6j0ePCSbvliouR4jZdqT9FkoeS4RVN+iy+GGgXuhIBVZurW6YT/CMO+QWrTwKJo/ywfO1nnV3qmSlNxROStdm4SwWAND0/5Wic08tmImaMabkDT19F03EBY7FwB4LSqY5XC9L5T5TVahyLzk7CuyyEOjedSda6WfJdmgkzta4EEEAgg2CD1C+d+NcMOHnc1ugJsd1HcLqfsl4g+TDSwvNiJwy+AcNR87+a9DHLbzeTDTeKSIVlKNLRirISLVYQlSIVFqiQrSEiEFRCiWq0tUSFIqIUS1WkKNIMrSdITpVWJCdJ0ginSdIQKkUpIQRpfOvM3D8uIma1paHTu37g4619fKl9GLlvG+X+0x2c6i36aVmLzfjs4f8AaqZ+GnH5VYDAdjBCPDX+I6r2Q/Re7HQfsXDuoj5BY/Dv6Lg5JqvQ47uMnA46L2Mda82Fo7rIwxCr6qcezK6NjLSfCe9W3VKTlppn8qx00ax8zNQspiXWsfKNR3LDLy1lavznwsPi7RvxN19F7PZNiaxEkewkizdazMcL176cCs5Pgu0icKuwVhOUo/s/EsLF39oz07J1evT0XVxWzpzcurHT6SpTpKl1OJAhIhTSIQVkJUrCFEhEKyEiFYQokIKiFGlaQokKUsinSE1CQhCFAEJoRJITQpCWquObG4gVYjoE9LcMwH1Wy4vFshY6SV4jY3dztgtX41xJsM0eIZLE7DTkNe5rrILR8WmmUDfuVbpaSpYmPM5g6V6brXnBkbnAmqJHkFkOJ8cZHHPIHA5G03K4G3E0NvFc7kxhc9xmec7jeRu/+wC5eWbdnB15bh/iSFhNyBe3C8xscRTwubYiCM29pa/XLTcQ3tAauq7Mgmulrx/bcp9wuBGmV9Bw9QaKpMPpvue3ZGcUBF2sfjeZo2AkuCxvBqkgBN3lBu29R4laDxPGntZGg3lcW9QNDubUTdNSN6/xn2hqNjnd5AcR9AvS3jWUgyAhpI1oivmFoGFx0cYIlbJK/LbR2r4Wk9zA0HMeutBZP/5Ux5Q1rwHC8jy14LT1Y8AG/AhTlx+yZS9OrYDKQDdgiwfosNHC13GcOxjS7swZHOAJaD2b/vVQ+IdeqwXDcb2kboWuMWe8ktuc+Pb4Gn3Xb9dvFZfi+Gdg54Z45DHA+Hs5ACRmLGl1106m/Na45TW3Llhflr7b+yZri4Nc1xbuAQSL2sDZSXMvZ3xOWXiUhkJZG+F+WPSrD2uaT3uy5tfFdOW3Hn85tlz8P8rL4/ttGkiFNKlowQISIU6UaRCBCRCmQkQgrISpTIUaRD3IQmoXCEIUgQmhAIQhBpXtYxMseBjdDIWftg19AEOYWOGU30ulo/IUjH4qpGAOui3+U28Eb7Vqumc+cO7fAyD8JEnoNCfS1yLDA4XiELhdZy3N1c0kiz3WuXO65P8AD0eLGZ8Gp57/ANPTzRgOxkMDHyTMsuaZcjng3ZogDTdYGHhxlLpC9rPeALCDbhV6EbC+i6JzBh2vyOOjr0P5enT1K13E8H9+x7l7gnT0OxVMstZIwksjD4HlnM8Znjsw7PlGYgnvogAGtLJVvFeAxtjkewOc7xIEbbP6eC2DC8JJ0L9O5pLj8m2pcZwVMa0tytu8pqyQN3foPHXXaLna1mGM6jZ+U3tGCjawe61gbXeAOveVp0vL0QmxAe3Oxzy5gqsmYEkWfiI0rurzW28qwlsJaPwql8Xvua8Ag/36Kt3pEmsq12fl2F2VxBsUNHkbDqCD+aubhmWA2MED1s7dVsI4MNw6x+8LI9QRahJhGjy65RlJ8Lux6UotuvKZrfUY12CDcoaBTRl02L3EFwHlTR5kjosjzxiAzh+HvUiRrSPB2hH1+i8804zsAFAEaDYAeCs4vxBr8VBC5uZvvOrcW6NwHXvTD8ares8d/Z8sYb/qcNK0b1t3EEH8l0Janyphw+YvaPdhZ2YPQvsg15W4ei26l1fw81i5/wCMy+Wf9oilSkkt3GikpUkgiQokKZCVIIJUpEJUg9SaEIkJoQgEUhCAQhCIKSMOBa4ZmkFpB2IIogriXM/BXwYt8BuomPnjeQ454mtLmtDvxaZfMLty1/nfhva4OWRjC+aJjnsDRbzQvKANTrRrwWXJjubdPByXC6+3NpuIOmw4J+JoF+IHX++5Lh3FCS1pKXBZGvZEd7zwv0N20VlPiF43YbsjJ4HRc+eO+3Vx5avxbjheIgClg+N46Mu/aHQAkNHU7C/ALyQ47TRYTmuGw2t+u9/MbLPGd6dF1Jt0LlrjsfZ1YNCl4+I8aiM2UuPU2Nmnp5rmXD8XJE0tzEjbc35X1V0GCfPO1ziTqBqXZQO4Dy6rS4ssbLduuYXiFtFaqvFYixoFF8Aa0FmgoDTovBLN0WNrSSKWOzSt815sY+8cw7ZdMwHc2638F7sFFbr2Wa4By3HPNLJK3MwBtCyAT1JrcLTDG3qOfkzku62bgWGDYWv6yAPPy0H6+qyKGtAAAFAaADYAdELtk1NODK/K7KkqUkirKopUpJIhFKlJJBFIhSKSD0IQhEmhCEAhCEQE0IRIQhChDWeeMFbI5wNWHKT+646fUfVc54tH7zq2IXZcdgxNFJE74XtLT3i9iPEGj6Lj3HYjE50b9HscWHoNP6iiPNY8kdHDkxTTkIJ2Xi4liw67IAHer67RoHXZY3GcHFixm8Suaa329Dyrie3bN4rPcHxEbdc7b7jofqsNDwGJ24yn92xfgslByvCRs71e/UeVq2Vx+15hGxt46NG3ptujt7s9FjYuW4qGVvZkbFun/Kte7swW3t9VhuXwjwyWDxNfNb/ypERh+0P+oS4fwjQH11Pquc8Bw32nEwRfde/Wt8rQXOr0B+a68yMNAa0U0AAAbAAaBdfDj7cHPl6NCaS6XKEk0kCISUlEhAklJJSIpKSSIXJpJokIQhAJpIQNCEIgIQhALmvtWwAEkcw++3I+uhHwOP5eS3Hm/mRvDcFPin0XNaRG0ms8h0Y31cRZ6C1y6NskvBY8RM4y4jEPfi5Xak/tXVGQO4MawV0F9yrnjvFfC6rWIJyDTtDdHzWUZAZK71rzpDfiNPMLI4HilV3jcdf9wuPLHfcejhlrqs7BwNxO9LJwcHLfvBYtnMHu0DqoQ8xENp5s+GyysrXbK4lhYND0Wu8QxmtfVLG8dLvLu71i3uMhs/7K2GGu6pllvqN19muIzY3tSKY0dmB3ZqBPnquwLlPs6wNU8j3C41+9lNH06LZOTOZB9pxvCpXXLhpSISd3wOaJGN82B4HkB4rt4p+l5/N+Tckk0ldkEIQgSEIQRSTSUoJJNJBcE0k0SEIQgE0k0AhChNO2Npe9wYwalziA0DxJRCaxPM3NEHDYDPiH0NmMFGWV/RjG9T47DckBaNzZ7bIos0XD2faJNu2dphwf3R8Unf0b4rkmK4rLi5ziMVM+d4FlzzsPwtaPdYNtAAFfHHflOmV575ul4g8Ol90E5mxA2yKMfCPFx3J/QBbZyvic+BgicdBEIx5N1Z9DXouWYiYve5x6/wB0ui8lvzQQMOnu6ehI/MFWy7W0x/EODkh0jBq3SRg3Hc9o6jvCwmXVdJx3CnipoxbhuOhFajx0+nksDxPgjZwXxjs5eo+67TZ373c7qB3hcuWG+42xz9VrTQVZ2aoOIMTyyQUR/d+I8U5OIt6brCyt5U+qz3L3AnYpxr3Y2kB7+g0stHe6vlv50cs8syY17XH3IN3O+87wZ4b2fla6lhOFNjYyGJoYwbDoBuSe8ncny7lphx77vhnnya6nkuFxNiBcBkiY3IwdzW/rr8yuSca406HjeInBLT2jWkjQ/wCSwb940+S6/jwBTOjdT+g/vvK4LzHL2mNxb/xSuPypv6Lrw+3O7xyrz/HiKgxD2sn2a46MlHSugd4denctwXzHw2ftIsp+Junp0Ky3COfsbgXARzmSMf6ctyR79L95p8jWuytcJe4rp9CoXN+C+2yCSm4qB8Dur4/2sXqPjHoCt74ZxmDFNz4eZkw/ccCR5jcLO42eUPYhNJVCSTSUoJJNJBahCESaEiaBJNAaknQD1Wr8e9pOCwYdcv2iQf6cNPN9xdeUepUybG0rzcR4pFhmGTETMhZ3vcGj0vdcY497Z8VOHNw7W4NpsAtPaS10OdwoH+X1WgYvGulkMsr3SyHd73OfIfDM7WvDZW+P2nTsHMntvjjJjwMJndsZZLZEOnut+J/rQ8SuW8d5nxOPfnxU7pe5llsDP4Yhp6mz4rFF6rEutH0/orTUTpY8ql89NyjqbPpt/VN8q8zgiVkOq61yNwsS8Kw8rdHxvnaSPDEP/Qt+RXJcPuu1exvEB2Bni/BO7T+ONrvrr81XIZvB4nLo8aH+u48jr808TwJpdnYPddvXz0+hCyLsGLcz1/3/ACK0DnDnjK88Ph/y2ktnlHU9YmV0H3j413ql67hO+kOZMHh5XGNjWzvHxOGYBvQlrmiyfAaA9VheDcv4ZslPbNO7MKa1ji3S8wdsBrW/is3wOCPEV2W5GaiQKa3Ld+pW4cOhELczmRushtFpIBYXDRw2B8ugXNbbd1t4mou5blqNrJomxS/CA03G4hoOUaCjqLHdse7LSzdmwu3J2/T+vp4rjnFuK4iSd/ZyvawNy2CW/BVuB6EloHiQAuhcn8zHiDCydvZ4uAASM0p91llaPwnqOhaRrut8e4yymu3sdhHPIBO5zO8hqfyK4BjX5pp3d8steXaur6L6UkeI45pTsxj3ejWE/oPmvmOBxLWuOpIzHzOpWuKsXwTljg5u/wBCO4r0zTBxDh8uoXhTa+tldK+VWYbHuYQ5rnMeNnsc5jx5OaQV5JH5ulItTsdB4L7W8ZAA2RzcW3/9RUnlnb+oJW7cH9seFmOXEMkwjtBZqSE/zN1H8zQuEh6k2UprG+ldPqjAcTixDc8ErJm97HB3zrZehfKsGKLHCRjnRvGz2OcyQeT2kELc+De1zGwU1724to6TCn+A7Rv6gqnw+kad2SWkcue1vDYyWKB8cmFlfTRnyOhMlfC2Rpuu4ua29Oq3cqllnlC1aF7Q/aUeHOGHw7GyYgjM5z7LIwRoMo+J3qAPot6fIGguOgaC4+QFlfLvMPFnYrEvxDvikcX+V7D0FD0VsJ7qY9fH+d8Tjie3mc9p+4NIh/IND62sC7EEqtACttfSWYphIJoFaTxog9D6IfsgrfqoEqZUCoE8Puuq+xrE/wD3oxuOxl+eZt/+I+i5TCdVvvsokeeIPgjcI+2geHO6hrHtJLR1fTnV0F3rVJ6RXS+JY04mcYPDOLXVc8rdom6e4Dt2hB9B5hYvjPs5jbhqgvMw5gNCbyHbv8lueE4cyABsbco6ndxOWyXHqTvani8S2KKWV+jGNL3eTQVSdVG3BuBYZ32qKNlnMRnbWjf2gDm1ppemp7l0zjfFI4YZnOJrLlbl6ENc0igdPerodlg+T8QyYzYgRND5HAvJ1fq7M2MC8oFkdNa1KxPM/C2RcQZiG4cFuhlYSxzHte4x3TSQfA3pS5rd9xvr1Wb5E5S7aNk89lo+FulOcScxPhdUto4nyUwuZiMM84fFR2WSDUG2i2uB3Yaoj9aK9fLEzfs7YQ7NlFtNVmjLvdPmLo+NHqsvOfd+Q+YW+PjpjlbtpXMHMgPC+JxSDsMXHhpQ6M6WHNyiSI/eYbb5XquGgUAu6e2GGMcLlkcwGQOiYx1e8M0wBo+VrhhWmHgJRtNRpXSadqIKY3QNAStCgStFqNpWgtjmILSDRDgdNwdKI8V9N8r8W+14PDzn4y0Nf/G3R31F+q+XM3xeYXafZLzPGyDEQSuDcjmSNvapGkED1Yfml7xVyb1zljOx4bjpOoheB5ublH5r5kxB94eS+gvaxisnCpgN3vij9C8E/QFfPeIPvlMfxIrKVoedUgVCyaSSkpAQo5rCkSq+p+aBFQcpqL1AI1t3s4xPZ8Y4c66DnviPiJIJGgH+bKfRahGszwLFdlisHIPuzwn0MrQfoSg+mm6n0/8AVab7UOLGDAOiYSJMRIIBXRgOeQ+rW5f51ubPi/vuXNPaRiGyY6KFxrsmB4F0C+R3lqab9VlkjDy9XL+BZhsLFTrLm9octZg5uUiqJ6nQV0TxPCftEmZzi5r4zG4nKHe+MzSGhoHukA66r38PjaIWMf8ADmFllk0AaurO9XSpfgyJmvjzdnmboS5ttreiASAehC59zW74+mvv92I5RxMzHzYad5bJCS+N1Gs/VpDWkljheg710HB8QbiYIpWfC7p1a5pLXNPcQQR6LBsiaJjNqXUc597KANhRAG9VV76lWctfs5J4rJDnCf3tHZ8oa85aFWAw6CrtaYWzqqZavbEe22WuGsb+KeP/AMSXLiRK697dpv8Ap8Azvnc70EB/UrkBXTj4VgSKaFZJJBDkIGkhFoESolyZVTiqgHwu81l8PbmNLXFulGuqw7fgPmvfwzE00hWxvaK7d7apSMFhm9HYjX0heQuF4g++UIT+mIxVSFIFCFCyTVNCEEbUH9PkhCACUiEKBCNeiY1G8g0QCQRuCBYKEIPqThkuaOFx3dGx3zauTc2/tOL4q9swbrrWWNrRXy+qELDkW4/Le8NIJMoa3s6ZVjLdkij8PTXe91ViMSI3ODmCTM0USG2KLxvXWwdK2QhW1Jza/wC8M5f0bXtiJj1ccxaGXrQrqG3vZ+gVWBlJx7Sa1a9umbai7qT1QhcfHld6b2NJ9uWIJxPD4/uiGWT1c9jdvJv1XNShC9HHwxJCEKyS6oCEIGVBCFARVLyhCgH3B6oidVoQg//Z
+
+
+
+ John Doe
+
+
+ Grand-Rosière
+ +3282823500
+ jod@openerp.com
+ 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
+
+
+
+ João Gomer
+
+
+ Auderghem
+ +3282823500
+ jog@openerp.com
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBhQSERUUEhQUFBQUFBQUEhYUFBUVFBQUFBQVFRQUFBQXHCYeFxkjGRQUHy8gIycpLCwsFR4xNTAqNSYrLCkBCQoKDgwOFA8PFCkYFBgpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKf/AABEIAOEA4QMBIgACEQEDEQH/xAAcAAABBQEBAQAAAAAAAAAAAAAFAgMEBgcAAQj/xABEEAABAwEFBQQHBQcCBgMAAAABAAIDEQQFEiExBkFRYXETIoGRBzJCobHB8CNSctHhFDM0YnOy8VOCJHSSorPSFRY1/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAECA//EABoRAQEBAAMBAAAAAAAAAAAAAAABESExQQL/2gAMAwEAAhEDEQA/AMgDk3IEu1RFjy3gSEklRTZTjCkvC9YqFPYmAM1LYm5I1BJs6mWeCtSd1ANNTkKZiuoyUaxRVUmWU5YdzqV8Kb9+agnQWhjAe1NaHDQOAw0rrQ5tO413cNW226smXZPDW0bUOALQK65ZiuR+jEhstS5jzWjHOYanC7WhNRxrr03KQ+zOYwYgQ4tyrua7QdMJHmimxbQ6TQYQCAKbwQQacKZLsdBT2n148ak/XFMMZQV5ZeJrXyCkGpIcRUuFGtA3HdThv8d+4hGLvAClARpx4fBPRQ6l3HjvOvyUyz3UaVeQOAB3HfkDTEQadNydNlLnhrfVpU1BrQby0EnXSuqCAxmXrOI0aK1A45JyMZEUpmpcNjzIcHDeBTvUHLIe/fvSobOHGu4ZGuo8v0RUV9gaRUa8tPJCZbJ3s8yflorTPEB3WgkZAchz96h3ld1DUClKct2aCrvj3FT7gi+08UzbICD5fBENm3AyAHU6K+Iu4b3PBArwjyKtEcfdQW8odVGjWz9q7tFVtsZKzKfZbZ2biOaB39PjkqrEDAn4nJhLYURN3KHaWb1KickzMQD1yd7Bcgsm213dnOSNHKuBy0z0h3bijxgZhZikKkOzCSxcw5LzeqH2FOltUywp5qgn2SznB1zTwyINAQ0Oy0zcNfMinROMZ3W1+6CnLIwuq0by3XLIbvMqKZu1oeyVxriLTHGDpR1MZ03Z+aebGTGKnNjcDq5ggnKh5An6KmXXdTgXNGmnhUVpw0CMturuYaDWvx/NFVMSsFARyaB7VTlQHTVeut4aaNpiFQc8geFRrT5oza9nTWrR04+aHjZZ59gnPdoiYbstsdTNzTqRqddx7wyPFS7GO8SXULszQg58RrT3ohd2x73ADAeVa5K02H0elwGIAHLP9ApqyKoLNjBaQDnUl2uXkPciN1XTjdm1rmt41rTdodPBXu7vR81o7xqegFRwyR+x7NRx+qKKauK7YtkWjMnXQZHLhXVe3rsix7QGjTwVtNnDcgmntU1rGHbUbJOhccss8x5hVKzOMUrXcCPivoi/buEsbsqmnmsK2msHZyEbqlajFmNAsfeblvFUNvOFP7KT44Gfhp4jJO3rGis4vvuuQO0SVKsW1EearDlph4EtqQEsIJETk+cwozE/G5AnCuTq5Brd7RCWIjiFjV4WYxyOadxWv3dacTeoWf7c3fhlxgZFSLVcjKU8JppTx0WkLYU80qNGU+wqCyywd1uvqg5cKDJELosh7RulA8VHEDeD9ahOMs1WsplVjRpXMjT4KWI3CjM2ihBGYzO/hWjWjxWWljuqwB9ab9CaVyXGKh6KfsvZ6truAHWhIrTw+CXfliwSZaHTyz96jSNZoQdUdsFnaKZDyQKyOzCsFjUBOOEcApVnTEBT7BRGkthzUoRqPEFLaoiNLGoczERlCizR1RYGOWQbf3fSVxHGvmthnbQrOPSBZ8zz+vzWoz9A+w1oqwt+6T780bvNmSrWxvdke3oflVWq8G5Ksxnu1MWSpjlftpou6VQX6rUSkhLCQltREiMJYSI0qqBeNeptcgu+xt6YowCc25KXtjYe0gJGozVL2Ut+CWh0ctGmIfERyUrTH0/Gck5etl7OVzeeSZiKrJQ1T7CmnBLjQa3YLOHwxuwkYGNrhHEjPmO9TPRKtUZJa5xaKEOI3BobWm4Cppv1J4KXs9ERHF3qtoKivABw6mu7mkXrBXOhJLTkRU1AyI3Aku8ATwWWxrZm21LQaYaAdQKg7t5y96l7UHutdSnHn935+/VArktFHhpBGQwgihpkAPKv6KxX7ZcUeM6NzNNc6DpzUXwFu9qO2YKtWGXNWOzPSkFbKKfJTI0PiloFMglqo0mxyKTHIoTU/HIoJDkzIxemYDMlDrVfTAcINTTcgTalnO3BdiApqQB40qOv5q9OvJrsjkVXtr7AHwlw1bQj68VqJWe7PPwzkfWRVxtgq1UO7JKWgcyRzV8kNWDoqzFO2gjqwrOJx3itQvqOrSs0traPPVWM1GS2pCW1aQ/GlJLEpoUHtFyXgXqCBDLhcCNxqtQuW2CSIHiFlhCuGxV4ZFh1GY6JViNtlY6ODx0PyVcjK0HaWx42HmKjqFntKFIVJOi9jK8YckW2c2Zltj3tiApGwySOdk1rQaZ9TQIjTbpm+ziLS2roq0dQ5dzKu72ffwSrY4BjczWUk1zyGEFuQ1GhHMkpi4Q0xiLEHPbHRwFSRhqG0yGQ39U/AXSuwEjuPDAa9W7qV0A6jrXDYtcN0l/ezyz4EU06f4Vk2hoyyVJpTw4DJEjZ2wRAAVyG7p+QWaekPacvHYxZgFtTXIU1FBzT1fA520IY7u6e/wDyp9j29YMn+6qqlgu9oGOd1G665nwSrbeFgJDWwvJJDQ7EGipNAauNAOdVcZ1o1i2zs8lAHUPPJE7JerT6pBHJY4+4nMZ2oY4REkAmhzBIILmEitQdcuaK7O3g5rmgE016hTF1s8U1Qh953+2H1tdymXO7E3wUG/Lrxtc5gq8Cjepy1UbUq+9pp53YWVZTeSRTPgNB1SrvuZ1A6S1VOvdyArz/ADoh1+bEvkaD3nPocQqO6TvaCaIzs3siaPdaG4nubGyPAQ14wNw4yY6YTp13qscpUt3yAVa/GOozoKUy3KZZXulspa4Udhc01BA30pXdml3bsvJESXSFzXatdQnLeXDU80VngDW5UCi4yHZ+7hJaHF3dayrnHcKcfNXFnqZablBuW7gJrY0j2qj8LqkZbwiBFC8cHFVFdvRmRWZXuykhWqXizVZntCykhWozQlLakJxi0h0JyMZpqqfgGaB/AvU7hXKAEVNuS29lM07q0PRRKJNFRqkzccWW5Zze9mwSngcwrlsleXaRhp1bkfkhW193U7w3GvgszharkLlbNjrwfFFasDsJLYcX8zcbgWniO8FT4irFsxPR0rP9SB48WFsgp/0FVIul2TYJWSsdTH6za+sN4r4KxXJYSbS0DPE5rjllhpUUOmtVVL4kbG2zM9Uss8bnU1xvrLU86PHkFedgrwbPgmz7pLQOB3j8uvisVuLTtTMWxvI3A0/RYu6yOLi6lc9+a2y+4u0hfmKYT9Z66LPIrKNKfJIWKu243PdilqWjRtaCm5EmbKxyuHrtzGRaxwrxrUK0susOUuy3WGpaYd/+NjFlbBpGBSgPeNakknmTXJU+0XO2EjAKAE0BNaAnSquk9AOAVavSSp+CQq47NT1Y3oizHUKqmy9pyAKswdmo1DpsIca/qnIYaZZeS6zSqQ4Z1UUxK1C7Y3VG5m1GSDWzQoK/ZrEO0kdveAP+nihkTqyS/jKO2cEVduqfE6UVWui045JCN73fFVg1eMazPaqOj1q15RrNNsIs1qJVWolxpFU5GVtksqVZRmopU2yBQS6LkpcgryVhSVLsrK5IJOzt4dlMODsj8le75sglhqOCoFqu8tzCumyl59rFgdqMiosZ/NEWPLTuKn3TauzljedA4Yvwnuu9xKm7W3b2cmIaFBYyr2i47Vk9sDuMcfTusa0+8Far6PJImXe1kYq4/aSHKuNxcKjkA0DwWYXDO20shZKMXfbE8jN7SSA1wG8EbuIKuGyM/YWuazEUYWuDK6gscDTrQkrNai8S2yjXCuXSniOKrNoFQ5wFA0/PIDwoEQtE27d9ZodJLhgcePHdVRpMu+atEaipSqqN12xG23hRuqgYvy8RE0kqtR2gPGJx10UfayR8gyPgqpIJC3AXuFN4yPuWpErStnrc0S0JVztFvY1uJxDWgVJJAAHMnRYhdVpcwgdo4kbzUnzWoXNGJ4R2wxUzAcMhwNOKlWUajtIlaHREOH3gajlmkwX4WnBJk7nv6JVmjbG0NYA1g0Ay/wApFusrZBRwG+h3g8lGk02+oyKh2iWqDQzuY8xk14dESJyRNDr0t3ZWV76Z98N/E40HxVJ2Sm7xRvau+BhMA1qXO5A5gdVWNmpaSkc1Watt4NyWc7YwZVWkWrMKjbXR1YVYVndEppXjguC0wdaiFlQ9iI2ZBJXLqrxABUmxuoUz2SdhjIKC2WaAPZQqBA11mmDh6pyKlXRLkiVqswkGain77sonhqNaVCzsswkg7ir7dE5aDG7dp0Vd2ou7C/G3Q68irCodyXq6zzNkaKgEYmnRwBrQ+S0KS2s/aGWmI1je4PGeYr6wPPWoWXNKIWK9HxigNW64TpXiOBUsSNznflXX61Qa9p6RYep9/wCqnWCTHZoX7nxRu82itOhqPBBb3f3qHT86LLby6HEotNPTqh+zpGY4IxJd5J5HNUV62vBOZTMdijdqRXzQraWzWmOVxazFHXVpJI5FoU/Z67JZmtLXhtZMDhTMc0RZ7nu+zNFXAk/hNFbbOYWNDmNNSKcPNA7o2QmL3NfLhpTCQ0UIIqCa+Sst27NNbEDM9znV71ThbTF6tBuUagba72azNxaNdXAIQNpRO/BZftXDN9D3WjTN+nvViva7LO9jo2xtIJcSaDulwoS0nfw4JOzVyQ2aLDC0NaMuZpxOpPNRUWGMvwl7cLhrv96cmNBRTrXkckNl48kGc7QyVtknLCPJoQu634Z/FKt1pxWh7/vPcR0rl7lHLsMwK0wvsjqt8FU9po6xlWOCarB0QO/21YUVlsmpSQnLQO8eqbWmDsaI2dD4kRgQSF4vVyAJHNRErJamnVCSuBQXOxFu4omxUOz25zd6NWK/dxUXRq0MzDhqE3bSJGGu/I8ilxWkOCblbToUVTLRFgcR5JIkRe+LAaYhu+CDYVWa2vYm0dpdlnO9hliP+2RxHuKg7QR6FM+i60YrBKz7loqP98bT8WnzRK9LPiaeOf8AhYb8V6xW0seCtBuy8GmOp0NM1mcjaHojtz284C2vRWpB23nMlvFN2S34aAgEA60zr+ajx2upoeGa9lsbjmytfioq12S8MZDhI4GgFMQAoMxkRzKLxAuFHyYm60JrXkqBAJgMyARyCOWCJ7vWkca8O6oso9OAcmmnFS4BRvgolhsjW0JJ+uKmSvRpFtIqgN/Wrs4nO0yNOpyHvKOTv1Wf7aXrie2Jp07z+u4fE+SJVPnyckW05tKXbhoVHtr+6Ftha7rtFYwmL3FWFRbgnqxTLc2rSgy63tpI7qo6m3uykpUIKsn4URhQ6BEYkD65IxL1ACXL0heIOS2OSF6EBWw3kWo3FbA8KogqTBaSN6C2RMDxQ6jVVq9buML6eyc2/kiV3XjRwPmrRa7nbaYctSKtPAqL2b9FDzgtbN2GJ/iC5vzVimtgB72mjuvFRfRtsjNAy0vmAbjjaxrK9+mMnG4bgaZDVRb0loSOoKnqzoze1iocQ0Kg2aXCapUN4lmR7zDqD8l5LCCMTDVutN46hAVhmxEZ/qrVclpacjrp4Kgwz0+Sn2W+sJ1RWguDa+qDUaqZDHQfqqvYr9Yad6njUIqy/m0pXQ6/D65LOLqxRsy1+gkPeAq6dpWn2+GhUS07Ql9GR58+KLo1aLWXHC3U68hvJWW3q7/iJd/2jx4BxA+C1C7LKWtq71jmT8llN5y1mk5vef8AuKsZpFrbVqGWx3cRXVqE2sd0hVEzZi3jRWedtWnosxsltMb6jirxdV9h7KE7lUlUq/2UlKGBGdpf3lQgyqH4EQjKgQKa05IF4l4msS5APK8XpXiDgvV4lIOXBdRKAVQ7BNQrS/RlaMcjmu9RjMee4kho95qswAWl+hWzF01pJFWCANPCrnggHnRrvJZrU7TbFf8ANY7bM20EmCfJj9QCKlp65kEcFFv6jnYm5g8FZr2sTY6tlaH2d2QJz7M7g7l/NuVUvq4ZIe9HWSHXLNzR4esOf+VFoS51VHMpaag0XPn3hNvNQqJsN4g+sM/JShgdqgSehlciDkcDRo9OOH83vQ+zwOcjVhuquuaim7JZMZyq7zorzcFxYBiIzovLgu1rRorBQAZKVqQilAVhF5T/AGjvxO+JW7E5FYt6Qbm/ZbSQw4opR2sDjva40c082uqEifRmxWiqYvRlAhdgttHIneFoDmLTKrSjMqVY7UW6KPJquaqhy3TYjUqGnpE0gehUmuSjQp9xQeYlybqvUEUrxekrxB6lJAKUECwlAJATrQqh6OznAX034W9aVJ+uK130MGM3faGVwyumxV0dhDQGEdCHeaz28LH2dnYz2gMTvxOzNemQ8ET2Dtrg6kZAkbUhtadozUtrucNyzWpxWmTWoucYpQMedPuyt3lvnmNyGmyvg/djHFvj9pvOM7x/KicccdqjzqaHo+N497XApNXw5T96PQTDdwErfZ/EMuiy2BWnZaC1jtITgdvLRv4PZx8jzVZvLZC0QZvZiZ99mbf9w1b4rTJbhDndpE7s5KZPZmHDcHt0eFKsl6mIhlpaGE5NkbUwu8fYPJ3gSmmMis90FyKWe5aUqKLVrRslZ5s2tEbjmHR0oeZbofBCLXs1JDqMbPvNFaD+Yat+HNNTFUs9gpTLyROGzDh5DeijbE0jLgnf2McfdmmrhF3Sbq+CK9rXRA5bAa1D1PsjaZVqVFifhyp9VVM9J91Ca7mTNp3Zg5nCknckA5FwY5XJ0oa0k5UFfJDtpLrfJcQbho8QiXDya5shHXCrE+nz2+FzdxSjajSiIpp8LTqFtzC1ymvu8bj5piSyOG6vRAwQmSnyEyQgdhTr0iFqXIgbquXLkDb7I4bimzGeC0ea52ncoM1yN4IuKLhXoCtr7ibwTX/14JqYrbAi9yWYA9o7Rh7o4u/Ia+SkWi5Gx+sact6amtIwhrRQAUp47+f5qBd4W4vrU1UCy2h0bg5hLXNNWkZEHqvTmu7NBq2yF/NtnqubFbGtzBHctDRxbvNNaZjdkrrd94B5MUrezloasdSjhxYdHtP0F89WaUscHNJa5pBa4GhBGhBGhWx7HbUw3jG2z2ugtLfUd6pkpo+Nw9WTiBrqN4GbG5VjF0PhqbMcq1MLj3Dx7N2sZ9ymWO2MlrG5pY+neikAxU6aOGmYqkME1mykxTRf6jR9qz8bB645jPkib7JDaYwThe3VrmnvNPFrhm0qNB8dxPhOKzPoNexkJMR/AczH4ZckSu+9MTsEjXRSfcfTvccDgaP3/km29tBrWeMe0B9s3qPbHMZqbH2NpZ7Mjee48xq13kUTTdruFju80BrjqPYd1A0PMIRNclahndeMyxxzPNjvaHkjbIpIdCZY+Bp2jRyPtjlqn+5M3I1ociMnMd8Wlaxjapb4i00cDUcdfelRszVntlkDspRXc2VozHJ43fDoq9fL47JR08rWRkEh+tQKaNGZ1b5hSxqV7LYDIx4/lz8SGgePyVslhBwsplgcKbqUa2nvWeR+lO72NayN7nDG10hcxzC6mfdypuGRIyGqul2bQQ2iQdm/Ps64T3XCpaaUO+gqrIlfPO11yfsdslhp3K44ucT+8zyGXghDmbwtc9NuzmKCK1NHehpHL/Tc6jXeDv71kNnmqqy8XoKdc1JLFQlzQdRVR33cw8uik0XqCGLvpofNNTWV3CqIpTUAXsDwK5HKLkVIs+1fFEob9Y/VZ/iTjJiEw1pETmO0KavK1shbxefVb8zyVUux0lA4khvsje7py5p+2zUqSakjX5KYag2+2Oc41NTv/JM2c508R8/kmwvXDeNRmqiX2a7AnGZgGiVRAgBPwvoQQSCCCCDQgjMEEaFM4Vzn0Hu+vBBuPo49I7bU0QWkgTjJjjkJgPg/lvVxtFzUcZIXGKQ60zY/+ozQ9Rn1ovl6GYtI5LWtgvSdJ3YZ/tNzSTR/IBxyPQ+azY1K0eC98LgydnZOPqmtY3/gfu6GhT892Nc7GwmOT7zMq8ntOTx180qG0xWhhGTho9jhmOTmHMFRxYZIP3Jxs/0nE5f03nToclFPx3i5hwzgNO54zjd46tPIqRNZATiacL/vDfycPaCTZbcyUEUIIyex4o4cnNO73JH7I6POI1bvjJ0/A7d0OS2wV+3YP31Ga96vcI44vZ8Viu3e0kNpnc3ssUcZIaC97QTvOFrxTOqs3pT2z+z/AGWB4jkdTtsdQWjItjyB19Y03AfeWORXY6o/4hlSeEpPPPCosWO64bKQ6V8D4xGTQiR7mktGJxLXucHBoplvLmDeQoIvKk3a2aZ2IAkA1D2a1IPtEak0HGh3GZLpE1mbCyePEAMXdkzAJcTk0+s7P8McaEO2InicJGuikDSHENc8HI6d9rQamgyO9BsOyu0DLysboLTQyua6OZugeHAnGymgNK8lhm0NyPsNqkgfngPdP32HNrvEe8FaXd+z9qi7C1WNmOgDg2oxOY7VjweIyrxHJS/SNswbxskdrs7a2iFpEkdKPLNXsLdcTDu5lRWSxPqvHBRo3FpoagjipbjUVCrJAevSmnE7x5FOMcqPV4vV4oPcRXJK9QVxet3dR8Vy5UWmb1m9Gf2hQb318T8ly5BBCUfryXLkEizeqE8Fy5B4dV5JoOvyXLkDe5Trp/et6t/uXLkJ2+g7v/i4v6Df7Wq1NXLlhuhF4/xUPT/2Rp35rly1GK+YPSH/APpWv/mJPkqzY/33+1/9pXLkU4P4g9fyVtuD91aOsX/htK5cpVjavR9/AWP+i74lTLq/jbT1b/axcuQr5x2l/i5v6knxTMOi5cqkckb1y5ELXhXLkHi5cuQf/9k=
+
+
+
+ Juan Gomez
+
+
+ Grand-Rosière
+ +3282823500
+ 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
+
+
+
+ Luigi Roni
+
+
+ Auderghem
+ +3282823500
+ lur@openerp.com
+ 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
+
+
+
+ Николай Петра
+
+
+ Grand-Rosière
+ +3282823500
+ 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
+
+
+
+ 佐藤さくら (demo_ja_JP)
+
+
+ Grand-Rosière
+ +3282823500
+ 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
+
+
+
+ 趙生 (demo_zh_CN)
+
+
+ Auderghem
+ +3282823500
+ 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
+
diff --git a/addons/hr/hr_department.py b/addons/hr/hr_department.py
index 185e9f73a45..dded3241b91 100644
--- a/addons/hr/hr_department.py
+++ b/addons/hr/hr_department.py
@@ -79,7 +79,6 @@ class hr_department(osv.osv):
(_check_recursion, 'Error! You cannot create recursive departments.', ['parent_id'])
]
-hr_department()
class ir_action_window(osv.osv):
_inherit = 'ir.actions.act_window'
@@ -103,7 +102,6 @@ class ir_action_window(osv.osv):
return False
return res
-ir_action_window()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py
index ce3dc00d258..dcff0ad5085 100644
--- a/addons/hr_attendance/hr_attendance.py
+++ b/addons/hr_attendance/hr_attendance.py
@@ -35,7 +35,6 @@ class hr_action_reason(osv.osv):
'action_type': 'sign_in',
}
-hr_action_reason()
def _employee_get(obj, cr, uid, context=None):
ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
@@ -86,7 +85,6 @@ class hr_attendance(osv.osv):
_constraints = [(_altern_si_so, 'Error ! Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])]
_order = 'name desc'
-hr_attendance()
class hr_employee(osv.osv):
_inherit = "hr.employee"
@@ -166,6 +164,5 @@ class hr_employee(osv.osv):
hr_attendance.create(cr, uid, vals, context=context)
return True
-hr_employee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/wizard/hr_attendance_bymonth.py b/addons/hr_attendance/wizard/hr_attendance_bymonth.py
index 6994bc5f906..93868bb2379 100644
--- a/addons/hr_attendance/wizard/hr_attendance_bymonth.py
+++ b/addons/hr_attendance/wizard/hr_attendance_bymonth.py
@@ -48,6 +48,5 @@ class hr_attendance_bymonth(osv.osv_memory):
'datas': datas,
}
-hr_attendance_bymonth()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/wizard/hr_attendance_byweek.py b/addons/hr_attendance/wizard/hr_attendance_byweek.py
index 7fcfc175f0e..963a2946ffa 100644
--- a/addons/hr_attendance/wizard/hr_attendance_byweek.py
+++ b/addons/hr_attendance/wizard/hr_attendance_byweek.py
@@ -49,6 +49,5 @@ class hr_attendance_byweek(osv.osv_memory):
'datas': datas,
}
-hr_attendance_byweek()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_attendance/wizard/hr_attendance_error.py b/addons/hr_attendance/wizard/hr_attendance_error.py
index 066f4a56e07..137bac30215 100644
--- a/addons/hr_attendance/wizard/hr_attendance_error.py
+++ b/addons/hr_attendance/wizard/hr_attendance_error.py
@@ -64,6 +64,5 @@ class hr_attendance_error(osv.osv_memory):
'datas': datas,
}
-hr_attendance_error()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_contract/hr_contract.py b/addons/hr_contract/hr_contract.py
index faf8b015a48..0cd31d66bcf 100644
--- a/addons/hr_contract/hr_contract.py
+++ b/addons/hr_contract/hr_contract.py
@@ -49,7 +49,6 @@ class hr_employee(osv.osv):
'contract_id':fields.function(_get_latest_contract, string='Contract', type='many2one', relation="hr.contract", help='Latest contract of the employee'),
}
-hr_employee()
class hr_contract_type(osv.osv):
_name = 'hr.contract.type'
@@ -57,7 +56,6 @@ class hr_contract_type(osv.osv):
_columns = {
'name': fields.char('Contract Type', size=32, required=True),
}
-hr_contract_type()
class hr_contract(osv.osv):
_name = 'hr.contract'
@@ -99,6 +97,5 @@ class hr_contract(osv.osv):
_constraints = [
(_check_dates, 'Error! Contract start-date must be less than contract end-date.', ['date_start', 'date_end'])
]
-hr_contract()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_evaluation/hr_evaluation.py b/addons/hr_evaluation/hr_evaluation.py
index d4ee28aff68..09c47b89153 100644
--- a/addons/hr_evaluation/hr_evaluation.py
+++ b/addons/hr_evaluation/hr_evaluation.py
@@ -45,7 +45,6 @@ class hr_evaluation_plan(osv.osv):
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
}
-hr_evaluation_plan()
class hr_evaluation_plan_phase(osv.osv):
_name = "hr_evaluation.plan.phase"
@@ -98,7 +97,6 @@ Thanks,
'''),
}
-hr_evaluation_plan_phase()
class hr_employee(osv.osv):
_name = "hr.employee"
@@ -272,7 +270,6 @@ class hr_evaluation(osv.osv):
obj_hr_eval_iterview.write(cr, uid, [survey_req.id], new_vals, context=context)
return super(hr_evaluation, self).write(cr, uid, ids, vals, context=context)
-hr_evaluation()
class survey_request(osv.osv):
_inherit = "survey.request"
@@ -280,7 +277,6 @@ class survey_request(osv.osv):
'is_evaluation': fields.boolean('Is Appraisal?'),
}
-survey_request()
class hr_evaluation_interview(osv.osv):
_name = 'hr.evaluation.interview'
@@ -357,6 +353,5 @@ class hr_evaluation_interview(osv.osv):
value = self.pool.get("survey").action_print_survey(cr, uid, ids, context=context)
return value
-hr_evaluation_interview()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:1
diff --git a/addons/hr_evaluation/report/hr_evaluation_report.py b/addons/hr_evaluation/report/hr_evaluation_report.py
index 62a5e4abd89..36353b65dfb 100644
--- a/addons/hr_evaluation/report/hr_evaluation_report.py
+++ b/addons/hr_evaluation/report/hr_evaluation_report.py
@@ -97,7 +97,6 @@ class hr_evaluation_report(osv.osv):
)
""")
-hr_evaluation_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index 2177add8878..73daa64f841 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -52,6 +52,9 @@ class hr_expense_expense(osv.osv):
res[expense.id] = total
return res
+ def _get_expense_from_line(self, cr, uid, ids, context=None):
+ return [line.expense_id.id for line in self.pool.get('hr.expense.line').browse(cr, uid, ids, context=context)]
+
def _get_currency(self, cr, uid, context=None):
user = self.pool.get('res.users').browse(cr, uid, [uid], context=context)[0]
if user.company_id:
@@ -84,7 +87,10 @@ class hr_expense_expense(osv.osv):
'account_move_id': fields.many2one('account.move', 'Ledger Posting'),
'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ),
'note': fields.text('Note'),
- 'amount': fields.function(_amount, string='Total Amount', digits_compute=dp.get_precision('Account')),
+ 'amount': fields.function(_amount, string='Total Amount', digits_compute=dp.get_precision('Account'),
+ store={
+ 'hr.expense.line': (_get_expense_from_line, ['unit_amount','unit_quantity'], 10)
+ }),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'department_id':fields.many2one('hr.department','Department', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True),
@@ -321,7 +327,7 @@ class hr_expense_expense(osv.osv):
'price_unit': tax['price_unit'],
'quantity': 1,
'price': tax['amount'] * tax['base_sign'] or 0.0,
- 'account_id': tax['account_collected_id'],
+ 'account_id': tax['account_collected_id'] or mres['account_id'],
'tax_code_id': tax['tax_code_id'],
'tax_amount': tax['amount'] * tax['base_sign'],
}
@@ -377,7 +383,6 @@ class hr_expense_expense(osv.osv):
}
return result
-hr_expense_expense()
class product_product(osv.osv):
_inherit = "product.product"
@@ -385,7 +390,6 @@ class product_product(osv.osv):
'hr_expense_ok': fields.boolean('Can be Expensed', help="Specify if the product can be selected in an HR expense line."),
}
-product_product()
class hr_expense_line(osv.osv):
_name = "hr.expense.line"
@@ -444,6 +448,5 @@ class hr_expense_line(osv.osv):
res['value'].update({'uom_id': product.uom_id.id})
return res
-hr_expense_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml
index eab24b06717..10abe95d892 100644
--- a/addons/hr_expense/hr_expense_view.xml
+++ b/addons/hr_expense/hr_expense_view.xml
@@ -32,7 +32,7 @@
-
+
diff --git a/addons/hr_expense/report/hr_expense_report.py b/addons/hr_expense/report/hr_expense_report.py
index 2adc11535ff..b29605a8e31 100644
--- a/addons/hr_expense/report/hr_expense_report.py
+++ b/addons/hr_expense/report/hr_expense_report.py
@@ -117,6 +117,5 @@ class hr_expense_report(osv.osv):
)
""")
-hr_expense_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index 4e113a23510..0eb3c0cbf16 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -180,7 +180,8 @@ class hr_holidays(osv.osv):
]
_sql_constraints = [
- ('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL))", "The employee or employee category of this request is missing."),
+ ('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL))",
+ "The employee or employee category of this request is missing. Please make sure that your user login is linked to an employee."),
('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be anterior to the end date."),
('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0."),
]
@@ -454,7 +455,6 @@ class resource_calendar_leaves(osv.osv):
'holiday_id': fields.many2one("hr.holidays", "Leave Request"),
}
-resource_calendar_leaves()
class hr_employee(osv.osv):
@@ -486,9 +486,9 @@ class hr_employee(osv.osv):
leave_id = holiday_obj.create(cr, uid, {'name': _('Leave Request for %s') % employee.name, 'employee_id': employee.id, 'holiday_status_id': status_id, 'type': 'remove', 'holiday_type': 'employee', 'number_of_days_temp': abs(diff)}, context=context)
else:
return False
- holidays_obj.signal_confirm(cr, uid, [leave_id])
- holidays_obj.signal_validate(cr, uid, [leave_id])
- holidays_obj.signal_second_validate(cr, uid, [leave_id])
+ holiday_obj.signal_confirm(cr, uid, [leave_id])
+ holiday_obj.signal_validate(cr, uid, [leave_id])
+ holiday_obj.signal_second_validate(cr, uid, [leave_id])
return True
def _get_remaining_days(self, cr, uid, ids, name, args, context=None):
@@ -543,6 +543,5 @@ class hr_employee(osv.osv):
'leave_date_to': fields.function(_get_leave_status, multi='leave_status', type='date', string='To Date'),
}
-hr_employee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_holidays/report/hr_holidays_report.py b/addons/hr_holidays/report/hr_holidays_report.py
index 394575d765d..0e5d6fe773c 100644
--- a/addons/hr_holidays/report/hr_holidays_report.py
+++ b/addons/hr_holidays/report/hr_holidays_report.py
@@ -55,6 +55,5 @@ class hr_holidays_remaining_leaves_user(osv.osv):
)
""")
-hr_holidays_remaining_leaves_user()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_holidays/wizard/hr_holidays_summary_department.py b/addons/hr_holidays/wizard/hr_holidays_summary_department.py
index ef1cb8f9e6f..8a204389572 100644
--- a/addons/hr_holidays/wizard/hr_holidays_summary_department.py
+++ b/addons/hr_holidays/wizard/hr_holidays_summary_department.py
@@ -53,6 +53,5 @@ class hr_holidays_summary_dept(osv.osv_memory):
'datas': datas,
}
-hr_holidays_summary_dept()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_holidays/wizard/hr_holidays_summary_employees.py b/addons/hr_holidays/wizard/hr_holidays_summary_employees.py
index 1897d82c882..1ec08eb2c86 100644
--- a/addons/hr_holidays/wizard/hr_holidays_summary_employees.py
+++ b/addons/hr_holidays/wizard/hr_holidays_summary_employees.py
@@ -50,6 +50,5 @@ class hr_holidays_summary_employee(osv.osv_memory):
'datas': datas,
}
-hr_holidays_summary_employee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py
index 06af3054b68..e08e8db5623 100644
--- a/addons/hr_payroll/hr_payroll.py
+++ b/addons/hr_payroll/hr_payroll.py
@@ -107,7 +107,6 @@ class hr_payroll_structure(osv.osv):
parent = self._get_parent_structure(cr, uid, parent, context)
return parent + struct_ids
-hr_payroll_structure()
class hr_contract(osv.osv):
"""
@@ -143,7 +142,6 @@ class hr_contract(osv.osv):
structure_ids = [contract.struct_id.id for contract in self.browse(cr, uid, contract_ids, context=context)]
return list(set(self.pool.get('hr.payroll.structure')._get_parent_structure(cr, uid, structure_ids, context=context)))
-hr_contract()
class contrib_register(osv.osv):
'''
@@ -166,7 +164,6 @@ class contrib_register(osv.osv):
context=context).company_id.id,
}
-contrib_register()
class hr_salary_rule_category(osv.osv):
"""
@@ -190,7 +187,6 @@ class hr_salary_rule_category(osv.osv):
context=context).company_id.id,
}
-hr_salary_rule_category()
class one2many_mod2(fields.one2many):
@@ -202,8 +198,8 @@ class one2many_mod2(fields.one2many):
res = {}
for id in ids:
res[id] = []
- ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids), ('appears_on_payslip', '=', True)], limit=self._limit)
- for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
+ ids2 = obj.pool[self._obj].search(cr, user, [(self._fields_id,'in',ids), ('appears_on_payslip', '=', True)], limit=self._limit)
+ for r in obj.pool[self._obj]._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
res[r[self._fields_id]].append( r['id'] )
return res
@@ -234,7 +230,6 @@ class hr_payslip_run(osv.osv):
def close_payslip_run(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'close'}, context=context)
-hr_payslip_run()
class hr_payslip(osv.osv):
'''
@@ -714,7 +709,6 @@ class hr_payslip(osv.osv):
res['value'].update({'struct_id': False})
return self.onchange_employee_id(cr, uid, ids, date_from=date_from, date_to=date_to, employee_id=employee_id, contract_id=contract_id, context=context)
-hr_payslip()
class hr_payslip_worked_days(osv.osv):
'''
@@ -736,7 +730,6 @@ class hr_payslip_worked_days(osv.osv):
_defaults = {
'sequence': 10,
}
-hr_payslip_worked_days()
class hr_payslip_input(osv.osv):
'''
@@ -759,7 +752,6 @@ class hr_payslip_input(osv.osv):
'amount': 0.0,
}
-hr_payslip_input()
class hr_salary_rule(osv.osv):
@@ -897,7 +889,6 @@ result = rules.NET > categories.NET * 0.10''',
except:
raise osv.except_osv(_('Error!'), _('Wrong python condition defined for salary rule %s (%s).')% (rule.name, rule.code))
-hr_salary_rule()
class hr_rule_input(osv.osv):
'''
@@ -912,7 +903,6 @@ class hr_rule_input(osv.osv):
'input_id': fields.many2one('hr.salary.rule', 'Salary Rule Input', required=True)
}
-hr_rule_input()
class hr_payslip_line(osv.osv):
'''
@@ -947,7 +937,6 @@ class hr_payslip_line(osv.osv):
'rate': 100.0,
}
-hr_payslip_line()
class hr_payroll_structure(osv.osv):
@@ -956,7 +945,6 @@ class hr_payroll_structure(osv.osv):
'rule_ids':fields.many2many('hr.salary.rule', 'hr_structure_salary_rule_rel', 'struct_id', 'rule_id', 'Salary Rules'),
}
-hr_payroll_structure()
class hr_employee(osv.osv):
'''
@@ -989,6 +977,5 @@ class hr_employee(osv.osv):
'total_wage': fields.function(_calculate_total_wage, method=True, type='float', string='Total Basic Salary', digits_compute=dp.get_precision('Payroll'), help="Sum of all current contract's wage of employee."),
}
-hr_employee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_payroll/wizard/hr_payroll_contribution_register_report.py b/addons/hr_payroll/wizard/hr_payroll_contribution_register_report.py
index 716a5060f14..ff078b09a67 100644
--- a/addons/hr_payroll/wizard/hr_payroll_contribution_register_report.py
+++ b/addons/hr_payroll/wizard/hr_payroll_contribution_register_report.py
@@ -50,6 +50,5 @@ class payslip_lines_contribution_register(osv.osv_memory):
'datas': datas,
}
-payslip_lines_contribution_register()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_payroll/wizard/hr_payroll_payslips_by_employees.py b/addons/hr_payroll/wizard/hr_payroll_payslips_by_employees.py
index aa36d223406..5837472be5f 100644
--- a/addons/hr_payroll/wizard/hr_payroll_payslips_by_employees.py
+++ b/addons/hr_payroll/wizard/hr_payroll_payslips_by_employees.py
@@ -68,6 +68,5 @@ class hr_payslip_employees(osv.osv_memory):
slip_pool.compute_sheet(cr, uid, slip_ids, context=context)
return {'type': 'ir.actions.act_window_close'}
-hr_payslip_employees()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_payroll_account/hr_payroll_account.py b/addons/hr_payroll_account/hr_payroll_account.py
index 07aff9001b6..ccab06c0dc1 100644
--- a/addons/hr_payroll_account/hr_payroll_account.py
+++ b/addons/hr_payroll_account/hr_payroll_account.py
@@ -187,7 +187,6 @@ class hr_payslip(osv.osv):
move_pool.post(cr, uid, [move_id], context=context)
return super(hr_payslip, self).process_sheet(cr, uid, [slip.id], context=context)
-hr_payslip()
class hr_salary_rule(osv.osv):
_inherit = 'hr.salary.rule'
@@ -197,7 +196,6 @@ class hr_salary_rule(osv.osv):
'account_debit': fields.many2one('account.account', 'Debit Account'),
'account_credit': fields.many2one('account.account', 'Credit Account'),
}
-hr_salary_rule()
class hr_contract(osv.osv):
@@ -207,7 +205,6 @@ class hr_contract(osv.osv):
'analytic_account_id':fields.many2one('account.analytic.account', 'Analytic Account'),
'journal_id': fields.many2one('account.journal', 'Salary Journal'),
}
-hr_contract()
class hr_payslip_run(osv.osv):
@@ -228,6 +225,5 @@ class hr_payslip_run(osv.osv):
'journal_id': _get_default_journal,
}
-hr_payslip_run()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_payroll_account/i18n/lt.po b/addons/hr_payroll_account/i18n/lt.po
new file mode 100644
index 00000000000..c29df14b44e
--- /dev/null
+++ b/addons/hr_payroll_account/i18n/lt.po
@@ -0,0 +1,126 @@
+# 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:21+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: hr_payroll_account
+#: field:hr.salary.rule,account_credit:0
+msgid "Credit Account"
+msgstr ""
+
+#. module: hr_payroll_account
+#: code:addons/hr_payroll_account/hr_payroll_account.py:103
+#, python-format
+msgid "Payslip of %s"
+msgstr ""
+
+#. module: hr_payroll_account
+#: code:addons/hr_payroll_account/hr_payroll_account.py:156
+#, python-format
+msgid ""
+"The Expense Journal \"%s\" has not properly configured the Credit Account!"
+msgstr ""
+
+#. module: hr_payroll_account
+#: field:hr.payslip,move_id:0
+msgid "Accounting Entry"
+msgstr ""
+
+#. module: hr_payroll_account
+#: code:addons/hr_payroll_account/hr_payroll_account.py:172
+#, python-format
+msgid ""
+"The Expense Journal \"%s\" has not properly configured the Debit Account!"
+msgstr ""
+
+#. module: hr_payroll_account
+#: field:hr.salary.rule,account_tax_id:0
+msgid "Tax Code"
+msgstr ""
+
+#. module: hr_payroll_account
+#: field:hr.payslip,period_id:0
+msgid "Force Period"
+msgstr ""
+
+#. module: hr_payroll_account
+#: help:hr.payslip,period_id:0
+msgid "Keep empty to use the period of the validation(Payslip) date."
+msgstr ""
+
+#. module: hr_payroll_account
+#: model:ir.model,name:hr_payroll_account.model_hr_contract
+msgid "Contract"
+msgstr ""
+
+#. module: hr_payroll_account
+#: field:hr.contract,analytic_account_id:0
+#: field:hr.salary.rule,analytic_account_id:0
+msgid "Analytic Account"
+msgstr ""
+
+#. module: hr_payroll_account
+#: field:hr.salary.rule,account_debit:0
+msgid "Debit Account"
+msgstr ""
+
+#. module: hr_payroll_account
+#: model:ir.model,name:hr_payroll_account.model_hr_payslip_run
+msgid "Payslip Batches"
+msgstr ""
+
+#. module: hr_payroll_account
+#: model:ir.model,name:hr_payroll_account.model_hr_payslip_employees
+msgid "Generate payslips for all selected employees"
+msgstr ""
+
+#. module: hr_payroll_account
+#: code:addons/hr_payroll_account/hr_payroll_account.py:156
+#: code:addons/hr_payroll_account/hr_payroll_account.py:172
+#, python-format
+msgid "Configuration Error!"
+msgstr ""
+
+#. module: hr_payroll_account
+#: model:ir.model,name:hr_payroll_account.model_hr_salary_rule
+msgid "hr.salary.rule"
+msgstr ""
+
+#. module: hr_payroll_account
+#: view:hr.contract:0
+#: view:hr.salary.rule:0
+msgid "Accounting"
+msgstr ""
+
+#. module: hr_payroll_account
+#: model:ir.model,name:hr_payroll_account.model_hr_payslip
+msgid "Pay Slip"
+msgstr ""
+
+#. module: hr_payroll_account
+#: code:addons/hr_payroll_account/hr_payroll_account.py:158
+#: code:addons/hr_payroll_account/hr_payroll_account.py:174
+#, python-format
+msgid "Adjustment Entry"
+msgstr ""
+
+#. module: hr_payroll_account
+#: field:hr.contract,journal_id:0
+#: field:hr.payslip,journal_id:0
+#: field:hr.payslip.run,journal_id:0
+msgid "Salary Journal"
+msgstr ""
diff --git a/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py b/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py
index 76d197a17ec..053fab16e84 100644
--- a/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py
+++ b/addons/hr_payroll_account/wizard/hr_payroll_payslips_by_employees.py
@@ -36,6 +36,5 @@ class hr_payslip_employees(osv.osv_memory):
if journal_id: context.update({'journal_id': journal_id})
return super(hr_payslip_employees, self).compute_sheet(cr, uid, ids, context=context)
-hr_payslip_employees()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index b0b60db6bd5..e41d80fb348 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -510,8 +510,9 @@ class hr_job(osv.osv):
def _auto_init(self, cr, context=None):
"""Installation hook to create aliases for all jobs and avoid constraint errors."""
- self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(hr_job,self)._auto_init,
+ res = self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(hr_job,self)._auto_init,
self._columns['alias_id'], 'name', alias_prefix='job+', alias_defaults={'job_id': 'id'}, context=context)
+ return res
def create(self, cr, uid, vals, context=None):
mail_alias = self.pool.get('mail.alias')
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index b531677d538..716c1cba8d5 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -41,7 +41,7 @@
-
+
@@ -199,7 +199,7 @@
-
+
diff --git a/addons/hr_recruitment/report/hr_recruitment_report.py b/addons/hr_recruitment/report/hr_recruitment_report.py
index 62fa1badc41..8c365b10070 100644
--- a/addons/hr_recruitment/report/hr_recruitment_report.py
+++ b/addons/hr_recruitment/report/hr_recruitment_report.py
@@ -116,6 +116,5 @@ class hr_recruitment_report(osv.osv):
s.department_id
)
""")
-hr_recruitment_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_recruitment/test/recruitment_process.yml b/addons/hr_recruitment/test/recruitment_process.yml
index f2d4e4736fa..335edc71892 100644
--- a/addons/hr_recruitment/test/recruitment_process.yml
+++ b/addons/hr_recruitment/test/recruitment_process.yml
@@ -4,8 +4,7 @@
An applicant is interested in the job position. So he sends a resume by email.
-
!python {model: mail.thread}: |
- from openerp import addons
- request_file = open(addons.get_module_resource('hr_recruitment','test', 'resume.eml'),'rb')
+ request_file = open(openerp.modules.module.get_module_resource('hr_recruitment','test', 'resume.eml'),'rb')
request_message = request_file.read()
self.message_process(cr, uid, 'hr.applicant', request_message)
-
diff --git a/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py b/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py
index 82dd534d81b..b0d4aebe09a 100644
--- a/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py
+++ b/addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py
@@ -80,6 +80,5 @@ class hr_recruitment_partner_create(osv.osv_memory):
'search_view_id': res['res_id']
}
-hr_recruitment_partner_create()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py b/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py
index 58fb706a09e..60d31e74eee 100644
--- a/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py
+++ b/addons/hr_recruitment/wizard/hr_recruitment_employee_hired.py
@@ -50,6 +50,5 @@ class hired_employee(osv.osv_memory):
context = {}
return self.pool.get('hr.applicant').case_close_with_emp(cr, uid,context.get('active_ids', []))
-hired_employee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet/hr_timesheet.py b/addons/hr_timesheet/hr_timesheet.py
index cc9c0653a85..22dfb7b9552 100644
--- a/addons/hr_timesheet/hr_timesheet.py
+++ b/addons/hr_timesheet/hr_timesheet.py
@@ -56,7 +56,6 @@ class hr_employee(osv.osv):
'journal_id': _getAnalyticJournal,
'product_id': _getEmployeeProduct
}
-hr_employee()
class hr_analytic_timesheet(osv.osv):
diff --git a/addons/hr_timesheet/wizard/hr_timesheet_print_employee.py b/addons/hr_timesheet/wizard/hr_timesheet_print_employee.py
index 1523756aae0..efffa6acd5f 100644
--- a/addons/hr_timesheet/wizard/hr_timesheet_print_employee.py
+++ b/addons/hr_timesheet/wizard/hr_timesheet_print_employee.py
@@ -62,6 +62,5 @@ class analytical_timesheet_employee(osv.osv_memory):
'report_name': 'hr.analytical.timesheet',
'datas': datas,
}
-analytical_timesheet_employee()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet/wizard/hr_timesheet_print_users.py b/addons/hr_timesheet/wizard/hr_timesheet_print_users.py
index 8d9f0b01f68..d7dda927111 100644
--- a/addons/hr_timesheet/wizard/hr_timesheet_print_users.py
+++ b/addons/hr_timesheet/wizard/hr_timesheet_print_users.py
@@ -52,6 +52,5 @@ class analytical_timesheet_employees(osv.osv_memory):
'datas': datas,
}
-analytical_timesheet_employees()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py
index 054e797a884..d0cbdc78c31 100644
--- a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py
+++ b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py
@@ -103,7 +103,6 @@ class hr_so_project(osv.osv_memory):
self._write(cr, uid, data, emp_id, context=context)
return {'type': 'ir.actions.act_window_close'}
-hr_so_project()
class hr_si_project(osv.osv_memory):
@@ -168,6 +167,5 @@ class hr_si_project(osv.osv_memory):
res.update({'name': employee.name, 'state': employee.state, 'emp_id': emp_id[0], 'server_date':time.strftime('%Y-%m-%d %H:%M:%S')})
return res
-hr_si_project()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
index 828c7230ddf..f8c27bded5e 100644
--- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
+++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py
@@ -37,7 +37,6 @@ class hr_timesheet_invoice_factor(osv.osv):
'factor': lambda *a: 0.0,
}
-hr_timesheet_invoice_factor()
class account_analytic_account(osv.osv):
@@ -286,7 +285,6 @@ class account_analytic_line(osv.osv):
invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
return invoices
-account_analytic_line()
class hr_analytic_timesheet(osv.osv):
@@ -314,7 +312,6 @@ class hr_analytic_timesheet(osv.osv):
return super(hr_analytic_timesheet, self).copy(cursor, user, obj_id,
default, context=context)
-hr_analytic_timesheet()
class account_invoice(osv.osv):
@@ -334,7 +331,6 @@ class account_invoice(osv.osv):
il['analytic_lines'][0][2]['to_invoice'] = to_invoice[0]
return iml
-account_invoice()
class account_move_line(osv.osv):
@@ -353,6 +349,5 @@ class account_move_line(osv.osv):
}, context=context)
return res
-account_move_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report.py b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report.py
index 02b46b71b20..3ea7e209051 100644
--- a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report.py
+++ b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report.py
@@ -71,7 +71,6 @@ class report_timesheet_line(osv.osv):
l.invoice_id
)
""")
-report_timesheet_line()
@@ -107,7 +106,6 @@ class report_timesheet_user(osv.osv):
group by l.date, to_char(l.date,'YYYY'),to_char(l.date,'MM'), l.user_id
)
""")
-report_timesheet_user()
class report_timesheet_account(osv.osv):
_name = "report_timesheet.account"
@@ -140,7 +138,6 @@ class report_timesheet_account(osv.osv):
to_char(create_date, 'YYYY'),to_char(create_date, 'MM'), user_id, account_id
)
""")
-report_timesheet_account()
class report_timesheet_account_date(osv.osv):
@@ -174,7 +171,6 @@ class report_timesheet_account_date(osv.osv):
to_char(date,'YYYY'),to_char(date,'MM'), user_id, account_id
)
""")
-report_timesheet_account_date()
class report_timesheet_invoice(osv.osv):
@@ -215,7 +211,6 @@ class report_timesheet_invoice(osv.osv):
a.user_id
)
""")
-report_timesheet_invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_invoice/report/report_analytic.py b/addons/hr_timesheet_invoice/report/report_analytic.py
index 53912fcb1d6..c620b2f9584 100644
--- a/addons/hr_timesheet_invoice/report/report_analytic.py
+++ b/addons/hr_timesheet_invoice/report/report_analytic.py
@@ -60,7 +60,6 @@ class report_analytic_account_close(osv.osv):
(a.quantity_max>0 and (sum(l.unit_amount)>=a.quantity_max)) or
a.date <= current_date
)""")
-report_analytic_account_close()
class report_account_analytic_line_to_invoice(osv.osv):
_name = "report.account.analytic.line.to.invoice"
@@ -105,7 +104,6 @@ class report_account_analytic_line_to_invoice(osv.osv):
to_char(l.date, 'YYYY'), to_char(l.date,'MM'), product_id, product_uom_id, account_id
)
""")
-report_account_analytic_line_to_invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_analytic_profit.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_analytic_profit.py
index 6c6523f93f9..2675556e8ac 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_analytic_profit.py
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_analytic_profit.py
@@ -70,6 +70,5 @@ class account_analytic_profit(osv.osv_memory):
'datas': datas,
}
-account_analytic_profit()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_final_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_final_invoice_create.py
index 1977d6cccc5..8d5f0c4067c 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_final_invoice_create.py
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_final_invoice_create.py
@@ -58,6 +58,5 @@ class final_invoice_create(osv.osv_memory):
act_win['name'] = _('Invoices')
return act_win
-final_invoice_create()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
index 6aa8b0f9d8d..874370fea22 100644
--- a/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
+++ b/addons/hr_timesheet_invoice/wizard/hr_timesheet_invoice_create.py
@@ -69,7 +69,6 @@ class hr_timesheet_invoice_create(osv.osv_memory):
return act_win
-hr_timesheet_invoice_create()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
index 4be032ba99b..156732ba33d 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
@@ -327,7 +327,6 @@ class hr_timesheet_line(osv.osv):
return dict([(el, self.on_change_account_id(cr, uid, ids, el, context.get('user_id', uid))) for el in account_ids])
-hr_timesheet_line()
class hr_attendance(osv.osv):
_inherit = "hr.attendance"
@@ -425,7 +424,6 @@ class hr_attendance(osv.osv):
raise osv.except_osv(_('Error!'), _('You cannot modify an entry in a confirmed timesheet'))
return True
-hr_attendance()
class hr_timesheet_sheet_sheet_day(osv.osv):
_name = "hr_timesheet_sheet.sheet.day"
@@ -505,7 +503,6 @@ class hr_timesheet_sheet_sheet_day(osv.osv):
GROUP BY name, sheet_id
)) AS bar""")
-hr_timesheet_sheet_sheet_day()
class hr_timesheet_sheet_sheet_account(osv.osv):
@@ -539,7 +536,6 @@ class hr_timesheet_sheet_sheet_account(osv.osv):
group by l.account_id, s.id, l.to_invoice
)""")
-hr_timesheet_sheet_sheet_account()
@@ -558,7 +554,6 @@ class res_company(osv.osv):
'timesheet_max_difference': lambda *args: 0.0
}
-res_company()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_sheet/report/hr_timesheet_report.py b/addons/hr_timesheet_sheet/report/hr_timesheet_report.py
index 49b66b63c0f..61c2b9e53da 100644
--- a/addons/hr_timesheet_sheet/report/hr_timesheet_report.py
+++ b/addons/hr_timesheet_sheet/report/hr_timesheet_report.py
@@ -79,6 +79,5 @@ class hr_timesheet_report(osv.osv):
l.currency_id
)
""")
-hr_timesheet_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_sheet/report/timesheet_report.py b/addons/hr_timesheet_sheet/report/timesheet_report.py
index 31255a3a6b2..16889253a68 100644
--- a/addons/hr_timesheet_sheet/report/timesheet_report.py
+++ b/addons/hr_timesheet_sheet/report/timesheet_report.py
@@ -114,6 +114,5 @@ class timesheet_report(osv.osv):
htss.user_id
)
""")
-timesheet_report()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py b/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py
index c2d5167c179..62511f4575b 100644
--- a/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py
+++ b/addons/hr_timesheet_sheet/wizard/hr_timesheet_current.py
@@ -58,6 +58,5 @@ class hr_timesheet_current_open(osv.osv_memory):
value['res_id'] = ids[0]
return value
-hr_timesheet_current_open()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/im/__init__.py b/addons/im/__init__.py
new file mode 100644
index 00000000000..23c6ad13350
--- /dev/null
+++ b/addons/im/__init__.py
@@ -0,0 +1,2 @@
+
+import im
diff --git a/addons/im/__openerp__.py b/addons/im/__openerp__.py
new file mode 100644
index 00000000000..a76dd7c8cc2
--- /dev/null
+++ b/addons/im/__openerp__.py
@@ -0,0 +1,27 @@
+{
+ 'name' : 'Instant Messaging',
+ 'version': '1.0',
+ 'summary': 'Live Chat, Talks with Others',
+ 'sequence': '18',
+ 'category': 'Tools',
+ 'complexity': 'easy',
+ 'description':
+ """
+Instant Messaging
+=================
+
+Allows users to chat with each other in real time. Find other users easily and
+chat in real time. It support several chats in parallel.
+ """,
+ 'data': [
+ 'security/ir.model.access.csv',
+ 'security/im_security.xml',
+ ],
+ 'depends' : ['base'],
+ 'js': ['static/src/js/*.js'],
+ 'css': ['static/src/css/*.css'],
+ 'qweb': ['static/src/xml/*.xml'],
+ 'installable': True,
+ 'auto_install': False,
+ 'application': True,
+}
diff --git a/addons/im/im.py b/addons/im/im.py
new file mode 100644
index 00000000000..0de9ea8c79b
--- /dev/null
+++ b/addons/im/im.py
@@ -0,0 +1,351 @@
+# -*- 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.tools.config
+import openerp.modules.registry
+from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
+import datetime
+from openerp.osv import osv, fields
+import time
+import logging
+import json
+import select
+
+_logger = logging.getLogger(__name__)
+
+def listen_channel(cr, channel_name, handle_message, check_stop=(lambda: False), check_stop_timer=60.):
+ """
+ Begin a loop, listening on a PostgreSQL channel. This method does never terminate by default, you need to provide a check_stop
+ callback to do so. This method also assume that all notifications will include a message formated using JSON (see the
+ corresponding notify_channel() method).
+
+ :param db_name: database name
+ :param channel_name: the name of the PostgreSQL channel to listen
+ :param handle_message: function that will be called when a message is received. It takes one argument, the message
+ attached to the notification.
+ :type handle_message: function (one argument)
+ :param check_stop: function that will be called periodically (see the check_stop_timer argument). If it returns True
+ this function will stop to watch the channel.
+ :type check_stop: function (no arguments)
+ :param check_stop_timer: The maximum amount of time between calls to check_stop_timer (can be shorter if messages
+ are received).
+ """
+ try:
+ conn = cr._cnx
+ cr.execute("listen " + channel_name + ";")
+ cr.commit();
+ stopping = False
+ while not stopping:
+ if check_stop():
+ stopping = True
+ break
+ if select.select([conn], [], [], check_stop_timer) == ([],[],[]):
+ pass
+ else:
+ conn.poll()
+ while conn.notifies:
+ message = json.loads(conn.notifies.pop().payload)
+ handle_message(message)
+ finally:
+ try:
+ cr.execute("unlisten " + channel_name + ";")
+ cr.commit()
+ except:
+ pass # can't do anything if that fails
+
+def notify_channel(cr, channel_name, message):
+ """
+ Send a message through a PostgreSQL channel. The message will be formatted using JSON. This method will
+ commit the given transaction because the notify command in Postgresql seems to work correctly when executed in
+ a separate transaction (despite what is written in the documentation).
+
+ :param cr: The cursor.
+ :param channel_name: The name of the PostgreSQL channel.
+ :param message: The message, must be JSON-compatible data.
+ """
+ cr.commit()
+ cr.execute("notify " + channel_name + ", %s", [json.dumps(message)])
+ cr.commit()
+
+POLL_TIMER = 30
+DISCONNECTION_TIMER = POLL_TIMER + 5
+WATCHER_ERROR_DELAY = 10
+
+if openerp.evented:
+ import gevent
+ import gevent.event
+
+ class ImWatcher(object):
+ watchers = {}
+
+ @staticmethod
+ def get_watcher(db_name):
+ if not ImWatcher.watchers.get(db_name):
+ ImWatcher(db_name)
+ return ImWatcher.watchers[db_name]
+
+ def __init__(self, db_name):
+ self.db_name = db_name
+ ImWatcher.watchers[db_name] = self
+ self.waiting = 0
+ self.wait_id = 0
+ self.users = {}
+ self.users_watch = {}
+ gevent.spawn(self.loop)
+
+ def loop(self):
+ _logger.info("Begin watching on channel im_channel for database " + self.db_name)
+ stop = False
+ while not stop:
+ try:
+ registry = openerp.modules.registry.RegistryManager.get(self.db_name)
+ with registry.cursor() as cr:
+ listen_channel(cr, "im_channel", self.handle_message, self.check_stop)
+ stop = True
+ except:
+ # if something crash, we wait some time then try again
+ _logger.exception("Exception during watcher activity")
+ time.sleep(WATCHER_ERROR_DELAY)
+ _logger.info("End watching on channel im_channel for database " + self.db_name)
+ del ImWatcher.watchers[self.db_name]
+
+ def handle_message(self, message):
+ if message["type"] == "message":
+ for waiter in self.users.get(message["receiver"], {}).values():
+ waiter.set()
+ else: #type status
+ for waiter in self.users_watch.get(message["user"], {}).values():
+ waiter.set()
+
+ def check_stop(self):
+ return self.waiting == 0
+
+ def _get_wait_id(self):
+ self.wait_id += 1
+ return self.wait_id
+
+ def stop(self, user_id, watch_users, timeout=None):
+ wait_id = self._get_wait_id()
+ event = gevent.event.Event()
+ self.waiting += 1
+ self.users.setdefault(user_id, {})[wait_id] = event
+ for watch in watch_users:
+ self.users_watch.setdefault(watch, {})[wait_id] = event
+ try:
+ event.wait(timeout)
+ finally:
+ for watch in watch_users:
+ del self.users_watch[watch][wait_id]
+ if len(self.users_watch[watch]) == 0:
+ del self.users_watch[watch]
+ del self.users[user_id][wait_id]
+ if len(self.users[user_id]) == 0:
+ del self.users[user_id]
+ self.waiting -= 1
+
+
+class LongPollingController(openerp.addons.web.http.Controller):
+ _cp_path = '/longpolling/im'
+
+ @openerp.addons.web.http.jsonrequest
+ def poll(self, req, last=None, users_watch=None, db=None, uid=None, password=None, uuid=None):
+ assert_uuid(uuid)
+ if not openerp.evented:
+ raise Exception("Not usable in a server not running gevent")
+ if db is not None:
+ req.session._db = db
+ req.session._uid = uid
+ req.session._password = password
+ req.session.model('im.user').im_connect(uuid=uuid, context=req.context)
+ my_id = req.session.model('im.user').get_by_user_id(uuid or req.session._uid, req.context)["id"]
+ num = 0
+ while True:
+ res = req.session.model('im.message').get_messages(last, users_watch, uuid=uuid, context=req.context)
+ if num >= 1 or len(res["res"]) > 0:
+ return res
+ last = res["last"]
+ num += 1
+ ImWatcher.get_watcher(res["dbname"]).stop(my_id, users_watch or [], POLL_TIMER)
+
+ @openerp.addons.web.http.jsonrequest
+ def activated(self, req):
+ return not not openerp.evented
+
+ @openerp.addons.web.http.jsonrequest
+ def gen_uuid(self, req):
+ import uuid
+ return "%s" % uuid.uuid1()
+
+def assert_uuid(uuid):
+ if not isinstance(uuid, (str, unicode, type(None))):
+ raise Exception("%s is not a uuid" % uuid)
+
+
+class im_message(osv.osv):
+ _name = 'im.message'
+
+ _order = "date desc"
+
+ _columns = {
+ 'message': fields.char(string="Message", size=200, required=True),
+ 'from_id': fields.many2one("im.user", "From", required= True, ondelete='cascade'),
+ 'to_id': fields.many2one("im.user", "To", required=True, select=True, ondelete='cascade'),
+ 'date': fields.datetime("Date", required=True, select=True),
+ }
+
+ _defaults = {
+ 'date': lambda *args: datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
+ }
+
+ def get_messages(self, cr, uid, last=None, users_watch=None, uuid=None, context=None):
+ assert_uuid(uuid)
+ users_watch = users_watch or []
+
+ # complex stuff to determine the last message to show
+ users = self.pool.get("im.user")
+ my_id = users.get_by_user_id(cr, uid, uuid or uid, context=context)["id"]
+ c_user = users.browse(cr, openerp.SUPERUSER_ID, my_id, context=context)
+ if last:
+ if c_user.im_last_received < last:
+ users.write(cr, openerp.SUPERUSER_ID, my_id, {'im_last_received': last}, context=context)
+ else:
+ last = c_user.im_last_received or -1
+
+ # how fun it is to always need to reorder results from read
+ mess_ids = self.search(cr, openerp.SUPERUSER_ID, [['id', '>', last], ['to_id', '=', my_id]], order="id", context=context)
+ mess = self.read(cr, openerp.SUPERUSER_ID, mess_ids, ["id", "message", "from_id", "date"], context=context)
+ index = {}
+ for i in xrange(len(mess)):
+ index[mess[i]["id"]] = mess[i]
+ mess = []
+ for i in mess_ids:
+ mess.append(index[i])
+
+ if len(mess) > 0:
+ last = mess[-1]["id"]
+ users_status = users.read(cr, openerp.SUPERUSER_ID, users_watch, ["im_status"], context=context)
+ return {"res": mess, "last": last, "dbname": cr.dbname, "users_status": users_status}
+
+ def post(self, cr, uid, message, to_user_id, uuid=None, context=None):
+ assert_uuid(uuid)
+ my_id = self.pool.get('im.user').get_by_user_id(cr, uid, uuid or uid)["id"]
+ self.create(cr, openerp.SUPERUSER_ID, {"message": message, 'from_id': my_id, 'to_id': to_user_id}, context=context)
+ notify_channel(cr, "im_channel", {'type': 'message', 'receiver': to_user_id})
+ return False
+
+class im_user(osv.osv):
+ _name = "im.user"
+
+ def _im_status(self, cr, uid, ids, something, something_else, context=None):
+ res = {}
+ current = datetime.datetime.now()
+ delta = datetime.timedelta(0, DISCONNECTION_TIMER)
+ data = self.read(cr, openerp.SUPERUSER_ID, ids, ["im_last_status_update", "im_last_status"], context=context)
+ for obj in data:
+ last_update = datetime.datetime.strptime(obj["im_last_status_update"], DEFAULT_SERVER_DATETIME_FORMAT)
+ res[obj["id"]] = obj["im_last_status"] and (last_update + delta) > current
+ return res
+
+ def search_users(self, cr, uid, domain, fields, limit, context=None):
+ # do not user openerp.SUPERUSER_ID, reserved to normal users
+ found = self.pool.get('res.users').search(cr, uid, domain, limit=limit, context=context)
+ found = self.get_by_user_ids(cr, uid, found, context=context)
+ return self.read(cr, uid, found, fields, context=context)
+
+ def im_connect(self, cr, uid, uuid=None, context=None):
+ assert_uuid(uuid)
+ return self._im_change_status(cr, uid, True, uuid, context)
+
+ def im_disconnect(self, cr, uid, uuid=None, context=None):
+ assert_uuid(uuid)
+ return self._im_change_status(cr, uid, False, uuid, context)
+
+ def _im_change_status(self, cr, uid, new_one, uuid=None, context=None):
+ assert_uuid(uuid)
+ id = self.get_by_user_id(cr, uid, uuid or uid, context=context)["id"]
+ current_status = self.read(cr, openerp.SUPERUSER_ID, id, ["im_status"], context=None)["im_status"]
+ self.write(cr, openerp.SUPERUSER_ID, id, {"im_last_status": new_one,
+ "im_last_status_update": datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
+ if current_status != new_one:
+ notify_channel(cr, "im_channel", {'type': 'status', 'user': id})
+ return True
+
+ def get_by_user_id(self, cr, uid, id, context=None):
+ ids = self.get_by_user_ids(cr, uid, [id], context=context)
+ return ids[0]
+
+ def get_by_user_ids(self, cr, uid, ids, context=None):
+ user_ids = [x for x in ids if isinstance(x, int)]
+ uuids = [x for x in ids if isinstance(x, (str, unicode))]
+ users = self.search(cr, openerp.SUPERUSER_ID, ["|", ["user", "in", user_ids], ["uuid", "in", uuids]], context=None)
+ records = self.read(cr, openerp.SUPERUSER_ID, users, ["user", "uuid"], context=None)
+ inside = {}
+ for i in records:
+ if i["user"]:
+ inside[i["user"][0]] = True
+ elif ["uuid"]:
+ inside[i["uuid"]] = True
+ not_inside = {}
+ for i in ids:
+ if not (i in inside):
+ not_inside[i] = True
+ for to_create in not_inside.keys():
+ if isinstance(to_create, int):
+ created = self.create(cr, openerp.SUPERUSER_ID, {"user": to_create}, context=context)
+ records.append({"id": created, "user": [to_create, ""]})
+ else:
+ created = self.create(cr, openerp.SUPERUSER_ID, {"uuid": to_create}, context=context)
+ records.append({"id": created, "uuid": to_create})
+ return records
+
+ def assign_name(self, cr, uid, uuid, name, context=None):
+ assert_uuid(uuid)
+ id = self.get_by_user_id(cr, uid, uuid or uid, context=context)["id"]
+ self.write(cr, openerp.SUPERUSER_ID, id, {"assigned_name": name}, context=context)
+ return True
+
+ def _get_name(self, cr, uid, ids, name, arg, context=None):
+ res = {}
+ for record in self.browse(cr, uid, ids, context=context):
+ res[record.id] = record.assigned_name
+ if record.user:
+ res[record.id] = record.user.name
+ continue
+ return res
+
+ _columns = {
+ 'name': fields.function(_get_name, type='char', size=200, string="Name", store=True, readonly=True),
+ 'assigned_name': fields.char(string="Assigned Name", size=200, required=False),
+ 'image': fields.related('user', 'image_small', type='binary', string="Image", readonly=True),
+ 'user': fields.many2one("res.users", string="User", select=True, ondelete='cascade'),
+ 'uuid': fields.char(string="UUID", size=50, select=True),
+ 'im_last_received': fields.integer(string="Instant Messaging Last Received Message"),
+ 'im_last_status': fields.boolean(strint="Instant Messaging Last Status"),
+ 'im_last_status_update': fields.datetime(string="Instant Messaging Last Status Update"),
+ 'im_status': fields.function(_im_status, string="Instant Messaging Status", type='boolean'),
+ }
+
+ _defaults = {
+ 'im_last_received': -1,
+ 'im_last_status': False,
+ 'im_last_status_update': lambda *args: datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
+ }
diff --git a/addons/im/security/im_security.xml b/addons/im/security/im_security.xml
new file mode 100644
index 00000000000..10297ac0669
--- /dev/null
+++ b/addons/im/security/im_security.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ Can only read messages that you sent or messages sent to you
+
+
+ ["|", ('to_id.user', '=', user.id), ('from_id.user', '=', user.id)]
+
+
+
+
+
+
+
+ Can only modify your user
+
+
+ [('user', '=', user.id)]
+
+
+
+
+
+
+
diff --git a/addons/im/security/ir.model.access.csv b/addons/im/security/ir.model.access.csv
new file mode 100644
index 00000000000..ed639353e21
--- /dev/null
+++ b/addons/im/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_im_message,im.message,model_im_message,base.group_user,1,0,1,0
+access_im_user,im.user,model_im_user,base.group_user,1,1,1,0
\ No newline at end of file
diff --git a/addons/im/static/src/audio/Ting.mp3 b/addons/im/static/src/audio/Ting.mp3
new file mode 100644
index 00000000000..6fd090a89ce
Binary files /dev/null and b/addons/im/static/src/audio/Ting.mp3 differ
diff --git a/addons/im/static/src/audio/Ting.ogg b/addons/im/static/src/audio/Ting.ogg
new file mode 100644
index 00000000000..8d17ea85bd3
Binary files /dev/null and b/addons/im/static/src/audio/Ting.ogg differ
diff --git a/addons/im/static/src/audio/purr.mp3 b/addons/im/static/src/audio/purr.mp3
new file mode 100644
index 00000000000..849d303c3b1
Binary files /dev/null and b/addons/im/static/src/audio/purr.mp3 differ
diff --git a/addons/im/static/src/audio/purr.ogg b/addons/im/static/src/audio/purr.ogg
new file mode 100644
index 00000000000..2ddc77537f1
Binary files /dev/null and b/addons/im/static/src/audio/purr.ogg differ
diff --git a/addons/im/static/src/css/im.css b/addons/im/static/src/css/im.css
new file mode 100644
index 00000000000..2f3e7dd58bb
--- /dev/null
+++ b/addons/im/static/src/css/im.css
@@ -0,0 +1,258 @@
+
+.openerp .oe_im {
+ position: fixed;
+ background-color: #E8EBEF;
+ width: 220px;
+ border-left: 1px solid #AEB9BD;
+}
+
+/* button */
+
+.openerp .oe_topbar_imbutton {
+ cursor: pointer;
+}
+
+/* search stuff */
+.openerp .oe_im_frame_header {
+ position: relative;
+ background: #dedede;
+ background: -moz-linear-gradient(#fcfcfc, #dedede);
+ background: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
+ border-bottom: 1px solid border-color !important;
+ padding: 5px;
+}
+.openerp .oe_im_frame_header .oe_im_searchbox {
+ width: 168px;
+ padding: 1px 21px 1px 19px;
+ font-size: 13px;
+ -moz-border-radius: 13px;
+ -webkit-border-radius: 13px;
+ border-radius: 13px;
+}
+.openerp .oe_im_frame_header .oe_im_search_icon {
+ position: absolute;
+ color: #888;
+ top: 2px;
+ left: 9px;
+ font-size: 28px;
+ font-family: "entypoRegular" !important;
+ font-weight: 300 !important;
+}
+.openerp .oe_im_frame_header .oe_im_search_clear {
+ display: none;
+ position: absolute;
+ right: 11px;
+ top: 4px;
+ font-size: 26px;
+ color: #b6b6b6;
+ cursor: pointer;
+}
+.openerp .oe_im_frame_header .oe_im_search_clear:hover {
+ color: #888;
+}
+
+/* users */
+
+.openerp .oe_im_users {
+ padding-bottom: 38px;
+}
+.openerp .oe_im_user {
+ position: relative;
+ padding: 2px 6px;
+ cursor: pointer;
+ font-size: 13px;
+ margin-bottom: 3px;
+}
+.openerp .oe_im_user:hover {
+ background: lightGrey;
+}
+.openerp .oe_im_user_clip {
+ display: inline-block;
+ 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);
+}
+.openerp .oe_im_user_avatar {
+ width: 26px;
+ height: auto;
+}
+.openerp .oe_im_user_name {
+ width: 162px;
+ line-height: 26px;
+ padding-right: 15px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ position: relative;
+}
+
+.openerp .oe_im_user_online {
+ display: none;
+ position: absolute;
+ top: 9.5px;
+ right: 11px;
+ width: 11px;
+ height: 11px;
+ vertical-align: middle;
+ border: 0;
+}
+
+/* conversations */
+
+.openerp .oe_im_chatview {
+ position: fixed;
+ overflow: hidden;
+ bottom: 6px;
+ 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;
+}
+.openerp .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;
+}
+.openerp .oe_im_chatview.oe_im_chatview_disconnected_status .oe_im_chatview_disconnected {
+ display: block;
+}
+.openerp .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;
+}
+.openerp .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;
+}
+.openerp .oe_im_chatview .oe_im_chatview_content {
+ overflow: auto;
+ height: 287px;
+}
+.openerp .oe_im_chatview.oe_im_chatview_disconnected_status .oe_im_chatview_content {
+ height: 249px;
+}
+.openerp .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;
+}
+.openerp .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);
+}
+.openerp .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;
+}
+.openerp .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);
+}
+.openerp .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;
+}
+.openerp .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;
+}
+.openerp .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;
+}
+.openerp .oe_im_chatview .oe_im_chatview_bubble_list {
+}
+.openerp .oe_im_chatview .oe_im_chatview_bubble_item {
+ margin: 0 0 2px 30px;
+ line-height: 14px;
+ word-wrap: break-word;
+}
+
+.openerp .oe_im_chatview_online {
+ display: none;
+ margin-top: -4px;
+ width: 11px;
+ height: 11px;
+}
diff --git a/addons/im/static/src/img/avatar/avatar.jpeg b/addons/im/static/src/img/avatar/avatar.jpeg
new file mode 100644
index 00000000000..7168794022e
Binary files /dev/null and b/addons/im/static/src/img/avatar/avatar.jpeg differ
diff --git a/addons/im/static/src/img/button-gloss.png b/addons/im/static/src/img/button-gloss.png
new file mode 100755
index 00000000000..6f3957702fe
Binary files /dev/null and b/addons/im/static/src/img/button-gloss.png differ
diff --git a/addons/im/static/src/img/glyphicons-halflings-white.png b/addons/im/static/src/img/glyphicons-halflings-white.png
new file mode 100755
index 00000000000..3bf6484a29d
Binary files /dev/null and b/addons/im/static/src/img/glyphicons-halflings-white.png differ
diff --git a/addons/im/static/src/img/glyphicons-halflings.png b/addons/im/static/src/img/glyphicons-halflings.png
new file mode 100755
index 00000000000..a9969993201
Binary files /dev/null and b/addons/im/static/src/img/glyphicons-halflings.png differ
diff --git a/addons/im/static/src/img/green.png b/addons/im/static/src/img/green.png
new file mode 100644
index 00000000000..01fb373c251
Binary files /dev/null and b/addons/im/static/src/img/green.png differ
diff --git a/addons/im/static/src/img/icon.png b/addons/im/static/src/img/icon.png
new file mode 100644
index 00000000000..07d2503ce4e
Binary files /dev/null and b/addons/im/static/src/img/icon.png differ
diff --git a/addons/im/static/src/img/logo.png b/addons/im/static/src/img/logo.png
new file mode 100644
index 00000000000..aca5f4c60d8
Binary files /dev/null and b/addons/im/static/src/img/logo.png differ
diff --git a/addons/im/static/src/img/wood.png b/addons/im/static/src/img/wood.png
new file mode 100644
index 00000000000..22f2450d3ad
Binary files /dev/null and b/addons/im/static/src/img/wood.png differ
diff --git a/addons/im/static/src/js/im.js b/addons/im/static/src/js/im.js
new file mode 100644
index 00000000000..b21a339cb84
--- /dev/null
+++ b/addons/im/static/src/js/im.js
@@ -0,0 +1,463 @@
+
+openerp.im = function(instance) {
+
+ var USERS_LIMIT = 20;
+ var ERROR_DELAY = 5000;
+
+ var _t = instance.web._t,
+ _lt = instance.web._lt;
+ var QWeb = instance.web.qweb;
+
+ instance.web.UserMenu.include({
+ do_update: function(){
+ var self = this;
+ this.update_promise.then(function() {
+ var im = new instance.im.InstantMessaging(self);
+ im.appendTo(instance.client.$el);
+ var button = new instance.im.ImTopButton(this);
+ button.on("clicked", im, im.switch_display);
+ button.appendTo(instance.webclient.$el.find('.oe_systray'));
+ });
+ return this._super.apply(this, arguments);
+ },
+ });
+
+ instance.im.ImTopButton = instance.web.Widget.extend({
+ template:'ImTopButton',
+ events: {
+ "click": "clicked",
+ },
+ clicked: function() {
+ this.trigger("clicked");
+ },
+ });
+
+ instance.im.InstantMessaging = instance.web.Widget.extend({
+ template: "InstantMessaging",
+ events: {
+ "keydown .oe_im_searchbox": "input_change",
+ "keyup .oe_im_searchbox": "input_change",
+ "change .oe_im_searchbox": "input_change",
+ },
+ init: function(parent) {
+ this._super(parent);
+ this.shown = false;
+ this.set("right_offset", 0);
+ this.set("current_search", "");
+ this.users = [];
+ this.c_manager = new instance.im.ConversationManager(this);
+ this.on("change:right_offset", this.c_manager, _.bind(function() {
+ this.c_manager.set("right_offset", this.get("right_offset"));
+ }, this));
+ this.user_search_dm = new instance.web.DropMisordered();
+ },
+ start: function() {
+ this.$el.css("right", -this.$el.outerWidth());
+ $(window).scroll(_.bind(this.calc_box, this));
+ $(window).resize(_.bind(this.calc_box, this));
+ this.calc_box();
+
+ this.on("change:current_search", this, this.search_changed);
+ this.search_changed();
+
+ var self = this;
+
+ return this.c_manager.start_polling();
+ },
+ calc_box: function() {
+ var $topbar = instance.client.$(".oe_topbar");
+ var top = $topbar.offset().top + $topbar.height();
+ top = Math.max(top - $(window).scrollTop(), 0);
+ this.$el.css("top", top);
+ this.$el.css("bottom", 0);
+ },
+ input_change: function() {
+ this.set("current_search", this.$(".oe_im_searchbox").val());
+ },
+ search_changed: function(e) {
+ var users = new instance.web.Model("im.user");
+ var self = this;
+ return this.user_search_dm.add(users.call("search_users",
+ [[["name", "ilike", this.get("current_search")], ["id", "<>", instance.session.uid]],
+ ["name", "user", "uuid", "im_status"], USERS_LIMIT], {context:new instance.web.CompoundContext()})).then(function(result) {
+ self.c_manager.add_to_user_cache(result);
+ self.$(".oe_im_input").val("");
+ var old_users = self.users;
+ self.users = [];
+ _.each(result, function(user) {
+ var widget = new instance.im.UserWidget(self, self.c_manager.get_user(user.id));
+ widget.appendTo(self.$(".oe_im_users"));
+ widget.on("activate_user", self, self.activate_user);
+ self.users.push(widget);
+ });
+ _.each(old_users, function(user) {
+ user.destroy();
+ });
+ });
+ },
+ switch_display: function() {
+ var fct = _.bind(function(place) {
+ this.set("right_offset", place + this.$el.outerWidth());
+ }, this);
+ var opt = {
+ step: fct,
+ };
+ if (this.shown) {
+ this.$el.animate({
+ right: -this.$el.outerWidth(),
+ }, opt);
+ } else {
+ if (! this.c_manager.get_activated()) {
+ this.do_warn("Instant Messaging is not activated on this server.", "");
+ return;
+ }
+ this.$el.animate({
+ right: 0,
+ }, opt);
+ }
+ this.shown = ! this.shown;
+ },
+ activate_user: function(user) {
+ this.c_manager.activate_user(user, true);
+ },
+ });
+
+ instance.im.UserWidget = instance.web.Widget.extend({
+ "template": "UserWidget",
+ events: {
+ "click": "activate_user",
+ },
+ init: function(parent, user) {
+ this._super(parent);
+ this.user = user;
+ this.user.add_watcher();
+ },
+ start: function() {
+ var change_status = function() {
+ this.$(".oe_im_user_online").toggle(this.user.get("im_status") === true);
+ };
+ this.user.on("change:im_status", this, change_status);
+ change_status.call(this);
+ },
+ activate_user: function() {
+ this.trigger("activate_user", this.user);
+ },
+ destroy: function() {
+ this.user.remove_watcher();
+ this._super();
+ },
+ });
+
+ instance.im.ImUser = instance.web.Class.extend(instance.web.PropertiesMixin, {
+ init: function(parent, user_rec) {
+ instance.web.PropertiesMixin.init.call(this, parent);
+ user_rec.image_url = instance.session.url("/im/static/src/img/avatar/avatar.jpeg");
+ if (user_rec.user)
+ user_rec.image_url = instance.session.url('/web/binary/image', {model:'res.users', field: 'image_small', id: user_rec.user[0]});
+ this.set(user_rec);
+ this.set("watcher_count", 0);
+ this.on("change:watcher_count", this, function() {
+ if (this.get("watcher_count") === 0)
+ this.destroy();
+ });
+ },
+ destroy: function() {
+ this.trigger("destroyed");
+ instance.web.PropertiesMixin.destroy.call(this);
+ },
+ add_watcher: function() {
+ this.set("watcher_count", this.get("watcher_count") + 1);
+ },
+ remove_watcher: function() {
+ this.set("watcher_count", this.get("watcher_count") - 1);
+ },
+ });
+
+ instance.im.ConversationManager = instance.web.Controller.extend({
+ init: function(parent) {
+ this._super(parent);
+ this.set("right_offset", 0);
+ this.conversations = [];
+ this.users = {};
+ this.on("change:right_offset", this, this.calc_positions);
+ this.set("window_focus", true);
+ this.set("waiting_messages", 0);
+ this.focus_hdl = _.bind(function() {
+ this.set("window_focus", true);
+ }, this);
+ $(window).bind("focus", this.focus_hdl);
+ this.blur_hdl = _.bind(function() {
+ this.set("window_focus", false);
+ }, this);
+ $(window).bind("blur", this.blur_hdl);
+ this.on("change:window_focus", this, this.window_focus_change);
+ this.window_focus_change();
+ this.on("change:waiting_messages", this, this.messages_change);
+ this.messages_change();
+ this.create_ting();
+ this.activated = false;
+ this.users_cache = {};
+ this.last = null;
+ this.unload_event_handler = _.bind(this.unload, this);
+ },
+ start_polling: function() {
+ var self = this;
+ return new instance.web.Model("im.user").call("get_by_user_id", [instance.session.uid]).then(function(my_id) {
+ self.my_id = my_id["id"];
+ return self.ensure_users([self.my_id]).then(function() {
+ var me = self.users_cache[self.my_id];
+ delete self.users_cache[self.my_id];
+ self.me = me;
+ self.rpc("/longpolling/im/activated", {}, {shadow: true}).then(function(activated) {
+ if (activated) {
+ self.activated = true;
+ $(window).on("unload", self.unload_event_handler);
+ self.poll();
+ }
+ }, function(a, e) {
+ e.preventDefault();
+ });
+ });
+ });
+ },
+ unload: function() {
+ return new instance.web.Model("im.user").call("im_disconnect", [], {context: new instance.web.CompoundContext()});
+ },
+ ensure_users: function(user_ids) {
+ var no_cache = {};
+ _.each(user_ids, function(el) {
+ if (! this.users_cache[el])
+ no_cache[el] = el;
+ }, this);
+ var self = this;
+ if (_.size(no_cache) === 0)
+ return $.when();
+ else
+ return new instance.web.Model("im.user").call("read", [_.values(no_cache), ["name", "user", "uuid", "im_status"]],
+ {context: new instance.web.CompoundContext()}).then(function(users) {
+ self.add_to_user_cache(users);
+ });
+ },
+ add_to_user_cache: function(user_recs) {
+ _.each(user_recs, function(user_rec) {
+ if (! this.users_cache[user_rec.id]) {
+ var user = new instance.im.ImUser(this, user_rec);
+ this.users_cache[user_rec.id] = user;
+ user.on("destroyed", this, function() {
+ delete this.users_cache[user_rec.id];
+ });
+ }
+ }, this);
+ },
+ get_user: function(user_id) {
+ return this.users_cache[user_id];
+ },
+ poll: function() {
+ var self = this;
+ var user_ids = _.map(this.users_cache, function(el) {
+ return el.get("id");
+ });
+ this.rpc("/longpolling/im/poll", {
+ last: this.last,
+ users_watch: user_ids,
+ context: instance.web.pyeval.eval('context', {}),
+ }, {shadow: true}).then(function(result) {
+ _.each(result.users_status, function(el) {
+ if (self.get_user(el.id))
+ self.get_user(el.id).set(el);
+ });
+ self.last = result.last;
+ var user_ids = _.pluck(_.pluck(result.res, "from_id"), 0);
+ self.ensure_users(user_ids).then(function() {
+ _.each(result.res, function(mes) {
+ var user = self.get_user(mes.from_id[0]);
+ self.received_message(mes, user);
+ });
+ self.poll();
+ });
+ }, function(unused, e) {
+ e.preventDefault();
+ setTimeout(_.bind(self.poll, self), ERROR_DELAY);
+ });
+ },
+ get_activated: function() {
+ return this.activated;
+ },
+ create_ting: function() {
+ var kitten = jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined;
+ this.ting = new Audio(instance.webclient.session.origin + "/im/static/src/audio/" + (kitten ? "purr" : "Ting") +
+ (new Audio().canPlayType("audio/ogg; codecs=vorbis") ? ".ogg" : ".mp3"));
+ },
+ window_focus_change: function() {
+ if (this.get("window_focus")) {
+ this.set("waiting_messages", 0);
+ }
+ },
+ messages_change: function() {
+ if (! instance.webclient.set_title_part)
+ return;
+ instance.webclient.set_title_part("aa_im_messages", this.get("waiting_messages") === 0 ? undefined :
+ _.str.sprintf(_t("%d Messages"), this.get("waiting_messages")));
+ },
+ activate_user: function(user, focus) {
+ var conv = this.users[user.get('id')];
+ if (! conv) {
+ conv = new instance.im.Conversation(this, user, this.me);
+ conv.appendTo(instance.client.$el);
+ conv.on("destroyed", this, function() {
+ this.conversations = _.without(this.conversations, conv);
+ delete this.users[conv.user.get('id')];
+ this.calc_positions();
+ });
+ this.conversations.push(conv);
+ this.users[user.get('id')] = conv;
+ this.calc_positions();
+ }
+ if (focus)
+ conv.focus();
+ return conv;
+ },
+ received_message: function(message, user) {
+ if (! this.get("window_focus")) {
+ this.set("waiting_messages", this.get("waiting_messages") + 1);
+ this.ting.play();
+ this.create_ting();
+ }
+ var conv = this.activate_user(user);
+ conv.received_message(message);
+ },
+ calc_positions: function() {
+ var current = this.get("right_offset");
+ _.each(_.range(this.conversations.length), function(i) {
+ this.conversations[i].set("right_position", current);
+ current += this.conversations[i].$el.outerWidth(true);
+ }, this);
+ },
+ destroy: function() {
+ $(window).off("unload", this.unload_event_handler);
+ $(window).unbind("blur", this.blur_hdl);
+ $(window).unbind("focus", this.focus_hdl);
+ this._super();
+ },
+ });
+
+ instance.im.Conversation = instance.web.Widget.extend({
+ "template": "Conversation",
+ events: {
+ "keydown input": "send_message",
+ "click .oe_im_chatview_close": "destroy",
+ "click .oe_im_chatview_header": "show_hide",
+ },
+ init: function(parent, user, me) {
+ this._super(parent);
+ this.me = me;
+ this.user = user;
+ this.user.add_watcher();
+ this.set("right_position", 0);
+ this.shown = true;
+ this.set("pending", 0);
+ },
+ start: function() {
+ var change_status = function() {
+ this.$el.toggleClass("oe_im_chatview_disconnected_status", this.user.get("im_status") === false);
+ this.$(".oe_im_chatview_online").toggle(this.user.get("im_status") === true);
+ this._go_bottom();
+ };
+ this.user.on("change:im_status", this, change_status);
+ change_status.call(this);
+
+ this.on("change:right_position", this, this.calc_pos);
+ this.full_height = this.$el.height();
+ this.calc_pos();
+ this.on("change:pending", this, _.bind(function() {
+ if (this.get("pending") === 0) {
+ this.$(".oe_im_chatview_nbr_messages").text("");
+ } else {
+ this.$(".oe_im_chatview_nbr_messages").text("(" + this.get("pending") + ")");
+ }
+ }, this));
+ },
+ show_hide: function() {
+ if (this.shown) {
+ this.$el.animate({
+ height: this.$(".oe_im_chatview_header").outerHeight(),
+ });
+ } else {
+ this.$el.animate({
+ height: this.full_height,
+ });
+ }
+ this.shown = ! this.shown;
+ if (this.shown) {
+ this.set("pending", 0);
+ }
+ },
+ calc_pos: function() {
+ this.$el.css("right", this.get("right_position"));
+ },
+ received_message: function(message) {
+ if (this.shown) {
+ this.set("pending", 0);
+ } else {
+ this.set("pending", this.get("pending") + 1);
+ }
+ this._add_bubble(this.user, message.message, message.date);
+ },
+ send_message: function(e) {
+ if(e && e.which !== 13) {
+ return;
+ }
+ var mes = this.$("input").val();
+ this.$("input").val("");
+ var send_it = _.bind(function() {
+ var model = new instance.web.Model("im.message");
+ return model.call("post", [mes, this.user.get('id')],
+ {context: new instance.web.CompoundContext()});
+ }, this);
+ var tries = 0;
+ send_it().then(_.bind(function() {
+ this._add_bubble(this.me, mes, instance.web.datetime_to_str(new Date()));
+ }, this), function(error, e) {
+ e.preventDefault();
+ tries += 1;
+ if (tries < 3)
+ return send_it();
+ });
+ },
+ _add_bubble: function(user, item, date) {
+ var items = [item];
+ if (user === this.last_user) {
+ this.last_bubble.remove();
+ items = this.last_items.concat(items);
+ }
+ this.last_user = user;
+ this.last_items = items;
+ date = instance.web.str_to_datetime(date);
+ var now = new Date();
+ var diff = now - date;
+ if (diff > (1000 * 60 * 60 * 24)) {
+ date = $.timeago(date);
+ } else {
+ date = date.toString(Date.CultureInfo.formatPatterns.shortTime);
+ }
+
+ this.last_bubble = $(QWeb.render("Conversation.bubble", {"items": items, "user": user, "time": date}));
+ $(this.$(".oe_im_chatview_content").children()[0]).append(this.last_bubble);
+ this._go_bottom();
+ },
+ _go_bottom: function() {
+ this.$(".oe_im_chatview_content").scrollTop($(this.$(".oe_im_chatview_content").children()[0]).height());
+ },
+ focus: function() {
+ this.$(".oe_im_chatview_input").focus();
+ if (! this.shown)
+ this.show_hide();
+ },
+ destroy: function() {
+ this.user.remove_watcher();
+ this.trigger("destroyed");
+ return this._super();
+ },
+ });
+
+}
\ No newline at end of file
diff --git a/addons/im/static/src/xml/im.xml b/addons/im/static/src/xml/im.xml
new file mode 100644
index 00000000000..795d1b3e698
--- /dev/null
+++ b/addons/im/static/src/xml/im.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+ ô
+
+ [
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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.form
+ im_livechat.channel
+
+
+
+
+
+
+ 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