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 (P3)



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

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).


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


Sau phần 2, mình tính được lượng nguyên vật liệu cần về (hay còn gọi là ‘Planned Receipt’).

Với điều kiện leadtime giao hàng (thay đổi theo [‘Item’, ‘Site’]) và ràng buộc về MOQ, phần này mình sẽ đi qua các code Python đã sử dụng để tính Planned Order Release ‘final’.

D. Planned Order Release


1. Dữ liệu đã xử lý và đang có sẵn

  • Planned Receipt: lượng nguyên vật liệu cần về hàng sau khi đã cấn trừ tồn kho và PO Pending (cả nguyên vật liệu có và không có hạn sử dụng) (thu được ở phần 2)

  • Leadtime và MOQ: có thể thay đổi theo [‘Item’, ‘Site’]


2. Logic & Python: Planned Order Release (chưa tính MOQ)

- Lấy dữ liệu Leadtime: Join bảng Planned Receipt (thu được ở phần 2) với bảng df_item_master, lấy Leadtime_days (cột chung là [‘Item’, ‘Site’]): pandas.merge

- Dời lùi Planned Receipt tương ứng với Leadtime_days để lấy Planned Order Release: pandas.DataFrame.shift

  • Viết udf để loop qua từng dòng trong group (group by ['Item', 'Site']), sau đó dùng .apply() để apply udf lên từng group (pandas.DataFrame.apply)

  • Trước khi apply udf, cần lọc bỏ dòng có ‘Period’ = ‘1900-01-01’ (Đây là ‘period’ được thêm vào ở các bước trước nhằm đưa Stock On Hand của nguyên vật liệu không có hạn sử dụng vào số Supply từ PO Pending. Giá trị của dòng này ở cột 'Planned Receipt' luôn bằng 0, vì vốn không có Demand ở thời điểm này. Vì thế cần bỏ dòng này trước khi thực hiện)

  • Trong udf, ứng dụng shift() function. Vì tham số ‘periods’ trong shift() function phải có dạng dữ liệu ‘integer’ nên cần phải chuyển kiểu dữ liệu của Leadtime_days từ ‘float’ sang ‘integer’

  • Udf mình sử dụng như sau:

Code to shift rows after grouping by ['Item', 'Site'] - LNPT
  • Ý nghĩa của dòng syntax được thể hiện trong hình ảnh bên dưới:

Logic explanation - Shift

3. Logic & Python: Urgent Order (order không đúng leadtime, nguy cơ thiếu hàng)

Cũng từ bảng Planned Receipt đã lọc bỏ ‘Period’ = ‘1900-01-01’:

  • Lấy những dòng đầu tiên trong mỗi group (sau khi group by [‘Item’, ‘Site’], với số lượng dòng bằng với Leadtime_days

  • Sau đó, lấy những dòng có Quantity lớn hơn 0

  • Đặt ‘Period’ của những ‘Urgent Order’ này là một ngày nào đó xưa nhất để khi sort_values thì dòng order này sẽ được đẩy lên trên cùng (ví dụ: ‘1900-01-01’)

Code to select a variable number of first rows in each group - LNPT

Kết quả Urgent Order (sau khi lọc lấy Quantity > 0)


4. Logic & Python: Planned Order Release (xét đến ràng buộc về MOQ)


4.1. Tổng hợp lại danh sách hàng cần đặt ở mỗi thời điểm

- Concat 2 df tạo ra ở mục 2 và mục 3 (Order đúng leadtime và Urgent Order không đúng leadtime), trong đó, với Urgent Order, đã set 'Period' = '1900-01-01'.

- Sort_values để 'Period' = ‘1900-01-01’ lên đầu tiên trong mỗi Group. Khi đó, Urgent Order là đơn hàng đầu tiên được đặt và phải đặt theo MOQ, nếu dư sẽ dùng để phân bổ cho thời điểm đặt hàng kế tiếp. Đồng thời, vì lý do này, sau khi thu được kết quả Urgent Order ở mục 3, cần Group By ['Item', 'Site'] trước khi đến mục 4 này.

4.2. Tính Planned Order Release dưới ràng buộc về MOQ

4.2.1. Lấy dữ liệu MOQ: Join bảng order ở mục 4.1 với df_item_master, lấy ‘MOQ’ (cột chung là [‘Item’, ‘Site’])

> Python: pandas.merge

4.2.2. Viết udf và dùng apply sau khi Group By ['Item', 'Site']

Concept:

  • Loop qua từng dòng dữ liệu trong Group

  • Sử dụng .at[] hoặc .loc[] để access và update số lượng sẽ đặt hàng theo MOQ, gọi là ‘order_final

  • Nếu ‘order_final’ lớn hơn số lượng định đặt ở kỳ đó, thì giữ lại phần dư để phân bổ cho kỳ tiếp theo (lưu vào biến ‘total_remain’)

  • Trước khi quyết định ở kỳ đó có tiếp tục đặt hàng theo MOQ hay không, cần xem xét kỳ trước có lượng dư có thể phân bổ hay không (lưu vào biến y = x + total_remain, với x là số lượng đặt chưa theo MOQ)

Logic chia trường hợp của biến y:

  • Nếu 0 < y <= MOQ, nghĩa là nếu tính luôn lượng dư ở kỳ trước thì ở kỳ này vẫn cần phải đặt thêm và phải đặt theo MOQ (order_final = MOQ, và total_remain = y - order_final)

  • Nếu y > MOQ, nghĩa là nếu tính luôn lượng dư ở kỳ trước thì ở kỳ này vẫn cần thêm và cần một lượng lớn hơn MOQ, nên sẽ đặt theo lượng y và không có dư để phân bổ cho kỳ tiếp theo (order_final = y, và total_remain = 0)

  • Nếu y < 0, nghĩa là nếu tính luôn lượng dư ở kỳ trước thì kỳ này đã đủ hàng và vẫn còn dư để phân bổ cho kỳ tiếp (order_final = 0, và total_remain = y)

Logic explanation - MOQ

Code Python mình sử dụng như bên dưới:

Code to adjust order based on MOQ - LNPT

Sau khi thu được kết quả, thực hiện các bước customize như rename column, pivot, ...

Kết quả thu được với bộ data sample:


Đến đây, mình đã hoàn thành phần tính toán Planned Order Release với 3 ràng buộc: Shelf life, Leadtime giao hàng, MOQ (với Leadtime và MOQ thay đổi theo [‘Item’, ‘Site’]),dưới giả định rằng nguyên vật liệu được trữ tại từng nhà máy nơi thành phẩm được sản xuất và sẽ được giao từ nhà cung cấp đến nhà máy đó.


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


P/s: Như đã đề cập trước đó, logic và cách tính toán 'automated' cho Planned Order Release có rất nhiều, và cách làm Python của mình chỉ là một trong số những cách có thể thực hiện được dù bạn không có background IT.

~ So, happy to share and exchange with you ~

~ If you are interest, see my next post ~


Và rất cảm ơn bạn đã đọc đến đây.



Lê Ngọc Phương Trinh

Enthusiast of Supply Chain, Data Analysis & Storytelling, Automation

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


22 lượt xem

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

Xem tất cả

Comments


bottom of page