[MERGE] forward port branch saas-15 up to aa19cb61f4
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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'})
|
||||
|
||||
#------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'):
|
||||
|
||||
+17
-13
@@ -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:
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 @@
|
||||
<field name="model">openacademy.session</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Session Form">
|
||||
+ <header>
|
||||
+ <button name="action_draft" type="object"
|
||||
+ string="Reset to draft"
|
||||
+ states="confirmed,done"/>
|
||||
+ <button name="action_confirm" type="object"
|
||||
+ string="Confirm" states="draft"
|
||||
+ class="oe_highlight"/>
|
||||
+ <button name="action_done" type="object"
|
||||
+ string="Mark as done" states="confirmed"
|
||||
+ class="oe_highlight"/>
|
||||
+ <field name="state" widget="statusbar"/>
|
||||
+ </header>
|
||||
+
|
||||
<sheet>
|
||||
<group>
|
||||
<group string="General">
|
||||
@@ -28,7 +28,7 @@ diff --git a/openacademy/models.py b/openacademy/models.py
|
||||
|
||||
default['name'] = new_name
|
||||
return super(Course, self).copy(default)
|
||||
@@ -97,15 +97,15 @@ class Session(models.Model):
|
||||
@@ -79,15 +79,15 @@ class Session(models.Model):
|
||||
if self.seats < 0:
|
||||
return {
|
||||
'warning': {
|
||||
@@ -48,7 +48,7 @@ diff --git a/openacademy/models.py b/openacademy/models.py
|
||||
},
|
||||
}
|
||||
|
||||
@@ -151,4 +151,4 @@ class Session(models.Model):
|
||||
@@ -133,4 +133,4 @@ class Session(models.Model):
|
||||
def _check_instructor_not_in_attendees(self):
|
||||
for r in self:
|
||||
if r.instructor_id and r.instructor_id in r.attendee_ids:
|
||||
|
||||
@@ -2,7 +2,7 @@ Index: addons/openacademy/views/openacademy.xml
|
||||
===================================================================
|
||||
--- addons.orig/openacademy/views/openacademy.xml 2014-08-28 14:34:19.255004611 +0200
|
||||
+++ addons/openacademy/views/openacademy.xml 2014-08-28 14:34:19.251004612 +0200
|
||||
@@ -248,6 +248,12 @@
|
||||
@@ -234,6 +234,12 @@
|
||||
<field name="session_id"/>
|
||||
<field name="attendee_ids"/>
|
||||
</group>
|
||||
|
||||
@@ -17,7 +17,7 @@ Index: addons/openacademy/views/openacademy.xml
|
||||
===================================================================
|
||||
--- addons.orig/openacademy/views/openacademy.xml 2014-08-28 14:34:07.879004780 +0200
|
||||
+++ addons/openacademy/views/openacademy.xml 2014-08-28 14:34:07.871004780 +0200
|
||||
@@ -237,5 +237,26 @@
|
||||
@@ -224,5 +224,26 @@
|
||||
<menuitem id="session_menu" name="Sessions"
|
||||
parent="openacademy_menu"
|
||||
action="session_list_action"/>
|
||||
|
||||
@@ -2,7 +2,7 @@ Index: addons/openacademy/views/openacademy.xml
|
||||
===================================================================
|
||||
--- addons.orig/openacademy/views/openacademy.xml 2014-08-28 14:34:28.583004473 +0200
|
||||
+++ addons/openacademy/views/openacademy.xml 2014-08-28 14:34:28.579004473 +0200
|
||||
@@ -245,7 +245,7 @@
|
||||
@@ -231,7 +231,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Add Attendees">
|
||||
<group>
|
||||
|
||||
@@ -24,7 +24,6 @@ exercise-searchview
|
||||
exercise-gantt
|
||||
exercise-graph
|
||||
exercise-kanban
|
||||
exercise-state-basic
|
||||
exercise-access-rights
|
||||
exercise-access-rules
|
||||
exercise-wizard
|
||||
|
||||
@@ -17,7 +17,6 @@ Index
|
||||
api_integration
|
||||
setup
|
||||
reference
|
||||
business
|
||||
|
||||
.. ifconfig:: todo_include_todos
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ default db to serve on localhost:8069
|
||||
http://www.enterprisedb.com/products-services-training/pgdownload
|
||||
.. _Quilt: http://en.wikipedia.org/wiki/Quilt_(software)
|
||||
.. _saas: https://www.odoo.com/page/start
|
||||
.. _the wkhtmltopdf download page: http://wkhtmltopdf.org/downloads.html
|
||||
.. _the wkhtmltopdf download page: https://github.com/wkhtmltopdf/wkhtmltopdf/releases/tag/0.12.1
|
||||
.. _UAC: http://en.wikipedia.org/wiki/User_Account_Control
|
||||
.. _wkhtmltopdf: http://wkhtmltopdf.org
|
||||
.. _pip: https://pip.pypa.io
|
||||
|
||||
Reference in New Issue
Block a user