summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/account/report/account_general_ledger.py2
-rw-r--r--addons/account/report/account_journal.py2
-rw-r--r--addons/account/report/account_partner_ledger.py2
-rw-r--r--addons/account/report/account_report_financial.py2
-rw-r--r--addons/hr_attendance/models/hr_attendance.py2
-rw-r--r--addons/hr_holidays/report/holidays_summary_report.py2
-rw-r--r--addons/hr_payroll/report/report_contribution_register.py2
-rw-r--r--addons/l10n_be/data/account_tax_template_data.xml2
-rw-r--r--addons/l10n_in_hr_payroll/report/report_hr_salary_employee_bymonth.py2
-rw-r--r--addons/l10n_in_hr_payroll/report/report_hr_yearly_salary_detail.py2
-rw-r--r--addons/point_of_sale/static/src/xml/pos.xml10
-rw-r--r--addons/product/models/product.py2
-rw-r--r--addons/purchase/models/purchase.py20
-rw-r--r--addons/report_intrastat/report/report_intrastat_invoice_template.xml4
-rw-r--r--addons/sale/models/sale.py8
-rw-r--r--addons/sale/tests/test_product_id_change.py48
-rw-r--r--addons/stock/models/product.py4
-rw-r--r--addons/stock/tests/test_stock_flow.py6
-rw-r--r--addons/web/static/src/js/views/search_menus.js8
-rw-r--r--addons/website_links/static/src/js/website_links_charts.js16
-rw-r--r--addons/website_portal_sale/models/payment.py2
-rw-r--r--addons/website_sale_stock/models/website.py10
22 files changed, 126 insertions, 32 deletions
diff --git a/addons/account/report/account_general_ledger.py b/addons/account/report/account_general_ledger.py
index f7ebf8ad451..9fef7e985fb 100644
--- a/addons/account/report/account_general_ledger.py
+++ b/addons/account/report/account_general_ledger.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import time
-from odoo import api, models
+from odoo import api, models, _
from odoo.exceptions import UserError
diff --git a/addons/account/report/account_journal.py b/addons/account/report/account_journal.py
index 9dfa7807f48..15b823e825a 100644
--- a/addons/account/report/account_journal.py
+++ b/addons/account/report/account_journal.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import time
-from odoo import api, models
+from odoo import api, models, _
from odoo.exceptions import UserError
diff --git a/addons/account/report/account_partner_ledger.py b/addons/account/report/account_partner_ledger.py
index 94d12a7bd3a..fa756c4b977 100644
--- a/addons/account/report/account_partner_ledger.py
+++ b/addons/account/report/account_partner_ledger.py
@@ -2,7 +2,7 @@
from datetime import datetime
import time
-from odoo import api, models
+from odoo import api, models, _
from odoo.exceptions import UserError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
diff --git a/addons/account/report/account_report_financial.py b/addons/account/report/account_report_financial.py
index 4aacdf68108..026f043592a 100644
--- a/addons/account/report/account_report_financial.py
+++ b/addons/account/report/account_report_financial.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import time
-from odoo import api, models
+from odoo import api, models, _
from odoo.exceptions import UserError
diff --git a/addons/hr_attendance/models/hr_attendance.py b/addons/hr_attendance/models/hr_attendance.py
index e3211fceb00..b2cee749965 100644
--- a/addons/hr_attendance/models/hr_attendance.py
+++ b/addons/hr_attendance/models/hr_attendance.py
@@ -91,7 +91,7 @@ class HrAttendance(models.Model):
# is the same as the one before our check_in time computed before, otherwise it overlaps
last_attendance_before_check_out = self.env['hr.attendance'].search([
('employee_id', '=', attendance.employee_id.id),
- ('check_in', '<=', attendance.check_out),
+ ('check_in', '<', attendance.check_out),
('id', '!=', attendance.id),
], order='check_in desc', limit=1)
if last_attendance_before_check_out and last_attendance_before_check_in != last_attendance_before_check_out:
diff --git a/addons/hr_holidays/report/holidays_summary_report.py b/addons/hr_holidays/report/holidays_summary_report.py
index 1428562ed62..b5dd3b14325 100644
--- a/addons/hr_holidays/report/holidays_summary_report.py
+++ b/addons/hr_holidays/report/holidays_summary_report.py
@@ -3,7 +3,7 @@
from datetime import timedelta
from dateutil.relativedelta import relativedelta
-from odoo import api, fields, models
+from odoo import api, fields, models, _
from odoo.exceptions import UserError
diff --git a/addons/hr_payroll/report/report_contribution_register.py b/addons/hr_payroll/report/report_contribution_register.py
index c56918c88be..51bccf507e3 100644
--- a/addons/hr_payroll/report/report_contribution_register.py
+++ b/addons/hr_payroll/report/report_contribution_register.py
@@ -5,7 +5,7 @@
from datetime import datetime
from dateutil.relativedelta import relativedelta
-from odoo import api, fields, models
+from odoo import api, fields, models, _
from odoo.exceptions import UserError
diff --git a/addons/l10n_be/data/account_tax_template_data.xml b/addons/l10n_be/data/account_tax_template_data.xml
index e7a3de02628..0ee540727cd 100644
--- a/addons/l10n_be/data/account_tax_template_data.xml
+++ b/addons/l10n_be/data/account_tax_template_data.xml
@@ -1007,7 +1007,7 @@
<field name="name">TVA Déductible 12% Intracomm. - Approvisionn. et marchandises</field>
<field name="price_include" eval="0"/>
<field name="amount">12</field>
- <field name="amount_type">percent</field>
+ <field name="amount_type">group</field>
<field name="type_tax_use">purchase</field>
<field name="children_tax_ids" eval="[(6, 0, [ref('attn_VAT-IN-V81-12-EU-C1'), ref('attn_VAT-IN-V81-12-EU-C2')])]"/>
<field name="chart_template_id" ref="l10nbe_chart_template"/>
diff --git a/addons/l10n_in_hr_payroll/report/report_hr_salary_employee_bymonth.py b/addons/l10n_in_hr_payroll/report/report_hr_salary_employee_bymonth.py
index 1cc67073146..d9853fab103 100644
--- a/addons/l10n_in_hr_payroll/report/report_hr_salary_employee_bymonth.py
+++ b/addons/l10n_in_hr_payroll/report/report_hr_salary_employee_bymonth.py
@@ -3,7 +3,7 @@
from datetime import date
-from odoo import api, models
+from odoo import api, models, _
from odoo.exceptions import UserError
diff --git a/addons/l10n_in_hr_payroll/report/report_hr_yearly_salary_detail.py b/addons/l10n_in_hr_payroll/report/report_hr_yearly_salary_detail.py
index bb6e2c75423..143bc0cea91 100644
--- a/addons/l10n_in_hr_payroll/report/report_hr_yearly_salary_detail.py
+++ b/addons/l10n_in_hr_payroll/report/report_hr_yearly_salary_detail.py
@@ -3,7 +3,7 @@
from datetime import date
-from odoo import api, models
+from odoo import api, models, _
from odoo.exceptions import UserError
diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml
index b9ce40f7950..995a27ddd3b 100644
--- a/addons/point_of_sale/static/src/xml/pos.xml
+++ b/addons/point_of_sale/static/src/xml/pos.xml
@@ -1458,10 +1458,12 @@
</tr>
</t>
<tr>
- <td>Discount:</td>
- <td class="pos-right-align">
- <t t-esc="widget.format_currency(order.get_total_discount())"/>
- </td>
+ <t t-if="order.get_total_discount() > 0">
+ <td>Discount:</td>
+ <td class="pos-right-align">
+ <t t-esc="widget.format_currency(order.get_total_discount())"/>
+ </td>
+ </t>
</tr>
<tr class="emph">
<td>Total:</td>
diff --git a/addons/product/models/product.py b/addons/product/models/product.py
index b50190b0fea..b4caa995c89 100644
--- a/addons/product/models/product.py
+++ b/addons/product/models/product.py
@@ -106,7 +106,7 @@ class ProductProduct(models.Model):
_description = "Product"
_inherits = {'product.template': 'product_tmpl_id'}
_inherit = ['mail.thread']
- _order = 'default_code, id'
+ _order = 'default_code, name, id'
price = fields.Float(
'Price', compute='_compute_product_price',
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py
index 600335eb4d2..4eea90ab7fa 100644
--- a/addons/purchase/models/purchase.py
+++ b/addons/purchase/models/purchase.py
@@ -230,6 +230,14 @@ class PurchaseOrder(models.Model):
self.currency_id = self.partner_id.property_purchase_currency_id.id or self.env.user.company_id.currency_id.id
return {}
+ @api.onchange('fiscal_position_id')
+ def _compute_tax_id(self):
+ """
+ Trigger the recompute of the taxes if the fiscal position is changed on the PO.
+ """
+ for order in self:
+ order.order_line._compute_tax_id()
+
@api.onchange('partner_id')
def onchange_partner_id_warning(self):
if not self.partner_id:
@@ -405,6 +413,10 @@ class PurchaseOrder(models.Model):
picking = pickings[0]
moves = order.order_line._create_stock_moves(picking)
moves = moves.filtered(lambda x: x.state not in ('done', 'cancel')).action_confirm()
+ seq = 0
+ for move in moves:
+ seq += 5
+ move.sequence = seq
moves.force_assign()
picking.message_post_with_view('mail.message_origin_link',
values={'self': picking, 'origin': order},
@@ -516,6 +528,14 @@ class PurchaseOrderLine(models.Model):
'price_subtotal': taxes['total_excluded'],
})
+ @api.multi
+ def _compute_tax_id(self):
+ for line in self:
+ fpos = line.order_id.fiscal_position_id or line.order_id.partner_id.property_account_position_id
+ # If company_id is set, always filter taxes by the company
+ taxes = line.product_id.supplier_taxes_id.filtered(lambda r: not line.company_id or r.company_id == line.company_id)
+ line.taxes_id = fpos.map_tax(taxes, line.product_id, line.order_id.partner_id) if fpos else taxes
+
@api.depends('invoice_lines.invoice_id.state')
def _compute_qty_invoiced(self):
for line in self:
diff --git a/addons/report_intrastat/report/report_intrastat_invoice_template.xml b/addons/report_intrastat/report/report_intrastat_invoice_template.xml
index d177f2ef724..06bbcf93231 100644
--- a/addons/report_intrastat/report/report_intrastat_invoice_template.xml
+++ b/addons/report_intrastat/report/report_intrastat_invoice_template.xml
@@ -130,6 +130,10 @@
</p>
<p t-if="o.fiscal_position_id">
<strong>Fiscal Position:</strong>
+ <span t-field="o.fiscal_position_id"/>
+ </p>
+ <p t-if="o.fiscal_position_id.note">
+ <strong>Fiscal Position Remark:</strong>
<span t-field="o.fiscal_position_id.note"/>
</p>
</div>
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index 4b71e041a09..a42011b3f70 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -510,12 +510,14 @@ class SaleOrder(models.Model):
for tax in line.tax_id:
group = tax.tax_group_id
res.setdefault(group, 0.0)
- taxes = tax.compute_all(line.price_reduce + base_tax, quantity=line.product_uom_qty,
+ # FORWARD-PORT UP TO SAAS-17
+ price_reduce = line.price_unit * (1.0 - line.discount / 100.0)
+ taxes = tax.compute_all(price_reduce + base_tax, quantity=line.product_uom_qty,
product=line.product_id, partner=self.partner_shipping_id)['taxes']
for t in taxes:
res[group] += t['amount']
if tax.include_base_amount:
- base_tax += tax.compute_all(line.price_reduce + base_tax, quantity=1, product=line.product_id,
+ base_tax += tax.compute_all(price_reduce + base_tax, quantity=1, product=line.product_id,
partner=self.partner_shipping_id)['taxes'][0]['amount']
res = sorted(res.items(), key=lambda l: l[0].sequence)
res = map(lambda l: (l[0].name, l[1]), res)
@@ -923,7 +925,7 @@ class SaleOrderLine(models.Model):
lang=self.order_id.partner_id.lang,
partner=self.order_id.partner_id.id,
quantity=self.product_uom_qty,
- date_order=self.order_id.date_order,
+ date=self.order_id.date_order,
pricelist=self.order_id.pricelist_id.id,
uom=self.product_uom.id,
fiscal_position=self.env.context.get('fiscal_position')
diff --git a/addons/sale/tests/test_product_id_change.py b/addons/sale/tests/test_product_id_change.py
index 4a795baa4c8..bf61c8d644f 100644
--- a/addons/sale/tests/test_product_id_change.py
+++ b/addons/sale/tests/test_product_id_change.py
@@ -68,3 +68,51 @@ class TestOnchangeProductId(TransactionCase):
so_line = so.order_line[0]
so_line.product_id_change()
self.assertEquals(100, so_line.price_unit, "The included tax must be subtracted to the price")
+
+ def test_pricelist_application(self):
+ """ Test different prices are correctly applied based on dates """
+ support_product = self.env.ref('product.product_product_2')
+ support_product.list_price = 100
+ partner = self.res_partner_model.create(dict(name="George"))
+
+ christmas_pricelist = self.env['product.pricelist'].create({
+ 'name': 'Christmas pricelist',
+ 'item_ids': [(0, 0, {
+ 'date_start': "2017-12-01",
+ 'date_end': "2017-12-24",
+ 'compute_price': 'percentage',
+ 'base': 'list_price',
+ 'percent_price': 20,
+ 'applied_on': '3_global',
+ 'name': 'Pre-Christmas discount'
+ }), (0, 0, {
+ 'date_start': "2017-12-25",
+ 'date_end': "2017-12-31",
+ 'compute_price': 'percentage',
+ 'base': 'list_price',
+ 'percent_price': 50,
+ 'applied_on': '3_global',
+ 'name': 'Post-Christmas super-discount'
+ })]
+ })
+
+ so = self.env['sale.order'].create({
+ 'partner_id': partner.id,
+ 'date_order': '2017-12-20',
+ 'pricelist_id': christmas_pricelist.id,
+ })
+
+ order_line = self.env['sale.order.line'].new({
+ 'order_id': so.id,
+ 'product_id': support_product.id,
+ })
+
+ # force compute uom and prices
+ order_line.product_id_change()
+ order_line.product_uom_change()
+
+ self.assertEqual(order_line.price_unit, 80, "First date pricelist rule not applied")
+
+ so.date_order = '2017-12-30'
+ order_line.product_id_change()
+ self.assertEqual(order_line.price_unit, 50, "Second date pricelist rule not applied")
diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py
index a37fa6ff77b..853be23c29a 100644
--- a/addons/stock/models/product.py
+++ b/addons/stock/models/product.py
@@ -272,6 +272,10 @@ class Product(models.Model):
if value == 0.0 and operator in ('=', '>=', '<='):
return self._search_product_quantity(operator, value, 'qty_available')
product_ids = self._search_qty_available_new(operator, value, self._context.get('lot_id'), self._context.get('owner_id'), self._context.get('package_id'))
+ if (value > 0 and operator in ('<=', '<')) or (value < 0 and operator in ('>=', '>')):
+ # include also unavailable products
+ domain = self._search_product_quantity(operator, value, 'qty_available')
+ product_ids += domain[0][2]
return [('id', 'in', product_ids)]
def _search_qty_available_new(self, operator, value, lot_id=False, owner_id=False, package_id=False):
diff --git a/addons/stock/tests/test_stock_flow.py b/addons/stock/tests/test_stock_flow.py
index 415214b7ca5..dbe76227118 100644
--- a/addons/stock/tests/test_stock_flow.py
+++ b/addons/stock/tests/test_stock_flow.py
@@ -1728,8 +1728,8 @@ class TestStockFlow(TestStockCommon):
self.assertEquals(picking_out.state, "assigned")
def test_74_move_state_waiting_mto(self):
- """ This test will check that when a move is unreserved, it state change to 'waiting' if
- it has ancestors or is has a 'procure_method' equal to 'make_to_order' else the state
+ """ This test will check that when a move is unreserved, its state changes to 'waiting' if
+ it has ancestors or if it has a 'procure_method' equal to 'make_to_order' else the state
changes to 'confirmed'.
"""
picking_out = self.PickingObj.create({
@@ -1754,7 +1754,7 @@ class TestStockFlow(TestStockCommon):
'picking_id': picking_out.id,
'location_id': self.stock_location,
'location_dest_id': self.customer_location})
- the_ancestor = self.MoveObj.create({
+ self.MoveObj.create({
'name': self.productA.name,
'product_id': self.productA.id,
'product_uom_qty': 2,
diff --git a/addons/web/static/src/js/views/search_menus.js b/addons/web/static/src/js/views/search_menus.js
index 10ab44ef30c..427aebda39d 100644
--- a/addons/web/static/src/js/views/search_menus.js
+++ b/addons/web/static/src/js/views/search_menus.js
@@ -120,6 +120,7 @@ return Widget.extend({
model_id: this.target_model,
context: results.context,
domain: results.domain,
+ sort: JSON.stringify(this.searchview.dataset._sort),
is_default: default_filter,
action_id: this.action_id,
};
@@ -237,6 +238,13 @@ return Widget.extend({
}
this.query.reset([this.facet_for(filter)], {
preventSearch: preventSearch || false});
+
+ // Load sort settings on view
+ if (!_.isUndefined(filter.sort)){
+ var sort_items = JSON.parse(filter.sort);
+ this.searchview.dataset.set_sort(sort_items);
+ }
+
this.$filters[this.key_for(filter)].addClass('selected');
},
remove_filter: function (filter, $filter, key) {
diff --git a/addons/website_links/static/src/js/website_links_charts.js b/addons/website_links/static/src/js/website_links_charts.js
index bd8d2e89064..8a39e531ef9 100644
--- a/addons/website_links/static/src/js/website_links_charts.js
+++ b/addons/website_links/static/src/js/website_links_charts.js
@@ -3,9 +3,11 @@ odoo.define('website_links.charts', function (require) {
var Widget = require('web.Widget');
var base = require('web_editor.base');
+var core = require('web.core');
var website = require('website.website');
var Model = require('web.Model');
+var _t = core._t;
var exports = {};
if(!$('.o_website_links_chart').length) {
@@ -48,11 +50,11 @@ if(!$('.o_website_links_chart').length) {
// Set title
var nb_clicks = _.reduce(clicks_array, function(total, val) { return total + val[1] ; }, 0);
- $(this.$element + ' .title').html(nb_clicks + ' clicks');
+ $(this.$element + ' .title').html(nb_clicks + _t(' clicks'));
// Fit data into the NVD3 scheme
var chart_data = [{}];
- chart_data[0]['key'] = '# of clicks';
+ chart_data[0]['key'] = _t('# of clicks');
chart_data[0]['values'] = clicks_array;
nv.addGraph(function() {
@@ -94,12 +96,12 @@ if(!$('.o_website_links_chart').length) {
// Process country data to fit into the NVD3 scheme
var processed_data = [];
for(var i = 0 ; i < this.data.length ; i++) {
- var country_name = this.data[i]['country_id'] ? this.data[i]['country_id'][1] : 'Undefined';
+ var country_name = this.data[i]['country_id'] ? this.data[i]['country_id'][1] : _t('Undefined');
processed_data.push({'label':country_name + ' (' + this.data[i]['country_id_count'] + ')', 'value':this.data[i]['country_id_count']});
}
// Set title
- $(this.$element + ' .title').html(this.data.length + ' countries');
+ $(this.$element + ' .title').html(this.data.length + _t(' countries'));
nv.addGraph(function() {
var chart = nv.models.pieChart()
@@ -205,9 +207,9 @@ if(!$('.o_website_links_chart').length) {
});
}
else {
- $('#all_time_charts').prepend('There is no data to show');
- $('#last_month_charts').prepend('There is no data to show');
- $('#last_week_charts').prepend('There is no data to show');
+ $('#all_time_charts').prepend(_t('There is no data to show'));
+ $('#last_month_charts').prepend(_t('There is no data to show'));
+ $('#last_week_charts').prepend(_t('There is no data to show'));
}
});
diff --git a/addons/website_portal_sale/models/payment.py b/addons/website_portal_sale/models/payment.py
index 8bfd8167229..a5095502fb6 100644
--- a/addons/website_portal_sale/models/payment.py
+++ b/addons/website_portal_sale/models/payment.py
@@ -67,7 +67,7 @@ class PaymentTransaction(models.Model):
amount_matches = float_compare(tx.amount, tx.sale_order_id.amount_total, 2) == 0
if amount_matches:
if not acquirer_name:
- acquirer_name = tx.sale_order_id.payment_acquirer_id.provider or 'unknown'
+ acquirer_name = tx.acquirer_id.provider or 'unknown'
if tx.state == 'authorized' and tx.acquirer_id.auto_confirm == 'authorize':
_logger.info('<%s> transaction authorized, auto-confirming order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id)
tx.sale_order_id.with_context(send_email=True).action_confirm()
diff --git a/addons/website_sale_stock/models/website.py b/addons/website_sale_stock/models/website.py
index b5c866c27bb..e00d29cec89 100644
--- a/addons/website_sale_stock/models/website.py
+++ b/addons/website_sale_stock/models/website.py
@@ -9,7 +9,11 @@ class Website(models.Model):
self.ensure_one()
values = super(Website, self)._prepare_sale_order_values(partner, pricelist)
if values['company_id']:
- warehouses = self.env['stock.warehouse'].sudo().search([('company_id', '=', values['company_id'])], limit=1)
- if warehouses:
- values['warehouse_id'] = warehouses.id
+ warehouse_id = (
+ self.env['ir.values'].get_default('sale.order', 'warehouse_id', company_id=values.get('company_id')) or
+ self.env['ir.values'].get_default('sale.order', 'warehouse_id') or
+ self.env['stock.warehouse'].sudo().search([('company_id', '=', values['company_id'])], limit=1).id
+ )
+ if warehouse_id:
+ values['warehouse_id'] = warehouse_id
return values