View Javadoc

1   /*
2    * @(#) Retailer.java Dec 8, 2003
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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 }