odoo-addon-rma 16.0.1.2.0.1__py3-none-any.whl → 17.0.1.0.0.2__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.
Files changed (34) hide show
  1. odoo/addons/rma/README.rst +87 -78
  2. odoo/addons/rma/__manifest__.py +1 -1
  3. odoo/addons/rma/controllers/main.py +2 -1
  4. odoo/addons/rma/data/mail_data.xml +3 -6
  5. odoo/addons/rma/hooks.py +1 -5
  6. odoo/addons/rma/i18n/it.po +2 -2
  7. odoo/addons/rma/i18n/rma.pot +49 -81
  8. odoo/addons/rma/models/rma.py +51 -112
  9. odoo/addons/rma/models/stock_move.py +1 -1
  10. odoo/addons/rma/readme/CONFIGURE.md +22 -0
  11. odoo/addons/rma/readme/CONTRIBUTORS.md +9 -0
  12. odoo/addons/rma/readme/{DESCRIPTION.rst → DESCRIPTION.md} +4 -4
  13. odoo/addons/rma/readme/ROADMAP.md +3 -0
  14. odoo/addons/rma/readme/USAGE.md +59 -0
  15. odoo/addons/rma/static/description/index.html +55 -46
  16. odoo/addons/rma/tests/test_rma.py +21 -37
  17. odoo/addons/rma/views/res_config_settings_views.xml +55 -124
  18. odoo/addons/rma/views/res_partner_views.xml +1 -1
  19. odoo/addons/rma/views/rma_finalization_views.xml +1 -1
  20. odoo/addons/rma/views/rma_team_views.xml +2 -6
  21. odoo/addons/rma/views/rma_views.xml +71 -39
  22. odoo/addons/rma/views/stock_picking_views.xml +1 -1
  23. odoo/addons/rma/wizard/rma_delivery_views.xml +8 -19
  24. odoo/addons/rma/wizard/stock_picking_return_views.xml +1 -1
  25. odoo_addon_rma-17.0.1.0.0.2.dist-info/METADATA +220 -0
  26. {odoo_addon_rma-16.0.1.2.0.1.dist-info → odoo_addon_rma-17.0.1.0.0.2.dist-info}/RECORD +28 -28
  27. {odoo_addon_rma-16.0.1.2.0.1.dist-info → odoo_addon_rma-17.0.1.0.0.2.dist-info}/WHEEL +1 -1
  28. odoo_addon_rma-17.0.1.0.0.2.dist-info/top_level.txt +1 -0
  29. odoo/addons/rma/readme/CONFIGURE.rst +0 -21
  30. odoo/addons/rma/readme/CONTRIBUTORS.rst +0 -9
  31. odoo/addons/rma/readme/ROADMAP.rst +0 -3
  32. odoo/addons/rma/readme/USAGE.rst +0 -57
  33. odoo_addon_rma-16.0.1.2.0.1.dist-info/METADATA +0 -214
  34. odoo_addon_rma-16.0.1.2.0.1.dist-info/top_level.txt +0 -1
@@ -35,60 +35,37 @@ class Rma(models.Model):
35
35
  sent = fields.Boolean()
36
36
  name = fields.Char(
37
37
  index=True,
38
- readonly=True,
39
- states={"draft": [("readonly", False)]},
40
38
  copy=False,
41
39
  default=lambda self: _("New"),
42
40
  )
43
41
  origin = fields.Char(
44
42
  string="Source Document",
45
- states={
46
- "locked": [("readonly", True)],
47
- "cancelled": [("readonly", True)],
48
- },
49
43
  help="Reference of the document that generated this RMA.",
50
44
  )
51
45
  date = fields.Datetime(
52
46
  default=fields.Datetime.now,
53
47
  index=True,
54
48
  required=True,
55
- readonly=True,
56
- states={"draft": [("readonly", False)]},
57
- )
58
- deadline = fields.Date(
59
- states={
60
- "locked": [("readonly", True)],
61
- "cancelled": [("readonly", True)],
62
- },
63
49
  )
