[MERGE] forward port of branch saas-6 up to a0c64bebe6

This commit is contained in:
Denis Ledoux
2015-10-28 12:01:30 +01:00
15 changed files with 39 additions and 19 deletions
+3 -2
View File
@@ -82,8 +82,9 @@ class MailMail(osv.Model):
body = tools.append_content_to_html(base, body, plaintext=False, container_tag='div')
# resolve relative image url to absolute for outlook.com
def _sub_relative2absolute(match):
return match.group(1) + urlparse.urljoin(domain, match.group(2)) + '"'
body = re.sub('(<img(?=\s)[^>]*\ssrc=")(/[^/][^"]+)"', _sub_relative2absolute, body)
return match.group(1) + urlparse.urljoin(domain, match.group(2))
body = re.sub('(<img(?=\s)[^>]*\ssrc=")(/[^/][^"]+)', _sub_relative2absolute, body)
body = re.sub(r'(<[^>]+\bstyle="[^"]+\burl\(\'?)(/[^/\'][^\'")]+)', _sub_relative2absolute, body)
# generate tracking URL
if mail.statistics_ids:
@@ -40,8 +40,8 @@
<field name="config_id"/>
<field name="partner_id"/>
<field name="user_id"/>
<field name="partner_id"/>
<field name="user_id"/>
<field name="product_id"/>
<field name="product_categ_id"/>
<group expand="1" string="Group By">
<filter string="Salesperson" name="User" context="{'group_by':'user_id'}"/>
<filter string="Product Category" context="{'group_by':'product_categ_id'}"/>
+1 -1
View File
@@ -66,7 +66,7 @@
<field name="product_id"/>
<field name="user_id"/>
<group expand="0" string="Extended Filters">
<field name="categ_id"/>
<field name="categ_id" filter_domain="[('categ_id', 'child_of', self)]"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group expand="1" string="Group By">
+4 -1
View File
@@ -2783,12 +2783,15 @@ class stock_move(osv.osv):
'product_uom_qty': uom_qty,
'procure_method': 'make_to_stock',
'restrict_lot_id': restrict_lot_id,
'restrict_partner_id': restrict_partner_id,
'split_from': move.id,
'procurement_id': move.procurement_id.id,
'move_dest_id': move.move_dest_id.id,
'origin_returned_move_id': move.origin_returned_move_id.id,
}
if restrict_partner_id:
defaults['restrict_partner_id'] = restrict_partner_id
if context.get('source_location_id'):
defaults['location_id'] = context['source_location_id']
new_move = self.copy(cr, uid, move.id, defaults, context=context)
@@ -182,13 +182,13 @@ class stock_landed_cost(osv.osv):
if not cost.valuation_adjustment_lines or not self._check_sum(cr, uid, cost, context=context):
raise UserError(_('You cannot validate a landed cost which has no valid valuation adjustments lines. Did you click on Compute?'))
move_id = self._create_account_move(cr, uid, cost, context=context)
quant_dict = {}
for line in cost.valuation_adjustment_lines:
if not line.move_id:
continue
per_unit = line.final_cost / line.quantity
diff = per_unit - line.former_cost_per_unit
quants = [quant for quant in line.move_id.quant_ids]
quant_dict = {}
for quant in quants:
if quant.id not in quant_dict:
quant_dict[quant.id] = quant.cost + diff
@@ -189,7 +189,7 @@
<group>
<field name="split_method"/>
<field name="standard_price"/>
<field name="property_account_expense_id"/>
<field name="property_account_expense_id" domain="[('internal_type','=','other'),('deprecated', '=', False)]"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
+1 -5
View File
@@ -34,7 +34,6 @@ import openerp
import openerp.modules.registry
from openerp.addons.base.ir.ir_qweb import AssetsBundle, QWebTemplateNotFound
from openerp.modules import get_module_resource
from openerp.service import model as service_model
from openerp.tools import topological_sort
from openerp.tools.translate import _
from openerp.tools import ustr
@@ -961,10 +960,7 @@ class DataSet(http.Controller):
if method.startswith('_'):
raise AccessError(_("Underscore prefixed methods cannot be remotely called"))
@service_model.check
def checked_call(__dbname, *args, **kwargs):
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
return checked_call(request.db, *args, **kwargs)
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
@http.route('/web/dataset/call', type='json', auth="user")
def call(self, model, method, args, domain_id=None, context_id=None):
+4
View File
@@ -85,6 +85,8 @@ class sale_quote(http.Controller):
return request.website.render('website.404')
if order.require_payment:
return request.website.render('website.404')
if order.state != 'sent':
return False
attachments=sign and [('signature.png', sign.decode('base64'))] or []
order_obj.action_confirm(request.cr, SUPERUSER_ID, [order_id], context=request.context)
message = _('Order signed by %s') % (signer,)
@@ -97,6 +99,8 @@ class sale_quote(http.Controller):
order = order_obj.browse(request.cr, SUPERUSER_ID, order_id)
if token != order.access_token:
return request.website.render('website.404')
if order.state != 'sent':
return werkzeug.utils.redirect("/quote/%s/%s?message=4" % (order_id, token))
request.registry.get('sale.order').action_cancel(request.cr, SUPERUSER_ID, [order_id])
message = post.get('decline_message')
if message:
@@ -62,6 +62,7 @@ if(!$('.o_website_quote').length) {
submitForm: function(ev){
// extract data
var self = this;
var $confirm_btn = self.$el.find('button[type="submit"]');
var href = self.$el.find('form').attr("action");
var action = href.match(/quote\/([a-z]+)/);
var order_id = href.match(/order_id=(.*)&/);
@@ -84,6 +85,8 @@ if(!$('.o_website_quote').length) {
})
return false;
}
$confirm_btn.prepend('<i class="fa fa-spinner fa-spin"></i> ');
$confirm_btn.attr('disabled', true);
ajax.jsonRpc("/quote/"+action[1], 'call', {
'order_id': parseInt(order_id[1]),
'token': token,
@@ -225,6 +225,14 @@
Your transaction is waiting confirmation.
<span t-if='tx_post_msg' t-raw="tx_post_msg"/>
</div>
<div class="alert alert-warning alert-dismissable" t-if="message==4 and quotation.state != 'sent'">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
This order has already been
<t t-if="quotation.state=='cancel'">cancelled</t>
<t t-if="quotation.state not in ('cancel','draft')">validated</t>
! You can <a href="#discussion">contact us</a> for
any question.
</div>
<!-- modal relative to the actions Accept/Reject/Cancel -->
<div class="modal fade" id="modalaccept" role="dialog" aria-hidden="true">
+1 -1
View File
@@ -1973,7 +1973,7 @@ Read-Write Field
Read-only fields, which only display content and don't allow the
user to modify it can be useful, but most fields in Odoo also allow editing.
This makes the field classes more complicated, mostly because fields are
supposed to handle both and editable and non-editable mode, those modes are
supposed to handle both editable and non-editable mode, those modes are
often completely different (for design and usability purpose) and the fields
must be able to switch between modes at any moment.
+1 -1
View File
@@ -552,7 +552,7 @@ class view(osv.osv):
separator = child.get('separator', ',')
if separator == ' ':
separator = None # squash spaces
to_add = map(str.strip, child.get('add', '').split(separator))
to_add = filter(bool, map(str.strip, child.get('add', '').split(separator)))
to_remove = map(str.strip, child.get('remove', '').split(separator))
values = map(str.strip, node.get(attribute, '').split(separator))
value = (separator or ' ').join(filter(lambda s: s not in to_remove, values) + to_add)
+2 -2
View File
@@ -748,7 +748,7 @@ class test_views(ViewCase):
<attribute name="thing">bob tata lolo</attribute>
<attribute name="thing" add="bibi and co" remove="tata" separator=" " />
<attribute name="otherthing">bob, tata,lolo</attribute>
<attribute name="otherthing" add="bibi" remove="tata, bob"/>
<attribute name="otherthing" remove="tata, bob"/>
</footer>
"""
})
@@ -768,7 +768,7 @@ class test_views(ViewCase):
E.p("Replacement data"),
E.footer(
E.button(name="action_next", type="object", string="New button"),
thing="bob lolo bibi and co", otherthing="lolo,bibi"
thing="bob lolo bibi and co", otherthing="lolo"
),
string="Replacement title", version="7.0"))
+1 -1
View File
@@ -2225,7 +2225,7 @@ class BaseModel(object):
# if val is a many2one, just write the ID
if type(val) == tuple:
val = val[0]
if val is not False:
if f._type == 'boolean' or val is not False:
cr.execute(update_query, (ss[1](val), key))
@api.model
+6 -1
View File
@@ -54,7 +54,12 @@ def check(f):
if args and isinstance(args[-1], dict):
ctx = args[-1]
elif isinstance(kwargs, dict):
ctx = kwargs.get('context', {})
if 'context' in kwargs:
ctx = kwargs['context']
elif 'kwargs' in kwargs:
# http entry points such as call_kw()
ctx = kwargs['kwargs'].get('context')
uid = 1
if args and isinstance(args[0], (long, int)):