odoo-addon-rma 16.0.1.3.0__py3-none-any.whl → 16.0.2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,13 @@
1
1
  # Copyright 2020 Tecnativa - Ernesto Tejeda
2
2
  # Copyright 2023 Tecnativa - Pedro M. Baeza
3
+ # Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
3
4
  # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4
5
  import logging
5
- from collections import Counter
6
+ from collections import defaultdict
7
+ from itertools import groupby
6
8
 
7
9
  from odoo import _, api, fields, models
8
10
  from odoo.exceptions import AccessError, ValidationError
9
- from odoo.tests import Form
10
11
  from odoo.tools import html2plaintext
11
12
 
12
13
  from odoo.addons.stock.models.stock_move import PROCUREMENT_PRIORITIES
@@ -317,18 +318,8 @@ class Rma(models.Model):
317
318
  )
318
319
 
319
320
  def _compute_delivery_picking_count(self):
320
- # It is enough to count the moves to know how many pickings
321
- # there are because there will be a unique move linked to the
322
- # same picking and the same rma.
323
- rma_data = self.env["stock.move"].read_group(
324
- [("rma_id", "in", self.ids)],
325
- ["rma_id", "picking_id"],
326
- ["rma_id", "picking_id"],
327
- lazy=False,
328
- )
329
- mapped_data = Counter(map(lambda r: r["rma_id"][0], rma_data))
330
- for record in self:
331
- record.delivery_picking_count = mapped_data.get(record.id, 0)
321
+ for rma in self:
322
+ rma.delivery_picking_count = len(rma.delivery_move_ids.picking_id)
332
323
 
333
324
  @api.depends(
334
325
  "delivery_move_ids",
@@ -670,21 +661,85 @@ class Rma(models.Model):
670
661
  }
671
662
 
672
663
  def _add_message_subscribe_partner(self):
664
+ self.ensure_one()
673
665
  if self.partner_id and self.partner_id not in self.message_partner_ids:
674
666
  self.message_subscribe([self.partner_id.id])
675
667
 
668
+ def _product_is_storable(self, product=None):
669
+ product = product or self.product_id
670
+ return product.type in ["product", "consu"]
671
+
672
+ def _prepare_procurement_group_vals(self):
673
+ return {
674
+ "move_type": "direct",
675
+ "partner_id": self and self.partner_shipping_id.id or False,
676
+ "name": self and ", ".join(self.mapped("name")) or False,
677
+ }
678
+
679
+ def _prepare_common_procurement_vals(
680
+ self, warehouse=None, scheduled_date=None, group=None
681
+ ):
682
+ self.ensure_one()
683
+ group = group or self.procurement_group_id
684
+ if not group:
685
+ group = self.env["procurement.group"].create(
686
+ self._prepare_procurement_group_vals()
687
+ )
688
+ return {
689
+ "company_id": self.company_id,
690
+ "group_id": group,
691
+ "date_planned": scheduled_date or fields.Datetime.now(),
692
+ "warehouse_id": warehouse or self.warehouse_id,
693
+ "partner_id": group.partner_id.id,
694
+ "priority": self.priority,
695
+ }
696
+
697
+ def _prepare_reception_procurement_vals(self, group=None):
698
+ """This method is used only for reception and a specific RMA IN route."""
699
+ vals = self._prepare_common_procurement_vals(group=group)
700
+ vals["route_ids"] = self.warehouse_id.rma_in_route_id
701
+ vals["rma_receiver_ids"] = [(6, 0, self.ids)]
702
+ if self.move_id:
703
+ vals["origin_returned_move_id"] = self.move_id.id
704
+ return vals
705
+
706
+ def _prepare_reception_procurements(self):
707
+ procurements = []
708
+ group_model = self.env["procurement.group"]
709
+ for rma in self:
710
+ if not rma._product_is_storable():
711
+ continue
712
+ group = rma.procurement_group_id
713
+ if not group:
714
+ group = group_model.create(rma._prepare_procurement_group_vals())
715
+ procurements.append(
716
+ group_model.Procurement(
717
+ rma.product_id,
718
+ rma.product_uom_qty,
719
+ rma.product_uom,
720
+ rma.location_id,
721
+ rma.product_id.display_name,
722
+ group.name,
723
+ rma.company_id,
724
+ rma._prepare_reception_procurement_vals(group),
725
+ )
726
+ )
727
+ return procurements
728
+
676
729
  def action_confirm(self):
