package service

import (
	"fmt"

	"github.com/astaxie/beego/logs"

	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/event/subscriber"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/factory"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/command"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/query"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
	domainService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain/service"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/dao"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
	"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
)

//OrderService 自建订单,意向单,实发订单
type OrderInfoService struct {
}

func NewOrderInfoService(option map[string]interface{}) *OrderInfoService {
	newAdminUserService := new(OrderInfoService)
	return newAdminUserService
}

// PageListOrderBase 获取订单列表
func (service OrderInfoService) PageListOrderBase(listOrderQuery query.ListOrderBaseQuery) ([]map[string]interface{}, int, error) {
	var err error
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, 0, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, 0, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderDao *dao.OrderBaseDao
		orders   []models.OrderBase
		cnt      int
	)

	if orderDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	orders, cnt, err = orderDao.OrderListByCondition(
		listOrderQuery.CompanyId,
		listOrderQuery.OrderType,
		listOrderQuery.PartnerOrCode,
		[2]string{listOrderQuery.UpdateTimeBegin, listOrderQuery.UpdateTimeEnd},
		[2]string{listOrderQuery.CreateTimeBegin, listOrderQuery.CreateTimeEnd},
		listOrderQuery.PartnerCategory,
		listOrderQuery.Limit, listOrderQuery.Offset,
	)
	if err != nil {
		return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var PartnerInfoRepository domain.PartnerInfoRepository
	if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}

	orderDataReturn := make([]map[string]interface{}, 0)

	for i := range orders {
		partnerData := &domain.PartnerInfo{}
		partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{
			UserId: orders[i].PartnerId,
		})
		if err != nil {
			//防崩溃
			partnerData = &domain.PartnerInfo{}
			logs.Error("获取合伙(id=%d)失败%s", orders[i].PartnerId, err)
		}
		listIndex := listOrderQuery.Offset + (1 + i)
		m := map[string]interface{}{
			"index":           listIndex,
			"createTime":      orders[i].CreateTime.Local().Format("2006-01-02 15:04:05"),
			"updateTime":      orders[i].UpdateTime.Local().Format("2006-01-02 15:04:05"),
			"buyer":           orders[i].Buyer.BuyerName,
			"id":              fmt.Sprint(orders[i].Id),
			"orderId":         orders[i].OrderCode,
			"shipmentsId":     orders[i].DeliveryCode,
			"partner":         partnerData.Partner.PartnerName,
			"orderNum":        orders[i].PlanOrderCount,
			"orderPrice":      orders[i].PlanOrderAmount,
			"orderDist":       orders[i].RegionInfo.RegionName,
			"quantityControl": "",
			"priceControl":    "",
			"status":          orders[i].IsDisable,
			"partnerCategory": orders[i].PartnerCategory.Name,
		}
		if orders[i].UseOrderCount >= 0 {
			m["quantityControl"] = fmt.Sprint(orders[i].UseOrderCount)
		}
		if orders[i].UseOrderAmount >= 0 {
			m["priceControl"] = fmt.Sprint(orders[i].UseOrderAmount)
		}
		orderDataReturn = append(orderDataReturn, m)
	}
	transactionContext.CommitTransaction()
	return orderDataReturn, cnt, nil
}

//GetOrderDetail 获取订单详情
func (service OrderInfoService) GetOrderDetail(getOrderQuery query.GetOrderQuery) (*domain.OrderBase, error) {
	//实际业务
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	var (
		orderBaseRepository   domain.OrderBaseRepository
		partnerInfoRepository domain.PartnerInfoRepository
		orderGoodRepository   domain.OrderGoodRepository
		order                 *domain.OrderBase
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if partnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	order, err = orderBaseRepository.FindOne(domain.OrderBaseFindOneQuery{
		OrderId:   getOrderQuery.OrderId,
		CompanyId: getOrderQuery.CompanyId,
	})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("获取订单数据失败:%s", err))
	}
	var (
		partnerData *domain.PartnerInfo
		goods       []domain.OrderGood
	)

	partnerData, err = partnerInfoRepository.FindOne(domain.PartnerFindOneQuery{
		UserId:    order.PartnerId,
		CompanyId: getOrderQuery.CompanyId,
	})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("检索合伙人数据失败:%s", err))
	}
	order.PartnerInfo = partnerData.Partner
	goods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{
		OrderId:   order.Id,
		CompanyId: getOrderQuery.CompanyId,
	})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("获取订单中的商品列表失败:%s", err))
	}
	order.Goods = goods
	err = transactionContext.CommitTransaction()
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return order, nil
}

