diff --git a/addons/base_import/models/base_import.py b/addons/base_import/models/base_import.py
index 996b91b0349..6c4b1904e64 100644
--- a/addons/base_import/models/base_import.py
+++ b/addons/base_import/models/base_import.py
@@ -615,7 +615,7 @@ class Import(models.TransientModel):
for num, line in enumerate(data):
if line[index]:
try:
- line[index] = dt.strftime(dt.strptime(ustr(line[index]).encode('utf-8'), user_format), server_format)
+ line[index] = dt.strftime(dt.strptime(ustr(line[index].strip()).encode('utf-8'), user_format), server_format)
except ValueError as e:
raise ValueError(_("Column %s contains incorrect values. Error in line %d: %s") % (name, num + 1, ustr(e.message)))
except Exception as e:
diff --git a/addons/l10n_fr_certification/models/account.py b/addons/l10n_fr_certification/models/account.py
index bef0880d7ca..07d5fc04e41 100644
--- a/addons/l10n_fr_certification/models/account.py
+++ b/addons/l10n_fr_certification/models/account.py
@@ -10,7 +10,7 @@ ERR_MSG = _("According to the french law, you cannot modify a %s in order for it
#forbidden fields
MOVE_FIELDS = ['date', 'journal_id', 'company_id']
-LINE_FIELDS = ['debit', 'credit', 'account_id', 'move_id', 'partner_id']
+LINE_FIELDS = ['debit', 'credit', 'account_id', 'partner_id']
class AccountMove(models.Model):
@@ -55,7 +55,8 @@ class AccountMove(models.Model):
for line in move.line_ids:
for field in LINE_FIELDS:
- values[field] = _getattrstring(line, field)
+ k = 'line_%d_%s' % (line.id, field)
+ values[k] = _getattrstring(line, field)
#make the json serialization canonical
# (https://tools.ietf.org/html/draft-staykov-hu-json-canonical-form-00)
move.l10n_fr_string_to_hash = dumps(values, sort_keys=True, encoding="utf-8",
diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py
index e86138d82b9..be91eb3fd01 100644
--- a/addons/mass_mailing/models/mass_mailing.py
+++ b/addons/mass_mailing/models/mass_mailing.py
@@ -559,7 +559,7 @@ class MassMailing(models.Model):
def retry_failed_mail(self):
failed_mails = self.env['mail.mail'].search([('mailing_id', 'in', self.ids), ('state', '=', 'exception')])
failed_mails.mapped('statistics_ids').unlink()
- failed_mails.unlink()
+ failed_mails.sudo().unlink()
self.write({'state': 'in_queue'})
#------------------------------------------------------
diff --git a/addons/mrp/models/mrp_workcenter.py b/addons/mrp/models/mrp_workcenter.py
index 0dc9cdc96af..cc12ec0060b 100644
--- a/addons/mrp/models/mrp_workcenter.py
+++ b/addons/mrp/models/mrp_workcenter.py
@@ -15,7 +15,7 @@ class MrpWorkcenter(models.Model):
# resource
name = fields.Char(related='resource_id.name', store=True)
- time_efficiency = fields.Float('Time Efficiency', related='resource_id.time_efficiency', store=True)
+ time_efficiency = fields.Float('Time Efficiency', related='resource_id.time_efficiency', default=100, store=True)
active = fields.Boolean('Active', related='resource_id.active', default=True, store=True)
code = fields.Char('Code', copy=False)
diff --git a/addons/point_of_sale/i18n/point_of_sale.pot b/addons/point_of_sale/i18n/point_of_sale.pot
index 77c4a996ec8..0d7ea224acf 100644
--- a/addons/point_of_sale/i18n/point_of_sale.pot
+++ b/addons/point_of_sale/i18n/point_of_sale.pot
@@ -3512,6 +3512,18 @@ msgid "You have to select a pricelist in the sale form !\n"
"Please set one before choosing a product."
msgstr ""
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_details.py:48
+#, python-format
+msgid "You have to set a logo for your company."
+msgstr ""
+
+#. module: point_of_sale
+#: code:addons/point_of_sale/wizard/pos_details.py:50
+#, python-format
+msgid "You have to set your reports's header and footer layout."
+msgstr ""
+
#. module: point_of_sale
#: code:addons/point_of_sale/models/pos_session.py:24
#, python-format
diff --git a/addons/point_of_sale/wizard/pos_details.py b/addons/point_of_sale/wizard/pos_details.py
index 0a599aefd86..fa363798dfc 100644
--- a/addons/point_of_sale/wizard/pos_details.py
+++ b/addons/point_of_sale/wizard/pos_details.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import api, fields, models
+from odoo import api, fields, models, _
from odoo.exceptions import UserError
@@ -44,6 +44,10 @@ class PosDetails(models.TransientModel):
@api.multi
def generate_report(self):
+ if (not self.env.user.company_id.logo):
+ raise UserError(_("You have to set a logo or a layout for your company."))
+ elif (not self.env.user.company_id.external_report_layout):
+ raise UserError(_("You have to set your reports's header and footer layout."))
data = {'date_start': self.start_date, 'date_stop': self.end_date, 'config_ids': self.pos_config_ids.ids}
return self.env['report'].get_action(
[], 'point_of_sale.report_saledetails', data=data)
diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py
index abe09f05fd6..e6c402bc95a 100644
--- a/addons/product/models/product_pricelist.py
+++ b/addons/product/models/product_pricelist.py
@@ -106,7 +106,7 @@ class Pricelist(models.Model):
"""
self.ensure_one()
if not date:
- date = self._context.get('date', fields.Date.today())
+ date = self._context.get('date') or fields.Date.today()
if not uom_id and self._context.get('uom'):
uom_id = self._context['uom']
if uom_id:
diff --git a/addons/resource/i18n/resource.pot b/addons/resource/i18n/resource.pot
index 30b510ade92..aa093e5292e 100644
--- a/addons/resource/i18n/resource.pot
+++ b/addons/resource/i18n/resource.pot
@@ -441,6 +441,12 @@ msgstr ""
msgid "This field is used to calculate the the expected duration of a work order at this work center. For example, if a work order takes one hour and the efficiency factor is 100%, then the expected duration will be one hour. If the efficiency factor is 200%, however the expected duration will be 30 minutes."
msgstr ""
+#. module: resource
+#: code:addons/resource/models/resource.py:667
+#, python-format
+msgid "The efficiency factor cannot be equal to 0."
+msgstr ""
+
#. module: resource
#: selection:resource.calendar.attendance,dayofweek:0
msgid "Thursday"
diff --git a/addons/resource/models/resource.py b/addons/resource/models/resource.py
index c464fada7a1..6f0353be2a4 100644
--- a/addons/resource/models/resource.py
+++ b/addons/resource/models/resource.py
@@ -669,6 +669,13 @@ class ResourceResource(models.Model):
required=True,
help="Define the schedule of resource")
+ @api.multi
+ @api.constrains('time_efficiency')
+ def _check_time_efficiency(self):
+ for record in self:
+ if record.time_efficiency == 0:
+ raise ValidationError(_('The efficiency factor cannot be equal to 0.'))
+
@api.model
def create(self, values):
if values.get('company_id') and not values.get('calendar_id'):
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index be7fea3d465..cb84495073d 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -889,6 +889,21 @@ class SaleOrderLine(models.Model):
uom=self.product_uom.id
)
+ result = {'domain': domain}
+
+ title = False
+ message = False
+ warning = {}
+ if product.sale_line_warn != 'no-message':
+ title = _("Warning for %s") % product.name
+ message = product.sale_line_warn_msg
+ warning['title'] = title
+ warning['message'] = message
+ result = {'warning': warning}
+ if product.sale_line_warn == 'block':
+ self.product_id = False
+ return result
+
name = product.name_get()[0][1]
if product.description_sale:
name += '\n' + product.description_sale
@@ -900,22 +915,11 @@ class SaleOrderLine(models.Model):
vals['price_unit'] = self.env['account.tax']._fix_tax_included_price(self._get_display_price(product), product.taxes_id, self.tax_id)
self.update(vals)
- title = False
- message = False
- warning = {}
- if product.sale_line_warn != 'no-message':
- title = _("Warning for %s") % product.name
- message = product.sale_line_warn_msg
- warning['title'] = title
- warning['message'] = message
- if product.sale_line_warn == 'block':
- self.product_id = False
- return {'warning': warning}
- return {'domain': domain}
+ return result
@api.onchange('product_uom', 'product_uom_qty')
def product_uom_change(self):
- if not self.product_uom:
+ if not self.product_uom or not self.product_id:
self.price_unit = 0.0
return
if self.order_id.pricelist_id and self.order_id.partner_id:
diff --git a/addons/stock_account/models/stock.py b/addons/stock_account/models/stock.py
index ca8e2e840dc..f68ed53d14e 100644
--- a/addons/stock_account/models/stock.py
+++ b/addons/stock_account/models/stock.py
@@ -318,8 +318,8 @@ class StockMove(models.Model):
'product_uom_id': self.product_id.uom_id.id,
'ref': self.picking_id.name,
'partner_id': partner_id,
- 'debit': debit_value,
- 'credit': 0,
+ 'debit': debit_value if debit_value > 0 else 0,
+ 'credit': -debit_value if debit_value < 0 else 0,
'account_id': debit_account_id,
}
credit_line_vals = {
@@ -329,8 +329,8 @@ class StockMove(models.Model):
'product_uom_id': self.product_id.uom_id.id,
'ref': self.picking_id.name,
'partner_id': partner_id,
- 'credit': credit_value,
- 'debit': 0,
+ 'credit': credit_value if credit_value > 0 else 0,
+ 'debit': -credit_value if credit_value < 0 else 0,
'account_id': credit_account_id,
}
res = [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
diff --git a/addons/website/static/src/js/website.backendDashboard.js b/addons/website/static/src/js/website.backendDashboard.js
index 9c6416da4ac..345110eaf12 100644
--- a/addons/website/static/src/js/website.backendDashboard.js
+++ b/addons/website/static/src/js/website.backendDashboard.js
@@ -59,8 +59,8 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
fetch_data: function() {
var self = this;
return ajax.jsonRpc('/website/fetch_dashboard_data', 'call', {
- 'date_from': this.date_from.format('YYYY-MM-DD'),
- 'date_to': this.date_to.format('YYYY-MM-DD'),
+ 'date_from': this.date_from.year()+'-'+(this.date_from.month()+1)+'-'+this.date_from.date(),
+ 'date_to': this.date_to.year()+'-'+(this.date_to.month()+1)+'-'+this.date_to.date(),
}).done(function(result) {
self.data = result;
self.dashboards_data = result.dashboards;
diff --git a/addons/website_crm_partner_assign/report/crm_lead_report.py b/addons/website_crm_partner_assign/report/crm_lead_report.py
index e72a1b3dedf..07676117473 100644
--- a/addons/website_crm_partner_assign/report/crm_lead_report.py
+++ b/addons/website_crm_partner_assign/report/crm_lead_report.py
@@ -67,7 +67,7 @@ class CrmLeadReportAssign(models.Model):
p.grade_id,
p.date as partner_date,
c.planned_revenue*(c.probability/100) as probable_revenue,
- 1 as nbr,
+ 1 as nbr_cases,
c.create_date as create_date,
extract('epoch' from (c.write_date-c.create_date))/(3600*24) as delay_close,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected,
diff --git a/addons/website_quote/models/sale_quote.py b/addons/website_quote/models/sale_quote.py
index e65f6ed905f..79743fdc814 100644
--- a/addons/website_quote/models/sale_quote.py
+++ b/addons/website_quote/models/sale_quote.py
@@ -23,7 +23,8 @@ class SaleQuoteTemplate(models.Model):
(2, 'Immediate after website order validation and save a token'),
], 'Payment', help="Require immediate payment by the customer when validating the order from the website quote")
mail_template_id = fields.Many2one('mail.template', 'Confirmation Mail',
- help="This e-mail template will be sent on confirmation. Leave empty to send nothing.")
+ help="This e-mail template will be sent on confirmation. Leave empty to send nothing.",
+ domain=[('model', '=', 'sale.quote.template')])
@api.multi
def open_template(self):
diff --git a/doc/howtos/backend/exercise-dashboard b/doc/howtos/backend/exercise-dashboard
index 91bc239dd7a..affbc7bdc8f 100644
--- a/doc/howtos/backend/exercise-dashboard
+++ b/doc/howtos/backend/exercise-dashboard
@@ -9,12 +9,13 @@ Index: addons/openacademy/__manifest__.py
'version': '0.1',
# any module necessary for this one to work correctly
-- 'depends': ['base'],
-+ 'depends': ['base', 'board'],
+- 'depends': ['base', 'report'],
++ 'depends': ['base', 'report', 'board'],
# always loaded
'data': [
-@@ -31,6 +31,7 @@
+@@ -30,6 +30,7 @@
+ 'templates.xml',
'views/openacademy.xml',
'views/partner.xml',
+ 'views/session_board.xml',
diff --git a/doc/howtos/backend/exercise-report b/doc/howtos/backend/exercise-report
index 351d34a92b2..08ac677b5c0 100644
--- a/doc/howtos/backend/exercise-report
+++ b/doc/howtos/backend/exercise-report
@@ -1,11 +1,24 @@
# HG changeset patch
# Parent c140f0a861a08881d8737bca0ffb83904a2059a3
+Index: addons/openacademy/__manifest__.py
+===================================================================
+--- addons.orig/openacademy/__manifest__.py 2014-08-26 17:26:21.535783052 +0200
++++ addons/openacademy/__manifest__.py 2014-08-26 17:26:21.531783052 +0200
+@@ -21,7 +21,7 @@
+ 'version': '0.1',
+
+ # any module necessary for this one to work correctly
+- 'depends': ['base'],
++ 'depends': ['base', 'report'],
+
+ # always loaded
+ 'data': [
Index: addons/openacademy/__manifest__.py
===================================================================
--- addons.orig/openacademy/__manifest__.py 2014-08-29 08:39:43.975536806 +0200
+++ addons/openacademy/__manifest__.py 2014-08-29 08:39:52.000000000 +0200
-@@ -31,6 +31,7 @@
+@@ -30,6 +30,7 @@
'templates.xml',
'views/openacademy.xml',
'views/partner.xml',
diff --git a/doc/howtos/backend/exercise-state-basic b/doc/howtos/backend/exercise-state-basic
deleted file mode 100644
index f70a41b4dae..00000000000
--- a/doc/howtos/backend/exercise-state-basic
+++ /dev/null
@@ -1,55 +0,0 @@
-# HG changeset patch
-# Parent 8c721171aa16a41e94059f53d6780c67b5ef2dfc
-# Parent 8d2ca42b5be2031ea9624896df53f09f7ca131be
-
-diff --git a/openacademy/models.py b/openacademy/models.py
---- a/openacademy/models.py
-+++ b/openacademy/models.py
-@@ -66,6 +66,24 @@ class Session(models.Model):
- attendees_count = fields.Integer(
- string="Attendees count", compute='_get_attendees_count', store=True)
-
-+ state = fields.Selection([
-+ ('draft', "Draft"),
-+ ('confirmed', "Confirmed"),
-+ ('done', "Done"),
-+ ], default='draft')
-+
-+ @api.multi
-+ def action_draft(self):
-+ self.state = 'draft'
-+
-+ @api.multi
-+ def action_confirm(self):
-+ self.state = 'confirmed'
-+
-+ @api.multi
-+ def action_done(self):
-+ self.state = 'done'
-+
- @api.depends('seats', 'attendee_ids')
- def _taken_seats(self):
- for r in self:
-diff --git a/openacademy/views/openacademy.xml b/openacademy/views/openacademy.xml
---- a/openacademy/views/openacademy.xml
-+++ b/openacademy/views/openacademy.xml
-@@ -96,6 +96,19 @@
- openacademy.session
-
-