odoo-addon-rma 16.0.3.6.0.2__py3-none-any.whl → 16.0.5.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.
- odoo/addons/rma/README.rst +1 -1
- odoo/addons/rma/__manifest__.py +3 -1
- odoo/addons/rma/i18n/de.po +85 -0
- odoo/addons/rma/i18n/de_AT.po +85 -0
- odoo/addons/rma/i18n/es.po +85 -0
- odoo/addons/rma/i18n/fr.po +85 -0
- odoo/addons/rma/i18n/it.po +85 -0
- odoo/addons/rma/i18n/nl.po +85 -0
- odoo/addons/rma/i18n/pt.po +85 -0
- odoo/addons/rma/i18n/pt_BR.po +85 -0
- odoo/addons/rma/i18n/rma.pot +225 -0
- odoo/addons/rma/i18n/ro.po +85 -0
- odoo/addons/rma/i18n/zh_CN.po +85 -0
- odoo/addons/rma/models/rma.py +160 -15
- odoo/addons/rma/models/rma_operation.py +148 -1
- odoo/addons/rma/static/description/index.html +1 -1
- odoo/addons/rma/tests/__init__.py +2 -0
- odoo/addons/rma/tests/test_rma_dashboard.py +73 -0
- odoo/addons/rma/tests/test_rma_operation.py +317 -0
- odoo/addons/rma/views/dashboard.xml +188 -0
- odoo/addons/rma/views/rma_operation.xml +85 -0
- odoo/addons/rma/views/rma_views.xml +32 -6
- odoo/addons/rma/wizard/stock_picking_return.py +9 -0
- odoo/addons/rma/wizard/stock_picking_return_views.xml +5 -0
- {odoo_addon_rma-16.0.3.6.0.2.dist-info → odoo_addon_rma-16.0.5.0.0.dist-info}/METADATA +2 -2
- {odoo_addon_rma-16.0.3.6.0.2.dist-info → odoo_addon_rma-16.0.5.0.0.dist-info}/RECORD +28 -24
- {odoo_addon_rma-16.0.3.6.0.2.dist-info → odoo_addon_rma-16.0.5.0.0.dist-info}/WHEEL +0 -0
- {odoo_addon_rma-16.0.3.6.0.2.dist-info → odoo_addon_rma-16.0.5.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,317 @@
|
|
1
|
+
# Copyright 2020 Tecnativa - Ernesto Tejeda
|
2
|
+
# Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
|
3
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
4
|
+
|
5
|
+
from odoo.exceptions import ValidationError
|
6
|
+
from odoo.tests.common import Form
|
7
|
+
|
8
|
+
from .test_rma import TestRma
|
9
|
+
|
10
|
+
|
11
|
+
class TestRmaOperation(TestRma):
|
12
|
+
def test_01(self):
|
13
|
+
"""
|
14
|
+
ensure that the receipt creation behaves correctly according to the
|
15
|
+
action_create_receipt setting.
|
16
|
+
- "automatic_on_confirm":
|
17
|
+
- receipts are created automatically
|
18
|
+
- the manual button is hidden
|
19
|
+
- "manual_on_confirm"
|
20
|
+
- manual button is visible after confirmation
|
21
|
+
- disappears once a receipt is manually created
|
22
|
+
"""
|
23
|
+
self.assertEqual(self.operation.action_create_receipt, "automatic_on_confirm")
|
24
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
25
|
+
self.assertFalse(rma.show_create_receipt)
|
26
|
+
rma.action_confirm()
|
27
|
+
self.assertTrue(rma.reception_move_id)
|
28
|
+
self.assertFalse(rma.show_create_receipt)
|
29
|
+
self.operation.action_create_receipt = "manual_on_confirm"
|
30
|
+
rma2 = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
31
|
+
rma2.action_confirm()
|
32
|
+
self.assertTrue(rma2.show_create_receipt)
|
33
|
+
self.assertFalse(rma2.reception_move_id)
|
34
|
+
rma2.action_create_receipt()
|
35
|
+
self.assertFalse(rma2.show_create_receipt)
|
36
|
+
|
37
|
+
def test_02(self):
|
38
|
+
"""
|
39
|
+
test delivery button visibility based on operation settings.
|
40
|
+
No deliver possible
|
41
|
+
"""
|
42
|
+
self.operation.action_create_delivery = False
|
43
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
44
|
+
self.assertFalse(rma.can_be_returned)
|
45
|
+
self.assertFalse(rma.can_be_replaced)
|
46
|
+
rma.action_confirm()
|
47
|
+
self.assertEqual(rma.state, "confirmed")
|
48
|
+
self.assertFalse(rma.can_be_returned)
|
49
|
+
self.assertFalse(rma.show_create_return)
|
50
|
+
self.assertFalse(rma.can_be_replaced)
|
51
|
+
self.assertFalse(rma.show_create_replace)
|
52
|
+
|
53
|
+
def test_03(self):
|
54
|
+
"""
|
55
|
+
test delivery button visibility based on operation settings.
|
56
|
+
deliver manually after confirm
|
57
|
+
"""
|
58
|
+
self.operation.action_create_delivery = "manual_on_confirm"
|
59
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
60
|
+
self.assertFalse(rma.can_be_returned)
|
61
|
+
self.assertFalse(rma.can_be_replaced)
|
62
|
+
rma.action_confirm()
|
63
|
+
self.assertEqual(rma.state, "confirmed")
|
64
|
+
self.assertTrue(rma.can_be_returned)
|
65
|
+
self.assertTrue(rma.show_create_return)
|
66
|
+
self.assertTrue(rma.can_be_replaced)
|
67
|
+
self.assertTrue(rma.show_create_replace)
|
68
|
+
|
69
|
+
def test_04(self):
|
70
|
+
"""
|
71
|
+
test delivery button visibility based on operation settings.
|
72
|
+
deliver automatically after confirm, return same product
|
73
|
+
"""
|
74
|
+
self.operation.action_create_delivery = "automatic_on_confirm"
|
75
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
76
|
+
self.assertFalse(rma.can_be_returned)
|
77
|
+
self.assertFalse(rma.can_be_replaced)
|
78
|
+
rma.action_confirm()
|
79
|
+
self.assertEqual(rma.state, "waiting_replacement")
|
80
|
+
self.assertFalse(rma.can_be_returned)
|
81
|
+
self.assertFalse(rma.show_create_return)
|
82
|
+
self.assertFalse(rma.can_be_replaced)
|
83
|
+
self.assertFalse(rma.show_create_replace)
|
84
|
+
self.assertTrue(rma.delivery_move_ids)
|
85
|
+
self.assertEqual(rma.delivery_move_ids.product_id, self.product)
|
86
|
+
self.assertEqual(rma.delivery_move_ids.product_uom_qty, 10)
|
87
|
+
|
88
|
+
def test_05(self):
|
89
|
+
"""
|
90
|
+
test delivery button visibility based on operation settings.
|
91
|
+
deliver manually after receipt
|
92
|
+
"""
|
93
|
+
self.operation.action_create_delivery = "manual_after_receipt"
|
94
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
95
|
+
self.assertFalse(rma.can_be_returned)
|
96
|
+
self.assertFalse(rma.can_be_replaced)
|
97
|
+
rma.action_confirm()
|
98
|
+
self.assertEqual(rma.state, "confirmed")
|
99
|
+
self.assertFalse(rma.can_be_returned)
|
100
|
+
self.assertFalse(rma.show_create_return)
|
101
|
+
self.assertFalse(rma.can_be_replaced)
|
102
|
+
self.assertFalse(rma.show_create_replace)
|
103
|
+
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
104
|
+
rma.reception_move_id.picking_id._action_done()
|
105
|
+
self.assertEqual(rma.state, "received")
|
106
|
+
self.assertTrue(rma.can_be_returned)
|
107
|
+
self.assertTrue(rma.show_create_return)
|
108
|
+
self.assertTrue(rma.can_be_replaced)
|
109
|
+
self.assertTrue(rma.show_create_replace)
|
110
|
+
|
111
|
+
def test_06(self):
|
112
|
+
"""
|
113
|
+
test delivery button visibility based on operation settings.
|
114
|
+
deliver automatically after receipt
|
115
|
+
"""
|
116
|
+
self.operation.action_create_delivery = "automatic_after_receipt"
|
117
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
118
|
+
self.assertFalse(rma.can_be_returned)
|
119
|
+
self.assertFalse(rma.can_be_replaced)
|
120
|
+
rma.action_confirm()
|
121
|
+
self.assertEqual(rma.state, "confirmed")
|
122
|
+
self.assertFalse(rma.can_be_returned)
|
123
|
+
self.assertFalse(rma.show_create_return)
|
124
|
+
self.assertFalse(rma.can_be_replaced)
|
125
|
+
self.assertFalse(rma.show_create_replace)
|
126
|
+
self.assertFalse(rma.delivery_move_ids)
|
127
|
+
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
128
|
+
rma.reception_move_id.picking_id._action_done()
|
129
|
+
self.assertEqual(rma.delivery_move_ids.product_id, self.product)
|
130
|
+
self.assertEqual(rma.delivery_move_ids.product_uom_qty, 10)
|
131
|
+
self.assertEqual(rma.state, "waiting_replacement")
|
132
|
+
self.assertFalse(rma.can_be_returned)
|
133
|
+
self.assertFalse(rma.show_create_return)
|
134
|
+
self.assertTrue(rma.can_be_replaced)
|
135
|
+
self.assertFalse(rma.show_create_replace)
|
136
|
+
|
137
|
+
def test_07(self):
|
138
|
+
"""
|
139
|
+
test delivery button visibility based on operation settings.
|
140
|
+
deliver automatically after confirm, different product
|
141
|
+
"""
|
142
|
+
self.operation.action_create_delivery = "automatic_on_confirm"
|
143
|
+
self.operation.different_return_product = True
|
144
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
145
|
+
with self.assertRaises(AssertionError, msg="Replacement fields are required"):
|
146
|
+
with Form(rma) as rma_form:
|
147
|
+
rma_form.save()
|
148
|
+
with self.assertRaises(
|
149
|
+
ValidationError, msg="Complete the replacement information"
|
150
|
+
):
|
151
|
+
rma.action_confirm()
|
152
|
+
rma.return_product_id = self.product_product.create(
|
153
|
+
{"name": "return Product test 1", "type": "product"}
|
154
|
+
)
|
155
|
+
rma.action_confirm()
|
156
|
+
self.assertEqual(rma.delivery_move_ids.product_id, rma.product_id)
|
157
|
+
self.assertEqual(rma.reception_move_id.product_id, rma.return_product_id)
|
158
|
+
self.assertEqual(rma.state, "waiting_replacement")
|
159
|
+
|
160
|
+
def test_08(self):
|
161
|
+
"""test refund, manually after confirm"""
|
162
|
+
self.operation.action_create_refund = "manual_on_confirm"
|
163
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
164
|
+
rma.action_confirm()
|
165
|
+
self.assertEqual(rma.state, "confirmed")
|
166
|
+
self.assertTrue(rma.can_be_refunded)
|
167
|
+
self.assertTrue(rma.show_create_refund)
|
168
|
+
|
169
|
+
def test_09(self):
|
170
|
+
"""test refund, manually after receipt"""
|
171
|
+
self.operation.action_create_refund = "manual_after_receipt"
|
172
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
173
|
+
rma.action_confirm()
|
174
|
+
self.assertEqual(rma.state, "confirmed")
|
175
|
+
self.assertFalse(rma.can_be_refunded)
|
176
|
+
self.assertFalse(rma.show_create_refund)
|
177
|
+
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
178
|
+
rma.reception_move_id.picking_id._action_done()
|
179
|
+
self.assertEqual(rma.state, "received")
|
180
|
+
self.assertTrue(rma.can_be_refunded)
|
181
|
+
self.assertTrue(rma.show_create_refund)
|
182
|
+
|
183
|
+
def test_10(self):
|
184
|
+
"""test refund, automatic after confirm"""
|
185
|
+
self.operation.action_create_refund = "automatic_on_confirm"
|
186
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
187
|
+
rma.action_confirm()
|
188
|
+
self.assertEqual(rma.state, "refunded")
|
189
|
+
self.assertTrue(rma.refund_id)
|
190
|
+
self.assertFalse(rma.can_be_refunded)
|
191
|
+
self.assertFalse(rma.show_create_refund)
|
192
|
+
|
193
|
+
def test_11(self):
|
194
|
+
"""test refund, automatic after confirm"""
|
195
|
+
self.operation.action_create_refund = "automatic_after_receipt"
|
196
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
197
|
+
rma.action_confirm()
|
198
|
+
self.assertEqual(rma.state, "confirmed")
|
199
|
+
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
200
|
+
rma.reception_move_id.picking_id._action_done()
|
201
|
+
self.assertEqual(rma.state, "refunded")
|
202
|
+
self.assertTrue(rma.refund_id)
|
203
|
+
self.assertFalse(rma.can_be_refunded)
|
204
|
+
self.assertFalse(rma.show_create_refund)
|
205
|
+
|
206
|
+
def test_12(self):
|
207
|
+
"""
|
208
|
+
Refund without product return
|
209
|
+
Some companies may offer refunds without requiring the return of the product,
|
210
|
+
often in cases of low-value items or when the cost of return shipping is
|
211
|
+
prohibitive.
|
212
|
+
- no receipt
|
213
|
+
- no return
|
214
|
+
- automatically refund on confirm
|
215
|
+
"""
|
216
|
+
self.operation.action_create_receipt = False
|
217
|
+
self.operation.action_create_refund = "automatic_on_confirm"
|
218
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
219
|
+
rma.action_confirm()
|
220
|
+
self.assertEqual(rma.state, "refunded")
|
221
|
+
self.assertFalse(rma.reception_move_id)
|
222
|
+
self.assertTrue(rma.refund_id)
|
223
|
+
|
224
|
+
def test_13(self):
|
225
|
+
"""
|
226
|
+
Return of non-ordered product
|
227
|
+
Occasionally, customers receive items they did not order and need a process for
|
228
|
+
returning these products. The delivered product don't figure on the sale order
|
229
|
+
- receipt
|
230
|
+
- no return
|
231
|
+
- no refund
|
232
|
+
"""
|
233
|
+
self.operation.action_create_receipt = "automatic_on_confirm"
|
234
|
+
self.operation.action_create_delivery = False
|
235
|
+
self.operation.action_create_refund = False
|
236
|
+
rma = self._create_rma(self.partner, self.product, 10, self.rma_loc)
|
237
|
+
rma.action_confirm()
|
238
|
+
rma.reception_move_id.quantity_done = rma.product_uom_qty
|
239
|
+
rma.reception_move_id.picking_id._action_done()
|
240
|
+
self.assertEqual(rma.state, "received")
|
241
|
+
self.assertFalse(rma.delivery_move_ids)
|
242
|
+
|
243
|
+
def test_14(self):
|
244
|
+
"""if the refund action is not ment to update quantity, return picking line
|
245
|
+
to_refund field should be False"""
|
246
|
+
self.operation.action_create_refund = "manual_after_receipt"
|
247
|
+
origin_delivery = self._create_delivery()
|
248
|
+
stock_return_picking_form = Form(
|
249
|
+
self.env["stock.return.picking"].with_context(
|
250
|
+
active_ids=origin_delivery.ids,
|
251
|
+
active_id=origin_delivery.id,
|
252
|
+
active_model="stock.picking",
|
253
|
+
)
|
254
|
+
)
|
255
|
+
stock_return_picking_form.create_rma = True
|
256
|
+
stock_return_picking_form.rma_operation_id = self.operation
|
257
|
+
return_wizard = stock_return_picking_form.save()
|
258
|
+
return_line = return_wizard.product_return_moves.filtered(
|
259
|
+
lambda m, p=self.product: m.product_id == p
|
260
|
+
)
|
261
|
+
self.assertEqual(return_line.rma_operation_id, self.operation)
|
262
|
+
picking_action = return_wizard.create_returns()
|
263
|
+
reception = self.env["stock.picking"].browse(picking_action["res_id"])
|
264
|
+
move = reception.move_ids.filtered(lambda m, p=self.product: m.product_id == p)
|
265
|
+
self.assertFalse(move.to_refund)
|
266
|
+
|
267
|
+
def test_15(self):
|
268
|
+
"""if the refund action is ment to update quantity, return picking line
|
269
|
+
to_refund field should be True"""
|
270
|
+
self.operation.action_create_refund = "update_quantity"
|
271
|
+
origin_delivery = self._create_delivery()
|
272
|
+
stock_return_picking_form = Form(
|
273
|
+
self.env["stock.return.picking"].with_context(
|
274
|
+
active_ids=origin_delivery.ids,
|
275
|
+
active_id=origin_delivery.id,
|
276
|
+
active_model="stock.picking",
|
277
|
+
)
|
278
|
+
)
|
279
|
+
stock_return_picking_form.create_rma = True
|
280
|
+
stock_return_picking_form.rma_operation_id = self.operation
|
281
|
+
return_wizard = stock_return_picking_form.save()
|
282
|
+
return_line = return_wizard.product_return_moves.filtered(
|
283
|
+
lambda m, p=self.product: m.product_id == p
|
284
|
+
)
|
285
|
+
self.assertEqual(return_line.rma_operation_id, self.operation)
|
286
|
+
picking_action = return_wizard.create_returns()
|
287
|
+
reception = self.env["stock.picking"].browse(picking_action["res_id"])
|
288
|
+
move = reception.move_ids.filtered(lambda m, p=self.product: m.product_id == p)
|
289
|
+
self.assertTrue(move.to_refund)
|
290
|
+
|
291
|
+
def test_rma_replace_pick_ship(self):
|
292
|
+
self.operation.action_create_delivery = "automatic_on_confirm"
|
293
|
+
self.warehouse.write({"delivery_steps": "pick_ship"})
|
294
|
+
rma = self._create_rma(self.partner, self.product, 1, self.rma_loc)
|
295
|
+
rma.action_confirm()
|
296
|
+
self.assertEqual(rma.state, "waiting_replacement")
|
297
|
+
out_pickings = rma.mapped("delivery_move_ids.picking_id")
|
298
|
+
self.assertEqual(rma.delivery_picking_count, 2)
|
299
|
+
self.assertIn(
|
300
|
+
self.warehouse.pick_type_id, out_pickings.mapped("picking_type_id")
|
301
|
+
)
|
302
|
+
self.assertIn(
|
303
|
+
self.warehouse.out_type_id, out_pickings.mapped("picking_type_id")
|
304
|
+
)
|
305
|
+
|
306
|
+
def test_16(self):
|
307
|
+
rma = self._create_rma(self.partner, self.product, 1, self.rma_loc)
|
308
|
+
rma.action_confirm()
|
309
|
+
self.assertEqual(rma.reception_move_id.state, "assigned")
|
310
|
+
self.assertEqual(rma.reception_move_id.picking_id.state, "assigned")
|
311
|
+
|
312
|
+
def test_17(self):
|
313
|
+
self.operation.auto_confirm_reception = True
|
314
|
+
rma = self._create_rma(self.partner, self.product, 1, self.rma_loc)
|
315
|
+
rma.action_confirm()
|
316
|
+
self.assertEqual(rma.reception_move_id.state, "done")
|
317
|
+
self.assertEqual(rma.reception_move_id.picking_id.state, "done")
|
@@ -0,0 +1,188 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<!-- Copyright 2024 ACSONE SA/NV
|
3
|
+
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
4
|
+
<odoo>
|
5
|
+
|
6
|
+
<record id="rma_operation_kanban" model="ir.ui.view">
|
7
|
+
<field name="model">rma.operation</field>
|
8
|
+
<field name="arch" type="xml">
|
9
|
+
<kanban
|
10
|
+
class="oe_background_grey o_kanban_dashboard o_emphasize_colors"
|
11
|
+
create="0"
|
12
|
+
group_create="false"
|
13
|
+
>
|
14
|
+
<field name="color" />
|
15
|
+
<field name="count_rma_draft" />
|
16
|
+
<field name="count_rma_awaiting_action" />
|
17
|
+
<field name="count_rma_processed" />
|
18
|
+
<templates>
|
19
|
+
<t t-name="kanban-box">
|
20
|
+
<div
|
21
|
+
t-attf-class="#{!selection_mode ? kanban_color(record.color.raw_value) : ''}"
|
22
|
+
name="rma_operation"
|
23
|
+
>
|
24
|
+
<div t-attf-class="o_kanban_card_header">
|
25
|
+
<div class="o_kanban_card_header_title">
|
26
|
+
<div class="o_primary" t-if="!selection_mode">
|
27
|
+
<a type="object" name="get_action_all_rma">
|
28
|
+
<field name="name" />
|
29
|
+
</a>
|
30
|
+
</div>
|
31
|
+
<div class="o_primary" t-if="selection_mode">
|
32
|
+
<field name="name" />
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
<div
|
36
|
+
class="o_kanban_manage_button_section"
|
37
|
+
t-if="!selection_mode"
|
38
|
+
>
|
39
|
+
<a class="o_kanban_manage_toggle_button" href="#"><i
|
40
|
+
class="fa fa-ellipsis-v"
|
41
|
+
role="img"
|
42
|
+
aria-label="Manage"
|
43
|
+
title="Manage"
|
44
|
+
/></a>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
<div
|
48
|
+
class="container o_kanban_card_content"
|
49
|
+
t-if="!selection_mode"
|
50
|
+
>
|
51
|
+
<div class="row">
|
52
|
+
<div class="col-9 o_kanban_primary_left">
|
53
|
+
<button
|
54
|
+
class="btn btn-link"
|
55
|
+
name="get_action_rma_tree_draft"
|
56
|
+
type="object"
|
57
|
+
>
|
58
|
+
<span>Draft</span>
|
59
|
+
</button>
|
60
|
+
</div>
|
61
|
+
<div class="col-3 o_kanban_primary_right">
|
62
|
+
<button
|
63
|
+
class="btn btn-link"
|
64
|
+
name="get_action_rma_tree_draft"
|
65
|
+
type="object"
|
66
|
+
>
|
67
|
+
<span
|
68
|
+
t-esc="record.count_rma_draft.value"
|
69
|
+
/>
|
70
|
+
</button>
|
71
|
+
</div>
|
72
|
+
<div class="col-9 o_kanban_primary_left">
|
73
|
+
<button
|
74
|
+
class="btn btn-link"
|
75
|
+
name="get_action_rma_tree_awaiting_action"
|
76
|
+
type="object"
|
77
|
+
>
|
78
|
+
<span>Awaiting action</span>
|
79
|
+
</button>
|
80
|
+
</div>
|
81
|
+
<div class="col-3 o_kanban_primary_right">
|
82
|
+
<button
|
83
|
+
class="btn btn-link"
|
84
|
+
name="get_action_rma_tree_awaiting_action"
|
85
|
+
type="object"
|
86
|
+
>
|
87
|
+
<span
|
88
|
+
t-esc="record.count_rma_awaiting_action.value"
|
89
|
+
/>
|
90
|
+
</button>
|
91
|
+
</div>
|
92
|
+
<div class="col-9 o_kanban_primary_left">
|
93
|
+
<button
|
94
|
+
class="btn btn-link"
|
95
|
+
name="get_action_rma_tree_processed"
|
96
|
+
type="object"
|
97
|
+
>
|
98
|
+
<span>Processed</span>
|
99
|
+
</button>
|
100
|
+
</div>
|
101
|
+
<div class="col-3 o_kanban_primary_right">
|
102
|
+
<button
|
103
|
+
class="btn btn-link"
|
104
|
+
name="get_action_rma_tree_processed"
|
105
|
+
type="object"
|
106
|
+
>
|
107
|
+
<span
|
108
|
+
t-esc="record.count_rma_processed.value"
|
109
|
+
/>
|
110
|
+
</button>
|
111
|
+
</div>
|
112
|
+
</div>
|
113
|
+
</div>
|
114
|
+
<div
|
115
|
+
class="container o_kanban_card_manage_pane dropdown-menu"
|
116
|
+
role="menu"
|
117
|
+
>
|
118
|
+
<div class="row">
|
119
|
+
<div
|
120
|
+
class="col-6 o_kanban_card_manage_section o_kanban_manage_new"
|
121
|
+
>
|
122
|
+
<div
|
123
|
+
role="menuitem"
|
124
|
+
class="o_kanban_card_manage_title"
|
125
|
+
>
|
126
|
+
<span>New</span>
|
127
|
+
</div>
|
128
|
+
<div role="menuitem">
|
129
|
+
<a
|
130
|
+
name="%(action_rma_form)d"
|
131
|
+
type="action"
|
132
|
+
>RMA</a>
|
133
|
+
</div>
|
134
|
+
</div>
|
135
|
+
</div>
|
136
|
+
|
137
|
+
<div
|
138
|
+
t-if="widget.editable"
|
139
|
+
class="o_kanban_card_manage_settings row"
|
140
|
+
>
|
141
|
+
<div
|
142
|
+
class="col-8"
|
143
|
+
role="menuitem"
|
144
|
+
aria-haspopup="true"
|
145
|
+
>
|
146
|
+
<ul
|
147
|
+
class="oe_kanban_colorpicker"
|
148
|
+
data-field="color"
|
149
|
+
role="menu"
|
150
|
+
/>
|
151
|
+
</div>
|
152
|
+
<div role="menuitem" class="col-4">
|
153
|
+
<a
|
154
|
+
class="dropdown-item"
|
155
|
+
role="menuitem"
|
156
|
+
type="edit"
|
157
|
+
>Configuration</a>
|
158
|
+
</div>
|
159
|
+
</div>
|
160
|
+
</div>
|
161
|
+
</div>
|
162
|
+
</t>
|
163
|
+
</templates>
|
164
|
+
</kanban>
|
165
|
+
</field>
|
166
|
+
</record>
|
167
|
+
|
168
|
+
<record id="rma_dashboard_action" model="ir.actions.act_window">
|
169
|
+
<field name="name">RMA Overview</field>
|
170
|
+
<field name="res_model">rma.operation</field>
|
171
|
+
<field name="type">ir.actions.act_window</field>
|
172
|
+
<field name="view_mode">kanban,form</field>
|
173
|
+
<field name="help" type="html">
|
174
|
+
<p class="o_view_nocontent_smiling_face"> Create a new RMA operation </p>
|
175
|
+
<p>The RMA operation system allows you to configure each return operation
|
176
|
+
with specific settings that will adjust its behavior.</p>
|
177
|
+
</field>
|
178
|
+
</record>
|
179
|
+
|
180
|
+
<menuitem
|
181
|
+
action="rma_dashboard_action"
|
182
|
+
id="rma_dashboard_menu"
|
183
|
+
parent="rma_menu"
|
184
|
+
sequence="0"
|
185
|
+
name="Overview"
|
186
|
+
/>
|
187
|
+
|
188
|
+
</odoo>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<!-- Copyright 2024 ACSONE SA/NV
|
3
|
+
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
4
|
+
<odoo>
|
5
|
+
|
6
|
+
<record model="ir.ui.view" id="rma_operation_form_view">
|
7
|
+
<field name="model">rma.operation</field>
|
8
|
+
<field name="arch" type="xml">
|
9
|
+
<form>
|
10
|
+
<sheet>
|
11
|
+
<group>
|
12
|
+
<field name="name" />
|
13
|
+
<field name="active" widget="boolean_toggle" />
|
14
|
+
</group>
|
15
|
+
<group string="Settings" name="settings">
|
16
|
+
<group>
|
17
|
+
<field name="action_create_receipt" />
|
18
|
+
|
19
|
+
</group>
|
20
|
+
<group>
|
21
|
+
<field
|
22
|
+
name="different_return_product"
|
23
|
+
attrs="{'invisible': [('action_create_receipt', '=', False)]}"
|
24
|
+
/>
|
25
|
+
<field
|
26
|
+
name="auto_confirm_reception"
|
27
|
+
attrs="{'invisible': [('action_create_receipt', '=', False)]}"
|
28
|
+
/>
|
29
|
+
</group>
|
30
|
+
<group>
|
31
|
+
<field name="action_create_delivery" />
|
32
|
+
|
33
|
+
</group>
|
34
|
+
<group />
|
35
|
+
<group>
|
36
|
+
<field name="action_create_refund" />
|
37
|
+
|
38
|
+
</group>
|
39
|
+
<group />
|
40
|
+
|
41
|
+
|
42
|
+
</group>
|
43
|
+
</sheet>
|
44
|
+
</form>
|
45
|
+
</field>
|
46
|
+
</record>
|
47
|
+
|
48
|
+
<record model="ir.ui.view" id="rma_operation_search_view">
|
49
|
+
<field name="model">rma.operation</field>
|
50
|
+
<field name="arch" type="xml">
|
51
|
+
<search>
|
52
|
+
<field name="name" />
|
53
|
+
</search>
|
54
|
+
</field>
|
55
|
+
</record>
|
56
|
+
|
57
|
+
<record model="ir.ui.view" id="rma_operation_tree_view">
|
58
|
+
<field name="model">rma.operation</field>
|
59
|
+
<field name="arch" type="xml">
|
60
|
+
<tree>
|
61
|
+
<field name="name" />
|
62
|
+
<field name="action_create_receipt" />
|
63
|
+
<field name="action_create_delivery" />
|
64
|
+
<field name="action_create_refund" />
|
65
|
+
<field name="active" widget="boolean_toggle" />
|
66
|
+
</tree>
|
67
|
+
</field>
|
68
|
+
</record>
|
69
|
+
|
70
|
+
<record model="ir.actions.act_window" id="rma_operation_act_window">
|
71
|
+
<field name="name">Operations</field>
|
72
|
+
<field name="res_model">rma.operation</field>
|
73
|
+
<field name="view_mode">tree,form</field>
|
74
|
+
<field name="domain">[]</field>
|
75
|
+
<field name="context">{}</field>
|
76
|
+
</record>
|
77
|
+
|
78
|
+
<record model="ir.ui.menu" id="rma_operation_menu">
|
79
|
+
<field name="name">Operations</field>
|
80
|
+
<field name="parent_id" ref="rma_configuration_menu" />
|
81
|
+
<field name="action" ref="rma_operation_act_window" />
|
82
|
+
<field name="sequence" eval="16" />
|
83
|
+
</record>
|
84
|
+
|
85
|
+
</odoo>
|
@@ -154,25 +154,32 @@
|
|
154
154
|
states="draft"
|
155
155
|
class="btn-primary"
|
156
156
|
/>
|
157
|
+
<button
|
158
|
+
name="action_create_receipt"
|
159
|
+
type="object"
|
160
|
+
string="Create Receipt"
|
161
|
+
attrs="{'invisible': [('show_create_receipt', '=', False)]}"
|
162
|
+
class="btn-primary"
|
163
|
+
/>
|
157
164
|
<button
|
158
165
|
type="object"
|
159
166
|
string="To Refund"
|
160
167
|
name="action_refund"
|
161
|
-
attrs="{'invisible': [('
|
168
|
+
attrs="{'invisible': [('show_create_refund', '=', False)]}"
|
162
169
|
class="btn-primary"
|
163
170
|
/>
|
164
171
|
<button
|
165
172
|
type="object"
|
166
173
|
string="Replace"
|
167
174
|
name="action_replace"
|
168
|
-
attrs="{'invisible': [('
|
175
|
+
attrs="{'invisible': [('show_create_replace', '=', False)]}"
|
169
176
|
class="btn-primary"
|
170
177
|
/>
|
171
178
|
<button
|
172
179
|
type="object"
|
173
180
|
string="Return to customer"
|
174
181
|
name="action_return"
|
175
|
-
attrs="{'invisible': [('
|
182
|
+
attrs="{'invisible': [('show_create_return', '=', False)]}"
|
176
183
|
class="btn-primary"
|
177
184
|
/>
|
178
185
|
<button
|
@@ -283,6 +290,11 @@
|
|
283
290
|
force_save="1"
|
284
291
|
attrs="{'readonly': ['|', ('picking_id', '!=', False), ('state', '!=', 'draft')]}"
|
285
292
|
/>
|
293
|
+
<field
|
294
|
+
name="return_product_id"
|
295
|
+
force_save="1"
|
296
|
+
attrs="{'readonly': ['|', ('picking_id', '!=', False), ('state', '!=', 'draft')], 'invisible': [('different_return_product', '=', False)], 'required': [('different_return_product', '=', True)]}"
|
297
|
+
/>
|
286
298
|
<field name="uom_category_id" invisible="1" />
|
287
299
|
<label for="product_uom_qty" />
|
288
300
|
<div class="o_row">
|
@@ -359,9 +371,11 @@
|
|
359
371
|
<field name="sent" invisible="1" />
|
360
372
|
<field name="reception_move_id" invisible="1" />
|
361
373
|
<field name="refund_id" invisible="1" />
|
362
|
-
<field name="
|
363
|
-
<field name="
|
364
|
-
<field name="
|
374
|
+
<field name="show_create_receipt" invisible="1" />
|
375
|
+
<field name="show_create_refund" invisible="1" />
|
376
|
+
<field name="show_create_return" invisible="1" />
|
377
|
+
<field name="show_create_replace" invisible="1" />
|
378
|
+
<field name="different_return_product" invisible="1" />
|
365
379
|
<field name="can_be_split" invisible="1" />
|
366
380
|
<field name="can_be_locked" invisible="1" />
|
367
381
|
<field name="can_be_finished" invisible="1" />
|
@@ -439,4 +453,16 @@
|
|
439
453
|
<record id="rma_orders_menu" model="ir.ui.menu">
|
440
454
|
<field name="action" ref="rma_action" />
|
441
455
|
</record>
|
456
|
+
|
457
|
+
<record id="action_rma_form" model="ir.actions.act_window">
|
458
|
+
<field name="name">New RMA</field>
|
459
|
+
<field name="res_model">rma</field>
|
460
|
+
<field name="type">ir.actions.act_window</field>
|
461
|
+
<field name="view_mode">form</field>
|
462
|
+
<field name="context">{
|
463
|
+
'search_operation_id': [active_id],
|
464
|
+
'default_operation_id': active_id,
|
465
|
+
}
|
466
|
+
</field>
|
467
|
+
</record>
|
442
468
|
</odoo>
|