odoo14-addon-ddmrp 14.0.1.19.0__py3-none-any.whl → 14.0.1.21.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.
@@ -7,7 +7,7 @@ DDMRP
7
7
  !! This file is generated by oca-gen-addon-readme !!
8
8
  !! changes will be overwritten. !!
9
9
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10
- !! source digest: sha256:0880e8b3b2f4d608a62db62b826aa48a2f7a08121d995e40bbd59753bd6c4944
10
+ !! source digest: sha256:dd2094363f04214437dadfb8b6ed6b185062e9fb60a1308d521cf306d8d9fee9
11
11
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12
12
 
13
13
  .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -5,7 +5,7 @@
5
5
  {
6
6
  "name": "DDMRP",
7
7
  "summary": "Demand Driven Material Requirements Planning",
8
- "version": "14.0.1.19.0",
8
+ "version": "14.0.1.21.0",
9
9
  "license": "LGPL-3",
10
10
  "development_status": "Beta",
11
11
  "author": "ForgeFlow, " "Odoo Community Association (OCA)",
@@ -19,4 +19,13 @@
19
19
  <field name="source_future">estimates</field>
20
20
  <field name="horizon_future">120</field>
21
21
  </record>
22
+ <record
23
+ id="adu_calculation_method_future_120_estimates_mrp"
24
+ model="product.adu.calculation.method"
25
+ >
26
+ <field name="name">Future (Direct + Indirect)(120 days)</field>
27
+ <field name="method">future</field>
28
+ <field name="source_future">estimates_mrp</field>
29
+ <field name="horizon_future">120</field>
30
+ </record>
22
31
  </odoo>
@@ -524,11 +524,6 @@ msgstr ""
524
524
  msgid "Follow-up Notes"
525
525
  msgstr ""
526
526
 
527
- #. module: ddmrp
528
- #: model:ir.model.fields,field_description:ddmrp.field_stock_buffer__virtual_location_qty
529
- msgid "Forecast On Location"
530
- msgstr ""
531
-
532
527
  #. module: ddmrp
533
528
  #: model:ir.model.fields,field_description:ddmrp.field_product_adu_calculation_method__factor_future
534
529
  msgid "Future Factor"
@@ -694,11 +689,6 @@ msgstr ""
694
689
  msgid "Incoming (Within DLT)"
695
690
  msgstr ""
696
691
 
697
- #. module: ddmrp
698
- #: model:ir.model.fields,field_description:ddmrp.field_stock_buffer__incoming_location_qty
699
- msgid "Incoming On Location"
700
- msgstr ""
701
-
702
692
  #. module: ddmrp
703
693
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_tree
704
694
  msgid "Incoming Outside DLT"
@@ -1057,11 +1047,6 @@ msgstr ""
1057
1047
  msgid "Order Spike Threshold"
1058
1048
  msgstr ""
1059
1049
 
1060
- #. module: ddmrp
1061
- #: model:ir.model.fields,field_description:ddmrp.field_stock_buffer__outgoing_location_qty
1062
- msgid "Outgoing On Location"
1063
- msgstr ""
1064
-
1065
1050
  #. module: ddmrp
1066
1051
  #: model:ir.actions.act_window,name:ddmrp.po_line_execution_action
1067
1052
  #: model:ir.ui.menu,name:ddmrp.menu_pol_execution
@@ -1288,11 +1273,6 @@ msgstr ""
1288
1273
  msgid "Quantity On Hand (Unreserved)"
1289
1274
  msgstr ""
1290
1275
 
1291
- #. module: ddmrp
1292
- #: model:ir.model.fields,field_description:ddmrp.field_stock_buffer__product_location_qty
1293
- msgid "Quantity On Location"
1294
- msgstr ""
1295
-
1296
1276
  #. module: ddmrp
1297
1277
  #: model:ir.model.fields,help:ddmrp.field_stock_buffer__product_location_qty_available_not_res
1298
1278
  msgid ""
@@ -1679,6 +1659,7 @@ msgid "Top of Yellow"
1679
1659
  msgstr ""
1680
1660
 
1681
1661
  #. module: ddmrp
1662
+ #: model:ir.model.fields,field_description:ddmrp.field_stock_buffer__incoming_total_qty
1682
1663
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_tree
1683
1664
  msgid "Total Incoming"
1684
1665
  msgstr ""
@@ -1782,12 +1763,22 @@ msgstr ""
1782
1763
 
1783
1764
  #. module: ddmrp
1784
1765
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1785
- msgid "View ADU (Future)"
1766
+ msgid "View ADU (Future - Direct Demand)"
1767
+ msgstr ""
1768
+
1769
+ #. module: ddmrp
1770
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1771
+ msgid "View ADU (Future - Indirect Demand)"
1772
+ msgstr ""
1773
+
1774
+ #. module: ddmrp
1775
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1776
+ msgid "View ADU (Past - Direct Demand)"
1786
1777
  msgstr ""
1787
1778
 
1788
1779
  #. module: ddmrp
1789
1780
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1790
- msgid "View ADU (Past)"
1781
+ msgid "View ADU (Past - Indirect Demand)"
1791
1782
  msgstr ""
1792
1783
 
1793
1784
  #. module: ddmrp
@@ -1829,12 +1829,22 @@ msgstr ""
1829
1829
 
1830
1830
  #. module: ddmrp
1831
1831
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1832
- msgid "View ADU (Future)"
1832
+ msgid "View ADU (Future - Direct Demand)"
1833
1833
  msgstr ""
1834
1834
 
1835
1835
  #. module: ddmrp
1836
1836
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1837
- msgid "View ADU (Past)"
1837
+ msgid "View ADU (Future - Indirect Demand)"
1838
+ msgstr ""
1839
+
1840
+ #. module: ddmrp
1841
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1842
+ msgid "View ADU (Past - Direct Demand)"
1843
+ msgstr ""
1844
+
1845
+ #. module: ddmrp
1846
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1847
+ msgid "View ADU (Past - Indirect Demand)"
1838
1848
  msgstr ""
1839
1849
 
1840
1850
  #. module: ddmrp
@@ -1879,13 +1879,23 @@ msgstr "Código de Vendedor"
1879
1879
 
1880
1880
  #. module: ddmrp
1881
1881
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1882
- msgid "View ADU (Future)"
1883
- msgstr "Ver ADU (Futuro)"
1882
+ msgid "View ADU (Future - Direct Demand)"
1883
+ msgstr ""
1884
+
1885
+ #. module: ddmrp
1886
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1887
+ msgid "View ADU (Future - Indirect Demand)"
1888
+ msgstr ""
1889
+
1890
+ #. module: ddmrp
1891
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1892
+ msgid "View ADU (Past - Direct Demand)"
1893
+ msgstr ""
1884
1894
 
1885
1895
  #. module: ddmrp
1886
1896
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1887
- msgid "View ADU (Past)"
1888
- msgstr "Ver ADU (Pasado)"
1897
+ msgid "View ADU (Past - Indirect Demand)"
1898
+ msgstr ""
1889
1899
 
1890
1900
  #. module: ddmrp
1891
1901
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
@@ -2064,6 +2074,12 @@ msgstr "minutos"
2064
2074
  msgid "or"
2065
2075
  msgstr "o"
2066
2076
 
2077
+ #~ msgid "View ADU (Future)"
2078
+ #~ msgstr "Ver ADU (Futuro)"
2079
+
2080
+ #~ msgid "View ADU (Past)"
2081
+ #~ msgstr "Ver ADU (Pasado)"
2082
+
2067
2083
  #~ msgid "MRP Move"
2068
2084
  #~ msgstr "Movimientos MRP"
2069
2085
 
@@ -1801,12 +1801,22 @@ msgstr ""
1801
1801
 
1802
1802
  #. module: ddmrp
1803
1803
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1804
- msgid "View ADU (Future)"
1804
+ msgid "View ADU (Future - Direct Demand)"
1805
1805
  msgstr ""
1806
1806
 
1807
1807
  #. module: ddmrp
1808
1808
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1809
- msgid "View ADU (Past)"
1809
+ msgid "View ADU (Future - Indirect Demand)"
1810
+ msgstr ""
1811
+
1812
+ #. module: ddmrp
1813
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1814
+ msgid "View ADU (Past - Direct Demand)"
1815
+ msgstr ""
1816
+
1817
+ #. module: ddmrp
1818
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1819
+ msgid "View ADU (Past - Indirect Demand)"
1810
1820
  msgstr ""
1811
1821
 
1812
1822
  #. module: ddmrp
@@ -1797,12 +1797,22 @@ msgstr ""
1797
1797
 
1798
1798
  #. module: ddmrp
1799
1799
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1800
- msgid "View ADU (Future)"
1800
+ msgid "View ADU (Future - Direct Demand)"
1801
1801
  msgstr ""
1802
1802
 
1803
1803
  #. module: ddmrp
1804
1804
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1805
- msgid "View ADU (Past)"
1805
+ msgid "View ADU (Future - Indirect Demand)"
1806
+ msgstr ""
1807
+
1808
+ #. module: ddmrp
1809
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1810
+ msgid "View ADU (Past - Direct Demand)"
1811
+ msgstr ""
1812
+
1813
+ #. module: ddmrp
1814
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1815
+ msgid "View ADU (Past - Indirect Demand)"
1806
1816
  msgstr ""
1807
1817
 
1808
1818
  #. module: ddmrp
@@ -1879,13 +1879,23 @@ msgstr "Codice fornitore"
1879
1879
 
1880
1880
  #. module: ddmrp
1881
1881
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1882
- msgid "View ADU (Future)"
1883
- msgstr "Visualizza ADU (futuro)"
1882
+ msgid "View ADU (Future - Direct Demand)"
1883
+ msgstr ""
1884
+
1885
+ #. module: ddmrp
1886
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1887
+ msgid "View ADU (Future - Indirect Demand)"
1888
+ msgstr ""
1889
+
1890
+ #. module: ddmrp
1891
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1892
+ msgid "View ADU (Past - Direct Demand)"
1893
+ msgstr ""
1884
1894
 
1885
1895
  #. module: ddmrp
1886
1896
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1887
- msgid "View ADU (Past)"
1888
- msgstr "Visualizza ADU (passato)"
1897
+ msgid "View ADU (Past - Indirect Demand)"
1898
+ msgstr ""
1889
1899
 
1890
1900
  #. module: ddmrp
1891
1901
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
@@ -2064,3 +2074,9 @@ msgstr "minuti"
2064
2074
  #: model_terms:ir.ui.view,arch_db:ddmrp.view_run_ddmrp_wizard
2065
2075
  msgid "or"
2066
2076
  msgstr "o"
2077
+
2078
+ #~ msgid "View ADU (Future)"
2079
+ #~ msgstr "Visualizza ADU (futuro)"
2080
+
2081
+ #~ msgid "View ADU (Past)"
2082
+ #~ msgstr "Visualizza ADU (passato)"
@@ -1791,12 +1791,22 @@ msgstr ""
1791
1791
 
1792
1792
  #. module: ddmrp
1793
1793
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1794
- msgid "View ADU (Future)"
1794
+ msgid "View ADU (Future - Direct Demand)"
1795
1795
  msgstr ""
1796
1796
 
1797
1797
  #. module: ddmrp
1798
1798
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1799
- msgid "View ADU (Past)"
1799
+ msgid "View ADU (Future - Indirect Demand)"
1800
+ msgstr ""
1801
+
1802
+ #. module: ddmrp
1803
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1804
+ msgid "View ADU (Past - Direct Demand)"
1805
+ msgstr ""
1806
+
1807
+ #. module: ddmrp
1808
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1809
+ msgid "View ADU (Past - Indirect Demand)"
1800
1810
  msgstr ""
1801
1811
 
1802
1812
  #. module: ddmrp
@@ -1829,12 +1829,22 @@ msgstr ""
1829
1829
 
1830
1830
  #. module: ddmrp
1831
1831
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1832
- msgid "View ADU (Future)"
1832
+ msgid "View ADU (Future - Direct Demand)"
1833
1833
  msgstr ""
1834
1834
 
1835
1835
  #. module: ddmrp
1836
1836
  #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1837
- msgid "View ADU (Past)"
1837
+ msgid "View ADU (Future - Indirect Demand)"
1838
+ msgstr ""
1839
+
1840
+ #. module: ddmrp
1841
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1842
+ msgid "View ADU (Past - Direct Demand)"
1843
+ msgstr ""
1844
+
1845
+ #. module: ddmrp
1846
+ #: model_terms:ir.ui.view,arch_db:ddmrp.stock_buffer_view_form
1847
+ msgid "View ADU (Past - Indirect Demand)"
1838
1848
  msgstr ""
1839
1849
 
1840
1850
  #. module: ddmrp
@@ -24,6 +24,7 @@ class ProductAduCalculationMethod(models.Model):
24
24
  return [
25
25
  ("actual", "Use actual Stock Moves"),
26
26
  ("estimates", "Use Demand Estimates"),
27
+ ("estimates_mrp", "Use Demand Estimates + Indirect Demand from MRP Moves"),
27
28
  ]
28
29
 
29
30
  name = fields.Char(string="Name", required=True)
@@ -200,6 +200,18 @@ class StockBuffer(models.Model):
200
200
  action["domain"] = self._past_moves_domain(date_from, date_to, locations)
201
201
  return action
202
202
 
203
+ def _demand_estimate_domain(self, locations, date_from=False, date_to=False):
204
+ self.ensure_one()
205
+ domain = [
206
+ ("location_id", "in", locations.ids),
207
+ ("product_id", "=", self.product_id.id),
208
+ ]
209
+ if date_to:
210
+ domain += [("date_from", "<=", date_to)]
211
+ if date_from:
212
+ domain += [("date_to", ">=", date_from)]
213
+ return domain
214
+
203
215
  def action_view_stock_demand_estimates(self):
204
216
  result = self.env["ir.actions.actions"]._for_xml_id(
205
217
  "stock_demand_estimate.stock_demand_estimate_action"
@@ -207,12 +219,8 @@ class StockBuffer(models.Model):
207
219
  locations = self.env["stock.location"].search(
208
220
  [("id", "child_of", [self.location_id.id])]
209
221
  )
210
- recs = self.env["stock.demand.estimate"].search(
211
- [
212
- ("product_id", "=", self.product_id.id),
213
- ("location_id", "in", locations.ids),
214
- ]
215
- )
222
+ domain = self._demand_estimate_domain(locations)
223
+ recs = self.env["stock.demand.estimate"].search(domain)
216
224
  result["domain"] = [("id", "in", recs.ids)]
217
225
  return result
218
226
 
@@ -342,21 +350,8 @@ class StockBuffer(models.Model):
342
350
 
343
351
  # STOCK INFORMATION:
344
352
 
345
- product_location_qty = fields.Float(
346
- string="Quantity On Location", compute="_compute_product_available_qty"
347
- )
348
- incoming_location_qty = fields.Float(
349
- string="Incoming On Location", compute="_compute_product_available_qty"
350
- )
351
- outgoing_location_qty = fields.Float(
352
- string="Outgoing On Location", compute="_compute_product_available_qty"
353
- )
354
- virtual_location_qty = fields.Float(
355
- string="Forecast On Location", compute="_compute_product_available_qty"
356
- )
357
353
  product_location_qty_available_not_res = fields.Float(
358
354
  string="Quantity On Hand (Unreserved)",
359
- compute="_compute_product_available_qty",
360
355
  help="Quantity available in this stock buffer, this is the total "
361
356
  "quantity on hand minus the outgoing reservations.",
362
357
  )
@@ -375,7 +370,17 @@ class StockBuffer(models.Model):
375
370
  )
376
371
  return sum(lines.mapped("product_qty"))
377
372
 
378
- def _compute_product_available_qty(self):
373
+ def _update_quantities_dict(self, product):
374
+ self.ensure_one()
375
+ reserved_qty = self._get_outgoing_reservation_qty()
376
+ self.update(
377
+ {
378
+ "product_location_qty_available_not_res": product["qty_available"]
379
+ - reserved_qty,
380
+ }
381
+ )
382
+
383
+ def _calc_product_available_qty(self):
379
384
  operation_by_location = defaultdict(lambda: self.browse())
380
385
  for rec in self:
381
386
  operation_by_location[rec.location_id] |= rec
@@ -391,19 +396,7 @@ class StockBuffer(models.Model):
391
396
  )
