[MERGE] forward port branch saas-11.3 up to d4c65a7ede
This commit is contained in:
@@ -1519,7 +1519,7 @@ class AccountInvoice(models.Model):
|
||||
res = {}
|
||||
for line in invoice.tax_line_ids:
|
||||
res.setdefault(line.tax_id.tax_group_id, {'base': 0.0, 'amount': 0.0})
|
||||
res[line.tax_id.tax_group_id]['amount'] += line.amount
|
||||
res[line.tax_id.tax_group_id]['amount'] += line.amount_total
|
||||
res[line.tax_id.tax_group_id]['base'] += line.base
|
||||
res = sorted(res.items(), key=lambda l: l[0].sequence)
|
||||
invoice.amount_by_group = [(
|
||||
|
||||
@@ -641,7 +641,7 @@ class AccountMoveLine(models.Model):
|
||||
# TODO: put the invoice link and partner_id on the account_move
|
||||
invoice_id = fields.Many2one('account.invoice', oldname="invoice")
|
||||
partner_id = fields.Many2one('res.partner', string='Partner', ondelete='restrict')
|
||||
user_type_id = fields.Many2one('account.account.type', related='account_id.user_type_id', index=True, store=True, oldname="user_type", readonly=False)
|
||||
user_type_id = fields.Many2one('account.account.type', related='account_id.user_type_id', index=True, store=True, oldname="user_type", readonly=True)
|
||||
tax_exigible = fields.Boolean(string='Appears in VAT report', default=True,
|
||||
help="Technical field used to mark a tax line as exigible in the vat report or not (only exigible journal items are displayed). By default all new journal items are directly exigible, but with the feature cash_basis on taxes, some will become exigible only when the payment is recorded.")
|
||||
parent_state = fields.Char(compute="_compute_parent_state", help="State of the parent account.move")
|
||||
|
||||
@@ -330,6 +330,12 @@ class AccountReconciliation(models.AbstractModel):
|
||||
allowed_ids = set(Partner.browse(ids).ids)
|
||||
rows = [row for row in rows if row['partner_id'] in allowed_ids]
|
||||
|
||||
# Keep mode for future use in JS
|
||||
if res_type == 'account':
|
||||
mode = 'accounts'
|
||||
else:
|
||||
mode = 'customers' if account_type == 'receivable' else 'suppliers'
|
||||
|
||||
# Fetch other data
|
||||
for row in rows:
|
||||
account = Account.browse(row['account_id'])
|
||||
@@ -338,6 +344,7 @@ class AccountReconciliation(models.AbstractModel):
|
||||
partner_id = is_partner and row['partner_id'] or None
|
||||
rec_prop = aml_ids and self.env['account.move.line'].browse(aml_ids) or self._get_move_line_reconciliation_proposition(account.id, partner_id)
|
||||
row['reconciliation_proposition'] = self._prepare_move_lines(rec_prop, target_currency=currency)
|
||||
row['mode'] = mode
|
||||
row['company_id'] = account.company_id.id
|
||||
|
||||
# Return the partners with a reconciliation proposition first, since they are most likely to
|
||||
|
||||
@@ -126,7 +126,7 @@ class ReportAgedPartnerBalance(models.AbstractModel):
|
||||
partners_amount = {}
|
||||
aml_ids = cr.fetchall()
|
||||
aml_ids = aml_ids and [x[0] for x in aml_ids] or []
|
||||
for line in self.env['account.move.line'].browse(aml_ids):
|
||||
for line in self.env['account.move.line'].browse(aml_ids).with_context(prefetch_fields=False):
|
||||
partner_id = line.partner_id.id or False
|
||||
if partner_id not in partners_amount:
|
||||
partners_amount[partner_id] = 0.0
|
||||
|
||||
@@ -42,6 +42,8 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
LineRenderer: ReconciliationRenderer.LineRenderer,
|
||||
// used context params
|
||||
params: ['statement_ids'],
|
||||
// number of statements/partners/accounts to display
|
||||
defaultDisplayQty: 10,
|
||||
// number of moves lines displayed in 'match' mode
|
||||
limitMoveLines: 15,
|
||||
},
|
||||
@@ -58,6 +60,7 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
this.params = params;
|
||||
this.model = new this.config.Model(this, {
|
||||
modelName: "account.reconciliation.widget",
|
||||
defaultDisplayQty: params.params && params.params.defaultDisplayQty || this.config.defaultDisplayQty,
|
||||
limitMoveLines: params.params && params.params.limitMoveLines || this.config.limitMoveLines,
|
||||
});
|
||||
this.widgets = [];
|
||||
@@ -329,6 +332,7 @@ var ManualAction = StatementAction.extend({
|
||||
ActionRenderer: ReconciliationRenderer.ManualRenderer,
|
||||
LineRenderer: ReconciliationRenderer.ManualLineRenderer,
|
||||
params: ['company_ids', 'mode', 'partner_ids', 'account_ids'],
|
||||
defaultDisplayQty: 30,
|
||||
limitMoveLines: 15,
|
||||
},
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ var StatementModel = BasicModel.extend({
|
||||
this.valuenow = 0;
|
||||
this.valuemax = 0;
|
||||
this.alreadyDisplayed = [];
|
||||
this.defaultDisplayQty = 10;
|
||||
this.defaultDisplayQty = options && options.defaultDisplayQty || 10;
|
||||
this.limitMoveLines = options && options.limitMoveLines || 15;
|
||||
},
|
||||
|
||||
@@ -1239,6 +1239,17 @@ var ManualModel = StatementModel.extend({
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return a boolean telling if load button needs to be displayed or not
|
||||
*
|
||||
* @returns {boolean} true if load more button needs to be displayed
|
||||
*/
|
||||
hasMoreLines: function () {
|
||||
if (this.manualLines.length > this.pagerIndex) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* load data from
|
||||
* - 'account.reconciliation.widget' fetch the lines to reconciliate
|
||||
@@ -1300,10 +1311,12 @@ var ManualModel = StatementModel.extend({
|
||||
context: context,
|
||||
})
|
||||
.then(function (result) {
|
||||
var defs = _.map(result, self._formatLine.bind(self, context.mode));
|
||||
self.manualLines = result;
|
||||
self.valuenow = 0;
|
||||
self.valuemax = Object.keys(self.lines).length;
|
||||
return $.when.apply($, defs);
|
||||
self.valuemax = Object.keys(self.manualLines).length;
|
||||
var lines = self.manualLines.splice(0, self.defaultDisplayQty);
|
||||
self.pagerIndex = lines.length;
|
||||
return self.loadData(lines);
|
||||
});
|
||||
case 'accounts':
|
||||
return self._rpc({
|
||||
@@ -1313,10 +1326,12 @@ var ManualModel = StatementModel.extend({
|
||||
context: context,
|
||||
})
|
||||
.then(function (result) {
|
||||
var defs = _.map(result, self._formatLine.bind(self, 'accounts'));
|
||||
self.manualLines = result;
|
||||
self.valuenow = 0;
|
||||
self.valuemax = Object.keys(self.lines).length;
|
||||
return $.when.apply($, defs);
|
||||
self.valuemax = Object.keys(self.manualLines).length;
|
||||
var lines = self.manualLines.splice(0, self.defaultDisplayQty);
|
||||
self.pagerIndex = lines.length;
|
||||
return self.loadData(lines);
|
||||
});
|
||||
default:
|
||||
var partner_ids = context.partner_ids;
|
||||
@@ -1332,16 +1347,46 @@ var ManualModel = StatementModel.extend({
|
||||
context: context,
|
||||
})
|
||||
.then(function (result) {
|
||||
var defs = _.map(result.accounts, self._formatLine.bind(self, 'accounts'));
|
||||
defs = defs.concat(_.map(result.customers, self._formatLine.bind(self, 'customers')));
|
||||
defs = defs.concat(_.map(result.suppliers, self._formatLine.bind(self, 'suppliers')));
|
||||
// Flatten the result
|
||||
self.manualLines = [].concat(result.accounts, result.customers, result.suppliers)
|
||||
self.valuenow = 0;
|
||||
self.valuemax = Object.keys(self.lines).length;
|
||||
return $.when.apply($, defs);
|
||||
self.valuemax = Object.keys(self.manualLines).length;
|
||||
var lines = self.manualLines.splice(0, self.defaultDisplayQty);
|
||||
self.pagerIndex = lines.length;
|
||||
return self.loadData(lines);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Load more partners/accounts
|
||||
*
|
||||
* @param {integer} qty quantity to load
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
loadMore: function(qty) {
|
||||
if (qty === undefined) {
|
||||
qty = this.defaultDisplayQty;
|
||||
}
|
||||
var lines = this.manualLines.splice(this.pagerIndex, qty);
|
||||
this.pagerIndex += qty;
|
||||
return this.loadData(lines);
|
||||
},
|
||||
/**
|
||||
* Method to load informations on lines
|
||||
*
|
||||
* @param {Array} lines manualLines to load
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
loadData: function(lines) {
|
||||
var self = this;
|
||||
var defs = [];
|
||||
_.each(lines, function (l) {
|
||||
defs.push(self._formatLine(l.mode, l))
|
||||
});
|
||||
return $.when.apply($, defs);
|
||||
|
||||
},
|
||||
/**
|
||||
* Mark the account or the partner as reconciled
|
||||
*
|
||||
|
||||
@@ -476,12 +476,12 @@ var auto_reconciliation = {
|
||||
var data_for_manual_reconciliation_widget = {
|
||||
'[null,null]': {
|
||||
'customers': [
|
||||
{'account_id': 287, 'partner_name': "Agrolait", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-14 12:30:31", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 8, 'account_name': "101200 Account Receivable"},
|
||||
{'account_id': 7, 'partner_name': "Camptocamp", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-13 14:24:55", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 12, 'account_name': "101200 Account Receivable"}
|
||||
{'account_id': 287, 'partner_name': "Agrolait", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-14 12:30:31", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 8, 'account_name': "101200 Account Receivable", 'mode': "customers"},
|
||||
{'account_id': 7, 'partner_name': "Camptocamp", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-13 14:24:55", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 12, 'account_name': "101200 Account Receivable", 'mode': "customers"}
|
||||
],
|
||||
'accounts': [
|
||||
{
|
||||
'account_id': 283, 'account_name': "101000 Current Assets", 'currency_id': 3, 'max_date': "2017-02-16 14:32:04", 'last_time_entries_checked': "2017-02-16", 'account_code': "101000",
|
||||
'account_id': 283, 'account_name': "101000 Current Assets", 'currency_id': 3, 'max_date': "2017-02-16 14:32:04", 'last_time_entries_checked': "2017-02-16", 'account_code': "101000", 'mode': "accounts",
|
||||
'reconciliation_proposition': [
|
||||
{'account_id': 283, 'account_type': "other", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-02-16", 'date': "2017-02-16", 'total_amount_str': "$ 1,000.00", 'partner_id': 8, 'account_name': "101000 Current Assets", 'name': "BNK1/2017/0006: Customer Payment", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 399, 'credit': 1000.0, 'journal_id': [3, "Bank"], 'amount_str': "$ 1,000.00", 'debit': 0.0, 'account_code': "101000", 'ref': "", 'already_paid': false},
|
||||
{'account_id': 283, 'account_type': "other", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-03-18", 'date': "2017-02-16", 'total_amount_str': "$ 1,000.00", 'partner_id': 8, 'account_name': "101000 Current Assets", 'name': "INV/2017/0006", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 402, 'credit': 0.0, 'journal_id': [1, "Customer Invoices"], 'amount_str': "$ 1,000.00", 'debit': 1000.0, 'account_code': "101000", 'ref': "", 'already_paid': false}
|
||||
@@ -495,20 +495,20 @@ var data_for_manual_reconciliation_widget = {
|
||||
{'account_id': 284, 'account_type': "other", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-02-16", 'date': "2017-02-16", 'total_amount_str': "$ 1,000.00", 'partner_id': 8, 'account_name': "101000 Current Assets", 'name': "BNK1/999: Customer Payment", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 999, 'credit': 1000.0, 'journal_id': [3, "Bank"], 'amount_str': "$ 1,000.00", 'debit': 0.0, 'account_code': "111100", 'ref': "", 'already_paid': false},
|
||||
{'account_id': 284, 'account_type': "other", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-03-18", 'date': "2017-02-16", 'total_amount_str': "$ 1,000.00", 'partner_id': 8, 'account_name': "101000 Current Assets", 'name': "INV/998", 'partner_name': "Agrolait", 'total_amount_currency_str': "", 'id': 998, 'credit': 0.0, 'journal_id': [1, "Customer Invoices"], 'amount_str': "$ 1,000.00", 'debit': 1000.0, 'account_code': "111100", 'ref': "", 'already_paid': false}
|
||||
],
|
||||
'currency_id': 3, 'max_date': "2017-02-14 12:36:05", 'last_time_entries_checked': null, 'account_code': "111100", 'partner_id': 8, 'account_name': "Account Payable"
|
||||
'currency_id': 3, 'max_date': "2017-02-14 12:36:05", 'last_time_entries_checked': null, 'account_code': "111100", 'partner_id': 8, 'account_name': "Account Payable", 'mode': "suppliers"
|
||||
}, {
|
||||
'account_id': 284, 'partner_name': "Camptocamp",
|
||||
'reconciliation_proposition': [
|
||||
{'account_id': 284, 'account_type': "other", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-02-16", 'date': "2017-02-16", 'total_amount_str': "$ 1,000.00", 'partner_id': 12, 'account_name': "101000 Current Assets", 'name': "BNK1/1999: Customer Payment", 'partner_name': "Camptocamp", 'total_amount_currency_str': "", 'id': 1999, 'credit': 1000.0, 'journal_id': [3, "Bank"], 'amount_str': "$ 1,000.00", 'debit': 0.0, 'account_code': "111100", 'ref': "", 'already_paid': false},
|
||||
{'account_id': 284, 'account_type': "other", 'amount_currency_str': "", 'currency_id': false, 'date_maturity': "2017-03-18", 'date': "2017-02-16", 'total_amount_str': "$ 1,000.00", 'partner_id': 12, 'account_name': "101000 Current Assets", 'name': "INV/1998", 'partner_name': "Camptocamp", 'total_amount_currency_str': "", 'id': 1998, 'credit': 0.0, 'journal_id': [1, "Customer Invoices"], 'amount_str': "$ 1,000.00", 'debit': 1000.0, 'account_code': "111100", 'ref': "", 'already_paid': false}
|
||||
],
|
||||
'currency_id': 3, 'max_date': "2017-02-14 12:36:05", 'last_time_entries_checked': null, 'account_code': "111100", 'partner_id': 12, 'account_name': "Account Payable"
|
||||
'currency_id': 3, 'max_date': "2017-02-14 12:36:05", 'last_time_entries_checked': null, 'account_code': "111100", 'partner_id': 12, 'account_name': "Account Payable", 'mode': "suppliers"
|
||||
}
|
||||
]
|
||||
},
|
||||
'["partner",null,"receivable"]': [
|
||||
{'account_id': 287, 'partner_name': "Agrolait", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-14 12:30:31", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 8, 'account_name': "101200 Account Receivable"},
|
||||
{'account_id': 287, 'partner_name': "Camptocamp", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-13 14:24:55", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 12, 'account_name': "101200 Account Receivable"}
|
||||
{'account_id': 287, 'partner_name': "Agrolait", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-14 12:30:31", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 8, 'account_name': "101200 Account Receivable", 'mode': "customers"},
|
||||
{'account_id': 287, 'partner_name': "Camptocamp", 'reconciliation_proposition': [], 'currency_id': 3, 'max_date': "2017-02-13 14:24:55", 'last_time_entries_checked': null, 'account_code': "101200", 'partner_id': 12, 'account_name': "101200 Account Receivable", 'mode': "customers"}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -487,6 +487,7 @@ class MrpProduction(models.Model):
|
||||
old_qty = move[0].product_uom_qty
|
||||
if quantity > 0:
|
||||
move[0].write({'product_uom_qty': quantity})
|
||||
move.unit_factor = quantity / move.raw_material_production_id.product_qty
|
||||
elif quantity < 0: # Do not remove 0 lines
|
||||
if move[0].quantity_done > 0:
|
||||
raise UserError(_('Lines need to be deleted, but can not as you still have some quantities to consume in them. '))
|
||||
|
||||
@@ -1569,11 +1569,21 @@ var ReceiptScreenWidget = ScreenWidget.extend({
|
||||
};
|
||||
},
|
||||
print_web: function() {
|
||||
if($.browser.safari){
|
||||
if ($.browser.safari) {
|
||||
document.execCommand('print', false, null);
|
||||
}
|
||||
else{
|
||||
window.print();
|
||||
} else {
|
||||
try {
|
||||
window.print();
|
||||
} catch(err) {
|
||||
if (navigator.userAgent.toLowerCase().indexOf("android") > -1) {
|
||||
this.gui.show_popup('error',{
|
||||
'title':_t('Printing is not supported on some android browsers'),
|
||||
'body': _t('Printing is not supported on some android browsers due to no default printing protocol is available. It is possible to print your tickets by making use of an IoT Box.'),
|
||||
});
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.pos.get_order()._printed = true;
|
||||
},
|
||||
|
||||
@@ -43,7 +43,10 @@ var History = function History($editable) {
|
||||
$editable.removeAttr('contentEditable').removeProp('contentEditable');
|
||||
}
|
||||
|
||||
$editable.trigger('content_will_be_destroyed');
|
||||
$editable.html(oSnap.contents).scrollTop(oSnap.scrollTop);
|
||||
$editable.trigger('content_was_recreated');
|
||||
|
||||
$('.oe_overlay').remove();
|
||||
$('.note-control-selection').hide();
|
||||
|
||||
@@ -291,6 +294,20 @@ var RTEWidget = Widget.extend({
|
||||
|
||||
var $editable = this.editable();
|
||||
|
||||
// When a undo/redo is performed, the whole DOM is changed so we have
|
||||
// to prepare for it (website will restart animations for example)
|
||||
// TODO should be better handled
|
||||
$editable.on('content_will_be_destroyed', function (ev) {
|
||||
self.trigger_up('content_will_be_destroyed', {
|
||||
$target: $(ev.currentTarget),
|
||||
});
|
||||
});
|
||||
$editable.on('content_was_recreated', function (ev) {
|
||||
self.trigger_up('content_was_recreated', {
|
||||
$target: $(ev.currentTarget),
|
||||
});
|
||||
});
|
||||
|
||||
$editable.addClass('o_editable')
|
||||
.data('rte', this)
|
||||
.each(function () {
|
||||
|
||||
@@ -339,6 +339,7 @@ var SnippetEditor = Widget.extend({
|
||||
}
|
||||
},
|
||||
});
|
||||
this.trigger_up('snippet_cloned', {$target: $clone});
|
||||
},
|
||||
/**
|
||||
* Called when the overlay dimensions/positions should be recomputed.
|
||||
|
||||
@@ -18,6 +18,9 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
|
||||
on_save: '_onSave',
|
||||
}),
|
||||
custom_events: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.custom_events || {}, {
|
||||
content_will_be_destroyed: '_onContentWillBeDestroyed',
|
||||
content_was_recreated: '_onContentWasRecreated',
|
||||
snippet_cloned: '_onSnippetCloned',
|
||||
snippet_dropped: '_onSnippetDropped',
|
||||
}),
|
||||
|
||||
@@ -108,6 +111,44 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Called when content will be destroyed in the page. Notifies the
|
||||
* WebsiteRoot that is should stop the animations.
|
||||
*
|
||||
* @private
|
||||
* @param {OdooEvent} ev
|
||||
*/
|
||||
_onContentWillBeDestroyed: function (ev) {
|
||||
this.trigger_up('animation_stop_demand', {
|
||||
$target: ev.data.$target,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Called when content will be recreated in the page. Notifies the
|
||||
* WebsiteRoot that is should start the animations.
|
||||
*
|
||||
* @private
|
||||
* @param {OdooEvent} ev
|
||||
*/
|
||||
_onContentWasRecreated: function (ev) {
|
||||
this.trigger_up('animation_start_demand', {
|
||||
editableMode: true,
|
||||
$target: ev.data.$target,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Called when a snippet is cloned in the page. Notifies the WebsiteRoot
|
||||
* that is should start the animations for this snippet.
|
||||
*
|
||||
* @private
|
||||
* @param {OdooEvent} ev
|
||||
*/
|
||||
_onSnippetCloned: function (ev) {
|
||||
this.trigger_up('animation_start_demand', {
|
||||
editableMode: true,
|
||||
$target: ev.data.$target,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Called when a snippet is dropped in the page. Notifies the WebsiteRoot
|
||||
* that is should start the animations for this snippet.
|
||||
|
||||
@@ -5,7 +5,7 @@ from odoo.addons import decimal_precision as dp
|
||||
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.translate import html_translate
|
||||
from odoo.tools import float_is_zero
|
||||
from odoo.tools import float_compare
|
||||
|
||||
|
||||
class ProductStyle(models.Model):
|
||||
@@ -206,8 +206,14 @@ class Product(models.Model):
|
||||
for p, p2 in pycompat.izip(self, self2):
|
||||
taxes = partner.property_account_position_id.map_tax(p.sudo().taxes_id.filtered(lambda x: x.company_id == company_id), p, partner)
|
||||
p.website_price = taxes.compute_all(p2.price, pricelist.currency_id, quantity=qty, product=p2, partner=partner)[ret]
|
||||
price_without_pricelist = taxes.compute_all(p.list_price, pricelist.currency_id)[ret]
|
||||
p.website_price_difference = False if float_is_zero(price_without_pricelist - p.website_price, precision_rounding=pricelist.currency_id.rounding) else True
|
||||
# We must convert the price_without_pricelist in the same currency than the
|
||||
# website_price, otherwise the comparison doesn't make sense. Moreover, we show a price
|
||||
# difference only if the website price is lower
|
||||
price_without_pricelist = p.list_price
|
||||
if company_id.currency_id != pricelist.currency_id:
|
||||
price_without_pricelist = company_id.currency_id.compute(price_without_pricelist, pricelist.currency_id)
|
||||
price_without_pricelist = taxes.compute_all(price_without_pricelist, pricelist.currency_id)[ret]
|
||||
p.website_price_difference = True if float_compare(price_without_pricelist, p.website_price, precision_rounding=pricelist.currency_id.rounding) > 0 else False
|
||||
p.website_public_price = taxes.compute_all(p2.lst_price, quantity=qty, product=p2, partner=partner)[ret]
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -62,9 +62,9 @@ class Property(models.Model):
|
||||
|
||||
@api.multi
|
||||
def _update_values(self, values):
|
||||
value = values.pop('value', None)
|
||||
if not value:
|
||||
if 'value' not in values:
|
||||
return values
|
||||
value = values.pop('value')
|
||||
|
||||
prop = None
|
||||
type_ = values.get('type')
|
||||
@@ -80,7 +80,9 @@ class Property(models.Model):
|
||||
raise UserError(_('Invalid type'))
|
||||
|
||||
if field == 'value_reference':
|
||||
if isinstance(value, models.BaseModel):
|
||||
if not value:
|
||||
value = False
|
||||
elif isinstance(value, models.BaseModel):
|
||||
value = '%s,%d' % (value._name, value.id)
|
||||
elif isinstance(value, pycompat.integer_types):
|
||||
field_id = values.get('fields_id')
|
||||
|
||||
@@ -818,6 +818,12 @@ class TestFields(common.TransactionCase):
|
||||
self.assertEqual(record.sudo(user1).tag_id, tag0.browse())
|
||||
self.assertEqual(record.sudo(user2).tag_id, tag0)
|
||||
|
||||
record.sudo(user1).foo = False
|
||||
record.invalidate_cache()
|
||||
self.assertEqual(record.sudo(user0).foo, 'main')
|
||||
self.assertEqual(record.sudo(user1).foo, False)
|
||||
self.assertEqual(record.sudo(user2).foo, 'default')
|
||||
|
||||
# create company record and attribute
|
||||
company_record = self.env['test_new_api.company'].create({'foo': 'ABC'})
|
||||
attribute_record = self.env['test_new_api.company.attr'].create({
|
||||
|
||||
@@ -901,6 +901,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
||||
# avoid broken transaction) and keep going
|
||||
cr.execute('ROLLBACK TO SAVEPOINT model_load_save')
|
||||
except Exception as e:
|
||||
_logger.exception("Error while loading record")
|
||||
info = rec_data['info']
|
||||
message = (_(u'Unknown error during import:') + u' %s: %s' % (type(e), e))
|
||||
moreinfo = _('Resolve other errors first')
|
||||
|
||||
Reference in New Issue
Block a user