[MERGE] forward port branch saas-6 up to 7cb977fc3c
This commit is contained in:
@@ -221,6 +221,7 @@ class calendar_attendee(osv.Model):
|
||||
'datas_fname': 'invitation.ics',
|
||||
'datas': str(ics_file).encode('base64')})]
|
||||
vals['model'] = None # We don't want to have the mail in the tchatter while in queue!
|
||||
vals['res_id'] = False
|
||||
the_mailmess = mail_pool.browse(cr, uid, mail_id, context=context).mail_message_id
|
||||
mailmess_pool.write(cr, uid, [the_mailmess.id], vals, context=context)
|
||||
mail_ids.append(mail_id)
|
||||
@@ -1615,11 +1616,11 @@ class calendar_event(osv.Model):
|
||||
super(calendar_event, self).write(cr, uid, real_ids, values, context=context)
|
||||
|
||||
# set end_date for calendar searching
|
||||
if values.get('recurrency') and values.get('end_type', 'count') in ('count', unicode('count')) and \
|
||||
(values.get('rrule_type') or values.get('count') or values.get('start') or values.get('stop')):
|
||||
for id in real_ids:
|
||||
final_date = self._get_recurrency_end_date(cr, uid, id, context=context)
|
||||
super(calendar_event, self).write(cr, uid, [id], {'final_date': final_date}, context=context)
|
||||
if any(field in values for field in ['recurrency', 'end_type', 'count', 'rrule_type', 'start', 'stop']):
|
||||
for event in self.browse(cr, uid, real_ids, context=context):
|
||||
if event.recurrency and event.end_type in ('count', unicode('count')):
|
||||
final_date = self._get_recurrency_end_date(cr, uid, event.id, context=context)
|
||||
super(calendar_event, self).write(cr, uid, [event.id], {'final_date': final_date}, context=context)
|
||||
|
||||
attendees_create = False
|
||||
if values.get('partner_ids', False):
|
||||
@@ -1714,7 +1715,8 @@ class calendar_event(osv.Model):
|
||||
for r in result:
|
||||
if r['user_id']:
|
||||
user_id = type(r['user_id']) in (tuple, list) and r['user_id'][0] or r['user_id']
|
||||
if user_id == uid:
|
||||
partner_id = self.pool['res.users'].browse(cr, uid, uid, context).partner_id.id
|
||||
if user_id == uid or partner_id in r.get("partner_ids", []):
|
||||
continue
|
||||
if r['class'] == 'private':
|
||||
for f in r.keys():
|
||||
|
||||
@@ -112,23 +112,31 @@ class Followers(models.Model):
|
||||
# Modifying followers change access rights to individual documents. As the
|
||||
# cache may contain accessible/inaccessible data, one has to refresh it.
|
||||
#
|
||||
@api.multi
|
||||
def _invalidate_documents(self):
|
||||
""" Invalidate the cache of the documents followed by ``self``. """
|
||||
for record in self:
|
||||
if record.res_id:
|
||||
self.env[record.res_model].invalidate_cache(ids=[record.res_id])
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
res = super(Followers, self).create(vals)
|
||||
self.invalidate_cache()
|
||||
res._invalidate_documents()
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
if 'res_model' in vals or 'res_id' in vals:
|
||||
self._invalidate_documents()
|
||||
res = super(Followers, self).write(vals)
|
||||
self.invalidate_cache()
|
||||
self._invalidate_documents()
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
res = super(Followers, self).unlink()
|
||||
self.invalidate_cache()
|
||||
return res
|
||||
self._invalidate_documents()
|
||||
return super(Followers, self).unlink()
|
||||
|
||||
_sql_constraints = [
|
||||
('mail_followers_res_partner_res_model_id_uniq', 'unique(res_model,res_id,partner_id)', 'Error, a partner cannot follow twice the same object.'),
|
||||
|
||||
@@ -853,6 +853,13 @@ class Message(models.Model):
|
||||
message_id = tools.generate_tracking_message_id('private')
|
||||
return message_id
|
||||
|
||||
@api.multi
|
||||
def _invalidate_documents(self):
|
||||
""" Invalidate the cache of the documents followed by ``self``. """
|
||||
for record in self:
|
||||
if record.res_id:
|
||||
self.env[record.model].invalidate_cache(ids=[record.res_id])
|
||||
|
||||
@api.model
|
||||
def create(self, values):
|
||||
# coming from mail.js that does not have pid in its values
|
||||
@@ -869,6 +876,7 @@ class Message(models.Model):
|
||||
values['record_name'] = self._get_record_name(values)
|
||||
|
||||
message = super(Message, self).create(values)
|
||||
message._invalidate_documents()
|
||||
|
||||
message._notify(force_send=self.env.context.get('mail_notify_force_send', True),
|
||||
user_signature=self.env.context.get('mail_notify_user_signature', True))
|
||||
@@ -881,6 +889,14 @@ class Message(models.Model):
|
||||
self.check_access_rule('read')
|
||||
return super(Message, self).read(fields=fields, load=load)
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
if 'model' in vals or 'res_id' in vals:
|
||||
self._invalidate_documents()
|
||||
res = super(Message, self).write(vals)
|
||||
self._invalidate_documents()
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
# cascade-delete attachments that are directly attached to the message (should only happen
|
||||
@@ -889,6 +905,7 @@ class Message(models.Model):
|
||||
self.mapped('attachment_ids').filtered(
|
||||
lambda attach: attach.res_model == self._name and (attach.res_id in self.ids or attach.res_id == 0)
|
||||
).unlink()
|
||||
self._invalidate_documents()
|
||||
return super(Message, self).unlink()
|
||||
|
||||
#------------------------------------------------------
|
||||
|
||||
@@ -25,6 +25,17 @@ class TestMailFeatures(TestMail):
|
||||
'login': 'b4r+_#_R3wl$$', 'alias_name': 'b4r+_#_R3wl$$'})
|
||||
self.assertEqual(user_barty.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens')
|
||||
|
||||
def test_10_cache_invalidation(self):
|
||||
""" Test that creating a mail-thread record does not invalidate the whole cache. """
|
||||
# make a new record in cache
|
||||
record = self.env['res.partner'].new({'name': 'Brave New Partner'})
|
||||
self.assertTrue(record.name)
|
||||
|
||||
# creating a mail-thread record should not invalidate the whole cache
|
||||
self.env['res.partner'].create({'name': 'Actual Partner'})
|
||||
self.assertTrue(record.name)
|
||||
|
||||
|
||||
@mute_logger('openerp.addons.mail.models.mail_mail')
|
||||
def test_needaction(self):
|
||||
na_emp1_base = self.env['mail.message'].sudo(self.user_employee)._needaction_count(domain=[])
|
||||
|
||||
@@ -251,3 +251,8 @@ class TestMailMessage(TestMail):
|
||||
msg.set_message_starred(False)
|
||||
self.assertFalse(msg.starred)
|
||||
self.assertTrue(msg_emp.starred)
|
||||
|
||||
def test_60_cache_invalidation(self):
|
||||
msg_cnt = len(self.group_pigs.message_ids)
|
||||
self.group_pigs.message_post(body='Hi!', subject='test')
|
||||
self.assertEqual(len(self.group_pigs.message_ids), msg_cnt + 1)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
<template id="layout" name="Main layout"><!DOCTYPE html>
|
||||
<html t-att-lang="lang and lang.replace('_', '-')"
|
||||
t-att-data-website-id="website.id if (editable or translatable) and website else None"
|
||||
t-att-data-website-id="website.id if website else None"
|
||||
t-att-data-editable="'1' if editable else None"
|
||||
t-att-data-translatable="'1' if translatable else None"
|
||||
t-att-data-edit_translations="'1' if edit_translations else None"
|
||||
|
||||
@@ -273,6 +273,25 @@ class website(orm.Model):
|
||||
def sale_product_domain(self, cr, uid, ids, context=None):
|
||||
return [("sale_ok", "=", True)]
|
||||
|
||||
def _prepare_sale_order_values(self, cr, uid, w, partner, pricelist, context=None):
|
||||
affiliate_id = request.session.get('affiliate_id')
|
||||
salesperson_id = affiliate_id if self.pool['res.users'].exists(cr, SUPERUSER_ID, affiliate_id, context=context) else request.website.salesperson_id.id
|
||||
addr = partner.address_get(['delivery', 'invoice'])
|
||||
values = {
|
||||
'partner_id': partner.id,
|
||||
'pricelist_id': pricelist.id,
|
||||
'payment_term_id': partner.property_payment_term_id.id if partner.property_payment_term_id else False,
|
||||
'team_id': w.salesteam_id.id,
|
||||
'partner_invoice_id': addr['invoice'],
|
||||
'partner_shipping_id': addr['delivery'],
|
||||
'user_id': salesperson_id or w.salesperson_id.id,
|
||||
}
|
||||
company_id = w.company_id or pricelist.company_id
|
||||
if company_id:
|
||||
values['company_id'] = company_id.id
|
||||
|
||||
return values
|
||||
|
||||
def get_partner(self, cr, uid):
|
||||
return self.pool['res.users'].browse(cr, SUPERUSER_ID, uid).partner_id
|
||||
|
||||
@@ -312,23 +331,9 @@ class website(orm.Model):
|
||||
# create so if needed
|
||||
if not sale_order_id and (force_create or code):
|
||||
# TODO cache partner_id session
|
||||
user_obj = self.pool['res.users']
|
||||
affiliate_id = request.session.get('affiliate_id')
|
||||
salesperson_id = affiliate_id if user_obj.exists(cr, SUPERUSER_ID, affiliate_id, context=context) else request.website.salesperson_id.id
|
||||
pricelist = self.pool['product.pricelist'].browse(cr, SUPERUSER_ID, [pricelist_id], context=context)
|
||||
for w in self.browse(cr, uid, ids):
|
||||
addr = partner.address_get(['delivery', 'invoice'])
|
||||
values = {
|
||||
'partner_id': partner.id,
|
||||
'pricelist_id': pricelist_id,
|
||||
'payment_term_id': partner.property_payment_term_id.id if partner.property_payment_term_id else False,
|
||||
'team_id': w.salesteam_id.id,
|
||||
'partner_invoice_id': addr['invoice'],
|
||||
'partner_shipping_id': addr['delivery'],
|
||||
'user_id': salesperson_id or w.salesperson_id.id,
|
||||
}
|
||||
company_id = w.company_id or self.pool['product.pricelist'].browse(cr, SUPERUSER_ID, [pricelist_id], context=context).company_id
|
||||
if company_id:
|
||||
values['company_id'] = company_id.id
|
||||
values = self._prepare_sale_order_values(cr, uid, w, partner, pricelist, context=context)
|
||||
sale_order_id = sale_order_obj.create(cr, SUPERUSER_ID, values, context=context)
|
||||
request.session['sale_order_id'] = sale_order_id
|
||||
sale_order = sale_order_obj.browse(cr, SUPERUSER_ID, sale_order_id, context=context)
|
||||
|
||||
@@ -417,7 +417,8 @@
|
||||
|
||||
<template id="product_price">
|
||||
<div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer" class="product_price mt16">
|
||||
<h4 class="oe_price_h4 css_editable_mode_hidden">
|
||||
<h4 class="oe_price_h4 css_editable_mode_hidden decimal_precision"
|
||||
t-att-data-precision="user_id.partner_id.property_product_pricelist.currency_id.rounding">
|
||||
<span class="text-danger oe_default_price" style="text-decoration: line-through; white-space: nowrap;"
|
||||
t-field="product.lst_price"
|
||||
t-field-options='{
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
import controllers
|
||||
import controllers
|
||||
import models
|
||||
@@ -0,0 +1 @@
|
||||
import website
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import orm
|
||||
|
||||
|
||||
class website(orm.Model):
|
||||
_inherit = 'website'
|
||||
|
||||
def _prepare_sale_order_values(self, cr, uid, w, partner, pricelist, context=None):
|
||||
values = super(website, self)._prepare_sale_order_values(cr, uid, w, partner, pricelist, context=context)
|
||||
if values['company_id']:
|
||||
warehouse_ids = self.pool['stock.warehouse'].search(cr, SUPERUSER_ID, [('company_id', '=', values['company_id'])], context=context)
|
||||
if warehouse_ids:
|
||||
values['warehouse_id'] = warehouse_ids[0]
|
||||
return values
|
||||
@@ -0,0 +1,21 @@
|
||||
Honduras, 2017-01-12
|
||||
|
||||
Business Analytics Consulting Group S.A. de C.V. agrees to the terms of the Odoo Corporate Contributor License
|
||||
Agreement v1.0.
|
||||
|
||||
I declare that I am authorized and able to make this agreement and sign this
|
||||
declaration.
|
||||
|
||||
Signed,
|
||||
|
||||
Leandro Gabriel Di Pasquale dipasquale@bacgroup.net https://github.com/leodipasquale
|
||||
|
||||
List of contributors:
|
||||
|
||||
Allan Daniel Aguilar Archaga aguilar@bacgroup.net https://github.com/allanaguilar
|
||||
Cesar Alejandro Rodriguez Castillo rodriguez@bacgroup.net https://github.com/hondurasopen
|
||||
Dewin Javier Garcia Armijo garcia@bacgroup.net https://github.com/dewingarcia
|
||||
Jose Reynaldo Cabrera Ayala cabrera@bacgroup.net https://github.com/jcabrera1990
|
||||
Leandro Gabriel Di Pasquale dipasquale@bacgroup.net https://github.com/leodipasquale
|
||||
Edwin Omar McClellan Salinas mcclellan@bacgroup.net https://github.com/prometeomcclellan
|
||||
Salvatore Josue Trimarchi Pinto trimarchi@bacgroup.net https://github.com/salvatoretrimarchi
|
||||
@@ -0,0 +1,11 @@
|
||||
canada, 2017/1/3
|
||||
|
||||
I hereby agree to the terms of the Odoo Individual Contributor License
|
||||
Agreement v1.0.
|
||||
|
||||
I declare that I am authorized and able to make this agreement and sign this
|
||||
declaration.
|
||||
|
||||
Signed,
|
||||
|
||||
kevin hua boogerlad@gmail.com https://github.com/boogerlad
|
||||
@@ -276,13 +276,13 @@ class ir_property(osv.osv):
|
||||
elif value <= 0 and operator == '>=':
|
||||
operator = '<'
|
||||
include_zero = True
|
||||
elif value <= 0 and operator == '>':
|
||||
elif value < 0 and operator == '>':
|
||||
operator = '<='
|
||||
include_zero = True
|
||||
elif value >= 0 and operator == '<=':
|
||||
operator = '>'
|
||||
include_zero = True
|
||||
elif value >= 0 and operator == '<':
|
||||
elif value > 0 and operator == '<':
|
||||
operator = '>='
|
||||
include_zero = True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user