1
2
3
4
5
6
7
8
9
10
11 package nl.tudelft.simulation.dsol.tutorial.section42;
12
13 import java.rmi.RemoteException;
14 import java.util.Properties;
15 import nl.tudelft.simulation.dsol.formalisms.devs.SimEvent;
16 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
17 import nl.tudelft.simulation.dsol.tutorial.section42.policies.OrderingPolicy;
18 import nl.tudelft.simulation.dsol.tutorial.section42.policies.StationaryPolicy;
19 import nl.tudelft.simulation.event.EventProducer;
20 import nl.tudelft.simulation.event.EventType;
21 import nl.tudelft.simulation.logger.Logger;
22
23 /***
24 * A Retailer <br>
25 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
26 * University of Technology </a>, the Netherlands. <br>
27 * See for project information <a
28 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
29 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
30 * License (GPL) </a>, no warranty <br>
31 *
32 * @version 1.0 Dec 8, 2003 <br>
33 * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
34 * Jacobs </a>
35 */
36 public class Retailer extends EventProducer implements BuyerInterface,
37 SellerInterface
38 {
39 /*** TOTAL_ORDERING_COST_EVENT is fired whenever ordering occurs */
40 public static final EventType TOTAL_ORDERING_COST_EVENT = new EventType(
41 "TOTAL_ORDERING_COST_EVENT");
42
43 /*** INVENTORY_LEVEL_EVENT is fired on changes in inventory */
44 public static final EventType INVENTORY_LEVEL_EVENT = new EventType(
45 "INVENTORY_LEVEL_EVENT");
46
47 /*** BACKLOG_LEVEL is fired on BACKLOG_LEVEL changes */
48 public static final EventType BACKLOG_LEVEL = new EventType("BACKLOG_LEVEL");
49
50 /*** the actual inventoryLevel */
51 private long inventory = 60L;
52
53 /*** the ordering backlog */
54 private long backLog = 0L;
55
56 /*** the simulator on which to schedule */
57 private DEVSSimulatorInterface simulator = null;
58
59 /*** the warehouse we use */
60 private SellerInterface warehouse = null;
61
62 /*** the orderingPolicy */
63 private OrderingPolicy orderingPolicy = null;
64
65 /*** the costs */
66 private double backlogCosts;
67
68 /*** the costs */
69 private double holdingCosts;
70
71 /*** the costs */
72 private double marginalCosts;
73
74 /*** the costs */
75 private double setupCosts;
76
77 /***
78 * constructs a new Retailer
79 *
80 * @param simulator the simulator on which we can schedule
81 * @param warehouse the warehouse to buy at
82 * @throws RemoteException on failure
83 */
84 public Retailer(final DEVSSimulatorInterface simulator,
85 final SellerInterface warehouse) throws RemoteException
86 {
87 super();
88 this.simulator = simulator;
89 this.warehouse = warehouse;
90 this.orderingPolicy = new StationaryPolicy(simulator);
91 Properties properties = this.simulator.getReplication().getRunControl()
92 .getTreatment().getProperties();
93 this.backlogCosts = new Double(properties
94 .getProperty("retailer.costs.setup")).doubleValue();
95 this.holdingCosts = new Double(properties
96 .getProperty("retailer.costs.holding")).doubleValue();
97 this.marginalCosts = new Double(properties
98 .getProperty("retailer.costs.marginal")).doubleValue();
99 this.setupCosts = new Double(properties
100 .getProperty("retailer.costs.setup")).doubleValue();
101 this.reviewInventory();
102 }
103
104 /***
105 * @see nl.tudelft.simulation.dsol.tutorial.section42.BuyerInterface
106 * #receiveProduct(long)
107 */
108 public void receiveProduct(final long amount)
109 {
110 long served = this.backLog - Math.max(0, this.backLog - amount);
111 this.backLog = Math.max(0, this.backLog - amount);
112 this.inventory = this.inventory + Math.max(0, amount - served);
113 try
114 {
115 this.fireEvent(INVENTORY_LEVEL_EVENT, this.inventory,
116 this.simulator.getSimulatorTime());
117 this.fireEvent(BACKLOG_LEVEL, this.backLog, this.simulator
118 .getSimulatorTime());
119 } catch (RemoteException exception)
120 {
121 Logger.warning(this, "receiveProduct", exception);
122 }
123 }
124
125 /***
126 * reviews the inventoryLevel and possibly orders
127 */
128 private void reviewInventory()
129 {
130 double costs = this.holdingCosts * this.inventory + this.backlogCosts
131 * this.backLog;
132 long amount = this.orderingPolicy.computeAmountToOrder(this.inventory);
133 if (amount > 0)
134 {
135 costs = costs + this.setupCosts + amount * this.marginalCosts;
136 this.fireEvent(TOTAL_ORDERING_COST_EVENT, costs);
137 this.warehouse.order(this, amount);
138 }
139 try
140 {
141 this.simulator.scheduleEvent(new SimEvent(this.simulator
142 .getSimulatorTime() + 1.0, this, this, "reviewInventory",
143 null));
144 } catch (Exception exception)
145 {
146 Logger.warning(this, "reviewInventory", exception);
147 }
148 }
149
150 /***
151 * @see nl.tudelft.simulation.dsol.tutorial.section42.SellerInterface
152 * #order(BuyerInterface,long)
153 */
154 public void order(final BuyerInterface buyer, final long amount)
155 {
156 long actualOrderSize = Math.min(amount, this.inventory);
157 this.inventory = this.inventory - actualOrderSize;
158 if (actualOrderSize < amount)
159 {
160 this.backLog = this.backLog + (amount - actualOrderSize);
161 }
162 try
163 {
164 this.fireEvent(INVENTORY_LEVEL_EVENT, this.inventory,
165 this.simulator.getSimulatorTime());
166 this.fireEvent(BACKLOG_LEVEL, this.backLog, this.simulator
167 .getSimulatorTime());
168 } catch (RemoteException exception)
169 {
170 Logger.warning(this, "receiveProduct", exception);
171 }
172 buyer.receiveProduct(actualOrderSize);
173 }
174 }