top of page
Tìm kiếm
Ảnh của tác giảLe Ngoc Phuong Trinh

Ứng dụng Python vào bài toán MRP - Planned Order Release (P1)

Đã cập nhật: 6 thg 9, 2022



------------------------------

Change the language setting at the top of page to go to English version.

------------------------------


MRP (Material Requirement Planning) chuyển đổi kế hoạch sản xuất thành một thời gian biểu để ra quyết định đặt hàng nguyên liệu và linh kiện nhằm đáp ứng nhu cầu sản xuất một cách đầy đủ và đúng thời điểm. MRP trả lời cho 3 câu hỏi chính:

  • Cần những gì?

  • Cần bao nhiêu?

  • Khi nào cần?

Với Python, mình tính toán lượng nguyên vật liệu cần phải đặt ở mỗi nhà máy (Planned Order Release - phân biệt theo ['Item', 'Site']) với những ràng buộc về Shelf life, MOQ (Minimum Order Quantity) và những inputs như Production Plan (kế hoạch sản xuất thành phẩm), Stock On Hand, PO Pending (in-transit goods).


A. Tổng quan bài toán


1. Viết tắt (Abbreviation)

Từ viết tắt

Nghĩa

Từ viết tắt

Nghĩa

SOH

Stock On Hand

RPM

Raw Pack Material

PO

Purchase Order

FG

Finished Goods

MOQ

Minimum Order Quantity

BOM

Bill of Material

PP

Production Plan

df

dataframe

2. Phạm vi bài toán (Scope)

  • Nguyên vật liệu có hoặc không có hạn sử dụng

  • Xuất nguyên vật liệu cho sản xuất theo nguyên tắc FEFO (First Expired, First Out)

  • Đặt hàng với ràng buộc về MOQ

  • Thành phẩm có thể được sản xuất ở hơn 1 nhà máy (Site), và nguyên vật liệu được trữ tại nhà máy, đồng thời, được giao từ Nhà cung cấp đến trực tiếp nhà máy đó

  • Đối với hàng đang đi đường (PO Pending), không có thông tin về hạn sử dụng cho đến khi nhập kho thực tế (trở thành SOH)

  • BOM level: input là BOM đã rã từ nhiều cấp BOM, trở thành BOM 1 level gồm 1 cấp thành phẩm và 1 cấp Nguyên vật liệu


3. Đầu vào dữ liệu (Input)

Gồm 5 bảng dữ liệu chính:

  • BOM (df_bom): chứa BOM đã rã, trở thành BOM 1 cấp

  • Item Master (df_item_master): chứa các thông tin của nguyên vật liệu (Item, Site, Leadtime delivery, MOQ, Shelf life)

  • FG Production Plan (df_fg_production): kế hoạch sản xuất của thành phẩm (bắt đầu từ ngày cần làm MRP), bảng dạng Pivot

  • Stock RPM (df_stock_rpm): tồn kho nguyên vật liệu theo Site, Expiry date

  • PO Pending (df_supply): lượng nguyên vật liệu sẽ nhận được từ các PO đang pending, bảng dạng Pivot


4. Flow xử lý bài toán

5. Dữ liệu bài toán

Bạn có thể tải file dữ liệu mẫu tại đây.

Mẫu 5 bảng dữ liệu như bên dưới:


B. Phân bổ tồn kho theo shelf life cho nhu cầu sử dụng nguyên vật liệu

Phần này sẽ xử lý bài toán đến Net demand (1) như mô tả trên flow


1. Tiền xử lý

Trước khi thực hiện phân bổ tồn kho theo shelf life cho nhu cầu sử dụng nguyên vật liệu, ta tiến hành các bước xử lý dữ liệu sau:

  • Unpivot bảng FG Production Plan (df_fg_production)

  • Join bảng df_fg_production với bảng df_bom, cột chung để join là ‘Item’ (ở bảng df_fg_production) hoặc là ‘parent’ (ở bảng df_bom). Đồng thời, lấy 2 cột từ df_bom: cột ‘component’ và cột ‘norm_total’ (định mức sử dụng nguyên vật liệu trên 1 thành phẩm)

  • Nhân lượng sản xuất ở mỗi kì của mỗi item (‘FG Planned Receipt’) với định mức sử dụng nguyên vật liệu (‘norm_total’)

  • Group by ‘component’, ‘site’, ‘period’ để lấy tổng nhu cầu nguyên vật liệu (‘Raw Gross Requirement’)

Tổng nhu cầu nguyên vật liệu theo ['Item', 'Site', 'Period'] là kết quả của bước này (đã thực hiện unpivot để dễ theo dõi)


2. Logic phân bổ

2.1. Lấy tồn kho và nhu cầu có thể đáp ứng lẫn nhau (không hết hạn trước khi cần dùng)

- Sau bước xử lý ở mục 1, thu được bảng tổng nhu cầu nguyên vật liệu df_raw_gross_raw

