package implments

import (
	meDal "LAPP_ACURA_MOM_BACKEND/dao/me"
	omDal "LAPP_ACURA_MOM_BACKEND/dao/om"
	dal "LAPP_ACURA_MOM_BACKEND/dao/pln"
	"LAPP_ACURA_MOM_BACKEND/db"
	"LAPP_ACURA_MOM_BACKEND/global"
	"LAPP_ACURA_MOM_BACKEND/grmi"
	omMeta "LAPP_ACURA_MOM_BACKEND/meta/om"
	baseModel "LAPP_ACURA_MOM_BACKEND/models/base"
	omModel "LAPP_ACURA_MOM_BACKEND/models/om"
	model "LAPP_ACURA_MOM_BACKEND/models/pln"
	"time"
)

// CancelCustOrderQtyMultiPlant 取消客户订单数量
func (impl *CustOrderServiceImplement) CancelCustOrderQtyMultiPlant(user *global.User, custOrderId string, cancelQty int) error {
	grmi.Log(user, "/services/pln/implments/CustOrder.service.impl.go", "CancelCustOrderQty", "取消客户订单数量")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	custOrderDao := dal.NewCustOrderDAO(session, user.PlantNr, user.UserId)
	custOrderQtyDao := dal.NewCustOrderQtyDAO(session, user.PlantNr, user.UserId)
	custOrderStatusDao := dal.NewCustOrderStatusDAO(session, user.PlantNr, user.UserId)
	custOrderStatusHistoryDao := dal.NewCustOrderStatusHistoryDAO(session, user.PlantNr, user.UserId)
	serialOrderDao := omDal.NewSerialOrderDAO(session, user.PlantNr, user.UserId)
	serialOrderStatusDao := omDal.NewSerialOrderStatusDAO(session, user.PlantNr, user.UserId)
	serialOrderStatusRecDao := omDal.NewSerialOrderStatusRecLstDAO(session, user.PlantNr, user.UserId)
	productFamilyRelateDao := meDal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)
	serialOrderPoDao := omDal.NewSerialOrderPOLstDAO(session, user.PlantNr, user.UserId)
	// 校验客户订单数据及状态
	custOrder, err := custOrderDao.SelectOne(custOrderId)
	if err != nil {
		return grmi.NewBusinessError("查询客户订单失败, error:" + err.Error())
	}
	if custOrder == nil {
		return grmi.NewBusinessError("客户订单不存在, 客户订单ID:" + custOrderId)
	}
	if custOrder.OrderStatus.Status <= baseModel.WO_STATUS_PLANNED || custOrder.OrderStatus.Status >= baseModel.WO_STATUS_FINISHED {
		return grmi.NewBusinessError("当前客户订单的状态不允许取消数量")
	}
	if custOrder.OrderQty.PlanQty-custOrder.OrderQty.RunningQty-custOrder.OrderQty.CancelQty < cancelQty {
		return grmi.NewBusinessError("取消数量已经大于客户订单允许取消的数量")
	}
	//originCancelQty := custOrder.OrderQty.CancelQty
	productLi, err := productFamilyRelateDao.SelectProductByFamilyIdForCreateSerialOrder(custOrder.ProjectId, custOrder.ProductFamilyId)
	if err != nil {
		return grmi.NewBusinessError("查询派生下的总成失败, error:" + err.Error())
	}
	productNum := len(productLi)
	serialOrderDataLi, err := serialOrderDao.SelectUnOnGoingSerialOrder(custOrderId)
	if err != nil {
		return grmi.NewBusinessError("查询工单数据失败, error:" + err.Error())
	}
	syncKeyMap := make(map[string][]omModel.VOmSerialorder)
	syncKeyLi := make([]string, 0)
	for _, serialOrderData := range serialOrderDataLi {
		_, exist := syncKeyMap[serialOrderData.SerialOrder.SyncKey]
		if !exist {
			syncKeyLi = append(syncKeyLi, serialOrderData.SerialOrder.SyncKey)
			syncKeyMap[serialOrderData.SerialOrder.SyncKey] = make([]omModel.VOmSerialorder, 0)
		}
		syncKeyMap[serialOrderData.SerialOrder.SyncKey] = append(syncKeyMap[serialOrderData.SerialOrder.SyncKey], serialOrderData)
	}
	var count int
	splitSyncKeyLi := make([]string, 0)
	for _, syncKey := range syncKeyLi {
		if len(syncKeyMap[syncKey]) == productNum {
			splitSyncKeyLi = append(splitSyncKeyLi, syncKey)
			count++
		}
	}
	if count < cancelQty {
		return grmi.NewBusinessError("当前客户订单可取消数量小于需要取消数量")
	}
	impl.QuickSort(splitSyncKeyLi)
	statusRecLi := make([]omModel.SerialOrderStatusRecLst, 0)
	cancelSerialOrderIdLi := make([]interface{}, 0)
	orderDataLi := make([]omModel.SerialOrder, 0)
	for i := 0; i < cancelQty; i++ {
		cancelSyncKey := splitSyncKeyLi[i]
		innerOrderLi, err := serialOrderDao.Select([]grmi.Predicate{omMeta.SerialOrder_SyncKey.NewPredicate(grmi.Equal, cancelSyncKey)}, nil)
		if err != nil {
			return grmi.NewBusinessError("查询工单数据失败, error:" + err.Error())
		}
		orderDataLi = append(orderDataLi, innerOrderLi...)
	}
	cancelSerialOrderLi := make([]interface{}, 0)
	if err = session.Begin(); err != nil {
		return grmi.NewBusinessError("开启事务失败, error:" + err.Error())
	}
	for _, serialOrderData := range orderDataLi {
		if serialOrderData.OrderType != baseModel.ORDER_TYPE_SEQ {
			cancelSerialOrderLi = append(cancelSerialOrderLi, serialOrderData.SerialOrderId)
		}
		cancelSerialOrderIdLi = append(cancelSerialOrderIdLi, serialOrderData.SerialOrderId)
		serialOrderStatus := serialOrderData.SerialOrderStatus
		statusRec := omModel.SerialOrderStatusRecLst{
			SerialOrderId: serialOrderData.SerialOrderId,
			PrevStatus:    serialOrderStatus.Status,
			Status:        baseModel.WO_STATUS_CANCELED,
			Remark1:       "SPLIT",
		}
		statusRecLi = append(statusRecLi, statusRec)
		serialOrderStatus.Status = baseModel.WO_STATUS_CANCELED
		err = serialOrderStatusDao.UpdateOneWithStatus(&serialOrderStatus, baseModel.WO_STATUS_RELEASED)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("更新工单状态失败, error:" + err.Error())
		}
	}
	// 保存工单状态变更记录
	num := len(statusRecLi) / 50
	remainder := len(statusRecLi) % 50
	for i := 0; i < num; i++ {
		insertLi := statusRecLi[50*i : (i+1)*50]
		err = serialOrderStatusRecDao.Insert(&insertLi)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("保存工单状态变更记录失败, 错误:" + err.Error())
		}
	}
	if remainder != 0 {
		insertLi := statusRecLi[num*50:]
		err = serialOrderStatusRecDao.Insert(&insertLi)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("保存工单状态变更记录失败, 错误:" + err.Error())
		}
	}
	// 更新工单工序状态
	poUpdateData := omModel.SerialOrderPOLst{
		Status: baseModel.WO_STATUS_CANCELED,
	}
	num = len(cancelSerialOrderIdLi) / 50
	remainder = len(cancelSerialOrderIdLi) % 50
	for i := 0; i < num; i++ {
		updateLi := cancelSerialOrderIdLi[50*i : (i+1)*50]
		err = serialOrderPoDao.UpdateWhere([]grmi.Predicate{
			omMeta.SerialOrderPOLst_SerialOrderId.NewPredicate(grmi.Include, updateLi...),
		}, &poUpdateData, omMeta.SerialOrderPOLst_Status.Name)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("更新工单工序状态变更记录失败, 错误:" + err.Error())
		}
	}
	if remainder != 0 {
		updateLi := cancelSerialOrderIdLi[num*50:]
		err = serialOrderPoDao.UpdateWhere([]grmi.Predicate{
			omMeta.SerialOrderPOLst_SerialOrderId.NewPredicate(grmi.Include, updateLi...),
		}, &poUpdateData, omMeta.SerialOrderPOLst_Status.Name)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("更新工单工序状态变更记录失败, 错误:" + err.Error())
		}
	}
	// 处理客户订单数量数据
	custOrder.OrderQty.CancelQty += cancelQty
	err = custOrderQtyDao.UpdateOne(&custOrder.OrderQty)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("更新客户订单数量数据失败, error:" + err.Error())
	}
	// 通过数量判断是否需要处理客户订单状态
	if custOrder.OrderQty.CancelQty+custOrder.OrderQty.ActQty == custOrder.OrderQty.PlanQty {
		if custOrder.OrderQty.CancelQty == custOrder.OrderQty.PlanQty {
			custOrderHistory := model.CustOrderStatusHistory{
				CustOrderId:      custOrderId,
				StatusChangeType: model.STATUS_CHANGE_TYPE_OPERATION,
				FromStatus:       custOrder.OrderStatus.Status,
				ToStatus:         baseModel.ORDER_STATUS_CANCELED,
				ChangeTime:       grmi.DateTime(time.Now()),
			}
			err = custOrderStatusHistoryDao.InsertOne(&custOrderHistory)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("插入客户订单状态变更历史失败, error:" + err.Error())
			}
			custOrder.OrderStatus.Status = baseModel.ORDER_STATUS_CANCELED
			err = custOrderStatusDao.UpdateOne(&custOrder.OrderStatus)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("更新客户订单状态失败, error:" + err.Error())
			}
		} else {
			custOrderHistory := model.CustOrderStatusHistory{
				CustOrderId:      custOrderId,
				StatusChangeType: model.STATUS_CHANGE_TYPE_OPERATION,
				FromStatus:       custOrder.OrderStatus.Status,
				ToStatus:         baseModel.ORDER_STATUS_CLOSED,
				ChangeTime:       grmi.DateTime(time.Now()),
			}
			err = custOrderStatusHistoryDao.InsertOne(&custOrderHistory)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("插入客户订单状态变更历史失败, error:" + err.Error())
			}
			custOrder.OrderStatus.Status = baseModel.ORDER_STATUS_CLOSED
			err = custOrderStatusDao.UpdateOne(&custOrder.OrderStatus)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("更新客户订单状态失败, error:" + err.Error())
			}
		}
	}
	_ = session.Commit()
	return nil
}
