diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py
index 46db7021f41..f3243ecfafe 100644
--- a/addons/account/models/account_bank_statement.py
+++ b/addons/account/models/account_bank_statement.py
@@ -241,7 +241,7 @@ class AccountBankStatement(models.Model):
for aml in st_line.journal_entry_ids:
moves |= aml.move_id
if moves:
- moves.post()
+ moves.filtered(lambda m: m.state != 'posted').post()
statement.message_post(body=_('Statement %s confirmed, journal items were created.') % (statement.name,))
statements.link_bank_to_partner()
statements.write({'state': 'confirm', 'date_done': time.strftime("%Y-%m-%d %H:%M:%S")})
diff --git a/addons/account/wizard/wizard_tax_adjustments.py b/addons/account/wizard/wizard_tax_adjustments.py
index 8c5002347c0..22d2235ef04 100644
--- a/addons/account/wizard/wizard_tax_adjustments.py
+++ b/addons/account/wizard/wizard_tax_adjustments.py
@@ -18,24 +18,26 @@ class TaxAdjustments(models.TransientModel):
debit_account_id = fields.Many2one('account.account', string='Debit account', required=True, domain=[('deprecated', '=', False)])
credit_account_id = fields.Many2one('account.account', string='Credit account', required=True, domain=[('deprecated', '=', False)])
amount = fields.Monetary(currency_field='company_currency_id', required=True)
+ adjustment_type = fields.Selection([('debit', 'Adjustment in favor of the Estate'), ('credit', 'Adjustment in your favor')], string="Adjustment Type", store=False, required=True)
company_currency_id = fields.Many2one('res.currency', readonly=True, default=lambda self: self.env.user.company_id.currency_id)
tax_id = fields.Many2one('account.tax', string='Adjustment Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'none'), ('tax_adjustment', '=', True)], required=True)
@api.multi
def _create_move(self):
+ adjustment_type = self.env.context.get('adjustment_type', (self.amount > 0.0 and 'debit' or 'credit'))
debit_vals = {
'name': self.reason,
- 'debit': self.amount,
+ 'debit': abs(self.amount),
'credit': 0.0,
'account_id': self.debit_account_id.id,
- 'tax_line_id': self.tax_id.id,
+ 'tax_line_id': adjustment_type == 'debit' and self.tax_id.id or False,
}
credit_vals = {
'name': self.reason,
'debit': 0.0,
- 'credit': self.amount,
+ 'credit': abs(self.amount),
'account_id': self.credit_account_id.id,
- 'tax_line_id': self.tax_id.id,
+ 'tax_line_id': adjustment_type == 'credit' and self.tax_id.id or False,
}
vals = {
'journal_id': self.journal_id.id,
@@ -48,6 +50,13 @@ class TaxAdjustments(models.TransientModel):
return move.id
@api.multi
+ def create_move_debit(self):
+ return self.with_context(adjustment_type='debit').create_move()
+
+ @api.multi
+ def create_move_credit(self):
+ return self.with_context(adjustment_type='credit').create_move()
+
def create_move(self):
#create the adjustment move
move_id = self._create_move()
diff --git a/addons/account/wizard/wizard_tax_adjustments_view.xml b/addons/account/wizard/wizard_tax_adjustments_view.xml
index 3d4ed0a9e9a..dba164388b9 100644
--- a/addons/account/wizard/wizard_tax_adjustments_view.xml
+++ b/addons/account/wizard/wizard_tax_adjustments_view.xml
@@ -12,6 +12,7 @@
+
@@ -26,8 +27,14 @@
diff --git a/addons/account_asset/models/account_asset.py b/addons/account_asset/models/account_asset.py
index 78cd786cda8..52d2c48a0d9 100644
--- a/addons/account_asset/models/account_asset.py
+++ b/addons/account_asset/models/account_asset.py
@@ -411,7 +411,7 @@ class AccountAssetAsset(models.Model):
@api.model
def create(self, vals):
asset = super(AccountAssetAsset, self.with_context(mail_create_nolog=True)).create(vals)
- asset.compute_depreciation_board()
+ asset.sudo().compute_depreciation_board()
return asset
@api.multi
diff --git a/addons/hr_timesheet/report/report_timesheet_templates.xml b/addons/hr_timesheet/report/report_timesheet_templates.xml
index 141eb0511e8..c706143dd93 100644
--- a/addons/hr_timesheet/report/report_timesheet_templates.xml
+++ b/addons/hr_timesheet/report/report_timesheet_templates.xml
@@ -36,7 +36,7 @@
-
+
|
@@ -72,4 +72,4 @@
name="hr_timesheet.report_timesheet"
file="report_timesheet"
/>
-
\ No newline at end of file
+
diff --git a/addons/payment_stripe/models/payment.py b/addons/payment_stripe/models/payment.py
index 72c02fc5aed..515dd3bcd1c 100644
--- a/addons/payment_stripe/models/payment.py
+++ b/addons/payment_stripe/models/payment.py
@@ -109,7 +109,7 @@ class PaymentTransactionStripe(models.Model):
@api.multi
def stripe_s2s_do_transaction(self, **kwargs):
self.ensure_one()
- result = self._create_stripe_charge(acquirer_ref=self.payment_token_id.acquirer_ref)
+ result = self._create_stripe_charge(acquirer_ref=self.payment_token_id.acquirer_ref, email=self.partner_email)
return self._stripe_s2s_validate_tree(result)
@api.model
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 6e12dc8b114..25b31fd0b8f 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -1152,7 +1152,8 @@ exports.Orderline = Backbone.Model.extend({
if (unit.rounding) {
this.quantity = round_pr(quant, unit.rounding);
var decimals = this.pos.dp['Product Unit of Measure'];
- this.quantityStr = formats.format_value(round_di(this.quantity, decimals), { type: 'float', digits: [69, decimals]});
+ this.quantity = round_di(this.quantity, decimals)
+ this.quantityStr = formats.format_value(this.quantity, { type: 'float', digits: [69, decimals]});
} else {
this.quantity = round_pr(quant, 1);
this.quantityStr = this.quantity.toFixed(0);
diff --git a/addons/pos_mercury/data/pos_mercury_demo.xml b/addons/pos_mercury/data/pos_mercury_demo.xml
index 5ff1a0d70e4..b242868f8df 100644
--- a/addons/pos_mercury/data/pos_mercury_demo.xml
+++ b/addons/pos_mercury/data/pos_mercury_demo.xml
@@ -5,8 +5,8 @@
Mercury Demo
- 334160
- 81303DUR
+ 755847002
+ xyz
diff --git a/addons/pos_mercury/models/pos_mercury.py b/addons/pos_mercury/models/pos_mercury.py
index 707f85692e0..6af9d437af9 100644
--- a/addons/pos_mercury/models/pos_mercury.py
+++ b/addons/pos_mercury/models/pos_mercury.py
@@ -4,6 +4,7 @@
import logging
from odoo import models, fields, api, _
+from odoo.tools.float_utils import float_compare
_logger = logging.getLogger(__name__)
@@ -71,8 +72,9 @@ class PosOrder(models.Model):
statement_id = super(PosOrder, self).add_payment(data)
statement_lines = self.env['account.bank.statement.line'].search([('statement_id', '=', statement_id),
('pos_statement_id', '=', self.id),
- ('journal_id', '=', data['journal']),
- ('amount', '=', data['amount'])])
+ ('journal_id', '=', data['journal'])])
+ statement_lines = statement_lines.filtered(lambda line: float_compare(line.amount, data['amount'],
+ precision_rounding=line.journal_currency_id.rounding) == 0)
# we can get multiple statement_lines when there are >1 credit
# card payments with the same amount. In that case it doesn't
diff --git a/addons/pos_mercury/models/pos_mercury_transaction.py b/addons/pos_mercury/models/pos_mercury_transaction.py
index cca78872ac5..4d8da0b9a98 100644
--- a/addons/pos_mercury/models/pos_mercury_transaction.py
+++ b/addons/pos_mercury/models/pos_mercury_transaction.py
@@ -63,7 +63,11 @@ class MercuryTransaction(models.Model):
'SOAPAction': 'http://www.mercurypay.com/CreditTransaction',
}
- r = urllib2.Request('https://w1.mercurypay.com/ws/ws.asmx', data=xml_transaction, headers=headers)
+ url = 'https://w1.mercurypay.com/ws/ws.asmx'
+ if self.env['ir.config_parameter'].sudo().get_param('pos_mercury.enable_test_env'):
+ url = 'https://w1.mercurycert.net/ws/ws.asmx'
+
+ r = urllib2.Request(url, data=xml_transaction, headers=headers)
try:
u = urllib2.urlopen(r, timeout=65)
response = werkzeug.utils.unescape(u.read())
diff --git a/addons/sale/models/account_invoice.py b/addons/sale/models/account_invoice.py
index 1ed8cda461b..a0b1a51cde1 100644
--- a/addons/sale/models/account_invoice.py
+++ b/addons/sale/models/account_invoice.py
@@ -39,6 +39,9 @@ class AccountInvoice(models.Model):
def _onchange_delivery_address(self):
addr = self.partner_id.address_get(['delivery'])
self.partner_shipping_id = addr and addr.get('delivery')
+ if self.env.context.get('type', 'out_invoice') == 'out_invoice':
+ company = self.company_id or self.env.user.company_id
+ self.comment = company.with_context(lang=self.partner_id.lang).sale_note
@api.multi
def action_invoice_paid(self):
diff --git a/addons/stock/wizard/make_procurement.py b/addons/stock/wizard/make_procurement.py
index 3ae8f6d6bf8..3bed9047bd9 100644
--- a/addons/stock/wizard/make_procurement.py
+++ b/addons/stock/wizard/make_procurement.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import datetime
from odoo import api, fields, models
-
class MakeProcurement(models.TransientModel):
_name = 'make.procurement'
_description = 'Make Procurements'
@@ -64,9 +64,14 @@ class MakeProcurement(models.TransientModel):
""" Creates procurement order for selected product. """
ProcurementOrder = self.env['procurement.order']
for wizard in self:
+ # we set the time to noon to avoid the date to be changed because of timezone issues
+ date = fields.Datetime.from_string(wizard.date_planned)
+ date = date + datetime.timedelta(hours=12)
+ date = fields.Datetime.to_string(date)
+
procurement = ProcurementOrder.create({
'name': 'INT: %s' % (self.env.user.login),
- 'date_planned': wizard.date_planned,
+ 'date_planned': date,
'product_id': wizard.product_id.id,
'product_qty': wizard.qty,
'product_uom': wizard.uom_id.id,
diff --git a/addons/stock_calendar/models/stock.py b/addons/stock_calendar/models/stock.py
index 9ed605cda30..88121065d7e 100644
--- a/addons/stock_calendar/models/stock.py
+++ b/addons/stock_calendar/models/stock.py
@@ -54,7 +54,7 @@ class StockWarehouseOrderpoint(models.Model):
date = interval[1]
res_intervals += [(date, group), ]
else:
- return [(now_date, None)]
+ return [(False, None)]
return res_intervals
def _get_previous_dates(self, start_date=False):
diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py
index a1223d896c8..5e5c88031c7 100644
--- a/addons/stock_landed_costs/models/stock_landed_cost.py
+++ b/addons/stock_landed_costs/models/stock_landed_cost.py
@@ -85,11 +85,13 @@ class LandedCost(models.Model):
raise UserError(_('Cost and adjustments lines do not match. You should maybe recompute the landed costs.'))
for cost in self:
- move = self.env['account.move'].create({
+ move = self.env['account.move']
+ move_vals = {
'journal_id': cost.account_journal_id.id,
'date': cost.date,
- 'ref': cost.name
- })
+ 'ref': cost.name,
+ 'line_ids': [],
+ }
for line in cost.valuation_adjustment_lines.filtered(lambda line: line.move_id):
per_unit = line.final_cost / line.quantity
diff = per_unit - line.former_cost_per_unit
@@ -134,8 +136,9 @@ class LandedCost(models.Model):
for quant in line.move_id.quant_ids:
if quant.location_id.usage != 'internal':
qty_out += quant.qty
- line._create_accounting_entries(move, qty_out)
- move.assert_balanced()
+ move_vals['line_ids'] += line._create_accounting_entries(move, qty_out)
+
+ move = move.create(move_vals)
cost.write({'state': 'done', 'account_move_id': move.id})
move.post()
return True
@@ -336,11 +339,10 @@ class AdjustmentLines(models.Model):
Generate the account.move.line values to track the landed cost.
Afterwards, for the goods that are already out of stock, we should create the out moves
"""
- AccountMoveLine = self.env['account.move.line'].with_context(check_move_validity=False, recompute=False)
+ AccountMoveLine = []
base_line = {
'name': self.name,
- 'move_id': move.id,
'product_id': self.product_id.id,
'quantity': self.quantity,
}
@@ -354,8 +356,8 @@ class AdjustmentLines(models.Model):
# negative cost, reverse the entry
debit_line['credit'] = -diff
credit_line['debit'] = -diff
- AccountMoveLine.create(debit_line)
- AccountMoveLine.create(credit_line)
+ AccountMoveLine.append([0, 0, debit_line])
+ AccountMoveLine.append([0, 0, credit_line])
# Create account move lines for quants already out of stock
if qty_out > 0:
@@ -375,8 +377,8 @@ class AdjustmentLines(models.Model):
# negative cost, reverse the entry
debit_line['credit'] = -diff
credit_line['debit'] = -diff
- AccountMoveLine.create(debit_line)
- AccountMoveLine.create(credit_line)
+ AccountMoveLine.append([0, 0, debit_line])
+ AccountMoveLine.append([0, 0, credit_line])
# TDE FIXME: oh dear
if self.env.user.company_id.anglo_saxon_accounting:
@@ -396,7 +398,7 @@ class AdjustmentLines(models.Model):
# negative cost, reverse the entry
debit_line['credit'] = -diff
credit_line['debit'] = -diff
- AccountMoveLine.create(debit_line)
- AccountMoveLine.create(credit_line)
+ AccountMoveLine.append([0, 0, debit_line])
+ AccountMoveLine.append([0, 0, credit_line])
- return True
+ return AccountMoveLine
diff --git a/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js b/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js
index 8619c44a7d6..304845a0fee 100644
--- a/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js
+++ b/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js
@@ -391,18 +391,14 @@ THE SOFTWARE.
if (picker.options.calendarWeeks === true) {
html.append(' | # | ');
}
- if (moment().localeData()._week.dow === 0) { // starts on Sunday
- for (i = 0; i < 7; i++) {
- html.append('' + weekdaysMin[i] + ' | ');
- }
- } else {
- for (i = 1; i < 8; i++) {
- if (i === 7) {
- html.append('' + weekdaysMin[0] + ' | ');
- } else {
- html.append('' + weekdaysMin[i] + ' | ');
- }
- }
+ // ODOO change so week starting not on sunday/monday have correct
+ // day name. This is solved in saas-15 by using new library version
+ var startDay = moment().localeData()._week.dow;
+ if (startDay === undefined) {
+ startDay = 1;
+ }
+ for (i = startDay; i < startDay + 7; i++) {
+ html.append('' + weekdaysMin[i % 7] + ' | ');
}
picker.widget.find('.datepicker-days thead').append(html);
},
diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js
index f5ed3b2e806..1ee3ea65ed1 100644
--- a/addons/web_calendar/static/src/js/web_calendar.js
+++ b/addons/web_calendar/static/src/js/web_calendar.js
@@ -920,9 +920,10 @@ var CalendarView = View.extend({
}
}
else {
+ var res_id = parseInt(id).toString() === id ? parseInt(id) : id;
new form_common.FormViewDialog(this, {
res_model: this.model,
- res_id: parseInt(id).toString() === id ? parseInt(id) : id,
+ res_id: res_id,
context: this.dataset.get_context(),
title: title,
view_id: +this.open_popup_action,
@@ -934,7 +935,7 @@ var CalendarView = View.extend({
}},
{text: _t("Delete"), close: true, click: function() {
- self.remove_event(id);
+ self.remove_event(res_id);
}},
{text: _t("Close"), close: true}
diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js
index 2678ba955af..435c5d7fa78 100644
--- a/addons/web_editor/static/src/js/summernote.js
+++ b/addons/web_editor/static/src/js/summernote.js
@@ -1856,12 +1856,17 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent)
var $dom = $(ancestor);
if (!dom.isList(ancestor)) {
+ // to indent a selection, we indent the child nodes of the common
+ // ancestor that contains this selection
$dom = $(dom.node(ancestor)).children();
}
- if (!$dom.length) {
- $dom = $(dom.ancestor(r.sc, dom.isList) || dom.ancestor(r.sc, dom.isCell));
+ if (!$dom.not('br').length) {
+ // if selection is inside a list, we indent its list items
+ $dom = $(dom.ancestor(r.sc, dom.isList));
if (!$dom.length) {
- $dom = $(r.sc).closest(options.styleTags.join(','));
+ // if the selection is contained in a single HTML node, we indent
+ // the first ancestor 'content block' (P, H1, PRE, ...) or TD
+ $dom = $(r.sc).closest(options.styleTags.join(',')+',td');
}
}
diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py
index fd68fa704dc..3843638c8b0 100644
--- a/addons/website/controllers/main.py
+++ b/addons/website/controllers/main.py
@@ -110,7 +110,10 @@ class Website(Home):
}
# /page/website.XXX --> /page/XXX
if page.startswith('website.'):
- return request.redirect('/page/' + page[8:], code=301)
+ url = '/page/' + page[8:]
+ if request.httprequest.query_string:
+ url += '?' + request.httprequest.query_string
+ return request.redirect(url, code=301)
elif '.' not in page:
page = 'website.%s' % page
diff --git a/addons/website_event_sale/static/src/js/website.tour.event_sale.js b/addons/website_event_sale/static/src/js/website.tour.event_sale.js
index 327afe03a56..d765351ed02 100644
--- a/addons/website_event_sale/static/src/js/website.tour.event_sale.js
+++ b/addons/website_event_sale/static/src/js/website.tour.event_sale.js
@@ -91,6 +91,7 @@ tour.register('event_buy_tickets', {
{
content: "Last step",
trigger: '.oe_website_sale:contains("Thank you for your order")',
+ timeout: 30000,
}
]
);
diff --git a/addons/website_form/static/src/js/website_form.js b/addons/website_form/static/src/js/website_form.js
index 2f91db94c9b..022156b99f7 100644
--- a/addons/website_form/static/src/js/website_form.js
+++ b/addons/website_form/static/src/js/website_form.js
@@ -13,7 +13,11 @@ odoo.define('website_form.animation', function (require) {
snippet_animation.registry.form_builder_send = snippet_animation.Class.extend({
selector: '.s_website_form',
- start: function() {
+ start: function(editable_mode) {
+ if (editable_mode) {
+ this.stop();
+ return;
+ }
var self = this;
this.templates_loaded = ajax.loadXML('/website_form/static/src/xml/website_form.xml', qweb);
this.$target.find('.o_website_form_send').on('click',function(e) {self.send(e);});
diff --git a/addons/website_sale/static/src/js/website_sale_tour_buy.js b/addons/website_sale/static/src/js/website_sale_tour_buy.js
index 18db42a1270..268a4448570 100644
--- a/addons/website_sale/static/src/js/website_sale_tour_buy.js
+++ b/addons/website_sale/static/src/js/website_sale_tour_buy.js
@@ -76,6 +76,7 @@ tour.register('shop_buy_product', {
{
content: "finish",
trigger: '.oe_website_sale:contains("Thank you for your order")',
+ timeout: 30000,
}
]
);
diff --git a/odoo/addons/base/module/module.py b/odoo/addons/base/module/module.py
index 3e2eb4749cb..e499eb6550b 100644
--- a/odoo/addons/base/module/module.py
+++ b/odoo/addons/base/module/module.py
@@ -599,7 +599,7 @@ class Module(models.Model):
res = [0, 0] # [update, add]
default_version = modules.adapt_version('1.0')
- known_mods = self.search([])
+ known_mods = self.with_context(lang=None).search([])
known_mods_names = {mod.name: mod for mod in known_mods}
# iterate through detected modules and update/create them in db
diff --git a/odoo/addons/base/res/res_country_data.xml b/odoo/addons/base/res/res_country_data.xml
index 8ff0caa1ef0..800e349bf56 100644
--- a/odoo/addons/base/res/res_country_data.xml
+++ b/odoo/addons/base/res/res_country_data.xml
@@ -1385,7 +1385,7 @@
Sudan
sd
-
+
diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml
index f986c0a08b8..dc864e1dc9a 100644
--- a/odoo/addons/base/res/res_currency_data.xml
+++ b/odoo/addons/base/res/res_currency_data.xml
@@ -1016,6 +1016,7 @@
+
SDD
£Sd
@@ -1023,6 +1024,13 @@
+
+ SDG
+ ج.س.
+ 0.01
+
+
+
LKR
Rs
diff --git a/odoo/addons/base/res/res_currency_demo.xml b/odoo/addons/base/res/res_currency_demo.xml
index ba316d0a7db..e74fb16fda8 100644
--- a/odoo/addons/base/res/res_currency_demo.xml
+++ b/odoo/addons/base/res/res_currency_demo.xml
@@ -877,6 +877,12 @@
544.44
+
+
+ 2010-01-01
+ 3.1999
+
+
2010-01-01