//CreateNewOrder 创建订单
func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (*domain.OrderBase, error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		err                   error
	)

	if err = transactionContext.StartTransaction(); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var PartnerInfoRepository domain.PartnerInfoRepository
	if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var partnerData *domain.PartnerInfo
	partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{UserId: cmd.PartnerId})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("检索合伙人数据失败"))
	}
	var (
		orderBaseRepository domain.OrderBaseRepository
		orderGoodRepository domain.OrderGoodRepository
		orderBaseDao        *dao.OrderBaseDao
	)
	if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	//检查order_code是否重复
	// if ok, err := orderBaseDao.OrderCodeExist(cmd.OrderCode, cmd.PartnerCategory, cmd.PartnerId); err != nil {
	// 	return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	// } else if ok {
	// 	return nil, lib.ThrowError(lib.BUSINESS_ERROR, "订单号已存在")
	// }
	//检查delivery_code是否重复
	if len(cmd.DeliveryCode) > 0 {
		if ok, err := orderBaseDao.DeliveryCodeExist(cmd.DeliveryCode, cmd.CompanyId); err != nil {
			return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
		} else if ok {
			return nil, lib.ThrowError(lib.BUSINESS_ERROR, "发货号已存在")
		}
	}
	newOrder := &domain.OrderBase{
		OrderType: cmd.OrderType, OrderCode: cmd.OrderCode,
		DeliveryCode: cmd.DeliveryCode,
		Buyer: domain.Buyer{
			BuyerName: cmd.BuyerName,
		},
		RegionInfo: domain.RegionInfo{
			RegionName: cmd.OrderRegion,
		},
		PartnerId:            cmd.PartnerId,
		PartnerInfo:          partnerData.Partner,
		SalesmanBonusPercent: cmd.SalesmanBonusPercent,
		CompanyId:            cmd.CompanyId,
	}
	var categoryRepository domain.PartnerCategoryRepository
	if categoryRepository, err = factory.CreatePartnerCategoryRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var cmdPartnerCategoryOk bool
	for _, v := range partnerData.PartnerCategoryInfos {
		if v.Id == cmd.PartnerCategory {
			_, categorys, err := categoryRepository.Find(domain.PartnerCategoryFindQuery{
				Ids: []int64{v.Id},
			})
			if err != nil {
				e := fmt.Sprintf("获取合伙人分类数据失败:%s", err)
				return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
			}
			if len(categorys) > 0 {
				newOrder.PartnerCategory = categorys[0]
				cmdPartnerCategoryOk = true
			}
			break
		}
	}
	if !cmdPartnerCategoryOk {
		return nil, lib.ThrowError(lib.BUSINESS_ERROR, "合伙人类型选择错误")
	}
	var orderGoods []domain.OrderGood
	for _, good := range cmd.Goods {
		m := domain.NewOrderGood()
		m.OrderId = 0
		m.GoodName = good.GoodName
		m.PlanGoodNumber = good.PlanGoodNumber
		m.Price = good.Price
		m.PartnerBonusPercent = good.PartnerBonusPercent
		m.Remark = good.Remark
		m.CompanyId = cmd.CompanyId
		err = m.Compute()
		if err != nil {
			return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中商品的数值失败:%s", err))
		}
		err = m.CurrentBonusStatus.WartPayPartnerBonus(&m)
		if err != nil {
			return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中商品的分红数值失败:%s", err))
		}
		orderGoods = append(orderGoods, m)
	}
	newOrder.Goods = orderGoods
	err = newOrder.Compute()
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中合计的数值失败:%s", err))
	}
	err = orderBaseRepository.Save(newOrder)
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单数据失败:%s", err))
	}
	for i := range newOrder.Goods {
		newOrder.Goods[i].OrderId = newOrder.Id
	}
	err = orderGoodRepository.Save(orderGoods)
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单中的商品数据失败:%s", err))
	}
	newOrder.Goods = orderGoods
	err = transactionContext.CommitTransaction()
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return newOrder, nil
}

//DeleteOrder 删除订单
func (service OrderInfoService) DeleteOrder(orderId int64, companyId int64) error {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		err                   error
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderBaseRepository domain.OrderBaseRepository
		orderGoodRepository domain.OrderGoodRepository
	)
	if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	err = orderBaseRepository.Remove(orderId, companyId)
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("删除订单数据失败:%s", err))
	}
	err = orderGoodRepository.Remove(orderId, companyId)
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("删除订单中商品数据失败:%s", err))
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return nil
}

