1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gscg.singleuser.production;
15
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.Map;
19
20 import org.gscg.singleuser.interactionlayer.dataobjects.ProductionStartedData;
21
22 import nl.tudelft.simulation.dsol.experiment.TimeUnit;
23 import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
24 import nl.tudelft.simulation.dsol.formalisms.devs.SimEvent;
25 import nl.tudelft.simulation.event.Event;
26 import nl.tudelft.simulation.event.EventInterface;
27 import nl.tudelft.simulation.event.EventProducer;
28 import nl.tudelft.simulation.event.EventType;
29 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
30 import nl.tudelft.simulation.logger.Logger;
31 import nl.tudelft.simulation.supplychain.actor.Trader;
32 import nl.tudelft.simulation.supplychain.content.ProductionOrder;
33 import nl.tudelft.simulation.supplychain.product.Cargo;
34 import nl.tudelft.simulation.supplychain.product.Product;
35 import nl.tudelft.simulation.supplychain.production.ProductionService;
36 import nl.tudelft.simulation.supplychain.stock.StockInterface;
37
38
39 /***
40 * The GameDelayProductionService starts production at the latest possible
41 * moment to meet the delivery date of the production order. Two versions are
42 * available: one that waits till all the raw materials are available. If not,
43 * production is delayed until all materials of the BoM are available in the
44 * right quantities. The other version is a greedy one, it takes all the
45 * materials it needs from the moment production should start, and delays if
46 * necessary to get the missing materials. <br>
47 * <br>
48 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
49 * Delft, the Netherlands. All rights reserved.
50 *
51 * See for project information <a href="http://www.simulation.tudelft.nl/">
52 * www.simulation.tudelft.nl </a>.
53 *
54 * The source code and binary code of this software is proprietary information
55 * of Delft University of Technology.
56 *
57 * @author <a
58 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
59 * Verbraeck </a>
60 * @version $$Revision: 1.3 $$ $$Date: 2005/08/10 11:23:30 $$
61 */
62 public class GameDelayProductionService extends ProductionService
63 {
64 /*** the EVENT_PRODUCTION_STARTED event */
65 public static final EventType EVENT_PRODUCTION_STARTED = new EventType(
66 "EVENT_PRODUCTION_STARTED");
67
68 /*** the serial version uid */
69 private static final long serialVersionUID = 12L;
70
71 /*** the time distribution to produce products */
72 protected DistContinuous productionTime;
73
74 /*** fixed time, independent of order size; otherwise time is per unit */
75 protected boolean fixedTime;
76
77 /*** if true, immediately start picking raw materials */
78 protected boolean greedy;
79
80 /*** the fraction that is added to the cost of the materials */
81 protected double profitMargin;
82
83 /*** the event producer */
84 private MyEventProducer eventProducer = null;
85
86 /***
87 * Constructs a new production service for one product.
88 *
89 * @param owner the actor that owns the production service.
90 * @param stock the stock for getting and storing materials.
91 * @param product the product of the production service.
92 * @param productionTime the time distribution to produce products.
93 * @param fixedTime fixed time, independent of order size; otherwise, the
94 * time is per unit.
95 * @param greedy if true, immediately start picking raw materials when
96 * production has to start.
97 * @param profitMargin the fraction that is added to the cost of the
98 * materials.
99 */
100 public GameDelayProductionService(final Trader owner,
101 final StockInterface stock, final Product product,
102 final DistContinuous productionTime, final boolean fixedTime,
103 final boolean greedy, final double profitMargin)
104 {
105 super(owner, stock, product);
106 this.eventProducer = new MyEventProducer();
107 this.productionTime = productionTime;
108 this.fixedTime = fixedTime;
109 this.greedy = greedy;
110 this.profitMargin = profitMargin;
111 }
112
113 /***
114 * Accept the production order, and delay till the start of production
115 * (equals delivery time minus production time minus transportation time) to
116 * get the raw materials to produce. Acquire the materials either greedy or
117 * all-at-once.
118 *
119 * @see nl.tudelft.simulation.supplychain.production.ProductionServiceInterface#acceptProductionOrder(nl.tudelft.simulation.supplychain.content.ProductionOrder)
120 */
121 public void acceptProductionOrder(final ProductionOrder productionOrder)
122 {
123
124 double ptime = this.productionTime.draw();
125 if (!this.fixedTime)
126 {
127 ptime *= productionOrder.getAmount();
128 }
129 double startTime = productionOrder.getDateReady() - ptime;
130 startTime = Math.max(super.owner.getSimulatorTime(), startTime);
131
132 Product product = productionOrder.getProduct();
133 Map bom = product.getBillOfMaterials().getMaterials();
134 HashMap availableMaterials = new HashMap();
135 Iterator bomIter = bom.keySet().iterator();
136 while (bomIter.hasNext())
137 {
138 Product raw = (Product) (bomIter.next());
139 double amount = ((Double) (bom.get(raw))).doubleValue();
140 amount *= productionOrder.getAmount();
141 availableMaterials.put(raw, new Double(amount));
142 }
143
144 Object[] args = new Object[]{productionOrder, new Double(ptime),
145 availableMaterials};
146 try
147 {
148 SimEvent simEvent = new SimEvent(startTime, this, this,
149 "startProduction", args);
150 System.out.println("GameDelayProductionService: actor: "
151 + this.owner.getName()
152 + " production started for product: "
153 + productionOrder.getProduct());
154 super.owner.getSimulator().scheduleEvent(simEvent);
155 } catch (Exception e)
156 {
157 Logger.severe(this, "acceptProductionOrder", e);
158 }
159 }
160
161 /***
162 * Start the production at the latest possible time. When raw materials are
163 *
164 * @param productionOrder the production order.
165 * @param ptime the production time.
166 * @param availableMaterials the gathered raw materials.
167 */
168 protected void startProduction(final ProductionOrder productionOrder,
169 final double ptime, final HashMap availableMaterials)
170 {
171
172 boolean ready = pickRawMaterials(productionOrder, availableMaterials,
173 false);
174 if (ready)
175 {
176 pickRawMaterials(productionOrder, availableMaterials, true);
177
178 Object[] args = new Object[]{productionOrder};
179 try
180 {
181 SimEvent simEvent = new SimEvent(super.owner.getSimulatorTime()
182 + ptime, this, this, "endProduction", args);
183 super.owner.getSimulator().scheduleEvent(simEvent);
184 } catch (Exception e)
185 {
186 Logger.severe(this, "startProduction", e);
187 }
188
189
190 this.eventProducer.fireEvent(new Event(
191 GameDelayProductionService.EVENT_PRODUCTION_STARTED,
192 this.eventProducer, new ProductionStartedData(
193 productionOrder,
194 (super.owner.getSimulatorTime() + ptime))));
195 } else
196 {
197 if (this.greedy)
198 {
199 pickRawMaterials(productionOrder, availableMaterials, true);
200 }
201
202 Object[] args = new Object[]{productionOrder, new Double(ptime),
203 availableMaterials};
204 try
205 {
206 SimEvent simEvent = new SimEvent(super.owner.getSimulatorTime()
207 + TimeUnit.convert(1.0, TimeUnitInterface.DAY,
208 super.owner.getSimulator()), this, this,
209 "startProduction", args);
210 super.owner.getSimulator().scheduleEvent(simEvent);
211 } catch (Exception e)
212 {
213 Logger.severe(this, "startProduction", e);
214 }
215 }
216 }
217
218 /***
219 * @param productionOrder the order that has to be produced
220 * @param availableMaterials the materials we already have picked
221 * @param pick pick materials (true) or just check availability (false)
222 * @return success meaning that all materials were available
223 */
224 protected boolean pickRawMaterials(final ProductionOrder productionOrder,
225 final HashMap availableMaterials, final boolean pick)
226 {
227 boolean ready = true;
228 Iterator materialIter = availableMaterials.keySet().iterator();
229 while (materialIter.hasNext())
230 {
231 Product rawProduct = (Product) (materialIter.next());
232 double neededAmount = ((Double) (availableMaterials.get(rawProduct)))
233 .doubleValue();
234 double pickAmount = Math.min(super.stock
235 .getActualAmount(rawProduct), neededAmount);
236 if (pickAmount == 0)
237 {
238 ready = false;
239 }
240 if (pick)
241 {
242 Cargo cargo = super.stock.getStock(rawProduct, pickAmount);
243 productionOrder.addMaterialCost(cargo.getValue());
244 System.out.println("GameDelayProductionService: owner: "
245 + this.owner.getName() + " products taken from stock: "
246 + cargo);
247 }
248 }
249 return ready;
250 }
251
252 /***
253 * endProduction is scheduled after the production time, which starts when
254 * all raw materials are available. The task of this scheduled method is to
255 * store the finished products in stock.
256 *
257 * @param productionOrder the original production order
258 */
259 protected void endProduction(final ProductionOrder productionOrder)
260 {
261 Product product = productionOrder.getProduct();
262 double amount = productionOrder.getAmount();
263 double cost = productionOrder.getMaterialCost();
264 super.stock.addStock(product, amount, cost * this.profitMargin);
265 }
266
267
268 /***
269 * Method getEventProducer
270 *
271 * @return returns the event producer used to fire events
272 */
273 public EventProducer getEventProducer()
274 {
275 return this.eventProducer;
276 }
277
278 /***
279 *
280 * <p>
281 * (c) copyright 2005 <a href="http://www.simulation.tudelft.nl">Delft
282 * University of Technology </a>, the Netherlands. <br>
283 * See for project information <a
284 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a>
285 * <br>
286 *
287 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628
288 * BX Delft, the Netherlands. All rights reserved.
289 *
290 * See for project information <a href="http://www.simulation.tudelft.nl/">
291 * www.simulation.tudelft.nl </a>.
292 *
293 * The source code and binary code of this software are proprietary
294 * information of Delft University of Technology.
295 *
296 * @author <a
297 * href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
298 * van Houten </a>
299 * @version $Revision: 1.3 $ $Date: 2005/08/10 11:23:30 $
300 * @since 1.1.12
301 */
302 private class MyEventProducer extends EventProducer
303 {
304 /***
305 * constructs a new MyEventProducer
306 */
307 public MyEventProducer()
308 {
309 super();
310 }
311
312 /***
313 * @see nl.tudelft.simulation.event.EventProducer#fireEvent(nl.tudelft.simulation.event.EventInterface)
314 */
315 protected synchronized EventInterface fireEvent(
316 final EventInterface event)
317 {
318 return super.fireEvent(event);
319 }
320 }
321 }