50
+ deadline = fields.Date()
64
51
  user_id = fields.Many2one(
65
52
  comodel_name="res.users",
66
53
  string="Responsible",
67
54
  index=True,
68
55
  tracking=True,
69
- states={
70
- "locked": [("readonly", True)],
71
- "cancelled": [("readonly", True)],
72
- },
73
56
  )
74
57
  team_id = fields.Many2one(
75
58
  comodel_name="rma.team",
76
59
  string="RMA team",
77
60
  index=True,
78
- states={
79
- "locked": [("readonly", True)],
80
- "cancelled": [("readonly", True)],
81
- },
82
61
  compute="_compute_team_id",
83
62
  store=True,
84
- readonly=False,
85
63
  )
86
64
  tag_ids = fields.Many2many(comodel_name="rma.tag", string="Tags")
87
65
  finalization_id = fields.Many2one(
88
66
  string="Finalization Reason",
89
67
  comodel_name="rma.finalization",
90
68
  copy=False,
91
- readonly=True,
92
69
  domain=(
93
70
  "['|', ('company_id', '=', False), ('company_id', '='," " company_id)]"
94
71
  ),
@@ -97,16 +74,10 @@ class Rma(models.Model):
97
74
  company_id = fields.Many2one(
98
75
  comodel_name="res.company",
99
76
  default=lambda self: self.env.company,
100
- states={
101
- "locked": [("readonly", True)],
102
- "cancelled": [("readonly", True)],
103
- },
104
77
  )
105
78
  partner_id = fields.Many2one(
106
79
  string="Customer",
107
80
  comodel_name="res.partner",
108
- readonly=True,
109
- states={"draft": [("readonly", False)]},
110
81
  index=True,
111
82
  tracking=True,
112
83
  )
@@ -143,8 +114,6 @@ class Rma(models.Model):
143
114
  " ('partner_id', 'child_of', commercial_partner_id),"
144
115
  "]"
145
116
  ),
146
- readonly=True,
147
- states={"draft": [("readonly", False)]},
148
117
  )
149
118
  move_id = fields.Many2one(
150
119
  comodel_name="stock.move",
@@ -187,18 +156,10 @@ class Rma(models.Model):
187
156
  procurement_group_id = fields.Many2one(
188
157
  comodel_name="procurement.group",
189
158
  string="Procurement group",
190
- readonly=True,
191
- states={
192
- "draft": [("readonly", False)],
193
- "confirmed": [("readonly", False)],
194
- "received": [("readonly", False)],
195
- },
196
159
  )
197
160
  priority = fields.Selection(
198
161
  selection=PROCUREMENT_PRIORITIES,
199
162
  default="1",
200
- readonly=True,
201
- states={"draft": [("readonly", False)]},
202
163
  )
203
164
  operation_id = fields.Many2one(
204
165
  comodel_name="rma.operation",
@@ -222,12 +183,7 @@ class Rma(models.Model):
222
183
  copy=False,
223
184
  tracking=True,
224
185
  )
225
- description = fields.Html(
226
- states={
227
- "locked": [("readonly", True)],
228
- "cancelled": [("readonly", True)],
229
- },
230
- )
186
+ description = fields.Html()
231
187
  # Reception fields
232
188
  location_id = fields.Many2one(
233
189
  comodel_name="stock.location",
@@ -249,12 +205,10 @@ class Rma(models.Model):
249
205
  # Refund fields
250
206
  refund_id = fields.Many2one(
251
207
  comodel_name="account.move",
252
- readonly=True,
253
208
  copy=False,
254
209
  )
255
210
  refund_line_id = fields.Many2one(
256
211
  comodel_name="account.move.line",
257
- readonly=True,
258
212
  copy=False,
259
213
  )
260
214
  can_be_refunded = fields.Boolean(compute="_compute_can_be_refunded")
@@ -263,7 +217,6 @@ class Rma(models.Model):
263
217
  comodel_name="stock.move",
264
218
  inverse_name="rma_id",
265
219
  string="Delivery reservation",
266
- readonly=True,
267
220
  copy=False,
268
221
  )
269
222
  delivery_picking_count = fields.Integer(
@@ -275,11 +228,6 @@ class Rma(models.Model):
275
228
  compute="_compute_delivered_qty",
276
229
  store=True,
277
230
  )
278
- delivered_qty_done = fields.Float(
279
- digits="Product Unit of Measure",
280
- compute="_compute_delivered_qty",
281
- compute_sudo=True,
282
- )
283
231
  can_be_returned = fields.Boolean(
284
232
  compute="_compute_can_be_returned",
285
233
  )
@@ -297,11 +245,6 @@ class Rma(models.Model):
297
245
  digits="Product Unit of Measure",
298
246
  compute="_compute_remaining_qty",
299
247
  )
