ExchangePCDAction4Special.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.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.consts.PcdStatus;
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 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.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 特殊交换晶舟
 *
 * @author yanbing.chen
 * @version 6.0.0
 * @date 2019/9/18
 **/
public class ExchangePCDAction4Special extends ExchangeCarrierSaveAction {

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

        Long facilityRrn = LocalContext.getFacilityRrn();
        String fromCarrierId = WebUtils.getParameterUpperCase("carrierId", request);
        String toCarrierId = WebUtils.getParameterUpperCase("productId", request);

        Assert.isFalse(StringUtils.isEmpty(fromCarrierId),
                       Errors.create().content("Source carrier cannnot be empty").build());

        Assert.isFalse(StringUtils.isEmpty(toCarrierId),
                       Errors.create().content("Target carrier cannnot be empty").build());

        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);
        Lot lot = getSingleLotInCarrier(facilityRrn, fromCarrier);

        this.checkIsRunCardLot(lot);

        this.validCarrierInfo(facilityRrn, fromCarrier, toCarrier, lot);

        Map<String, Object> lotInfo = BeanUtils.copyBeanToMap(lot);

        lotInfo.put("sourceListValue",
                    parseToJsonString(wipQueryService.getUnitListByCarrier(fromCarrier.getInstanceRrn())));
        lotInfo.put("targetListValue", initEmptyCarrier());

        lotInfo.put("targetCarrierRrn", toCarrier.getInstanceRrn());
        lotInfo.put("targetCarrierId", toCarrierId);
        lotInfo.put("currentCarrierId", fromCarrier.getInstanceId());
        lotInfo.put("maxSize", fromCarrier.getSlotCount());
        lotInfo.put("targetMaxSize", toCarrier.getSlotCount());
        lotInfo.put("currentProcessLocation", ctxExecService.getCurrentProcessLocation(facilityRrn, lot));
        // 13
        // 换到cst25
        // 要回到尾标位置
        lotInfo.put("toDefaultPosition", fromCarrier.getSlotCount() == 13 && toCarrier.getSlotCount() == 25);

        // 换到cst13需要可以拖动
        Boolean canDropTarget = fromCarrier.getSlotCount() == 25 && toCarrier.getSlotCount() == 13;
        lotInfo.put("canDropTarget", canDropTarget);

        request.setAttribute("lotInfo", lotInfo);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward exchangePCD(ActionMapping mapping, HttpServletRequest request) throws Exception {
        Long facilityRrn = LocalContext.getFacilityRrn();
        String userId = LocalContext.getUserId();
        String fromCarrierId = WebUtils.getParameter("carrierId", request);
        String toCarrierId = WebUtils.getParameter("productId", request);
        List<Lot> lockLots = new ArrayList<>();
        Assert.isFalse(StringUtils.isEmpty(fromCarrierId),
                       Errors.create().content("Source carrier cannnot be empty").build());

        Assert.isFalse(StringUtils.isEmpty(toCarrierId),
                       Errors.create().content("Target carrier cannnot be empty").build());

        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);
        Lot lot = getSingleLotInCarrier(facilityRrn, fromCarrier);

        this.checkIsRunCardLot(lot);

        this.validCarrierInfo(facilityRrn, fromCarrier, toCarrier, lot);
        lot.setLotComments("Exchange carrier, initial carrier: " + fromCarrierId);
        lot.setTransPerformedby(userId);
        lot.setTransId(TransactionNames.EXCHANGE_KEY);
        lockLots.add(lot);

        carrierService.exchangeCarrierSpecial(lot, toCarrier.getInstanceRrn(), parseJsonStrAndRemoveIdlePostion(
                request.getParameter("targetListValues")), toCarrier, facilityRrn, userId);

        return mapping.getInputForward();
    }

    private void validCarrierInfo(Long facilityRrn, Carrier sourceCarrier, Carrier targetCarrier, Lot lot) {

        if (carrierService.isAssseblyNeed(targetCarrier.getObjectSubtype())) {
            if (!StringUtils.equals(targetCarrier.getCarrierStatus(), PcdStatus.ASSEMBLY_KEY)) {
                throw new SystemIllegalArgumentException(
                        Errors.create().key(MessageIdList.CARRIER_INVALID_CASSETTE_STATUS).content("晶舟当前状态不能交换!")
                              .build());
            }
        } else {
            if (!StringUtils.equals(targetCarrier.getCarrierStatus(), PcdStatus.FREE_KEY)) {
                throw new SystemIllegalArgumentException(
                        Errors.create().key(MessageIdList.CARRIER_INVALID_CASSETTE_STATUS).content("晶舟当前状态不能交换!")
                              .build());
            }
        }

        carrierService.checkPcdIsValid(targetCarrier.getInstanceRrn(), facilityRrn);

        Assert.isFalse(
                StringUtils.equalsIgnoreCase(targetCarrier.getObjectSubtype(), Carrier.CarrierType.DUMMY.toString()),
                Errors.create().content("The carrier: {} is a  dummy carrier!").args(targetCarrier.getInstanceId())
                      .build());

        Assert.isFalse(targetCarrier.getAvailableSlotCount() < lot.getQty1(),
                       Errors.create().content("CST {}'s qty is {}" + " " + "> {}")
                             .args(sourceCarrier.getInstanceId(), lot.getInt_qty1(), targetCarrier.getSlotCount())
                             .build());

        Assert.isFalse(!StringUtils.equalsIgnoreCase(targetCarrier.getCarrierStatus(), PcdStatus.FREE_KEY) &&
                               !StringUtils.equalsIgnoreCase(targetCarrier.getCarrierStatus(), PcdStatus.ASSEMBLY_KEY),
                       Errors.create().content("Invalid carrier status!").build());

        Assert.state(!lotAutoMonitorInqService.checkMonitorCarrierUsed(targetCarrier.getInstanceRrn()),
                     Errors.create().key(MessageIdList.AUTOMONITOR_CARRIER_INUSED).build());

        List<String> lots = carrierService.getInUseCarrierLotIdList(targetCarrier.getInstanceRrn());
        if (!lots.isEmpty()) {
            StringBuilder errorMessage = new StringBuilder();
            errorMessage.append("Cassette Id: ").append(targetCarrier.getInstanceId());
            errorMessage.append(" is already in use by Lot Id: ");
            for (String string : lots) {
                errorMessage.append(string);
                errorMessage.append(" ");
            }

            throw new SystemIllegalArgumentException(Errors.create().content(errorMessage.toString()).build());
        }

        //check SortJob
        checkWaitJobs(sourceCarrier.getInstanceRrn(), targetCarrier.getInstanceRrn(), 0L);
    }

    private Lot getSingleLotInCarrier(Long facilityRrn, Carrier fromCarrier) {
        Lot lot;
        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 = lotQueryService.getLot(lotId, facilityRrn);

        Assert.isTrue(StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.HOLD) ||
                              StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.WAITING),
                      Errors.create().key(MessageIdList.CARRIER_EXCHANGE_MUST_HOLD_WAITING)
                            .content("批次:{} 必须是HOLD或者WAITING才可以完成特殊交换!").args(lotId).build());

        return lot;
    }

}