//UpdateOrderData 编辑订单
func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand) (*domain.OrderBase, error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		err                   error
	)

	if err = transactionContext.StartTransaction(); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var PartnerInfoRepository domain.PartnerInfoRepository
	if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var partnerData *domain.PartnerInfo
	partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{
		UserId: cmd.PartnerId, CompanyId: cmd.CompanyId,
	})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("检索合伙人数据失败"))
	}
	var (
		orderBaseRepository domain.OrderBaseRepository
		orderGoodRepository domain.OrderGoodRepository
		oldOrderData        *domain.OrderBase
		oldOrderGoods       []domain.OrderGood
		newOrderGoods       []domain.OrderGood
		delGoods            []int64
		orderBaseDao        *dao.OrderBaseDao
	)
	if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	//获取旧的订单
	oldOrderData, err = orderBaseRepository.FindOne(domain.OrderBaseFindOneQuery{
		OrderId:   cmd.Id,
		CompanyId: cmd.CompanyId,
	})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("未找到指定的订单:%s", err))
	}
	//判定要求的更新的订单类型
	if oldOrderData.OrderType != cmd.OrderType {
		return nil, lib.ThrowError(lib.BUSINESS_ERROR, fmt.Sprintf("操作失败,待更新的订单的类型已变更"))
	}
	if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	//检查order_code是否重复
	// if oldOrderData.OrderCode != cmd.OrderCode || cmd.PartnerCategory != oldOrderData.PartnerCategory.Id {
	// 	if ok, err := orderBaseDao.OrderCodeExist(cmd.OrderCode, cmd.PartnerCategory, cmd.PartnerId); err != nil {
	// 		return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	// 	} else if ok {
	// 		return nil, lib.ThrowError(lib.BUSINESS_ERROR, "订单号已存在")
	// 	}
	// }
	//检查delivery_code是否重复
	if cmd.DeliveryCode != oldOrderData.DeliveryCode {
		if ok, err := orderBaseDao.DeliveryCodeExist(cmd.DeliveryCode, cmd.CompanyId, cmd.Id); err != nil {
			return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
		} else if ok {
			return nil, lib.ThrowError(lib.BUSINESS_ERROR, "发货号已存在")
		}
	}
	//获取旧的订单中的商品
	oldOrderGoods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{
		OrderId:   cmd.Id,
		CompanyId: cmd.CompanyId,
	})
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("未找到指定的订单中的商品列表失败:%s", err))
	}
	for _, good := range cmd.Goods {
		m := domain.NewOrderGood()
		m.OrderId = oldOrderData.Id
		m.GoodName = good.GoodName
		m.PlanGoodNumber = good.PlanGoodNumber
		m.Price = good.Price
		m.PartnerBonusPercent = good.PartnerBonusPercent
		m.Remark = good.Remark
		m.CompanyId = cmd.CompanyId
		err = m.Compute()
		if err != nil {
			return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中商品的数值失败:%s", err))
		}
		err = m.CurrentBonusStatus.WartPayPartnerBonus(&m)
		if err != nil {
			return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中商品的分红数值失败:%s", err))
		}
		newOrderGoods = append(newOrderGoods, m)
	}
	var cmdPartnerCategoryOk bool
	for _, v := range partnerData.PartnerCategoryInfos {
		if v.Id == cmd.PartnerCategory {
			oldOrderData.PartnerCategory = v
			cmdPartnerCategoryOk = true
		}
	}
	if !cmdPartnerCategoryOk {
		return nil, lib.ThrowError(lib.BUSINESS_ERROR, "合伙人类型选择错误")
	}
	oldOrderData.OrderCode = cmd.OrderCode
	oldOrderData.DeliveryCode = cmd.DeliveryCode
	oldOrderData.Buyer.BuyerName = cmd.BuyerName
	oldOrderData.RegionInfo.RegionName = cmd.OrderRegion
	oldOrderData.PartnerId = cmd.PartnerId
	oldOrderData.PartnerInfo = partnerData.Partner
	oldOrderData.SalesmanBonusPercent = cmd.SalesmanBonusPercent
	oldOrderData.Goods = newOrderGoods
	err = oldOrderData.Compute()
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中合计的数值失败:%s", err))
	}

	err = orderBaseRepository.Save(oldOrderData)
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单数据失败:%s", err))
	}
	err = orderGoodRepository.Save(newOrderGoods)
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单中的商品数据失败:%s", err))
	}
	oldOrderData.Goods = newOrderGoods
	//删不需要的订单总不需要的商品
	delGoods = service.deleteOldOrderGoods(newOrderGoods, oldOrderGoods)
	if len(delGoods) > 0 {
		err = orderGoodRepository.Remove(oldOrderData.Id, cmd.CompanyId, delGoods...)
		if err != nil {
			return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("删除订单中的商品数据失败:%s", err))
		}
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return oldOrderData, nil
}

