diff --git a/addons/mrp/i18n/mrp.pot b/addons/mrp/i18n/mrp.pot
index 3b0b060b657124618dc111f7f5ae27c9fd931bbd..cf28e088bd746e7a312667ceba028685ceb983b2 100644
--- a/addons/mrp/i18n/mrp.pot
+++ b/addons/mrp/i18n/mrp.pot
@@ -3707,6 +3707,12 @@ msgstr ""
 msgid "Sequence stock after manufacturing"
 msgstr ""
 
+#. module: mrp
+#: code:addons/mrp/models/mrp_production.py:0
+#, python-format
+msgid "Serial number (%s) has already been produced."
+msgstr ""
+
 #. module: mrp
 #: model:ir.model.fields.selection,name:mrp.selection__mrp_routing_workcenter__time_mode__manual
 msgid "Set duration manually"
diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py
index 5b17ba3f1630b156b6d32496a9b59cde897e2103..c3c1b83d7d96d5fdb358cfbeb4010eef8104910b 100644
--- a/addons/mrp/models/mrp_production.py
+++ b/addons/mrp/models/mrp_production.py
@@ -693,20 +693,28 @@ class MrpProduction(models.Model):
 
     @api.onchange('lot_producing_id')
     def _onchange_lot_producing(self):
-        if self.product_id.tracking == 'serial':
+        res = self._can_produce_serial_number()
+        if res is not True:
+            return res
+
+    def _can_produce_serial_number(self, sn=None):
+        self.ensure_one()
+        sn = sn or self.lot_producing_id
+        if self.product_id.tracking == 'serial' and sn:
             if self.env['stock.move.line'].search([
-                ('lot_id', '=', self.lot_producing_id.id),
+                ('lot_id', '=', sn.id),
                 ('qty_done', '=', 1),
                 ('state', '=', 'done'),
                 ('location_id.usage', '!=', 'production'),
                 ('location_dest_id.usage', '!=', 'production'),
-            ], limit=1) or self._is_finished_sn_already_produced(self.lot_producing_id):
+            ], limit=1) or self._is_finished_sn_already_produced(sn):
                 return {
                     'warning': {
                         'title': _('Warning'),
-                        'message': _('Existing Serial number (%s). Please correct the serial numbers encoded.') % self.lot_producing_id.name
+                        'message': _('Serial number (%s) has already been produced.') % sn.name,
                     }
                 }
+        return True
 
     @api.onchange('bom_id')
     def _onchange_workorder_ids(self):
diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py
index 06146fc8bb810082c21a40fe8ad5b7dd54dd136c..44cdd91e62b774e2fee634ef9f1e9e8a46abf8e6 100644
--- a/addons/mrp/models/mrp_workorder.py
+++ b/addons/mrp/models/mrp_workorder.py
@@ -407,6 +407,12 @@ class MrpWorkorder(models.Model):
     def _onchange_expected_duration(self):
         self.duration_expected = self._get_duration_expected()
 
+    @api.onchange('finished_lot_id')
+    def _onchange_finished_lot_id(self):
+        res = self.production_id._can_produce_serial_number(sn=self.finished_lot_id)
+        if res is not True:
+            return res
+
     def write(self, values):
         if 'production_id' in values:
             raise UserError(_('You cannot link this work order to another manufacturing order.'))
@@ -847,16 +853,8 @@ class MrpWorkorder(models.Model):
             )
 
     def _check_sn_uniqueness(self):
-        """ Alert the user if the serial number as already been produced """
-        if self.product_tracking == 'serial' and self.finished_lot_id:
-            sml = self.env['stock.move.line'].search_count([
-                ('lot_id', '=', self.finished_lot_id.id),
-                ('location_id.usage', '=', 'production'),
-                ('qty_done', '=', 1),
-                ('state', '=', 'done')
-            ])
-            if sml:
-                raise UserError(_('This serial number for product %s has already been produced', self.product_id.name))
+        # todo master: remove
+        pass
 
     def _update_qty_producing(self, quantity):
         self.ensure_one()