- Join df_raw_gross_raw với df_stock_rpm, cột chung là [‘Item’, ‘Site’]

- Lấy những dòng mà tại đó, Hạn sử dụng của nguyên vật liệu có thể đáp ứng được nhu cầu sử dụng: ['Demand period'] <= ['Expiry date']

- Những nguyên vật liệu không có Hạn sử dụng và Những nguyên vật liệu có Demand Period mà tại đó không có tồn kho với hạn sử dụng đủ điều kiện: sẽ bị lọc bỏ và được đưa vào xử lý chung với PO Pending ở bài viết sau

2.2. Group By và lặp qua từng dòng trong group để phân bổ tồn kho cho nhu cầu

- Group df_demand_stock_raw by [‘Item’, ‘Site’] và loop qua

  • Từng group

  • Từng dòng trong mỗi group

- Ở mỗi vòng lặp (loop), thực hiện phép trừ (Raw gross requirement - Quantity = remain)

  • Nếu nhu cầu nguyên vật liệu đã được đáp ứng đủ (remain <= 0): từ dòng hiện tại trở đi, thay thế số nhu cầu nguyên vật liệu của cùng kỳ bằng 0, và tồn kho nguyên vật liệu cùng hạn sử dụng bằng giá trị |remain|

  • Ngược lại, nếu nhu cầu nguyên vật liệu chưa được đáp ứng đủ (remain > 0): từ dòng hiện tại trở đi, thay thế số nhu cầu nguyên vật liệu của cùng kỳ bằng |remain|, và tồn kho nguyên vật liệu cùng hạn sử dụng bằng 0

- Sử dụng .loc[] để access vào các giá trị trong df và gán giá trị mới trước khi vòng lặp tiếp theo được thực hiện

- Sự thay đổi của nhu cầu và tồn kho ở mỗi kỳ qua mỗi vòng lặp được mô tả như bên dưới:

2.3. Sau vòng lặp, thu lại kết quả

- Group by [‘Item’, ‘Site’], lấy giá trị MIN ở cột ‘Raw gross requirement’ sẽ thu được Net Demand của những nguyên vật liệu có hạn sử dụng. Từ đó, sử dụng tiếp cho bước tính toán có PO Pending.

- Đồng thời, cũng sẽ trả lời được câu hỏi, với mỗi loại nguyên vật liệu còn lại bao nhiêu tồn kho (tính theo Expiry date)


3. Python

- Import các thư viện cần thiết như Pandas, Numpy, Datetime

- Đọc dữ liệu từ file Excel: pandas.read_excel

- Unpivot bảng FG Production Plan: pandas.melt

- Join bảng FG Production Plan (đã unpivot) với bảng BOM: pandas.merge

- Thực hiện phép nhân để lấy lượng nguyên vật liệu cần sử dụng, và Group by, sau đó Join với bảng Stock RPM: pandas.DataFrame.groupby

- Lấy những dòng mà tại đó Stock có thể dùng cho sản xuất (chưa hết hạn): pandas.DataFrame.loc

- Group By, thực hiện vòng lặp qua Group, và từng dòng trong Group (Bên dưới là đoạn code mình đã viết)

- Từ kết quả trên, lấy được Net demand (1) (như mô tả trên flow ở đầu bài viết), và số tồn kho còn lại của NVL theo ‘Expiry date’ (Stock Left): pandas.core.groupby.DataFrameGroupBy.agg

Code loop within group - LNPT

Kết quả Stock Left của NVL có hạn sử dụng, và nhu cầu sử dụng của nguyên vật liệu ở các thời điểm có tồn kho đáp ứng:


Ở phần này, mình đã thực hiện phân bổ tồn kho có hạn sử dụng lên nhu cầu nguyên vật liệu, đồng thời cũng thu được lượng tồn kho còn lại (tính theo hạn sử dụng) của mỗi nguyên vật liệu trên.


Phần tiếp theo mình sẽ lấy kết quả ở bước này (nhu cầu của nguyên vật liệu có hạn sử dụng sau khi thực hiện phân bổ) và những nhu cầu chưa được đưa vào tính toán, kết hợp với lượng tồn nguyên vật liệu không có hạn sử dụng và những PO Pending, để tính ra lượng hàng thực sự cần (final_net_demand ~ hay còn gọi là ‘planned receipt’) của tất cả nguyên vật liệu.


-------------------------------------------------------------------------


P/s: Theo mình, để tính toán Planned Order Release có rất nhiều logic để tính, và có thể được thực hiện trên nhiều ngôn ngữ và nền tảng khác nhau, kể cả Power Query. Và cách làm Python của mình chỉ là một trong số những cách thực hiện đó.

~ So, happy to share and exchange with you ~

~ If you are interest, see my next post ~




Lê Ngọc Phương Trinh

Enthusiast of Supply Chain, Data Analysis & Storytelling, Automation

https://www.linkedin.com/in/kayleetrinh99/


48 lượt xem

Bài đăng gần đây

Xem tất cả

Bình luận


bottom of page