odoo-addon-stock-restrict-lot 18.0.1.1.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 (29) hide show
  1. odoo/addons/stock_restrict_lot/README.rst +94 -0
  2. odoo/addons/stock_restrict_lot/__init__.py +1 -0
  3. odoo/addons/stock_restrict_lot/__manifest__.py +15 -0
  4. odoo/addons/stock_restrict_lot/i18n/es.po +73 -0
  5. odoo/addons/stock_restrict_lot/i18n/hr.po +78 -0
  6. odoo/addons/stock_restrict_lot/i18n/it.po +77 -0
  7. odoo/addons/stock_restrict_lot/i18n/nl.po +69 -0
  8. odoo/addons/stock_restrict_lot/i18n/nl_NL.po +77 -0
  9. odoo/addons/stock_restrict_lot/i18n/pt.po +69 -0
  10. odoo/addons/stock_restrict_lot/i18n/pt_BR.po +69 -0
  11. odoo/addons/stock_restrict_lot/i18n/stock_restrict_lot.pot +68 -0
  12. odoo/addons/stock_restrict_lot/i18n/tr.po +77 -0
  13. odoo/addons/stock_restrict_lot/models/__init__.py +4 -0
  14. odoo/addons/stock_restrict_lot/models/product_product.py +22 -0
  15. odoo/addons/stock_restrict_lot/models/stock_move.py +160 -0
  16. odoo/addons/stock_restrict_lot/models/stock_picking.py +12 -0
  17. odoo/addons/stock_restrict_lot/models/stock_rule.py +17 -0
  18. odoo/addons/stock_restrict_lot/readme/CONTRIBUTORS.md +3 -0
  19. odoo/addons/stock_restrict_lot/readme/DESCRIPTION.md +4 -0
  20. odoo/addons/stock_restrict_lot/static/description/icon.png +0 -0
  21. odoo/addons/stock_restrict_lot/static/description/index.html +437 -0
  22. odoo/addons/stock_restrict_lot/tests/__init__.py +1 -0
  23. odoo/addons/stock_restrict_lot/tests/test_restrict_lot.py +392 -0
  24. odoo/addons/stock_restrict_lot/views/stock_move_views.xml +41 -0
  25. odoo/addons/stock_restrict_lot/views/stock_picking.xml +34 -0
  26. odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/METADATA +110 -0
  27. odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/RECORD +29 -0
  28. odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/WHEEL +5 -0
  29. odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,392 @@