//deleteOldOrderGoods 新旧商品列表对比
func (service OrderInfoService) deleteOldOrderGoods(newGoods []domain.OrderGood, oldGoods []domain.OrderGood) (goodIds []int64) {
	for _, old := range oldGoods {
		var hasIn bool
		for _, new := range newGoods {
			if old.Id == new.Id {
				hasIn = true
				break
			}
		}
		if !hasIn {
			goodIds = append(goodIds, old.Id)
		}
	}
	return
}

//DisableOrEnable 开启关闭订单
func (service OrderInfoService) DisableOrEnable(cmd command.DisableOrderCommand) error {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		err                   error
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderBaseRepository domain.OrderBaseRepository
		oldOrderData        *domain.OrderBase
	)
	if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	//获取旧的订单
	oldOrderData, err = orderBaseRepository.FindOne(domain.OrderBaseFindOneQuery{
		OrderId:   cmd.OrderId,
		CompanyId: cmd.CompanyId,
	})
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("未找到指定的订单:%s", err))
	}
	if oldOrderData.OrderType != cmd.OrderType {
		return lib.ThrowError(lib.BUSINESS_ERROR, fmt.Sprintf("操作失败,指定的订单的类型发生变更"))
	}
	oldOrderData.IsDisable = cmd.IsDisable
	err = orderBaseRepository.Save(oldOrderData)
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单数据失败:%s", err))
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return nil
}

//PageListOrderBouns 获取订单的分红列表
func (service OrderInfoService) PageListOrderBonus(listOrderQuery query.ListOrderBonusQuery) ([]map[string]interface{}, int, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, 0, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, 0, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		ordersM      []models.OrderBase
		orders       []domain.OrderBase
		cnt          int
		orderBaseDao *dao.OrderBaseDao
	)

	if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, cnt, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	ordersM, cnt, err = orderBaseDao.OrderBonusListByCondition(
		listOrderQuery.CompanyId,
		listOrderQuery.OrderType,
		listOrderQuery.PartnerOrCode,
		listOrderQuery.PartnerCategory,
		[2]string{listOrderQuery.CreateTimeBegin, listOrderQuery.CreateTimeEnd},
		listOrderQuery.Limit,
		listOrderQuery.Offset,
	)
	for _, orderModel := range ordersM {
		order := domain.OrderBase{
			Id: orderModel.Id, OrderType: orderModel.OrderType, OrderCode: orderModel.OrderCode,
			DeliveryCode: orderModel.DeliveryCode, Buyer: orderModel.Buyer, RegionInfo: orderModel.RegionInfo,
			PartnerId: orderModel.PartnerId, SalesmanBonusPercent: orderModel.SalesmanBonusPercent,
			CreateTime: orderModel.CreateTime, DeliveryTime: orderModel.DeliveryTime, UpdateTime: orderModel.UpdateTime,
			IsDisable: orderModel.IsDisable,
			OrderCompute: domain.OrderCompute{
				PlanPartnerBonus: orderModel.PlanPartnerBonus, UsePartnerBonus: orderModel.UsePartnerBonus,
				PartnerBonusHas: orderModel.PartnerBonusHas, PartnerBonusNot: orderModel.PartnerBonusNot,
				PartnerBonusExpense: orderModel.PartnerBonusExpense, SalesmanBonus: orderModel.SalesmanBonus,
				PlanOrderCount: orderModel.PlanOrderCount, PlanOrderAmount: orderModel.PlanOrderAmount,
				UseOrderCount: orderModel.UseOrderCount, UseOrderAmount: orderModel.UseOrderAmount,
			},
			PartnerInfo: domain.Partner{
				Id: orderModel.PartnerId,
			},
			BonusStatus: orderModel.BonusStatus,
			CompanyId:   orderModel.CompanyId,
		}
		orders = append(orders, order)
	}
	var (
		PartnerInfoRepository domain.PartnerInfoRepository
		orderGoodRepository   domain.OrderGoodRepository
	)
	if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var resp = []map[string]interface{}{}
	for i := range orders {
		partnerData := &domain.PartnerInfo{}
		partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{
			UserId: orders[i].PartnerId,
		})
		if err != nil {
			logs.Error("获取合伙(id=%d)失败%s", orders[i].PartnerId, err)
		} else {
			orders[i].PartnerInfo = partnerData.Partner
		}
		var (
			goods           []domain.OrderGood
			hasBonusPercent bool
		)
		goods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{OrderId: orders[i].Id})
		for ii := range goods {
			if goods[ii].PartnerBonusPercent >= 0 {
				hasBonusPercent = true
			}
		}
		listIndex := listOrderQuery.Offset + (1 + i)
		listItem := map[string]interface{}{
			"index":                listIndex,
			"createTime":           orders[i].CreateTime.Local().Format("2006-01-02 15:04:05"),
			"updateTime":           orders[i].UpdateTime.Local().Format("2006-01-02 15:04:05"),
			"id":                   fmt.Sprint(orders[i].Id),
			"shipmentsId":          orders[i].DeliveryCode,
			"partner":              orders[i].PartnerInfo.PartnerName,
			"dividendsReceivable":  fmt.Sprint(orders[i].GetCurrentPartnerBonus()),
			"dividendSpending":     fmt.Sprint(orders[i].OrderCompute.PartnerBonusExpense),
			"receiveDividends":     fmt.Sprint(orders[i].OrderCompute.PartnerBonusHas),
			"uncollectedDividends": fmt.Sprint(orders[i].OrderCompute.PartnerBonusNot),
			"stateOfPayment":       orders[i].BonusStatus,
			"orderType":            orders[i].OrderType,
			"orderTypeName":        domain.GetOrderBaseTypeName(orders[i].OrderType),
			"orderNumber":          orders[i].OrderCode,
		}
		if !hasBonusPercent {
			listItem["receiveDividends"] = "-"
			listItem["dividendsReceivable"] = "-"
			listItem["dividendSpending"] = "-"
			listItem["uncollectedDividends"] = "-"
		}
		resp = append(resp, listItem)
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return resp, cnt, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return resp, cnt, nil
}

