/*
 * 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.util.*;
import java.lang.*;
import org.apache.ofbiz.base.util.*;
import org.apache.ofbiz.entity.*;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilDateTime;
import org.apache.ofbiz.entity.util.*;
import org.apache.ofbiz.entity.condition.*;
import org.apache.ofbiz.webapp.website.WebSiteWorker;
import java.sql.Timestamp;

uiLabelMap = UtilProperties.getResourceBundleMap("scrumUiLabels", locale);
partyId = parameters.partyId;
if (!partyId) {
    partyId = parameters.userLogin.partyId;
}

// show the requested timesheet, otherwise the current , if not exist create
timesheet = null;
timesheetId = parameters.timesheetId;
if (timesheetId) {
    timesheet = from("Timesheet").where("timesheetId", timesheetId).queryOne();
    partyId = timesheet.partyId; // use the party from this timesheet
} else {
    // make sure because of timezone changes, not a duplicate timesheet is created
    midweek = UtilDateTime.addDaysToTimestamp(UtilDateTime.getWeekStart(UtilDateTime.nowTimestamp()),3);
    entryExprs = EntityCondition.makeCondition([
        EntityCondition.makeCondition("fromDate", EntityComparisonOperator.LESS_THAN, midweek),
        EntityCondition.makeCondition("thruDate", EntityComparisonOperator.GREATER_THAN, midweek),
        EntityCondition.makeCondition("partyId", EntityComparisonOperator.EQUALS, partyId)
        ], EntityOperator.AND);
    entryIterator = from("Timesheet").where(entryExprs).queryIterator();
    timesheet = entryIterator.next();
    entryIterator.close();
    if (timesheet == null) {
        result = runService('createProjectTimesheet', ["userLogin" : parameters.userLogin, "partyId" : partyId]);
        if (result && result.timesheetId) {
            timesheet = from("Timesheet").where("timesheetId", result.timesheetId).queryOne();
        }
    }
}
if (!timesheet) return;
context.timesheet = timesheet;
context.weekNumber = UtilDateTime.weekNumber(timesheet.fromDate);

// get the user names
context.partyNameView = from("PartyNameView").where("partyId", partyId).queryOne();
// get the default rate for this person
rateTypes = from("PartyRate").where("partyId", partyId, "defaultRate", "Y").filterByDate().queryList();
if (rateTypes) {
    context.defaultRateTypeId = rateTypes[0].rateTypeId;
}

entries = [];
entry = ["timesheetId" : timesheet.timesheetId];
leaveEntry = ["timesheetId" : timesheet.timesheetId];
taskTotal = 0.00;
planTotal = 0.00;
leaveTaskTotal = 0.00;
leavePlanTotal = 0.00;
day0Total = 0.00; day1Total=0.00; day2Total=0.00; day3Total=0.00; day4Total=0.00; day5Total=0.00; day6Total=0.00;
pDay0Total = 0.00; pDay1Total=0.00; pDay2Total=0.00; pDay3Total=0.00; pDay4Total=0.00; pDay5Total=0.00; pDay6Total=0.00;
pHours = 0.00;
timeEntry = null;
lastTimeEntry = null;
emplLeaveEntry = null;
lastEmplLeaveEntry = null;

// retrieve work effort data when the workeffortId has changed.
void retrieveWorkEffortData() {
        // get the planned number of hours
        entryWorkEffort = lastTimeEntry.getRelatedOne("WorkEffort", false);
        if (entryWorkEffort) {
            plannedHours = entryWorkEffort.getRelated("WorkEffortSkillStandard", null, null, false);
            pHours = 0.00;
            plannedHours.each { plannedHour ->
                if (plannedHour.estimatedDuration) {
                    pHours += plannedHour.estimatedDuration;
                }
            }
            estimatedHour =  0.00;
            
            estimatedMilliSeconds = entryWorkEffort.estimatedMilliSeconds
            if (estimatedMilliSeconds > 0) 
                estimatedHour = estimatedMilliSeconds/3600000;
            entry.plannedHours = estimatedHour;
            //entry.plannedHours = pHours;
            planHours = 0.0;
            planHours = lastTimeEntry.planHours;
            lastTimeEntryOfTasks = from("TimeEntry").where("workEffortId", lastTimeEntry.workEffortId, "partyId", partyId).orderBy("-fromDate").queryList();
            if (lastTimeEntryOfTasks.size() != 0) lastTimeEntry = lastTimeEntryOfTasks[0];
            if (planHours < 1) {
                planHours = estimatedHour;
            }
            entry.planHours = lastTimeEntry.planHours;
            actualHours = entryWorkEffort.getRelated("TimeEntry", null, null, false);
            aHours = 0.00;
            actualHours.each { actualHour ->
                if (actualHour.hours) {
                    aHours += actualHour.hours;
                }
            }
            entry.actualHours = aHours;
            // get party assignment data to be able to set the task to complete
            workEffortPartyAssigns = EntityUtil.filterByDate(entryWorkEffort.getRelated("WorkEffortPartyAssignment", ["partyId" : partyId], null, false));
            if (workEffortPartyAssigns) {
                workEffortPartyAssign = workEffortPartyAssigns[0];
                entry.fromDate = workEffortPartyAssign.getTimestamp("fromDate");
                entry.roleTypeId = workEffortPartyAssign.roleTypeId;
                if ("SCAS_COMPLETED".equals(workEffortPartyAssign.statusId)) {
                    entry.checkComplete = "Y";
                    
                }
            } else {
                if ("STS_COMPLETED".equals(entryWorkEffort.currentStatusId)) {
                    entry.checkComplete = "Y";
                }
            }

            // get project/phase information
            entry.workEffortId = entryWorkEffort.workEffortId;
            entry.workEffortName = entryWorkEffort.workEffortName;
            result = runService('getProjectInfoFromTask', ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
                entry.phaseId = result.phaseId;
                entry.phaseName = result.phaseName;
                entry.projectId = result.projectId;
                entry.projectName = result.projectName;
                entry.taskWbsId = result.taskWbsId;

        }
        entry.acualTotal = taskTotal;
        entry.planTotal = planTotal;
        //Drop Down Lists
        if (entry.checkComplete != "Y") {
            if (aHours > 0.00)
                entries.add(entry);
        } else {
                entries.add(entry);
        }
        // start new entry
        taskTotal = 0.00;
        planTotal = 0.00;
        entry = ["timesheetId" : timesheet.timesheetId];
}

timeEntries = timesheet.getRelated("TimeEntry", null, ["workEffortId", "rateTypeId", "fromDate"], false);
te = timeEntries.iterator();
while (te.hasNext()) {
    // only fill lastTimeEntry when not the first time
    if (timeEntry!=void) {
        lastTimeEntry = timeEntry;
    }
    timeEntry = te.next();

    if (lastTimeEntry &&
            (!lastTimeEntry.workEffortId.equals(timeEntry.workEffortId) ||
            !lastTimeEntry.rateTypeId.equals(timeEntry.rateTypeId))) {
            retrieveWorkEffortData();
        }
    if (timeEntry.hours) {
        dayNumber = "d" + (timeEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
        hours = timeEntry.hours.doubleValue();
        entry.put(String.valueOf(dayNumber), hours);
        if (dayNumber.equals("d0")) day0Total += hours;
        if (dayNumber.equals("d1")) day1Total += hours;
        if (dayNumber.equals("d2")) day2Total += hours;
        if (dayNumber.equals("d3")) day3Total += hours;
        if (dayNumber.equals("d4")) day4Total += hours;
        if (dayNumber.equals("d5")) day5Total += hours;
        if (dayNumber.equals("d6")) day6Total += hours;
        taskTotal += hours;
    }
    if (timeEntry.planHours) {
        dayNumber = "pd" + (timeEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
        planHours = timeEntry.planHours.doubleValue();
        entry.put(String.valueOf(dayNumber), planHours);
        if (dayNumber.equals("pd0")) pDay0Total += planHours;
        if (dayNumber.equals("pd1")) pDay1Total += planHours;
        if (dayNumber.equals("pd2")) pDay2Total += planHours;
        if (dayNumber.equals("pd3")) pDay3Total += planHours;
        if (dayNumber.equals("pd4")) pDay4Total += planHours;
        if (dayNumber.equals("pd5")) pDay5Total += planHours;
        if (dayNumber.equals("pd6")) pDay6Total += planHours;
        planTotal += planHours;

    }
    entry.rateTypeId = timeEntry.rateTypeId;
}
//retrieve Empl Leave data.
void retrieveEmplLeaveData() {
        if (lastEmplLeaveEntry) {
            //service get Hours
            result = runService('getPartyLeaveHoursForDate', 
                ["userLogin": parameters.userLogin, "partyId": lastEmplLeaveEntry.partyId, "leaveTypeId": lastEmplLeaveEntry.leaveTypeId, "fromDate": lastEmplLeaveEntry.fromDate]);
            if (result.hours) {
                leaveEntry.plannedHours = result.hours;
                leaveEntry.planHours =  result.hours;
            }
            if (lastEmplLeaveEntry.leaveStatus == "LEAVE_APPROVED") {
                leaveEntry.checkComplete = "Y";
            }
            leaveEntry.partyId = lastEmplLeaveEntry.partyId;
            leaveEntry.leaveTypeId = lastEmplLeaveEntry.leaveTypeId;
            leaveEntry.leavefromDate = lastEmplLeaveEntry.fromDate;
            leaveEntry.leavethruDate = lastEmplLeaveEntry.thruDate;
            leaveEntry.description = lastEmplLeaveEntry.description;
        }
        leaveEntry.acualTotal = leaveTaskTotal;
        leaveEntry.planHours = leavePlanTotal;
        leaveEntry.actualHours = leaveTaskTotal;
        //Drop Down Lists
        entries.add(leaveEntry);
        // start new leaveEntry
        leaveTaskTotal = 0.00;
        leavePlanTotal = 0.00;
        leaveEntry = ["timesheetId" : timesheet.timesheetId];
   }

// define condition
leaveExprs = [];
leaveExprs.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheet.fromDate));
leaveExprs.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheet.thruDate));
leaveExprs.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
emplLeave = from("EmplLeave").where(leaveExprs).cursorScrollInsensitive().distinct().queryIterator();

while ((emplLeaveMap = emplLeave.next())) {
    if (emplLeaveEntry!=void) {
        lastEmplLeaveEntry = emplLeaveEntry;
    }
    
    emplLeaveEntry = emplLeaveMap;
    
    if (lastEmplLeaveEntry && (
            !lastEmplLeaveEntry.leaveTypeId.equals(emplLeaveEntry.leaveTypeId) ||
            !lastEmplLeaveEntry.partyId.equals(emplLeaveEntry.partyId))) {
            retrieveEmplLeaveData();
        }
    resultHours = runService('getPartyLeaveHoursForDate', 
        ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
    
    if (resultHours.hours) {
        leaveDayNumber = "d" + (emplLeaveEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
        resultHours = runService('getPartyLeaveHoursForDate', 
            ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
        leaveHours = resultHours.hours.doubleValue();
        leaveEntry.put(String.valueOf(leaveDayNumber), leaveHours);
        if (leaveDayNumber.equals("d0")) day0Total += leaveHours;
        if (leaveDayNumber.equals("d1")) day1Total += leaveHours;
        if (leaveDayNumber.equals("d2")) day2Total += leaveHours;
        if (leaveDayNumber.equals("d3")) day3Total += leaveHours;
        if (leaveDayNumber.equals("d4")) day4Total += leaveHours;
        if (leaveDayNumber.equals("d5")) day5Total += leaveHours;
        if (leaveDayNumber.equals("d6")) day6Total += leaveHours;
        leaveTaskTotal += leaveHours;
    }
    if (resultHours.hours) {
        leavePlanDay = "pd" + (emplLeaveEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
        resultPlanHours = runService('getPartyLeaveHoursForDate', 
            ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
        leavePlanHours = resultPlanHours.hours.doubleValue();
        leaveEntry.put(String.valueOf(leavePlanDay), leavePlanHours);
        if (leavePlanDay.equals("pd0")) pDay0Total += leavePlanHours;
        if (leavePlanDay.equals("pd1")) pDay1Total += leavePlanHours;
        if (leavePlanDay.equals("pd2")) pDay2Total += leavePlanHours;
        if (leavePlanDay.equals("pd3")) pDay3Total += leavePlanHours;
        if (leavePlanDay.equals("pd4")) pDay4Total += leavePlanHours;
        if (leavePlanDay.equals("pd5")) pDay5Total += leavePlanHours;
        if (leavePlanDay.equals("pd6")) pDay6Total += leavePlanHours;
        leavePlanTotal += leavePlanHours;
    }
    leaveEntry.rateTypeId = "STANDARD";
}
emplLeave.close();

if (timeEntry) {
    lastTimeEntry = timeEntry;
    retrieveWorkEffortData();
    }
if (emplLeaveEntry) {
    lastEmplLeaveEntry = emplLeaveEntry;
    retrieveEmplLeaveData();
    }

// add empty lines if timesheet not completed
if (!timesheet.statusId.equals("TIMESHEET_COMPLETED")) {
    for (c=0; c < 3; c++) { // add empty lines
        entries.add(["timesheetId" : timesheet.timesheetId]);
    }
}

// add the totals line if at least one entry
if (timeEntry || emplLeaveEntry) {
    entry = ["timesheetId" : timesheet.timesheetId];
    entry.d0 = day0Total;
    entry.d1 = day1Total;
    entry.d2 = day2Total;
    entry.d3 = day3Total;
    entry.d4 = day4Total;
    entry.d5 = day5Total;
    entry.d6 = day6Total;
    entry.pd0 = pDay0Total;
    entry.pd1 = pDay1Total;
    entry.pd2 = pDay2Total;
    entry.pd3 = pDay3Total;
    entry.pd4 = pDay4Total;
    entry.pd5 = pDay5Total;
    entry.pd6 = pDay6Total;
    entry.phaseName = uiLabelMap.ScrumTotals;
    entry.workEffortId = "Totals";
    entry.total = day0Total + day1Total + day2Total + day3Total + day4Total + day5Total + day6Total;
    entries.add(entry);
}
context.timeEntries = entries;
// get all timesheets of this user, including the planned hours
timesheetsDb = from("Timesheet").where("partyId", partyId).orderBy("fromDate DESC").queryList();
timesheets = new LinkedList();
timesheetsDb.each { timesheetDb ->
    //get hours from EmplLeave;
    findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
    leaveExprsList = [];
    leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheetDb.fromDate));
    leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheetDb.thruDate));
    leaveExprsList.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
    emplLeaveList = from("EmplLeave").where(leaveExprsList).cursorScrollInsensitive().distinct().queryIterator();
    leaveHours = 0.00;
    
    while ((emplLeaveMap = emplLeaveList.next())) {
        emplLeaveEntry = emplLeaveMap;
        resultHour = runService('getPartyLeaveHoursForDate', 
            ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
        if (resultHour) {
            leaveActualHours = resultHour.hours.doubleValue();
            leaveHours += leaveActualHours;
        }
    }
    //get hours from TimeEntry;
    timesheet = [:];
    timesheet.putAll(timesheetDb);
    entries = timesheetDb.getRelated("TimeEntry", null, null, false);
    hours = 0.00;
    entries.each { timeEntry ->
        if (timeEntry.hours) {
            hours += timeEntry.hours.doubleValue();
        }
    }
    timesheet.weekNumber = UtilDateTime.weekNumber(timesheetDb.fromDate);
    timesheet.hours = hours + leaveHours;
    timesheets.add(timesheet);
    emplLeaveList.close();
}
context.timesheets = timesheets;

// get existing task that no assign
taskList=[];
projectSprintBacklogAndTaskList = [];
backlogIndexList = [];
projectAndTaskList = from("ProjectSprintBacklogAndTask").where("sprintTypeId" : "SCRUM_SPRINT","taskCurrentStatusId" : "STS_CREATED").orderBy("projectName ASC","taskActualStartDate DESC").queryList();
projectAndTaskList.each { projectAndTaskMap ->
userLoginId = userLogin.partyId;
    sprintId = projectAndTaskMap.sprintId;
    workEffortList = from("WorkEffortAndProduct").where("workEffortId", projectAndTaskMap.projectId).queryList();
    backlogIndexList.add(workEffortList[0].productId);
	
    partyAssignmentSprintList = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", userLoginId).queryList();
    partyAssignmentSprintMap = partyAssignmentSprintList[0];
    // if this userLoginId is a member of sprint
    if (partyAssignmentSprintMap) {
        workEffortId = projectAndTaskMap.taskId;
        partyAssignmentTaskList = from("WorkEffortPartyAssignment").where("workEffortId", workEffortId).queryList();
        partyAssignmentTaskMap = partyAssignmentTaskList[0];
        // if the task do not assigned
        if (partyAssignmentTaskMap) {
            custRequestTypeId = projectAndTaskMap.custRequestTypeId;
			backlogStatusId = projectAndTaskMap.backlogStatusId;
			if (custRequestTypeId.equals("RF_SCRUM_MEETINGS") && backlogStatusId.equals("CRQ_REVIEWED")) {
				projectSprintBacklogAndTaskList.add(projectAndTaskMap);
			   }
            } else {
					projectSprintBacklogAndTaskList.add(0,projectAndTaskMap);
             }
        }
    }

// for unplanned taks.
unplanList=[];
if (backlogIndexList) {
    backlogIndex = new HashSet(backlogIndexList);
    custRequestList = from("CustRequest").where("custRequestTypeId", "RF_UNPLAN_BACKLOG","statusId", "CRQ_REVIEWED").orderBy("custRequestDate DESC").queryList();
    if (custRequestList) {
        custRequestList.each { custRequestMap ->
            custRequestItemList = custRequestMap.getRelated("CustRequestItem", null, null, false);
			custRequestItem =  
			productOut = custRequestItemList[0].productId;
			product = from("Product").where("productId", productOut).queryOne();
            backlogIndex.each { backlogProduct ->
                productId = backlogProduct
                if (productId.equals(productOut)) {
                    custRequestWorkEffortList = from("CustRequestWorkEffort").where("custRequestId", custRequestItemList[0].custRequestId).queryList();
                    custRequestWorkEffortList.each { custRequestWorkEffortMap ->
                        partyAssignmentTaskList = from("WorkEffortPartyAssignment").where("workEffortId", custRequestWorkEffortMap.workEffortId).queryList();
                        partyAssignmentTaskMap = partyAssignmentTaskList[0];
                        // if the task do not assigned
                        if (!partyAssignmentTaskMap) {
                            result = [:];
                            workEffortMap = from("WorkEffort").where("workEffortId", custRequestWorkEffortMap.workEffortId).queryOne();
                            result.description = custRequestMap.description;
                            result.productName = product.internalName;
                            result.taskId = workEffortMap.workEffortId;
                            result.taskName = workEffortMap.workEffortName;
							result.custRequestTypeId = custRequestMap.custRequestTypeId;
							result.taskTypeId = workEffortMap.workEffortTypeId;
                            unplanList.add(result);
                        }
                    }
                }
            }
        }
    }
}
projectSprintBacklogAndTaskList = UtilMisc.sortMaps(projectSprintBacklogAndTaskList, ["projectName","sprintName","-taskTypeId","custRequestId"]);
projectSprintBacklogAndTaskList.each { projectSprintBacklogAndTaskMap ->
	blTypeId = projectSprintBacklogAndTaskMap.custRequestTypeId;
	if (blTypeId == "RF_SCRUM_MEETINGS"){
		taskList.add(projectSprintBacklogAndTaskMap);
	}
}
projectSprintBacklogAndTaskList = UtilMisc.sortMaps(projectSprintBacklogAndTaskList, ["-projectName","sprintName","-taskTypeId","custRequestId"]);
projectSprintBacklogAndTaskList.each { projectSprintBacklogAndTaskMap ->
	blTypeId = projectSprintBacklogAndTaskMap.custRequestTypeId;
	if (blTypeId == "RF_PROD_BACKLOG"){
		taskList.add(0,projectSprintBacklogAndTaskMap);
	}
}
unplanList = UtilMisc.sortMaps(unplanList,["-productName","-taskTypeId","custRequestId"]);
unplanList.each { unplanMap->
		taskList.add(0,unplanMap);
}
context.taskList = taskList;

// notification context
webSiteId = WebSiteWorker.getWebSiteId(request);
context.webSiteId = webSiteId;
