pg_confirm_dividends_incentives_estimate_service.go 12.7 KB
package domain_service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	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,
		})
		if err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		if cooperationContract == nil {
			return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("共创合约%s不存在", orderGood.CooperationContractNumber))
		}
		// TODO 校验合约关联的项目是否已结束
		cooperationProject, err := cooperationProjectRepository.FindOne(map[string]interface{}{
			"cooperationProjectNumber": cooperationContract.CooperationProjectNumber,
		})
		if err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		if cooperationProject == nil {
			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 {
				return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "分红订单不存在")
			}
			if dividendsOrder == nil {
				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.Before(dividendsIncentivesRule.DividendsIncentivesStageEnd) {
					dividendsIncentivesRuleMatched = dividendsIncentivesRule
					break
				}
			}
			if dividendsIncentivesRuleMatched == nil {
				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,
					})
					//	添加推荐人分红预算信息详情
					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,
						})
					}
					//	添加关联业务员分红预算信息详情
					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,
						})
					}
				}
			}
		} else if orderGood.DividendsReturnedOrderNumber != "" { // 获取分红退货单
			dividendsReturnedOrder, err3 := dividendsReturnedOrderRepository.FindOne(map[string]interface{}{
				"dividendsReturnedOrderNumber": orderGood.DividendsReturnedOrderNumber,
			})
			if err3 != nil {
				return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "分红退货单不存在")
			}
			if dividendsReturnedOrder == nil {
				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.Before(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,
				})
				//	添加推荐人分红退货预算信息详情
				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,
					})
				}
				//	添加关联业务员分红退货预算信息详情
				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,
					})
				}
			}
		}
	}
	return dividendsEstimateDetails, nil
}

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