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

package implments

import (
	dal "LAPP_ACURA_MOM_BACKEND/dao/me"
	"LAPP_ACURA_MOM_BACKEND/db"
	"LAPP_ACURA_MOM_BACKEND/global"
	"LAPP_ACURA_MOM_BACKEND/grmi"
	meta "LAPP_ACURA_MOM_BACKEND/meta/me"
	model "LAPP_ACURA_MOM_BACKEND/models/me"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
	"strconv"
)

/******************************************************************************
 *
 * @Description              : ProductFamilyRelate的默认查询条件
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-10-22 15:30:32
 *
 ******************************************************************************/
var DefaultConditionOfProductFamilyRelate = grmi.NewCondition(
	map[string]grmi.ConditionItem{
		meta.ProductFamilyRelate_ProductFamilyId.UrlParameterName: grmi.NewConditionItem(meta.ProductFamilyRelate_ProductFamilyId, grmi.Equal, true),
		meta.ProductFamilyRelate_ProjectId.UrlParameterName:       grmi.NewConditionItem(meta.ProductFamilyRelate_ProjectId, grmi.Equal, true),
		meta.ProductFamilyRelate_ProductId.UrlParameterName:       grmi.NewConditionItem(meta.ProductFamilyRelate_ProductId, grmi.Equal, true),
		meta.ProductFamilyRelate_ProductDescr.UrlParameterName:    grmi.NewConditionItem(meta.ProductFamilyRelate_ProductDescr, grmi.Equal, false),
		meta.ProductFamilyRelate_Pos.UrlParameterName:             grmi.NewConditionItem(meta.ProductFamilyRelate_Pos, grmi.Equal, false),
		meta.ProductFamilyRelate_LastModify.UrlParameterName:      grmi.NewConditionItem(meta.ProductFamilyRelate_LastModify, grmi.Approximate, false),
		meta.ProductFamilyRelate_LastUser.UrlParameterName:        grmi.NewConditionItem(meta.ProductFamilyRelate_LastUser, grmi.Equal, false),
		meta.ProductFamilyRelate_CreateTime.UrlParameterName:      grmi.NewConditionItem(meta.ProductFamilyRelate_CreateTime, grmi.Approximate, false),
		meta.ProductFamilyRelate_Count.UrlParameterName:           grmi.NewConditionItem(meta.ProductFamilyRelate_Count, grmi.Equal, false),
	},
	nil,
)

/******************************************************************************
 *
 * @Description              : ProductFamilyRelate的默认分页查询条件
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-10-22 15:30:32
 *
 ******************************************************************************/
var DefaultConditionOfProductFamilyRelateAndPaging = grmi.NewCondition(
	DefaultConditionOfProductFamilyRelate.Items,
	grmi.NewPaging(),
)

/******************************************************************************
 *
 * @Struct Name              : ProductFamilyRelateServiceImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : ProductFamilyRelate的服务实现
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-10-22 15:30:32
 *
 ******************************************************************************/
type ProductFamilyRelateServiceImplement struct {
}

/******************************************************************************
 *
 * @Function Name            : NewProductFamilyRelateDAOImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : 创建一个ProductFamilyRelateDAOImplement实例
 *
 * @Return Value             : ProductFamilyRelateDAOImplement实例
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-10-22 15:30:32
 *
 ******************************************************************************/
