pg_confirm_dividends_incentives_estimate_service.go 18.9 KB
package domain_service

import (
	"fmt"
	coreDomain "github.com/linmadan/egglib-go/core/domain"
	pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
	"github.com/shopspring/decimal"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/domain/service"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/repository"
)

type ConfirmDividendsIncentivesEstimateService struct {
	coreDomain.BaseEventPublisher
	transactionContext *pgTransaction.TransactionContext
}

// Confirm 确认业绩分红预算
func (domainService *ConfirmDividendsIncentivesEstimateService) Confirm(orderGoods []*domain.OrderGood) ([]*service.DividendsEstimateDetail, error) {
	var cooperationContractRepository domain.CooperationContractRepository       // 共创合约仓储
	var cooperationProjectRepository domain.CooperationProjectRepository         // 共创项目仓储
	var dividendsOrderRepository domain.DividendsOrderRepository                 // 分红订单仓储
	var dividendsReturnedOrderRepository domain.DividendsReturnedOrderRepository // 分红退货单仓储

	// 共创合约仓储初始化
	if repo, err := repository.NewCooperationContractRepository(domainService.transactionContext); err != nil {
		return nil, err
	} else {
		cooperationContractRepository = repo
	}

	// 共创项目仓储初始化
	if repo, err := repository.NewCooperationProjectRepository(domainService.transactionContext); err != nil {
		return nil, err
	} else {
		cooperationProjectRepository = repo
	}

	// 分红订单仓储初始化
	if repo, err := repository.NewDividendsOrderRepository(domainService.transactionContext); err != nil {
		return nil, err
	} else {
		dividendsOrderRepository = repo
	}

	// 分红退货单仓储初始化
	if repo, err := repository.NewDividendsReturnedOrderRepository(domainService.transactionContext); err != nil {
		return nil, err
	} else {
		dividendsReturnedOrderRepository = repo
	}

	// 确认业绩分红预算
	var dividendsEstimateDetails []*service.DividendsEstimateDetail
	for _, orderGood := range orderGoods {
		// 获取合约
		cooperationContract, err := cooperationContractRepository.FindOne(map[string]interface{}{
			"cooperationContractNumber": orderGood.CooperationContractNumber,
			"companyId":                 orderGood.CompanyId,
			"orgId":                     orderGood.OrgId,
		})
		if err != nil {
			dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
				DividendsUser:              nil,
				DividendsParticipateType:   0,
				DividendsStage:             0,
				DividendsAmount:            0,
				OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
				IsSuccessfully:             false,
				Reason:                     "共创合约错误",
			})
			continue
			//return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		if cooperationContract == nil {
			dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
				DividendsUser:              nil,
				DividendsParticipateType:   0,
				DividendsStage:             0,
				DividendsAmount:            0,
				OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
				IsSuccessfully:             false,
				Reason:                     "共创合约" + orderGood.CooperationContractNumber + "不存在",
			})
			continue
			//return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("共创合约%s不存在", orderGood.CooperationContractNumber))
		}

		// 获取共创项目
		cooperationProject, err := cooperationProjectRepository.FindOne(map[string]interface{}{
			"cooperationProjectNumber": cooperationContract.CooperationProjectNumber,
			"companyId":                cooperationContract.Company.CompanyId,
			"orgId":                    cooperationContract.Org.OrgId,
			"notPause":                 true,
		})
		if err != nil {
			dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
				DividendsUser:              nil,
				DividendsParticipateType:   0,
				DividendsStage:             0,
				DividendsAmount:            0,
				OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
				IsSuccessfully:             false,
				Reason:                     "共创项目" + orderGood.CooperationContractNumber + "查询错误",
			})
			continue
			//return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		if cooperationProject == nil {
			dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
				DividendsUser:              nil,
				DividendsParticipateType:   0,
				DividendsStage:             0,
				DividendsAmount:            0,
				OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
				IsSuccessfully:             false,
				Reason:                     "共创项目" + orderGood.CooperationContractNumber + "已结束或不存在",
			})
			continue
			//return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("共创项目%s不存在", cooperationContract.CooperationProjectNumber))
		}

		// 校验合约关联的项目是否已结束
		//if cooperationProject.Status == 2 {
		//	dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
		//		DividendsUser:              nil,
		//		DividendsParticipateType:   0,
		//		DividendsStage:             0,
		//		DividendsAmount:            0,
		//		OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
		//		IsSuccessfully:             false,
		//		Reason:                     "共创项目" + orderGood.CooperationContractNumber + "已结束",
		//	})
		//	continue
		//	//return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("共创项目%s已结束", cooperationContract.CooperationProjectNumber))
		//}

		if orderGood.DividendsOrderNumber != "" { // 获取分红订单
			// 获取分红订单
			dividendsOrder, err2 := dividendsOrderRepository.FindOne(map[string]interface{}{
				"dividendsOrderNumber": orderGood.DividendsOrderNumber,
				"companyId":            orderGood.CompanyId,
				"orgId":                orderGood.OrgId,
			})
			if err2 != nil {
				dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
					DividendsUser:              nil,
					DividendsParticipateType:   0,
					DividendsStage:             0,
					DividendsAmount:            0,
					OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
					IsSuccessfully:             false,
					Reason:                     "分红订单" + orderGood.DividendsOrderNumber + "查询错误",
				})
				continue
				//return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "分红订单不存在")
			}
			if dividendsOrder == nil {
				dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
					DividendsUser:              nil,
					DividendsParticipateType:   0,
					DividendsStage:             0,
					DividendsAmount:            0,
					OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
					IsSuccessfully:             false,
					Reason:                     "分红订单" + orderGood.DividendsOrderNumber + "不存在",
				})
				continue
				//return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("分红订单%s不存在", orderGood.DividendsOrderNumber))
			}

			// 匹配分红规则
			var dividendsIncentivesRuleMatched *domain.DividendsIncentivesRule
			for _, dividendsIncentivesRule := range cooperationContract.DividendsIncentivesRules {
				if (dividendsOrder.OrderTime.After(dividendsIncentivesRule.DividendsIncentivesStageStart) || dividendsOrder.OrderTime.Equal(dividendsIncentivesRule.DividendsIncentivesStageStart)) &&
					(dividendsOrder.OrderTime.Before(dividendsIncentivesRule.DividendsIncentivesStageEnd) || dividendsOrder.OrderTime.Equal(dividendsIncentivesRule.DividendsIncentivesStageEnd)) {
					dividendsIncentivesRuleMatched = dividendsIncentivesRule
					break
				}
			}
			if dividendsIncentivesRuleMatched == nil {
				dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
					DividendsUser:              nil,
					DividendsParticipateType:   0,
					DividendsStage:             0,
					DividendsAmount:            0,
					OrderOrReturnedOrderNumber: orderGood.DividendsOrderNumber,
					IsSuccessfully:             false,
					Reason:                     "未匹配到分红规则",
				})
				continue
				//return nil, application.ThrowError(application.RES_NO_FIND_ERROR, "未匹配到分红规则")
			}

			// 计算分红
			if dividendsIncentivesRuleMatched != nil {
				for _, undertaker := range cooperationContract.Undertakers {
					// 添加承接人分红预算信息详情
					undertakerDividendsAmount, _ := decimal.NewFromFloat(orderGood.OrderGoodAmount).Mul(decimal.NewFromFloat(dividendsIncentivesRuleMatched.DividendsIncentivesPercentage).Div(decimal.NewFromFloat(100))).Float64()
					dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
						DividendsUser: &domain.User{
							UserId:     undertaker.UserId,
							UserBaseId: undertaker.UserBaseId,
							Org:        undertaker.Org,
							Orgs:       undertaker.Orgs,
							Department: undertaker.Department,
							Roles:      undertaker.Roles,
							UserInfo:   undertaker.UserInfo,
							UserType:   undertaker.UserType,
							UserName:   undertaker.UserInfo.UserName,
							UserPhone:  undertaker.UserPhone,
							Status:     undertaker.Status,
							Company:    undertaker.Company,
						},
						DividendsParticipateType:   domain.UNDERTAKER,
						DividendsStage:             dividendsIncentivesRuleMatched.DividendsIncentivesStage,
						DividendsAmount:            undertakerDividendsAmount,
						OrderOrReturnedOrderNumber: dividendsOrder.DividendsOrderNumber,
						IsSuccessfully:             true,
					})
					//	添加推荐人分红预算信息详情
					if undertaker.Referrer != nil {
						referrerDividendsAmount, _ := decimal.NewFromFloat(orderGood.OrderGoodAmount).Mul(decimal.NewFromFloat(dividendsIncentivesRuleMatched.ReferrerPercentage).Div(decimal.NewFromFloat(100))).Float64()
						dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
							DividendsUser: &domain.User{
								UserId:     undertaker.Referrer.UserId,
								UserBaseId: undertaker.Referrer.UserBaseId,
								Org:        undertaker.Referrer.Org,
								Orgs:       undertaker.Referrer.Orgs,
								Department: undertaker.Referrer.Department,
								Roles:      undertaker.Referrer.Roles,
								UserInfo:   undertaker.Referrer.UserInfo,
								UserType:   undertaker.Referrer.UserType,
								UserName:   undertaker.Referrer.UserName,
								UserPhone:  undertaker.Referrer.UserPhone,
								Company:    undertaker.Referrer.Company,
							},
							DividendsParticipateType:   domain.REFERRER,
							DividendsStage:             dividendsIncentivesRuleMatched.DividendsIncentivesStage,
							DividendsAmount:            referrerDividendsAmount,
							OrderOrReturnedOrderNumber: dividendsOrder.DividendsOrderNumber,
							IsSuccessfully:             true,
						})
					}
					//	添加关联业务员分红预算信息详情
					if undertaker.Salesman != nil {
						salesmanDividendsAmount, _ := decimal.NewFromFloat(orderGood.OrderGoodAmount).Mul(decimal.NewFromFloat(dividendsIncentivesRuleMatched.SalesmanPercentage).Div(decimal.NewFromFloat(100))).Float64()
						dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
							DividendsUser: &domain.User{
								UserId:     undertaker.Salesman.UserId,
								UserBaseId: undertaker.Salesman.UserBaseId,
								Org:        undertaker.Salesman.Org,
								Orgs:       undertaker.Salesman.Orgs,
								Department: undertaker.Salesman.Department,
								Roles:      undertaker.Salesman.Roles,
								UserInfo:   undertaker.Salesman.UserInfo,
								UserType:   undertaker.Salesman.UserType,
								UserName:   undertaker.Salesman.UserInfo.UserName,
								UserPhone:  undertaker.Salesman.UserPhone,
								Company:    undertaker.Salesman.Company,
							},
							DividendsParticipateType:   domain.SALESMAN,
							DividendsStage:             dividendsIncentivesRuleMatched.DividendsIncentivesStage,
							DividendsAmount:            salesmanDividendsAmount,
							OrderOrReturnedOrderNumber: dividendsOrder.DividendsOrderNumber,
							IsSuccessfully:             true,
						})
					}
				}
			}
		} else if orderGood.DividendsReturnedOrderNumber != "" { // 获取退货单
			dividendsReturnedOrder, err3 := dividendsReturnedOrderRepository.FindOne(map[string]interface{}{
				"dividendsReturnedOrderNumber": orderGood.DividendsReturnedOrderNumber,
				"companyId":                    orderGood.CompanyId,
				"orgId":                        orderGood.OrgId,
			})
			if err3 != nil {
				dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
					DividendsUser:              nil,
					DividendsParticipateType:   0,
					DividendsStage:             0,
					DividendsAmount:            0,
					OrderOrReturnedOrderNumber: orderGood.DividendsReturnedOrderNumber,
					IsSuccessfully:             false,
					Reason:                     "退货单" + orderGood.DividendsReturnedOrderNumber + "不存在",
				})
				continue
				//return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "分红退货单不存在")
			}
			if dividendsReturnedOrder == nil {
				dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
					DividendsUser:              nil,
					DividendsParticipateType:   0,
					DividendsStage:             0,
					DividendsAmount:            0,
					OrderOrReturnedOrderNumber: orderGood.DividendsReturnedOrderNumber,
					IsSuccessfully:             false,
					Reason:                     "退货单" + orderGood.DividendsReturnedOrderNumber + "不存在",
				})
				continue
				//return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", orderGood.DividendsReturnedOrderNumber))
			}
			// 匹配分红规则
			var dividendsIncentivesRuleMatched *domain.DividendsIncentivesRule
			for _, dividendsIncentivesRule := range cooperationContract.DividendsIncentivesRules {
				if (dividendsReturnedOrder.OrderTime.After(dividendsIncentivesRule.DividendsIncentivesStageStart) || dividendsReturnedOrder.OrderTime.Equal(dividendsIncentivesRule.DividendsIncentivesStageStart)) &&
					(dividendsReturnedOrder.OrderTime.Before(dividendsIncentivesRule.DividendsIncentivesStageEnd) || dividendsReturnedOrder.OrderTime.Equal(dividendsIncentivesRule.DividendsIncentivesStageEnd)) {
					dividendsIncentivesRuleMatched = dividendsIncentivesRule
					break
				}
			}
			//	计算分红
			for _, undertaker := range cooperationContract.Undertakers {
				// 添加承接人分红退货预算信息详情
				undertakerDividendsAmount, _ := decimal.NewFromFloat(orderGood.OrderGoodAmount).Mul(decimal.NewFromFloat(dividendsIncentivesRuleMatched.DividendsIncentivesPercentage).Div(decimal.NewFromFloat(100))).Float64()
				dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
					DividendsUser: &domain.User{
						UserId:     undertaker.UserId,
						UserBaseId: undertaker.UserBaseId,
						Org:        undertaker.Org,
						Orgs:       undertaker.Orgs,
						Department: undertaker.Department,
						Roles:      undertaker.Roles,
						UserInfo:   undertaker.UserInfo,
						UserType:   undertaker.UserType,
						UserName:   undertaker.UserInfo.UserName,
						UserPhone:  undertaker.UserPhone,
						Status:     undertaker.Status,
						Company:    undertaker.Company,
					},
					DividendsParticipateType:   domain.UNDERTAKER,
					DividendsStage:             dividendsIncentivesRuleMatched.DividendsIncentivesStage,
					DividendsAmount:            -undertakerDividendsAmount,
					OrderOrReturnedOrderNumber: dividendsReturnedOrder.DividendsOrderNumber,
					IsSuccessfully:             true,
				})
				//	添加推荐人分红退货预算信息详情
				if undertaker.Referrer != nil {
					referrerDividendsAmount, _ := decimal.NewFromFloat(orderGood.OrderGoodAmount).Mul(decimal.NewFromFloat(dividendsIncentivesRuleMatched.ReferrerPercentage).Div(decimal.NewFromFloat(100))).Float64()
					dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
						DividendsUser: &domain.User{
							UserId:     undertaker.Referrer.UserId,
							UserBaseId: undertaker.Referrer.UserBaseId,
							Org:        undertaker.Referrer.Org,
							Orgs:       undertaker.Referrer.Orgs,
							Department: undertaker.Referrer.Department,
							Roles:      undertaker.Referrer.Roles,
							UserInfo:   undertaker.Referrer.UserInfo,
							UserType:   undertaker.Referrer.UserType,
							UserName:   undertaker.Referrer.UserInfo.UserName,
							UserPhone:  undertaker.Referrer.UserPhone,
							Company:    undertaker.Referrer.Company,
						},
						DividendsParticipateType:   domain.REFERRER,
						DividendsStage:             dividendsIncentivesRuleMatched.DividendsIncentivesStage,
						DividendsAmount:            -referrerDividendsAmount,
						OrderOrReturnedOrderNumber: dividendsReturnedOrder.DividendsOrderNumber,
						IsSuccessfully:             true,
					})
				}
				//	添加关联业务员分红退货预算信息详情
				if undertaker.Salesman != nil {
					salesmanDividendsAmount, _ := decimal.NewFromFloat(orderGood.OrderGoodAmount).Mul(decimal.NewFromFloat(dividendsIncentivesRuleMatched.SalesmanPercentage).Div(decimal.NewFromFloat(100))).Float64()
					dividendsEstimateDetails = append(dividendsEstimateDetails, &service.DividendsEstimateDetail{
						DividendsUser: &domain.User{
							UserId:     undertaker.Salesman.UserId,
							UserBaseId: undertaker.Salesman.UserBaseId,
							Org:        undertaker.Salesman.Org,
							Orgs:       undertaker.Salesman.Orgs,
							Department: undertaker.Salesman.Department,
							Roles:      undertaker.Salesman.Roles,
							UserInfo:   undertaker.Salesman.UserInfo,
							UserType:   undertaker.Salesman.UserType,
							UserName:   undertaker.Salesman.UserInfo.UserName,
							UserPhone:  undertaker.Salesman.UserPhone,
							Company:    undertaker.Salesman.Company,
						},
						DividendsParticipateType:   domain.SALESMAN,
						DividendsStage:             dividendsIncentivesRuleMatched.DividendsIncentivesStage,
						DividendsAmount:            -salesmanDividendsAmount,
						OrderOrReturnedOrderNumber: dividendsReturnedOrder.DividendsOrderNumber,
						IsSuccessfully:             true,
					})
				}
			}
		}
	}
	return dividendsEstimateDetails, nil
}

func NewConfirmDividendsIncentivesEstimateService(transactionContext *pgTransaction.TransactionContext) (*ConfirmDividendsIncentivesEstimateService, error) {
	if transactionContext == nil {
		return nil, fmt.Errorf("transactionContext参数不能为空")
	} else {
		return &ConfirmDividendsIncentivesEstimateService{
			transactionContext: transactionContext,
		}, nil
	}
}