300
- remaining_qty_to_done = fields.Float(
301
- string="Remaining delivered qty to done",
302
- digits="Product Unit of Measure",
303
- compute="_compute_remaining_qty",
304
- )
305
248
  uom_category_id = fields.Many2one(
306
249
  related="product_id.uom_id.category_id", string="Category UoM"
307
250
  )
@@ -312,7 +255,6 @@ class Rma(models.Model):
312
255
  origin_split_rma_id = fields.Many2one(
313
256
  comodel_name="rma",
314
257
  string="Extracted from",
315
- readonly=True,
316
258
  copy=False,
317
259
  )
318
260
 
@@ -335,8 +277,7 @@ class Rma(models.Model):
335
277
  "delivery_move_ids.state",
336
278
  "delivery_move_ids.scrapped",
337
279
  "delivery_move_ids.product_uom_qty",
338
- "delivery_move_ids.reserved_availability",
339
- "delivery_move_ids.quantity_done",
280
+ "delivery_move_ids.quantity",
340
281
  "delivery_move_ids.product_uom",
341
282
  "product_uom",
342
283
  )
@@ -355,29 +296,21 @@ class Rma(models.Model):
355
296
  """
356
297
  for record in self:
357
298
  delivered_qty = 0.0
358
- delivered_qty_done = 0.0
359
299
  for move in record.delivery_move_ids.filtered(
360
300
  lambda r: r.state != "cancel" and not r.scrapped
361
301
  ):
362
- if move.quantity_done:
363
- quantity_done = move.product_uom._compute_quantity(
364
- move.quantity_done, record.product_uom
365
- )
366
- if move.state == "done":
367
- delivered_qty_done += quantity_done
368
- delivered_qty += quantity_done
369
- elif move.reserved_availability:
370
- delivered_qty += move.product_uom._compute_quantity(
371
- move.reserved_availability, record.product_uom
302
+ if move.quantity:
303
+ quantity = move.product_uom._compute_quantity(
304
+ move.quantity, record.product_uom
372
305
  )
306
+ delivered_qty += quantity
373
307
  elif move.product_uom_qty:
374
308
  delivered_qty += move.product_uom._compute_quantity(
375
309
  move.product_uom_qty, record.product_uom
376
310
  )
377
311
  record.delivered_qty = delivered_qty
378
- record.delivered_qty_done = delivered_qty_done
379
312
 
380
- @api.depends("product_uom_qty", "delivered_qty", "delivered_qty_done")
313
+ @api.depends("product_uom_qty", "delivered_qty")
381
314
  def _compute_remaining_qty(self):
382
315
  """Compute 'remaining_qty' and 'remaining_qty_to_done' fields.
383
316
 
@@ -392,7 +325,6 @@ class Rma(models.Model):
392
325
  """
393
326
  for r in self:
394
327
  r.remaining_qty = r.product_uom_qty - r.delivered_qty
395
- r.remaining_qty_to_done = r.product_uom_qty - r.delivered_qty_done
396
328
 
397
329
  @api.depends(
398
330
  "state",
@@ -443,7 +375,7 @@ class Rma(models.Model):
443
375
  and rma.remaining_qty > 0
444
376
  )
445
377
 
446
- @api.depends("product_uom_qty", "state", "remaining_qty", "remaining_qty_to_done")
378
+ @api.depends("product_uom_qty", "state", "remaining_qty")
447
379
  def _compute_can_be_split(self):
448
380
  """Compute 'can_be_split'. This field controls the
