ExchangeCarrierSaveAction.java

/*
 *        @ Copyright 2001 FA Software;
 *        All right reserved. No part of this program may be reproduced or
 *        transmitted in any form or by any means, electronic or
 *        mechanical, including photocopying, recording, or by any
 *        information storage or retrieval system without written
 *        permission from FA Software, except for inclusion of brief
 *        quotations in a review.
 */
package com.mycim.webapp.actions.carrier.exchangecarrier;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.context.spring.SpringContext;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotStatus;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.CarrierSetupAction;
import com.mycim.webapp.forms.LotBaseInfoForm;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 交换carrier
 *
 * @author yanbing.chen
 * @version 6.0.0
 * @date 2019/9/17
 **/
public class ExchangeCarrierSaveAction extends CarrierSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        if (WebUtils.getParameterBoolean(Constants.INIT_KEY, request)) {
            return mapping.findForward("setup");
        }

        long facilityRrn = LocalContext.getFacilityRrn();
        LotBaseInfoForm theform = (LotBaseInfoForm) form;
        String fromCarrierId = theform.getCarrierId().trim().toUpperCase();
        String toCarrierId = theform.getProductId().trim().toUpperCase();

        // validate from and to carrier
        Assert.isFalse(fromCarrierId.equalsIgnoreCase(toCarrierId),
                       Errors.create().content("Two Cassette ID is same").build());

        Carrier fromCarrier = carrierService.getCarrier(facilityRrn, fromCarrierId);
        Carrier toCarrier = carrierService.getCarrier(facilityRrn, toCarrierId);

        carrierService.compareRealCarrierAndCheckAvailabile(facilityRrn, fromCarrier.getInstanceId(),
                                                            toCarrier.getInstanceId());
        //check sortJob
        checkWaitJobs(fromCarrier.getInstanceRrn(), toCarrier.getInstanceRrn(), 0L);


        List<String> lotIds = carrierService.getInUseCarrierLotIdList(fromCarrier.getInstanceRrn());
        String lotId;
        Assert.isFalse(lotIds == null || lotIds.size() != 1,
                       Errors.create().key(MessageIdList.CARRIER_CASSETTE_HAVE_SOME_LOTS).content("该晶舟内有{}个批次")
                             .args(lotIds == null ? 0 : lotIds.size()).build());

        lotId = lotIds.get(0);

        Lot lot = lotQueryService.getLot(lotId, facilityRrn);

        this.checkIsRunCardLot(lot);

        carrierService.getCarrierRrnForLot(facilityRrn, lot, toCarrierId);

        Assert.isFalse(fromCarrier.getCarrierMapRrn() == null || fromCarrier.getCarrierMapRrn() <= 0,
                       Errors.create().key(MessageIdList.NOT_FOUND_UNIT).content("Not found unit in fromCassette!").build());

        Long num4AvailableInCarrier = carrierService.getNumberOfAvailableInCarrier(toCarrier.getInstanceRrn());
        Long num4UnitInCarrier = wipQueryService.getNumberOfUnitInCarrier(fromCarrier.getInstanceRrn());

        Assert.isFalse(toCarrier.getCarrierMapRrn() != null && toCarrier.getCarrierMapRrn() > 0 &&
                               num4AvailableInCarrier < num4UnitInCarrier,
                       Errors.create().content("Please choose a empty Cassette to exchange.").build());

        // make value to next page
        theform.setSourceListValues(
                parseToJsonString(wipQueryService.getUnitListByCarrier(fromCarrier.getInstanceRrn())));
        theform.setTargetListValues(initEmptyCarrier());

        theform.setCarrierId(fromCarrierId);
        theform.setProductId(toCarrierId);

        request.setAttribute("carrierSlot", fromCarrier.getSlotCount());

        return mapping.findForward(Constants.MODIFY_KEY);
    }


    @Override
    public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        if (mapping.getAttribute() != null) {
            request.removeAttribute(mapping.getAttribute());
        }
        return mapping.findForward(Constants.SETUP_KEY);
    }

    public ActionForward exchangecarrier(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
        String language = I18nUtils.getCurrentLanguage().name();
        String userId = LocalContext.getUserId();
        Long facilityRrn = LocalContext.getFacilityRrn();
        // Populate the form bean instance
        LotBaseInfoForm theform = (LotBaseInfoForm) form;

        Carrier fromCarrier = carrierService.getCarrier(facilityRrn, theform.getCarrierId().trim().toUpperCase());
        Carrier toCarrier = carrierService.getCarrier(facilityRrn, theform.getProductId().trim().toUpperCase());
        carrierService.compareRealCarrierAndCheckAvailabile(facilityRrn, fromCarrier.getInstanceId(),
                                                            toCarrier.getInstanceId());
        Assert.state(!lotAutoMonitorInqService.checkMonitorCarrierUsed(toCarrier.getInstanceRrn()),
                     Errors.create().key(MessageIdList.AUTOMONITOR_CARRIER_INUSED).build());

        //check SortJob
        checkWaitJobs(fromCarrier.getInstanceRrn(), toCarrier.getInstanceRrn(), 0L);

        // 验证目标晶舟数量是否足够
        Assert.isFalse(
                toCarrier.getAvailableSlotCount() < (fromCarrier.getSlotCount() - fromCarrier.getAvailableSlotCount()),
                Errors.create().content("Available slot count in carrier:{} is not enough !")
                      .args(toCarrier.getInstanceId()).build());

        List<String> lotIds;
        lotIds = carrierService.getInUseCarrierLotIdList(fromCarrier.getInstanceRrn());
        String lotId;
        Assert.isFalse(lotIds == null || lotIds.size() != 1,
                       Errors.create().key(MessageIdList.CARRIER_CASSETTE_HAVE_SOME_LOTS).content("该晶舟内有{}个批次")
                             .args(lotIds == null ? 0 : lotIds.size()).build());

        lotId = lotIds.get(0);

        Lot lot = lotQueryService.getLot(lotId, facilityRrn);

        this.checkIsRunCardLot(lot);

        if (StringUtils.equalsIgnoreCase("CN", language)) {
            lot.setLotComments("交换晶舟,初始晶舟为: " + fromCarrier.getInstanceId());
        } else {
            lot.setLotComments("Exchange carrier, initial carrier: " + fromCarrier.getInstanceId());
        }
        Assert.isTrue((StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.HOLD) ||
                              StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.WAITING)),
                      Errors.create().key(MessageIdList.LOT_EXCHANGECARRIER_STATUS_ALLOW)
                            .content("Only {} Status Allow!").args("HOLD or WAITING").build());
        lot.setTransPerformedby(userId);
        lot.setTransId(TransactionNames.EXCHANGE_KEY);
        List<Lot> lockLots = new ArrayList<>();
        lockLots.add(lot);
        //        checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_EXCHANGE_CST,
        //                                    lockLots, "Exchange CST in ExchangeCarrierSaveAction by: " +
        //                                    userId);
        carrierService.exchangeCarrierSpecial(lot, toCarrier.getInstanceRrn(),
                                              parseJsonStrAndRemoveIdlePostion(theform.getTargetListValues()),
                                              toCarrier, facilityRrn, userId);
        if (mapping.getAttribute() != null) {
            request.removeAttribute(mapping.getAttribute());
        }

        return mapping.findForward(Constants.SETUP_KEY);
    }


    /**
     * @param unitList
     * @return String
     * @Description 将集合对象转换成json字符串(包含空位置信息的json, 一般用于前台ext的展示)
     * @author Aiden
     */
    public String parseToJsonString(List<Map> unitList) {
        Collections.sort(unitList, new Comparator<Map>() {

            // 将wafer重新排序
            @Override
            public int compare(Map map1, Map map2) {
                int position1 = MapUtils.getIntValue(map1, "position");
                int position2 = MapUtils.getIntValue(map2, "position");
                if (position1 > position2) {
                    return 1;
                } else if (position1 < position2) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        // 指wafer位置从1开始
        int number = 1;
        int seq = 1;
        List<Map<String, Object>> units = new ArrayList<>();
        for (Map unit : unitList) {
            Map<String, Object> unitMap = null;
            seq = MapUtils.getIntValue(unit, "position");
            while ((number < seq)) {
                unitMap = new HashMap<String, Object>();
                unitMap.put("position", number + "");
                unitMap.put("unitId", "");
                unitMap.put("unitRrn", "");
                unitMap.put("lotid", "");
                unitMap.put("chooseFlag", "");
                units.add(unitMap);
                number++;
            }
            unitMap = new HashMap<String, Object>();
            unitMap.put("position", number + "");
            unitMap.put("unitId", unit.get("unitId"));
            unitMap.put("unitRrn", unit.get("unitRrn"));
            unitMap.put("lotid", unit.get("lotid"));
            unitMap.put("chooseFlag", unit.get("chooseFlag"));
            units.add(unitMap);
            number++;
        }
        // 已有
        int listSize = units.size();
        for (int i = listSize + 1; i <= 25; i++) {
            Map<String, Object> unitMap = new HashMap<String, Object>();
            unitMap.put("position", i + "");
            unitMap.put("unitId", "");
            unitMap.put("unitRrn", "");
            unitMap.put("lotid", "");
            unitMap.put("chooseFlag", "");
            units.add(unitMap);
        }
        return JsonUtils.toString(units);
    }

    /**
     * @param jsonStr
     * @return List<Map < String, Object>>
     * @Description 获得移除空位后的wafer信息
     * @author Aiden
     */
    public List<Map> parseJsonStrAndRemoveIdlePostion(String jsonStr) {
        List<Map> unitList = new ArrayList();
        List<Map> tempUnits = JsonUtils.toObject(jsonStr, List.class);
        for (Map unitMap : tempUnits) {
            String unitId = MapUtils.getString(unitMap, "unitId");
            String unitRrn = MapUtils.getString(unitMap, "unitRrn");
            String lotid = MapUtils.getString(unitMap, "lotid");
            if (StringUtils.isNotBlank(unitId) && StringUtils.isNotBlank(unitRrn) && StringUtils.isNotBlank(lotid)) {
                unitList.add(unitMap);
            }
        }
        return unitList;
    }

}