[MERGE] Forward-port 9.0 up to 93e8bf8ccf
This commit is contained in:
@@ -641,7 +641,7 @@ class AccountTax(models.Model):
|
||||
if tax.amount_type == 'group':
|
||||
ret = tax.children_tax_ids.compute_all(price_unit, currency, quantity, product, partner)
|
||||
total_excluded = ret['total_excluded']
|
||||
base = ret['total_excluded']
|
||||
base = ret['base']
|
||||
total_included = ret['total_included']
|
||||
tax_amount = total_included - total_excluded
|
||||
taxes += ret['taxes']
|
||||
@@ -677,6 +677,7 @@ class AccountTax(models.Model):
|
||||
'taxes': sorted(taxes, key=lambda k: k['sequence']),
|
||||
'total_excluded': currency.round(total_excluded),
|
||||
'total_included': currency.round(total_included),
|
||||
'base': base,
|
||||
}
|
||||
|
||||
@api.v7
|
||||
|
||||
@@ -5,8 +5,8 @@ from lxml import etree
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from openerp import api, fields, models, _, SUPERUSER_ID
|
||||
from openerp.tools import float_is_zero
|
||||
from openerp import api, fields, models, _
|
||||
from openerp.tools import float_is_zero, float_compare
|
||||
from openerp.tools.misc import formatLang
|
||||
|
||||
from openerp.exceptions import UserError, RedirectWarning, ValidationError
|
||||
@@ -1093,13 +1093,16 @@ class AccountInvoiceLine(models.Model):
|
||||
taxes = self.product_id.taxes_id or self.account_id.tax_ids
|
||||
else:
|
||||
taxes = self.product_id.supplier_taxes_id or self.account_id.tax_ids
|
||||
if self.env.uid == SUPERUSER_ID:
|
||||
taxes = taxes.filtered(lambda r: r.company_id == self.company_id)
|
||||
|
||||
# Keep only taxes of the company
|
||||
company_id = self.company_id or self.env.user.company_id
|
||||
taxes = taxes.filtered(lambda r: r.company_id == company_id)
|
||||
|
||||
self.invoice_line_tax_ids = fp_taxes = self.invoice_id.fiscal_position_id.map_tax(taxes)
|
||||
|
||||
fix_price = self.env['account.tax']._fix_tax_included_price
|
||||
if type in ('in_invoice', 'in_refund'):
|
||||
if not self.price_unit or self.price_unit == self.product_id.standard_price:
|
||||
if self.invoice_id.type in ('in_invoice', 'in_refund'):
|
||||
if not self.price_unit or float_compare(self.price_unit, self.product_id.standard_price, precision_digits=self.currency_id.rounding) == 0:
|
||||
self.price_unit = fix_price(self.product_id.standard_price, taxes, fp_taxes)
|
||||
else:
|
||||
self.price_unit = fix_price(self.product_id.lst_price, taxes, fp_taxes)
|
||||
|
||||
@@ -38,10 +38,10 @@ class TestProductIdChange(AccountingTestCase):
|
||||
amount='0.00'))
|
||||
product_tmpl = self.product_tmpl_model.create(dict(name="Voiture",
|
||||
list_price='121',
|
||||
standard_price='121',
|
||||
taxes_id=[(6, 0, [tax_include_sale.id])],
|
||||
supplier_taxes_id=[(6, 0, [tax_include_purchase.id])]))
|
||||
product = self.product_model.create(dict(product_tmpl_id=product_tmpl.id))
|
||||
product = self.product_model.create(dict(product_tmpl_id=product_tmpl.id,
|
||||
standard_price='242'))
|
||||
fp = self.fiscal_position_model.create(dict(name="fiscal position", sequence=1))
|
||||
fp_tax_sale = self.fiscal_position_tax_model.create(dict(position_id=fp.id,
|
||||
tax_src_id=tax_include_sale.id,
|
||||
@@ -80,7 +80,7 @@ class TestProductIdChange(AccountingTestCase):
|
||||
in_line = self.invoice_line_model.create({
|
||||
'product_id': product.id,
|
||||
'quantity': 1,
|
||||
'price_unit': 121.0,
|
||||
'price_unit': 242.0,
|
||||
'invoice_id': in_invoice.id,
|
||||
'name': 'something in',
|
||||
'account_id': self.account_revenue.id,
|
||||
@@ -88,4 +88,4 @@ class TestProductIdChange(AccountingTestCase):
|
||||
out_line._onchange_product_id()
|
||||
self.assertEquals(100, out_line.price_unit, "The included tax must be subtracted to the price")
|
||||
in_line._onchange_product_id()
|
||||
self.assertEquals(100, in_line.price_unit, "The included tax must be subtracted to the price")
|
||||
self.assertEquals(200, in_line.price_unit, "The included tax must be subtracted to the price")
|
||||
|
||||
@@ -694,6 +694,9 @@ var chat_manager = {
|
||||
}
|
||||
},
|
||||
|
||||
get_message: function (id) {
|
||||
return _.findWhere(messages, {id: id});
|
||||
},
|
||||
get_messages: function (options) {
|
||||
var channel;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ return Widget.extend({
|
||||
this.folded = is_folded;
|
||||
this.options = _.defaults(options || {}, {
|
||||
display_stars: true,
|
||||
display_reply_icon: false,
|
||||
placeholder: _t("Say something"),
|
||||
input_less: false,
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
chat_manager.undo_mark_as_read(msgs_ids, channel);
|
||||
});
|
||||
},
|
||||
"click .o_mail_annoying_notification_bar .fa-close": function (event) {
|
||||
"click .o_mail_annoying_notification_bar .fa-close": function () {
|
||||
this.$(".o_mail_annoying_notification_bar").slideUp();
|
||||
},
|
||||
"click .o_mail_request_permission": function (event) {
|
||||
@@ -124,6 +124,11 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
this.$(".o_mail_annoying_notification_bar").slideUp();
|
||||
window.Notification.requestPermission();
|
||||
},
|
||||
"keydown": function (event) {
|
||||
if (event.which === $.ui.keyCode.ESCAPE && this.selected_message) {
|
||||
this.unselect_message();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
on_attach_callback: function () {
|
||||
@@ -144,6 +149,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
this.channels_scrolltop = {};
|
||||
this.throttled_render_sidebar = _.throttle(this.render_sidebar.bind(this), 100, { leading: false });
|
||||
this.notification_bar = (window.Notification && window.Notification.permission === "default");
|
||||
this.selected_message = null;
|
||||
},
|
||||
|
||||
willStart: function () {
|
||||
@@ -206,6 +212,9 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
this.thread.on('toggle_star_status', this, function (message_id) {
|
||||
chat_manager.toggle_star_status(message_id);
|
||||
});
|
||||
this.thread.on('select_message', this, this.select_message);
|
||||
this.thread.on('unselect_message', this, this.unselect_message);
|
||||
|
||||
this.basic_composer.on('post_message', this, this.on_post_message);
|
||||
this.basic_composer.on('input_focused', this, this.on_composer_input_focused);
|
||||
this.extended_composer.on('post_message', this, this.on_post_message);
|
||||
@@ -241,6 +250,31 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
});
|
||||
},
|
||||
|
||||
select_message: function(message_id) {
|
||||
this.$el.addClass('o_mail_selection_mode');
|
||||
var message = chat_manager.get_message(message_id);
|
||||
this.selected_message = message;
|
||||
var subject = "Re: " + message.record_name;
|
||||
this.extended_composer.set_subject(subject);
|
||||
if (this.channel.type !== 'static') {
|
||||
this.basic_composer.toggle(false);
|
||||
}
|
||||
this.extended_composer.toggle(true);
|
||||
this.thread.scroll_to({id: message_id, duration: 200, only_if_necessary: true});
|
||||
this.extended_composer.focus('body');
|
||||
},
|
||||
|
||||
unselect_message: function() {
|
||||
if (this.channel.type !== 'static' && !this.channel.mass_mailing) {
|
||||
this.basic_composer.toggle(true);
|
||||
this.basic_composer.focus();
|
||||
}
|
||||
this.$el.removeClass('o_mail_selection_mode');
|
||||
this.extended_composer.toggle(this.channel.mass_mailing);
|
||||
this.thread.unselect();
|
||||
this.selected_message = null;
|
||||
},
|
||||
|
||||
render_sidebar: function () {
|
||||
var self = this;
|
||||
var $sidebar = $(QWeb.render("mail.chat.Sidebar", {
|
||||
@@ -299,14 +333,16 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
});
|
||||
},
|
||||
|
||||
render_snackbar: function (nb_needactions) {
|
||||
this.$snackbar = $(QWeb.render('mail.chat.UndoSnackbar', {
|
||||
nb_needactions: nb_needactions,
|
||||
}));
|
||||
render_snackbar: function (template, context, timeout) {
|
||||
if (this.$snackbar) {
|
||||
this.$snackbar.remove();
|
||||
}
|
||||
timeout = timeout || 20000;
|
||||
this.$snackbar = $(QWeb.render(template, context));
|
||||
this.$('.o_mail_chat_content').append(this.$snackbar);
|
||||
// Hide snackbar after 20s
|
||||
// Hide snackbar after [timeout] milliseconds (by default, 20s)
|
||||
var $snackbar = this.$snackbar;
|
||||
setTimeout(function() { $snackbar.fadeOut(); }, 20000);
|
||||
setTimeout(function() { $snackbar.fadeOut(); }, timeout);
|
||||
},
|
||||
|
||||
do_search_channel: function(search_val){
|
||||
@@ -349,7 +385,9 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
if (channel.type !== 'static') {
|
||||
// Display snackbar if needactions have been cleared
|
||||
if (channel.needaction_counter > 0) {
|
||||
self.render_snackbar(channel.needaction_counter);
|
||||
self.render_snackbar('mail.chat.MessageSentSnackbar', {
|
||||
nb_needactions: channel.needaction_counter,
|
||||
});
|
||||
}
|
||||
chat_manager.mark_channel_as_seen(channel);
|
||||
self.clear_needactions_def = chat_manager.mark_all_as_read(channel);
|
||||
@@ -374,6 +412,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
|
||||
self.basic_composer.toggle(channel.type !== 'static' && !channel.mass_mailing);
|
||||
self.extended_composer.toggle(channel.type !== 'static' && channel.mass_mailing);
|
||||
self.$el.removeClass('o_mail_selection_mode');
|
||||
|
||||
self.$('.o_mail_chat_channel_item')
|
||||
.removeClass('o_active')
|
||||
@@ -439,6 +478,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
display_empty_channel: !messages.length && !this.domain.length,
|
||||
display_no_match: !messages.length && this.domain.length,
|
||||
display_subject: this.channel.mass_mailing || this.channel.id === "channel_inbox",
|
||||
display_reply_icon: true,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -512,11 +552,25 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
|
||||
on_post_message: function (message) {
|
||||
var self = this;
|
||||
var options = {channel_id: this.channel.id};
|
||||
var options = this.selected_message ? {} : {channel_id: this.channel.id};
|
||||
if (this.selected_message) {
|
||||
message.subtype = 'mail.mt_comment';
|
||||
message.subtype_id = false;
|
||||
message.message_type = 'comment';
|
||||
message.content_subtype = 'html';
|
||||
|
||||
options.model = this.selected_message.model;
|
||||
options.res_id = this.selected_message.res_id;
|
||||
}
|
||||
chat_manager
|
||||
.post_message(message, options)
|
||||
.then(function() {
|
||||
self.thread.scroll_to();
|
||||
if (self.selected_message) {
|
||||
self.render_snackbar('mail.chat.MessageSentSnackbar', {record_name: self.selected_message.record_name}, 5000);
|
||||
self.unselect_message();
|
||||
} else {
|
||||
self.thread.scroll_to();
|
||||
}
|
||||
})
|
||||
.fail(function () {
|
||||
// todo: display notification
|
||||
|
||||
@@ -698,9 +698,15 @@ var ExtendedComposer = BasicComposer.extend({
|
||||
should_send: function () {
|
||||
return false;
|
||||
},
|
||||
|
||||
focus: function () {
|
||||
this.$subject_input.focus();
|
||||
focus: function (target) {
|
||||
if (target === 'body') {
|
||||
this.$input.focus();
|
||||
} else {
|
||||
this.$subject_input.focus();
|
||||
}
|
||||
},
|
||||
set_subject: function(subject) {
|
||||
this.$('.o_composer_subject input').val(subject);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -21,27 +21,36 @@ var Thread = Widget.extend({
|
||||
"click strong": "on_click_redirect",
|
||||
"click .o_thread_show_more": "on_click_show_more",
|
||||
"click .o_thread_message_needaction": function (event) {
|
||||
event.stopPropagation();
|
||||
var message_id = $(event.currentTarget).data('message-id');
|
||||
this.trigger("mark_as_read", message_id);
|
||||
},
|
||||
"click .o_thread_message_star": function (event) {
|
||||
event.stopPropagation();
|
||||
var message_id = $(event.currentTarget).data('message-id');
|
||||
this.trigger("toggle_star_status", message_id);
|
||||
},
|
||||
"click .o_thread_message": function (event) {
|
||||
var selected = $(event.currentTarget).hasClass('o_thread_selected_message');
|
||||
"click .o_thread_message_reply": function (event) {
|
||||
this.selected_id = $(event.currentTarget).data('message-id');
|
||||
this.$('.o_thread_message').removeClass('o_thread_selected_message');
|
||||
$(event.currentTarget).toggleClass('o_thread_selected_message', !selected);
|
||||
this.$('.o_thread_message[data-message-id=' + this.selected_id + ']')
|
||||
.addClass('o_thread_selected_message');
|
||||
this.trigger('select_message', this.selected_id);
|
||||
event.stopPropagation();
|
||||
},
|
||||
"click .oe_mail_expand": function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var $message = $(event.currentTarget).parents('.o_thread_message');
|
||||
$message.addClass('o_message_expanded');
|
||||
this.expanded_msg_ids.push($message.data('message-id'));
|
||||
},
|
||||
"click .o_thread_message": function (event) {
|
||||
$(event.currentTarget).toggleClass('o_thread_selected_message');
|
||||
},
|
||||
"click": function () {
|
||||
if (this.selected_id) {
|
||||
this.unselect();
|
||||
this.trigger('unselect_message');
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
init: function (parent, options) {
|
||||
@@ -54,8 +63,10 @@ var Thread = Widget.extend({
|
||||
display_avatar: true,
|
||||
shorten_messages: true,
|
||||
squash_close_messages: true,
|
||||
display_reply_icon: false,
|
||||
});
|
||||
this.expanded_msg_ids = [];
|
||||
this.selected_id = null;
|
||||
},
|
||||
|
||||
render: function (messages, options) {
|
||||
@@ -69,11 +80,14 @@ var Thread = Widget.extend({
|
||||
|
||||
// Hide avatar and info of a message if that message and the previous
|
||||
// one are both comments wrote by the same author at the same minute
|
||||
// and in the same document (users can now post message in documents
|
||||
// directly from a channel that follows it)
|
||||
var prev_msg;
|
||||
_.each(msgs, function (msg) {
|
||||
if (!prev_msg || (Math.abs(msg.date.diff(prev_msg.date)) > 60000) ||
|
||||
prev_msg.message_type !== 'comment' || msg.message_type !== 'comment' ||
|
||||
(prev_msg.author_id[0] !== msg.author_id[0])) {
|
||||
(prev_msg.author_id[0] !== msg.author_id[0]) || prev_msg.model !== msg.model ||
|
||||
prev_msg.res_id !== msg.res_id) {
|
||||
msg.display_author = true;
|
||||
} else {
|
||||
msg.display_author = !options.squash_close_messages;
|
||||
@@ -138,6 +152,7 @@ var Thread = Widget.extend({
|
||||
}
|
||||
|
||||
msg.display_subject = message.subject && !message.is_system_notification;
|
||||
msg.is_selected = msg.id === this.selected_id;
|
||||
return msg;
|
||||
},
|
||||
|
||||
@@ -159,18 +174,23 @@ var Thread = Widget.extend({
|
||||
|
||||
/**
|
||||
* Scrolls the thread to a given message or offset if any, to bottom otherwise
|
||||
* @param {int} [target.id] optional: the id of the message to scroll to
|
||||
* @param {int} [target.offset] optional: the number of pixels to scroll
|
||||
* @param {int} [options.id] optional: the id of the message to scroll to
|
||||
* @param {int} [options.offset] optional: the number of pixels to scroll
|
||||
*/
|
||||
scroll_to: function (target) {
|
||||
target = target || {};
|
||||
if (target.id !== undefined) {
|
||||
var $target = this.$('.o_thread_message[data-message-id=' + target.id + ']');
|
||||
if ($target.length) {
|
||||
scroll_to: function (options) {
|
||||
options = options || {};
|
||||
if (options.id !== undefined) {
|
||||
var $target = this.$('.o_thread_message[data-message-id=' + options.id + ']');
|
||||
if (options.only_if_necessary) {
|
||||
var delta = $target.parent().height() - $target.height();
|
||||
var offset = delta < 0 ? 0 : delta - ($target.offset().top - $target.offsetParent().offset().top);
|
||||
offset = - Math.min(offset, 0);
|
||||
this.$el.scrollTo("+=" + offset + "px", options);
|
||||
} else if ($target.length) {
|
||||
this.$el.scrollTo($target);
|
||||
}
|
||||
} else if (target.offset !== undefined) {
|
||||
this.$el.scrollTop(target.offset);
|
||||
} else if (options.offset !== undefined) {
|
||||
this.$el.scrollTop(options.offset);
|
||||
} else {
|
||||
this.$el.scrollTop(this.el.scrollHeight);
|
||||
}
|
||||
@@ -181,6 +201,10 @@ var Thread = Widget.extend({
|
||||
is_at_bottom: function () {
|
||||
return this.el.scrollHeight - this.$el.scrollTop() - this.$el.outerHeight() < 5;
|
||||
},
|
||||
unselect: function () {
|
||||
this.$('.o_thread_message').removeClass('o_thread_selected_message');
|
||||
this.selected_id = null;
|
||||
},
|
||||
});
|
||||
|
||||
Thread.ORDER = ORDER;
|
||||
|
||||
@@ -112,6 +112,9 @@
|
||||
height: 100%;
|
||||
margin-left: @mail-chat-sidebar-width;
|
||||
position: relative;
|
||||
@media (min-width: @screen-sm-min) {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@media (max-width: @screen-xs-max) {
|
||||
margin-left: 0;
|
||||
@@ -120,8 +123,7 @@
|
||||
.o_mail_thread {
|
||||
.o-flex(1, 0, 0);
|
||||
overflow: auto;
|
||||
.o-webclient-padding();
|
||||
padding-bottom: 15px;
|
||||
padding: 0 0 15px 0;
|
||||
|
||||
.o_chat_help_message {
|
||||
padding: 25px 0;
|
||||
@@ -253,6 +255,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.o_mail_selection_mode {
|
||||
.o_thread_message {
|
||||
opacity: 0.5;
|
||||
&.o_thread_selected_message {
|
||||
padding: 4px @odoo-horizontal-padding;
|
||||
opacity: 1;
|
||||
background-color: lightgray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User status bullet (in Discuss sidebar and Invite dialog)
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
.o_thread_message {
|
||||
.o-flex-display();
|
||||
padding: 4px 0;
|
||||
padding: 4px @odoo-horizontal-padding;
|
||||
margin-bottom: 0px;
|
||||
|
||||
.o_thread_message_sidebar {
|
||||
.o-flex(0, 0, @mail-thread-avatar-size);
|
||||
@@ -69,7 +70,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
i.o_thread_message_star, i.o_thread_message_needaction {
|
||||
i.o_thread_message_star, i.o_thread_message_needaction, i.o_thread_message_reply {
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
&.fa-star {
|
||||
@@ -83,7 +84,7 @@
|
||||
opacity: @mail-thread-side-date-opacity;
|
||||
}
|
||||
|
||||
i.o_thread_message_star, i.o_thread_message_needaction {
|
||||
i.o_thread_message_star, i.o_thread_message_needaction, i.o_thread_message_reply {
|
||||
opacity: @mail-thread-icon-opacity;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
@@ -141,7 +142,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.o_thread_message_star, .o_thread_message_needaction {
|
||||
.o_thread_message_star, .o_thread_message_needaction, .o_thread_message_reply {
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,13 @@
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="mail.chat.MessageSentSnackbar">
|
||||
<div class="alert o_mail_snackbar" data-dismiss="alert" role="alert">
|
||||
Message sent in "<t t-esc="record_name"/>".
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
<!-- Buttons of the Control Panel -->
|
||||
<t t-name="mail.chat.ControlButtons">
|
||||
<div>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</t>
|
||||
|
||||
<t t-name="mail.ChatThread.Message">
|
||||
<div t-att-class="'o_thread_message' + (message.expanded ? ' o_message_expanded' : '')" t-att-data-message-id="message.id">
|
||||
<div t-att-class="'o_thread_message' + (message.expanded ? ' o_message_expanded ' : ' ') + (message.is_selected ? 'o_thread_selected_message' : '')" t-att-data-message-id="message.id">
|
||||
<div t-if="options.display_avatar" class="o_thread_message_sidebar">
|
||||
<t t-if="!message.mailto && message.author_id[0]">
|
||||
<img t-if="message.avatar_src && message.display_author"
|
||||
@@ -103,6 +103,9 @@
|
||||
<i t-if="message.is_needaction && options.display_needactions"
|
||||
class="fa fa-check o_thread_message_needaction"
|
||||
t-att-data-message-id="message.id" title="Mark as Read"/>
|
||||
<i t-if="message.record_name && message.model != 'mail.channel' && options.display_reply_icon"
|
||||
class="fa fa-reply o_thread_message_reply"
|
||||
t-att-data-message-id="message.id" title="Reply"/>
|
||||
</span>
|
||||
</p>
|
||||
<t t-if="message.tracking_value_ids && message.tracking_value_ids.length > 0">
|
||||
|
||||
@@ -57,7 +57,7 @@ class sale_order_line(osv.osv):
|
||||
if line.product_id.company_id and line.order_id.pricelist_id.currency_id.id != line.product_id.company_id.currency_id.id:
|
||||
# new_list_price is in company's currency while price in pricelist currency
|
||||
ctx = dict(context_partner, date=self.order_id.date_order)
|
||||
new_list_price = self.env['res.currency'].browse(currency_id).with_context(ctx).compute(new_list_price, line.order_id.pricelist_id.currency_id.id)
|
||||
new_list_price = self.env['res.currency'].browse(currency_id).with_context(ctx).compute(new_list_price, line.order_id.pricelist_id.currency_id)
|
||||
discount = (new_list_price - line.price_unit) / new_list_price * 100
|
||||
if discount > 0:
|
||||
line.price_unit = new_list_price
|
||||
@@ -86,7 +86,7 @@ class sale_order_line(osv.osv):
|
||||
if self.product_id.company_id and self.order_id.pricelist_id.currency_id.id != self.product_id.company_id.currency_id.id:
|
||||
# new_list_price is in company's currency while price in pricelist currency
|
||||
ctx = dict(context_partner, date=self.order_id.date_order)
|
||||
new_list_price = self.env['res.currency'].browse(currency_id).with_context(ctx).compute(new_list_price, self.order_id.pricelist_id.currency_id.id)
|
||||
new_list_price = self.env['res.currency'].browse(currency_id).with_context(ctx).compute(new_list_price, self.order_id.pricelist_id.currency_id)
|
||||
discount = (new_list_price - self.price_unit) / new_list_price * 100
|
||||
if discount > 0:
|
||||
self.price_unit = new_list_price
|
||||
|
||||
@@ -3877,7 +3877,7 @@ class stock_warehouse(osv.osv):
|
||||
for pull in route.pull_ids:
|
||||
pull_obj.write(cr, uid, pull.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context)
|
||||
for push in route.push_ids:
|
||||
push_obj.write(cr, uid, push.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context)
|
||||
push_obj.write(cr, uid, push.id, {'name': push.name.replace(warehouse.name, name, 1)}, context=context)
|
||||
#change the mto procurement rule name
|
||||
if warehouse.mto_pull_id.id:
|
||||
pull_obj.write(cr, uid, warehouse.mto_pull_id.id, {'name': warehouse.mto_pull_id.name.replace(warehouse.name, name, 1)}, context=context)
|
||||
|
||||
@@ -1000,7 +1000,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1023,7 +1023,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1047,7 +1047,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1071,7 +1071,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1096,7 +1096,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1120,7 +1120,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1145,7 +1145,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
@@ -1170,7 +1170,7 @@
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar</field>
|
||||
<field name="domain"></field>
|
||||
<field name="context">{
|
||||
'search_default_picking_type_id': [active_id],
|
||||
|
||||
@@ -1054,5 +1054,5 @@ class website_sale(http.Controller):
|
||||
pricelist_id = request.website.get_current_pricelist(context=context).id
|
||||
else:
|
||||
pricelist_id = partner.property_product_pricelist.id
|
||||
prices = pool['product.pricelist'].price_rule_get_multi(cr, uid, [], [(product, add_qty, partner) for product in products], context=context)
|
||||
prices = pool['product.pricelist'].price_rule_get_multi(cr, uid, [pricelist_id], [(product, add_qty, partner) for product in products], context=context)
|
||||
return {product_id: prices[product_id][pricelist_id][0] for product_id in product_ids}
|
||||
|
||||
@@ -1111,11 +1111,15 @@ consteq = getattr(passlib.utils, 'consteq', _consteq)
|
||||
|
||||
class Pickle(object):
|
||||
@classmethod
|
||||
def load(cls, stream):
|
||||
def load(cls, stream, errors=False):
|
||||
unpickler = cPickle.Unpickler(stream)
|
||||
# pickle builtins: str/unicode, int/long, float, bool, tuple, list, dict, None
|
||||
unpickler.find_global = None
|
||||
return unpickler.load()
|
||||
try:
|
||||
return unpickler.load()
|
||||
except Exception:
|
||||
_logger.warning('Failed unpickling data, returning default: %r', errors, exc_info=True)
|
||||
return errors
|
||||
|
||||
@classmethod
|
||||
def loads(cls, text):
|
||||
|
||||
Reference in New Issue
Block a user