392
397
  for buffer in buffer_in_location:
393
398
  product = products[buffer.product_id.id]
394
- reserved_qty = buffer._get_outgoing_reservation_qty()
395
- buffer.update(
396
- {
397
- "product_location_qty": product["qty_available"],
398
- "incoming_location_qty": product["incoming_qty"],
399
- "outgoing_location_qty": product["outgoing_qty"],
400
- "virtual_location_qty": product["virtual_available"],
401
- "product_location_qty_available_not_res": product[
402
- "qty_available"
403
- ]
404
- - reserved_qty,
405
- }
406
- )
399
+ buffer._update_quantities_dict(product)
407
400
 
408
401
  # PURCHASES LINK:
409
402
 
@@ -1160,6 +1153,10 @@ class StockBuffer(models.Model):
1160
1153
  qualified_demand_mrp_move_ids = fields.Many2many(
1161
1154
  comodel_name="mrp.move",
1162
1155
  )
1156
+ incoming_total_qty = fields.Float(
1157
+ string="Total Incoming",
1158
+ readonly=True,
1159
+ )
1163
1160
  incoming_dlt_qty = fields.Float(
1164
1161
  string="Incoming (Within DLT)",
1165
1162
  readonly=True,
@@ -1341,7 +1338,6 @@ class StockBuffer(models.Model):
1341
1338
  "in",
1342
1339
  ["draft", "waiting", "confirmed", "partially_available", "assigned"],
1343
1340
  ),