449
381
  visibility of 'Split' button in the rma form view and
@@ -460,10 +392,10 @@ class Rma(models.Model):
460
392
  else:
461
393
  r.can_be_split = False
462
394
 
463
- @api.depends("remaining_qty_to_done", "state")
395
+ @api.depends("state")
464
396
  def _compute_can_be_locked(self):
465
397
  for r in self:
466
- r.can_be_locked = r.remaining_qty_to_done > 0 and r.state in [
398
+ r.can_be_locked = r.remaining_qty > 0 and r.state in [
467
399
  "received",
468
400
  "waiting_return",
469
401
  "waiting_replacement",
@@ -555,7 +487,7 @@ class Rma(models.Model):
555
487
 
556
488
  def _compute_access_url(self):
557
489
  for record in self:
558
- record.access_url = "/my/rmas/{}".format(record.id)
490
+ record.access_url = f"/my/rmas/{record.id}"
559
491
 
560
492
  # Constrains methods (@api.constrains)
561
493
  @api.constrains(
@@ -612,34 +544,41 @@ class Rma(models.Model):
612
544
  def _send_draft_email(self):
613
545
  """Send customer notifications they place the RMA from the portal"""
614
546
  for rma in self.filtered("company_id.send_rma_draft_confirmation"):
615
- rma_template_id = rma.company_id.rma_mail_draft_confirmation_template_id.id
616
547
  rma.with_context(
617
548
  force_send=True,
618
549
  mark_rma_as_sent=True,
619
- default_subtype_id=self.env.ref("rma.mt_rma_notification").id,
620
- ).message_post_with_template(rma_template_id)
550
+ ).message_post_with_source(
551
+ rma.company_id.rma_mail_draft_confirmation_template_id.get_external_id()[
552
+ rma.company_id.rma_mail_draft_confirmation_template_id.id
553
+ ],
554
+ subtype_xmlid="rma.mt_rma_notification",
555
+ )
621
556
 
622
557
  def _send_confirmation_email(self):
623
558
  """Auto send notifications"""
624
559
  for rma in self.filtered(lambda p: p.company_id.send_rma_confirmation):
625
- rma_template_id = rma.company_id.rma_mail_confirmation_template_id.id
626
560
  rma.with_context(
627
561
  force_send=True,
628
562
  mark_rma_as_sent=True,
629
- default_subtype_id=self.env.ref("rma.mt_rma_notification").id,
630
- ).message_post_with_template(rma_template_id)
563
+ ).message_post_with_source(
564
+ rma.company_id.rma_mail_confirmation_template_id.get_external_id()[
565
+ rma.company_id.rma_mail_confirmation_template_id.id
566
+ ],
567
+ subtype_xmlid="rma.mt_rma_notification",
568
+ )
631
569
 
632
570
  def _send_receipt_confirmation_email(self):
633
571
  """Send customer notifications when the products are received"""
634
572
  for rma in self.filtered("company_id.send_rma_receipt_confirmation"):
635
- rma_template_id = (
636
- rma.company_id.rma_mail_receipt_confirmation_template_id.id
637
- )
638
573
  rma.with_context(
639
574
  force_send=True,
640
575
  mark_rma_as_sent=True,
641
- default_subtype_id=self.env.ref("rma.mt_rma_notification").id,
642
- ).message_post_with_template(rma_template_id)
576
+ ).message_post_with_source(
577
+ rma.company_id.rma_mail_receipt_confirmation_template_id.get_external_id()[
578
+ rma.company_id.rma_mail_receipt_confirmation_template_id.id
579
+ ],
580
+ subtype_xmlid="rma.mt_rma_notification",
581
+ )
643
582
 
644
583
  # Action methods
645
584
  def action_rma_send(self):
@@ -682,6 +621,7 @@ class Rma(models.Model):
682
621
  reception_move = self._create_receptions_from_picking()
683
622
  else:
684
623
  reception_move = self._create_receptions_from_product()
624
+ reception_move.picked = True
685
625
  self.write({"reception_move_id": reception_move.id, "state": "confirmed"})