func NewProductFamilyRelateServiceImplement() *ProductFamilyRelateServiceImplement {
	return &ProductFamilyRelateServiceImplement{}
}

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.InsertOne
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) InsertOne(user *global.User, entity *model.ProductFamilyRelate) error {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "InsertOneProductFamilyRelate", "插入一个ProductFamilyRelate")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)
	record, err := dao.SelectOne(entity.ProductFamilyId, entity.ProjectId, entity.ProductId)
	if err != nil {
		return err
	}
	if record != nil {
		return grmi.NewBusinessError("已经存在相同主键的记录!")
	}
	err = dao.InsertOne(entity)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.DeleteOne
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) DeleteOne(user *global.User, productFamilyId string, projectId string, productId string) error {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "DeleteOneProductFamilyRelate", "删除一个ProductFamilyRelate")

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

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.SelectOne
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) SelectOne(user *global.User, productFamilyId string, projectId string, productId string) (*model.ProductFamilyRelate, error) {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "SelectOneProductFamilyRelate", "查询一个ProductFamilyRelate")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)
	result, err := dao.SelectOne(productFamilyId, projectId, productId)
	if err != nil {
		return nil, err
	}
	return result, nil
}

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.UpdateOne
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) UpdateOne(user *global.User, entity *model.ProductFamilyRelate) error {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "UpdateOneProductFamilyRelate", "修改一个ProductFamilyRelate")

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

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.Insert
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) Insert(user *global.User, entities *[]model.ProductFamilyRelate) error {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "InsertProductFamilyRelate", "插入多个ProductFamilyRelate")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)

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

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

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.Delete
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) Delete(user *global.User, entities *[]model.ProductFamilyRelate) error {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "DeleteProductFamilyRelate", "删除多个ProductFamilyRelate")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)

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

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

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.Select
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) Select(user *global.User, urlParameters map[string]string) ([]model.ProductFamilyRelate, error) {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "SelectProductFamilyRelate", "查询ProductFamilyRelate")

	condition := DefaultConditionOfProductFamilyRelateAndPaging
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	predicates, err := condition.BuildPredicates(urlParameters)
	if err != nil {
		return nil, err
	}
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)
	result, err := dao.Select(predicates, condition.OrderByFields)
	if err != nil {
		return nil, err
	}
	return result, nil
}

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.SelectAndPaging
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) SelectAndPaging(user *global.User, urlParameters map[string]string) (grmi.PagingResult, error) {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "SelectProductFamilyRelate", "查询ProductFamilyRelate")

	condition := DefaultConditionOfProductFamilyRelateAndPaging
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	predicates, err := condition.BuildPredicates(urlParameters)
	if err != nil {
		return grmi.EmptyPagingResult, err
	}
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)
	condition.Fill(urlParameters)
	result, err := dao.SelectAndPaging(condition.Paging, predicates, condition.OrderByFields)
	if err != nil {
		return grmi.EmptyPagingResult, err
	}
	return result, nil
}

/******************************************************************************
 *
 * @Reference LAPP_ACURA_MOM_BACKEND/services/me/ProductFamilyRelateService.Update
 *
 ******************************************************************************/
func (impl *ProductFamilyRelateServiceImplement) Update(user *global.User, entities *[]model.ProductFamilyRelate) error {

	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "UpdateProductFamilyRelate", "修改多个ProductFamilyRelate")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)

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

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