1344
- ("location_dest_id", "=", self.location_id.id),
1345
1341
  ]
1346
1342
 
1347
1343
  @api.model
@@ -1369,8 +1365,11 @@ class StockBuffer(models.Model):
1369
1365
  # Utility method used to add an "Open Moves" button in the buffer
1370
1366
  # planning view
1371
1367
  domain = self._search_open_stock_moves_domain()
1372
- records = self.env["stock.move"].search(domain)
1373
- return self._stock_move_tree_view(records)
1368
+ moves = self.env["stock.move"].search(domain)
1369
+ moves = moves.filtered(
1370
+ lambda move: move.location_dest_id.is_sublocation_of(self.location_id)
1371
+ )
1372
+ return self._stock_move_tree_view(moves)
1374
1373
 
1375
1374
  def _get_horizon_adu_past_demand(self):
1376
1375
  return self.adu_calculation_method.horizon_past or 0
@@ -1384,13 +1383,15 @@ class StockBuffer(models.Model):
1384
1383
  )
1385
1384
  return date_from, date_to
1386
1385
 
1387
- def _past_demand_estimate_domain(self, date_from, date_to, locations):
1386
+ def _past_mrp_move_domain(self, date_from, date_to, locations):
1388
1387
  self.ensure_one()
1389
1388
  return [
1390
- ("location_id", "in", locations.ids),
1391
1389
  ("product_id", "=", self.product_id.id),
1392
- ("date_from", "<=", date_to),
1393
- ("date_to", ">=", date_from),
1390
+ ("mrp_date", "<=", date_to),
1391
+ ("mrp_date", ">=", date_from),
1392
+ ("mrp_area_id.location_id", "in", locations.ids),
1393
+ ("mrp_type", "=", "d"),
1394
+ ("mrp_origin", "in", ["mrp", "mo"]),
1394
1395
  ]
1395
1396
 
1396
1397
  def _past_moves_domain(self, date_from, date_to, locations):
@@ -1419,24 +1420,24 @@ class StockBuffer(models.Model):
1419
1420
  .with_context(active_test=False)
1420
1421
  .search([("id", "child_of", self.location_id.ids)])
1421
1422
  )
1422
- if self.adu_calculation_method.source_past == "estimates":
1423
- qty = 0.0
1424
- domain = self._past_demand_estimate_domain(date_from, date_to, locations)
1423
+ qty = 0.0
1424
+ if self.adu_calculation_method.source_past == "estimates_mrp":
1425
+ domain = self._past_mrp_move_domain(date_from, date_to, locations)
1426
+ for mrp_move in self.env["mrp.move"].search(domain):
1427
+ qty += -mrp_move.mrp_qty
1428
+ if self.adu_calculation_method.source_past in ["estimates", "estimates_mrp"]:
1429
+ domain = self._demand_estimate_domain(locations, date_from, date_to)
1425
1430
  for estimate in self.env["stock.demand.estimate"].search(domain):
1426
1431
  qty += estimate.get_quantity_by_date_range(
1427
1432
  fields.Date.from_string(date_from), fields.Date.from_string(date_to)
1428
1433
  )
1429
- return qty / horizon
1430
1434
  elif self.adu_calculation_method.source_past == "actual":
1431
- qty = 0.0
1432
1435
  domain = self._past_moves_domain(date_from, date_to, locations)
1433
1436
  for group in self.env["stock.move"].read_group(
1434
1437
  domain, ["product_id", "product_qty"], ["product_id"]
1435
1438
  ):
1436
1439
  qty += group["product_qty"]
1437
- return qty / horizon
1438
- else:
1439
- return 0.0
1440
+ return qty / horizon
1440
1441
 
