From 320efea40c3e9c144e5a0c894e7fb856334e0599 Mon Sep 17 00:00:00 2001 From: Johan De Taeye Date: Tue, 8 Oct 2024 18:40:00 +0200 Subject: [PATCH 1/6] set correct warehouse for PO exported from frepple --- frepple/controllers/inbound.py | 40 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/frepple/controllers/inbound.py b/frepple/controllers/inbound.py index 5f1d2754..7c2fd1a4 100644 --- a/frepple/controllers/inbound.py +++ b/frepple/controllers/inbound.py @@ -281,16 +281,36 @@ def run(self): # Create purchase order if supplier_id not in supplier_reference: - po = proc_order.create( - { - "company_id": self.company.id, - "partner_id": supplier_id, - # TODO Odoo has no place to store the location and criticality - # int(elem.get('location_id')), - # elem.get('criticality'), - "origin": "frePPLe", - } - ) + po_args = { + "company_id": self.company.id, + "partner_id": supplier_id, + "origin": "frePPLe", + } + try: + picking_type_id = stck_picking_type.search( + [ + ("code", "=", "incoming"), + ( + "warehouse_id", + "=", + int(elem.get("location_id")), + ), + ], + limit=1, + )[:1] + if not picking_type_id: + picking_type_id = stck_picking_type.search( + [ + ("code", "=", "incoming"), + ("warehouse_id", "=", False), + ], + limit=1, + )[:1] + if picking_type_id: + po_args["picking_type_id"] = picking_type_id.id + except Exception: + pass + po = proc_order.create(po_args) po.payment_term_id = ( po.partner_id.property_supplier_payment_term_id.id ) From 0b5cb444c307298ded8632576f39547df05216ea Mon Sep 17 00:00:00 2001 From: Johan De Taeye Date: Wed, 9 Oct 2024 16:30:24 +0200 Subject: [PATCH 2/6] bug fix: DO export still used the long warehouse name instead of the code --- frepple/controllers/inbound.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frepple/controllers/inbound.py b/frepple/controllers/inbound.py index 7c2fd1a4..36382f64 100644 --- a/frepple/controllers/inbound.py +++ b/frepple/controllers/inbound.py @@ -399,10 +399,10 @@ def run(self): destination = elem.get("destination") origin_id = stck_warehouse.search( - [("name", "=", origin)], limit=1 + [("code", "=", origin)], limit=1 )[0] destination_id = stck_warehouse.search( - [("name", "=", destination)], limit=1 + [("code", "=", destination)], limit=1 )[0] location_id = None From 3ae50fe4baa2e7bee273dba24e6590a50aee1fd5 Mon Sep 17 00:00:00 2001 From: Johan De Taeye Date: Wed, 9 Oct 2024 16:31:47 +0200 Subject: [PATCH 3/6] source field now populated with remark from frepple --- frepple/controllers/inbound.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/frepple/controllers/inbound.py b/frepple/controllers/inbound.py index 36382f64..e7f271ee 100644 --- a/frepple/controllers/inbound.py +++ b/frepple/controllers/inbound.py @@ -116,7 +116,7 @@ def run(self): if self.mode == 1: # Cancel previous draft purchase quotations m = self.env["purchase.order"] - recs = m.search([("state", "=", "draft"), ("origin", "=", "frePPLe")]) + recs = m.search([("state", "=", "draft"), ("origin", "=like", "frePPLe%")]) recs.write({"state": "cancel"}) recs.unlink() msg.append("Removed %s old draft purchase orders" % len(recs)) @@ -127,7 +127,7 @@ def run(self): "|", ("state", "=", "draft"), ("state", "=", "cancel"), - ("origin", "=", "frePPLe"), + ("origin", "=like", "frePPLe%"), ] ) recs.write({"state": "cancel"}) @@ -280,11 +280,16 @@ def run(self): continue # Create purchase order + remark = elem.get("remark", None) + if remark: + remark = "frePPLe - %s" % remark + else: + remark = "frePPLe" if supplier_id not in supplier_reference: po_args = { "company_id": self.company.id, "partner_id": supplier_id, - "origin": "frePPLe", + "origin": remark, } try: picking_type_id = stck_picking_type.search( @@ -465,6 +470,11 @@ def run(self): if not hasattr(self, "stock_picking_dict"): self.stock_picking_dict = {} if not self.stock_picking_dict.get((origin, destination)): + remark = elem.get("remark", None) + if remark: + remark = "frePPLe - %s" % remark + else: + remark = "frePPLe" self.stock_picking_dict[(origin, destination)] = ( stck_picking.create( { @@ -473,7 +483,7 @@ def run(self): "location_id": location_id["id"], "location_dest_id": location_dest_id["id"], "move_type": "direct", - "origin": "frePPLe", + "origin": remark, } ) ) @@ -604,6 +614,11 @@ def run(self): ) if (elem.get("status") or "proposed") == "proposed": # MO creation + remark = elem.get("remark", None) + if remark: + remark = "frePPLe - %s" % remark + else: + remark = "frePPLe" mo = mfg_order.with_context(context).create( { "product_qty": elem.get("quantity"), @@ -619,7 +634,7 @@ def run(self): "qty_producing": 0.00, # TODO no place to store the criticality # elem.get('criticality'), - "origin": "frePPLe", + "origin": remark, } ) # Remember odoo name for the MO reference passed by frepple. @@ -641,6 +656,11 @@ def run(self): continue if mo: new_qty = float(elem.get("quantity")) + remark = elem.get("remark", None) + if remark: + remark = "frePPLe - %s" % remark + else: + remark = "frePPLe" if mo.product_qty != new_qty: cpq = change_product_qty.create( { @@ -653,7 +673,7 @@ def run(self): { "date_start": elem.get("start"), "date_finished": elem.get("end"), - "origin": "frePPLe", + "origin": remark, } ) mo_references[elem.get("reference")] = mo From abcdbbaf6c522139ad2e0ea0607158ef4bdea01e Mon Sep 17 00:00:00 2001 From: Johan De Taeye Date: Wed, 23 Oct 2024 18:14:09 +0200 Subject: [PATCH 4/6] small update to handle negative demand quantities more robust --- frepple/controllers/outbound.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frepple/controllers/outbound.py b/frepple/controllers/outbound.py index 3acc4900..268d6dd5 100644 --- a/frepple/controllers/outbound.py +++ b/frepple/controllers/outbound.py @@ -2060,7 +2060,7 @@ def getReservedQuantity(stock_move_id): ), due, priority, - j["picking_policy"] == "one" and qty or 0.0, + qty - reserved_quantity if j["picking_policy"] == "one" and qty - reserved_quantity > 0 else 0.0, "open" if qty - reserved_quantity > 0 else "closed", quoteattr(product["name"]), quoteattr(customer), @@ -2120,7 +2120,7 @@ def getReservedQuantity(stock_move_id): qty, due, priority, - j["picking_policy"] == "one" and qty or 0.0, + qty if j["picking_policy"] == "one" and qty > 0 else 0.0, status, quoteattr(product["name"]), quoteattr(customer), From 17b400b8246edb1f6ec4e98d2fd02444c16b6b30 Mon Sep 17 00:00:00 2001 From: hichamlahlou Date: Thu, 24 Oct 2024 11:18:04 +0200 Subject: [PATCH 5/6] populate the blanket order reference when creating PO --- frepple/controllers/inbound.py | 87 ++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/frepple/controllers/inbound.py b/frepple/controllers/inbound.py index e7f271ee..cb05c357 100644 --- a/frepple/controllers/inbound.py +++ b/frepple/controllers/inbound.py @@ -97,6 +97,16 @@ def run(self): change_product_qty = self.env["change.production.qty"].with_user( self.actual_user ) + hasRequisition = True + try: + purchase_requisition = self.env["purchase.requisition"].with_user( + self.actual_user + ) + purchase_requisition_line = self.env[ + "purchase.requisition.line" + ].with_user(self.actual_user) + except: + hasRequisition = False else: product_product = self.env["product.product"] product_supplierinfo = self.env["product.supplierinfo"] @@ -113,6 +123,12 @@ def run(self): stck_warehouse = self.env["stock.warehouse"] stck_location = self.env["stock.location"] change_product_qty = self.env["change.production.qty"] + hasRequisition = True + try: + purchase_requisition = self.env["purchase.requisition"] + purchase_requisition_line = self.env["purchase.requisition.line"] + except: + hasRequisition = False if self.mode == 1: # Cancel previous draft purchase quotations m = self.env["purchase.order"] @@ -134,6 +150,31 @@ def run(self): recs.unlink() msg.append("Removed %s old draft manufacturing orders" % len(recs)) + # read all the blanket orders + if hasRequisition: + pr_ids = [ + i + for i in purchase_requisition.search( + [ + "&", + "&", + "|", + ("date_end", "=", False), + ("date_end", ">=", datetime.now()), + ("type_id.name", "=", "Blanket Order"), + ("state", "=", "ongoing"), + ] + ) + ] + requisition_dic = { + (i.product_id.id, i.requisition_id.vendor_id.id): i.requisition_id + for i in purchase_requisition_line.search( + [ + ("requisition_id", "in", [j.id for j in pr_ids]), + ] + ) + } + # Parsing the XML data file countproc = 0 countmfg = 0 @@ -366,6 +407,52 @@ def run(self): "product_uom": int(uom_id), } ) + + # Is there a blanket order for this product /supplier ? + if ( + self.mode == 1 + and hasRequisition + and not po_line.order_id.requisition_id + and (int(item_id), supplier_id) in requisition_dic + ): + po.requisition_id = requisition_dic[ + (int(item_id), supplier_id) + ] + elif ( + self.mode != 1 + and hasRequisition + and not po_line.order_id.requisition_id + ): + for i in purchase_requisition_line.search( + [ + "&", + "&", + "&", + "&", + "|", + ("requisition_id.date_end", "=", False), + ( + "requisition_id.date_end", + ">=", + datetime.now(), + ), + ( + "requisition_id.type_id.name", + "=", + "Blanket Order", + ), + ("requisition_id.state", "=", "ongoing"), + ("product_id.id", "=", int(item_id)), + ( + "requisition_id.vendor_id.id", + "=", + supplier_id, + ), + ] + ): + po_line.order_id.requisition_id = i.requisition_id + break + # Then let odoo computes all the fields (taxes, name, description...) d = po_line._prepare_purchase_order_line( From d6c58e2d14625057a9f838af138b2fde7a0cd0dd Mon Sep 17 00:00:00 2001 From: hichamlahlou Date: Thu, 24 Oct 2024 12:32:10 +0200 Subject: [PATCH 6/6] pull one record only for a blanket order --- frepple/controllers/inbound.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frepple/controllers/inbound.py b/frepple/controllers/inbound.py index cb05c357..582d5296 100644 --- a/frepple/controllers/inbound.py +++ b/frepple/controllers/inbound.py @@ -448,10 +448,10 @@ def run(self): "=", supplier_id, ), - ] + ], + limit=1, ): po_line.order_id.requisition_id = i.requisition_id - break # Then let odoo computes all the fields (taxes, name, description...)