diff --git a/addons/account/account.py b/addons/account/account.py
index 1a44e480e03..529cbf96623 100644
--- a/addons/account/account.py
+++ b/addons/account/account.py
@@ -1384,6 +1384,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 +1421,7 @@ class account_move(osv.osv):
context = {} if context is None else context.copy()
default.update({
'state':'draft',
+ 'ref': False,
'name':'/',
})
context.update({
@@ -3401,7 +3403,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:
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 222a0bebbb4..4feee980ae5 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -313,7 +313,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 +367,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
diff --git a/addons/account/wizard/pos_box.py b/addons/account/wizard/pos_box.py
index 49178dfd3ea..810d101eefd 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)
diff --git a/addons/account_analytic_plans/account_analytic_plans.py b/addons/account_analytic_plans/account_analytic_plans.py
index 5834db99cd3..40a227d8ceb 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
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_asset/account_asset.py b/addons/account_asset/account_asset.py
index 5a22a888772..c35e1c4e807 100644
--- a/addons/account_asset/account_asset.py
+++ b/addons/account_asset/account_asset.py
@@ -80,7 +80,7 @@ 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)
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"
+"
- [[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/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/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/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..9dac1c4d262 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)
@@ -684,7 +684,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 +754,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:
@@ -853,13 +853,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':
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_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/crm/crm_lead.py b/addons/crm/crm_lead.py
index 6d195fec383..2361f12d61b 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
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 3001e8b1d88..d94683f895f 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -152,7 +152,7 @@
-->
-
@@ -429,7 +429,7 @@
-
+
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_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/wizard/open_questionnaire.py b/addons/crm_profiling/wizard/open_questionnaire.py
index cb7ad220e3f..be0d2ef54af 100644
--- a/addons/crm_profiling/wizard/open_questionnaire.py
+++ b/addons/crm_profiling/wizard/open_questionnaire.py
@@ -61,7 +61,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'}
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_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/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/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/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/google_docs/google_docs.py b/addons/google_docs/google_docs.py
index cdb14de1de3..3b060e199c0 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)
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
+ 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
+
+
+
+ John Doe
+
+
+ Grand-Rosière
+ +3282823500
+ jod@openerp.com
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBhQSEBQUEBQUFRUUFRQUFBUUFBQUFhQXFxgWFBUVFBQXHCYeFxkkGhUVHy8gIycpLC0sFR4xNTAqNSYrLCkBCQoKDgwOGg8PFywkHBwqKSkqKSksKSwsLCkpKSwpKSksKSkpKSwsKSkpKSkpLCkpKSksKSkpKSwpKSwsLCwpKf/AABEIAQQAwgMBIgACEQEDEQH/xAAcAAABBQEBAQAAAAAAAAAAAAABAAIDBAUGBwj/xAA+EAABAwIDBQUGBAUDBQEAAAABAAIRAyEEMUEFElFhcQYigZGhEzJCscHwB1LR4RQVI2JyssLxJDNDguKS/8QAGQEBAAMBAQAAAAAAAAAAAAAAAAECAwQF/8QAJhEBAAIBBAEDBQEBAAAAAAAAAAECEQMSITFBBDJhEyJCUcFxI//aAAwDAQACEQMRAD8A83hEBEBGFRcIToShGEChKEYRhAIRhGEYRIQktvZPZapWG+4inTtDnAy7kxvxfJdBR7I4Zo75qOvmXMZe3wgEx4+qjI4WEgu4/keCNt2oMripMyJyIVrC9lMDvd41jyJAjLg3r93TI8+Rhep0dhYFmVHem0ubUd0z6cFG/AYJ1vYszGTCPkROt0yPMIQhej4ns1hHghrHNiDNLenKfiJB8tVg4vsSZPsKgf8A2PBY/wDQ9bJkctCSuYzZdWkYq03N6ix6HIqqQpDEoToShA2EoToQhQGpJ0IQgEJJySIQQnAJAJwCkABGEQEYRIQjCICMIha2TgxVrNa6d2ZdGYaLkrew+yMN7ZzgXOptiKbyCS+xgkR3Yc3neFX2LRDKL6riBvWHGARPnfyWX2Xxzqj6zjlvGD1IJ15DyUJdlVx5NxbQcAIyA0FvRU2PeQXSbi9zrx8imRvCBynmLOiZTi6H2ndgjTgNDnHHnyUAjEuENBmPdJib3AuJiQoquOJIhxygRxtJt9OJQqnu2tcWPP1BtpZRvYJPQZ6QAeEjP7ugl/jqvvBz72s4+M/eis09r1SPecYOsTExBn5dVTY+CM8sgIgicgeaayuBE2zzHP8ATrkgvHbTyc7cMom59AfXil/OnERvC1r3mMxObf3WW/ei3GJyA4ffJRj4pGUQeeufVB01Pa26DvSWmQfiBnjxPVZeL2JRrDepxTcfy5STaWaDp5LKNYtsJAIkkER0jLNTUseZ3rTIiJB6+nogobQ2FUo3cN5v52neb4xl4rOhdXT23G8CQRMQbGLz1nnwWXtWgxxL6Td3PebNuO83lGY5KcjJhCE6EoUhsIQnwhCINSTkEEQCcAkAjCJJFKEQEQSMJQp8HR3qjW8SAiWnt+r7DAgCzvZwePfuZPTeWZ2IoxRLj8Tj6WS/ECsdyN43eGx0k/ULT2RSDcPTa3ukNF+ZGnO6jwjy0WOdp1MHqb8PVJ1Tee2/9swORtdPNSWuhwMNAga3vrn55Jlal3oiLjdvkYABgeN0SjfmQTPeF+kifVCq0uceYuBaLDThF09rIDpOTj8zYD795RvqXufhniZIEQoSY9pBbc717wDqYE8EH9OJm2ZuZMKRrbtIjObi+YJ58PNNe+0AC7r3jjYRqgjc838iQCToZ5C5TXgTY6ax4g+SfUqTMETaNTkLTPX7KiqgwM8rxOdxEDmiEWUHOWzy5fNQlwEzwPpfPQQnvMkEwInQAxzAvqq7wIzN79RcmfvVSD7QZEiLGPCJ1UDsRqLxe+Xj6+aFarl0HISTkqz32Pl4qBaqATLcjccuR5jJNhNoGWzzP0T4Vg1KE6EoQMhJOhJBCEUUYRAQnAJIgIkgFe2R/wB0HgCfSPqqYV7Zebug0nWUGZ25YSxjuDgDnqNdNFvbMqf02Otk03mAfdjyVPtLhzUw9SIsQ4WnLeNj0J9Fb2eQ2jTGoYLW1Av5wo8I8rzWSRED3Gm3p6IvaQ10/ERBj15ZqH2sCJBuLnOQIOmSbUqHdGfxAExu2AvOuSJTPw0F5mLjI2nIfOfBMqaZzunOYBAPK565KH+Ic7elwkxrzBNrxnopg7dcDvADd0JPw5+o8SoBbQdDI/MYyHA5c5UVVp72d3DTre1lNTrtAbJuLujd/NyJA/4KipuaQbjMAXnjPLh5qEq9VvvXMcb8OGWaiNt2RwmLHMzHkdFdrtEWkSL3EZZeQz5Ks1tmm13HgeZN0QpucJBHHiM7a9TkoajsiTOZAEWz/VSVsKYEXvyIvefvgq1SiWgeP7AKwjrgESMx6eHiqjnQIH39yrBfMi8WUDwkoWMDiAd5mrb+djby81ZhYmwqv9Z4OZLvqfot1SGwlCMJIk2Ek5JBBCICQCIQKEUYSQGFe2b8XQfPRVsPRL3taM3ODR4mF2+wn4Wvv4b2RYWyA8hveOU74uHcj+yzveK8N9HQtqRMx1Dl8TjWtmTaLgxfXLrfwUOyalOs4spvI3WmRY2yAAnIQPRZfbzY+IoVA192H3XNyPXgVR7F7IqVMQNwkbufC+YPHRTFoxlnNJi2127djNMBxJiZkkT1A8lMdmUhaAbEjeJMcLSfvyVzG4V1M9/ugwC4Tum+X1hRuYSLgGIPAAHS+d+PFItnlE1mOJRfwNPds1oI5Dw00Q9g2fdAkGYaJjL5j1UpbNwC0EEOztxy8DZN9jYgZi4sbDW3MNnwUIVjh90nutEZ5X8Iy/VDcAyA7wv5yfpZSveW31yO9mZzN9FFXLBZz2NmD77Zvr3Z4RCJJ7RfutMcQDIHGRbxlRP3TbdHhYZaqB22KLf/ACX4RPpaf3QbtehIh5ANzIiD/wAc0Qe/Ct0ka5mZ8R9yqGJwJbqHAcbHSw8Z9Faftqkbh7dJzuOMfead/GMd7rh148ZUjEqDiIiMxeL5qpUaIEa8PvktvFYQPzzOULJxWHczO4ynIjqFOUM/Yzf+of1d8it5YuwMN33vP90dCbfVbasg1JGEoUAQgnJIIAE6EkQpSQRASARQWdm1N2tTccg9s+a9C2PsxlGi91TWTPif0XmwXfbTxLquCp7ubxTJ8Rf1BXPrx1L0vQ2zE0/yXJ/iDtH2lZrWvD2Umb0zq4m3WwWr+FmzRDnamTKxtvdnvZURWcSd5wDuAgOMfJdp+G+BNPD7zhBqd4CMhp+qzmcUVtX/AKy39p4YFhBC4/G9nyJNNxbxg2jpku7xzO6ei4faYmd48dZHkVnWcT20xExzDl9ourUzHtTyEibZLPrbTxJze7TXhkeoWhjdl73u1GjpLfkVi1dm1WZPt1ldEW+XPNMT7S/qOneJM53N09mEPkpMNinAw4StWk0G6ra0wvWkSxTgyFFUw5hdFUoDgo/4UAKsXTNHJ18M7mq289mR8/1XVVvZ6kDqsrFBnEFaRaWVqwGB22cj6/rqtUVmvFiDeP8AlYWNwQFIuF53cuoVvB4N5pgz3ufDmtInLC9MNChRDRDeqfCqUsWZh4IPnKuK7I2EkYSQCEkYSUiBOAQATgiSRCQRCAhegdhKja1L2biA6kciJlrjIt1kLz8LR2HtY4esHi4ycOLdfHVUvXdDbQ1Nl8vSO1XZ2m/DOpxDC5rjBNnBwgwdInzUuzAGMa0ZAAJuL2qyrh2mm4GXN18boUn281xWd8e7lsC4hcx2g7G060mXN47piVu4SqtB9EOURBb7XjuO7B0WhwBdvH3XEl0QsnZnZtlMOFUudmW7sggxnvEC3LJetbZ2U1wNo5yuUxHZ0k90OPVafUtHEqfTpPOHF0MBUmAJiLzIz4rpMBsYyJ1XR7J7IlneqeDRkOvFaDtnwbcVWZTDmamzN0GdFym2sWGEyeUBeibfobod0BXA7Uwkm7RyMT1SOJTbpzdDEtquLQ182tLZMkNAEm5lwsFbZg6clsua4WLXCCOoK1cFgAxwe0br9DAMdJt4qSpskOfvvku1Op5dFtN4xwwjTnyxsRhCwNzLS8fVaVPJWNoUp3RoDPkCPqo4WmnOYy59aMWwaknJQtGRiSKUIGwkikiEITghCKlIohBEICigE4INHYVUiuy9r28Cu/o1LDw5LzvZX/daeEnyF129GtLei5Nft2+n6b1B60GVbWWDh8SIlaeGxIOqwiXZaMwmrUic0KVMDhxTzUssfaW1S0GBc2F1OcM9szw13125KI0p6LP2bjKYa0Pe0Pde5uVtYOmJzmL2V68k12ub7XWa7wC5EskQRIXX9o277Hk6LiGY/dfuv1Ej5Ktu1scLNLCBOqUBCs04hQ1nRKonDDxnvRwUCkrOlxPNRrv04xWHl6s5vJIIpK7M1JFIoGpIpIIUUAnKQkQgiEBCmw2HdUe1jAXOcYaBmSoguw/DbBb1d9Qj3GFrf8ncPAHzSZwtWu6cK2B2QylXaxzt+puu392NxloLZzce9mpsFXglrs2mD1EhQdlWmpi8W5wvTd7PLXeJP+n1Um1qXsq4f8L7HgDlPl8lw2ndPL0tsUj7Wvh3cDOh/RauGeVk4F4zkH5HotqkFk13RhLVxFlBgqAed4ieEz9UMXiGtzi0eJ4KHD7VDrNMnkcuqRGZUmTO0PZCjiQ0uEObkbeSxf5zUwXckuAGZJPgSb+a6HFYnu997Wjm4D7C5jalNlZ4DarHATMOH3C2WrumEVbtZ7VhbHvZ8ljbRoBzQ5ubb/qpccKDXbrajeFspyzyUP8AFMMtDgTunIg6HyUTCszMLmBxXcuq+LxljGeSL+60HKWieqoaqNOu6ymrqbahCUIpLueYCCISKAIFFBAEUkkEKKaE5SEnBNJUNTHNGs9FIshel9kMAcPRbve8477hw3hYdYhcl+H2DbWqh9QAgElo/wAY06keS9I+LqqW/Tq9PT8lR2zGUqlU0xHtne2PMwGu+Q81i7ZwYqMc06/YhdZ7HebBzb7p+axMXSgkOEH59Fx3rMTl2RDktl44iQ6ZYYPPgeWq6LCbVAFuvVYO2MEWO9ozMe8OLcyjhcUHtG6Re8C3SFSVOpapoCs7vG3Dqnv7IYUSQHga7lRwnnY2UWz2u4ff1TsRinsGSROGsSz6vZrBgzvVmn+6o48dSVlVuz9GT/UfGnf+dlLtDalUmGsnwlZDnVibgdIWu5r9WI8Iq+x6e+Qwlw1Jk+F1bZhmshrQAI0RpggXUJeXu3W5nM/lAzKrM7pY3tk3aGM1MhgO6XAGAYsCdExlQHIrdwzhSbugS0iCDBnrOa57aWzxd+HBbF3UvhPHcIuw8sui6dOIrGHHq0tblKUlg/ztzY+JpEibGFew22qb8zunn+q1w48r6SDagORB6JKEkgiggSSSSCuXAZqniNpgWbfmsqpiCcyVE56vhXKzXxxOd1E+qoHFAuUj1L8JawvxG/6ln7eS9CxNnTovI/wqxobidw/EQPBwLfnur12q6QQdPsrG/b0vTc0W6DpEqPamz/aMsYcLgxl+vRVcHX3bHJbNN1vqq4zDWftlwGIcTvMcIc33hnbiOIK5fHYd9F+9TmJkt48SF0vaTtjgHVxRbV/qSQHtBLWn8rnDME8FSqUi4Qd13HdId4x7w8lzTWayvMReD9jbea4AtgmDI1nWeC6RlVjxcDhpdec4zZoDt6k4sd5g9eKFPb1ekIcN6LS10+majET0yxNZ5d3tB7GtiAPBYeLrt0+i5iv2r3vfcRyIIVLGdqhHdl3DQeZTZMp3Q0dsbSDRAzNgNSeSk2JRgSfecfv75rkX7S3Xh9Yy4/CL7reJBynhnquw2PimVADTIPT6jRbRTbCsWiZ+VzH1Yaeh/RV8C6Gm0TfqOIUG2sQLN8T00+qr7NdxM8OQVl8cOT29S3KrwMg8kdHDe/VUGV1s9rG/1Xf4s/3Bc8uis8PL1YxeV6lji090kdCtHDdoHj3ocOdj5rABUjSrMnW0NuMdnLfUeiv06rXe6Qei4hr1NSxJBsYUbVsuzSXMjbNT83yQUbZMqxKaUEldBBBEIDVBqdnMaaWIYQYm3jmPUBe9txIqMZWb7rgN7lOvgvnJjogjSCvc/wAO8d7XDOByMHpvXI8w7zWWpDt9JfEzDSxjSw8s5Hz6LmPxN7Tvo7PDKRLXVXbhcMw25Inw9V25w1t12Wh4Lj+2XZY16LqYzmW6wRkRy/dZw77xurO3t4dhCd8Obm0gjqDK9Tq9uxjHUvbsbTe1pDqm8BvuhsCTE3Djc/Frp52dkvpvh3ccDEOs13R2RWqymYuwyfeYcnDix2RK2mImHmae7TtnDsNoVmES10uvl397xb9f2XNYjGFy2uzu0wyKboh3uPjdM/lfzWfi6lOnVc9rd4ky0RLWnVxmxMzA0zPBc9tLnh3fUi0ZU6OwnP71TutiQHfF4cPmsraWLZTdFKHOHxQIb0581a2ptOpUBDbTmSblZAwu60kiePCdBzV60x2x1NTxRn1CSSSZOpOq3OyNR7K4cJDYO9wiE3ZmwKmIeLBrczpA/Wy6ars9lLdpU8yAXnlo36+Cta0dM9HRnO6SBNRxcdfsBOwFLvkFWMPhjCs4fDQ4nksna43tUP6j54U/qufXQ9rD/Ud1aPJs/Vc8t69PK1vfIBHeQhJWZDvIhyaigl9qUlEkiF5FNlOCskkm5pIOzQJel/hBtYCoaTj70i/PvN9QR/7BeauC0ez+0DRxDHC1wJ4XBB8CAomMwvS220S+kGU1DisODEgHiOI1Cbs7GirTbUGT2g20Oo8DKtHJc71Ys5HtbsajUxVP2bGubWa/epkRJpxLgCLG/jBXMY78PGi+GqPZM9wkiOQORHVel/y5jqgqEd5s7pkxfMxMTzUWKoCZjPPgVJivEPI8NsupSLmVwT+VxzkdcrKpjcJF16N2twwGH3jmx7I1zO7E56nyXDY+IM/OFrW3Dl1KYt8OTxL72W/s/Yg3AH6d53U/YCycJQDq/wDa3vX14eq6nAsNR4baLE89VS88tNGsTGWl2XrDCNe5zA4kSBxDrNB6xCr0NnG5cO8TJIWlicKPatkTAEeCvswt/wB1l26orEcshuE9U91DdBWpWwigxbAGnkiXlHap01T/AJO9ICxIWnt981vCfMkrNhdMRw8S85tMmpIpQigJJwCUIGopQkpFwJwQanKUmpP/AESlJwsUDtExpTgU059UHtn4V7Y9rQNMm7bjxs71E+K7hzF4V+G+2fYYoA5HPobO+h8F7s4rG0Yl6GjbdWAAumlpjROb4JuIqBrXOcYABJ6ASfkqtXFfiRjIoCjTP9R5Du78LRInlJy/xK4w4emwb263eAjeIBd5m60NpY41ar6js3EW4DJrfAALBxlQklaxGHPa0XlXwfeqnK4K7HYmEh3l8guIpEtcCNF6F2WqNqAObykcDqs7x5baFsRtntfxGH77VpUMPCjxLe+tLDe6FR0TPChWp2Kytsd2i8j8p+S3sYLLne0tbdwziTpH1+iImcRMvGdqP3qzyOMeVlVIUj7kniSfNNq5LpeKiCdCTQiiACUIooGwgnwggtBElAIlSkCUQE1OCANyQqIhJ6CbA4k06jXj4TPUajyX0P2X2j7fCsdMkDdPUa+IXzg1eufhDtuWOouOnd6t/wDkj/8AJVLxxl0enti2P29Ka1ZvaEOOGqgHNpy8ytP7Ko4lkyDkfqP0WTtxl4y7Hb1Wqwf+PcHiQ4u+g8E2sbQoMNhyzHYym7NtT5FwB8iFYxC1xnEywraaxatZ74n5hQqtutzsdtL2dcD4XGD10WI6+Smw003B2ocD6pbHSNOLcW+cZ/j1Vxl0rWwjAQsXZz98A6wCugwgssHbbpn7Rb0XE9vsTu4YjKxjxt9V2m1HXtK84/E7Gd1rOMfU/QK1e2etO3Tl50AmV/qpAFFWNwt3kk0IkIhJwQNSRSUBQkkkhhYSKCBKsCigE6UAQqFEBMqoDkV0PYna5oYpjpgSD1jTxBcufenUKpa4OGYII8FEpicTl9QNeC0EGxEiPPRQ1c+qxuwm1vb4NvFkN8Ilp8reC2K0yLeqwl6tcTy4Dtn2dDMV/FMiKrBTqDLvtgtcOrRH/qOK5DHu0Xp/bgzhJ4VG/wC79V5biLuWtOnLqxi3BYZkXUWMqQrVMWVHGuupxhE2m1cZ+cf16p2ccTTaeQXS4U9391zHYx4dh6d82jgulpjOB8uqwdszlR2qJd+y8e/EXETiQ3h+w+hXr21nQQfkvDu1mJ38W8nSB9fqr07c/qbfZEMghV3XcrBNlWp5rV56WEnp0JrygCCcggakkkoQnKCSSkFP0SSRIBQ1cwkkiEkoNSSUj1T8HMU4+0act0+hEf6ivScUIARSWF+3paHthzfbQf8ASP5Fn+oLzTdukktKdM/Ue6DnuWbjSkkrSwjt6V+HNQ/wzerh6ldi2nL78AUklzvQ8MXtI7d3o0DvkvB9qPmtUP8Ac70MJJLSjk9V+KpUNvBR0Uklo40rk1xSSQJNSSQNlJJJEP/Z
+
+
+
+ João Gomer
+
+
+ Auderghem
+ +3282823500
+ jog@openerp.com
+ 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
+
+
+
+ Juan Gomez
+
+
+ Grand-Rosière
+ +3282823500
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBg8PEA8QDw8PDxAQDw8PDw8PDw8MDQ8QFBAVFBQQEhQXHCYfFxkjGRQUHy8gIycpLCwsFR8xNTAqNSYrLCkBCQoKDQwOFA8PFCkYFBwpKSkpKSkpKSkpLSkpKSkpKSkuLSkpKSkpKSkpKSkpKSkpKSkpKSkpKSwpKSkpKSkpLP/AABEIAQoAvgMBIgACEQEDEQH/xAAcAAACAgMBAQAAAAAAAAAAAAAAAQIDBAUGBwj/xABBEAACAQIDBQYDAwkHBQAAAAABAgADEQQhMQUGEkFRBxMiYXGBMpGhQlKxFCNicpKiweHwJENTc4Ky0QgzNGOD/8QAGQEBAQEBAQEAAAAAAAAAAAAAAAEEAgMF/8QAHxEBAQACAgMBAQEAAAAAAAAAAAECEQMhEjFBMpEi/9oADAMBAAIRAxEAPwD1cCTEiJMQACO0I4CtCOEAAjtGIQCEcIBC0ccCMI7QgKFo4QFC0cIBFaOEBQjhAUI4oFAkxICTEBxwEIBACEcAjhHAIQhaA4QhAIQhAIQhAIQhAIo4oBCEUBxQhApEkIhJCAxHARwFHCEBwEI4BCEIBCY+N2jSoLxVXVByv8R9BqZz+N38pJ/26bv5t+bX/mS2RZLfTqITzuv2hYj7IoqP1WaZGC7RqmXe0VcfepNZvkZPKOvDJ3kJqNm71YXEWC1Arn7FTwN7X1m3nTjQhCEAihCARRxQCBhFAgJISIkhAkIGAgYBHEI4BHCEAmi25vH3TGjRs1a13Y506IOnF1bymw2zj+4ou4+LJaY6uxsv/PtOD7u18ySSWZjq7HVjPPPPT148PJDFV2ZizMzudXbNvQdB5Ca+tTvmZnusoqJM1y23Y4yNNiqVphKxBuJs8YJqnMTIyxZ1OstTwtkeTaG/rN/sDfmthKgo4smrQNglTWpT87/aHlr0nHGoJkhxWXgJ8QzUnn5es9Mc3hnhHulCutRVdGDKwBVlN1IPMGTnm/ZftxhUfBuSVKmpSv8AZYfGo8iM/Yz0iaJdslmqUIQlQoQigEIRQEIxIiThDEIo4U44o5QQhHA0G9b5Ul83f3ACj/cZzq07zfb1nx0R1Sp/uSaVDaZeT218P5UnDSqrh5sA8oxNQTz0991oMXh5p8VRtedFjMppMawznD09tI97wo1CGBHKW1VlNPWNuLHRbAxHdYzDVRke9QNna4Y8J+hM9ong+Ce1eh/mU/ownvBmzjvTDy+yijino8hFHFAIoQgREkJEGMGESjEQjhTEcUcoIQjEg4rbuMqPimRlULSVlS17kGxJbzyHzmKGF8zNpvFhQlct/iLxehACn8BOS2rW4Dn3rsxsq0wPTU6DPWZcvfbdhrU035ta95g4yrmBrecTX2tVpYhqRDjhzJ77jXVhyA5Lfnkw6zrNnsKtPizuL5NqJzeneNlSxagqJz+Pp2uZZtvbq0gVJ06TS1MQzU++d2p0iwTi4HqqCSBYldM2Ue4nGvJ3cvEqjSNKQdbgFKqVB1U/QydCc6S1k4GqBisPxMFUVKfExyVRxAkk9J7js3a9DFKXw9RaihuElbix1zBF54HXp3c9LAW0udcp6L2T0XviqmfdkUUHTjHETb0BHzmjjz/14vDk494XPfp6HFCBmljKBhEYBeKEUCIjEiJKETEciDJQp3jijEIcYkZIQNLvOg4aZ5hiPYi/8JytZOc6zealemjX+FyLdeIfynLPXVQSReZuT9N/B3i1OL2cjm5/CXm1KmQMvD/CXUsVxi4p2XqdTMbalMmk50ytPOtEjgMc/eOSc/FebbDCm1IU2pqVBBAtkG6gaXzmoqeFjlfObbZtVHyHhYcus5nRqWsbE7KFwVAW3TLLpBFtkJn4ziAmBROfznP1MsdFjKTlkVRmbZ9P5me57vbIGEw1KiNVF6h+9UbNj88vQCeSbAwz1cbhkReI95SZsrgU1YFifIAGe2TTwzu1l58rrHERGOKaGQSMcUBQhFAiDHeRElKiQMmJWDJgyCQMcjHCpRyjEYpKSl6jpTQavUZaaD1JynD7wdsmAw4ZcNxYuqAbcAKYcNy4nOo/VB9YHS71YqmtNFZ1V3qDu0LAM/CpLcI52Gc5DGUsr3Nuds55Rjd6sViMUMZWqF6oYFeSKoOVNV+yvl59Z6ts/GLXopUX4aiBhfWxEz8s+tXDlqaUGq9rKNOVpTiMcWp8BGZOV8gZZiMKTwVVZ1dGsyhj3brfMMt/rqMvSFbF4dwFdqtEm3xBai+oOXnPP41zbhcdh6wdvDbn4dfnKsPxJnYj8ZvtqVKK8QR3qnkTamumX1mqwNEvU4nfw8kA8AHU3zM4LttHqd7SVuZ8J9Zr6a+IDzm2xtVUREXpxH1M1eC2xhcPiKT4rjNPjuy01DOQM7WJGV7A+smM3k4zz1O3te7ezFoYekAiq5poajBQHYkXsx1Nr8+k2s5rYnaLszGMEpYkJUOlKuDQdj0Xi8LHyBM6WfQ1p863ZQhCEKKEUAMUcUCAkpESvFYynRQ1KtRKaLq9RlpoPUnKVF4kxPPtu9smBoXXDq+Lfqt6VAf62Fz7D3nn28HavtHFgotQYamcimHujEdDUJ4j7EQr2bb+++AwFxiMQveD+5p/na/7I+H/AFWnm+3+3Cu91wVFaC6CrVtVreoX4V/enlrVCSSTcnM+ZkSZBn7X2/icU3HiK9Ss3I1GLAfqjQe0wklFRpcsKsWe4bn0PyjZGErUxd6KPRqKNWWnUYD3AsfQzw0T13sL25/5ODY53GJpD5JUA/cPzjUymqS6u429BgGK8mHF76GYe2VAAB05aZX5WM6Tend8qTiaCFiLl6a656so/ETjcVtVWAu1uo0IPSZssbi3cfJK02LpK+lzbloAZiN+bHmfTrMnaGIVc0YaXOc1JBduNrgai/OeWnpll/Vz4ktr6TT75YbuqtBSLN+TKz/rGrUOfoMvadbsPY5JFWoLKM0B1Y8jbpOH3vxxq42ueSN3S+iCx/e4vnPTinbNy3rTVs1x6Ts9ze1nG4ErTqscVhhYd1Ua9RB/63OY9Dcek4gNKic5qZn09sbtM2XiuELiRSZvsVx3Bv04j4frOnVwQCCCDmCDcH0M+Q6Fa03ex97MbgWvhcRUpi9zTvx0W9abXX6Qj6hhPL91u2ylVK08fTFFjl39IE0SerpqvqL+09LoYhKiq9NldGF1dCGRh1BGRgTMIQgcjvl2gUNm/m+E1cSycS0hki3+E1G5A9Bnly1niO8O9GKx9TvMRUL2vwIPDSpjoi6D116kzYb/AFdqm0saW5Yh0HkqeBR8lE5hzY+v4ygJkSYzImAiYiYExSKhzlwMoOstUwLOKb/cjbH5HtDCVibKKoSp/l1PA1/Y39pzl5byhH1zOb2/u3TrXZVVX5+EEN/OX7j7a/LMBha97saQSp/mJ4W+ov7zC37273CUsNTYitiiU4lNnpUrHiqDoT8IOouSMxGclna42y9ODx2zFBJL4amoYrxPWopexsSBe5F/KdFgN0sKqJVZ1xDModGGdCxFwVH2vU/ITy7aGDFMsAMgb58TEaWLcXiGV7KfedHuPt9xx4RibENUpXOasM6ie4u2WQKnmxmeeM+Pa55V0W08StMOxPhRSzHyAuZ4XicQaju51d2c+rEn+M9K7Q9pd3huAHxVn4PPgGbfwHvPL51xz65yTBkSbmSCxcNj5T2eaQlq1eRlZhAvDdJ0O62/GL2e16FTwE+OhUu9BvPh+yfMZzmRJqYH1XsLa64zDUMSg4VrUw/CTcqdGW/OxBHtM6cJ2MY81dmcB/uK9WmP1W4ag+rtO8hHzTvXiTVx2Mc6tiq/yFQgfQCaPELcTZ7bxi1sTiKyjhWrXq1FHQNUJH4zXtKMdGuL/wBXjMiuTW5HT1k3ECpoxEYxIqI19cpIRMsA384AxlqHKUMZOi0D2PsM28Fp4vDVGAFP+0KToFtZz9AZrt4MZUxeLq4ojwIycIYcSrTDcKqR73PnecFsDaLUK/hJAqIabWNrrcNY/s2956BtDblEJilAzqjDLTVRrwsGex0FgRmeslVq95LBr9cweK7Z8WjEfGbjI6TVbARkr0KugauaYysLW4W/3Ee02O8BZi1gQaVNe8BN2XiZV4T943vcnxWzk2VKGFwtQ2PdqlUWyBY+Mj6zN9d4ua7QNo97i+7B8NBQn+s+Jj+A9pzSiSxOIao71GzZ2Zz6sbwpiaMZqac2pgSL8h1/CWWlV8yfYTpyZOcnaVS4Qogp1jkRoIR6r2Lb0rRc4FwAMQ5em/MVQtuA+RVcvMec9nM+Vt3No/k+LwtY5CliKNRj+itQE/S8+pqNZXVXRgyMAyMDdWUi4IPS0I+ViZAw4svORJlFOIXLzGYkg3EoMbiUUHsxXkcxAcZMHykbyKmsOGJTJwKGMlSMVUSKGBkFyCGH2SD8p3WxaYZKNY+IFQ1/ia9zeitza5Kg2HRb9JweonYboYm+GKm96buuRs3CfFYGwt1vf7Ok4z9ES27icqlreMi5ybQEAg6m4NmPIzG3rxv9joKp1WiPOxo5yG2G4mOntcJn9wcqbcvM3nN7SxzVAqnSmOEfIAfQTyxm679RgCZFMSmkLzJUT3ck55czlIOJJMyT0yH8ZF5UQMuTSVsMpZS0kU30kWH0AhVOg6kSUqBDa0937FttmvgqlBmu2GqAJzPdVAWA9Awf5ieDkzsuzHfSnsutWqVab1Fq0QgCW4gQ4IOZAta/0grl6nUe8hxXlhylLpzHylRImYtccxqM5ZxexiqU7iBZVEqEtPwj0H4SoSKmJZIKJMwKaplY1jrGQU3HmMoVepm63VxPDUqoTZWVXN9BwH4jzNtbc85olMzNlV+7xFJgSLNqBxMPMDrOcvQ3u1NWuPUH9IXt5KwzA+yJyeJa5J+8xPnbledLtx7BrWGqgA8QBJzUHmL5365cpzFbW3TKefHPdWp0RJ1GsPPlBBYSIzN+Q09Z7IsRbACUvrLiZQdYRIjKW09JAjKMtYQqt2uwlxN9PnMVM2mWYRAgDMwRjr9PKPh5n2gIGXeVHKTvINKiLKDKSbSzitKKphWQrXUekgBCj8A/rmZNRCJgSJaVVq/ISVNOsiq6kguUsrSlmhVgliNZkPRh+MpptcemUkxy9JKNztqvcJ5i9tLAD4bfdufD7zRILmZeKxPHc8h4R11/q0xqYkxmoVYx5DnJAWkKeefXT0gzTpEiZUNZYNJDhgWyio0nKHMKswg1MyjMXCHWXOb5D3lQcV/SOO1pG8IyLyLQBiYwKmMoqGTZ85VUkVlUD4R6fxldat0jRvCPSYzHOUX0EubmZJMroiwhUaBVWaVgRtJKsikotJNoY7RHp7QFbwqPf5xHkOv4Syqbe0qo5kmEX3iivAwqUiTHeVsYAzTu+yPc2jtGviRiU4qSYVx5rUqngRx+ko42HmBOCn0F2IbFNDAPWYWOJqArfnTpjhB/aLwjw3aWx6mDxFfDVR+co1Gpt0Njkw8iLEeRlAFp6j29bv8ABXw2NQWFZTQrEf4lMXRj6oSP/nPKwTKhnOBYCRL/AHfnoJWCOZufKBkcUcqNQ9ImqEdPaFRqLaUO0k5MrvILqT+G0rGZiU5GSojOEZq6SuoZMGVMZaqAEtAkQskxtIExkKRuwkC5OQk0Qi9tSNeQHWBGu9zaSpDKUhc5eogSERMUV4VK8qcyd5UxgZOz8K1arTpoLtUdKaj9JmCj6mfXOAwa0KVKigslKmlNQOiqFH4T5z7H9k/lG1cOSLrQ4sQ3T82PD++Un0pCVxXa/ghV2TiDa5ovRrL5WqBGP7LtPnImwz56z642lgExFGrQqC6Vab0n68LKVNvPOfLm8ux0weLr0ErDECk5TvQvACQPELXOYNwc9QZYjUlb8svPISai38hYQ7yFzCnwzHqOQZeZXW0iinjvIESS84mkRGW0JUZZRgZRMiBHFKoLWlLteN5FZBbSS0HYg5c1IMmuntK6usCuWKZUZNZFSJivHINKAtK7waC6wj2P/p+wn5zG1LaUaSBuQ4nJt+6PlPaLziOx2ko2VRIVQWqVixAALEPYEnnkAPadrCNfvHtYYTCYnEn+5o1HXze1kHuxUe8+V6rFiSxuSbknUk6kz6A7ZGI2W9iRfEYcGxtcXJsfcA+0+fG/r5yiLG0QaSlRkV//2Q==
+
+
+
+ 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_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index 2177add8878..dc3c159463f 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -321,7 +321,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'],
}
diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py
index 06af3054b68..a3d3da04f0e 100644
--- a/addons/hr_payroll/hr_payroll.py
+++ b/addons/hr_payroll/hr_payroll.py
@@ -202,8 +202,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
diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py
index 213040d6204..9465980629c 100644
--- a/addons/l10n_be_coda/wizard/account_coda_import.py
+++ b/addons/l10n_be_coda/wizard/account_coda_import.py
@@ -389,7 +389,7 @@ class account_coda_import(osv.osv_memory):
if statement['coda_note'] != '':
self.pool.get('account.bank.statement').write(cr, uid, [statement['id']], {'coda_note': statement['coda_note']}, context=context)
model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'action_bank_statement_tree')
- action = self.pool.get(model).browse(cr, uid, action_id, context=context)
+ action = self.pool[model].browse(cr, uid, action_id, context=context)
return {
'name': action.name,
'view_type': action.view_type,
diff --git a/addons/l10n_multilang/l10n_multilang.py b/addons/l10n_multilang/l10n_multilang.py
index 9596b292ff3..b94ff303eae 100644
--- a/addons/l10n_multilang/l10n_multilang.py
+++ b/addons/l10n_multilang/l10n_multilang.py
@@ -78,7 +78,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
else:
#replace the value in the destination object only if it's the user lang
if context.get('lang') == lang:
- self.pool.get(out_obj._name).write(cr, uid, out_ids[j], {in_field: value[in_id]})
+ self.pool[out_obj._name].write(cr, uid, out_ids[j], {in_field: value[in_id]})
else:
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' %(lang, src[in_id]))#out_obj._name))
return True
diff --git a/addons/mail/data/mail_data.xml b/addons/mail/data/mail_data.xml
index 3f517ee7858..02cfd626768 100644
--- a/addons/mail/data/mail_data.xml
+++ b/addons/mail/data/mail_data.xml
@@ -27,6 +27,19 @@
1000
+
+ Garbage Collect Mail Attachments
+
+
+ 1
+ weeks
+ -1
+
+ mail.thread
+ _garbage_collect_attachments
+ ()
+
+
Discussions
diff --git a/addons/mail/mail_alias.py b/addons/mail/mail_alias.py
index 55746b11678..f806b325291 100644
--- a/addons/mail/mail_alias.py
+++ b/addons/mail/mail_alias.py
@@ -164,7 +164,7 @@ class mail_alias(osv.Model):
registry = RegistryManager.get(cr.dbname)
mail_alias = registry.get('mail.alias')
- child_class_model = registry.get(child_model_name)
+ child_class_model = registry[child_model_name]
no_alias_ids = child_class_model.search(cr, SUPERUSER_ID, [('alias_id', '=', False)], context={'active_test':False})
# Use read() not browse(), to avoid prefetching uninitialized inherited fields
for obj_data in child_class_model.read(cr, SUPERUSER_ID, no_alias_ids, [alias_key]):
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
index ab2b6f3e922..3c30a950230 100644
--- a/addons/mail/mail_mail.py
+++ b/addons/mail/mail_mail.py
@@ -108,8 +108,8 @@ class mail_mail(osv.Model):
res_id = message.res_id
# if model and res_id: try to use ``message_get_reply_to`` that returns the document alias
- if model and res_id and hasattr(self.pool.get(model), 'message_get_reply_to'):
- email_reply_to = self.pool.get(model).message_get_reply_to(cr, uid, [res_id], context=context)[0]
+ if model and res_id and hasattr(self.pool[model], 'message_get_reply_to'):
+ email_reply_to = self.pool[model].message_get_reply_to(cr, uid, [res_id], context=context)[0]
# no alias reply_to -> reply_to will be the email_from, only the email part
if not email_reply_to and values.get('email_from'):
emails = tools.email_split(values.get('email_from'))
@@ -118,7 +118,7 @@ class mail_mail(osv.Model):
# format 'Document name '
if email_reply_to and model and res_id:
- document_name = self.pool.get(model).name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
+ document_name = self.pool[model].name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
if document_name:
# sanitize document name
sanitized_doc_name = re.sub(r'[^\w+.]+', '-', document_name[1])
@@ -217,7 +217,7 @@ class mail_mail(osv.Model):
and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False):
related_user = partner.user_ids[0]
try:
- self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
+ self.pool[mail.model].check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
# the parameters to encode for the query and fragment part of url
query = {'db': cr.dbname}
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index 4f830b21e50..defc12a2f73 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -76,9 +76,9 @@ class mail_message(osv.Model):
# TDE note: regroup by model/ids, to have less queries to perform
result = dict.fromkeys(ids, False)
for message in self.read(cr, uid, ids, ['model', 'res_id'], context=context):
- if not message.get('model') or not message.get('res_id') or not self.pool.get(message['model']):
+ if not message.get('model') or not message.get('res_id') or message['model'] not in self.pool:
continue
- result[message['id']] = self.pool.get(message['model']).name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1]
+ result[message['id']] = self.pool[message['model']].name_get(cr, SUPERUSER_ID, [message['res_id']], context=context)[0][1]
return result
def _get_to_read(self, cr, uid, ids, name, arg, context=None):
@@ -369,6 +369,7 @@ class mail_message(osv.Model):
return {'id': message.id,
'type': message.type,
+ 'subtype': message.subtype_id.name if message.subtype_id else False,
'body': body_html,
'model': message.model,
'res_id': message.res_id,
@@ -569,7 +570,7 @@ class mail_message(osv.Model):
def _find_allowed_model_wise(self, cr, uid, doc_model, doc_dict, context=None):
doc_ids = doc_dict.keys()
- allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context)
+ allowed_doc_ids = self.pool[doc_model].search(cr, uid, [('id', 'in', doc_ids)], context=context)
return set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]])
def _find_allowed_doc_ids(self, cr, uid, model_ids, context=None):
@@ -717,7 +718,7 @@ class mail_message(osv.Model):
model_record_ids = _generate_model_record_ids(message_values, other_ids)
document_related_ids = []
for model, doc_dict in model_record_ids.items():
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
mids = model_obj.exists(cr, uid, doc_dict.keys())
if operation in ['create', 'write', 'unlink']:
model_obj.check_access_rights(cr, uid, 'write')
@@ -773,7 +774,7 @@ class mail_message(osv.Model):
attachments_to_delete = []
for message in self.browse(cr, uid, ids, context=context):
for attach in message.attachment_ids:
- if attach.res_model == self._name and attach.res_id == message.id:
+ if attach.res_model == self._name and (attach.res_id == message.id or attach.res_id == 0):
attachments_to_delete.append(attach.id)
if attachments_to_delete:
self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context)
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 7ca9fcb7b53..5ddf412e66b 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -408,7 +408,7 @@ class mail_thread(osv.AbstractModel):
posted = False
for subtype in subtypes:
try:
- subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1])
+ subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1], context=context)
except ValueError, e:
_logger.debug('subtype %s not found, giving error "%s"' % (subtype, e))
continue
@@ -429,6 +429,26 @@ class mail_thread(osv.AbstractModel):
return [('message_unread', '=', True)]
return []
+ def _garbage_collect_attachments(self, cr, uid, context=None):
+ """ Garbage collect lost mail attachments. Those are attachments
+ - linked to res_model 'mail.compose.message', the composer wizard
+ - with res_id 0, because they were created outside of an existing
+ wizard (typically user input through Chatter or reports
+ created on-the-fly by the templates)
+ - unused since at least one day (create_date and write_date)
+ """
+ limit_date = datetime.datetime.utcnow() - datetime.timedelta(days=1)
+ limit_date_str = datetime.datetime.strftime(limit_date, tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ ir_attachment_obj = self.pool.get('ir.attachment')
+ attach_ids = ir_attachment_obj.search(cr, uid, [
+ ('res_model', '=', 'mail.compose.message'),
+ ('res_id', '=', 0),
+ ('create_date', '<', limit_date_str),
+ ('write_date', '<', limit_date_str),
+ ], context=context)
+ ir_attachment_obj.unlink(cr, uid, attach_ids, context=context)
+ return True
+
#------------------------------------------------------
# Email specific
#------------------------------------------------------
@@ -449,13 +469,15 @@ class mail_thread(osv.AbstractModel):
""" Used by the plugin addon, based for plugin_outlook and others. """
ret_dict = {}
for model_name in self.pool.obj_list():
- model = self.pool.get(model_name)
+ model = self.pool[model_name]
if 'mail.thread' in getattr(model, '_inherit', []):
ret_dict[model_name] = model._description
return ret_dict
def _message_find_partners(self, cr, uid, message, header_fields=['From'], context=None):
- """ Find partners related to some header fields of the message. """
+ """ Find partners related to some header fields of the message.
+
+ TDE TODO: merge me with other partner finding methods in 8.0 """
partner_obj = self.pool.get('res.partner')
partner_ids = []
s = ', '.join([decode(message.get(h)) for h in header_fields if message.get(h)])
@@ -467,6 +489,7 @@ class mail_thread(osv.AbstractModel):
return partner_ids
def _message_find_user_id(self, cr, uid, message, context=None):
+ """ TDE TODO: check and maybe merge me with other user finding methods in 8.0 """
from_local_part = tools.email_split(decode(message.get('From')))[0]
# FP Note: canonification required, the minimu: .lower()
user_ids = self.pool.get('res.users').search(cr, uid, ['|',
@@ -520,12 +543,12 @@ class mail_thread(osv.AbstractModel):
if ref_match:
thread_id = int(ref_match.group(1))
model = ref_match.group(2) or model
- model_pool = self.pool.get(model)
- if thread_id and model and model_pool and model_pool.exists(cr, uid, thread_id) \
- and hasattr(model_pool, 'message_update'):
- _logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s',
- email_from, email_to, message_id, model, thread_id, custom_values, uid)
- return [(model, thread_id, custom_values, uid)]
+ if thread_id and model in self.pool:
+ model_obj = self.pool[model]
+ if model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'):
+ _logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s',
+ email_from, email_to, message_id, model, thread_id, custom_values, uid)
+ return [(model, thread_id, custom_values, uid)]
# Verify whether this is a reply to a private message
if in_reply_to:
@@ -666,7 +689,7 @@ class mail_thread(osv.AbstractModel):
if self._name == 'mail.thread':
context.update({'thread_model': model})
if model:
- model_pool = self.pool.get(model)
+ model_pool = self.pool[model]
assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \
"Undeliverable mail with Message-Id %s, model %s does not accept incoming emails" % \
(msg['message_id'], model)
@@ -720,7 +743,7 @@ class mail_thread(osv.AbstractModel):
if isinstance(custom_values, dict):
data = custom_values.copy()
model = context.get('thread_model') or self._name
- model_pool = self.pool.get(model)
+ model_pool = self.pool[model]
fields = model_pool.fields_get(cr, uid, context=context)
if 'name' in fields and not data.get('name'):
data['name'] = msg_dict.get('subject', '')
@@ -892,7 +915,8 @@ class mail_thread(osv.AbstractModel):
recipient in the result dictionary. The form is :
partner_id, partner_name or partner_name, reason """
if email and not partner:
- partner_info = self.message_get_partner_info_from_emails(cr, uid, [email], context=context)[0]
+ # get partner info from email
+ partner_info = self.message_get_partner_info_from_emails(cr, uid, [email], context=context, res_id=obj.id)[0]
if partner_info.get('partner_id'):
partner = self.pool.get('res.partner').browse(cr, SUPERUSER_ID, [partner_info.get('partner_id')], context=context)[0]
if email and email in [val[1] for val in result[obj.id]]: # already existing email -> skip
@@ -920,29 +944,49 @@ class mail_thread(osv.AbstractModel):
self._message_add_suggested_recipient(cr, uid, result, obj, partner=obj.user_id.partner_id, reason=self._all_columns['user_id'].column.string, context=context)
return result
- def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None):
+ def message_get_partner_info_from_emails(self, cr, uid, emails, link_mail=False, context=None, res_id=None):
+ """ Wrapper with weird order parameter because of 7.0 fix.
+
+ TDE TODO: remove me in 8.0 """
+ return self.message_find_partner_from_emails(cr, uid, res_id, emails, link_mail=link_mail, context=context)
+
+ def message_find_partner_from_emails(self, cr, uid, id, emails, link_mail=False, context=None):
""" Convert a list of emails into a list partner_ids and a list
new_partner_ids. The return value is non conventional because
it is meant to be used by the mail widget.
:return dict: partner_ids and new_partner_ids
- """
+
+ TDE TODO: merge me with other partner finding methods in 8.0 """
mail_message_obj = self.pool.get('mail.message')
partner_obj = self.pool.get('res.partner')
result = list()
+ if id and self._name != 'mail.thread':
+ obj = self.browse(cr, SUPERUSER_ID, id, context=context)
+ else:
+ obj = None
for email in emails:
partner_info = {'full_name': email, 'partner_id': False}
m = re.search(r"((.+?)\s*<)?([^<>]+@[^<>]+)>?", email, re.IGNORECASE | re.DOTALL)
if not m:
continue
email_address = m.group(3)
- ids = partner_obj.search(cr, SUPERUSER_ID, [('email', '=', email_address)], context=context)
- if ids:
- partner_info['partner_id'] = ids[0]
+ # first try: check in document's followers
+ if obj:
+ for follower in obj.message_follower_ids:
+ if follower.email == email_address:
+ partner_info['partner_id'] = follower.id
+ # second try: check in partners
+ if not partner_info.get('partner_id'):
+ ids = partner_obj.search(cr, SUPERUSER_ID, [('email', 'ilike', email_address), ('user_ids', '!=', False)], limit=1, context=context)
+ if not ids:
+ ids = partner_obj.search(cr, SUPERUSER_ID, [('email', 'ilike', email_address)], limit=1, context=context)
+ if ids:
+ partner_info['partner_id'] = ids[0]
result.append(partner_info)
# link mail with this from mail to the new partner id
- if link_mail and ids:
+ if link_mail and partner_info['partner_id']:
message_ids = mail_message_obj.search(cr, SUPERUSER_ID, [
'|',
('email_from', '=', email),
@@ -950,7 +994,7 @@ class mail_thread(osv.AbstractModel):
('author_id', '=', False)
], context=context)
if message_ids:
- mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': ids[0]}, context=context)
+ mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': partner_info['partner_id']}, context=context)
return result
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification',
@@ -997,7 +1041,7 @@ class mail_thread(osv.AbstractModel):
model = context.get('thread_model', self._name) if self._name == 'mail.thread' else self._name
if model != self._name:
del context['thread_model']
- return self.pool.get(model).message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
+ return self.pool[model].message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
# 0: Parse email-from, try to find a better author_id based on document's followers for incoming emails
email_from = kwargs.get('email_from')
@@ -1046,7 +1090,6 @@ class mail_thread(osv.AbstractModel):
if attachment_ids:
filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
('res_model', '=', 'mail.compose.message'),
- ('res_id', '=', 0),
('create_uid', '=', uid),
('id', 'in', attachment_ids)], context=context)
if filtered_attachment_ids:
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index 934fb6b5487..6bc086a5b58 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -57,6 +57,9 @@
.openerp .oe_mail .oe_msg.oe_msg_nobody{
background: #F8F8F8;
}
+.openerp .oe_mail .oe_msg.oe_msg_notification{
+ background: #F8F8F8;
+}
.openerp .oe_mail .oe_msg .oe_msg_left{
position: absolute;
left:0; top: 0; bottom: 0; width: 40px;
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index ec4feed82e2..b1a579ba057 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -217,6 +217,7 @@ openerp.mail = function (session) {
this.res_id = datasets.res_id || this.context.default_res_id || false,
this.parent_id = datasets.parent_id || false,
this.type = datasets.type || false,
+ this.subtype = datasets.subtype || false,
this.is_author = datasets.is_author || false,
this.is_private = datasets.is_private || false,
this.subject = datasets.subject || false,
@@ -619,7 +620,10 @@ openerp.mail = function (session) {
// have unknown names -> call message_get_partner_info_from_emails to try to find partner_id
var find_done = $.Deferred();
if (names_to_find.length > 0) {
- find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [names_to_find]);
+ var values = {
+ 'res_id': this.context.default_res_id,
+ }
+ find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [names_to_find], values);
}
else {
find_done.resolve([]);
@@ -665,7 +669,11 @@ openerp.mail = function (session) {
var new_names_to_find = _.difference(names_to_find, names_to_remove);
find_done = $.Deferred();
if (new_names_to_find.length > 0) {
- find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [new_names_to_find, true]);
+ var values = {
+ 'link_mail': true,
+ 'res_id': self.context.default_res_id,
+ }
+ find_done = self.parent_thread.ds_thread._model.call('message_get_partner_info_from_emails', [new_names_to_find], values);
}
else {
find_done.resolve([]);
diff --git a/addons/mail/static/src/js/mail_followers.js b/addons/mail/static/src/js/mail_followers.js
index 6fc2f0fdfcd..f812844194b 100644
--- a/addons/mail/static/src/js/mail_followers.js
+++ b/addons/mail/static/src/js/mail_followers.js
@@ -148,8 +148,6 @@ openerp_mail_followers = function(session, mail) {
}).then(self.proxy('display_generic'));
},
_format_followers: function(count){
- // TDE note: why redefining _t ?
- function _t(str) { return str; }
var str = '';
if(count <= 0){
str = _t('No followers');
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index 2229fc99de1..fd49802ceb3 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -227,7 +227,7 @@
-
+
@@ -264,13 +264,23 @@
-
+
+ updated document
+
+ •
+
+
+
logged a note
-
+
to
+
+ nobody
+
-
+
@@ -280,6 +290,9 @@
and more
+
+ notified
+ ••
diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py
index a68011298c7..e4269d59d8b 100644
--- a/addons/mail/tests/test_mail_gateway.py
+++ b/addons/mail/tests/test_mail_gateway.py
@@ -83,7 +83,47 @@ Sylvie
class TestMailgateway(TestMailBase):
- def test_00_message_process(self):
+ def test_00_partner_find_from_email(self):
+ """ Tests designed for partner fetch based on emails. """
+ cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs
+
+ # --------------------------------------------------
+ # Data creation
+ # --------------------------------------------------
+ # 1 - Partner ARaoul
+ p_a_id = self.res_partner.create(cr, uid, {'name': 'ARaoul', 'email': 'test@test.fr'})
+
+ # --------------------------------------------------
+ # CASE1: without object
+ # --------------------------------------------------
+
+ # Do: find partner with email -> first partner should be found
+ partner_info = self.mail_thread.message_find_partner_from_emails(cr, uid, None, ['Maybe Raoul '], link_mail=False)[0]
+ self.assertEqual(partner_info['full_name'], 'Maybe Raoul ',
+ 'mail_thread: message_find_partner_from_emails did not handle email')
+ self.assertEqual(partner_info['partner_id'], p_a_id,
+ 'mail_thread: message_find_partner_from_emails wrong partner found')
+
+ # Data: add some data about partners
+ # 2 - User BRaoul
+ p_b_id = self.res_partner.create(cr, uid, {'name': 'BRaoul', 'email': 'test@test.fr', 'user_ids': [(4, user_raoul.id)]})
+
+ # Do: find partner with email -> first user should be found
+ partner_info = self.mail_thread.message_find_partner_from_emails(cr, uid, None, ['Maybe Raoul '], link_mail=False)[0]
+ self.assertEqual(partner_info['partner_id'], p_b_id,
+ 'mail_thread: message_find_partner_from_emails wrong partner found')
+
+ # --------------------------------------------------
+ # CASE1: with object
+ # --------------------------------------------------
+
+ # Do: find partner in group where there is a follower with the email -> should be taken
+ self.mail_group.message_subscribe(cr, uid, [group_pigs.id], [p_b_id])
+ partner_info = self.mail_group.message_find_partner_from_emails(cr, uid, group_pigs.id, ['Maybe Raoul '], link_mail=False)[0]
+ self.assertEqual(partner_info['partner_id'], p_b_id,
+ 'mail_thread: message_find_partner_from_emails wrong partner found')
+
+ def test_10_message_process(self):
""" Testing incoming emails processing. """
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
@@ -325,7 +365,7 @@ class TestMailgateway(TestMailBase):
self.assertEqual(msg.body, '
\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
',
'message_process: plaintext incoming email incorrectly parsed')
- def test_10_thread_parent_resolution(self):
+ def test_20_thread_parent_resolution(self):
""" Testing parent/child relationships are correctly established when processing incoming mails """
cr, uid = self.cr, self.uid
@@ -370,7 +410,7 @@ class TestMailgateway(TestMailBase):
self.assertEqual(6, len(group_pigs.message_ids), 'message_process: group should contain 6 messages')
self.assertEqual(3, len(msg1.child_ids), 'message_process: msg1 should have 3 children now')
- def test_20_private_discussion(self):
+ def test_30_private_discussion(self):
""" Testing private discussion between partners. """
cr, uid = self.cr, self.uid
diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py
index 2eb48f3d998..4ff6584d789 100644
--- a/addons/mail/wizard/invite.py
+++ b/addons/mail/wizard/invite.py
@@ -37,10 +37,10 @@ class invite_wizard(osv.osv_memory):
res_id = result.get('res_id')
if 'message' in fields and model and res_id:
ir_model = self.pool.get('ir.model')
- model_ids = ir_model.search(cr, uid, [('model', '=', self.pool.get(model)._name)], context=context)
+ model_ids = ir_model.search(cr, uid, [('model', '=', self.pool[model]._name)], context=context)
model_name = ir_model.name_get(cr, uid, model_ids, context=context)[0][1]
- document_name = self.pool.get(model).name_get(cr, uid, [res_id], context=context)[0][1]
+ document_name = self.pool[model].name_get(cr, uid, [res_id], context=context)[0][1]
message = _('
Hello,
%s invited you to follow %s document: %s.
') % (user_name, model_name, document_name)
result['message'] = message
elif 'message' in fields:
@@ -63,7 +63,7 @@ class invite_wizard(osv.osv_memory):
def add_followers(self, cr, uid, ids, context=None):
for wizard in self.browse(cr, uid, ids, context=context):
- model_obj = self.pool.get(wizard.res_model)
+ model_obj = self.pool[wizard.res_model]
document = model_obj.browse(cr, uid, wizard.res_id, context=context)
# filter partner_ids to get the new followers, to avoid sending email to already following partners
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index 629dd6a88f0..dfda3038de8 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -19,10 +19,8 @@
#
##############################################################################
-import base64
import re
from openerp import tools
-
from openerp import SUPERUSER_ID
from openerp.osv import osv
from openerp.osv import fields
@@ -174,7 +172,7 @@ class mail_compose_message(osv.TransientModel):
related to.
:param int res_id: id of the document record this mail is related to
"""
- doc_name_get = self.pool.get(model).name_get(cr, uid, [res_id], context=context)
+ doc_name_get = self.pool[model].name_get(cr, uid, [res_id], context=context)
record_name = False
if doc_name_get:
record_name = doc_name_get[0][1]
@@ -230,33 +228,35 @@ class mail_compose_message(osv.TransientModel):
email(s), rendering any template patterns on the fly if needed. """
if context is None:
context = {}
+ ir_attachment_obj = self.pool.get('ir.attachment')
active_ids = context.get('active_ids')
is_log = context.get('mail_compose_log', False)
for wizard in self.browse(cr, uid, ids, context=context):
mass_mail_mode = wizard.composition_mode == 'mass_mail'
- if mass_mail_mode: # mass mail: avoid any auto subscription because this could lead to people being follower of plenty of documents
- context['mail_create_nosubscribe'] = True
- active_model_pool = self.pool.get(wizard.model if wizard.model else 'mail.thread')
+ active_model_pool = self.pool[wizard.model if wizard.model else 'mail.thread']
# wizard works in batch mode: [res_id] or active_ids
res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id]
for res_id in res_ids:
- # default values, according to the wizard options
+ # mail.message values, according to the wizard options
post_values = {
'subject': wizard.subject,
'body': wizard.body,
'parent_id': wizard.parent_id and wizard.parent_id.id,
'partner_ids': [partner.id for partner in wizard.partner_ids],
- 'attachments': [(attach.datas_fname or attach.name, base64.b64decode(attach.datas)) for attach in wizard.attachment_ids],
+ 'attachment_ids': [attach.id for attach in wizard.attachment_ids],
}
# mass mailing: render and override default values
if mass_mail_mode and wizard.model:
email_dict = self.render_message(cr, uid, wizard, res_id, context=context)
- new_partner_ids = email_dict.pop('partner_ids', [])
- post_values['partner_ids'] += new_partner_ids
- new_attachments = email_dict.pop('attachments', [])
- post_values['attachments'] += new_attachments
+ post_values['partner_ids'] += email_dict.pop('partner_ids', [])
+ post_values['attachments'] = email_dict.pop('attachments', [])
+ attachment_ids = []
+ for attach_id in post_values.pop('attachment_ids'):
+ new_attach_id = ir_attachment_obj.copy(cr, uid, attach_id, {'res_model': self._name, 'res_id': wizard.id}, context=context)
+ attachment_ids.append(new_attach_id)
+ post_values['attachment_ids'] = attachment_ids
post_values.update(email_dict)
# email_from: mass mailing only can specify another email_from
if email_dict.get('email_from'):
@@ -319,7 +319,7 @@ class mail_compose_message(osv.TransientModel):
exp = str(match.group()[2:-1]).strip()
result = eval(exp, {
'user': self.pool.get('res.users').browse(cr, uid, uid, context=context),
- 'object': self.pool.get(model).browse(cr, uid, res_id, context=context),
+ 'object': self.pool[model].browse(cr, uid, res_id, context=context),
'context': dict(context), # copy context to prevent side-effects of eval
})
return result and tools.ustr(result) or ''
diff --git a/addons/marketing_campaign/marketing_campaign.py b/addons/marketing_campaign/marketing_campaign.py
index dfa13259383..4aa340d7a14 100644
--- a/addons/marketing_campaign/marketing_campaign.py
+++ b/addons/marketing_campaign/marketing_campaign.py
@@ -165,7 +165,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
# dead code
def signal(self, cr, uid, model, res_id, signal, run_existing=True, context=None):
- record = self.pool.get(model).browse(cr, uid, res_id, context)
+ record = self.pool[model].browse(cr, uid, res_id, context)
return self._signal(cr, uid, record, signal, run_existing, context)
#dead code
@@ -228,7 +228,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
if unique_value:
if unique_field.ttype == 'many2one':
unique_value = unique_value.id
- similar_res_ids = self.pool.get(campaign_rec.object_id.model).search(cr, uid,
+ similar_res_ids = self.pool[campaign_rec.object_id.model].search(cr, uid,
[(unique_field.name, '=', unique_value)], context=context)
if similar_res_ids:
duplicate_workitem_domain = [('res_id','in', similar_res_ids),
@@ -349,7 +349,7 @@ class marketing_campaign_segment(osv.osv):
act_ids = self.pool.get('marketing.campaign.activity').search(cr,
uid, [('start', '=', True), ('campaign_id', '=', segment.campaign_id.id)], context=context)
- model_obj = self.pool.get(segment.object_id.model)
+ model_obj = self.pool[segment.object_id.model]
criteria = []
if segment.sync_last_date and segment.sync_mode != 'all':
criteria += [(segment.sync_mode, '>', segment.sync_last_date)]
@@ -594,7 +594,7 @@ class marketing_campaign_workitem(osv.osv):
if not wi.res_id:
continue
- proxy = self.pool.get(wi.object_id.model)
+ proxy = self.pool[wi.object_id.model]
if not proxy.exists(cr, uid, [wi.res_id]):
continue
ng = proxy.name_get(cr, uid, [wi.res_id], context=context)
@@ -628,7 +628,7 @@ class marketing_campaign_workitem(osv.osv):
for id, res_id, model in res:
workitem_map.setdefault(model,{}).setdefault(res_id,set()).add(id)
for model, id_map in workitem_map.iteritems():
- model_pool = self.pool.get(model)
+ model_pool = self.pool[model]
condition_name[0] = model_pool._rec_name
condition = [('id', 'in', id_map.keys()), condition_name]
for res_id in model_pool.search(cr, uid, condition, context=context):
@@ -676,7 +676,7 @@ class marketing_campaign_workitem(osv.osv):
return False
activity = workitem.activity_id
- proxy = self.pool.get(workitem.object_id.model)
+ proxy = self.pool[workitem.object_id.model]
object_id = proxy.browse(cr, uid, workitem.res_id, context=context)
eval_context = {
diff --git a/addons/pad/pad.py b/addons/pad/pad.py
index 90f5354054c..4cd9e91b76e 100644
--- a/addons/pad/pad.py
+++ b/addons/pad/pad.py
@@ -42,7 +42,7 @@ class pad_common(osv.osv_memory):
myPad.createPad(path)
#get attr on the field model
- model = self.pool.get(context["model"])
+ model = self.pool[context["model"]]
field = model._all_columns[context['field_name']]
real_field = field.column.pad_content_field
diff --git a/addons/plugin/plugin_handler.py b/addons/plugin/plugin_handler.py
index f13fc255a6d..c278db2f19a 100644
--- a/addons/plugin/plugin_handler.py
+++ b/addons/plugin/plugin_handler.py
@@ -58,7 +58,7 @@ class plugin_handler(osv.osv_memory):
res_id = msg.res_id
model = msg.model
url = self._make_url(cr, uid, res_id, model)
- name = self.pool.get(model).name_get(cr, uid, [res_id])[0][1]
+ name = self.pool[model].name_get(cr, uid, [res_id])[0][1]
return (model, res_id, url, name)
def document_type(self, cr, uid, context=None):
@@ -82,7 +82,7 @@ class plugin_handler(osv.osv_memory):
@return : the result of name_search a list of tuple
[(id, 'name')]
"""
- return self.pool.get(model).name_search(cr, uid, name)
+ return self.pool[model].name_search(cr, uid, name)
def push_message(self, cr, uid, model, email, res_id=0):
"""
@@ -92,7 +92,7 @@ class plugin_handler(osv.osv_memory):
@return Dictionary which contain model , url and resource id.
"""
mail_message = self.pool.get('mail.message')
- model_obj = self.pool.get(model)
+ model_obj = self.pool[model]
msg = self.pool.get('mail.thread').message_parse(cr, uid, email)
message_id = msg.get('message-id')
mail_ids = mail_message.search(cr, uid, [('message_id', '=', message_id), ('res_id', '=', res_id), ('model', '=', model)])
diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py
index 7e8487b2b2b..2185f372caa 100644
--- a/addons/point_of_sale/point_of_sale.py
+++ b/addons/point_of_sale/point_of_sale.py
@@ -50,7 +50,7 @@ class pos_config(osv.osv):
required=True, help="An internal identification of the point of sale"),
'journal_ids' : fields.many2many('account.journal', 'pos_config_journal_rel',
'pos_config_id', 'journal_id', 'Available Payment Methods',
- domain="[('journal_user', '=', True )]",),
+ domain="[('journal_user', '=', True ), ('type', 'in', ['bank', 'cash'])]",),
'shop_id' : fields.many2one('sale.shop', 'Shop',
required=True),
'journal_id' : fields.many2one('account.journal', 'Sale Journal',
@@ -408,6 +408,9 @@ class pos_session(osv.osv):
if not self.pool.get('ir.model.access').check_groups(cr, uid, "point_of_sale.group_pos_manager"):
raise osv.except_osv( _('Error!'),
_("Your ending balance is too different from the theorical cash closing (%.2f), the maximum allowed is: %.2f. You can contact your manager to force it.") % (st.difference, st.journal_id.amount_authorized_diff))
+ if (st.journal_id.type not in ['bank', 'cash']):
+ raise osv.except_osv(_('Error!'),
+ _("The type of the journal for your payment method should be bank or cash "))
if st.difference and st.journal_id.cash_control == True:
if st.difference > 0.0:
name= _('Point of Sale Profit')
@@ -428,7 +431,6 @@ class pos_session(osv.osv):
if st.journal_id.type == 'bank':
st.write({'balance_end_real' : st.balance_end})
-
getattr(st, 'button_confirm_%s' % st.journal_id.type)(context=context)
self._confirm_orders(cr, uid, ids, context=context)
self.write(cr, uid, ids, {'state' : 'closed'}, context=context)
@@ -522,6 +524,24 @@ class pos_order(osv.osv):
self.signal_paid(cr, uid, [order_id])
return order_ids
+ def write(self, cr, uid, ids, vals, context=None):
+ res = super(pos_order, self).write(cr, uid, ids, vals, context=context)
+ #If you change the partner of the PoS order, change also the partner of the associated bank statement lines
+ partner_obj = self.pool.get('res.partner')
+ bsl_obj = self.pool.get("account.bank.statement.line")
+ if 'partner_id' in vals:
+ for posorder in self.browse(cr, uid, ids, context=context):
+ if posorder.invoice_id:
+ raise osv.except_osv( _('Error!'), _("You cannot change the partner of a POS order for which an invoice has already been issued."))
+ if vals['partner_id']:
+ p_id = partner_obj.browse(cr, uid, vals['partner_id'], context=context)
+ part_id = partner_obj._find_accounting_partner(p_id).id
+ else:
+ part_id = False
+ bsl_ids = [x.id for x in posorder.statement_ids]
+ bsl_obj.write(cr, uid, bsl_ids, {'partner_id': part_id}, context=context)
+ return res
+
def unlink(self, cr, uid, ids, context=None):
for rec in self.browse(cr, uid, ids, context=context):
if rec.state not in ('draft','cancel'):
@@ -948,9 +968,9 @@ class pos_order(osv.osv):
})
if data_type == 'product':
- key = ('product', values['product_id'],)
+ key = ('product', values['partner_id'], values['product_id'])
elif data_type == 'tax':
- key = ('tax', values['tax_code_id'],)
+ key = ('tax', values['partner_id'], values['tax_code_id'],)
elif data_type == 'counter_part':
key = ('counter_part', values['partner_id'], values['account_id'])
else:
@@ -1026,7 +1046,7 @@ class pos_order(osv.osv):
'debit': ((amount<0) and -amount) or 0.0,
'tax_code_id': tax_code_id,
'tax_amount': tax_amount,
- 'partner_id': order.partner_id and order.partner_id.id or False
+ 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False
})
# For each remaining tax with a code, whe create a move line
@@ -1044,6 +1064,7 @@ class pos_order(osv.osv):
'debit': 0.0,
'tax_code_id': tax_code_id,
'tax_amount': tax_amount,
+ 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False
})
# Create a move for each tax group
@@ -1060,6 +1081,7 @@ class pos_order(osv.osv):
'debit': ((tax_amount<0) and -tax_amount) or 0.0,
'tax_code_id': key[tax_code_pos],
'tax_amount': tax_amount,
+ 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False
})
# counterpart
@@ -1068,14 +1090,17 @@ class pos_order(osv.osv):
'account_id': order_account,
'credit': ((order.amount_total < 0) and -order.amount_total) or 0.0,
'debit': ((order.amount_total > 0) and order.amount_total) or 0.0,
- 'partner_id': order.partner_id and order.partner_id.id or False
+ 'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False
})
order.write({'state':'done', 'account_move': move_id})
+ all_lines = []
for group_key, group_data in grouped_data.iteritems():
for value in group_data:
- account_move_line_obj.create(cr, uid, value, context=context)
+ all_lines.append((0, 0, value),)
+ if move_id: #In case no order was changed
+ self.pool.get("account.move").write(cr, uid, [move_id], {'line_id':all_lines}, context=context)
return True
@@ -1279,7 +1304,7 @@ class ean_wizard(osv.osv_memory):
ean13 = openerp.addons.product.product.sanitize_ean13(r.ean13_pattern)
m = context.get('active_model')
m_id = context.get('active_id')
- self.pool.get(m).write(cr,uid,[m_id],{'ean13':ean13})
+ self.pool[m].write(cr,uid,[m_id],{'ean13':ean13})
return { 'type' : 'ir.actions.act_window_close' }
class product_product(osv.osv):
diff --git a/addons/point_of_sale/wizard/pos_box.py b/addons/point_of_sale/wizard/pos_box.py
index 776d962a3a8..471153695f4 100644
--- a/addons/point_of_sale/wizard/pos_box.py
+++ b/addons/point_of_sale/wizard/pos_box.py
@@ -16,7 +16,7 @@ class PosBox(CashBox):
active_ids = context.get('active_ids', []) or []
if active_model == 'pos.session':
- records = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)
+ records = self.pool[active_model].browse(cr, uid, active_ids, context=context)
bank_statements = [record.cash_register_id for record in records if record.cash_register_id]
if not bank_statements:
@@ -41,7 +41,7 @@ class PosBoxIn(PosBox):
active_ids = context.get('active_ids', []) or []
if active_model == 'pos.session':
- session = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)[0]
+ session = self.pool[active_model].browse(cr, uid, active_ids, context=context)[0]
values['ref'] = session.name
return values
@@ -57,7 +57,7 @@ class PosBoxOut(PosBox):
active_ids = context.get('active_ids', []) or []
if active_model == 'pos.session':
- session = self.pool.get(active_model).browse(cr, uid, active_ids, context=context)[0]
+ session = self.pool[active_model].browse(cr, uid, active_ids, context=context)[0]
values['ref'] = session.name
return values
diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py
index 3810ddd2540..bc982671bfe 100644
--- a/addons/portal/mail_mail.py
+++ b/addons/portal/mail_mail.py
@@ -45,7 +45,7 @@ class mail_mail(osv.Model):
and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False):
related_user = partner.user_ids[0]
try:
- self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
+ self.pool[mail.model].check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
url = partner_obj._get_signup_url_for_action(cr, related_user.id, [partner.id], action='', res_id=mail.res_id, model=mail.model, context=context)[partner.id]
text = _("""Access this document directly in OpenERP""") % url
except except_orm, e:
diff --git a/addons/portal_stock/security/portal_security.xml b/addons/portal_stock/security/portal_security.xml
index 154a7fc9ddd..c5587453e40 100644
--- a/addons/portal_stock/security/portal_security.xml
+++ b/addons/portal_stock/security/portal_security.xml
@@ -17,19 +17,5 @@
-
- Portal Personal Stock Moves
-
- [('message_follower_ids','in',[user.partner_id.id])]
-
-
-
-
- Portal Personal Stock Warehouse Orderpoints
-
- [('message_follower_ids','in',[user.partner_id.id])]
-
-
-
diff --git a/addons/procurement/schedulers.py b/addons/procurement/schedulers.py
index 1009873beb2..7c9d5ec3290 100644
--- a/addons/procurement/schedulers.py
+++ b/addons/procurement/schedulers.py
@@ -155,7 +155,7 @@ class procurement_order(osv.osv):
warehouse_obj = self.pool.get('stock.warehouse')
warehouse_ids = warehouse_obj.search(cr, uid, [], context=context)
- products_ids = product_obj.search(cr, uid, [('purchase_ok', '=', True)], order='id', context=context)
+ products_ids = product_obj.search(cr, uid, [], order='id', context=context)
for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context):
context['warehouse'] = warehouse
diff --git a/addons/project/wizard/project_task_delegate.py b/addons/project/wizard/project_task_delegate.py
index bb15c62db1f..bbea5ce2d8f 100644
--- a/addons/project/wizard/project_task_delegate.py
+++ b/addons/project/wizard/project_task_delegate.py
@@ -125,7 +125,7 @@ class project_task_delegate(osv.osv_memory):
action_model, action_id = models_data.get_object_reference(cr, uid, 'project', 'action_view_task')
view_model, task_view_form_id = models_data.get_object_reference(cr, uid, 'project', 'view_task_form2')
view_model, task_view_tree_id = models_data.get_object_reference(cr, uid, 'project', 'view_task_tree2')
- action = self.pool.get(action_model).read(cr, uid, action_id, context=context)
+ action = self.pool[action_model].read(cr, uid, action_id, context=context)
action['res_id'] = delegated_tasks[task_id]
action['view_id'] = False
action['views'] = [(task_view_form_id, 'form'), (task_view_tree_id, 'tree')]
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py
index e53ff9ed253..109f0c03c6f 100644
--- a/addons/project_long_term/project_long_term.py
+++ b/addons/project_long_term/project_long_term.py
@@ -283,9 +283,11 @@ class account_analytic_account(osv.osv):
res['value']['use_phases'] = template.use_phases
return res
+
def _trigger_project_creation(self, cr, uid, vals, context=None):
- res= super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)
- return res or vals.get('use_phases')
+ if context is None: context = {}
+ res = super(account_analytic_account, self)._trigger_project_creation(cr, uid, vals, context=context)
+ return res or (vals.get('use_phases') and not 'project_creation_in_progress' in context)
account_analytic_account()
diff --git a/addons/project_mrp/test/project_task_procurement.yml b/addons/project_mrp/test/project_task_procurement.yml
index 8854ce20c80..967461ca30a 100644
--- a/addons/project_mrp/test/project_task_procurement.yml
+++ b/addons/project_mrp/test/project_task_procurement.yml
@@ -27,7 +27,7 @@
assert (not project and not account) or project.analytic_account_id == account, "Project does not correspond."
planned_hours = self._convert_qty_company_hours(cr, uid, procurement, context=context)
assert task.planned_hours == planned_hours, 'Planned Hours do not correspond.'
- assert datetime.strptime(task.date_deadline, '%Y-%m-%d') == datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S'), 'Deadline does not correspond.'
+ assert datetime.strptime(task.date_deadline, '%Y-%m-%d') == datetime.strptime(procurement.date_planned[:10], '%Y-%m-%d'), 'Deadline does not correspond.'
if procurement.product_id.product_manager:
assert task.user_id.id == procurement.product_id.product_manager.id, 'Allocated Person does not correspond with Service Product Manager.'
-
diff --git a/addons/purchase/company.py b/addons/purchase/company.py
index 275f5ea200d..7a5d26a1b52 100644
--- a/addons/purchase/company.py
+++ b/addons/purchase/company.py
@@ -24,8 +24,12 @@ from openerp.osv import osv,fields
class company(osv.osv):
_inherit = 'res.company'
_columns = {
- 'po_lead': fields.float('Purchase Lead Time', required=True,
- help="This is the leads/security time for each purchase order."),
+ 'po_lead': fields.float(
+ 'Purchase Lead Time', required=True,
+ help="Margin of error for supplier lead times. When the system"\
+ "generates Purchase Orders for procuring products,"\
+ "they will be scheduled that many days earlier "\
+ "to cope with unexpected supplier delays."),
}
_defaults = {
'po_lead': lambda *a: 1.0,
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 4c18739cc78..7e95a64fcee 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -20,6 +20,8 @@
##############################################################################
import time
+import pytz
+from openerp import SUPERUSER_ID
from datetime import datetime
from dateutil.relativedelta import relativedelta
from operator import attrgetter
@@ -371,7 +373,7 @@ class purchase_order(osv.osv):
pick_ids += [picking.id for picking in po.picking_ids]
action_model, action_id = tuple(mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree4'))
- action = self.pool.get(action_model).read(cr, uid, action_id, context=context)
+ action = self.pool[action_model].read(cr, uid, action_id, context=context)
ctx = eval(action['context'])
ctx.update({
'search_default_purchase_id': ids[0]
@@ -592,11 +594,34 @@ class purchase_order(osv.osv):
self.signal_purchase_cancel(cr, uid, ids)
return True
+ def date_to_datetime(self, cr, uid, userdate, context=None):
+ """ Convert date values expressed in user's timezone to
+ server-side UTC timestamp, assuming a default arbitrary
+ time of 12:00 AM - because a time is needed.
+
+ :param str userdate: date string in in user time zone
+ :return: UTC datetime string for server-side use
+ """
+ # TODO: move to fields.datetime in server after 7.0
+ user_date = datetime.strptime(userdate, DEFAULT_SERVER_DATE_FORMAT)
+ if context and context.get('tz'):
+ tz_name = context['tz']
+ else:
+ tz_name = self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz']
+ if tz_name:
+ utc = pytz.timezone('UTC')
+ context_tz = pytz.timezone(tz_name)
+ user_datetime = user_date + relativedelta(hours=12.0)
+ local_timestamp = context_tz.localize(user_datetime, is_dst=False)
+ user_datetime = local_timestamp.astimezone(utc)
+ return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+ return user_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+
def _prepare_order_picking(self, cr, uid, order, context=None):
return {
'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.in'),
'origin': order.name + ((order.origin and (':' + order.origin)) or ''),
- 'date': order.date_order,
+ 'date': self.date_to_datetime(cr, uid, order.date_order, context),
'partner_id': order.dest_address_id.id or order.partner_id.id,
'invoice_state': '2binvoiced' if order.invoice_method == 'picking' else 'none',
'type': 'in',
@@ -614,8 +639,8 @@ class purchase_order(osv.osv):
'product_uos_qty': order_line.product_qty,
'product_uom': order_line.product_uom.id,
'product_uos': order_line.product_uom.id,
- 'date': order_line.date_planned,
- 'date_expected': order_line.date_planned,
+ 'date': self.date_to_datetime(cr, uid, order.date_order, context),
+ 'date_expected': self.date_to_datetime(cr, uid, order.date_order, context),
'location_id': order.partner_id.property_stock_supplier.id,
'location_dest_id': order.location_id.id,
'picking_id': picking_id,
diff --git a/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml b/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml
index bcc67a2a215..d1db411f68c 100644
--- a/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml
+++ b/addons/purchase_analytic_plans/purchase_analytic_plans_view.xml
@@ -38,5 +38,22 @@
+
+
+
+
+
+
+
+ account.invoice.supplier.form.inherit
+ account.invoice
+
+ 2
+
+
+
+
+
+
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index d1b4236cd4e..2efa571c265 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -211,8 +211,7 @@ class sale_order(osv.osv):
'order_policy': fields.selection([
('manual', 'On Demand'),
], 'Create Invoice', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
- help="""This field controls how invoice and delivery operations are synchronized.
- - With 'Before Delivery', a draft invoice is created, and it must be paid before delivery."""),
+ help="""This field controls how invoice and delivery operations are synchronized."""),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="Pricelist for current sales order."),
'currency_id': fields.related('pricelist_id', 'currency_id', type="many2one", relation="res.currency", string="Currency", readonly=True, required=True),
'project_id': fields.many2one('account.analytic.account', 'Contract / Analytic', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="The analytic account related to a sales order."),
diff --git a/addons/sale_analytic_plans/sale_analytic_plans_view.xml b/addons/sale_analytic_plans/sale_analytic_plans_view.xml
index 6c788866520..3600d71b7d4 100644
--- a/addons/sale_analytic_plans/sale_analytic_plans_view.xml
+++ b/addons/sale_analytic_plans/sale_analytic_plans_view.xml
@@ -38,5 +38,19 @@
+
+
+
+
+ account.invoice.line.form.inherit
+ account.invoice.line
+
+
+
+
+
+
+
+
diff --git a/addons/sale_crm/sale_crm.py b/addons/sale_crm/sale_crm.py
index 3177aec4c5f..d0899729050 100644
--- a/addons/sale_crm/sale_crm.py
+++ b/addons/sale_crm/sale_crm.py
@@ -68,6 +68,21 @@ class res_users(osv.Model):
}
+class sale_crm_lead(osv.Model):
+ _inherit = 'crm.lead'
+
+ def on_change_user(self, cr, uid, ids, user_id, context=None):
+ """ Override of on change user_id on lead/opportunity; when having sale
+ the new logic is :
+ - use user.default_section_id
+ - or fallback on previous behavior """
+ if user_id:
+ user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
+ if user.default_section_id and user.default_section_id.id:
+ return {'value': {'section_id': user.default_section_id.id}}
+ return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context)
+
+
class account_invoice(osv.osv):
_inherit = 'account.invoice'
_columns = {
diff --git a/addons/sale_stock/company.py b/addons/sale_stock/company.py
index 67440ed6c67..eb2d644e57b 100644
--- a/addons/sale_stock/company.py
+++ b/addons/sale_stock/company.py
@@ -24,9 +24,12 @@ from openerp.osv import fields, osv
class company(osv.osv):
_inherit = 'res.company'
_columns = {
- 'security_lead': fields.float('Security Days', required=True,
- help="This is the days added to what you promise to customers "\
- "for security purpose"),
+ 'security_lead': fields.float(
+ 'Security Days', required=True,
+ help="Margin of error for dates promised to customers. "\
+ "Products will be scheduled for procurement and delivery "\
+ "that many days earlier than the actual promised date, to "\
+ "cope with unexpected delays in the supply chain."),
}
_defaults = {
'security_lead': 0.0,
diff --git a/addons/sale_stock/process/sale_stock_process.xml b/addons/sale_stock/process/sale_stock_process.xml
index 666f6ba6502..c10b34c8866 100644
--- a/addons/sale_stock/process/sale_stock_process.xml
+++ b/addons/sale_stock/process/sale_stock_process.xml
@@ -64,17 +64,6 @@
-
-
-
-
-
-
-
-
-
@@ -106,7 +95,7 @@
-
+
diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py
index bd4eb2b8256..15cb4d1e7e7 100644
--- a/addons/sale_stock/sale_stock.py
+++ b/addons/sale_stock/sale_stock.py
@@ -24,6 +24,8 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FO
from dateutil.relativedelta import relativedelta
from openerp.osv import fields, osv
from openerp.tools.translate import _
+import pytz
+from openerp import SUPERUSER_ID
class sale_shop(osv.osv):
_inherit = "sale.shop"
@@ -229,6 +231,29 @@ class sale_order(osv.osv):
res.append(line.procurement_id.id)
return res
+ def date_to_datetime(self, cr, uid, userdate, context=None):
+ """ Convert date values expressed in user's timezone to
+ server-side UTC timestamp, assuming a default arbitrary
+ time of 12:00 AM - because a time is needed.
+
+ :param str userdate: date string in in user time zone
+ :return: UTC datetime string for server-side use
+ """
+ # TODO: move to fields.datetime in server after 7.0
+ user_date = datetime.strptime(userdate, DEFAULT_SERVER_DATE_FORMAT)
+ if context and context.get('tz'):
+ tz_name = context['tz']
+ else:
+ tz_name = self.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz']
+ if tz_name:
+ utc = pytz.timezone('UTC')
+ context_tz = pytz.timezone(tz_name)
+ user_datetime = user_date + relativedelta(hours=12.0)
+ local_timestamp = context_tz.localize(user_datetime, is_dst=False)
+ user_datetime = local_timestamp.astimezone(utc)
+ return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+ return user_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+
# if mode == 'finished':
# returns True if all lines are done, False otherwise
# if mode == 'canceled':
@@ -311,7 +336,7 @@ class sale_order(osv.osv):
return {
'name': pick_name,
'origin': order.name,
- 'date': order.date_order,
+ 'date': self.date_to_datetime(cr, uid, order.date_order, context),
'type': 'out',
'state': 'auto',
'move_type': order.picking_policy,
@@ -345,7 +370,8 @@ class sale_order(osv.osv):
return True
def _get_date_planned(self, cr, uid, order, line, start_date, context=None):
- date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=line.delay or 0.0)
+ start_date = self.date_to_datetime(cr, uid, start_date, context)
+ date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=line.delay or 0.0)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
return date_planned
@@ -605,11 +631,6 @@ class sale_advance_payment_inv(osv.osv_memory):
sale_line_obj = self.pool.get('sale.order.line')
wizard = self.browse(cr, uid, [result], context)
sale = sale_obj.browse(cr, uid, sale_id, context=context)
- if sale.order_policy == 'postpaid':
- raise osv.except_osv(
- _('Error!'),
- _("You cannot make an advance on a sales order \
- that is defined as 'Automatic Invoice after delivery'."))
# If invoice on picking: add the cost on the SO
# If not, the advance will be deduced when generating the final invoice
diff --git a/addons/sale_stock/test/picking_order_policy.yml b/addons/sale_stock/test/picking_order_policy.yml
index 1df3626880f..92cdac4a85c 100644
--- a/addons/sale_stock/test/picking_order_policy.yml
+++ b/addons/sale_stock/test/picking_order_policy.yml
@@ -26,7 +26,8 @@
order = self.browse(cr, uid, ref("sale.sale_order_6"))
for order_line in order.order_line:
procurement = order_line.procurement_id
- date_planned = datetime.strptime(order.date_order, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=order_line.delay or 0.0)
+ sale_order_date = self.date_to_datetime(cr, uid, order.date_order, context)
+ date_planned = datetime.strptime(sale_order_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=order_line.delay or 0.0)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
assert procurement.date_planned == date_planned, "Scheduled date is not correspond."
assert procurement.product_id.id == order_line.product_id.id, "Product is not correspond."
@@ -60,7 +61,8 @@
output_id = sale_order.shop_id.warehouse_id.lot_output_id.id
for move in picking.move_lines:
order_line = move.sale_line_id
- date_planned = datetime.strptime(sale_order.date_order, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=order_line.delay or 0.0)
+ sale_order_date = self.date_to_datetime(cr, uid, sale_order.date_order, context)
+ date_planned = datetime.strptime(sale_order_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=order_line.delay or 0.0)
date_planned = (date_planned - timedelta(days=sale_order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
assert datetime.strptime(move.date_expected, DEFAULT_SERVER_DATETIME_FORMAT) == datetime.strptime(date_planned, DEFAULT_SERVER_DATETIME_FORMAT), "Excepted Date is not correspond with Planned Date."
assert move.product_id.id == order_line.product_id.id,"Product is not correspond."
diff --git a/addons/share/wizard/share_wizard.py b/addons/share/wizard/share_wizard.py
index 429a1dc2f08..813a8a80e88 100644
--- a/addons/share/wizard/share_wizard.py
+++ b/addons/share/wizard/share_wizard.py
@@ -205,7 +205,7 @@ class share_wizard(osv.TransientModel):
raise osv.except_osv(_('No email address configured'),
_('You must configure your email address in the user preferences before using the Share button.'))
model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'share', 'action_share_wizard_step1')
- action = self.pool.get(model).read(cr, uid, res_id, context=context)
+ action = self.pool[model].read(cr, uid, res_id, context=context)
action['res_id'] = ids[0]
action.pop('context', '')
return action
@@ -404,7 +404,7 @@ class share_wizard(osv.TransientModel):
local_rel_fields = []
models = [x[1].model for x in relation_fields]
model_obj = self.pool.get('ir.model')
- model_osv = self.pool.get(model.model)
+ model_osv = self.pool[model.model]
for colinfo in model_osv._all_columns.itervalues():
coldef = colinfo.column
coltype = coldef._type
@@ -412,7 +412,7 @@ class share_wizard(osv.TransientModel):
if coltype in ttypes and colinfo.column._obj not in models:
relation_model_id = model_obj.search(cr, UID_ROOT, [('model','=',coldef._obj)])[0]
relation_model_browse = model_obj.browse(cr, UID_ROOT, relation_model_id, context=context)
- relation_osv = self.pool.get(coldef._obj)
+ relation_osv = self.pool[coldef._obj]
if coltype == 'one2many':
# don't record reverse path if it's not a real m2o (that happens, but rarely)
dest_model_ci = relation_osv._all_columns
@@ -422,7 +422,7 @@ class share_wizard(osv.TransientModel):
local_rel_fields.append((relation_field, relation_model_browse))
for parent in relation_osv._inherits:
if parent not in models:
- parent_model = self.pool.get(parent)
+ parent_model = self.pool[parent]
parent_colinfos = parent_model._all_columns
parent_model_browse = model_obj.browse(cr, UID_ROOT,
model_obj.search(cr, UID_ROOT, [('model','=',parent)]))[0]
@@ -458,7 +458,7 @@ class share_wizard(osv.TransientModel):
"""
# obj0 class and its parents
obj0 = [(None, model)]
- model_obj = self.pool.get(model.model)
+ model_obj = self.pool[model.model]
ir_model_obj = self.pool.get('ir.model')
for parent in model_obj._inherits:
parent_model_browse = ir_model_obj.browse(cr, UID_ROOT,
@@ -777,7 +777,7 @@ class share_wizard(osv.TransientModel):
# Record id not found: issue
if res_id <= 0:
raise osv.except_osv(_('Record id not found'), _('The share engine has not been able to fetch a record_id for your invitation.'))
- self.pool.get(model.model).message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context)
+ self.pool[model.model].message_subscribe(cr, uid, [res_id], new_ids + existing_ids, context=context)
# self.send_invite_email(cr, uid, wizard_data, context=context)
# self.send_invite_note(cr, uid, model.model, res_id, wizard_data, context=context)
@@ -823,7 +823,7 @@ class share_wizard(osv.TransientModel):
elif tmp_idx == len(wizard_data.result_line_ids)-2:
body += ' and'
body += '.'
- return self.pool.get(model_name).message_post(cr, uid, [res_id], body=body, context=context)
+ return self.pool[model_name].message_post(cr, uid, [res_id], body=body, context=context)
def send_invite_email(self, cr, uid, wizard_data, context=None):
# TDE Note: not updated because will disappear
diff --git a/addons/stock/report/product_stock.py b/addons/stock/report/product_stock.py
index 0315c44281b..d213db673dc 100644
--- a/addons/stock/report/product_stock.py
+++ b/addons/stock/report/product_stock.py
@@ -30,6 +30,7 @@ from openerp.report.render import render
import stock_graph
import StringIO
+import unicodedata
class external_pdf(render):
def __init__(self, pdf):
@@ -107,7 +108,12 @@ class report_stock(report_int):
io = StringIO.StringIO()
gt = stock_graph.stock_graph(io)
for prod_id in products:
- gt.add(prod_id, names.get(prod_id, 'Unknown'), products[prod_id])
+ prod_name = names.get(prod_id,'Unknown')
+ if isinstance(prod_name, str):
+ prod_name = prod_name.decode('utf-8')
+ prod_name = unicodedata.normalize('NFKD',prod_name)
+ prod_name = prod_name.encode('ascii','replace')
+ gt.add(prod_id, prod_name, products[prod_id])
gt.draw()
gt.close()
self.obj = external_pdf(io.getvalue())
diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py
index 39591021735..7956699c113 100644
--- a/addons/stock/report/report_stock_move.py
+++ b/addons/stock/report/report_stock_move.py
@@ -193,6 +193,7 @@ CREATE OR REPLACE view report_stock_inventory AS (
LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id)
LEFT JOIN product_uom u ON (m.product_uom=u.id)
LEFT JOIN stock_location l ON (m.location_id=l.id)
+ WHERE m.state != 'cancel'
GROUP BY
m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id,
m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM')
@@ -216,6 +217,7 @@ CREATE OR REPLACE view report_stock_inventory AS (
LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id)
LEFT JOIN product_uom u ON (m.product_uom=u.id)
LEFT JOIN stock_location l ON (m.location_dest_id=l.id)
+ WHERE m.state != 'cancel'
GROUP BY
m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id,
m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM')
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index be0dd59468c..d62ce7c2eaf 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -2944,6 +2944,12 @@ class stock_picking_in(osv.osv):
_table = "stock_picking"
_description = "Incoming Shipments"
+ def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
+ return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count)
+
+ def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
+ return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load)
+
def check_access_rights(self, cr, uid, operation, raise_exception=True):
#override in order to redirect the check of acces rights on the stock.picking object
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
@@ -2999,6 +3005,12 @@ class stock_picking_out(osv.osv):
_table = "stock_picking"
_description = "Delivery Orders"
+ def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
+ return self.pool.get('stock.picking').search(cr, user, args, offset, limit, order, context, count)
+
+ def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
+ return self.pool.get('stock.picking').read(cr, uid, ids, fields=fields, context=context, load=load)
+
def check_access_rights(self, cr, uid, operation, raise_exception=True):
#override in order to redirect the check of acces rights on the stock.picking object
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
diff --git a/addons/stock/wizard/stock_invoice_onshipping.py b/addons/stock/wizard/stock_invoice_onshipping.py
index 7c960c5e617..d742ede366d 100644
--- a/addons/stock/wizard/stock_invoice_onshipping.py
+++ b/addons/stock/wizard/stock_invoice_onshipping.py
@@ -39,7 +39,7 @@ class stock_invoice_onshipping(osv.osv_memory):
if not model or 'stock.picking' not in model:
return []
- model_pool = self.pool.get(model)
+ model_pool = self.pool[model]
journal_obj = self.pool.get('account.journal')
res_ids = context and context.get('active_ids', [])
vals = []
@@ -119,7 +119,7 @@ class stock_invoice_onshipping(osv.osv_memory):
elif inv_type == "in_refund":
action_model,action_id = data_pool.get_object_reference(cr, uid, 'account', "action_invoice_tree4")
if action_model:
- action_pool = self.pool.get(action_model)
+ action_pool = self.pool[action_model]
action = action_pool.read(cr, uid, action_id, context=context)
action['domain'] = "[('id','in', ["+','.join(map(str,invoice_ids))+"])]"
return action
diff --git a/addons/subscription/subscription.py b/addons/subscription/subscription.py
index 92bde135bc6..356ab78aadb 100644
--- a/addons/subscription/subscription.py
+++ b/addons/subscription/subscription.py
@@ -115,7 +115,7 @@ class subscription_subscription(osv.osv):
try:
(model_name, id) = row['doc_source'].split(',')
id = int(id)
- model = self.pool.get(model_name)
+ model = self.pool[model_name]
except:
raise osv.except_osv(_('Wrong Source Document !'), _('Please provide another source document.\nThis one does not exist !'))
@@ -136,7 +136,7 @@ class subscription_subscription(osv.osv):
# the subscription is over and we mark it as being done
if remaining == 1:
state = 'done'
- id = self.pool.get(model_name).copy(cr, uid, id, default, context)
+ id = self.pool[model_name].copy(cr, uid, id, default, context)
self.pool.get('subscription.subscription.history').create(cr, uid, {'subscription_id': row['id'], 'date':time.strftime('%Y-%m-%d %H:%M:%S'), 'document_id': model_name+','+str(id)})
self.write(cr, uid, [row['id']], {'state':state})
return True
diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py
index 903937af441..a108388ac8e 100644
--- a/addons/survey/wizard/survey_answer.py
+++ b/addons/survey/wizard/survey_answer.py
@@ -402,9 +402,10 @@ class survey_question_wiz(osv.osv_memory):
sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
# mark the survey request as done; call 'survey_req_done' on its actual model
- survey_req_obj = self.pool.get(context.get('active_model'))
- if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'):
- survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
+ if context.get('active_model') in self.pool:
+ survey_req_obj = self.pool[context.get('active_model')]
+ if hasattr(survey_req_obj, 'survey_req_done'):
+ survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
if sur_rec.send_response:
survey_data = survey_obj.browse(cr, uid, survey_id)
@@ -609,10 +610,10 @@ class survey_question_wiz(osv.osv_memory):
survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
if context.has_key('cur_id'):
if context.has_key('request') and context.get('request',False):
- self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
- self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
+ self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
+ self.pool[context.get('object')].survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
else:
- self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
+ self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
if sur_name_read['store_ans'] and type(safe_eval(sur_name_read['store_ans'])) == dict:
sur_name_read['store_ans'] = safe_eval(sur_name_read['store_ans'])
for key,val in sur_name_read['store_ans'].items():