Global Operation Management - Inventory Management
Pull inventory control - single (Economic order quantity EOQ)Watch Tutorial
def on_eoq(event):
D = float(Element("D").element.value)
S = float(Element("S").element.value)
C = float(Element("C").element.value)
I = float(Element("I").element.value)
result = eoq(D,S,C,I)
Element("out_eoq").element.innerHTML = result
Element("button_EOQ").element.onclick = on_eoq
OUTPUT
Optimal Reorder Point - Instantaneous ResupplyWatch Tutorial
def get_plot_string(Q_star, R_star, D, LT):
plt = plot_inventory_wave(Q_star, R_star, D, LT)
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close()
buf.seek(0)
string = base64.b64encode(buf.read()).decode('utf-8')
# output pic
return "data:image/png;base64,"+ string
def on_instant(event):
try:
D = float(Element("D1").element.value)
S = float(Element("S1").element.value)
C = float(Element("C1").element.value)
I = float(Element("I1").element.value) / 100
LT = float(Element("LT1").element.value)
Q_star, R_star = instant_order(D, S, C, I, LT)
if Q_star is not None and R_star is not None:
Element("instant_result").element.innerHTML = order(D, S, C, I, LT)
img_data = get_plot_string(Q_star, R_star, D, LT)
Element("out_instant").element.innerHTML = "Plot generated!"
Element("plot_image").element.src = img_data
Element("plot_image").element.style.display = "block"
except ValueError:
Element("out_instant").element.innerHTML = "Invalid input. Please enter numeric values."
Element("button_instant").element.onclick = on_instant
OUTPUT
Optimal Reorder Point - NON - Instantaneous ResupplyWatch Tutorial
import math
import numpy as np
import matplotlib.pyplot as plt
def noninstant1(D, S, C, I, LT, P):
try:
numerator = 2 * D * S
denominator = I * C
Q_squared = numerator / denominator
Q = math.sqrt(Q_squared)
Q_up = math.ceil(Q)
R_square = (D / 52) * LT
R_up = math.ceil(R_square)
Q_square = Q_up * math.sqrt(P / (P - D / 52))
round_Q = math.ceil(Q_square)
max_inventory = (round_Q / P) * (P - D / 52)
print(f"When the inventory level drops to {R_up} units, place a replenishment order for {round_Q}.")
return round_Q, max_inventory, R_up
except ValueError:
Element("out_noninstant").element.innerHTML = "Invalid input. Please enter positive values."
return None, None, None
def plot_inventory_wave2(round_Q, max_inventory, R_up):
# repeat 3 times
repetitions = 3
time_period = 10 # Total time for one cycle
t = np.linspace(0, time_period * repetitions, 1000)
inventory_levels = np.zeros_like(t)
# Generate the sawtooth wave
for i in range(len(t)):
cycle_position = t[i] % time_period # Position within the current cycle
if cycle_position < time_period / 2:
inventory_levels[i] = (max_inventory / (time_period / 2)) * cycle_position # Linear up
else:
inventory_levels[i] = max_inventory - ((max_inventory / (time_period / 2)) * (cycle_position - time_period / 2)) # Linear down
# Plot
plt.figure(figsize=(10, 6))
plt.plot(t, inventory_levels, label='Inventory Level', color='blue')
# label line here
plt.axhline(y=round_Q, color='green', linestyle='--', label=f'Q*: {round_Q}')
plt.axhline(y=max_inventory, color='red', linestyle='--', label=f'Max Inventory: {max_inventory:.2f}')
plt.axhline(y=R_up, color='orange', linestyle='--', label=f'Reordering Quantity: {R_up}')
plt.ylim(0, max(round_Q, max_inventory) * 1.1) # Enlarged to the value of Q*
plt.title('Sawtooth Wave of Inventory Levels (3 Cycles)')
plt.xlabel('Time')
plt.ylabel('Inventory Level')
plt.xlim(0, time_period * repetitions)
plt.grid()
plt.legend()
plt.text(0, round_Q + 0.05 * max(round_Q, max_inventory), f'Q*: {round_Q}', color='green')
plt.text(0, max_inventory + 0.05 * max(round_Q, max_inventory), f'Max Inventory: {max_inventory:.2f}', color='red')
plt.text(0, R_up + 0.05 * max(round_Q, max_inventory), f'Reordering Quantity: {R_up}', color='orange')
return plt
def get_plot_string2(round_Q, max_inventory, R_up):
plt = plot_inventory_wave2(round_Q, max_inventory, R_up)
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close()
buf.seek(0)
string = base64.b64encode(buf.read()).decode('utf-8')
# output pic
return "data:image/png;base64,"+ string
def on_noninstant(event):
try:
D = float(Element("D2").element.value)
S = float(Element("S2").element.value)
C = float(Element("C2").element.value)
I = float(Element("I2").element.value)
LT = float(Element("LT2").element.value)
P = float(Element("P2").element.value)
round_Q, max_inventory, R_up = noninstant1(D, S, C, I, LT, P)
result = noninstant(D,S,C,I,LT,P)
Element("non_result").element.innerHTML = result
if round_Q is not None:
img_data = get_plot_string2(round_Q, max_inventory, R_up)
Element("out_noninstant").element.innerHTML = "Plot generated!"
Element("plot_image_non").element.src = img_data
Element("plot_image_non").element.style.display = "block"
except ValueError:
Element("out_noninstant").element.innerHTML = "Invalid input. Please enter numeric values."
Element("button_noninstant").element.onclick = on_noninstant