686
626
  self._add_message_subscribe_partner()
687
627
  self._send_confirmation_email()
@@ -703,10 +643,10 @@ class Rma(models.Model):
703
643
  (0, 0, rma._prepare_refund_line_vals())
704
644
  )
705
645
  refund = self.env["account.move"].sudo().create(refund_vals)
706
- refund.with_user(self.env.uid).message_post_with_view(
646
+ refund.with_user(self.env.uid).message_post_with_source(
707
647
  "mail.message_origin_link",
708
- values={"self": refund, "origin": rmas},
709
- subtype_id=self.env.ref("mail.mt_note").id,
648
+ render_values={"self": refund, "origin": rmas},
649
+ subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
710
650
  )
711
651
  for line in refund.invoice_line_ids:
712
652
  line.rma_id.write(
@@ -1017,7 +957,7 @@ class Rma(models.Model):
1017
957
  ).create_returns()
1018
958
  picking_id = picking_action["res_id"]
1019
959
  picking = self.env["stock.picking"].browse(picking_id)
1020
- picking.origin = "{} ({})".format(self.name, picking.origin)
960
+ picking.origin = f"{self.name} ({picking.origin})"
1021
961
  move = picking.move_ids
1022
962
  move.priority = self.priority
1023
963
  return move
@@ -1027,10 +967,10 @@ class Rma(models.Model):
1027
967
  picking = self.env["stock.picking"].create(self._prepare_picking_vals())
1028
968
  picking.action_confirm()
1029
969
  picking.action_assign()
1030
- picking.message_post_with_view(
970
+ picking.message_post_with_source(
1031
971
  "mail.message_origin_link",
1032
- values={"self": picking, "origin": self},
1033
- subtype_id=self.env.ref("mail.mt_note").id,
972
+ render_values={"self": picking, "origin": self},
973
+ subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
1034
974
  )
1035
975
  return picking.move_ids
1036
976
 
@@ -1052,7 +992,9 @@ class Rma(models.Model):
1052
992
  or self.product_id.with_context(
1053
993
  lang=self.partner_id.lang or "en_US"
1054
994
  ).display_name,
1055
- "location_id": self.partner_shipping_id.property_stock_customer.id,
995
+ "location_id": (
996
+ self.partner_shipping_id.property_stock_customer.id
997
+ ),
1056
998
  "location_dest_id": self.location_id.id,
1057
999
  "product_uom_qty": self.product_uom_qty,
1058
1000
  },
@@ -1066,7 +1008,7 @@ class Rma(models.Model):
1066
1008
  self._ensure_can_be_split()
1067
1009
  self._ensure_qty_to_extract(qty, uom)
1068
1010
  self.product_uom_qty -= uom._compute_quantity(qty, self.product_uom)
1069
- if self.remaining_qty_to_done <= 0:
1011
+ if self.remaining_qty <= 0:
1070
1012
  if self.state == "waiting_return":
1071
1013
  self.state = "returned"
1072
1014
  elif self.state == "waiting_replacement":
@@ -1081,10 +1023,10 @@ class Rma(models.Model):
1081
1023
  "origin_split_rma_id": self.id,
1082
1024
  }
1083
1025
  )
