diff --git a/addons/account/models/product.py b/addons/account/models/product.py
index 61cbe55803..02aef9842b 100644
--- a/addons/account/models/product.py
+++ b/addons/account/models/product.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from flectra import api, fields, models, _
+from flectra.exceptions import ValidationError
ACCOUNT_DOMAIN = "[('deprecated', '=', False), ('internal_type','=','other'), ('company_id', '=', current_company_id), ('is_off_balance', '=', False)]"
@@ -53,6 +54,12 @@ class ProductTemplate(models.Model):
fiscal_pos = self.env['account.fiscal.position']
return fiscal_pos.map_accounts(accounts)
+ @api.constrains('uom_id')
+ def _check_uom_not_in_invoice(self):
+ for template in self:
+ invoices = self.env['account.move.line'].sudo().search([('product_id.product_tmpl_id.id', '=', template.id)], limit=1)
+ if invoices:
+ raise ValidationError(_('The product "%s" is used in invoices. You cannot change its Unit of Measure.', self.display_name))
class ProductProduct(models.Model):
_inherit = "product.product"
diff --git a/addons/account/views/account_move_views.xml b/addons/account/views/account_move_views.xml
index d6b02a387c..938f70227f 100644
--- a/addons/account/views/account_move_views.xml
+++ b/addons/account/views/account_move_views.xml
@@ -706,20 +706,27 @@
-
+
+ options="{'no_create': True}"
+ attrs="{'readonly': [('posted_before', '=', True)]}"/>
in
in
+ groups="base.group_multi_currency"> in
+ groups="base.group_multi_currency"
+ attrs="{'readonly': [('state', '!=', 'draft')]}"/>
+
+
+
diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py
index 88dcac977e..1d45783060 100644
--- a/addons/hr_holidays/models/hr_leave.py
+++ b/addons/hr_holidays/models/hr_leave.py
@@ -16,7 +16,7 @@ from flectra import api, fields, models, SUPERUSER_ID, tools
from flectra.addons.base.models.res_partner import _tz_get
from flectra.addons.resource.models.resource import float_to_time, HOURS_PER_DAY
from flectra.exceptions import AccessError, UserError, ValidationError
-from flectra.tools import float_compare
+from flectra.tools import float_compare, format_date
from flectra.tools.float_utils import float_round
from flectra.tools.translate import _
from flectra.osv import expression
@@ -654,6 +654,7 @@ class HolidaysRequest(models.Model):
target = leave.category_id.name
else:
target = leave.employee_id.name
+ display_date = format_date(self.env, leave.date_from)
if leave.leave_type_request_unit == 'hour':
if self.env.context.get('hide_employee_name') and 'employee_id' in self.env.context.get('group_by', []):
res.append((
@@ -662,7 +663,7 @@ class HolidaysRequest(models.Model):
person=target,
leave_type=leave.holiday_status_id.name,
duration=leave.number_of_hours_display,
- date=fields.Date.to_string(leave.date_from),
+ date=display_date,
)
))
else:
@@ -672,13 +673,12 @@ class HolidaysRequest(models.Model):
person=target,
leave_type=leave.holiday_status_id.name,
duration=leave.number_of_hours_display,
- date=fields.Date.to_string(leave.date_from),
+ date=display_date,
)
))
else:
- display_date = fields.Date.to_string(leave.date_from)
if leave.number_of_days > 1:
- display_date += ' ⇨ %s' % fields.Date.to_string(leave.date_to)
+ display_date += ' ⇨ %s' % format_date(self.env, leave.date_to)
if self.env.context.get('hide_employee_name') and 'employee_id' in self.env.context.get('group_by', []):
res.append((
leave.id,
diff --git a/addons/hr_work_entry/views/hr_work_entry_views.xml b/addons/hr_work_entry/views/hr_work_entry_views.xml
index 8498a682d4..1ae1a03cfa 100644
--- a/addons/hr_work_entry/views/hr_work_entry_views.xml
+++ b/addons/hr_work_entry/views/hr_work_entry_views.xml
@@ -55,7 +55,7 @@
-
+
Hours
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index 78cd14177a..0521e02ae3 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -1825,3 +1825,10 @@ class StockMove(models.Model):
moves_to_reserve = self.env['stock.move'].search(expression.AND([static_domain, expression.OR(domains)]),
order='priority desc, date asc, id asc')
moves_to_reserve._action_assign()
+
+ def _get_orig_reserved_availability(self):
+ self.ensure_one()
+ reserved = self.reserved_availability if self.show_reserved_availability else 0.0
+ if not reserved and self.move_orig_ids:
+ reserved = sum([m._get_orig_reserved_availability() for m in self.move_orig_ids])
+ return reserved
diff --git a/addons/stock/report/report_stock_forecasted.py b/addons/stock/report/report_stock_forecasted.py
index ce7ba021ad..30a11b20fe 100644
--- a/addons/stock/report/report_stock_forecasted.py
+++ b/addons/stock/report/report_stock_forecasted.py
@@ -163,8 +163,10 @@ class ReplenishmentReport(models.AbstractModel):
)
outs = self.env['stock.move'].search(out_domain, order='priority desc, date, id')
outs_per_product = defaultdict(lambda: [])
+ outs_reservation = {}
for out in outs:
outs_per_product[out.product_id.id].append(out)
+ outs_reservation[out.id] = out._get_orig_reserved_availability()
ins = self.env['stock.move'].search(in_domain, order='priority desc, date, id')
ins_per_product = defaultdict(lambda: [])
for in_ in ins:
@@ -178,20 +180,22 @@ class ReplenishmentReport(models.AbstractModel):
lines = []
for product in (ins | outs).product_id:
for out in outs_per_product[product.id]:
- if out.state not in ('partially_available', 'assigned'):
+ reserved_availability = outs_reservation[out.id]
+ if float_is_zero(reserved_availability, precision_rounding=product.uom_id.rounding):
continue
current = currents[out.product_id.id]
- reserved = out.product_uom._compute_quantity(out.reserved_availability, product.uom_id)
+ reserved = out.product_uom._compute_quantity(reserved_availability, product.uom_id)
currents[product.id] -= reserved
lines.append(self._prepare_report_line(reserved, move_out=out, reservation=True))
unreconciled_outs = []
for out in outs_per_product[product.id]:
+ reserved_availability = outs_reservation[out.id]
# Reconcile with the current stock.
current = currents[out.product_id.id]
reserved = 0.0
- if out.state in ('partially_available', 'assigned'):
- reserved = out.product_uom._compute_quantity(out.reserved_availability, product.uom_id)
+ if not float_is_zero(reserved_availability, precision_rounding=product.uom_id.rounding):
+ reserved = out.product_uom._compute_quantity(reserved_availability, product.uom_id)
demand = out.product_qty - reserved
taken_from_stock = min(demand, current)
if not float_is_zero(taken_from_stock, precision_rounding=product.uom_id.rounding):
diff --git a/addons/web_editor/static/shapes/Blocks/01_001.svg b/addons/web_editor/static/shapes/Blocks/01_001.svg
index a5c6fbb599..37aae25993 100644
--- a/addons/web_editor/static/shapes/Blocks/01_001.svg
+++ b/addons/web_editor/static/shapes/Blocks/01_001.svg
@@ -1,7 +1,7 @@