1
+ # License LGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
2
+
3
+ from odoo.exceptions import UserError, ValidationError
4
+ from odoo.tests.common import TransactionCase
5
+
6
+
7
+ class TestRestrictLot(TransactionCase):
8
+ @classmethod
9
+ def setUpClass(cls):
10
+ super().setUpClass()
11
+ cls.customer_loc = cls.env.ref("stock.stock_location_customers")
12
+ cls.output_loc = cls.env.ref("stock.stock_location_output")
13
+ cls.product = cls.env.ref("product.product_product_16").copy()
14
+ cls.product.write({"tracking": "lot"})
15
+ cls.warehouse = cls.env.ref("stock.warehouse0")
16
+ cls.warehouse.write({"delivery_steps": "pick_ship"})
17
+ cls.stock_loc = cls.warehouse.lot_stock_id
18
+
19
+ # Set up a pull route from an external warehouse
20
+ cls.warehouse2 = cls.env["stock.warehouse"].create(
21
+ {"name": __name__, "code": "_WH2"}
22
+ )
23
+ cls.warehouse.resupply_wh_ids = cls.warehouse2
24
+ route = cls.env["stock.route"].search(
25
+ [("supplied_wh_id", "=", cls.warehouse.id)]
26
+ )
27
+ assert route
28
+ cls.product.route_ids = route
29
+
30
+ cls.lot = cls.env["stock.lot"].create(
31
+ {
32
+ "name": "lot1",
33
+ "product_id": cls.product.id,
34
+ "company_id": cls.warehouse.company_id.id,
35
+ }
36
+ )
37
+
38
+ def _create_move_with_lot(self):
39
+ move = self.env["stock.move"].create(
40
+ {
41
+ "product_id": self.product.id,
42
+ "location_id": self.stock_loc.id,
43
+ "location_dest_id": self.output_loc.id,
44
+ "product_uom_qty": 1,
45
+ "product_uom": self.product.uom_id.id,
46
+ "name": "test",
47
+ "procure_method": "make_to_order",
48
+ "warehouse_id": self.warehouse.id,
49
+ "route_ids": [(6, 0, self.warehouse.delivery_route_id.ids)],
50
+ "restrict_lot_id": self.lot.id,
51
+ }
52
+ )
53
+ move._action_confirm()
54
+ move._action_assign()
55
+ new_lot = self.env["stock.lot"].create(
56
+ {
57
+ "name": "lot2",
58
+ "product_id": self.product.id,
59
+ "company_id": self.warehouse.company_id.id,
60
+ }
61
+ )
62
+ return move, new_lot
63
+
64
+ def _create_move_dest(self):
65
+ return self.env["stock.move"].create(
66
+ {
67
+ "product_id": self.product.id,
68
+ "location_id": self.customer_loc.id,
69
+ "product_uom_qty": 1,
70
+ "product_uom": self.product.uom_id.id,
71
+ "picking_type_id": self.warehouse.out_type_id.id,
72
+ "location_dest_id": self.output_loc.id,
73
+ "name": "test",
74
+ "procure_method": "make_to_order",
75
+ "warehouse_id": self.warehouse.id,
76
+ "route_ids": [(6, 0, self.warehouse.delivery_route_id.ids)],
77
+ "state": "waiting",
78
+ "restrict_lot_id": self.lot.id,
79
+ }
80
+ )
81
+
82
+ def test_00_move_restrict_lot_propagation(self):
83
+ move = self.env["stock.move"].create(
84
+ {
85
+ "product_id": self.product.id,
86
+ "location_id": self.stock_loc.id,
87
+ "location_dest_id": self.output_loc.id,
88
+ "product_uom_qty": 1,
89
+ "product_uom": self.product.uom_id.id,
90
+ "name": "test",
91
+ "procure_method": "make_to_order",
92
+ "warehouse_id": self.warehouse.id,
93
+ "route_ids": [(6, 0, self.warehouse.delivery_route_id.ids)],
94
+ "restrict_lot_id": self.lot.id,
95
+ }
96
+ )
97
+ move._action_confirm()
98
+ orig_move = move.move_orig_ids
99
+ self.assertEqual(orig_move.restrict_lot_id.id, self.lot.id)
100
+
101
+ def test_01_move_split_and_copy(self):
102
+ move = self.env["stock.move"].create(
103
+ {
104
+ "product_id": self.product.id,
105
+ "location_id": self.stock_loc.id,
106
+ "location_dest_id": self.output_loc.id,
107
+ "product_uom_qty": 2,
108
+ "product_uom": self.product.uom_id.id,
109
+ "name": "test",
110
+ "procure_method": "make_to_stock",
111
+ "warehouse_id": self.warehouse.id,
112
+ "route_ids": [(6, 0, self.warehouse.delivery_route_id.ids)],
113
+ "restrict_lot_id": self.lot.id,
114
+ }
115
+ )
116
+ move._action_confirm()
117
+ vals_list = move._split(1)
118
+ new_move = self.env["stock.move"].create(vals_list)
119
+ self.assertEqual(new_move.restrict_lot_id.id, move.restrict_lot_id.id)
120
+ other_move = move.copy()
121
+ self.assertFalse(other_move.restrict_lot_id.id)
122
+
123
+ def _update_product_stock(self, qty, lot_id=False, location=None):
124
+ quant = self.env["stock.quant"].create(
125
+ {
126
+ "product_id": self.product.id,
127
+ "location_id": (
128
+ location.id if location else self.warehouse.lot_stock_id.id
129
+ ),
130
+ "lot_id": lot_id,
131
+ "inventory_quantity": qty,
132
+ }
133
+ )
134
+ quant.action_apply_inventory()
135
+
136
+ def test_02_move_restrict_lot_reservation(self):
137
+ lot2 = self.env["stock.lot"].create(
138
+ {
139
+ "name": "lot2",
140
+ "product_id": self.product.id,
141
+ "company_id": self.warehouse.company_id.id,
142
+ }
143
+ )
144
+ self._update_product_stock(1, lot2.id)
145
+
146
+ move = self.env["stock.move"].create(
147
+ {
148
+ "product_id": self.product.id,
149
+ "location_id": self.warehouse.lot_stock_id.id,
150
+ "location_dest_id": self.customer_loc.id,
151
+ "product_uom_qty": 1,
152
+ "product_uom": self.product.uom_id.id,
153
+ "name": "test",
154
+ "warehouse_id": self.warehouse.id,
155
+ "restrict_lot_id": self.lot.id,
156
+ }
157
+ )
158
+ move._action_confirm()
159
+ move._action_assign()
160
+ # move should not reserve wrong free lot
161
+ self.assertEqual(move.state, "confirmed")
162
+
163
+ self._update_product_stock(1, self.lot.id)
164
+ move._action_assign()
165
+ self.assertEqual(move.state, "assigned")
166
+ self.assertEqual(move.move_line_ids.lot_id.id, self.lot.id)
167
+
168
+ def test_procurement_with_2_steps_output(self):
169
+ # make warehouse output in two step
170
+ self.env["res.config.settings"].write(
171
+ {
172
+ "group_stock_adv_location": True,
173
+ "group_stock_multi_locations": True,
174
+ }
175
+ )
176
+
177
+ self.product.categ_id.route_ids |= self.warehouse.delivery_route_id
178
+ location_1 = self.env["stock.location"].create(
179
+ {"name": "loc1", "location_id": self.warehouse.lot_stock_id.id}
180
+ )
181
+ location_2 = self.env["stock.location"].create(
182
+ {"name": "loc2", "location_id": self.warehouse.lot_stock_id.id}
183
+ )
184
+
185
+ # create goods in stock
186
+ lot2 = self.env["stock.lot"].create(
187
+ {
188
+ "name": "lot 2",
189
+ "product_id": self.product.id,
190
+ "company_id": self.warehouse.company_id.id,
191
+ }
192
+ )
193
+ self._update_product_stock(10, self.lot.id, location=location_1)
194
+ self._update_product_stock(10, self.lot.id, location=location_2)
195
+ self._update_product_stock(5, lot2.id, location=location_1)
196
+ self._update_product_stock(25, lot2.id, location=location_2)
197
+
198
+ # create a procurement with two lines of same product with different lots
199
+ procurement_group = self.env["procurement.group"].create(
200
+ {"name": "My procurement", "move_type": "one"}
201
+ )
202
+ self.env["procurement.group"].run(
203
+ [
204
+ self.env["procurement.group"].Procurement(
205
+ self.product,
206
+ 15,
207
+ self.product.uom_id,
208
+ self.customer_loc,
209
+ "a name",
210
+ "an origin restrict on lot 1",
211
+ self.env.company,
212
+ {
213
+ "group_id": procurement_group,
214
+ "restrict_lot_id": self.lot.id,
215
+ },
216
+ ),
217
+ self.env["procurement.group"].Procurement(
218
+ self.product,
219
+ 30,
220
+ self.product.uom_id,
221
+ self.customer_loc,
222
+ "a name",
223
+ "an origin restrict on lot 2",
224
+ self.env.company,
225
+ {
226
+ "group_id": procurement_group,
227
+ "restrict_lot_id": lot2.id,
228
+ },
229
+ ),
230
+ ]
231
+ )
232
+ # make sure in the two stock picking we get right quantities
233
+ # for expected lot and locations
234
+
235
+ def assert_move_qty_per_lot(moves, expect_lot, expect_qty):
236
+ concern_move = moves.filtered(lambda mov: mov.restrict_lot_id == expect_lot)
237
+ self.assertEqual(len(concern_move), 1)
238
+ self.assertEqual(concern_move.product_uom_qty, expect_qty)
239
+
240
+ def assert_move_line_per_lot_and_location(
241
+ move_lines, expect_lot, expect_from_location, expect_reserved_qty
242
+ ):
243
+ concern_move_line = move_lines.filtered(
244
+ lambda mov: mov.lot_id == expect_lot
245
+ and mov.location_id == expect_from_location
246
+ )
247
+ self.assertEqual(len(concern_move_line), 1)
248
+ self.assertEqual(
249
+ concern_move_line.quantity_product_uom, expect_reserved_qty
250
+ )
251
+
252
+ pick = procurement_group.stock_move_ids.picking_id
253
+ self.assertEqual(len(pick), 1)
254
+ self.assertEqual(pick.picking_type_id.code, "internal")
255
+ self.assertEqual(pick.state, "assigned")
256
+ self.assertEqual(len(pick.move_ids), 2)
257
+ assert_move_qty_per_lot(pick.move_ids_without_package, self.lot, 15)
258
+ assert_move_qty_per_lot(pick.move_ids_without_package, lot2, 30)
259
+ assert_move_line_per_lot_and_location(
260
+ pick.move_line_ids_without_package, self.lot, location_1, 10
261
+ )
262
+ assert_move_line_per_lot_and_location(
263
+ pick.move_line_ids_without_package, self.lot, location_2, 5
264
+ )
265
+ assert_move_line_per_lot_and_location(
266
+ pick.move_line_ids_without_package, lot2, location_1, 5
267
+ )
268
+ assert_move_line_per_lot_and_location(
269
+ pick.move_line_ids_without_package, lot2, location_2, 25
270
+ )
271
+ pick.button_validate()
272
+ self.assertEqual(pick.state, "done")
273
+
274
+ delivery = procurement_group.stock_move_ids.picking_id - pick
275
+ self.assertEqual(delivery.picking_type_id.code, "outgoing")
276
+ self.assertEqual(delivery.state, "assigned")
277
+
278
+ assert_move_qty_per_lot(delivery.move_ids_without_package, self.lot, 15)
279
+ assert_move_qty_per_lot(delivery.move_ids_without_package, lot2, 30)
280
+
281
+ def test_compute_quantites(self):
282
+ move = self.env["stock.move"].create(
283
+ {
284
+ "product_id": self.product.id,
285
+ "location_id": self.stock_loc.id,
286
+ "location_dest_id": self.customer_loc.id,
287
+ "product_uom_qty": 1,
288
+ "product_uom": self.product.uom_id.id,
289
+ "name": "test",
290
+ "procure_method": "make_to_stock",
291
+ "warehouse_id": self.warehouse.id,
292
+ "route_ids": [(6, 0, self.warehouse.delivery_route_id.ids)],
293
+ "restrict_lot_id": self.lot.id,
294
+ }
295
+ )
296
+ move._action_confirm()
297
+
298
+ lot2 = self.lot.copy({"name": "lot2"})
299
+ move2 = move.copy()
300
+ move2.restrict_lot_id = lot2.id
301
+ move2._action_confirm()
302
+
303
+ product = move.product_id
304
+ self.assertEqual(product.outgoing_qty, 2)
305
+
306
+ product.invalidate_recordset()
307
+ product = product.with_context(lot_id=self.lot.id)
308
+ self.assertEqual(product.outgoing_qty, 1)
309
+
310
+ product.invalidate_recordset()
311
+ product = product.with_context(lot_id=lot2.id)
312
+ self.assertEqual(product.outgoing_qty, 1)
313
+
314
+ def test_move_validation_inconsistent_lot(self):
315
+ """
316
+ Check that an error is raised when performing a move _action_done()
317
+ if the lot restriction on the move is inconsistent with the
318
+ lot in the move line
319
+ """
320
+ lot2 = self.env["stock.lot"].create(
321
+ {
322
+ "name": "lot2",
323
+ "product_id": self.product.id,
324
+ "company_id": self.warehouse.company_id.id,
325
+ }
326
+ )
327
+ self._update_product_stock(1, lot2.id)
328
+
329
+ move = self.env["stock.move"].create(
330
+ {
331
+ "product_id": self.product.id,
332
+ "location_id": self.warehouse.lot_stock_id.id,
333
+ "location_dest_id": self.customer_loc.id,
334
+ "product_uom_qty": 1,
335
+ "product_uom": self.product.uom_id.id,
336
+ "name": "test",
337
+ "warehouse_id": self.warehouse.id,
338
+ "restrict_lot_id": self.lot.id,
339
+ }
340
+ )
341
+ move_line = self.env["stock.move.line"].create(
342
+ {
343
+ "move_id": move.id,
344
+ "product_id": move.product_id.id,
345
+ "quantity": 1,
346
+ "product_uom_id": move.product_uom.id,
347
+ "location_id": move.location_id.id,
348
+ "location_dest_id": move.location_dest_id.id,
349
+ "lot_id": lot2.id,
350
+ }
351
+ )
352
+ self.assertRaises(UserError, move._action_done)
353
+ move_line.lot_id = self.lot
354
+ move._action_done()
355
+
356
+ def test_restrict_lot_propagation_dest_moves(self):
357
+ move, new_lot = self._create_move_with_lot()
358
+ move_dest = self._create_move_dest()
359
+ move.move_dest_ids = [(4, move_dest.id)]
360
+ self.assertEqual(move_dest.restrict_lot_id, self.lot)
361
+ move.restrict_lot_id = new_lot.id
362
+ self.assertEqual(move_dest.restrict_lot_id, new_lot)
363
+
364
+ def test_restrict_lot_propagation_origin_moves(self):
365
+ move, new_lot = self._create_move_with_lot()
366
+ orig_move = move.move_orig_ids
367
+ self.assertEqual(orig_move.restrict_lot_id, self.lot)
368
+ move.restrict_lot_id = new_lot.id
369
+ self.assertEqual(orig_move.restrict_lot_id, new_lot)
370
+
371
+ def test_restrict_lot_propagation_origin_and_dest_moves(self):
372
+ move, new_lot = self._create_move_with_lot()
373
+ move_dest = self._create_move_dest()
374
+ move.move_dest_ids = [(4, move_dest.id)]
375
+ orig_move = move.move_orig_ids
376
+ self.assertEqual(move_dest.restrict_lot_id, self.lot)
377
+ self.assertEqual(orig_move.restrict_lot_id, self.lot)
378
+ move.restrict_lot_id = new_lot.id
379
+ self.assertEqual(orig_move.restrict_lot_id, new_lot)
380
+ self.assertEqual(move_dest.restrict_lot_id, new_lot)
381
+
382
+ def test_restrict_lot_no_propagation_error(self):
383
+ move, new_lot = self._create_move_with_lot()
384
+ orig_move = move.move_orig_ids
385
+ orig_move._action_assign()
386
+ orig_move.quantity = orig_move.product_uom_qty
387
+ orig_move.picked = True
388
+ orig_move._action_done()
389
+ self.assertEqual(orig_move.state, "done")
390
+ with self.assertRaises(ValidationError) as m:
391
+ move.restrict_lot_id = new_lot.id
392
+ self.assertIn("You can't modify the Lot/Serial number", m.exception.args[0])
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <odoo>
3
+ <record id="stock_move_pick_tree_view" model="ir.ui.view">
4
+ <field name="model">stock.move</field>
5
+ <field name="inherit_id" ref="stock.view_picking_move_tree" />
6
+ <field name="arch" type="xml">
7
+ <field name="product_id" position="after">
8
+ <field
9
+ name="restrict_lot_id"
10
+ readonly="1"
11
+ optional="show"
12
+ groups="stock.group_production_lot"
13
+ />
14
+ </field>
15
+ </field>
16
+ </record>
17
+
18
+ <record id="stock_move_tree_view" model="ir.ui.view">
19
+ <field name="model">stock.move</field>
20
+ <field name="inherit_id" ref="stock.view_move_tree" />
21
+ <field name="arch" type="xml">
22
+ <field name="product_id" position="after">
23
+ <field
24
+ name="restrict_lot_id"
25
+ readonly="1"
26
+ optional="show"
27
+ groups="stock.group_production_lot"
28
+ />
29
+ </field>
30
+ </field>
31
+ </record>
32
+ <record id="stock_move_kanban_view" model="ir.ui.view">
33
+ <field name="model">stock.move</field>
34
+ <field name="inherit_id" ref="stock.view_move_kandan" />
35
+ <field name="arch" type="xml">
36
+ <field name="product_id" position="after">
37
+ <field name="restrict_lot_id" groups="stock.group_production_lot" />
38
+ </field>
39
+ </field>
40
+ </record>
41
+ </odoo>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <odoo>
3
+ <record id="custom_main_stock_picking_form_view" model="ir.ui.view">
4
+ <field name="model">stock.picking</field>
5
+ <field name="inherit_id" ref="stock.view_picking_form" />
6
+ <field name="arch" type="xml">
7
+ <xpath
8
+ expr="//field[@name='move_ids_without_package']/list/field[@name='product_id']"
9
+ position="after"
10
+ >
11
+ <field
12
+ name="restrict_lot_id"
13
+ readonly="1"
14
+ optional="show"
15
+ groups="stock.group_production_lot"
16
+ />
17
+ </xpath>
18
+ </field>
19
+ </record>
20
+
21
+ <record id="custom_stock_picking_search_view" model="ir.ui.view">
22
+ <field name="model">stock.picking</field>
23
+ <field name="inherit_id" ref="stock.view_picking_internal_search" />
24
+ <field name="arch" type="xml">
25
+ <field name="product_id" position="after">
26
+ <field
27
+ name="restrict_lot_id"
28
+ string="Lot"
29
+ groups="stock.group_production_lot"
30
+ />
31
+ </field>
32
+ </field>
33
+ </record>
34
+ </odoo>
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.1
2
+ Name: odoo-addon-stock_restrict_lot
3
+ Version: 18.0.1.1.0.2
4
+ Requires-Python: >=3.10
5
+ Requires-Dist: odoo==18.0.*
6
+ Summary: Base module that add back the concept of restrict lot on stock move
7
+ Home-page: https://github.com/OCA/stock-logistics-workflow
8
+ License: LGPL-3
9
+ Author: Akretion, Odoo Community Association (OCA)
10
+ Author-email: support@odoo-community.org
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Framework :: Odoo
13
+ Classifier: Framework :: Odoo :: 18.0
14
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
15
+ Description-Content-Type: text/x-rst
16
+
17
+ .. image:: https://odoo-community.org/readme-banner-image
18
+ :target: https://odoo-community.org/get-involved?utm_source=readme
19
+ :alt: Odoo Community Association
20
+
21
+ ==================
22
+ Stock Restrict Lot
23
+ ==================
24
+
25
+ ..
26
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27
+ !! This file is generated by oca-gen-addon-readme !!
28
+ !! changes will be overwritten. !!
29
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
30
+ !! source digest: sha256:25c1df28bea27dac9e51a5ed95b98f3c2d2fd41c30de975db7d00c940bf7cd12
31
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
32
+
33
+ .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
34
+ :target: https://odoo-community.org/page/development-status
35
+ :alt: Beta
36
+ .. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
37
+ :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
38
+ :alt: License: LGPL-3
39
+ .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--workflow-lightgray.png?logo=github
40
+ :target: https://github.com/OCA/stock-logistics-workflow/tree/18.0/stock_restrict_lot
41
+ :alt: OCA/stock-logistics-workflow
42
+ .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
43
+ :target: https://translation.odoo-community.org/projects/stock-logistics-workflow-18-0/stock-logistics-workflow-18-0-stock_restrict_lot
44
+ :alt: Translate me on Weblate
45
+ .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
46
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-workflow&target_branch=18.0
47
+ :alt: Try me on Runboat
48
+
49
+ |badge1| |badge2| |badge3| |badge4| |badge5|
50
+
51
+ This module adds a field to restrict a stock move to a specific lot. It
52
+ propagates it between chained moves. A move with a restrict lot will
53
+ only be able to reserve or transfer products with the specified lot.
54
+ This module serves as a basis for other modules, it has not effect on
55
+ its own.
56
+
57
+ **Table of contents**
58
+
59
+ .. contents::
60
+ :local:
61
+
62
+ Bug Tracker
63
+ ===========
64
+
65
+ Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-workflow/issues>`_.
66
+ In case of trouble, please check there if your issue has already been reported.
67
+ If you spotted it first, help us to smash it by providing a detailed and welcomed
68
+ `feedback <https://github.com/OCA/stock-logistics-workflow/issues/new?body=module:%20stock_restrict_lot%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
69
+
70
+ Do not contact contributors directly about support or help with technical issues.
71
+
72
+ Credits
73
+ =======
74
+
75
+ Authors
76
+ -------
77
+
78
+ * Akretion
79
+
80
+ Contributors
81
+ ------------
82
+
83
+ - Florian da Costa <florian.dacosta@akretion.com>
84
+ - Ruchir Shukla <ruchir@bizzappdev.com>
85
+ - Stefan Rijnhart <stefan@opener.amsterdam>
86
+
87
+ Maintainers
88
+ -----------
89
+
90
+ This module is maintained by the OCA.
91
+
92
+ .. image:: https://odoo-community.org/logo.png
93
+ :alt: Odoo Community Association
94
+ :target: https://odoo-community.org
95
+
96
+ OCA, or the Odoo Community Association, is a nonprofit organization whose
97
+ mission is to support the collaborative development of Odoo features and
98
+ promote its widespread use.
99
+
100
+ .. |maintainer-florian-dacosta| image:: https://github.com/florian-dacosta.png?size=40px
101
+ :target: https://github.com/florian-dacosta
102
+ :alt: florian-dacosta
103
+
104
+ Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
105
+
106
+ |maintainer-florian-dacosta|
107
+
108
+ This module is part of the `OCA/stock-logistics-workflow <https://github.com/OCA/stock-logistics-workflow/tree/18.0/stock_restrict_lot>`_ project on GitHub.
109
+
110
+ You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
@@ -0,0 +1,29 @@
1
+ odoo/addons/stock_restrict_lot/README.rst,sha256=sREqig1ONlXq1iFWJOp0XFp8nwkezrIAAVx23vmrB4c,3711
2
+ odoo/addons/stock_restrict_lot/__init__.py,sha256=X9EJGOE2GtZbS0G82PtSXmWSZ_R8jEM0rlJTDliQjp4,21
3
+ odoo/addons/stock_restrict_lot/__manifest__.py,sha256=RHnVfGn-fn4AyEchjnlyriWBDvfXh4_LXmBaBtnOPl4,576
4
+ odoo/addons/stock_restrict_lot/i18n/es.po,sha256=lXZi8UnhBuVOh-qMlsI7EUFxDh2rFQ0ILxEjpPNI5p8,2293
5
+ odoo/addons/stock_restrict_lot/i18n/hr.po,sha256=GcmxhcFqa5Mbfv1zWhPdZHSWjps85VrSuHboxJo7H5A,2644
6
+ odoo/addons/stock_restrict_lot/i18n/it.po,sha256=C8GLt8kyIAMaka1WDwjWef_RwkMvwQ-xLWvG1J8zwYM,2589
7
+ odoo/addons/stock_restrict_lot/i18n/nl.po,sha256=F9syRUn6zI7dfZFq32lPpXWnqiVsoeMFaljdLG_u42I,2024
8
+ odoo/addons/stock_restrict_lot/i18n/nl_NL.po,sha256=ZXLRlMBda1ubPObP4a5LtgUFoevJXc2UBmA3P_tW1_c,2585
9
+ odoo/addons/stock_restrict_lot/i18n/pt.po,sha256=Qb8sXDSaA7Bf9pnGIhwHCmee7evoAaNMNtbJd-HDZsc,2023
10
+ odoo/addons/stock_restrict_lot/i18n/pt_BR.po,sha256=dI5Bx6bFUvTnFapBEh4rO92uhvmTTKzD9Ez-qXv-g3A,2026
11
+ odoo/addons/stock_restrict_lot/i18n/stock_restrict_lot.pot,sha256=nvOiQgDpfOhBpgOFZVbVfgjs12txTi-2BjnxUph6s_k,1954
12
+ odoo/addons/stock_restrict_lot/i18n/tr.po,sha256=VWOIrqnAYMtnM6CVMsPiB4KQ7zV_s2VNePQcZ1ZBnSk,2549
13
+ odoo/addons/stock_restrict_lot/models/__init__.py,sha256=3nhRO6ipFBMbcrlWXMEMR62djB3_7q2TxcUM42xYMGg,108
14
+ odoo/addons/stock_restrict_lot/models/product_product.py,sha256=sv-ZLxXqmf6UX4MII1lX7s1BsRgyiKOD_wDpo993KmU,888
15
+ odoo/addons/stock_restrict_lot/models/stock_move.py,sha256=lXtBPTeuVdu1WYWUuIONn7iCWk5FZtcuzYP9T594neo,5802
16
+ odoo/addons/stock_restrict_lot/models/stock_picking.py,sha256=0l60llnOb3tnmk-3pNF21kP1aR8vO0qu5BbbeqD3T6A,417
17
+ odoo/addons/stock_restrict_lot/models/stock_rule.py,sha256=1oOOLWBEC-inoLWHqhDxxH0Q9XXsInasxbIMLmYjQ5E,547
18
+ odoo/addons/stock_restrict_lot/readme/CONTRIBUTORS.md,sha256=Yzf9SONTbOQxjFZA7UFGibcNzh3pOkl5ZkBgHifmQvc,146
19
+ odoo/addons/stock_restrict_lot/readme/DESCRIPTION.md,sha256=jYTY5vmrg7LmJCnnJ2qwOpIVuvEaOepvYGAFy0vdlBA,289
20
+ odoo/addons/stock_restrict_lot/static/description/icon.png,sha256=6xBPJauaFOF0KDHfHgQopSc28kKvxMaeoQFQWZtfZDo,9455
21
+ odoo/addons/stock_restrict_lot/static/description/index.html,sha256=9YEJxPObI0a19oB_ejzBjwPelku0peFcW29732FZS48,13297
22
+ odoo/addons/stock_restrict_lot/tests/__init__.py,sha256=5RimjaqBd8kD55SNoLqh-g9sCmmI28hPx7IQMUX6AOQ,32
23
+ odoo/addons/stock_restrict_lot/tests/test_restrict_lot.py,sha256=k-tOml6ti2jDKBh3SLJ-Ow-fKoHTTPNplSjWqa-b4Ws,15501
24
+ odoo/addons/stock_restrict_lot/views/stock_move_views.xml,sha256=HPvaV4gaEfg_f9yEPvQATYGizkuCX098kGIpWiHr8w0,1520
25
+ odoo/addons/stock_restrict_lot/views/stock_picking.xml,sha256=s6ONtCnjx151Ob_BOyQ4BvkTs98xqcv7QoysZb8WQ3c,1225
26
+ odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/METADATA,sha256=cr6hcP92Zbwb2CyzmgkuvXc49r0jYF9PoBiS0ShRFOI,4321
27
+ odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/WHEEL,sha256=ZhOvUsYhy81Dx67gN3TV0RchQWBIIzutDZaJODDg2Vo,81
28
+ odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/top_level.txt,sha256=QE6RBQ0QX5f4eFuUcGgU5Kbq1A_qJcDs-e_vpr6pmfU,4
29
+ odoo_addon_stock_restrict_lot-18.0.1.1.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: Whool 1.3
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+