1441
1442
  def _get_horizon_adu_future_demand(self):
1442
1443
  return self.adu_calculation_method.horizon_future or 1
@@ -1451,13 +1452,15 @@ class StockBuffer(models.Model):
1451
1452
  )
1452
1453
  return date_from, date_to
1453
1454
 
1454
- def _future_demand_estimate_domain(self, date_from, date_to, locations):
1455
+ def _future_mrp_move_domain(self, date_from, date_to, locations):
1455
1456
  self.ensure_one()
1456
1457
  return [
1457
- ("location_id", "in", locations.ids),
1458
1458
  ("product_id", "=", self.product_id.id),
1459
- ("date_from", "<=", date_to),
1460
- ("date_to", ">=", date_from),
1459
+ ("mrp_date", "<=", date_to),
1460
+ ("mrp_date", ">=", date_from),
1461
+ ("mrp_area_id.location_id", "in", locations.ids),
1462
+ ("mrp_type", "=", "d"),
1463
+ ("mrp_origin", "in", ["mrp", "mo"]),
1461
1464
  ]
1462
1465
 
1463
1466
  def _future_moves_domain(self, date_from, date_to, locations):
@@ -1482,24 +1485,24 @@ class StockBuffer(models.Model):
1482
1485
  locations = self.env["stock.location"].search(
1483
1486
  [("id", "child_of", [self.location_id.id])]
1484
1487
  )
1485
- if self.adu_calculation_method.source_future == "estimates":
1486
- qty = 0.0
1487
- domain = self._future_demand_estimate_domain(date_from, date_to, locations)
1488
+ qty = 0.0
1489
+ if self.adu_calculation_method.source_future == "estimates_mrp":
1490
+ domain = self._future_mrp_move_domain(date_from, date_to, locations)
1491
+ for mrp_move in self.env["mrp.move"].search(domain):
1492
+ qty += -mrp_move.mrp_qty
1493
+ if self.adu_calculation_method.source_future in ["estimates", "estimates_mrp"]:
1494
+ domain = self._demand_estimate_domain(locations, date_from, date_to)
1488
1495
  for estimate in self.env["stock.demand.estimate"].search(domain):
1489
1496
  qty += estimate.get_quantity_by_date_range(
1490
1497
  fields.Date.from_string(date_from), fields.Date.from_string(date_to)
1491
1498
  )
1492
- return qty / horizon
1493
1499
  elif self.adu_calculation_method.source_future == "actual":
1494
- qty = 0.0
1495
1500
  domain = self._future_moves_domain(date_from, date_to, locations)
1496
1501
  for group in self.env["stock.move"].read_group(
1497
1502
  domain, ["product_id", "product_qty"], ["product_id"]
1498
1503
  ):
1499
1504
  qty += group["product_qty"]
1500
- return qty / horizon
1501
- else:
1502
- return 0.0
1505
+ return qty / horizon
1503
1506
 
1504
1507
  def _calc_adu_blended(self):
1505
1508
  self.ensure_one()
@@ -1677,6 +1680,7 @@ class StockBuffer(models.Model):
1677
1680
  rec.rfq_outside_dlt_qty = sum(pols.mapped("product_qty"))
1678
1681
  else:
1679
1682
  rec.rfq_outside_dlt_qty = 0.0
1683
+ rec.incoming_total_qty = rec.incoming_dlt_qty + rec.incoming_outside_dlt_qty
1680
1684
  return True
1681
1685
 
1682
1686
  def _calc_net_flow_position(self):
@@ -1743,6 +1747,7 @@ class StockBuffer(models.Model):
1743
1747
  records = super().create(vals_list)
1744
1748
  if not self.env.context.get("skip_adu_calculation", False):
1745
1749
  records._calc_adu()
1750
+ records._calc_product_available_qty()
1746
1751
  records._calc_distributed_source_location()
1747
1752
  return records
1748
1753
 
@@ -1871,7 +1876,7 @@ class StockBuffer(models.Model):
1871
1876
  result["domain"] = [("id", "in", mrp_moves.ids)]
1872
1877
  return result
1873
1878
 
1874
- def action_view_past_adu(self):
1879
+ def action_view_past_adu_direct_demand(self):
1875
1880
  horizon = self._get_horizon_adu_past_demand()
1876
1881
  date_from, date_to = self._get_dates_adu_past_demand(horizon)