// ImportFromExcel 从excel导入数据
func (impl *ProductFamilyRelateServiceImplement) ImportFromExcel(user *global.User, filepath string) error {
	grmi.Log(user, "/services/me/implments/ProductFamilyRelate.service.impl.go", "ImportFromExcel", "Copy复制Bom")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	daoProject := dal.NewProjectDAO(session, user.PlantNr, user.UserId)
	daoProductFamily := dal.NewProductFamilyDAO(session, user.PlantNr, user.UserId)
	daoProduct := dal.NewProductDAO(session, user.PlantNr, user.UserId)
	daoProductFamilyRelate := dal.NewProductFamilyRelateDAO(session, user.PlantNr, user.UserId)
	file, err := excelize.OpenFile(filepath)
	if err != nil {
		return grmi.NewBusinessError("读取文件失败, error:" + err.Error())
	}
	rowsIterator, err := file.Rows("Sheet1")
	if err != nil {
		return grmi.NewBusinessError("读取Sheet1页失败, error:" + err.Error())
	}
	rowIndex := 0
	projectMap := make(map[string]interface{})
	productMap := make(map[string]string)
	productFamilyMap := make(map[string]interface{})
	productFamilyRelateMap := make(map[string][]model.ProductFamilyRelate)
	for rowsIterator.Next() {
		rowIndex++
		if rowIndex == 1 {
			_, err = rowsIterator.Columns()
			if err != nil {
				return grmi.NewBusinessError("去读excel行数据失败, error:" + err.Error())
			}
			continue
		}
		row, err := rowsIterator.Columns()
		if err != nil {
			return grmi.NewBusinessError("去读excel行数据失败, error:" + err.Error())
		}
		if len(row) != 5 {
			return grmi.NewBusinessError("excel数据不合规, 行数:" + strconv.Itoa(rowIndex))
		}
		_, exist := projectMap[row[1]]
		if !exist {
			project, err := daoProject.SelectOne(row[1])
			if err != nil {
				return grmi.NewBusinessError("查询车型项目数据失败， error:" + err.Error())
			}
			if project == nil {
				return grmi.NewBusinessError("车型项目不存在, 车型项目ID:" + row[1])
			}
			projectMap[row[1]] = nil
		}
		desc, exist := productMap[row[2]]
		if !exist {
			product, err := daoProduct.SelectOne(row[2], row[1])
			if err != nil {
				return grmi.NewBusinessError("查询产品总成数据失败, error:" + err.Error())
			}
			if product == nil {
				return grmi.NewBusinessError("产品总成不存在, 总成ID:" + row[2])
			}
			productMap[row[2]] = product.Descr
			desc = product.Descr
		}
		_, exist = productFamilyMap[row[0]]
		if !exist {
			productFamily, err := daoProductFamily.SelectOne(row[0])
			if err != nil {
				return grmi.NewBusinessError("查询派生数据失败， error:" + err.Error())
			}
			if productFamily == nil {
				return grmi.NewBusinessError("派生数据不存在, 派生ID:" + row[0])
			}
			productFamilyMap[row[0]] = nil
		}
		count, err := strconv.Atoi(row[3])
		if err != nil {
			return grmi.NewBusinessError("excel数据不合规, 行数:" + strconv.Itoa(rowIndex))
		}
		relate := model.ProductFamilyRelate{
			ProductFamilyId: row[0],
			ProjectId: row[1],
			ProductId: row[2],
			ProductDescr: desc,
			Count: count,
		}
		_, exist = productFamilyRelateMap[row[0]]
		if !exist {
			productFamilyRelateMap[row[0]] = make([]model.ProductFamilyRelate, 0)
		}
		productFamilyRelateMap[row[0]] = append(productFamilyRelateMap[row[0]], relate)
	}
	if err = session.Begin(); err != nil {
		return err
	}
	tempProductFamilyRelateLi := make([]model.ProductFamilyRelate, 0, 20)
	for productFamilyId, relateLi := range productFamilyRelateMap {
		originRelateLi, err := daoProductFamilyRelate.Select([]grmi.Predicate{meta.ProductFamilyRelate_ProductFamilyId.NewPredicate(grmi.Equal, productFamilyId)}, nil)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("查询已存在关联关系失败, error:" + err.Error())
		}
		if len(originRelateLi) != 0 {
			_ = session.Rollback()
			return grmi.NewBusinessError("派生已存在关联关系, 派生ID:" + productFamilyId)
		}
		for index, relate := range relateLi {
			if index != 0 && index % 20 == 0 {
				err = daoProductFamilyRelate.Insert(&tempProductFamilyRelateLi)
				if err != nil {
					_ = session.Rollback()
					return grmi.NewBusinessError("写入关联关系失败, error:" + err.Error())
				}
				tempProductFamilyRelateLi = make([]model.ProductFamilyRelate, 0, 20)
			}
			relate.Pos = index + 1
			tempProductFamilyRelateLi = append(tempProductFamilyRelateLi, relate)
		}
		if len(tempProductFamilyRelateLi) != 0 {
			err = daoProductFamilyRelate.Insert(&tempProductFamilyRelateLi)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("写入关联关系失败, error:" + err.Error())
			}
		}
	}
	_ = session.Commit()
	return nil
}
