Source Code Cross Referenced for AllocationAssessor.java in  » Science » Cougaar12_4 » org » cougaar » logistics » plugin » inventory » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Cougaar12_4 » org.cougaar.logistics.plugin.inventory 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * <copyright>
0003:         *  
0004:         *  Copyright 1997-2004 BBNT Solutions, LLC
0005:         *  under sponsorship of the Defense Advanced Research Projects
0006:         *  Agency (DARPA).
0007:         * 
0008:         *  You can redistribute this software and/or modify it under the
0009:         *  terms of the Cougaar Open Source License as published on the
0010:         *  Cougaar Open Source Website (www.cougaar.org).
0011:         * 
0012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023:         *  
0024:         * </copyright>
0025:         */
0026:
0027:        package org.cougaar.logistics.plugin.inventory;
0028:
0029:        import java.util.*;
0030:
0031:        import org.cougaar.logistics.ldm.Constants;
0032:        import org.cougaar.glm.ldm.asset.Inventory;
0033:        import org.cougaar.glm.ldm.plan.AlpineAspectType;
0034:        import org.cougaar.glm.ldm.plan.ObjectScheduleElement;
0035:
0036:        import org.cougaar.planning.plugin.util.PluginHelper;
0037:
0038:        import org.cougaar.planning.ldm.plan.*;
0039:        import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
0040:
0041:        import org.cougaar.planning.ldm.measure.*;
0042:
0043:        /** AllocationAssessor module is a module of the InventoryPlugin looks at
0044:         *  Refill results and Inventory levels to allocate Withdraws
0045:         *  against the Inventories.
0046:         *  Right now this is implemented with first come first serve, but it
0047:         *  should be changed to allocate withdraws that have the highest score
0048:         *  first where the score is something like quantity * time late or
0049:         *  scoring function scores.
0050:         *  Note that this allocator does NOT allocate split shipments.
0051:         **/
0052:
0053:        public class AllocationAssessor extends InventoryLevelGenerator {
0054:            public class AllocPhase {
0055:                public int startBucket; // first bucket where allocation occurs
0056:                public int endBucket; // bucket beyond where allocation occurs
0057:                public double amount; //amount allocated (per bucket) in the phase
0058:
0059:                public AllocPhase(int startBucket, double amount) {
0060:                    this .startBucket = startBucket;
0061:                    this .endBucket = startBucket + 1;
0062:                    this .amount = amount;
0063:                }
0064:
0065:                public String toString(LogisticsInventoryPG thePG) {
0066:                    return ("AllocPhase of amount: "
0067:                            + amount
0068:                            + " from "
0069:                            + getTimeUtils().dateString(
0070:                                    thePG.convertBucketToTime(startBucket))
0071:                            + " to " + getTimeUtils().dateString(
0072:                            thePG.convertBucketToTime(endBucket)));
0073:                }
0074:            }
0075:
0076:            public class TaskDeficit {
0077:
0078:                public Task task;
0079:
0080:                public Task getTask() {
0081:                    return task;
0082:                }
0083:
0084:                LogisticsInventoryPG thePG;
0085:
0086:                public ArrayList rateBlocks = new ArrayList();
0087:
0088:                public double getRemainingQty(int currentBucket) {
0089:                    ConstantRateBlock block = getRateBlock(currentBucket);
0090:                    if (block != null) {
0091:                        return block.getRemainingQty();
0092:                    }
0093:                    return 0.0d;
0094:                }
0095:
0096:                public void setRemainingQty(int currentBucket, double rq) {
0097:                    ConstantRateBlock block = getRateBlock(currentBucket);
0098:                    if (block != null) {
0099:                        block.setRemainingQty(rq);
0100:                    }
0101:                }
0102:
0103:                public void incrementBacklog(int currentBucket, double bl) {
0104:                    ConstantRateBlock block = getRateBlock(currentBucket);
0105:                    if (block != null) {
0106:                        block.incrementBacklog(bl);
0107:                    }
0108:                }
0109:
0110:                public Collection getDeficitAllocationPhases() {
0111:                    ArrayList defPhases = new ArrayList();
0112:                    Iterator rateBlocksIt = rateBlocks.iterator();
0113:
0114:                    while (rateBlocksIt.hasNext()) {
0115:                        ConstantRateBlock currentBlock = (ConstantRateBlock) rateBlocksIt
0116:                                .next();
0117:                        defPhases.addAll(currentBlock
0118:                                .getDeficitAllocationPhases());
0119:                    }
0120:                    return defPhases;
0121:                }
0122:
0123:                public void initializeRateBlocks() {
0124:                    long taskStartTime = getTaskUtils().getStartTime(task);
0125:                    long taskEndTime = getTaskUtils().getEndTime(task);
0126:                    PrepositionalPhrase pp_rate = task
0127:                            .getPrepositionalPhrase(Constants.Preposition.DEMANDRATE);
0128:                    if (pp_rate != null) {
0129:                        Object indObj = pp_rate.getIndirectObject();
0130:                        if (indObj instanceof  Schedule) {
0131:                            Schedule sched = (Schedule) indObj;
0132:                            Collection rate_elems = sched
0133:                                    .getOverlappingScheduleElements(
0134:                                            taskStartTime, taskEndTime);
0135:                            int n = (rate_elems == null ? 0 : rate_elems.size());
0136:                            if (n == 1) {
0137:                                rateBlocks.add(new ConstantRateBlock(
0138:                                        taskStartTime, taskEndTime, 0.0d));
0139:                            } else if (n > 1) {
0140:                                // return a schedule of daily rates
0141:                                rateBlocks = new ArrayList(n);
0142:                                for (Iterator iter = rate_elems.iterator(); iter
0143:                                        .hasNext();) {
0144:                                    ObjectScheduleElement ose = (ObjectScheduleElement) iter
0145:                                            .next();
0146:                                    rateBlocks.add(new ConstantRateBlock(ose
0147:                                            .getStartTime(), ose.getEndTime(),
0148:                                            0.0d));
0149:                                }
0150:                            }
0151:                        }
0152:                    } else {
0153:                        rateBlocks.add(new ConstantRateBlock(taskStartTime,
0154:                                taskEndTime, 0.0d));
0155:                    }
0156:                }
0157:
0158:                //Fill in the gaps in the deficit buckets with successful buckets
0159:                public Collection generateAllAllocationPhases() {
0160:                    Iterator rateBlocksIt = rateBlocks.iterator();
0161:
0162:                    ArrayList allPhases = new ArrayList();
0163:
0164:                    while (rateBlocksIt.hasNext()) {
0165:                        ConstantRateBlock currentBlock = (ConstantRateBlock) rateBlocksIt
0166:                                .next();
0167:                        allPhases.addAll(currentBlock
0168:                                .generateAllAllocationPhases(task, thePG));
0169:                    }
0170:                    return allPhases;
0171:                }
0172:
0173:                public TaskDeficit(Task withdraw, int currentBucket,
0174:                        double qty, LogisticsInventoryPG thePG) {
0175:                    task = withdraw;
0176:                    this .thePG = thePG;
0177:                    initializeRateBlocks();
0178:                    setRemainingQty(currentBucket, qty);
0179:                }
0180:
0181:                public ConstantRateBlock getRateBlock(int bucket) {
0182:                    long time = thePG.convertBucketToTime(bucket);
0183:                    return getRateBlock(time);
0184:                }
0185:
0186:                public ConstantRateBlock getRateBlock(long time) {
0187:                    Iterator rateBlocksIt = rateBlocks.iterator();
0188:
0189:                    while (rateBlocksIt.hasNext()) {
0190:                        ConstantRateBlock currentBlock = (ConstantRateBlock) rateBlocksIt
0191:                                .next();
0192:                        if ((currentBlock.startTime <= time)
0193:                                && (currentBlock.endTime > time)) {
0194:                            return currentBlock;
0195:                        }
0196:                    }
0197:                    return null;
0198:                }
0199:
0200:                public void addPhase(double amount, int currentBucket) {
0201:                    ConstantRateBlock block = getRateBlock(currentBucket);
0202:                    if (block != null) {
0203:                        block.addPhase(task, thePG, amount, currentBucket);
0204:                    }
0205:                }
0206:            }
0207:
0208:            public class ConstantRateBlock {
0209:                public long startTime;
0210:                public long endTime;
0211:                public ArrayList allocated = new ArrayList();
0212:                public AllocPhase lastPhase;
0213:
0214:                public double remainingQty;
0215:
0216:                public double getRemainingQty() {
0217:                    return remainingQty;
0218:                }
0219:
0220:                public void setRemainingQty(double rq) {
0221:                    remainingQty = rq;
0222:                }
0223:
0224:                public double backlog = 0.0;
0225:
0226:                public void incrementBacklog(double bl) {
0227:                    backlog = bl + backlog;
0228:                }
0229:
0230:                public Collection getDeficitAllocationPhases() {
0231:                    return allocated;
0232:                }
0233:
0234:                //Fill in the gaps in the deficit buckets with successful buckets
0235:                public Collection generateAllAllocationPhases(Task task,
0236:                        LogisticsInventoryPG thePG) {
0237:                    Iterator defPhasesIt = allocated.iterator();
0238:
0239:                    int rateBlockStartBucket = thePG.convertTimeToBucket(
0240:                            startTime, false);
0241:
0242:                    int rateBlockEndBucket = thePG.convertTimeToBucket(endTime,
0243:                            true);
0244:
0245:                    int lastBucket = rateBlockStartBucket;
0246:
0247:                    ArrayList allPhases = new ArrayList();
0248:
0249:                    while (defPhasesIt.hasNext()) {
0250:                        AllocPhase currentPhase = (AllocPhase) defPhasesIt
0251:                                .next();
0252:                        if (currentPhase.startBucket > lastBucket) {
0253:                            /*if ((inventoryPlugin.getClusterId().toString().indexOf("2-NLOS-BTY") >= 0) &&
0254:                               (task.getDirectObject().getTypeIdentificationPG().getTypeIdentification().indexOf("155mm-DPICM") >= 0)) {
0255:                              System.out.println("Got a Phase after the end time of the task..." +
0256:                                                 " qty of phase is " + currentPhase.amount + " " +
0257:                                                 task.getUID() + " late phase starts on " +
0258:                                                 new Date(thePG.convertBucketToTime(currentPhase.startBucket)));
0259:                            }*/
0260:                            //TODO - EPD This best quantity fill in code causes lots of problems!!!!
0261:                            long lastTime = thePG
0262:                                    .convertBucketToTime(lastBucket);
0263:                            AllocPhase betweenPhase = new AllocPhase(
0264:                                    lastBucket, getBestBucketQty(task, thePG,
0265:                                            lastTime));
0266:                            betweenPhase.endBucket = currentPhase.startBucket;
0267:                            allPhases.add(betweenPhase);
0268:                        }
0269:                        allPhases.add(currentPhase);
0270:                        lastBucket = currentPhase.endBucket;
0271:                    }
0272:
0273:                    if (lastBucket < rateBlockEndBucket) {
0274:                        long lastTime = thePG.convertBucketToTime(lastBucket);
0275:                        AllocPhase lastPhase = new AllocPhase(lastBucket,
0276:                                getBestBucketQty(task, thePG, lastTime));
0277:                        lastPhase.endBucket = rateBlockEndBucket;
0278:                        allPhases.add(lastPhase);
0279:                    }
0280:                    return allPhases;
0281:                }
0282:
0283:                public ConstantRateBlock(long startTime, long endTime,
0284:                        double qty) {
0285:                    //task = withdraw;
0286:                    lastPhase = null;
0287:                    remainingQty = qty;
0288:                    this .startTime = startTime;
0289:                    this .endTime = endTime;
0290:                    //this.thePG=thePG;
0291:                }
0292:
0293:                public void addPhase(Task task, LogisticsInventoryPG thePG,
0294:                        double amount, int currentBucket) {
0295:                    if (amount < 0.0) {
0296:                        if (logger.isInfoEnabled()) {
0297:                            String itemId = getTaskUtils()
0298:                                    .getTaskItemName(task);
0299:                            TypeIdentificationPG typeIdPG = thePG.getResource()
0300:                                    .getTypeIdentificationPG();
0301:                            String nomenclature = null;
0302:                            String orgId = thePG.getOrg()
0303:                                    .getItemIdentificationPG()
0304:                                    .getItemIdentification();
0305:                            if (typeIdPG == null) {
0306:                                logger
0307:                                        .warn("No typeIdentificationPG for asset");
0308:                            } else {
0309:                                nomenclature = typeIdPG.getNomenclature();
0310:                            }
0311:                            if (nomenclature == null) {
0312:                                nomenclature = itemId;
0313:                            }
0314:                            logger
0315:                                    .info(" Adding a phase of a negative amount=="
0316:                                            + amount
0317:                                            + " at bucket "
0318:                                            + getTimeUtils()
0319:                                                    .dateString(
0320:                                                            thePG
0321:                                                                    .convertBucketToTime(currentBucket))
0322:                                            + "for task: "
0323:                                            + task.getUID()
0324:                                            + " org is "
0325:                                            + inventoryPlugin.getOrgName()
0326:                                            + " and the item is : "
0327:                                            + nomenclature);
0328:                        }
0329:                        amount = 0.0;
0330:                    }
0331:                    if (amount == 0.0) {
0332:                        if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0333:                            return;
0334:                        }
0335:                    }
0336:                    if (task.getVerb().equals(Constants.Verb.PROJECTWITHDRAW)
0337:                            && lastPhase != null
0338:                            && currentBucket == lastPhase.endBucket
0339:                            && amount == lastPhase.amount) {
0340:                        // same as last phase so just extend last phase
0341:                        lastPhase.endBucket = currentBucket + 1;
0342:                    } else {
0343:
0344:                        // find existing phase for bucket if exists
0345:                        Iterator phases = allocated.iterator();
0346:                        AllocPhase aPhase = null, thePhase = null;
0347:                        while (phases.hasNext()) {
0348:                            aPhase = (AllocPhase) phases.next();
0349:                            if ((aPhase.startBucket <= currentBucket)
0350:                                    && (aPhase.endBucket > currentBucket)) {
0351:                                thePhase = aPhase;
0352:                                break;
0353:                            }
0354:                        }
0355:                        if (thePhase == null) {
0356:                            //          if ((inventoryPlugin.getClusterId().toString().indexOf("2-NLOS-BTY") >= 0) &&
0357:                            //              (task.getDirectObject().getTypeIdentificationPG().getTypeIdentification().indexOf("155mm-DPICM") >= 0)) {
0358:                            //            System.out.println("Adding new last phase to fill deficit... task " + task.getUID() + " bucket " +
0359:                            //                               new Date (thePG.convertBucketToTime(currentBucket)) + " amount " + amount);
0360:                            //          }
0361:                            // add new phase
0362:                            lastPhase = new AllocPhase(currentBucket, amount);
0363:                            allocated.add(lastPhase);
0364:                        } else {
0365:                            thePhase.amount += amount;
0366:                        }
0367:                    }
0368:                    if (remainingQty == amount) {
0369:                        if (backlog > 0.0) {
0370:                            remainingQty = taskQtyInBucket(task, currentBucket,
0371:                                    thePG);
0372:                            backlog = backlog - remainingQty;
0373:                        } else {
0374:                            remainingQty = 0.0;
0375:                        }
0376:                    } else {
0377:                        remainingQty = remainingQty - amount;
0378:                    }
0379:                }
0380:            }
0381:
0382:            private transient HashMap trailingPointersHash = new HashMap();
0383:            private transient ArrayList trailingPointers = new ArrayList();
0384:            private transient ArrayList trailingPointersRemove = new ArrayList();
0385:            private Role myRole;
0386:
0387:            /** Constructor for this module
0388:             *  @param imPlugin The Plugin calling this module.
0389:             *  @param role  The role the Plugin is playing.
0390:             **/
0391:            public AllocationAssessor(InventoryManager imPlugin, Role role) {
0392:                super (imPlugin);
0393:                myRole = role;
0394:            }
0395:
0396:            /** Called by the InventoryPlugin when we are processing in Backwards Flow
0397:             *  (which is allocation result notifications) to try and allocated
0398:             *  withdraw tasks.  It also updates the BG's Inventory Levels.
0399:             *  @param inventories  The collection of inventories to be processed
0400:             **/
0401:            public void reconcileInventoryLevels(Collection inventories) {
0402:                Iterator inv_list = inventories.iterator();
0403:                long currentTime = inventoryPlugin.getCurrentTimeMillis();
0404:                int today_bucket;
0405:                Inventory inventory;
0406:                LogisticsInventoryPG thePG;
0407:                long endOfLevel2 = ((LevelOfDetailInventoryManager) inventoryPlugin)
0408:                        .getEndOfLevelTwo();
0409:                while (inv_list.hasNext()) {
0410:                    inventory = (Inventory) inv_list.next();
0411:                    resetTrailingPointers();
0412:                    thePG = (LogisticsInventoryPG) inventory
0413:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
0414:                    long inventoryStart = thePG.getStartTime();
0415:                    long today = Math.max(inventoryStart, currentTime);
0416:                    today_bucket = thePG.convertTimeToBucket(today, false);
0417:                    reconcileThePast(today_bucket, thePG);
0418:                    int end_bucket = thePG.getLastDemandBucket();
0419:                    int endOfLevel2Bucket = thePG.convertTimeToBucket(
0420:                            endOfLevel2, false);
0421:                    if (end_bucket > endOfLevel2Bucket) {
0422:                        end_bucket = endOfLevel2Bucket;
0423:                    }
0424:                    createAllocations(today_bucket, end_bucket, inventory,
0425:                            thePG);
0426:                    allocateNotCountedProjections(inventory, thePG);
0427:                    allocateCountedEarlyProjections(today_bucket, inventory,
0428:                            thePG);
0429:                }
0430:            }
0431:
0432:            /**
0433:             * Reset Pointers Map, list of pointers, and pointer remove list
0434:             */
0435:            protected void resetTrailingPointers() {
0436:                // clear out the trailing pointers every time we get another inventory
0437:                trailingPointersHash = new HashMap();
0438:                trailingPointers = new ArrayList();
0439:                trailingPointersRemove = new ArrayList();
0440:            }
0441:
0442:            /** Update the inventory levels from time zero to today.
0443:             *  @param today_bucket  Representation of today.
0444:             *  @param thePG The PG for the Inventory Asset we are working with.
0445:             **/
0446:            public void reconcileThePast(int today_bucket,
0447:                    LogisticsInventoryPG thePG) {
0448:                calculateInventoryLevels(thePG.getStartBucket(), today_bucket,
0449:                        thePG);
0450:            }
0451:
0452:            public double getBestBucketQty(Task task,
0453:                    LogisticsInventoryPG thePG, long time) {
0454:                Rate r = getTaskUtils().getRate(task, time);
0455:                return getQuantityForDuration(r, thePG.getBucketMillis());
0456:            }
0457:
0458:            public double getQuantityForDuration(Rate r, long duration) {
0459:                Duration d = Duration.newMilliseconds(duration);
0460:                Scalar scalar = (Scalar) r.computeNumerator(d);
0461:                return getTaskUtils().getDouble(scalar);
0462:            }
0463:
0464:            /** Create and update Withdraw and ProjectWithdraw Task Allocations for a particular Inventory
0465:             *  @param todayBucket This is the starting bucket to process
0466:             *  @param endBucket Whats the last valid bucket for the inventory
0467:             *  @param inv The Inventory we are processing
0468:             *  @param thePG This is the PG for the Inventory we are processing
0469:             **/
0470:            protected void createAllocations(int todayBucket, int endBucket,
0471:                    Inventory inv, LogisticsInventoryPG thePG) {
0472:
0473:                int currentBucket = todayBucket;
0474:                double qty = 0;
0475:                double todayLevel, todayRefill;
0476:                Task withdraw;
0477:
0478:                // DEBUG
0479:                String myOrgName = inventoryPlugin.getClusterId().toString();
0480:                String myItemId = inv.getItemIdentificationPG()
0481:                        .getItemIdentification();
0482:                LogisticsInventoryPG logInvPG = (LogisticsInventoryPG) inv
0483:                        .searchForPropertyGroup(LogisticsInventoryPG.class);
0484:                String nomenclature = logInvPG.getResource()
0485:                        .getTypeIdentificationPG().getNomenclature();
0486:
0487:                /*if ((myOrgName.indexOf("2-NLOS-BTY") >= 0) && (myItemId.indexOf("155mm-DPICM") >= 0)) {
0488:                	      System.out.println("### createAlloc : Assessing allocations RIGHT ORG NAME COMBO - " + myOrgName + " - " + myItemId);
0489:                }*/
0490:
0491:                // loop through the buckets in the inventory
0492:                while (currentBucket <= endBucket) {
0493:
0494:                    todayRefill = findCommittedRefill(currentBucket, thePG,
0495:                            true);
0496:                    todayLevel = thePG.getLevel(currentBucket - 1)
0497:                            + todayRefill;
0498:
0499:                    /***
0500:                     **
0501:
0502:                    if((inventoryPlugin.getOrgName().indexOf("47-FSB") != -1) &&
0503:                       (thePG.getItemName().indexOf("9140002865294") != -1)) {
0504:                      logger.error("createAllocations - bucket is "+getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket))+
0505:                                   ", committed refill "+todayRefill+" and today's inventory level "+todayLevel);
0506:                    }
0507:
0508:                     **/
0509:
0510:                    // First try to fill any previous deficits
0511:                    Iterator tpIt = trailingPointers.iterator();
0512:                    while (tpIt.hasNext()) {
0513:                        TaskDeficit td = (TaskDeficit) tpIt.next();
0514:                        withdraw = td.getTask();
0515:                        //TODO - EPD HACK for LAT 1.0 delivery to stop late fills of projections
0516:                        // related problem is in the TD code that "fills in" bare spots.
0517:                        if (withdraw.getVerb().equals(
0518:                                Constants.Verb.PROJECTWITHDRAW)) {
0519:                            long taskEndTime = getTaskUtils().getEndTime(
0520:                                    withdraw);
0521:                            int taskEndBucket = thePG.convertTimeToBucket(
0522:                                    taskEndTime, true);
0523:                            if (taskEndBucket < currentBucket) {
0524:                                continue;
0525:                            }
0526:                        }
0527:                        qty = td.getRemainingQty(currentBucket);
0528:                        // DEBUG Task deficits
0529:                        //if ((myOrgName.indexOf("592-ORDCO") >= 0) && (myItemId.indexOf("Level2Am") >= 0)) {
0530:                        //if ((myOrgName.indexOf("2-NLOS-BTY") >= 0) && (myItemId.indexOf("155mm-DPICM") >= 0)) {
0531:                        //System.out.println("### createAlloc : trying to fill a PREVIOUS deficit for task:|" + withdraw.getUID() + "| : todaylevel|" + todayLevel + "| and qty is |" + qty + "| and the date is " +  getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket)));
0532:                        //}
0533:                        //}
0534:                        // check the level
0535:                        if (todayLevel <= 0.0) {
0536:                            //          if ((myOrgName.indexOf("2-NLOS-BTY") >= 0) && (myItemId.indexOf("155mm-DPICM") >= 0)) {
0537:                            //            System.out.println("TodayLevel is " + todayLevel + " adding 0 phase for bucket " +
0538:                            //                               new Date(thePG.convertBucketToTime(currentBucket)) + " task " +
0539:                            //                               td.getTask().getUID());
0540:                            //          }
0541:                            td.addPhase(0.0, currentBucket);
0542:                            break;
0543:                        } else if (todayLevel >= qty) {
0544:                            // Can completely fill known deficit
0545:                            /***
0546:                             **
0547:                            if((inventoryPlugin.getOrgName().indexOf("47-FSB") != -1) &&
0548:                               (thePG.getItemName().indexOf("9140002865294") != -1)) {
0549:                              logger.error("calculateAllocations - filling deficit on day "+
0550:                                           getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket))+
0551:                                           " and the remaining qty is "+qty+" and new inventory level is "+todayLevel+" for task "+
0552:                                           withdraw.getUID() + " task request qty " + getTaskUtils().getDailyQuantity(withdraw));               
0553:                            }        
0554:                             **/
0555:
0556:                            fillDeficit(td, currentBucket, inv, thePG);
0557:                            todayLevel = todayLevel - qty;
0558:                        } else {
0559:                            //this withdraw has previously had a deficit we cannot fill the deficit entirely during this bucket`
0560:                            //  leave the TaskDeficit in the same place on the queue -- it still needs to be filled with its old priority
0561:
0562:                            /****
0563:                             ***
0564:
0565:                            if((inventoryPlugin.getOrgName().indexOf("47-FSB") != -1) &&
0566:                               (thePG.getItemName().indexOf("9140002865294") != -1)) {
0567:                              logger.error("calculateAllocations - adding phase on day "+
0568:                                           getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket))+
0569:                                           " and td.remaining qty is " + qty + " today level is " + todayLevel + " setting today level to 0. This is for task " + withdraw.getUID() +  " task request daily quantity " + getTaskUtils().getDailyQuantity(withdraw ));               
0570:                            }  
0571:
0572:                             **/
0573:
0574:                            td.addPhase(todayLevel, currentBucket);
0575:                            todayLevel = 0.0;
0576:                            break; // nothing more to allocate
0577:                        }
0578:                    }
0579:                    // remove any trailing pointers we filled
0580:                    trailingPointers.removeAll(trailingPointersRemove);
0581:                    trailingPointersRemove.clear();
0582:
0583:                    // Fill any counted tasks with remaining inventory (if any)
0584:
0585:                    Collection wdTasks = thePG
0586:                            .getActualDemandTasks(currentBucket);
0587:                    Iterator wdIter = wdTasks.iterator();
0588:                    while (wdIter.hasNext()) {
0589:                        withdraw = (Task) wdIter.next();
0590:                        qty = taskQtyInBucket(withdraw, currentBucket, thePG);
0591:                        // check the level
0592:                        if ((todayLevel - qty) > -.00000005) {
0593:                            // enough inventory to fill task completely
0594:
0595:                            //  NOTE: we have had a case where todayLevel= 12.999999999999995
0596:                            //   and quantity = 12.999999999999998
0597:
0598:                            fulfillTask(withdraw, currentBucket, inv, thePG);
0599:                            todayLevel = Math.max(0.0, todayLevel - qty);
0600:
0601:                            //          if((inventoryPlugin.getOrgName().indexOf("47-FSB") != -1) &&
0602:                            //             (thePG.getItemName().indexOf("9140002865294") != -1)) {
0603:                            //            logger.error("calculateAllocations - fulfill task on day "+
0604:                            //                         getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket))+
0605:                            //                         " demand is "+qty+" and new inventory level is "+todayLevel+" for task "+
0606:                            //                         withdraw.getUID() + " task qty " + getTaskUtils().getDailyQuantity(withdraw));
0607:                            //          }
0608:
0609:                        } else {
0610:                            // can't fill this task totally -- create deficit on this task
0611:                            // if it already has a pe - rescind it
0612:                            PlanElement pe = withdraw.getPlanElement();
0613:                            if (pe != null)
0614:                                inventoryPlugin.publishRemove(pe);
0615:                            TaskDeficit td = getTaskDeficit(withdraw,
0616:                                    currentBucket, thePG);
0617:                            td.addPhase(todayLevel, currentBucket);
0618:                            // DEBUG Task deficits
0619:                            //if ((myOrgName.indexOf("592-ORDCO") >= 0) && (myItemId.indexOf("Level2Amm") >= 0)) {
0620:                            //    System.out.println("### createAlloc : adding a phase to a task deficit/deficit added to TRAILING POINTERS for task:|" 
0621:                            //+ td.getTask().getUID() +"|  todaylevel|" + todayLevel + 
0622:                            // "| and qty is |" + qty + "| and the date is " +  
0623:                            //getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket)));
0624:                            //}
0625:
0626:                            /***
0627:                             **
0628:                            if((inventoryPlugin.getOrgName().indexOf("47-FSB") != -1) &&
0629:                               (thePG.getItemName().indexOf("9140002865294") != -1)) {
0630:                              logger.error("calculateAllocations - deficit for task on day "+
0631:                                           getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket))+
0632:                                           " demand is "+qty+" and new inventory level is 0.0 and provided "+todayLevel+" to "+
0633:                                           withdraw.getUID()+ " task qty " + getTaskUtils().getDailyQuantity(withdraw) + " TD: remainingQty " + td.getRemainingQty() + " backlog " + td.backlog);
0634:                                if(td.lastPhase != null) {
0635:                                  logger.error("And Last Phase is = " + td.lastPhase.toString(thePG));
0636:                                }
0637:                            }          
0638:
0639:                             ***
0640:                             **/
0641:
0642:                            trailingPointers.add(td);
0643:                            // this task depletes the inventory level
0644:                            todayLevel = 0.0;
0645:                        }
0646:                    }
0647:
0648:                    //when we are done going through all the tasks for the day set the level
0649:                    thePG.setLevel(currentBucket, todayLevel);
0650:                    currentBucket = currentBucket + 1;
0651:                }
0652:
0653:                // DEBUG inventory levels
0654:                //if ((myOrgName.indexOf("592-ORDCO") >= 0) && (myItemId.indexOf("Level2Amm") >= 0)) {
0655:                //  for(currentBucket = 0; currentBucket<80; currentBucket++){
0656:                //if (thePG.convertBucketToTime(currentBucket) >= 1128643200000L) {
0657:                //System.out.println("###-" + myOrgName + 
0658:                //"-createAlloc Inventory Level = "+
0659:                //thePG.getLevel(currentBucket)+ " on ("+ currentBucket +") " +
0660:                //getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket)));
0661:                //	}
0662:                // }
0663:                //}
0664:
0665:                //when we are finished, if we have things left in trailingPointers, fail them
0666:                Iterator tpIt = trailingPointers.iterator();
0667:                while (tpIt.hasNext()) {
0668:                    TaskDeficit td = (TaskDeficit) tpIt.next();
0669:                    //      if ((myOrgName.indexOf("2-NLOS-BTY") >= 0) && (myItemId.indexOf("155mm-DPICM") >= 0)) {
0670:                    //        System.out.println("Creating failed phased AR. task deficit is " + td.getTask() + " " + td.getRemainingQty());
0671:                    //      }
0672:                    //createPhasedAllocationResult(td, inv, thePG, false);
0673:                    createPhasedAllocationResult(td, inv, thePG, true);
0674:                }
0675:            }
0676:
0677:            private TaskDeficit getTaskDeficit(Task task, int currentBucket,
0678:                    LogisticsInventoryPG thePG) {
0679:                double qty = taskQtyInBucket(task, currentBucket, thePG);
0680:                TaskDeficit td = ((TaskDeficit) trailingPointersHash.get(task));
0681:                if (td == null) {
0682:                    td = new TaskDeficit(task, currentBucket, qty, thePG);
0683:                    if (task.getVerb().equals(Constants.Verb.PROJECTWITHDRAW)) {
0684:                        trailingPointersHash.put(task, td);
0685:                    }
0686:                } else if (td.getRemainingQty(currentBucket) > 0.0) {
0687:                    // can only happen when we have a projectWithdraw task which has a previous bucket still
0688:                    //  unfilled
0689:                    td.incrementBacklog(currentBucket, qty);
0690:                } else {
0691:                    // can only happen when we have a projectWithdraw task which has no previous bucket still
0692:                    //  unfilled
0693:                    td.setRemainingQty(currentBucket, qty);
0694:                }
0695:                return td;
0696:            }
0697:
0698:            private void fillDeficit(TaskDeficit td, int currentBucket,
0699:                    Inventory inv, LogisticsInventoryPG thePG) {
0700:                // DEBUG      
0701:                //String myOrgName = inventoryPlugin.getMyOrganization().getItemIdentificationPG().getItemIdentification();
0702:                //String myItemId = inv.getItemIdentificationPG().getItemIdentification();
0703:                Task task = td.getTask();
0704:                if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0705:                    // task is completed
0706:                    if (td.getDeficitAllocationPhases().isEmpty()) {
0707:                        createLateAllocation(task, thePG
0708:                                .convertBucketToTime(currentBucket), inv, thePG);
0709:                    } else {
0710:                        //BD added the td.addPhase line to make a phase to fill the deficit
0711:                        td.addPhase(td.getRemainingQty(currentBucket),
0712:                                currentBucket);
0713:                        createPhasedAllocationResult(td, inv, thePG, true);
0714:                    }
0715:                } else {
0716:                    td.addPhase(td.getRemainingQty(currentBucket),
0717:                            currentBucket);
0718:                    if ((thePG.convertBucketToTime(currentBucket + 1) >= (long) PluginHelper
0719:                            .getPreferenceBestValue(task, AspectType.END_TIME))) {
0720:                        //DEBUG
0721:                        //  if ((myOrgName.indexOf("592") >= 0) && (myItemId.indexOf("Level2Amm") >= 0)) {
0722:                        //  logger.debug("### fillDeficit : creating a phased allocation result for task: " + task.getUID() + " on the date of " + getTimeUtils().dateString(thePG.convertBucketToTime(currentBucket)));
0723:                        //}
0724:                        createPhasedAllocationResult(td, inv, thePG, true);
0725:                    }
0726:                }
0727:                trailingPointersRemove.add(td);
0728:            }
0729:
0730:            private void fulfillTask(Task task, int currentBucket,
0731:                    Inventory inv, LogisticsInventoryPG thePG) {
0732:                if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0733:                    //Safely check if the pe is null here and if we get one, pass it to the check method
0734:                    //instead of letting the check method get it since it may have been rescinded in between
0735:                    // the task.getPlanElement() calls which can cause an NPE in checkPlanElement
0736:                    PlanElement pe = task.getPlanElement();
0737:                    if (pe != null) {
0738:                        // previously allocated WITHDRAW task -- update plan element if needed
0739:                        checkPlanElement(task, pe);
0740:                    } else {
0741:                        // previously un-allocated WITHDRAW task
0742:                        createBestAllocation(task, inv, thePG);
0743:                    }
0744:                } else {
0745:                    //projection
0746:                    TaskDeficit td = (TaskDeficit) trailingPointersHash
0747:                            .get(task);
0748:                    if (td != null) {
0749:                        //this project withdraw has previously had a deficit
0750:                        td.addPhase(
0751:                                taskQtyInBucket(task, currentBucket, thePG),
0752:                                currentBucket);
0753:                        if ((thePG.convertBucketToTime(currentBucket + 1) >= (long) PluginHelper
0754:                                .getPreferenceBestValue(task,
0755:                                        AspectType.END_TIME))) {
0756:                            // the projectWithdraw does end during this bucket
0757:                            createPhasedAllocationResult(td, inv, thePG, true);
0758:                        }
0759:                    } else if (thePG.convertBucketToTime(currentBucket + 1) >= (long) PluginHelper
0760:                            .getPreferenceBestValue(task, AspectType.END_TIME)) {
0761:                        //this project withdraw ends during this bucket
0762:                        // it has not previously had a deficit
0763:                        createBestAllocation(task, inv, thePG);
0764:                    } //else {
0765:                    //this project withdraw has never had a deficit and does not end during this bucket
0766:                    //  do nothing -- hope for createBestAllocation
0767:                    //}
0768:                }
0769:            }
0770:
0771:            public void createPhasedAllocationResult(TaskDeficit td,
0772:                    Inventory inv, LogisticsInventoryPG thePG, boolean success) {
0773:                //if we are passing in a false - see if we already made a failed AR/PE. If we did just get out.
0774:                Task task = td.getTask();
0775:                PlanElement prevPE = task.getPlanElement();
0776:                /**if (prevPE != null && !success) {
0777:                  if (!prevPE.getEstimatedResult().isSuccess()) {
0778:                    return;
0779:                  }
0780:                }*/
0781:
0782:                ArrayList phasedResults = new ArrayList();
0783:                double rollupQty = 0;
0784:                AspectValue avs[];
0785:
0786:                if (shouldSkipMakingResult(task)) {
0787:                    return;
0788:                }
0789:
0790:                //initialize the rollup array depending on the verb --sigh...
0791:                if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0792:                    avs = new AspectValue[2];
0793:                } else {
0794:                    avs = new AspectValue[3];
0795:                }
0796:
0797:                ArrayList phases = (ArrayList) td.getDeficitAllocationPhases();
0798:                if (phases.isEmpty()) {
0799:                    //if we totally fail
0800:                    if ((inventoryPlugin.getClusterId().toString().indexOf(
0801:                            "2-NLOS-BTY") >= 0)
0802:                            && (task.getDirectObject()
0803:                                    .getTypeIdentificationPG()
0804:                                    .getTypeIdentification().indexOf(
0805:                                            "155mm-DPICM") >= 0)) {
0806:                        System.out
0807:                                .println("Totally failing task b/c there are not phases... "
0808:                                        + task.getUID());
0809:                    }
0810:                    createFailedAllocation(task, inv, thePG);
0811:                    return;
0812:                }
0813:
0814:                if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0815:                    int rollupEnd = ((AllocPhase) phases.get(phases.size() - 1)).endBucket;
0816:                    int rollupStart = ((AllocPhase) phases.get(0)).startBucket;
0817:                    avs[0] = AspectValue.newAspectValue(AspectType.END_TIME,
0818:                            thePG.convertBucketToTime(rollupEnd));
0819:                    avs[1] = AspectValue.newAspectValue(AspectType.START_TIME,
0820:                            thePG.convertBucketToTime(rollupStart));
0821:
0822:                    Iterator phasesIt = phases.iterator();
0823:                    //use end and qty
0824:                    while (phasesIt.hasNext()) {
0825:                        AllocPhase aPhase = (AllocPhase) phasesIt.next();
0826:                        AspectValue this Phase[] = new AspectValue[2];
0827:                        rollupQty = rollupQty + aPhase.amount;
0828:                        this Phase[0] = AspectValue.newAspectValue(
0829:                                AspectType.END_TIME, thePG
0830:                                        .convertBucketToTime(aPhase.endBucket));
0831:                        this Phase[1] = AspectValue.newAspectValue(
0832:                                AspectType.QUANTITY, aPhase.amount);
0833:                        phasedResults.add(this Phase);
0834:                    }
0835:                    avs[1] = AspectValue.newAspectValue(AspectType.QUANTITY,
0836:                            rollupQty);
0837:                } else {
0838:
0839:                    phases = (ArrayList) td.generateAllAllocationPhases();
0840:
0841:                    int rollupEnd = ((AllocPhase) phases.get(phases.size() - 1)).endBucket;
0842:                    int rollupStart = ((AllocPhase) phases.get(0)).startBucket;
0843:                    avs[0] = AspectValue.newAspectValue(AspectType.END_TIME,
0844:                            thePG.convertBucketToTime(rollupEnd));
0845:                    avs[1] = AspectValue.newAspectValue(AspectType.START_TIME,
0846:                            thePG.convertBucketToTime(rollupStart));
0847:
0848:                    Iterator phasesIt = phases.iterator();
0849:
0850:                    phasesIt = phases.iterator();
0851:                    while (phasesIt.hasNext()) {
0852:                        AllocPhase aPhase = (AllocPhase) phasesIt.next();
0853:                        rollupQty = rollupQty
0854:                                + ((aPhase.endBucket - aPhase.startBucket) * aPhase.amount);
0855:                        // take the max endBucket for the rollup end time
0856:                        if (aPhase.endBucket > rollupEnd) {
0857:                            rollupEnd = aPhase.endBucket;
0858:                        }
0859:                        // take the min startBucket for the rollup start time
0860:                        if (aPhase.startBucket < rollupStart) {
0861:                            rollupStart = aPhase.startBucket;
0862:                        }
0863:                        AspectValue this Phase[] = new AspectValue[3];
0864:                        this Phase[0] = AspectValue.newAspectValue(
0865:                                AspectType.END_TIME, thePG
0866:                                        .convertBucketToTime(aPhase.endBucket));
0867:                        this Phase[1] = AspectValue.newAspectValue(
0868:                                AspectType.START_TIME,
0869:                                thePG.convertBucketToTime(aPhase.startBucket));
0870:                        this Phase[2] = getDemandRateAV(aPhase.amount, thePG
0871:                                .getBucketMillis());
0872:                        // add this phase to our phased results list
0873:                        phasedResults.add(this Phase);
0874:                    }
0875:                    avs[2] = getDemandRateAV(rollupQty, thePG
0876:                            .convertBucketToTime(rollupEnd)
0877:                            - thePG.convertBucketToTime(rollupStart));
0878:                }
0879:
0880:                AllocationResult estimatedResult = inventoryPlugin
0881:                        .getPlanningFactory().newPhasedAllocationResult(
0882:                                Constants.Confidence.SCHEDULED, success, avs,
0883:                                (new Vector(phasedResults)).elements());
0884:
0885:                compareResults(estimatedResult, task, inv, thePG);
0886:            }
0887:
0888:            /**
0889:             * Do not process tasks whose end times are beyond level 2
0890:             * @param task
0891:             * @return true if after level 2 horizon
0892:             */
0893:            protected boolean shouldSkipMakingResult(Task task) {
0894:                long endOfLevel2 = ((LevelOfDetailInventoryManager) inventoryPlugin)
0895:                        .getEndOfLevelTwo();
0896:                long endOfTask = (long) PluginHelper.getPreferenceBestValue(
0897:                        task, AspectType.END_TIME);
0898:                // Do not process tasks whose end times are beyond level 2
0899:                return (endOfTask > endOfLevel2);
0900:            }
0901:
0902:            public double taskQtyInBucket(Task task, int currentBucket,
0903:                    LogisticsInventoryPG thePG) {
0904:                if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0905:                    return getTaskUtils().getPreference(task,
0906:                            AspectType.QUANTITY);
0907:                } else {
0908:                    long start = (long) PluginHelper.getPreferenceBestValue(
0909:                            task, AspectType.START_TIME);
0910:                    long end = (long) PluginHelper.getPreferenceBestValue(task,
0911:                            AspectType.END_TIME);
0912:                    return thePG.getProjectionTaskDemand(task, currentBucket,
0913:                            start, end);
0914:                }
0915:            }
0916:
0917:            /** Create best allocations for Projections that are not being counted.
0918:             *  These are likely early projections that are not counted because
0919:             *  Supply tasks (actuals) are being counted in their place.
0920:             *  Allocate these with yes or best.
0921:             *  Note that projections that span the not counted and counted projection
0922:             *  windows are not allocated here.
0923:             *  @param inventory The Inventory we are processing
0924:             *  @param thePG This is the PG for the Inventory we are processing
0925:             **/
0926:            protected void allocateNotCountedProjections(Inventory inventory,
0927:                    LogisticsInventoryPG thePG) {
0928:                //      String myOrgName = inventoryPlugin.getMyOrganization().getItemIdentificationPG().getItemIdentification();
0929:                //String myItemId = thePG.getResource().getTypeIdentificationPG().getTypeIdentification();
0930:
0931:                HashMap customerHash = thePG.getCustomerHash();
0932:                Set keys = customerHash.keySet();
0933:                Iterator keysIt = keys.iterator();
0934:                while (keysIt.hasNext()) {
0935:                    Object org = keysIt.next();
0936:                    int countedBucket = thePG.convertTimeToBucket(
0937:                            ((Long) customerHash.get(org)).longValue(), false) + 1;
0938:                    int currentBucket = 0;
0939:                    // loop through the buckets in the inventory
0940:                    while (currentBucket < countedBucket) {
0941:                        Collection wdprojs = thePG
0942:                                .getProjectedDemandTasks(currentBucket);
0943:                        Iterator wdpIter = wdprojs.iterator();
0944:                        while (wdpIter.hasNext()) {
0945:                            Task withdrawProj = (Task) wdpIter.next();
0946:                            Object customerOrg = TaskUtils
0947:                                    .getCustomer(withdrawProj);
0948:                            if (customerOrg.equals(org)) {
0949:                                double endTimePref = getTaskUtils()
0950:                                        .getPreference(withdrawProj,
0951:                                                AspectType.END_TIME);
0952:                                //make sure there is an end time pref AND that the
0953:                                //bucket of the end time pref is not equal to or past the countedBucket
0954:                                //Since endTime is not inclusive of the bucket it falls in decrement by 1
0955:                                // countedBucket is the firstCountedProjection - if the projection spans both
0956:                                //the uncounted and counted windows - dont blindly allocate it here ... it should
0957:                                // be picked up by the counted projections allocation method.
0958:                                if ((endTimePref != Double.NaN)
0959:                                        && ((thePG.convertTimeToBucket(
0960:                                                (long) endTimePref, true) - 1) < countedBucket)) {
0961:                                    if (withdrawProj.getPlanElement() == null) {
0962:                                        createBestAllocation(withdrawProj,
0963:                                                inventory, thePG);
0964:                                    }
0965:                                    // if it already has a pe we could check it - but for now we won't
0966:                                }
0967:                            }
0968:                        }
0969:                        //bump the bucket
0970:                        currentBucket = currentBucket + 1;
0971:                    }
0972:                }
0973:            }
0974:
0975:            /** Create best allocations for Projections that are counted but in the past.
0976:             *  These may need to be re-allocated in the past if the optempo changes
0977:             *  and these tasks are still counted.
0978:             *  @param today_bucket The current day of the society
0979:             *  @param inventory The Inventory we are processing
0980:             *  @param thePG This is the PG for the Inventory we are processing
0981:             **/
0982:            protected void allocateCountedEarlyProjections(int today_bucket,
0983:                    Inventory inventory, LogisticsInventoryPG thePG) {
0984:                int currentBucket = 0;
0985:                // loop through the buckets in the inventory
0986:                while (currentBucket < today_bucket) {
0987:                    Collection wdprojs = thePG
0988:                            .getProjectedDemandTasks(currentBucket);
0989:                    Iterator wdpIter = wdprojs.iterator();
0990:                    while (wdpIter.hasNext()) {
0991:                        Task withdrawProj = (Task) wdpIter.next();
0992:                        double endTimePref = getTaskUtils().getPreference(
0993:                                withdrawProj, AspectType.END_TIME);
0994:                        //make sure there is an end time pref AND that the
0995:                        //bucket of the end time pref is not equal to or past the today_bucket
0996:                        //Since endTime is not inclusive of the bucket it falls in decrement by 1
0997:                        if ((endTimePref != Double.NaN)
0998:                                && ((thePG.convertTimeToBucket(
0999:                                        (long) endTimePref, true) - 1) < today_bucket)) {
1000:                            if (withdrawProj.getPlanElement() == null) {
1001:                                createBestAllocation(withdrawProj, inventory,
1002:                                        thePG);
1003:                            }
1004:                        }
1005:                    }
1006:                    currentBucket = currentBucket + 1;
1007:                }
1008:            }
1009:
1010:            /** Utility method to create an Allocation that matches the
1011:             *  best preferences for the withdraw task
1012:             *  @param withdraw The withdraw task we are allocating
1013:             *  @param inv The Inventory we are allocating against
1014:             *  @param thePG The PG of the Inventory we are allocating against
1015:             **/
1016:            private void createBestAllocation(Task withdraw, Inventory inv,
1017:                    LogisticsInventoryPG thePG) {
1018:                AllocationResult estimatedResult = null;
1019:                if (withdraw.getVerb().equals(Constants.Verb.WITHDRAW)) {
1020:                    estimatedResult = PluginHelper
1021:                            .createEstimatedAllocationResult(withdraw,
1022:                                    inventoryPlugin.getPlanningFactory(),
1023:                                    Constants.Confidence.SCHEDULED, true);
1024:                } else {
1025:                    long taskStartTime = getTaskUtils().getStartTime(withdraw);
1026:                    long taskEndTime = getTaskUtils().getEndTime(withdraw);
1027:                    PrepositionalPhrase pp_rate = withdraw
1028:                            .getPrepositionalPhrase(Constants.Preposition.DEMANDRATE);
1029:                    if (pp_rate != null) {
1030:                        Object indObj = pp_rate.getIndirectObject();
1031:                        if (indObj instanceof  Schedule) {
1032:                            Schedule sched = (Schedule) indObj;
1033:                            Collection rate_elems = sched
1034:                                    .getOverlappingScheduleElements(
1035:                                            taskStartTime, taskEndTime);
1036:                            int n = (rate_elems == null ? 0 : rate_elems.size());
1037:                            ArrayList phasedResults = new ArrayList(n);
1038:                            double rollupQty = 0;
1039:                            AspectValue avs[];
1040:
1041:                            avs = new AspectValue[3];
1042:
1043:                            // return a schedule of daily rates
1044:                            int rollupEnd = thePG.convertTimeToBucket(
1045:                                    taskEndTime, true);
1046:                            int rollupStart = thePG.convertTimeToBucket(
1047:                                    taskStartTime, false);
1048:
1049:                            avs[0] = AspectValue.newAspectValue(
1050:                                    AspectType.END_TIME, taskEndTime);
1051:                            avs[1] = AspectValue.newAspectValue(
1052:                                    AspectType.START_TIME, taskStartTime);
1053:
1054:                            for (Iterator iter = rate_elems.iterator(); iter
1055:                                    .hasNext();) {
1056:                                ObjectScheduleElement ose = (ObjectScheduleElement) iter
1057:                                        .next();
1058:                                int rateStartBucket = thePG
1059:                                        .convertTimeToBucket(
1060:                                                ose.getStartTime(), false);
1061:                                int rateEndBucket = thePG.convertTimeToBucket(
1062:                                        ose.getEndTime(), true);
1063:                                Rate currentRate = (Rate) ose.getObject();
1064:
1065:                                rollupQty = rollupQty
1066:                                        + this 
1067:                                                .getQuantityForDuration(
1068:                                                        currentRate,
1069:                                                        (rateEndBucket - rateStartBucket));
1070:                                // take the max endBucket for the rollup end time
1071:                                if (rateEndBucket > rollupEnd) {
1072:                                    rollupEnd = rateEndBucket;
1073:                                }
1074:                                // take the min startBucket for the rollup start time
1075:                                if (rateStartBucket < rollupStart) {
1076:                                    rollupStart = rateStartBucket;
1077:                                }
1078:                                AspectValue this Phase[] = new AspectValue[3];
1079:                                this Phase[0] = AspectValue
1080:                                        .newAspectValue(
1081:                                                AspectType.END_TIME,
1082:                                                thePG
1083:                                                        .convertBucketToTime(rateEndBucket));
1084:                                this Phase[1] = AspectValue
1085:                                        .newAspectValue(
1086:                                                AspectType.START_TIME,
1087:                                                thePG
1088:                                                        .convertBucketToTime(rateStartBucket));
1089:                                this Phase[2] = getDemandRateAV(
1090:                                        getQuantityForDuration(currentRate,
1091:                                                thePG.getBucketMillis()), thePG
1092:                                                .getBucketMillis());
1093:                                // add this phase to our phased results list
1094:                                phasedResults.add(this Phase);
1095:                            }
1096:                            avs[2] = getDemandRateAV(rollupQty, thePG
1097:                                    .convertBucketToTime(rollupEnd)
1098:                                    - thePG.convertBucketToTime(rollupStart));
1099:
1100:                            estimatedResult = inventoryPlugin
1101:                                    .getPlanningFactory()
1102:                                    .newPhasedAllocationResult(
1103:                                            Constants.Confidence.SCHEDULED,
1104:                                            true,
1105:                                            avs,
1106:                                            (new Vector(phasedResults))
1107:                                                    .elements());
1108:
1109:                        }
1110:                    } else {
1111:                        estimatedResult = PluginHelper
1112:                                .createEstimatedAllocationResult(withdraw,
1113:                                        inventoryPlugin.getPlanningFactory(),
1114:                                        Constants.Confidence.SCHEDULED, true);
1115:                    }
1116:                }
1117:                compareResults(estimatedResult, withdraw, inv, thePG);
1118:            }
1119:
1120:            /** Utility method to create a late Allocation
1121:             *  @param withdraw The withdraw task to allocate
1122:             *  @param end The end time of the window that it will be filled
1123:             *  @param inv  The Inventory we are allocating against
1124:             *  @param thePG  The PG for the Inventory we are allocating against
1125:             *  Note that we are using a start and end preference because the allocation
1126:             *  is based on a bucket that may span more than one day. So we want to say it
1127:             *  will be filled sometime within the bucket start and end time.
1128:             **/
1129:            private void createLateAllocation(Task withdraw, long end,
1130:                    Inventory inv, LogisticsInventoryPG thePG) {
1131:                AspectValue avs[] = new AspectValue[2];
1132:                avs[0] = AspectValue.newAspectValue(AspectType.END_TIME, end);
1133:                avs[1] = AspectValue.newAspectValue(AspectType.QUANTITY,
1134:                        getTaskUtils().getPreference(withdraw,
1135:                                AspectType.QUANTITY));
1136:                AllocationResult estimatedResult = inventoryPlugin
1137:                        .getPlanningFactory().newAllocationResult(
1138:                                Constants.Confidence.SCHEDULED, true, avs);
1139:                compareResults(estimatedResult, withdraw, inv, thePG);
1140:            }
1141:
1142:            private void createFailedAllocation(Task task, Inventory inventory,
1143:                    LogisticsInventoryPG thePG) {
1144:                //check if the task already has a failed allocation on it - don't even bother to compare
1145:                //failed should equal failed at this point.
1146:                PlanElement prevPE = task.getPlanElement();
1147:                if (prevPE != null) {
1148:                    if (!prevPE.getEstimatedResult().isSuccess()) {
1149:                        return;
1150:                    }
1151:                }
1152:                if (logger.isDebugEnabled()) {
1153:                    logger.debug("Failing task: "
1154:                            + getTaskUtils().taskDesc(task) + " at agent: "
1155:                            + inventoryPlugin.getClusterId().toString()
1156:                            + " Inventory initial level is: "
1157:                            + thePG.getLevel(0));
1158:                }
1159:                // make the failed time the day after the end of the oplan
1160:                long failed_time = inventoryPlugin.getOPlanEndTime()
1161:                        + TimeUtils.MSEC_PER_DAY;
1162:                AspectValue avs[];
1163:
1164:                if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
1165:                    avs = new AspectValue[2];
1166:                    avs[0] = AspectValue.newAspectValue(AspectType.END_TIME,
1167:                            failed_time);
1168:                    avs[1] = AspectValue.newAspectValue(AspectType.QUANTITY,
1169:                            PluginHelper.getPreferenceBestValue(task,
1170:                                    AspectType.QUANTITY));
1171:                } else {
1172:                    // projection... set start and end to failed_time and set the rate to the pref over 1 bucket
1173:                    avs = new AspectValue[3];
1174:                    long failed_start = PluginHelper.getStartTime(task);
1175:                    AspectValue failedAV;
1176:                    Duration dur = new Duration(failed_time - failed_start,
1177:                            Duration.MILLISECONDS);
1178:                    if (getTaskUtils().isFlowRate(task)) {
1179:                        Volume vol = new Volume(0.0, Volume.GALLONS);
1180:                        failedAV = AspectValue.newAspectValue(
1181:                                AlpineAspectType.DEMANDRATE, new FlowRate(vol,
1182:                                        dur));
1183:                    } else {
1184:                        Count cnt = new Count(0.0, Count.EACHES);
1185:                        failedAV = AspectValue.newAspectValue(
1186:                                AlpineAspectType.DEMANDRATE, new CountRate(cnt,
1187:                                        dur));
1188:                    }
1189:
1190:                    avs[0] = AspectValue.newAspectValue(AspectType.START_TIME,
1191:                            failed_start);
1192:                    avs[1] = AspectValue.newAspectValue(AspectType.END_TIME,
1193:                            failed_time);
1194:                    avs[2] = failedAV;
1195:                }
1196:                AllocationResult failed = inventoryPlugin.getPlanningFactory()
1197:                        .newAllocationResult(Constants.Confidence.SCHEDULED,
1198:                                false, avs);
1199:                //PlanElement prevPE = task.getPlanElement();
1200:                if (prevPE == null) {
1201:                    Allocation alloc = inventoryPlugin.getPlanningFactory()
1202:                            .createAllocation(task.getPlan(), task, inventory,
1203:                                    failed, myRole);
1204:                    inventoryPlugin.publishAdd(alloc);
1205:                } else {
1206:                    AllocationResult previous = prevPE.getEstimatedResult();
1207:                    if (!previous.isEqual(failed)) {
1208:                        prevPE.setEstimatedResult(failed);
1209:                        inventoryPlugin.publishChange(prevPE);
1210:                    }
1211:                }
1212:            }
1213:
1214:            /** Method which checks a previously created planelement for the withdraw task
1215:             *  to make sure its consistent with the result we just calculated.
1216:             *  This is called if we want to give a best result - so if the previous
1217:             *  result was not best we will change it.
1218:             *  @param withdraw The Withdraw Task we are allocating against the Inventory
1219:             *  @param pe The PlanElement associated with the Task.
1220:             **/
1221:            private void checkPlanElement(Task withdraw, PlanElement pe) {
1222:                //if this task already has a pe - make sure the results are consistent
1223:                // with best.
1224:                //PlanElement pe = withdraw.getPlanElement();
1225:                AllocationResult ar = pe.getEstimatedResult();
1226:                AllocationResult estimatedResult = PluginHelper
1227:                        .createEstimatedAllocationResult(withdraw,
1228:                                inventoryPlugin.getPlanningFactory(),
1229:                                Constants.Confidence.SCHEDULED, true);
1230:                if (ar == null || !ar.isEqual(estimatedResult)) {
1231:                    pe.setEstimatedResult(estimatedResult);
1232:                    inventoryPlugin.publishChange(pe);
1233:                    //       updatePG(withdraw, thePG);
1234:                }
1235:            }
1236:
1237:            public void compareResults(AllocationResult estimatedResult,
1238:                    Task withdraw, Inventory inv, LogisticsInventoryPG thePG) {
1239:                PlanElement prevPE = withdraw.getPlanElement();
1240:                if (prevPE == null) {
1241:                    Allocation alloc = inventoryPlugin.getPlanningFactory()
1242:                            .createAllocation(withdraw.getPlan(), withdraw,
1243:                                    inv, estimatedResult, myRole);
1244:                    inventoryPlugin.publishAdd(alloc);
1245:                } else {
1246:                    AllocationResult previous = prevPE.getEstimatedResult();
1247:                    if (!previous.isEqual(estimatedResult)) {
1248:                        if (logger.isDebugEnabled()) {
1249:                            logger
1250:                                    .debug("Inside compareResults... results are !.equals..."
1251:                                            + "\n previous result: "
1252:                                            + previous
1253:                                            + " estimated result: "
1254:                                            + estimatedResult);
1255:                        }
1256:                        prevPE.setEstimatedResult(estimatedResult);
1257:                        inventoryPlugin.publishChange(prevPE);
1258:                    } else {
1259:                        // otherwise leave it alone and don't bother to update the PG
1260:                        return;
1261:                    }
1262:                }
1263:
1264:                //     updatePG(withdraw, thePG);
1265:            }
1266:
1267:            public void updatePG(Task withdraw, LogisticsInventoryPG thePG) {
1268:                if (withdraw.getVerb().equals(Constants.Verb.WITHDRAW)) {
1269:                    thePG.updateWithdrawRequisition(withdraw);
1270:                } else {
1271:                    thePG.updateWithdrawProjection(withdraw);
1272:                }
1273:            }
1274:
1275:            public AspectValue getDemandRateAV(double amount, long millis) {
1276:                AspectValue demandRateAV = null;
1277:                Duration dur = new Duration(millis, Duration.MILLISECONDS);
1278:                if (inventoryPlugin.getSupplyType().equals("BulkPOL")) {
1279:                    Volume vol = new Volume(amount, Volume.GALLONS);
1280:                    demandRateAV = AspectValue
1281:                            .newAspectValue(AlpineAspectType.DEMANDRATE,
1282:                                    new FlowRate(vol, dur));
1283:
1284:                } else {
1285:                    Count cnt = new Count(amount, Count.EACHES);
1286:                    demandRateAV = AspectValue.newAspectValue(
1287:                            AlpineAspectType.DEMANDRATE,
1288:                            new CountRate(cnt, dur));
1289:                }
1290:                return demandRateAV;
1291:            }
1292:
1293:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.