/*
 * 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.awt.Dimension
import org.ofbiz.entity.util.*
import org.ofbiz.manufacturing.jobshopmgt.ProductionRun
import org.ofbiz.manufacturing.jobshopmgt.ProductionRunHelper

if (security.hasEntityPermission("MANUFACTURING", "_VIEW", session)) {
    context.hasPermission = Boolean.TRUE;
} else {
    context.hasPermission = Boolean.FALSE;
}

// -----------------------------
// Report's parameters
//groupByFeatureTypeIdParameter = "COLOR";
selectWorkEffortNameParameter = "O-PREL_A"; // sezionatura
selectPrimaryCategoryIdParameter = "CABINETS"; // struttura
// -----------------------------

shipmentId = request.getParameter("shipmentId");
context.shipmentId = shipmentId;

shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
context.shipment = shipment;

// dimensionsByFeatureMap [key=feature; value=productsByShapeMap]
// productsByShapeMap [key=dimension; value=quantityByProductsMap]
// quantityByProductsMap [key=product; value=quantity]
// dimension={width*, height*, qty}
// product={productId*,...}

productIdToQuantity = [:]; // key=productId, value=quantity
productIdToProduct = [:]; // key=productId, value=product
dimensionToProducts = [:]; // key=Dimension, value=list of products
dimensionToQuantity = [:]; // key=Dimension, value=tot qty (of products)

shipmentPlans = delegator.findList("OrderShipment", EntityCondition.makeCondition([shipmentId : shipmentId]), null, null, null, false);

if (shipmentPlans) {
    shipmentPlans.each { shipmentPlan ->
        // Select the production run, if available
        weIds = delegator.findList("WorkOrderItemFulfillment", EntityCondition.makeCondition([orderId : shipmentPlan.orderId, orderItemSeqId : shipmentPlan.orderItemSeqId]), null, ['workEffortId'], null, false); // TODO: add shipmentId
        weId = EntityUtil.getFirst(weIds);
        productionRunTree = [] as ArrayList;
        // TODO
        if (weId) {
            ProductionRunHelper.getLinkedProductionRuns(delegator, dispatcher, weId.workEffortId, productionRunTree);
            for (int i = 0; i < productionRunTree.size(); i++) {
                oneProductionRun = (ProductionRun)productionRunTree.get(i);
                if (ProductionRunHelper.hasTask(delegator, selectWorkEffortNameParameter, oneProductionRun.getGenericValue().workEffortId)) {
                    product = oneProductionRun.getProductProduced();
                    primaryCategory = product.primaryProductCategoryId;
                    if (primaryCategory && selectPrimaryCategoryIdParameter.equals(primaryCategory)) {
                        productId = product.productId;
                        productIdToProduct.put(productId, product);
                        if (!productIdToQuantity.containsKey(productId)) {
                            productIdToQuantity.put(productId, 0.0);
                        }
                        qty = productIdToQuantity.get(productId);
                        productIdToQuantity.put(productId, oneProductionRun.getGenericValue().quantityToProduce + qty);
                    }
                }
            }
        }
    }
    productIdToProduct.values().each { product ->
        heightD = product.productHeight;
        height = 0;
        if (heightD) {
            height = (heightD * 1000) as int;
        }

        widthD = product.productWidth;
        width = 0;
        if (widthD) {
            width = (widthD * 1000) as int;
        }
        Dimension dim = new Dimension(width, height);
        if (!dimensionToProducts.containsKey(dim)) {
            dimensionToProducts.put(dim, new ArrayList());
        }
        prodList = (List)dimensionToProducts.get(dim);
        prodList.add(product);
        // tot qty per dimension
        if (!dimensionToQuantity.containsKey(dim)) {
            dimensionToQuantity.put(dim, 0.0);
        }
        qty = dimensionToQuantity[dim];
        dimensionToQuantity.put(dim, productIdToQuantity[product.productId] + qty);
    }
    //
    //
    //
    list1 = [] as ArrayList;
    dimensionToProducts.keySet().each { dim ->
        map1 = [:];
        list1.add(map1);
        map1.width = (dim.getWidth() / 1000);
        map1.height = (dim.getHeight() / 1000);
        map1.quantity = dimensionToQuantity.get(dim);
        list2 = [] as ArrayList;
        map1.products = list2;
        products = (List)dimensionToProducts.get(dim);
        for (int i = 0; i < products.size(); i++) {
            product = products.get(i);
            Map map2 = [:];
            list2.add(map2);
            map2.product = product;
            map2.quantity = productIdToQuantity.get(product.productId);
        }
    }
    context.cuttingList = list1;
}