View Javadoc

1   /*
2    * @(#)PCShopRequestForQuoteHandler.java Mar 3, 2004
3    * 
4    * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands. All rights reserved.
6    * 
7    * See for project information <a href="http://www.simulation.tudelft.nl/">
8    * www.simulation.tudelft.nl </a>.
9    * 
10   * The source code and binary code of this software is proprietary information
11   * of Delft University of Technology.
12   */
13  
14  package org.gscg.singleuser.handlers;
15  
16  import java.io.Serializable;
17  import java.util.HashMap;
18  import java.util.Map;
19  
20  import nl.tudelft.simulation.jstats.distributions.DistContinuous;
21  import nl.tudelft.simulation.logger.Logger;
22  import nl.tudelft.simulation.supplychain.actor.Trader;
23  import nl.tudelft.simulation.supplychain.content.Quote;
24  import nl.tudelft.simulation.supplychain.content.RequestForQuote;
25  import nl.tudelft.simulation.supplychain.handlers.SupplyChainHandler;
26  import nl.tudelft.simulation.supplychain.product.Product;
27  import nl.tudelft.simulation.supplychain.transport.TransportMode;
28  
29  import org.gscg.common.geo.CalculateLatLonDistance;
30  import org.gscg.experiment.DistTriangularGetters;
31  
32  /***
33   * The RequestForQuotehandler implements the business logic for a supplier who
34   * receives a RequestForQuote. The most simple version answers yes if the
35   * product is on stock or ordered, and bases the price on the average costs of
36   * the items on stock, after adding a fixed, but changeable, profit margin. The
37   * answer is no if the product is not on stock, nor ordered. <br>
38   * <p>
39   * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
40   * Delft, the Netherlands. All rights reserved.
41   * 
42   * See for project information <a href="http://www.simulation.tudelft.nl/">
43   * www.simulation.tudelft.nl </a>.
44   * 
45   * The source code and binary code of this software is proprietary information
46   * of Delft University of Technology.
47   * 
48   * @version 1.0 Mar 4, 2004 <br>
49   * @author <a
50   *         href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
51   *         Verbraeck </a>
52   */
53  public class PCShopRequestForQuoteHandler extends SupplyChainHandler
54  {
55  	/*** the serial version uid */
56  	private static final long serialVersionUID = 11L;
57  
58  	/*** the reaction time of the handler in simulation time units */
59  	private DistContinuous handlingTimeDistribution = null;
60  
61  	/*** the distribution to use for the price */
62  	private Map priceDistributions = null;
63  
64  	/*** the distribution to use for the delay */
65  	private DistContinuous delayDistribution = null;
66  
67  	/*** the lat lon distance calculator to use */
68  	private CalculateLatLonDistance latLonDistanceCalculator = null;
69  
70  	/***
71  	 * Construct a new RFQ handler.
72  	 * 
73  	 * @param owner a trader in this case as only traders handle RFQs
74  	 * @param handlingTimeDistribution the distribution for the handling time
75  	 * @param products the products to link to the price distributions
76  	 * @param priceDistributions the price distributions
77  	 * @param delayDistribution the distribution for the delay
78  	 */
79  	public PCShopRequestForQuoteHandler(final Trader owner,
80  			final DistContinuous handlingTimeDistribution,
81  			final Product[] products,
82  			final DistTriangularGetters[] priceDistributions,
83  			final DistContinuous delayDistribution)
84  	{
85  		super(owner);
86  		this.handlingTimeDistribution = handlingTimeDistribution;
87  		this.priceDistributions = new HashMap();
88  		for (int i = 0; i < products.length; i++)
89  		{
90  			this.priceDistributions.put(products[i], priceDistributions[i]);
91  		}
92  		this.delayDistribution = delayDistribution;
93  		this.latLonDistanceCalculator = new CalculateLatLonDistance();
94  	}
95  
96  	/***
97  	 * @see nl.tudelft.simulation.content.HandlerInterface#handleContent(java.io.Serializable)
98  	 */
99  	public synchronized boolean handleContent(final Serializable content)
100 	{
101 		RequestForQuote rfq = (RequestForQuote) checkContent(content);
102 		if (!isValidContent(rfq))
103 		{
104 			return false;
105 		}
106 		Product product = rfq.getProduct();
107 
108 		// react with a Quote. First calculate the price
109 		/*
110 		 * double price = Math.round(rfq.getAmount() ((1 +
111 		 * ((DistTriangularGetters) this.priceDistributions
112 		 * .get(product)).draw() / 100) * this.stock .getUnitPrice(product)) *
113 		 * 0.7);
114 		 */
115 
116 		// we sneaky take the price of the product we got instead of the product
117 		// price from our own stock, as such we keep in line with price changed
118 		// scenario events; of course, a human player should do this by himself
119 		// we have to do it in this way since the pointer to a product is not
120 		// the same, as these are cloned when put in stock
121 		double price = Math.round(rfq.getAmount()
122 				* ((1 + ((DistTriangularGetters) this.priceDistributions
123 						.get(product)).draw() / 100) * product
124 						.getUnitMarketPrice()) * 0.7);
125 
126 		double weight = rfq.getAmount()
127 				* rfq.getProduct().getAverageUnitWeight();
128 
129 		// calculate the costs based on the the lat lon distance!
130 		double transportCosts = TransportMode.PLANE.transportCosts(
131 				this.latLonDistanceCalculator.getDistance(rfq.getSender(), rfq
132 						.getReceiver()), weight);
133 
134 		// add the transport costs to the price
135 		price += transportCosts;
136 
137 		// the handling time
138 		double handlingDelay = this.handlingTimeDistribution.draw();
139 
140 		// look at the delivery date
141 		double date = Math.max(this.owner.getSimulatorTime(), rfq
142 				.getEarliestDeliveryDate()
143 				+ this.delayDistribution.draw() + handlingDelay);
144 
145 		// construct the quote
146 		Quote quote = new Quote(this.owner, rfq.getSender(), rfq
147 				.getInternalDemandID(), rfq, product, rfq.getAmount(), price,
148 				date, TransportMode.PLANE);
149 		super.owner.sendContent(quote, handlingDelay);
150 		return true;
151 	}
152 
153 	/***
154 	 * @see nl.tudelft.simulation.supplychain.handlers.SupplyChainHandler#checkContentClass(java.io.Serializable)
155 	 */
156 	protected boolean checkContentClass(final Serializable content)
157 	{
158 		return (content instanceof RequestForQuote);
159 	}
160 
161 	/***
162 	 * Method changePrice changes the price distribution of a PCManufacturer
163 	 * 
164 	 * @param product the product to change the distribution for
165 	 * @param up if true, price will increase, if false, the price will decrease
166 	 * @param percentage the percentage to change the price with
167 	 */
168 	public synchronized void changePrice(final Product product,
169 			final boolean up, final double percentage)
170 	{
171 		DistTriangularGetters distribution = (DistTriangularGetters) this.priceDistributions
172 				.get(product);
173 		DistTriangularGetters newDistribution = null;
174 		if (distribution != null)
175 		{
176 			if (up)
177 			{
178 				double newB = distribution.getB() * (1 + (percentage / 100));
179 
180 				// we keep the original difference between a - b - c
181 				newDistribution = new DistTriangularGetters(distribution
182 						.getStream(), newB
183 						- (distribution.getB() - distribution.getA()), newB,
184 						newB + (distribution.getC() - distribution.getB()));
185 			} else
186 			{
187 				newDistribution = new DistTriangularGetters(distribution
188 						.getStream(), distribution.getA()
189 						* (1 - (percentage / 100)), distribution.getB()
190 						* (1 - (percentage / 100)), distribution.getC()
191 						* (1 - (percentage / 100)));
192 			}
193 
194 			this.priceDistributions.put(product, newDistribution);
195 		} else
196 		{
197 			Logger.severe(this, "changePrice",
198 					"Could not find distribution for product: "
199 							+ product.getName());
200 		}
201 	}
202 }