// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.

package implments

import (
	dal "LAPP_LF_MOM_BACKEND/dao/wm"
	"LAPP_LF_MOM_BACKEND/db"
	"LAPP_LF_MOM_BACKEND/grmi"
	meta "LAPP_LF_MOM_BACKEND/meta/wm"
	model "LAPP_LF_MOM_BACKEND/models/wm"
	"LAPP_LF_MOM_BACKEND/utils"
	"LAPP_LF_MOM_BACKEND/web/models"
	"fmt"
)

/******************************************************************************
 *
 * @Description              : StockTransferHead的默认查询条件
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-06-29 10:57:04
 *
 ******************************************************************************/
var DefaultConditionOfStockTransferHead = grmi.NewCondition(
	map[string]grmi.ConditionItem{
		meta.StockTransferHead_StockTransferId.UrlParameterName:   grmi.NewConditionItem(meta.StockTransferHead_StockTransferId, grmi.Equal, true),
		meta.StockTransferHead_RefOrderId.UrlParameterName:        grmi.NewConditionItem(meta.StockTransferHead_RefOrderId, grmi.Equal, false),
		meta.StockTransferHead_WarehouseId.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_WarehouseId, grmi.Equal, false),
		meta.StockTransferHead_TargetWarehouseId.UrlParameterName: grmi.NewConditionItem(meta.StockTransferHead_TargetWarehouseId, grmi.Equal, false),
		meta.StockTransferHead_Remark.UrlParameterName:            grmi.NewConditionItem(meta.StockTransferHead_Remark, grmi.Equal, false),
		meta.StockTransferHead_DemandDate.UrlParameterName:        grmi.NewConditionItem(meta.StockTransferHead_DemandDate, grmi.Approximate, false),
		meta.StockTransferHead_RegisterDate.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_RegisterDate, grmi.Approximate, false),
		meta.StockTransferHead_Status.UrlParameterName:            grmi.NewConditionItem(meta.StockTransferHead_Status, grmi.Equal, false),
		meta.StockTransferHead_STType.UrlParameterName:            grmi.NewConditionItem(meta.StockTransferHead_STType, grmi.Equal, false),
		meta.StockTransferHead_STType1.UrlParameterName:           grmi.NewConditionItem(meta.StockTransferHead_STType1, grmi.Equal, false),
		meta.StockTransferHead_STType2.UrlParameterName:           grmi.NewConditionItem(meta.StockTransferHead_STType2, grmi.Equal, false),
		meta.StockTransferHead_STReason.UrlParameterName:          grmi.NewConditionItem(meta.StockTransferHead_STReason, grmi.Equal, false),
		meta.StockTransferHead_OrderedQty.UrlParameterName:        grmi.NewConditionItem(meta.StockTransferHead_OrderedQty, grmi.Equal, false),
		meta.StockTransferHead_DeliveredQty.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_DeliveredQty, grmi.Equal, false),
		meta.StockTransferHead_Applicant.UrlParameterName:         grmi.NewConditionItem(meta.StockTransferHead_Applicant, grmi.Equal, false),
		meta.StockTransferHead_Department.UrlParameterName:        grmi.NewConditionItem(meta.StockTransferHead_Department, grmi.Equal, false),
		meta.StockTransferHead_ApplyTime.UrlParameterName:         grmi.NewConditionItem(meta.StockTransferHead_ApplyTime, grmi.Approximate, false),
		meta.StockTransferHead_STCtrlPara1.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara1, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara2.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara2, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara3.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara3, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara4.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara4, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara5.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara5, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara6.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara6, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara7.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara7, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara8.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara8, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara9.UrlParameterName:       grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara9, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara10.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara10, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara11.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara11, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara12.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara12, grmi.Equal, false),
		meta.StockTransferHead_STCtrlPara13.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara13, grmi.Approximate, false),
		meta.StockTransferHead_STCtrlPara14.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara14, grmi.Approximate, false),
		meta.StockTransferHead_STCtrlPara15.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara15, grmi.Approximate, false),
		meta.StockTransferHead_STCtrlPara16.UrlParameterName:      grmi.NewConditionItem(meta.StockTransferHead_STCtrlPara16, grmi.Approximate, false),
		meta.StockTransferHead_LastModify.UrlParameterName:        grmi.NewConditionItem(meta.StockTransferHead_LastModify, grmi.Approximate, false),
		meta.StockTransferHead_LastUser.UrlParameterName:          grmi.NewConditionItem(meta.StockTransferHead_LastUser, grmi.Equal, false),
		meta.StockTransferHead_CreateTime.UrlParameterName:        grmi.NewConditionItem(meta.StockTransferHead_CreateTime, grmi.Approximate, false),
	},
	nil,
)

