/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import java.sql.*;
import java.sql.Timestamp;
import java.util.Calendar;
import net.fortuna.ical4j.model.DateTime;
import org.ofbiz.base.util.*;
import org.ofbiz.entity.condition.*;
import sun.util.calendar.LocalGregorianCalendar.Date;

def module = "AddProductBacklogItem.groovy";

// find cust request and items
def performFindInMap = [:];
performFindInMap.entityName = "CustRequestAndCustRequestItem";
def inputFields = [:];

if(parameters.statusId == null){
    parameters.statusId = "";
}else if("Any".equals(parameters.statusId)){
    parameters.statusId = "";
}
inputFields.putAll(parameters);
inputFields.custRequestTypeId = "RF_PROD_BACKLOG";
performFindInMap.inputFields = inputFields;
performFindInMap.orderBy = "custSequenceNum";
def performFindResults = dispatcher.runSync("performFind", performFindInMap);
def custRequestAndItems = performFindResults.listIt.getCompleteList();
performFindResults.listIt.close();

// prepare cust request item list [cust request and item Map]
def countSequence = 1;
def custRequestAndCustRequestItems = [];
custRequestAndItems.each() { custRequestAndItem ->
    def tempCustRequestAndItem = [:];
    tempCustRequestAndItem.putAll(custRequestAndItem);
    tempCustRequestAndItem.custSequenceNum = countSequence;
    tempCustRequestAndItem.realSequenceNum = custRequestAndItem.custSequenceNum;
    // if custRequest has task then get Actual Hours
    custWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : custRequestAndItem.custRequestId], null, false);
    if (custWorkEffortList) {
        actualHours = 0.00;
        custWorkEffortList.each() { custWorkEffortMap ->
            result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
            actualHours += result.actualHours;
        }
        if(actualHours) {
            tempCustRequestAndItem.actualHours = actualHours;
        } else {
            tempCustRequestAndItem.actualHours = null;
        }
    } else {
        tempCustRequestAndItem.actualHours = null;
    }
    custRequestAndCustRequestItems.add(tempCustRequestAndItem);
    countSequence ++;
}

if ("N".equals(parameters.sequence)) { // re-order category list item
    custRequestAndCustRequestItems = UtilMisc.sortMaps(custRequestAndCustRequestItems, ["parentCustRequestId"]);
}
//set status back for display in Find screen
if("".equals(parameters.statusId)){
    parameters.statusId = "Any";
}
context.custRequestAndCustRequestItems = custRequestAndCustRequestItems;

// unplanned backlog item list

productId = parameters.productId;

conditionList = [];
orConditionList = [];
mainConditionList = [];

conditionList.add(EntityCondition.makeCondition("custRequestTypeId", EntityOperator.EQUALS, "RF_UNPLAN_BACKLOG"));
conditionList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, parameters.productId));

orConditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CRQ_ACCEPTED"));
orConditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CRQ_REOPENED"));

orConditions = EntityCondition.makeCondition(orConditionList, EntityOperator.OR);
conditions = EntityCondition.makeCondition(conditionList, EntityOperator.AND);

mainConditionList.add(orConditions);
mainConditionList.add(conditions);
mainConditions = EntityCondition.makeCondition(mainConditionList, EntityOperator.AND);

unplannedList = delegator.findList("CustRequestAndCustRequestItem", mainConditions, ["custRequestId", "custSequenceNum", "statusId", "description", "custEstimatedMilliSeconds", "custRequestName", "parentCustRequestId"] as Set, ["custSequenceNum"], null, false);

def countSequenceUnplanned = 1;
def unplanBacklogItems = [];
unplannedList.each() { unplannedItem ->
    def tempUnplanned = [:];
    tempUnplanned.putAll(unplannedItem);
    tempUnplanned.custSequenceNum = countSequenceUnplanned;
    tempUnplanned.realSequenceNum = unplannedItem.custSequenceNum;
    // if custRequest has task then get Actual Hours
    unplanCustWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : unplannedItem.custRequestId], null, false);
    if (unplanCustWorkEffortList) {
        actualHours = 0.00;
        unplanCustWorkEffortList.each() { custWorkEffortMap ->
            result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
            actualHours += result.actualHours;
        }
        if(actualHours) {
            tempUnplanned.actualHours = actualHours;
        } else {
            tempUnplanned.actualHours = null;
        }
    } else {
        tempUnplanned.actualHours = null;
    }
    unplanBacklogItems.add(tempUnplanned);
    countSequenceUnplanned ++;
}
if ("N".equals(parameters.UnplannedSequence)) { // re-order category list item
    unplanBacklogItems = UtilMisc.sortMaps(unplanBacklogItems, ["parentCustRequestId"]);
}
context.unplanBacklogItems = unplanBacklogItems;