677
730
  """Invoked when 'Confirm' button in rma form view is clicked."""
678
- self.ensure_one()
679
731
  self._ensure_required_fields()
680
- if self.state == "draft":
681
- if self.picking_id:
682
- reception_move = self._create_receptions_from_picking()
683
- else:
684
- reception_move = self._create_receptions_from_product()
685
- self.write({"reception_move_id": reception_move.id, "state": "confirmed"})
686
- self._add_message_subscribe_partner()
687
- self._send_confirmation_email()
732
+ self = self.filtered(lambda rma: rma.state == "draft")
733
+ if not self:
734
+ return
735
+ procurements = self._prepare_reception_procurements()
736
+ if procurements:
737
+ self.env["procurement.group"].run(procurements)
738
+ self.reception_move_id.picking_id.action_assign()
739
+ self.write({"state": "confirmed"})
740
+ for rma in self:
741
+ rma._add_message_subscribe_partner()
742
+ self._send_confirmation_email()
688
743
 
689
744
  def action_refund(self):
690
745
  """Invoked when 'Refund' button in rma form view is clicked
@@ -723,11 +778,8 @@ class Rma(models.Model):
723
778
  self._ensure_can_be_replaced()
724
779
  # Force active_id to avoid issues when coming from smart buttons
725
780
  # in other models
726
- action = (
727
- self.env.ref("rma.rma_delivery_wizard_action")
728
- .sudo()
729
- .with_context(active_id=self.id)
730
- .read()[0]
781
+ action = self.env["ir.actions.act_window"]._for_xml_id(
782
+ "rma.rma_delivery_wizard_action"
731
783
  )
732
784
  action["name"] = "Replace product(s)"
733
785
  action["context"] = dict(self.env.context)
@@ -746,11 +798,8 @@ class Rma(models.Model):
746
798
  self._ensure_can_be_returned()
747
799
  # Force active_id to avoid issues when coming from smart buttons
748
800
  # in other models
749
- action = (
750
- self.env.ref("rma.rma_delivery_wizard_action")
751
- .sudo()
752
- .with_context(active_id=self.id)
753
- .read()[0]
801
+ action = self.env["ir.actions.act_window"]._for_xml_id(
802
+ "rma.rma_delivery_wizard_action"
754
803
  )
755
804
  action["context"] = dict(self.env.context)
756
805
  action["context"].update(
@@ -766,11 +815,8 @@ class Rma(models.Model):
766
815
  self._ensure_can_be_split()
767
816
  # Force active_id to avoid issues when coming from smart buttons
768
817
  # in other models
769
- action = (
770
- self.env.ref("rma.rma_split_wizard_action")
771
- .sudo()
772
- .with_context(active_id=self.id)
773
- .read()[0]
818
+ action = self.env["ir.actions.act_window"]._for_xml_id(
819
+ "rma.rma_split_wizard_action"
774
820
  )
775
821
  action["context"] = dict(self.env.context)
776
822
  action["context"].update(active_id=self.id, active_ids=self.ids)
@@ -782,11 +828,8 @@ class Rma(models.Model):
782
828
  self._ensure_can_be_returned()
783
829
  # Force active_id to avoid issues when coming from smart buttons
784
830
  # in other models
785
- action = (
786
- self.env.ref("rma.rma_finalization_wizard_action")
787
- .sudo()
788
- .with_context(active_id=self.id)
789
- .read()[0]
831
+ action = self.env["ir.actions.act_window"]._for_xml_id(
832
+ "rma.rma_finalization_wizard_action"
790
833
  )
791
834
  action["context"] = dict(self.env.context)
792
835
  action["context"].update(active_id=self.id, active_ids=self.ids)
@@ -794,7 +837,7 @@ class Rma(models.Model):
794
837
 
795
838
  def action_cancel(self):
796
839
  """Invoked when 'Cancel' button in rma form view is clicked."""
797
- self.mapped("reception_move_id")._action_cancel()
840
+ self.reception_move_id._action_cancel()
798
841
  self.write({"state": "cancelled"})
799
842
 
800
843
  def action_draft(self):
@@ -819,25 +862,28 @@ class Rma(models.Model):
819
862
  "url": self.get_portal_url(),
820
863
  }
821
864
 
822
- def action_view_receipt(self):
823
- """Invoked when 'Receipt' smart button in rma form view is clicked."""
865
+ def _action_view_pickings(self, pickings):
824
866
  self.ensure_one()
825
867
  # Force active_id to avoid issues when coming from smart buttons
826
868
  # in other models
827
- action = (
828
- self.env.ref("stock.action_picking_tree_all")
829
- .sudo()
830
- .with_context(active_id=self.id)
831
- .read()[0]
832
- )
833
- action.update(
834
- res_id=self.reception_move_id.picking_id.id,
835
- view_mode="form",
836
- view_id=False,
837
- views=False,
869
+ action = self.env["ir.actions.act_window"]._for_xml_id(
870
+ "stock.action_picking_tree_all"
838
871
  )
872
+ if len(pickings) > 1:
873
+ action["domain"] = [("id", "in", pickings.ids)]
874
+ elif pickings:
875
+ action.update(
876
+ res_id=pickings.id,
877
+ view_mode="form",
878
+ view_id=False,
879
+ views=False,
880
+ )
839
881
  return action
840
882
 
883
+ def action_view_receipt(self):
884
+ """Invoked when 'Receipt' smart button in rma form view is clicked."""
885
+ return self._action_view_pickings(self.mapped("reception_move_id.picking_id"))
886
+
841
887
  def action_view_refund(self):
842
888
  """Invoked when 'Refund' smart button in rma form view is clicked."""
843
889
  self.ensure_one()
@@ -853,23 +899,7 @@ class Rma(models.Model):
853
899
 
854
900
  def action_view_delivery(self):
855
901
  """Invoked when 'Delivery' smart button in rma form view is clicked."""
856
- action = (
857
- self.env.ref("stock.action_picking_tree_all")
858
- .sudo()
859
- .with_context(active_id=self.id)
860
- .read()[0]
861
- )
862
- picking = self.delivery_move_ids.mapped("picking_id")
863
- if len(picking) > 1:
864
- action["domain"] = [("id", "in", picking.ids)]
865
- elif picking:
866
- action.update(
867
- res_id=picking.id,
868
- view_mode="form",
869
- view_id=False,
870
- views=False,
871
- )
872
- return action
902
+ return self._action_view_pickings(self.mapped("delivery_move_ids.picking_id"))
873
903
 
874
904
  # Validation business methods
875
905
  def _ensure_required_fields(self):
@@ -985,81 +1015,6 @@ class Rma(models.Model):
985
1015
  )
986
1016
  )
987
1017
 
988
- # Reception business methods
989
- def _create_receptions_from_picking(self):
990
- self.ensure_one()
991
- stock_return_picking_form = Form(
992
- self.env["stock.return.picking"].with_context(
993
- active_ids=self.picking_id.ids,
994
- active_id=self.picking_id.id,
995
- active_model="stock.picking",
996
- )
997
- )
998
- return_wizard = stock_return_picking_form.save()
999
- if self.location_id:
1000
- return_wizard.location_id = self.location_id
1001
- return_wizard.product_return_moves.filtered(
1002
- lambda r: r.move_id != self.move_id
1003
- ).unlink()
1004
- return_line = return_wizard.product_return_moves
1005
- return_line.update(
1006
- {
1007
- "quantity": self.product_uom_qty,
1008
- # The to_refund field is now True by default, which isn't right in the
1009
- # RMA creation context
1010
- "to_refund": False,
1011
- }
1012
- )
1013
- # set_rma_picking_type is to override the copy() method of stock
1014
- # picking and change the default picking type to rma picking type.
1015
- picking_action = return_wizard.with_context(
1016
- set_rma_picking_type=True
1017
- ).create_returns()
1018
- picking_id = picking_action["res_id"]
1019
- picking = self.env["stock.picking"].browse(picking_id)
1020
- picking.origin = "{} ({})".format(self.name, picking.origin)
1021
- move = picking.move_ids
1022
- move.priority = self.priority
1023
- return move
1024
-
1025
- def _create_receptions_from_product(self):
1026
- self.ensure_one()
1027
- picking = self.env["stock.picking"].create(self._prepare_picking_vals())
1028
- picking.action_confirm()
1029
- picking.action_assign()
1030
- picking.message_post_with_view(
1031
- "mail.message_origin_link",
1032
- values={"self": picking, "origin": self},
1033
- subtype_id=self.env.ref("mail.mt_note").id,
1034
- )
1035
- return picking.move_ids
1036
-
1037
- def _prepare_picking_vals(self):
1038
- return {
1039
- "picking_type_id": self.warehouse_id.rma_in_type_id.id,
1040
- "origin": self.name,
1041
- "partner_id": self.partner_shipping_id.id,
1042
- "location_id": self.partner_shipping_id.property_stock_customer.id,
1043
- "location_dest_id": self.location_id.id,
1044
- "move_ids": [
1045
- (
1046
- 0,
1047
- 0,
1048
- {
1049
- "product_id": self.product_id.id,
1050
- # same text as origin move or product text in partner lang
1051
- "name": self.move_id.name
1052
- or self.product_id.with_context(
1053
- lang=self.partner_id.lang or "en_US"
1054
- ).display_name,
1055
- "location_id": self.partner_shipping_id.property_stock_customer.id,
1056
- "location_dest_id": self.location_id.id,
1057
- "product_uom_qty": self.product_uom_qty,
1058
- },
1059
- )
1060
- ],
1061
- }
1062
-
1063
1018
  # Extract business methods
1064
1019
  def extract_quantity(self, qty, uom):
1065
1020
  self.ensure_one()
@@ -1133,44 +1088,100 @@ class Rma(models.Model):
1133
1088
  "rma_id": self.id,
1134
1089
  }
1135
1090
 
1136
- # Returning business methods
1137
- def create_return(self, scheduled_date, qty=None, uom=None):
1138
- """Intended to be invoked by the delivery wizard"""
1091
+ def _delivery_should_be_grouped(self):
1092
+ """Checks if the rmas should be grouped for the delivery process"""
1139
1093
  group_returns = self.env.company.rma_return_grouping
1140
1094
  if "rma_return_grouping" in self.env.context:
1141
1095
  group_returns = self.env.context.get("rma_return_grouping")
1142
- self._ensure_can_be_returned()
1143
- self._ensure_qty_to_return(qty, uom)
1144
- group_dict = {}
1145
- rmas_to_return = self.filtered("can_be_returned")
1146
- for record in rmas_to_return:
1147
- key = (
1148
- record.partner_shipping_id.id,
1149
- record.company_id.id,
1150
- record.warehouse_id,
1096
+ return group_returns
1097
+
1098
+ def _delivery_group_key(self):
1099
+ """Returns a key by which the rmas should be grouped for the delivery process"""
1100
+ self.ensure_one()
1101
+ return (self.partner_shipping_id.id, self.company_id.id, self.warehouse_id.id)
1102
+
1103
+ def _group_delivery_if_needed(self):
1104
+ """Groups the given rmas by the returned key from _delivery_group_key
1105
+ by setting the procurement_group_id on the each rma if there is not yet on set"""
1106
+ if not self._delivery_should_be_grouped():
1107
+ return
1108
+ grouped_rmas = groupby(
1109
+ sorted(self, key=lambda rma: rma._delivery_group_key()),
1110
+ key=lambda rma: [rma._delivery_group_key()],
1111
+ )
1112
+ for _group, rmas in grouped_rmas:
1113
+ rmas = (
1114
+ self.browse()
1115
+ .concat(*list(rmas))
1116
+ .filtered(lambda rma: not rma.procurement_group_id)
1151
1117
  )
1152
- group_dict.setdefault(key, self.env["rma"])
1153
- group_dict[key] |= record
1154
- if group_returns:
1155
- grouped_rmas = group_dict.values()
1156
- else:
1157
- grouped_rmas = rmas_to_return
1158
- for rmas in grouped_rmas:
1159
- origin = ", ".join(rmas.mapped("name"))
1160
- picking_vals = rmas[0]._prepare_returning_picking_vals(origin)
1161
- for rma in rmas:
1162
- picking_vals["move_ids"].append(
1163
- (0, 0, rma._prepare_returning_move_vals(scheduled_date, qty, uom))
1118
+ if not rmas:
1119
+ continue
1120
+ proc_group = self.env["procurement.group"].create(
1121
+ rmas._prepare_procurement_group_vals()
1122
+ )
1123
+ rmas.write({"procurement_group_id": proc_group.id})
1124
+
1125
+ def _prepare_delivery_procurement_vals(self, scheduled_date=None):
1126
+ """This method is used only for Delivery (not replace). It is important to set
1127
+ RMA Out route."""
1128
+ vals = self._prepare_common_procurement_vals(scheduled_date=scheduled_date)
1129
+ vals["rma_id"] = self.id
1130
+ vals["route_ids"] = self.warehouse_id.rma_out_route_id
1131
+ vals["move_orig_ids"] = [(6, 0, self.reception_move_id.ids)]
1132
+ return vals
1133
+
1134
+ def _prepare_delivery_procurements(self, scheduled_date=None, qty=None, uom=None):
1135
+ self._group_delivery_if_needed()
1136
+ procurements = []
1137
+ group_model = self.env["procurement.group"]
1138
+ for rma in self:
1139
+ if not rma.procurement_group_id:
1140
+ rma.procurement_group_id = group_model.create(
1141
+ rma._prepare_procurement_group_vals()
1164
1142
  )
1165
- picking = self.env["stock.picking"].create(picking_vals)
1166
- for rma in rmas:
1167
- rma.message_post(
1168
- body=_(
1169
- 'Return: <a href="#" data-oe-model="stock.picking" '
1170
- 'data-oe-id="%(id)d">%(name)s</a> has been created.'
1171
- )
1172
- % ({"id": picking.id, "name": picking.name})
1143
+
1144
+ vals = rma._prepare_delivery_procurement_vals(scheduled_date)
1145
+ group = vals.get("group_id")
1146
+ procurements.append(
1147
+ group_model.Procurement(
1148
+ rma.product_id,
1149
+ qty or rma.product_uom_qty,
1150
+ uom or rma.product_uom,
1151
+ rma.partner_shipping_id.property_stock_customer,
1152
+ rma.product_id.display_name,
1153
+ group.name,
1154
+ rma.company_id,
1155
+ vals,
1173
1156
  )
1157
+ )
1158
+ return procurements
1159
+
1160
+ # Returning business methods
1161
+ def create_return(self, scheduled_date, qty=None, uom=None):
1162
+ """Intended to be invoked by the delivery wizard"""
1163
+ self._ensure_can_be_returned()
1164
+ self._ensure_qty_to_return(qty, uom)
1165
+ rmas_to_return = self.filtered(
1166
+ lambda rma: rma.can_be_returned and rma._product_is_storable()
1167
+ )
1168
+ procurements = rmas_to_return._prepare_delivery_procurements(
1169
+ scheduled_date, qty, uom
1170
+ )
1171
+ if procurements:
1172
+ self.env["procurement.group"].run(procurements)
1173
+ pickings = defaultdict(lambda: self.browse())
1174
+ for rma in rmas_to_return:
1175
+ picking = rma.delivery_move_ids.picking_id.sorted("id", reverse=True)[0]
1176
+ pickings[picking] |= rma
1177
+ rma.message_post(
1178
+ body=_(
1179
+ 'Return: <a href="#" data-oe-model="stock.picking" '
1180
+ 'data-oe-id="%(id)d">%(name)s</a> has been created.'
1181
+ )
1182
+ % ({"id": picking.id, "name": picking.name})
1183
+ )
1184
+ for picking, rmas in pickings.items():
1174
1185
  picking.action_confirm()
1175
1186
  picking.action_assign()
1176
1187
  picking.message_post_with_view(
@@ -1180,42 +1191,53 @@ class Rma(models.Model):
1180
1191
  )
1181
1192
  rmas_to_return.write({"state": "waiting_return"})
1182
1193
 
1183
- def _prepare_returning_picking_vals(self, origin=None):
1184
- self.ensure_one()
1185
- return {
1186
- "picking_type_id": self.warehouse_id.rma_out_type_id.id,
1187
- "location_id": self.location_id.id,
1188
- "location_dest_id": self.reception_move_id.location_id.id,
1189
- "origin": origin or self.name,
1190
- "partner_id": self.partner_shipping_id.id,
1191
- "company_id": self.company_id.id,
1192
- "move_ids": [],
1193
- }
1194
+ def _prepare_replace_procurement_vals(self, warehouse=None, scheduled_date=None):
1195
+ """This method is used only for Replace (not Delivery). We do not use any
1196
+ specific route here."""
1197
+ vals = self._prepare_common_procurement_vals(warehouse, scheduled_date)
1198
+ vals["rma_id"] = self.id
1199
+ return vals
1194
1200
 
1195
- def _prepare_returning_move_vals(self, scheduled_date, quantity=None, uom=None):
1196
- self.ensure_one()
1197
- return {
1198
- "product_id": self.product_id.id,
1199
- "name": self.product_id.with_context(
1200
- lang=self.partner_shipping_id.lang or "en_US"
1201
- ).display_name,
1202
- "product_uom_qty": quantity or self.product_uom_qty,
1203
- "product_uom": uom and uom.id or self.product_uom.id,
1204
- "location_id": self.location_id.id,
1205
- "location_dest_id": self.reception_move_id.location_id.id,
1206
- "date": scheduled_date,
1207
- "rma_id": self.id,
1208
- "move_orig_ids": [(4, self.reception_move_id.id)],
1209
- "company_id": self.company_id.id,
1210
- }
1201
+ def _prepare_replace_procurements(
1202
+ self, warehouse, scheduled_date, product, qty, uom
1203
+ ):
1204
+ procurements = []
1205
+ group_model = self.env["procurement.group"]
1206
+ for rma in self:
1207
+ if not rma._product_is_storable(product):
1208
+ continue
1209
+
1210
+ if not rma.procurement_group_id:
1211
+ rma.procurement_group_id = group_model.create(
1212
+ rma._prepare_procurement_group_vals()
1213
+ )
1214
+
1215
+ vals = rma._prepare_replace_procurement_vals(warehouse, scheduled_date)
1216
+ group = vals.get("group_id")
1217
+ procurements.append(
1218
+ group_model.Procurement(
1219
+ product,
1220
+ qty,
1221
+ uom,
1222
+ rma.partner_shipping_id.property_stock_customer,
1223
+ product.display_name,
1224
+ group.name,
1225
+ rma.company_id,
1226
+ vals,
1227
+ )
1228
+ )
1229
+ return procurements
1211
1230
 
1212
1231
  # Replacing business methods
1213
1232
  def create_replace(self, scheduled_date, warehouse, product, qty, uom):
1214
1233
  """Intended to be invoked by the delivery wizard"""
1215
- self.ensure_one()
1216
1234
  self._ensure_can_be_replaced()
1217
1235
  moves_before = self.delivery_move_ids
1218
- self._action_launch_stock_rule(scheduled_date, warehouse, product, qty, uom)
1236
+ procurements = self._prepare_replace_procurements(
1237
+ warehouse, scheduled_date, product, qty, uom
1238
+ )
1239
+ if procurements:
1240
+ self.env["procurement.group"].run(procurements)
1219
1241
  new_moves = self.delivery_move_ids - moves_before
1220
1242
  body = ""
1221
1243
  # The product replacement could explode into several moves like in the case of
@@ -1239,6 +1261,12 @@ class Rma(models.Model):
1239
1261
  )
1240
1262
  + "\n"
1241
1263
  )
1264
+ for rma in self:
1265
+ rma._add_replace_message(body, qty, uom)
1266
+ self.write({"state": "waiting_replacement"})
1267
+
1268
+ def _add_replace_message(self, body, qty, uom):
1269
+ self.ensure_one()
1242
1270
  self.message_post(
1243
1271
  body=body
1244
1272
  or _(
@@ -1251,74 +1279,13 @@ class Rma(models.Model):
1251
1279
  )
1252
1280
  % (
1253
1281
  {
1254
- "id": product.id,
1255
- "name": product.display_name,
1282
+ "id": self.id,
1283
+ "name": self.display_name,
1256
1284
  "qty": qty,
1257
1285
  "uom": uom.name,
1258
1286
  }
1259
1287
  )
1260
1288
  )
1261
- if self.state != "waiting_replacement":
1262
- self.state = "waiting_replacement"
1263
-
1264
- def _action_launch_stock_rule(
1265
- self,
1266
- scheduled_date,
1267
- warehouse,
1268
- product,
1269
- qty,
1270
- uom,
1271
- ):
1272
- """Creates a delivery picking and launch stock rule. It is invoked by:
1273
- rma.create_replace
1274
- """
1275
- self.ensure_one()
1276
- if self.product_id.type not in ("consu", "product"):
1277
- return
1278
- if not self.procurement_group_id:
1279
- self.procurement_group_id = (
1280
- self.env["procurement.group"]
1281
- .create(
1282
- {
1283
- "name": self.name,
1284
- "move_type": "direct",
1285
- "partner_id": self.partner_shipping_id.id,
1286
- }
1287
- )
1288
- .id
1289
- )
1290
- values = self._prepare_procurement_values(
1291
- self.procurement_group_id, scheduled_date, warehouse
1292
- )
1293
- procurement = self.env["procurement.group"].Procurement(
1294
- product,
1295
- qty,
1296
- uom,
1297
- self.partner_shipping_id.property_stock_customer,
1298
- self.product_id.display_name,
1299
- self.procurement_group_id.name,
1300
- self.company_id,
1301
- values,
1302
- )
1303
- self.env["procurement.group"].run([procurement])
1304
- return True
1305
-
1306
- def _prepare_procurement_values(
1307
- self,
1308
- group_id,
1309
- scheduled_date,
1310
- warehouse,
1311
- ):
1312
- self.ensure_one()
1313
- return {
1314
- "company_id": self.company_id,
1315
- "group_id": group_id,
1316
- "date_planned": scheduled_date,
1317
- "warehouse_id": warehouse,
1318
- "partner_id": self.partner_shipping_id.id,
1319
- "rma_id": self.id,
1320
- "priority": self.priority,
1321
- }
1322
1289
 
1323
1290
  # Mail business methods
1324
1291
  def _creation_subtype(self):