1084
- extracted_rma.message_post_with_view(
1026
+ extracted_rma.message_post_with_source(
1085
1027
  "mail.message_origin_link",
1086
- values={"self": extracted_rma, "origin": self},
1087
- subtype_id=self.env.ref("mail.mt_note").id,
1028
+ render_values={"self": extracted_rma, "origin": self},
1029
+ subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
1088
1030
  )
1089
1031
  self.message_post(
1090
1032
  body=_(
@@ -1173,10 +1115,10 @@ class Rma(models.Model):
1173
1115
  )
1174
1116
  picking.action_confirm()
1175
1117
  picking.action_assign()
1176
- picking.message_post_with_view(
1118
+ picking.message_post_with_source(
1177
1119
  "mail.message_origin_link",
1178
- values={"self": picking, "origin": rmas},
1179
- subtype_id=self.env.ref("mail.mt_note").id,
1120
+ render_values={"self": picking, "origin": rmas},
1121
+ subtype_id=self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note"),
1180
1122
  )
1181
1123
  rmas_to_return.write({"state": "waiting_return"})
1182
1124
 
@@ -1232,7 +1174,7 @@ class Rma(models.Model):
1232
1174
  % (
1233
1175
  {
1234
1176
  "move_id": new_move.id,
1235
- "move_name": new_move.name_get()[0][1],
1177
+ "move_name": new_move.display_name,
1236
1178
  "picking_id": new_move.picking_id.id,
1237
1179
  "picking_name": new_move.picking_id.name,
1238
1180
  }
@@ -1425,10 +1367,7 @@ class Rma(models.Model):
1425
1367
  [stock.move]._action_cancel
1426
1368
  """
1427
1369
  rma = self.filtered(
1428
- lambda r: (
1429
- r.state == "waiting_replacement"
1430
- and 0 >= r.remaining_qty_to_done == r.remaining_qty
1431
- )
1370
+ lambda r: (r.state == "waiting_replacement" and 0 >= r.remaining_qty)
1432
1371
  )
1433
1372
  if rma:
1434
1373
  rma.write({"state": "replaced"})
@@ -1436,7 +1375,7 @@ class Rma(models.Model):
1436
1375
  def update_returned_state(self):
1437
1376
  """Invoked by [stock.move]._action_done"""
1438
1377
  rma = self.filtered(
1439
- lambda r: (r.state == "waiting_return" and r.remaining_qty_to_done <= 0)
1378
+ lambda r: (r.state == "waiting_return" and r.remaining_qty <= 0)
1440
1379
  )
1441
1380
  if rma:
1442
1381
  rma.write({"state": "returned"})
@@ -59,7 +59,7 @@ class StockMove(models.Model):
59
59
  """
60
60
  for move in self.filtered(lambda r: r.state not in ("done", "cancel")):
61
61
  rma_receiver = move.sudo().rma_receiver_ids
62
- if rma_receiver and move.quantity_done != rma_receiver.product_uom_qty:
62
+ if rma_receiver and move.quantity != rma_receiver.product_uom_qty:
63
63
  raise ValidationError(
64
64
  _(
65
65
  "The quantity done for the product '%(id)s' must "
@@ -0,0 +1,22 @@
1
+ If you want RMAs to be created from incoming emails, you need to:
2
+
3
+ 1. Go to *Settings \> General Settings*.
4
+ 2. Check 'External Email Servers' checkbox under *Discuss* section.
5
+ 3. Set an 'alias domain' and an incoming server.
6
+ 4. Go to *RMA \> Configuration \> RMA Team* and select a team or create
7
+ a new one.
8
+ 5. Go to 'Email' tab and set an 'Email Alias'.
9
+
10
+ If you want to manually finish RMAs, you need to:
11
+
12
+ 1. Go to *Settings \> Inventory*.
13
+ 2. Set *Finish RMAs manually* checkbox on.
14
+
15
+ By default, returns to customer are grouped by shipping address,
16
+ warehouse and company. If you want to avoid this grouping you can:
17
+
18
+ 1. Go to *Settings \> Inventory*.
19
+ 2. Set *Group RMA returns by customer address and warehouse* checkbox
20
+ off.
21
+
22
+ The users will still be able to group those pickings from the wizard.
@@ -0,0 +1,9 @@
1
+ - [Tecnativa](https://www.tecnativa.com):
2
+ - Ernesto Tejeda
3
+ - Pedro M. Baeza
4
+ - David Vidal
5
+ - Víctor Martínez
6
+ - Chafique Delli \<<chafique.delli@akretion.com>\>
7
+ - Giovanni Serra - Ooops \<<giovanni@ooops404.com>\>
8
+ - [APSL-Nagarro](https://www.apsl.tech):
9
+ - Antoni Marroig \<<amarroig@apsl.net>\>
@@ -1,8 +1,8 @@
1
- This module allows you to manage `Return Merchandise Authorization (RMA)
2
- <https://en.wikipedia.org/wiki/Return_merchandise_authorization>`_.
1
+ This module allows you to manage [Return Merchandise Authorization
2
+ (RMA)](https://en.wikipedia.org/wiki/Return_merchandise_authorization).
3
3
  RMA documents can be created from scratch, from a delivery order or from
4
4
  an incoming email. Product receptions and returning delivery operations
5
5
  of the RMA module are fully integrated with the Receipts and Deliveries
6
6
  Operations of Odoo inventory core module. It also allows you to generate
7
- refunds in the same way as Odoo generates it.
8
- Besides, you have full integration of the RMA documents in the customer portal.
7
+ refunds in the same way as Odoo generates it. Besides, you have full
8
+ integration of the RMA documents in the customer portal.
@@ -0,0 +1,3 @@
1
+ - As soon as the picking is selected, the user should select the move,
2
+ but perhaps stock.move \_rec_name could be improved to better show
3
+ what the product of that move is.
@@ -0,0 +1,59 @@
1
+ To use this module, you need to:
2
+
3
+ 1. Go to *RMA \> Orders* and create a new RMA.
4
+ 2. Select a partner, an invoice address, select a product (or select a
5
+ picking and a move instead), write a quantity, fill the rest of the
6
+ form and click on 'confirm' button in the status bar.
7
+ 3. You will see an smart button labeled 'Receipt'. Click on that button
8
+ to see the reception operation form.
9
+ 4. If everything is right, validate the operation and go back to the
10
+ RMA to see it in a 'received' state.
11
+ 5. Now you are able to generate a refund, generate a delivery order to
12
+ return to the customer the same product or another product as a
13
+ replacement, split the RMA by extracting a part of the remaining
14
+ quantity to another RMA, preview the RMA in the website. All of
15
+ these operations can be done by clicking on the buttons in the
16
+ status bar.
17
+ - If you click on 'To Refund' button, a refund will be created, and it
18
+ will be accessible via the smart button labeled Refund. The RMA
19
+ will be set automatically to 'Refunded' state when the refund is
20
+ validated.
21
+ - If you click on 'Replace' or 'Return to customer' button instead,
22
+ a popup wizard will guide you to create a Delivery order to the
23
+ client and this order will be accessible via the smart button
24
+ labeled Delivery. The RMA will be set automatically to 'Replaced'
25
+ or 'Returned' state when the RMA quantity is equal or lower than
26
+ the quantity in done delivery orders linked to it.
27
+ 6. You can also finish the RMA without further ado. To do so click on
28
+ the *Finish* button. A wizard will ask you for the reason from a
29
+ selection of preconfigured ones. Be sure to configure them in
30
+ advance on *RMA \> Configuration \> Finalization Reasons*. Once the
31
+ RMA is finished, it will be set to that state and the reason will be
32
+ registered.
33
+
34
+ An RMA can also be created from a return of a delivery order:
35
+
36
+ 1. Select a delivery order and click on 'Return' button to create a
37
+ return.
38
+ 2. Check "Create RMAs" checkbox in the returning wizard, select the RMA
39
+ stock location and click on 'Return' button.
40
+ 3. An RMA will be created for each product returned in the previous
41
+ step. Every RMA will be in confirmed state and they will be linked
42
+ to the returning operation generated previously.
43
+
44
+ There are Optional RMA Teams that can be used for:
45
+
46
+ > - Organize RMAs in sections.
47
+ > - Subscribe users to notifications.
48
+ > - Create RMAs from incoming mail to special aliases (See configuration
49
+ > section).
50
+
51
+ To create an RMA Team (RMA Responsible user level required):
52
+
53
+ > 1. Go to *RMA \> Configuration \> RMA Teams*
54
+ > 2. Create a new team and assign a name, a responsible and members.
55
+ > 3. Subscribe users to notifications, that can be of these subtypes:
56
+ > - RMA draft. When a new RMA is created.
57
+ > - Notes, Debates, Activities. As in standard Odoo.
58
+ > 4. In the list view, use the cross handle to sort RMA Teams. The top
59
+ > team will be the default one if no team is set.