1877
1882
  locations = self.env["stock.location"].search(
@@ -1886,7 +1891,7 @@ class StockBuffer(models.Model):
1886
1891
  result["context"] = {}
1887
1892
  result["domain"] = [("id", "in", moves.ids)]
1888
1893
  else:
1889
- domain = self._past_demand_estimate_domain(date_from, date_to, locations)
1894
+ domain = self._demand_estimate_domain(locations, date_from, date_to)
1890
1895
  estimates = self.env["stock.demand.estimate"].search(domain)
1891
1896
  result = self.env["ir.actions.actions"]._for_xml_id(
1892
1897
  "stock_demand_estimate.stock_demand_estimate_action"
@@ -1895,7 +1900,22 @@ class StockBuffer(models.Model):
1895
1900
  result["domain"] = [("id", "in", estimates.ids)]
1896
1901
  return result
1897
1902
 
1898
- def action_view_future_adu(self):
1903
+ def action_view_past_adu_indirect_demand(self):
1904
+ horizon = self._get_horizon_adu_past_demand()
1905
+ date_from, date_to = self._get_dates_adu_past_demand(horizon)
1906
+ locations = self.env["stock.location"].search(
1907
+ [("id", "child_of", [self.location_id.id])]
1908
+ )
1909
+ domain = self._past_mrp_move_domain(date_from, date_to, locations)
1910
+ mrp_moves = self.env["mrp.move"].search(domain)
1911
+ result = self.env["ir.actions.actions"]._for_xml_id(
1912
+ "mrp_multi_level.mrp_move_action"
1913
+ )
1914
+ result["context"] = {}
1915
+ result["domain"] = [("id", "in", mrp_moves.ids)]
1916
+ return result
1917
+
1918
+ def action_view_future_adu_direct_demand(self):
1899
1919
  horizon = self._get_horizon_adu_future_demand()
1900
1920
  date_from, date_to = self._get_dates_adu_future_demand(horizon)
1901
1921
  locations = self.env["stock.location"].search(
@@ -1910,7 +1930,7 @@ class StockBuffer(models.Model):
1910
1930
  result["context"] = {}
1911
1931
  result["domain"] = [("id", "in", moves.ids)]
1912
1932
  else:
1913
- domain = self._future_demand_estimate_domain(date_from, date_to, locations)
1933
+ domain = self._demand_estimate_domain(locations, date_from, date_to)
1914
1934
  estimates = self.env["stock.demand.estimate"].search(domain)
1915
1935
  result = self.env["ir.actions.actions"]._for_xml_id(
1916
1936
  "stock_demand_estimate.stock_demand_estimate_action"
@@ -1919,6 +1939,21 @@ class StockBuffer(models.Model):
1919
1939
  result["domain"] = [("id", "in", estimates.ids)]
1920
1940
  return result
1921
1941
 
1942
+ def action_view_future_adu_indirect_demand(self):
1943
+ horizon = self._get_horizon_adu_future_demand()
1944
+ date_from, date_to = self._get_dates_adu_future_demand(horizon)
1945
+ locations = self.env["stock.location"].search(
1946
+ [("id", "child_of", [self.location_id.id])]
1947
+ )
1948
+ domain = self._future_mrp_move_domain(date_from, date_to, locations)
1949
+ mrp_moves = self.env["mrp.move"].search(domain)
1950
+ result = self.env["ir.actions.actions"]._for_xml_id(
1951
+ "mrp_multi_level.mrp_move_action"
1952
+ )
1953
+ result["context"] = {}
1954
+ result["domain"] = [("id", "in", mrp_moves.ids)]
1955
+ return result
1956
+
1922
1957
  @api.model
1923
1958
  def cron_ddmrp_adu(self, automatic=False):
1924
1959
  """calculate ADU for each DDMRP buffer. Called by cronjob."""
@@ -1957,16 +1992,13 @@ class StockBuffer(models.Model):
1957
1992
  self.ensure_one()
1958
1993
  self.invalidate_cache(
1959
1994
  fnames=[
1960
- "product_location_qty",
1961
- "incoming_location_qty",
1962
- "outgoing_location_qty",
1963
- "virtual_location_qty",
1964
1995
  "product_location_qty_available_not_res",
1965
1996
  "dlt",
1966
1997
  "distributed_source_location_qty",
1967
1998
  ],
1968
1999
  ids=self.ids,
1969
2000
  )
2001
+ self._calc_product_available_qty()
1970
2002
  if not only_nfp or only_nfp == "out":
1971
2003
  self._calc_qualified_demand()
1972
2004
  if not only_nfp or only_nfp == "in":
@@ -7,6 +7,6 @@ from odoo import fields, models
7
7
  class StockMoveLine(models.Model):
8
8
  _inherit = "stock.move.line"
9
9
 
10
- # Override to make '_compute_product_available_qty' method of
10
+ # Override to make '_calc_product_available_qty' method of
11
11
  # 'stock.buffer' more efficient.
12
12
  state = fields.Selection(index=True)
@@ -367,7 +367,7 @@ ul.auto-toc {
367
367
  !! This file is generated by oca-gen-addon-readme !!
368
368
  !! changes will be overwritten. !!
369
369
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
370
- !! source digest: sha256:0880e8b3b2f4d608a62db62b826aa48a2f7a08121d995e40bbd59753bd6c4944
370
+ !! source digest: sha256:dd2094363f04214437dadfb8b6ed6b185062e9fb60a1308d521cf306d8d9fee9
371
371
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
372
372
  <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/ddmrp/tree/14.0/ddmrp"><img alt="OCA/ddmrp" src="https://img.shields.io/badge/github-OCA%2Fddmrp-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/ddmrp-14-0/ddmrp-14-0-ddmrp"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/ddmrp&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
373
373
  <p>Demand Driven Material Requirements Planning is a formal multi-echelon
@@ -1104,3 +1104,98 @@ class TestDdmrp(TestDdmrpCommon):
1104
1104
  buffer_distributed.distributed_source_location_id,
1105
1105
  self.warehouse.lot_stock_id,
1106
1106
  )
1107
+
1108
+ def test_45_adu_calculation_blended_120_days_estimated_mrp(self):
1109
+ """Test blended ADU calculation method with direct and indirect demand."""
1110
+ mrpMoveModel = self.env["mrp.move"]
1111
+ mrpAreaModel = self.env["mrp.area"]
1112
+ productMrpAreaModel = self.env["product.mrp.area"]
1113
+ method = self.aducalcmethodModel.create(
1114
+ {
1115
+ "name": "Blended (120 d. estimates_mrp past, 120 d. estimates_mrp future)",
1116
+ "method": "blended",
1117
+ "source_past": "estimates_mrp",
1118
+ "horizon_past": 120,
1119
+ "factor_past": 0.5,
1120
+ "source_future": "estimates_mrp",
1121
+ "horizon_future": 120,
1122
+ "factor_future": 0.5,
1123
+ "company_id": self.main_company.id,
1124
+ }
1125
+ )
1126
+ self.buffer_a.adu_calculation_method = method.id
1127
+ mrp_area_id = mrpAreaModel.create(
1128
+ {
1129
+ "name": "WH/Stock",
1130
+ "warehouse_id": self.warehouse.id,
1131
+ "location_id": self.stock_location.id,
1132
+ }
1133
+ )
1134
+ product_mrp_area_id = productMrpAreaModel.create(
1135
+ {
1136
+ "mrp_area_id": mrp_area_id.id,
1137
+ "product_id": self.productA.id,
1138
+ }
1139
+ )
1140
+ today = fields.Date.today()
1141
+
1142
+ # Past.
1143
+ # create estimate: 120 units / 120 days = 1 unit/day
1144
+ # create mrp move: 120 units / 120 days = 1 unit/day
1145
+ dt = self.calendar.plan_days(-1 * 120, datetime.today())
1146
+ estimate_date_from = dt.date()
1147
+ estimate_date_to = (datetime.today() - timedelta(days=1)).date()
1148
+ self.estimateModel.create(
1149
+ {
1150
+ "manual_date_from": estimate_date_from,
1151
+ "manual_date_to": estimate_date_to,
1152
+ "product_id": self.productA.id,
1153
+ "product_uom_qty": 120,
1154
+ "product_uom": self.productA.uom_id.id,
1155
+ "location_id": self.stock_location.id,
1156
+ }
1157
+ )
1158
+ mrpMoveModel.create(
1159
+ {
1160
+ "mrp_area_id": product_mrp_area_id.mrp_area_id.id,
1161
+ "product_id": product_mrp_area_id.product_id.id,
1162
+ "product_mrp_area_id": product_mrp_area_id.id,
1163
+ "mrp_qty": -120,
1164
+ "current_qty": 0,
1165
+ "mrp_date": today - timedelta(days=5),
1166
+ "current_date": None,
1167
+ "mrp_type": "d",
1168
+ "mrp_origin": "mrp",
1169
+ }
1170
+ )
1171
+
1172
+ # Future.
1173
+ # create estimate: 120 units / 120 days = 1 unit/day
1174
+ # create mrp move: 120 units / 120 days = 1 unit/day
1175
+ self.estimateModel.create(
1176
+ {
1177
+ "manual_date_from": self.estimate_date_from,
1178
+ "manual_date_to": self.estimate_date_to,
1179
+ "product_id": self.productA.id,
1180
+ "product_uom_qty": 120,
1181
+ "product_uom": self.productA.uom_id.id,
1182
+ "location_id": self.stock_location.id,
1183
+ }
1184
+ )
1185
+ mrpMoveModel.create(
1186
+ {
1187
+ "mrp_area_id": product_mrp_area_id.mrp_area_id.id,
1188
+ "product_id": product_mrp_area_id.product_id.id,
1189
+ "product_mrp_area_id": product_mrp_area_id.id,
1190
+ "mrp_qty": -120,
1191
+ "current_qty": 0,
1192
+ "mrp_date": today + timedelta(days=5),
1193
+ "current_date": None,
1194
+ "mrp_type": "d",
1195
+ "mrp_origin": "mrp",
1196
+ }
1197
+ )
1198
+
1199
+ self.bufferModel.cron_ddmrp_adu()
1200
+ to_assert_value = 2 * 0.5 + 2 * 0.5
1201
+ self.assertEqual(self.buffer_a.adu, to_assert_value)
@@ -39,7 +39,7 @@
39
39
  />
40
40
  <field name="incoming_dlt_qty" string="Incoming Within DLT" />
41
41
  <field
42
- name="incoming_location_qty"
42
+ name="incoming_total_qty"
43
43
  string="Total Incoming"
44
44
  optional="show"
45
45
  />
@@ -230,19 +230,33 @@
230
230
  <div name="adu" class="o_row">
231
231
  <field name="adu" force_save="1" />
232
232
  <button
233
- title="View ADU (Past)"
234
- name="action_view_past_adu"
233
+ title="View ADU (Past - Direct Demand)"
234
+ name="action_view_past_adu_direct_demand"
235
235
  icon="fa-search"
236
236
  type="object"
237
237
  attrs="{'invisible': ['|', ('adu_calculation_method_type', 'in', ['fixed', 'future']), ('adu', '=', 0)]}"
238
238
  />
239
239
  <button
240
- title="View ADU (Future)"
241
- name="action_view_future_adu"
240
+ title="View ADU (Past - Indirect Demand)"
241
+ name="action_view_past_adu_indirect_demand"
242
+ icon="fa-search"
243
+ type="object"
244
+ attrs="{'invisible': ['|', '|', ('adu_calculation_method_type', 'in', ['fixed', 'future']), ('used_in_bom_count', '=', 0), ('adu', '=', 0)]}"
245
+ />
246
+ <button
247
+ title="View ADU (Future - Direct Demand)"
248
+ name="action_view_future_adu_direct_demand"
242
249
  icon="fa-search"
243
250
  type="object"
244
251
  attrs="{'invisible': ['|', ('adu_calculation_method_type', 'in', ['fixed', 'past']), ('adu', '=', 0)]}"
245
252
  />
253
+ <button
254
+ title="View ADU (Future - Indirect Demand)"
255
+ name="action_view_future_adu_indirect_demand"
256
+ icon="fa-search"
257
+ type="object"
258
+ attrs="{'invisible': ['|', '|', ('adu_calculation_method_type', 'in', ['fixed', 'past']), ('used_in_bom_count', '=', 0), ('adu', '=', 0)]}"
259
+ />
246
260
  </div>
247
261
  <field
248
262
  name="lead_days"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: odoo14-addon-ddmrp
3
- Version: 14.0.1.19.0
3
+ Version: 14.0.1.21.0
4
4
  Summary: Demand Driven Material Requirements Planning
5
5
  Home-page: https://github.com/OCA/ddmrp
6
6
  Author: ForgeFlow, Odoo Community Association (OCA)
@@ -31,7 +31,7 @@ DDMRP
31
31
  !! This file is generated by oca-gen-addon-readme !!
32
32
  !! changes will be overwritten. !!
33
33
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
34
- !! source digest: sha256:0880e8b3b2f4d608a62db62b826aa48a2f7a08121d995e40bbd59753bd6c4944
34
+ !! source digest: sha256:dd2094363f04214437dadfb8b6ed6b185062e9fb60a1308d521cf306d8d9fee9
35
35
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
36
36
 
37
37
  .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -1,11 +1,11 @@
1
- odoo/addons/ddmrp/README.rst,sha256=GbUfrJgaxi_8WLuUnoy7vRynIr3X_iaHAlSIXzbdJa4,12239
1
+ odoo/addons/ddmrp/README.rst,sha256=5li1ckLjDz38DfYUVdQklUYoZJeuhfA0JUCsFzUrsGo,12239
2
2
  odoo/addons/ddmrp/__init__.py,sha256=nksc4q8fpyy8n5h1T3-Wl9lh_CpdgZj9bBt5fQGvW5Y,98
3
- odoo/addons/ddmrp/__manifest__.py,sha256=8pAeo0MDM6ttz76VbpsPvVAMYcQVzmF53W40lgbZXo0,2472
3
+ odoo/addons/ddmrp/__manifest__.py,sha256=i6Q_pPQoVmwWWfU8NONau2dt366HcoP9qvhNB0ZNdJs,2472
4
4
  odoo/addons/ddmrp/hooks.py,sha256=81CupDt-4OpjEz7EXiAyqkUHzZ_cYLI5WiyEO6Y4DdQ,3269
5
5
  odoo/addons/ddmrp/data/decimal_precision_data.xml,sha256=mzYy_aam6bZLGPFl7HPhRv5XGTDCbHAKVZeAl0UYms4,528
6
6
  odoo/addons/ddmrp/data/ir_cron.xml,sha256=sW-Y2O0ZfpxQ6IcOOMGzgPX2k-vnSJbKxdcRD_6ybhY,1510
7
7
  odoo/addons/ddmrp/data/ir_sequence.xml,sha256=8EQIchapKj5Mmk0CE2gNzL7GuIOm3l9BrYU-QysaMzE,455
8
- odoo/addons/ddmrp/data/product_adu_calculation_method_data.xml,sha256=I6kTNR1VZjSCcTeMu4AoWRsz-qoltHntXFxDTO36QPs,870
8
+ odoo/addons/ddmrp/data/product_adu_calculation_method_data.xml,sha256=ifGCN9OnGgFHUo30YHnlNjGxDnoifR4DLxOkV7oxgBs,1233
9
9
  odoo/addons/ddmrp/data/stock_buffer_profile_data.xml,sha256=zn4449PamEWO208h--GlToeqXgQsJLhwpF_GzEY8o-A,36339
10
10
  odoo/addons/ddmrp/data/stock_buffer_profile_lead_time_data.xml,sha256=aOE280q8PE3mb_LbSDgVQDlz7pSPovV4VcJufimwnWE,703
11
11
  odoo/addons/ddmrp/data/stock_buffer_profile_variability_data.xml,sha256=48W7aW9J9JuK8lWQF7FJJP9OQwOTWQC9H0KLASdvw5Y,711
@@ -16,31 +16,31 @@ odoo/addons/ddmrp/demo/product_product_demo.xml,sha256=-jp5RGrexRsHIITmPhUGKClat
16
16
  odoo/addons/ddmrp/demo/product_supplierinfo_demo.xml,sha256=cfbqUhoZbhvEqNUwX4jIu3fckMa9yvDUPh6Sfg1jUM0,768
17
17
  odoo/addons/ddmrp/demo/res_partner_demo.xml,sha256=9MG3stWjWBzbLm_94f7IIZ-1K6a19vwmq3XwAA1Nrrs,766
18
18
  odoo/addons/ddmrp/demo/stock_buffer_demo.xml,sha256=R5fo0T_M05zLKCKm2KREjx2QlFo-7zCOKIU46QvwluY,1366
19
- odoo/addons/ddmrp/i18n/ddmrp.pot,sha256=8IgVosdl4h5O5F11g3p1QfKCnW65aREZuMZbqT5_zNE,65780
20
- odoo/addons/ddmrp/i18n/es.po,sha256=I9kB9KDnqXL0cf2G5JVttV7EmEp3pSTmSboGuHT-_5s,73628
21
- odoo/addons/ddmrp/i18n/es_AR.po,sha256=Y1b7fDtyH0rZyj8kRM9-Is9dwj80gokV8V25R-Htr1U,80639
22
- odoo/addons/ddmrp/i18n/fr.po,sha256=W0HffTzzkyFfXmw_faHIXerJNlAlzS1kvmRxwNdEJtw,67185
23
- odoo/addons/ddmrp/i18n/id.po,sha256=nsHZmGKzD60b_hTF-VpDkp11lbIZdClXYIJm5iKXw8A,66576
24
- odoo/addons/ddmrp/i18n/it.po,sha256=rta5RCrttMSQoijVvtBjCSHGKMX7u4tSDj7y45QTtO4,80108
25
- odoo/addons/ddmrp/i18n/pt_BR.po,sha256=cPVMyRRTLlbU5WthogYsxqTDWhZFk7jXPOO89eYnYYQ,65865
26
- odoo/addons/ddmrp/i18n/zh_Hans.po,sha256=n8T4KuE6fGLNCjPy5MSl6-FpkrZwcSORZ4oy957Ws_s,68903
19
+ odoo/addons/ddmrp/i18n/ddmrp.pot,sha256=-O3S5-4yDFC9om4kav4j6KUFveSMquByDK3BK41JJsk,65578
20
+ odoo/addons/ddmrp/i18n/es.po,sha256=24nY_Ai20z6pGrgFOUGS1k0n8rVOSST9TweUW8sExtw,73928
21
+ odoo/addons/ddmrp/i18n/es_AR.po,sha256=YFj0xQo3rNPpyJniqgQ6kgczGHuLZmXSMv2vMzdNp6E,81023
22
+ odoo/addons/ddmrp/i18n/fr.po,sha256=Wgdrk2u9lachRxbfKm-tcGx8kZNdBCUz-9CUC9tH7N0,67485
23
+ odoo/addons/ddmrp/i18n/id.po,sha256=sv_vJeseu6vYPmgM-ZY4W4G3ggErxuAMrUZJwuwhIDg,66876
24
+ odoo/addons/ddmrp/i18n/it.po,sha256=t9FdnKTUWrNKWAS7kCBU_iPmlemXPWinjOeQJHUq_AM,80492
25
+ odoo/addons/ddmrp/i18n/pt_BR.po,sha256=baXegWdxZMdGKuZZftd3k9l3y98UsdG665feNYu9tMA,66165
26
+ odoo/addons/ddmrp/i18n/zh_Hans.po,sha256=6GhQxU06cJSfl4JQ4akrRW5hxwSypjQ5YqkOuxofTew,69203
27
27
  odoo/addons/ddmrp/migrations/14.0.1.14.1/post-fix_distributed_source_location.py,sha256=1c02vpmyKZeDpQ3E9oHMmFCn9ad2CUEh8vAL6HjbPhI,289
28
28
  odoo/addons/ddmrp/migrations/14.0.1.6.0/post-migration.py,sha256=nz4eRPsr2J_HwTwcJ3VZtH98xqpyPXndYuNgMH-U__A,533
29
29
  odoo/addons/ddmrp/models/__init__.py,sha256=KiU2xBuUtylJnncjZkELtZPkEG_CwPXA8k_0YbH4LT0,536
30
30
  odoo/addons/ddmrp/models/mrp_bom.py,sha256=mEmZExDIVGn9hFHQ49erjQF7p7DDTtZnUWKm4sgqSgg,5462
31
31
  odoo/addons/ddmrp/models/mrp_production.py,sha256=hhTkhNb-cXl7cmWPa-ECh0EKSxE4B12Oza0XR9N3BZs,2732
32
32
  odoo/addons/ddmrp/models/procurement_group.py,sha256=nGmhn_ZGtYeRwNaV12PRFrC1bmVhsr9JVJ_c_Us2ZLA,2270
33
- odoo/addons/ddmrp/models/product_adu_calculation_method.py,sha256=Qe4FPb4rBV3JHFlN4gtrsoNAJ6rQoOW-f9RcJUI4R30,3648
33
+ odoo/addons/ddmrp/models/product_adu_calculation_method.py,sha256=AeQ-o78SfrjkW7R9OnzzkMXVUs9jKL5-loNTbQlEoHk,3736
34
34
  odoo/addons/ddmrp/models/product_product.py,sha256=oMzmvqX6waFk3TXTrK6AeOzlBpHEJ6WGuxx_r-Z0M7w,1099
35
35
  odoo/addons/ddmrp/models/product_template.py,sha256=sUUZ8kO3V5Cd7phAopCtd_wuMS_7JUR1giVamnPrI54,975
36
36
  odoo/addons/ddmrp/models/purchase_order.py,sha256=9kLCSlskdC-1uDBgAdM4zna-Lw18EB3mIlvci5fo54E,3732
37
37
  odoo/addons/ddmrp/models/res_company.py,sha256=7yGp6UwS0mtoTRY4a4khfufqadLs80pJDEVUnw8icOY,657
38
- odoo/addons/ddmrp/models/stock_buffer.py,sha256=7tnjXbd0qYZiI09Y8Brfp8wWJ5b2ARVqIYPbnw2IoOw,77140
38
+ odoo/addons/ddmrp/models/stock_buffer.py,sha256=5gqIAXd9TGtIaqtS3d4nVjlMFF4fxG_460AkAbtGgN0,78656
39
39
  odoo/addons/ddmrp/models/stock_buffer_profile.py,sha256=a4jPw9tmIPJxbIm89QKHLlpxY0coJmWu7sY88QfY_Lg,2855
40
40
  odoo/addons/ddmrp/models/stock_buffer_profile_lead_time.py,sha256=8ZQMuxU0a-mob6MIzDSnkTvC3-4KGn4NLtQ2D3Cuwi8,592
41
41
  odoo/addons/ddmrp/models/stock_buffer_profile_variability.py,sha256=vMz4mSk2h2GVqhFidlZgpC3BXGMlyu9zjHm0aO5B7is,601
42
42
  odoo/addons/ddmrp/models/stock_move.py,sha256=tVOykcNZ5ApOMjsvseCP-FQwdWzXlGc-00WdFdeP624,3596
43
- odoo/addons/ddmrp/models/stock_move_line.py,sha256=1oVcxoyzcadBlNjm5fWDbI5g0GSRC7NkrtHN7yxYpp8,342
43
+ odoo/addons/ddmrp/models/stock_move_line.py,sha256=dJleguJeIUkfzl4dqeFQvLYo60gO4mjYVBukrkJhYFY,339
44
44
  odoo/addons/ddmrp/models/stock_picking.py,sha256=nZg-VTJvlWPYi0U_9JyTaVLww-fCGyy_ONgaf5MpV48,710
45
45
  odoo/addons/ddmrp/models/stock_rule.py,sha256=GHeUZFKfO0IS26epDMLYhJ-bjRjhs-j9uf4DioLoCcQ,2811
46
46
  odoo/addons/ddmrp/models/stock_warehouse.py,sha256=-c8hMCLGqYDFtGoFeA6AYefwyr2Czff60aCv8IzNYNg,524
@@ -59,7 +59,7 @@ odoo/addons/ddmrp/security/ddmrp_groups.xml,sha256=dW2V1aZD5w9ssvtfaxy73jRf53sNh
59
59
  odoo/addons/ddmrp/security/ddmrp_rules.xml,sha256=W1hYvw6WtAKMLytNHzpQgX0aCx9PTM3fWsmcxrqXL88,2079
60
60
  odoo/addons/ddmrp/security/ir.model.access.csv,sha256=BMRQVRUcOKX6CV6k3SFCUG54QkcD-OIFqXUTl5GpGVg,2153
61
61
  odoo/addons/ddmrp/static/description/icon.png,sha256=QThDd6zhQU48MY3Y7Ij5m6yWQACbl0BCyoaHLL9-hAQ,7006
62
- odoo/addons/ddmrp/static/description/index.html,sha256=4gUSSE6zJ-GTHYhC22P0K6vi-7CSJqweiqUJiSn4qY0,26581
62
+ odoo/addons/ddmrp/static/description/index.html,sha256=QYFHRNTql24c20LqHVM-09ARhSpP2mErFyQh072_sVo,26581
63
63
  odoo/addons/ddmrp/static/img/has_mto_rule.png,sha256=IVYC3_qpiYrSTPfruURd7kQkwpaOnBlQ1Id3WAJisRo,4604
64
64
  odoo/addons/ddmrp/static/img/is_buffered.png,sha256=uGFYPIo5YIE9TO96uu8-LfHAlAtKN97H9j1Ik74hcHQ,5000
65
65
  odoo/addons/ddmrp/static/img/res_partner_eficent-image.jpg,sha256=ja8mU9YHbRwEDOHbXE5ROiKhABWqq4YFQ7cZwHWAqPA,24419
@@ -68,7 +68,7 @@ odoo/addons/ddmrp/static/src/js/list_renderer_buffer_info.js,sha256=BBCLCM0LkHew
68
68
  odoo/addons/ddmrp/static/src/scss/list_view.scss,sha256=Z-pJ16rXrnBxprxg9QEOHODf90fXUrMFnA1if1wGg2w,447
69
69
  odoo/addons/ddmrp/tests/__init__.py,sha256=-3cd_5sIPTRJYKEh4j7ipqKG_hNwXbAu_Gcr0ZM_DJ0,123
70
70
  odoo/addons/ddmrp/tests/common.py,sha256=82j8fL0il73a1jKQvRdC8y9ores6EGRQGOoS_FkPOUc,18594
71
- odoo/addons/ddmrp/tests/test_ddmrp.py,sha256=ieLL93MUvFtq7iiCqmaPKeATpehTWnraG5oFbInwQ-8,47727
71
+ odoo/addons/ddmrp/tests/test_ddmrp.py,sha256=0uVOyLfniDzSHFz74kMXlzSCyvThYeNtL6B4rOcTRy8,51410
72
72
  odoo/addons/ddmrp/tests/test_ddmrp_distributed_source_location.py,sha256=ibWkRTUt-0dYrnNwas9Y11pjmrE9mgcFxoMc-vTkR-0,6938
73
73
  odoo/addons/ddmrp/tests/test_distributed_max_proc_time.py,sha256=pYY2JH7WOQxq6bxzg_zy-MD3_y6vsp8HvDmvg_U8YDk,5519
74
74
  odoo/addons/ddmrp/views/ddmrp_assets_backend.xml,sha256=IHuM6eKSo0QluTtp8B2Ndo3AE8CfTGUQD2b54NJjsB0,570
@@ -81,7 +81,7 @@ odoo/addons/ddmrp/views/purchase_order_view.xml,sha256=mw0NRSKz_VilND3OG_sJHP_x1
81
81
  odoo/addons/ddmrp/views/stock_buffer_profile_lead_time_view.xml,sha256=uX0oEwJv3EUYYynV0WuWBuZMfpYGx9j-HuYXxzVaaFA,2919
82
82
  odoo/addons/ddmrp/views/stock_buffer_profile_variability_view.xml,sha256=BLMlWsQD2TwxkZ4U-LQLSGKwJzBUD9WtxLeOX2ajBF4,2987
83
83
  odoo/addons/ddmrp/views/stock_buffer_profile_view.xml,sha256=m14bFUZs6KVNtHX0YqaRsUIh5PNZr-Sp0iQs52BaJ3I,4129
84
- odoo/addons/ddmrp/views/stock_buffer_view.xml,sha256=ePWNyEaW26tCfu_r7uQI77oCCtr6nTt7v4G42Rx5his,34302
84
+ odoo/addons/ddmrp/views/stock_buffer_view.xml,sha256=Z1TSiRgaCfBfXiQ7HbHUAvZnuis5NyNw6tkSS5hwxrc,35445
85
85
  odoo/addons/ddmrp/views/stock_move_views.xml,sha256=ZC0c_ACXQ7lzlFbBxiT0vgqSBTYnVDvG6NHprAUI2b8,2253
86
86
  odoo/addons/ddmrp/views/stock_picking.xml,sha256=CD82zoeS6Nnbxw_c53fE-L-0YgTSITW-78Y3c63JzuE,684
87
87
  odoo/addons/ddmrp/views/stock_warehouse_views.xml,sha256=wPLTji7AncZWhsWxbQSPJa7_pAhdybYblMxaeJIVQ5c,612
@@ -93,7 +93,7 @@ odoo/addons/ddmrp/wizards/make_procurement_buffer_view.xml,sha256=wqaOv0Gq1IoaG0
93
93
  odoo/addons/ddmrp/wizards/multi_level_mrp.py,sha256=7PjXJ4Gx8_DqK81eFSeeGTyN1YETSxWFEs6xddwbS2c,753
94
94
  odoo/addons/ddmrp/wizards/res_config_settings.py,sha256=WquTRzrSDWAUyd4Fk6qRBBkXRKVZiTcWumQNCzmyGGQ,1530
95
95
  odoo/addons/ddmrp/wizards/res_config_settings_views.xml,sha256=X8yZQpuF2xDeSSJWn9dtKt7WbSGc-vWZQjIr7J0y-yk,10278
96
- odoo14_addon_ddmrp-14.0.1.19.0.dist-info/METADATA,sha256=rD9KJG9bNyIC7zAeqaFQyMzuEYUpXMNrhi1lG5w9Xdk,13162
97
- odoo14_addon_ddmrp-14.0.1.19.0.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
98
- odoo14_addon_ddmrp-14.0.1.19.0.dist-info/top_level.txt,sha256=qBj40grFkGOfDZ2WDSw3y1RnDlgG0u8rP8pvGNdbz4w,5
99
- odoo14_addon_ddmrp-14.0.1.19.0.dist-info/RECORD,,
96
+ odoo14_addon_ddmrp-14.0.1.21.0.dist-info/METADATA,sha256=rxSR3-f-uN_yUa3OXpZ6bzVOduYWqJ1bxrhhr-uZk84,13162
97
+ odoo14_addon_ddmrp-14.0.1.21.0.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
98
+ odoo14_addon_ddmrp-14.0.1.21.0.dist-info/top_level.txt,sha256=qBj40grFkGOfDZ2WDSw3y1RnDlgG0u8rP8pvGNdbz4w,5
99
+ odoo14_addon_ddmrp-14.0.1.21.0.dist-info/RECORD,,