//PayPartnerBonusWithOrderBestshop 支付分红
func (service OrderInfoService) PayPartnerBonus(orderId int64, goodId int64, adminId int64) error {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		err                   error
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderBonuSrv domainService.OrderBonusService
	)
	orderBonuSrv, err = factory.CreateOrderBonusService(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	orderBonuSrv.Subscribe(&subscriber.OrderLogSubscriber{
		TransactionContext: transactionContext.(*transaction.TransactionContext),
	})
	err = orderBonuSrv.PayOrderGoodBonus(orderId, goodId, adminId)
	if err != nil {
		return err
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return nil
}

//UpdateOrderRemarkBonus 订单分红详情,更新备注
func (service OrderInfoService) UpdateOrderRemarkBonus(orderId int64, adminId int64, remark string) error {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		err                   error
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderBonuSrv domainService.OrderBonusService
	)
	orderBonuSrv, err = factory.CreateOrderBonusService(map[string]interface{}{
		"transactionContext": transactionContext,
	})
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	orderBonuSrv.Subscribe(&subscriber.OrderLogSubscriber{
		TransactionContext: transactionContext.(*transaction.TransactionContext),
	})
	err = orderBonuSrv.UpdateOrderRemarkBonus(orderId, adminId, remark)
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	return nil
}

