001: /*
002: * <copyright>
003: * Copyright 2002-2003 BBNT Solutions, LLC
004: * under sponsorship of the Defense Advanced Research Projects Agency (DARPA).
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the Cougaar Open Source License as published by
008: * DARPA on the Cougaar Open Source Website (www.cougaar.org).
009: *
010: * THE COUGAAR SOFTWARE AND ANY DERIVATIVE SUPPLIED BY LICENSOR IS
011: * PROVIDED 'AS IS' WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS OR
012: * IMPLIED, INCLUDING (BUT NOT LIMITED TO) ALL IMPLIED WARRANTIES OF
013: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND WITHOUT
014: * ANY WARRANTIES AS TO NON-INFRINGEMENT. IN NO EVENT SHALL COPYRIGHT
015: * HOLDER BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL
016: * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE OF DATA OR PROFITS,
017: * TORTIOUS CONDUCT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
018: * PERFORMANCE OF THE COUGAAR SOFTWARE.
019: * </copyright>
020: */
021:
022: package org.cougaar.logistics.plugin.inventory;
023:
024: import org.cougaar.core.util.UniqueObject;
025: import org.cougaar.core.blackboard.Publishable;
026: import org.cougaar.core.util.UID;
027: import org.cougaar.planning.servlet.data.xml.XMLWriter;
028: import org.cougaar.planning.servlet.data.xml.XMLable;
029:
030: import java.util.ArrayList;
031: import java.util.HashSet;
032: import java.util.Collection;
033: import java.util.Iterator;
034:
035: /**
036: * ShortfallSummary is an object that summarizizes which inventories of
037: * a particular inventory have shortfall.
038: */
039:
040: public class ShortfallInventory implements java.io.Serializable,
041: Publishable {
042:
043: private String invID;
044: private String unitOfIssue;
045: private int numDemandSupply = 0;
046: private int numResupplySupply = 0;
047: private int numDemandProj = 0;
048: private int numResupplyProj = 0;
049: private int numTempResupplySupply = 0;
050: private int numTempDemandSupply = 0;
051: private int numTempResupplyProj = 0;
052: private int numTempDemandProj = 0;
053:
054: private boolean unexpected = true;
055:
056: private ArrayList shortfallPeriods;
057:
058: /**
059: * Constructor
060: *
061: * @param anInvID String identifier of the inventory (item/NSN)
062: * @param uoi The Unit of Issue for this Shortfall Inventory
063: */
064:
065: public ShortfallInventory(String anInvID, String uoi) {
066: invID = anInvID;
067: unitOfIssue = uoi;
068: shortfallPeriods = new ArrayList();
069: }
070:
071: /**
072: * The inventory id for this inventory.
073: *
074: * @return The identifier for this inventory
075: * @see org.cougaar.logistics.servlet.LogisticsInventoryServlet>>getNomenclature(inv);
076: */
077: public String getInvID() {
078: return invID;
079: }
080:
081: /**
082: * The unit of issue for the asset contained in this inventory
083: *
084: * @return String the unit of issue for the asset of this inventory.
085: */
086: public String getUnitOfIssue() {
087: return unitOfIssue;
088: }
089:
090: /**
091: * The number of demand supply tasks asked for by customers that had some form of shortfall. Shortfall being
092: * an allocation result that does not deliver the requested amount of demand at the time asked.
093: *
094: * @return int - The number of demand tasks asked for by customers that had some form of shortfall
095: */
096:
097: public int getNumDemandSupply() {
098: return numDemandSupply;
099: }
100:
101: /**
102: * The number of resupply supply tasks asked of the supplier that has some form of shortfall. Shortfall being
103: * an allocation result the amounts to not delivering the requested amount of refill at the time requested.
104: *
105: * @return int - The number of resupply supply tasks asked of the supplier that has some form of shortfall
106: */
107: public int getNumResupplySupply() {
108: return numResupplySupply;
109: }
110:
111: /**
112: * The number of demand project supply tasks asked for by customers that had some form of shortfall
113: *
114: * @return int The number of demand project supply tasks asked for by customers that had some form of shortfall
115: */
116: public int getNumDemandProj() {
117: return numDemandProj;
118: }
119:
120: /**
121: * The number of refill project supply tasks asked for of supplier that has some form of shortfall
122: *
123: * @return int The number of refill project supply tasks asked for of supplier that has some form of shortfall
124: */
125: public int getNumResupplyProj() {
126: return numResupplyProj;
127: }
128:
129: /**
130: * The total number of demand tasks (both supply and project supply) that had some form of shortfall
131: *
132: * @return int The total number of demand tasks (both supply and project supply) that had some form of shortfall
133: */
134: public int getNumDemand() {
135: return numDemandSupply + numDemandProj;
136: }
137:
138: /**
139: * The total number of refill tasks requested from supplier (both actuals and projections) that had some form of shortfall
140: *
141: * @return int The total number of refill tasks requested from supplier (both actuals and projections) that had some form of shortfall
142: */
143: public int getNumRefill() {
144: return numResupplyProj + numResupplySupply;
145: }
146:
147: /**
148: * The total number of projections demand and refill that have some form of shortfall
149: *
150: * @return int The total number of projections demand and refill that have some form of shortfall
151: */
152: public int getNumProjection() {
153: return numDemandProj + numResupplyProj;
154: }
155:
156: /**
157: * The total number of actual supply tasks demand and refill that have some form of shortfall
158: *
159: * @return int The total number of actual supply tasks demand and refill that have some form of shortfall
160: */
161: public int getNumActual() {
162: return numDemandSupply + numResupplySupply;
163: }
164:
165: /**
166: * The total number of refill supply tasks that weren't filled on time, but eventually do get completely filled -
167: * thus temporary shortfall
168: *
169: * @return int The total number of refill supply tasks that eventually do get completely filled and thus temporary shortfall
170: */
171: public int getNumTempResupplySupply() {
172: return numTempResupplySupply;
173: }
174:
175: /**
176: * Get the total number of demand supply tasks that do not get filled on time, but eventually do get completely filled
177: *
178: * @return int - the total number of demand supply tasks that do not get filled on time, but eventually do get completely filled
179: */
180: public int getNumTempDemandSupply() {
181: return numTempDemandSupply;
182: }
183:
184: /**
185: * Get the total number of refill projections that do not get filled on time, but eventually do get completely filled.
186: *
187: * @return int - the total number of refill projections that do not get filled on time, but eventually do get completely filled.
188: */
189: public int getNumTempResupplyProj() {
190: return numTempResupplyProj;
191: }
192:
193: /**
194: * Get the total number of demand projections that do not get filled on time, but eventually do get completely filled.
195: *
196: * @return int - the total number of demand projections that do not get filled on time, but eventually do get completely filled.
197: */
198: public int getNumTempDemandProj() {
199: return numTempDemandProj;
200: }
201:
202: /**
203: * Get the total number of all tasks that contribute to permanent shortfall equivilent usually to failed tasks.
204: *
205: * @return - the total number of all tasks that contribute to permanent shortfall equivilent usually to failed tasks.
206: */
207: public int getNumPermShortfall() {
208: return (getNumTotalShortfall() - getNumTempShortfall());
209: }
210:
211: /**
212: * Get the total number of all tasks that contribute to temporary shortfall. IE tasks that have shortfall but recover.
213: *
214: * @return the total number of all tasks that contribute to temporary shortfall. IE tasks that have shortfall but recover.
215: */
216: public int getNumTempShortfall() {
217: return (getNumTempResupplySupply() + getNumTempDemandSupply()
218: + getNumTempResupplyProj() + getNumTempDemandProj());
219: }
220:
221: /**
222: * Get the total number of tasks that contain shortfall ie the request for an amount is not met on time.
223: *
224: * @return int - the total number of tasks that contain shortfall ie the request for an amount is not met on time.
225: */
226: public int getNumTotalShortfall() {
227: return ((getNumDemandSupply() + getNumResupplySupply()
228: + getNumDemandProj() + getNumResupplyProj()));
229: }
230:
231: /**
232: * Filled in by shortfall servlet. This is whether or not there is shortfall expected at this org/inventory after
233: * the rules of discounting are applied. IE Shortfall of projections in the UA are expected shortfall and therefore discounted.
234: *
235: * @return boolean true if unexpected shortfall exists at this inventory.
236: */
237: public boolean getUnexpected() {
238: return unexpected;
239: }
240:
241: /**
242: * Below are the mutators for the above numbers. Most are set in the LogisticsInventoryBG and UALogisticsBG.
243: * The setUnexpected mutator is called in the servlet.data.shortfall methods in ShortfallShortData and LatShortfallShortData.
244: */
245:
246: public void setUnexpected(boolean isUnexpected) {
247: unexpected = isUnexpected;
248: }
249:
250: public void setNumDemandSupply(int numDemandSupply) {
251: this .numDemandSupply = numDemandSupply;
252: }
253:
254: public void setNumResupplySupply(int numResupplySupply) {
255: this .numResupplySupply = numResupplySupply;
256: }
257:
258: public void setNumDemandProj(int numDemandProj) {
259: this .numDemandProj = numDemandProj;
260: }
261:
262: public void setNumResupplyProj(int numResupplyProj) {
263: this .numResupplyProj = numResupplyProj;
264: }
265:
266: public void setNumTempDemandSupply(int numDemandTemp) {
267: this .numTempDemandSupply = numDemandTemp;
268: }
269:
270: public void setNumTempResupplySupply(int numResupplyTemp) {
271: this .numTempResupplySupply = numResupplyTemp;
272: }
273:
274: public void setNumTempDemandProj(int numDemandTemp) {
275: this .numTempDemandProj = numDemandTemp;
276: }
277:
278: public void setNumTempResupplyProj(int numResupplyTemp) {
279: this .numTempResupplyProj = numResupplyTemp;
280: }
281:
282: public void addShortfallPeriod(ShortfallPeriod aPeriod) {
283: this .shortfallPeriods.add(aPeriod);
284: }
285:
286: public ArrayList getShortfallPeriods() {
287: return shortfallPeriods;
288: }
289:
290: /**
291: * Return the max percent shortfall qty of all the shortfall periods. This percent shortfall is the max of all
292: * totalDemandQty-totalFilledQty/totalDemandQty * 100 percentiles.
293: *
294: * @return int the max percent shortfall of all the shortfall periods.
295: */
296: public int getMaxPercentShortfall() {
297: int maxShortfall = 0;
298: Iterator periodsIt = shortfallPeriods.iterator();
299: while (periodsIt.hasNext()) {
300: ShortfallPeriod period = (ShortfallPeriod) periodsIt.next();
301: maxShortfall = Math.max(maxShortfall, ((int) period
302: .getPercentShortfall()));
303: }
304: return maxShortfall;
305: }
306:
307: public String toString() {
308: StringBuffer sb = new StringBuffer(getInvID());
309: sb.append("\nUnitOfIssue=" + getUnitOfIssue());
310: sb.append("\nNumDemand=" + getNumDemand());
311: sb.append(",NumResupplySupply=" + getNumResupplySupply());
312: sb.append("\nNumDemandProj=" + getNumDemandProj());
313: sb.append(",NumResupplyProj=" + getNumResupplyProj());
314: sb.append(",NumTempDemandSupply=" + getNumTempDemandSupply());
315: sb.append(",NumTempResupplySupply="
316: + getNumTempResupplySupply());
317: sb.append(",NumTempDemandProj=" + getNumTempDemandProj());
318: sb.append(",NumTempResupplyProj=" + getNumTempResupplyProj());
319: sb.append("\nNumPerm=" + getNumPermShortfall());
320: return sb.toString();
321: }
322:
323: /**
324: * Determines equality of shortfall inventory by comparing all the slot and shortfall periods. If all equivlent then
325: * these two shortall inventories are equal.
326: *
327: * @param si The compared to ShortfallInvenotry
328: * @return true if this ShortfallInvenotry and passed on are equivilent
329: */
330: public boolean equals(ShortfallInventory si) {
331: return ((this .getInvID().equals(si.getInvID()))
332: && (this .getNumDemand() == si.getNumDemand())
333: && (this .getNumResupplySupply() == si
334: .getNumResupplySupply())
335: && (this .getNumDemandProj() == si.getNumDemandProj())
336: && (this .getNumResupplyProj() == si
337: .getNumResupplyProj())
338: && (this .getNumTempDemandSupply() == si
339: .getNumTempDemandSupply())
340: && (this .getNumTempResupplySupply() == si
341: .getNumTempResupplySupply())
342: && (this .getNumTempDemandProj() == si
343: .getNumTempDemandProj())
344: && (this .getNumTempResupplyProj() == si
345: .getNumTempResupplyProj()) && (hasEqualShortfallPeriods(si
346: .getShortfallPeriods())));
347: }
348:
349: /**
350: * Helper function to compare shortfall periods in a shortfall inventory
351: *
352: * @param otherShortfallPeriods - shortfall periods in the compared with shortfall inventory
353: * @return true if they are all equivilent.
354: */
355: public boolean hasEqualShortfallPeriods(
356: ArrayList otherShortfallPeriods) {
357: Iterator myPeriods = getShortfallPeriods().iterator();
358: outer_loop: while (myPeriods.hasNext()) {
359: ShortfallPeriod myPeriod = (ShortfallPeriod) myPeriods
360: .next();
361: Iterator otherPeriods = otherShortfallPeriods.iterator();
362: boolean found = false;
363: while (otherPeriods.hasNext()) {
364: ShortfallPeriod otherPeriod = (ShortfallPeriod) otherPeriods
365: .next();
366: if (myPeriod.equals(otherPeriod)) {
367: continue outer_loop;
368: }
369: }
370: return false;
371: }
372: return true;
373: }
374:
375: public boolean isPersistable() {
376: return true;
377: }
378: }
|