/******************************************************************************
 *
 * @Description              : StockTransferHead的默认分页查询条件
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-06-29 10:57:04
 *
 ******************************************************************************/
var DefaultConditionOfStockTransferHeadAndPaging = grmi.NewCondition(
	DefaultConditionOfStockTransferHead.Items,
	grmi.NewPaging(),
)

/******************************************************************************
 *
 * @Struct Name              : StockTransferHeadServiceImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : StockTransferHead的服务实现
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-06-29 10:57:04
 *
 ******************************************************************************/
type StockTransferHeadServiceImplement struct {
}

/******************************************************************************
 *
 * @Function Name            : NewStockTransferHeadDAOImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : 创建一个StockTransferHeadDAOImplement实例
 *
 * @Return Value             : StockTransferHeadDAOImplement实例
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-06-29 10:57:04
 *
 ******************************************************************************/
func NewStockTransferHeadServiceImplement() *StockTransferHeadServiceImplement {
	return &StockTransferHeadServiceImplement{}
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.InsertOne
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) InsertOne(user *models.Usertab, entity *model.StockTransferHead) error {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "InsertOneStockTransferHead", "插入一个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()

	session.Begin()
	bookDao := dal.NewInventoryBookDAO(session, user.Userid)
	binDao := dal.NewStorageBinDAO(session, user.Userid)
	daoWorkAreaUserLst := dal.NewWorkAreaUserLstDAO(session, user.Userid)
	daoWorkArea := dal.NewWorkAreaDAO(session, user.Userid)
	var workAreaCheck,targetWorkAreaCheck model.WorkAreaCheck
	checkLi, err := binDao.Select([]grmi.Predicate{meta.StorageBin_Status.NewPredicate(grmi.Equal, model.BIN_STAUTS_CHECK)}, nil)
	if err != nil {
		session.Rollback()
		fmt.Println(err)
		return err
	}
	if len(checkLi) > 0 {
		session.Rollback()
		return grmi.NewBusinessError("目前存在未完成的盘点单")
	}

	snr := new(models.Snrtab)
	snr.Finr = 100
	//生成ID
	StockTransferId, err := snr.GetNextSnrWithSession(session, "StockTrans")
	if err != nil {
		session.Rollback()
		fmt.Println(err)
		return err
	}

	entity.StockTransferId = StockTransferId
	for k, _ := range entity.StockTransferDetail {
		entity.StockTransferDetail[k].StockTransferId = StockTransferId
		entity.StockTransferDetail[k].STPos = k + 1
	}

	dao := dal.NewStockTransferHeadDAO(session, user.Userid)
	err = dao.InsertOne(entity)
	if err != nil {
		session.Rollback()
		fmt.Println(err)
		return err
	}

	dao2 := dal.NewStockTransferDetailDAO(session, user.Userid)
	for _, detail := range entity.StockTransferDetail {
		workAreaCheck.StorageBinIdList = utils.AddListOnce(workAreaCheck.StorageBinIdList, detail.StorageBinId)
		workAreaCheck.WarehouseIdList = utils.AddListOnce(workAreaCheck.WarehouseIdList, detail.WarehouseId)
		workAreaCheck.StorageAreaIdList = utils.AddListOnce(workAreaCheck.StorageAreaIdList, detail.StorageAreaId)
		workAreaCheck.StorageRackIdList = utils.AddListOnce(workAreaCheck.StorageRackIdList, detail.StorageRackId)

		targetWorkAreaCheck.StorageBinIdList = utils.AddListOnce(targetWorkAreaCheck.StorageBinIdList, detail.TargetStorageBinId)
		targetWorkAreaCheck.WarehouseIdList = utils.AddListOnce(targetWorkAreaCheck.WarehouseIdList, detail.TargetWarehouseId)
		targetWorkAreaCheck.StorageAreaIdList = utils.AddListOnce(targetWorkAreaCheck.StorageAreaIdList, detail.TargetStorageAreaId)
		targetWorkAreaCheck.StorageRackIdList = utils.AddListOnce(targetWorkAreaCheck.StorageRackIdList, detail.TargetStorageRackId)
		// 库存表
		book, err := bookDao.SelectOne(detail.StorageBinId, detail.WarehouseId, detail.ArtId)
		if err != nil {
			_ = session.Rollback()
			return err
		}
		if book == nil || book.Qty-detail.OrderedQty < 0 {
			_ = session.Rollback()
			return grmi.NewBusinessError(detail.WarehouseId + detail.StorageBinId + "物料"+detail.ArtId + "数量不足!")
		} else {
			//减库存
			book.Qty -= detail.OrderedQty
			if book.Qty == 0{
				err = bookDao.DeleteOne(detail.StorageBinId, detail.WarehouseId, detail.ArtId)
				if err != nil {
					_ = session.Rollback()
					return err
				}
			}
			err = bookDao.UpdateOne(book)
			if err != nil {
				_ = session.Rollback()
				return err
			}
		}

		//增加库存
		book2, err := bookDao.SelectOne(detail.TargetStorageBinId, detail.TargetWarehouseId, detail.ArtId)
		if err != nil {
			_ = session.Rollback()
			return err
		}

		if book2 == nil {
			inventoryBook := model.InventoryBook{
				StorageBinId:  detail.TargetStorageBinId,
				WarehouseId:   detail.TargetWarehouseId,
				ArtId:         detail.ArtId,
				StorageAreaId: detail.TargetStorageAreaId,
				StorageRackId: detail.TargetStorageRackId,
				ArtName:       detail.ArtName,
				ArtType:       detail.ArtType,
				QtyUom:        detail.QtyUom,
				Qty:           detail.OrderedQty,
			}
			err = bookDao.InsertOne(&inventoryBook)
			if err != nil {
				_ = session.Rollback()
				return err
			}
		} else {
			book2.Qty += detail.OrderedQty
			err = bookDao.UpdateOne(book2)
			if err != nil {
				_ = session.Rollback()
				return err
			}
		}
	}

	// 权限
	if model.WM_AUTH_CHECK == model.WM_AUTH_CHECK_ON {
		selectWorkAreaUserLst, err := daoWorkAreaUserLst.Select([]grmi.Predicate{meta.WorkAreaUserLst_UserId.NewPredicate(grmi.Equal, user.Userid)}, nil)
		if err != nil {
			session.Rollback()
			return err
		}
		if len(selectWorkAreaUserLst) == 0 {
			session.Rollback()
			return nil
		}

		var workAreaList []*model.WorkArea
		for _, info := range selectWorkAreaUserLst {
			selectWorkArea, err := daoWorkArea.SelectOne(info.WorkAreaId)
			if err != nil || selectWorkArea == nil {
				continue
			}
			workAreaList = append(workAreaList, selectWorkArea)
		}

		err = model.WM_Check(workAreaCheck, workAreaList)
		if err != nil {
			session.Rollback()
			fmt.Println(err)
			return err
		}
		err = model.WM_Check(targetWorkAreaCheck, workAreaList)
		if err != nil {
			session.Rollback()
			fmt.Println(err)
			return err
		}
	}

	err = dao2.Insert(&entity.StockTransferDetail)
	if err != nil {
		session.Rollback()
		fmt.Println(err)
		return err
	}

	session.Commit()

	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.DeleteOne
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) DeleteOne(user *models.Usertab, stockTransferId string) error {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "DeleteOneStockTransferHead", "删除一个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)
	record, err := dao.SelectOne(stockTransferId)
	if err != nil {
		return err
	}
	if record == nil {
		return grmi.NewBusinessError("不存在指定记录!")
	}
	err = dao.DeleteOne(stockTransferId)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.SelectOne
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) SelectOne(user *models.Usertab, stockTransferId string) (*model.StockTransferHead, error) {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "SelectOneStockTransferHead", "查询一个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)
	result, err := dao.SelectOne(stockTransferId)
	if err != nil {
		return nil, err
	}

	dao2 := dal.NewStockTransferDetailDAO(session, user.Userid)
	result2, err := dao2.Select([]grmi.Predicate{meta.StockTransferDetail_StockTransferId.NewPredicate(grmi.Equal,stockTransferId)}, nil)
	if err != nil {
		return nil, err
	}

	result.StockTransferDetail = result2

	return result, nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.UpdateOne
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) UpdateOne(user *models.Usertab, entity *model.StockTransferHead) error {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "UpdateOneStockTransferHead", "修改一个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)
	record, err := dao.SelectOne(entity.StockTransferId)
	if err != nil {
		return err
	}
	if record == nil {
		return grmi.NewBusinessError("不存在指定记录!")
	}
	err = dao.UpdateOne(entity)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.Insert
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) Insert(user *models.Usertab, entities *[]model.StockTransferHead) error {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "InsertStockTransferHead", "插入多个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)

	for _, entity := range *entities {
		record, err := dao.SelectOne(entity.StockTransferId)
		if err != nil {
			return err
		}
		if record != nil {
			return grmi.NewBusinessError("已经存在相同主键的记录!")
		}
	}

	err := dao.Insert(entities)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.Delete
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) Delete(user *models.Usertab, entities *[]model.StockTransferHead) error {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "DeleteStockTransferHead", "删除多个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)

	for _, entity := range *entities {
		record, err := dao.SelectOne(entity.StockTransferId)
		if err != nil {
			return err
		}
		if record == nil {
			return grmi.NewBusinessError("不存在指定记录!")
		}
	}

	err := dao.Delete(entities)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.Select
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) Select(user *models.Usertab, urlParameters map[string]string) (interface{}, error) {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "SelectStockTransferHead", "查询StockTransferHead")

	condition := DefaultConditionOfStockTransferHeadAndPaging
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	predicates, err := condition.BuildPredicates(urlParameters)
	if err != nil {
		return nil, err
	}
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)
	if condition.Fill(urlParameters) {
		result, err := dao.SelectAndPaging(condition.Paging, predicates, condition.OrderByFields)
		if err != nil {
			return nil, err
		}
		return result, nil
	} else {
		result, err := dao.Select(predicates, condition.OrderByFields)
		if err != nil {
			return nil, err
		}
		return result, nil
	}
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/wm/StockTransferHeadService.Update
 *
 ******************************************************************************/