func (service OrderInfoService) ListOrderBonusForExcel(listOrderQuery query.ListOrderBonusQuery) ([]map[string]string, [][2]string, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderBaseDao *dao.OrderBaseDao
	)

	if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	result, err := orderBaseDao.OrderBonusListForExcel(
		listOrderQuery.CompanyId,
		listOrderQuery.OrderType,
		listOrderQuery.PartnerOrCode,
		listOrderQuery.PartnerCategory,
	)
	if err != nil {
		return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}

	err = transactionContext.CommitTransaction()
	if err != nil {
		return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var resultMaps []map[string]string
	for i := range result {
		m := map[string]string{
			"num":                   fmt.Sprint(i + 1),
			"order_type":            domain.GetOrderBaseTypeName(result[i].OrderType),
			"order_code":            result[i].OrderCode,
			"delivery_code":         result[i].DeliveryCode,
			"partner_name":          result[i].PartnerName,
			"bonus_status":          "",
			"update_time":           result[i].UpdateTime,
			"create_time":           result[i].CreateTime,
			"partner_bonus":         fmt.Sprintf("%10.2f", result[i].PartnerBonus),
			"partner_bonus_has":     fmt.Sprintf("%10.2f", result[i].PartnerBonusHas),
			"partner_bonus_not":     fmt.Sprintf("%10.2f", result[i].PartnerBonusNot),
			"partner_bonus_expense": fmt.Sprintf("%10.2f", result[i].PartnerBonusExpense),
		}
		if result[i].HasBonusPercent == 0 {
			m["partner_bonus"] = "-"
			m["partner_bonus_has"] = "-"
			m["partner_bonus_not"] = "-"
			m["partner_bonus_expense"] = "-"
		}
		switch result[i].BonusStatus {
		case domain.OrderGoodWaitPay:
			m["bonus_status"] = "等待支付分红"
		case domain.OrderGoodHasPay:
			m["bonus_status"] = "已支付分红"
		}
		resultMaps = append(resultMaps, m)
	}
	column := [][2]string{
		[2]string{"num", "序号"},
		[2]string{"order_type", "订单类型"},
		[2]string{"order_code", "订单号"},
		[2]string{"delivery_code", "发货单号"},
		[2]string{"partner_name", "合伙人"},
		[2]string{"bonus_status", "支付状态"},
		[2]string{"create_time", "创建时间"},
		[2]string{"partner_bonus", "应收分红"},
		[2]string{"partner_bonus_has", "已收分红"},
		[2]string{"partner_bonus_not", "未收分红"},
		[2]string{"partner_bonus_expense", "分红支出"},
	}
	return resultMaps, column, nil
}

func (service OrderInfoService) ListOrderForExcel(listOrderQuery query.ListOrderBaseQuery) ([]map[string]string, [][2]string, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var (
		orderBaseDao *dao.OrderBaseDao
	)

	if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
	}
	ordersData, err := orderBaseDao.OrderListForExcel(
		listOrderQuery.CompanyId,
		listOrderQuery.PartnerOrCode,
		[2]string{listOrderQuery.UpdateTimeBegin, listOrderQuery.UpdateTimeEnd},
		[2]string{listOrderQuery.CreateTimeBegin, listOrderQuery.UpdateTimeEnd},
		listOrderQuery.PartnerCategory,
	)
	if err != nil {
		return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	err = transactionContext.CommitTransaction()
	if err != nil {
		return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
	}
	var resultMaps []map[string]string
	for i := range ordersData {
		m := map[string]string{
			"num":               fmt.Sprint(i + 1),
			"order_code":        ordersData[i].OrderCode,
			"delivery_code":     ordersData[i].DeliveryCode,
			"partner_name":      ordersData[i].PartnerName,
			"update_time":       ordersData[i].UpdateTime,
			"create_time":       ordersData[i].CreateTime,
			"plan_order_count":  fmt.Sprint(ordersData[i].PlanOrderCount),
			"use_order_count":   "",
			"region_name":       fmt.Sprint(ordersData[i].RegionName),
			"plan_order_amount": fmt.Sprintf("%10.2f", ordersData[i].PlanOrderAmount),
			"use_order_amount":  "",
			"partner_category":  ordersData[i].PartnerCategory,
			"buyer_name":        ordersData[i].BuyerName,
		}
		if ordersData[i].UseOrderCount >= 0 {
			m["use_order_count"] = fmt.Sprint(ordersData[i].UseOrderCount)
		}
		if ordersData[i].UseOrderAmount >= 0 {
			m["use_order_amount"] = fmt.Sprintf("%10.2f", ordersData[i].UseOrderAmount)
		}
		resultMaps = append(resultMaps, m)
	}
	column := [][2]string{
		[2]string{"num", "序号"},
		[2]string{"order_code", "订单号"},
		[2]string{"delivery_code", "发货单号"},
		[2]string{"create_time", "创建时间"},
		[2]string{"update_time", "更新时间"},
		[2]string{"plan_order_count", "订单数量"},
		[2]string{"use_order_count", "数量调整"},
		[2]string{"plan_order_amount", "订单金额"},
		[2]string{"use_order_amount", "金额调整"},
		[2]string{"region_name", "订单区域"},
		[2]string{"partner_category", "合伙人类型"},
		[2]string{"buyer_name", "客户"},
		[2]string{"partner_name", "合伙人"},
	}
	return resultMaps, column, nil
}