func (impl *StockTransferHeadServiceImplement) Update(user *models.Usertab, entities *[]model.StockTransferHead) error {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "UpdateStockTransferHead", "修改多个StockTransferHead")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)

	for _, entity := range *entities {
		record, err := dao.SelectOne(entity.StockTransferId)
		if err != nil {
			return err
		}
		if record == nil {
			return grmi.NewBusinessError("不存在指定记录!")
		}
	}

	err := dao.Update(entities)
	if err != nil {
		return err
	}
	return nil
}

func (impl *StockTransferHeadServiceImplement) ExportExcel(user *models.Usertab, urlParameters map[string]string) (interface{}, error) {

	grmi.Log(user, "/services/wm/implments/StockTransferHead.service.impl.go", "ExportExcel", "导出excel表")

	condition := DefaultConditionOfStockTransferHeadAndPaging
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	predicates, err := condition.BuildPredicates(urlParameters)
	if err != nil {
		return nil, err
	}
	dao := dal.NewStockTransferHeadDAO(session, user.Userid)
	//condition.OrderByFields = append(condition.OrderByFields, meta.StockTransferHead_StockTransferId)
	result, err := dao.Select(predicates, condition.OrderByFields)
	if err != nil {
		return nil, err
	}
	temp := make([]interface{}, len(result))
	for index, item := range result {
		temp[index] = item
	}
	titleList := []string{}

	filepath, err := grmi.SaveExcelFile(temp, titleList, "移库", "移库")
	if err != nil {
		return nil, grmi.NewBusinessError(fmt.Sprintf("导出报表失败，请重试, errors: %s", err.Error()))
	}
	return filepath, nil
}
