From cc7c2094568ea8f9d1697da5ed0a2c759ca81abd Mon Sep 17 00:00:00 2001
From: yinbentan <yinbentan@live.com>
Date: 星期五, 30 八月 2024 17:18:30 +0800
Subject: [PATCH] 方法修改,修改薪资列表,添加分页查询

---
 service/salary_plan.go |  629 +++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 453 insertions(+), 176 deletions(-)

diff --git a/service/salary_plan.go b/service/salary_plan.go
index df0f491..5c6c3b1 100644
--- a/service/salary_plan.go
+++ b/service/salary_plan.go
@@ -5,24 +5,23 @@
 	"fmt"
 	"github.com/shopspring/decimal"
 	"gorm.io/gorm"
+	"regexp"
 	"silkserver/constvar"
 	"silkserver/models"
+	"silkserver/pkg/logx"
+	"silkserver/utils"
+	"silkserver/utils/calculator"
 	"strconv"
 	"strings"
+	"time"
 )
-
-type WeaversAmount struct {
-	WorkerID string          `json:"workerID"`
-	Amount   decimal.Decimal `json:"amount"`
-}
-
-// 钖祫璁$畻
-// 绾ゅ害鐧昏锛歴ilk_fineness_register	silk_fineness_register_item
-// 绾ゅ害妫�楠岋細silk_fineness_check	silk_fineness_check_item
-// 浜ч噺鐧昏鐧昏锛歴ilk_yield_register_circle
 
 // WorkingHours 瀛樿〃锛氬伐鏃惰绠楋紙鏃ユ湡锛堝勾鏈堟棩锛夈�佸伐绉嶃�佸憳宸ュ鍚嶃�佸皬缁勩�佽溅鍙般�佷骇閲忓伐璧勩�佷笂鐝秴鏃讹紙灏忔椂锛夈�佷笂鐝秴鏃讹紙澶╋級銆佸姞鐝紙鍗曠嫭锛夈�佸姞鐝紙鍏ㄨ溅闂达級銆佸嚭鍕わ紙澶╋級銆佸甫寰掞紙澶╋級銆佷骇閲忥紙KG锛夈�佸叾瀹冿級
 func WorkingHours(date string) error {
+	dateTime, err := time.Parse("2006-01-02", date)
+	if err != nil {
+		return err
+	}
 	// 浜哄憳淇℃伅
 	workers, err := models.NewWorkerSearch().FindNotTotal()
 	if err != nil {
@@ -32,9 +31,18 @@
 	// 鎺掔彮淇℃伅(鍔熻兘缂哄け)
 	// 鎵撳崱淇℃伅锛堥�氳繃浜哄憳鍏宠仈锛�
 	attendances, err := models.NewAttendanceManageSearch().SetDate(date).FindNotTotal()
+	if err != nil {
+		return err
+	}
+	if len(attendances) == 0 {
+		return errors.New(date + ":鎵撳崱淇℃伅涓虹┖")
+	}
 
 	// 杞﹀彴淇℃伅锛堥�氳繃浜哄憳鍏宠仈锛�
 	workerPositions, err := models.NewWorkerPositionSearch().SetOverlappingDate(date, date).FindAll()
+	if err != nil {
+		return err
+	}
 
 	list := make([]*models.PayrollWorkingHours, 0)
 	for _, worker := range workers {
@@ -57,8 +65,13 @@
 				}
 				workingHours.ShiftClockInTime = attendance.StartWorkTime
 				workingHours.ShiftClockOutTime = attendance.EndWorkTime
-				workingHours.OvertimeType = constvar.ShiftOvertimeTypeTimeout
-				workingHours.OvertimeDuration = attendance.OverTimeDuration
+				if dateTime.Weekday() == 0 {
+					workingHours.OvertimeType = constvar.ShiftOvertimeTypeOvertime
+					workingHours.OvertimeDuration = decimal.NewFromInt32(1)
+				} else {
+					workingHours.OvertimeType = constvar.ShiftOvertimeTypeTimeout
+					workingHours.OvertimeDuration = attendance.OverTimeDuration
+				}
 			}
 		}
 		for _, position := range workerPositions {
@@ -77,10 +90,15 @@
 	}
 
 	err = models.WithTransaction(func(db *gorm.DB) error {
-
-		models.NewPayrollWorkingHoursSearch().SetOrm(db).SetCycle(date).Delete()
-
-		models.NewPayrollWorkingHoursSearch().SetOrm(db).CreateBatch(list)
+		if len(list) == 0 {
+			return nil
+		}
+		if err := models.NewPayrollWorkingHoursSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
+			return err
+		}
+		if err := models.NewPayrollWorkingHoursSearch().SetOrm(db).CreateBatch(list); err != nil {
+			return err
+		}
 		return nil
 	})
 
@@ -93,10 +111,18 @@
 	if err != nil {
 		return err
 	}
+	if len(yieldRegisters) == 0 {
+		return errors.New(date + ":浜ч噺鐧昏涓虹┖")
+	}
+
 	finenesss, err := models.NewFinenessRegisterSearch().SetFinishDate(date).FindAll() // 绾ゅ害鐧昏
 	if err != nil {
 		return err
 	}
+	if len(finenesss) == 0 {
+		return errors.New(date + ":绾ゅ害鐧昏涓虹┖")
+	}
+
 	finenessIds := make([]uint, len(finenesss))
 	for i, fineness := range finenesss {
 		finenessIds[i] = fineness.ID
@@ -106,8 +132,15 @@
 		return err
 	}
 
-	priceStandards, _ := models.NewRawSilkPriceStandardSearch().FindNotTotal() // 鐢熶笣瀹氫环
-	priceStandardMap := make(map[string]decimal.Decimal)                       // map[搴勫彛\鏍囧彿]瀹氫环
+	priceStandards, err := models.NewRawSilkPriceStandardSearch().FindNotTotal() // 鐢熶笣瀹氫环
+	if err != nil {
+		return err
+	}
+	if len(priceStandards) == 0 {
+		return errors.New(date + ":鐢熶笣瀹氫环涓虹┖")
+	}
+
+	priceStandardMap := make(map[string]decimal.Decimal) // map[搴勫彛\鏍囧彿]瀹氫环
 	for _, price := range priceStandards {
 		key := fmt.Sprintf("%d%s", price.MarketNumber, price.RawSilkGrade)
 		priceStandardMap[key] = price.PayStandard
@@ -117,28 +150,58 @@
 	if err != nil {
 		return err
 	}
+	if len(workingHours) == 0 {
+		return errors.New(date + ":鎸¤溅宸ユ墦鍗′俊鎭负绌�")
+	}
 
 	// 杞﹀彴鎸¤溅宸ラ噸澶嶄汉鍛樻爣璁�
-	carEmployeeMap := make(map[string]map[string]bool) // map[杞﹂棿\缁勫埆\杞﹀彿]map[浜哄憳]true
-	for _, yield := range yieldRegisters {
+	carEmployeeMap := make(map[string]map[string]bool) // map[杞﹂棿\缁勫埆\杞﹀彿]map[浜哄憳ID]true
+	// 鏂规1 鏍规嵁鎵撳崱鍛樺伐鏉ユ煡浜烘暟
+	workingHourArr := make([]models.PayrollWorkingHours, 0)
+	for _, workingHour := range workingHours {
+		for i := workingHour.StartCarNumber; i <= workingHour.EndCarNumber; i++ {
+			workingHourArr = append(workingHourArr, models.PayrollWorkingHours{
+				Cycle:          workingHour.Cycle,
+				WorkTypeID:     workingHour.WorkTypeID,
+				WorkTypeCode:   workingHour.WorkTypeCode,
+				WorkerID:       workingHour.WorkerID,
+				WorkshopId:     workingHour.WorkshopId,
+				WorkshopNumber: workingHour.WorkshopNumber,
+				GroupNumber:    workingHour.GroupNumber,
+				StartCarNumber: i,
+			})
+		}
+	}
+	for _, workingHour := range workingHourArr {
+		key := fmt.Sprintf("%v%v%v", workingHour.WorkshopNumber, workingHour.GroupNumber, workingHour.StartCarNumber)
+		if temp, ok := carEmployeeMap[key]; ok {
+			temp[workingHour.WorkerID] = true
+			carEmployeeMap[key] = temp
+		} else {
+			carEmployeeMap[key] = map[string]bool{workingHour.WorkerID: true}
+		}
+
+	}
+
+	// 鏂规2 鏍规嵁绾ゅ害鐧昏鏉ユ煡浜烘暟
+	/*	for _, yield := range yieldRegisters {
 		for _, workingHour := range workingHours {
 			if yield.WorkshopNumber == workingHour.WorkshopNumber && yield.GroupNumber == workingHour.GroupNumber {
 				for _, circle := range yield.Circles {
 					if circle.CarNumber >= workingHour.StartCarNumber && circle.CarNumber <= workingHour.EndCarNumber {
 						key := fmt.Sprintf("%v%v%v", workingHour.WorkshopNumber, workingHour.GroupNumber, circle.CarNumber)
-						tempMap := carEmployeeMap[key]
-						tempMap[workingHour.WorkerID] = true
-						carEmployeeMap[key] = tempMap
+						carEmployeeMap[key][workingHour.WorkerID] = true
 					}
 				}
 			}
 		}
-	}
+	}*/
 
 	productionCar := make([]*models.PayrollProductionCar, 0)
 	for _, yield := range yieldRegisters {
 		info := models.PayrollProductionCar{
 			Cycle:             date,
+			WorkshopId:        yield.WorkshopId,
 			WorkshopNumber:    yield.WorkshopNumber,
 			GroupNumber:       yield.GroupNumber,
 			MarketId:          yield.MarketId,
@@ -175,14 +238,9 @@
 		// 閲庣氦缁熻
 		badSilkQuantityMap := make(map[int]map[string]int) // map[杞﹀彿]map[绾ゅ害绛夌骇]鏁伴噺
 		for _, check := range finenessChecks {
-			if yield.MarketId == check.FinenessRegister.MarketId &&
-				yield.WorkshopNumber == check.FinenessRegister.WorkshopNumber &&
-				yield.GroupNumber == check.FinenessRegister.WorkshopGroup {
-
+			if yield.MarketId == check.FinenessRegister.MarketId && yield.WorkshopNumber == check.FinenessRegister.WorkshopNumber && yield.GroupNumber == check.FinenessRegister.WorkshopGroup {
 				if strings.Contains(check.FinenessGrade, "閲�") {
-					temp := badSilkQuantityMap[check.FinenessRegister.Position]
-					temp[check.FinenessGrade] = temp[check.FinenessGrade] + 1
-					badSilkQuantityMap[check.FinenessRegister.Position] = temp
+					badSilkQuantityMap[check.FinenessRegister.Position][check.FinenessGrade] += 1
 				}
 			}
 		}
@@ -195,23 +253,23 @@
 			if workIdMap, ok := carEmployeeMap[key]; ok {
 				result.CarWorkQuantity = len(workIdMap)
 				for workId := range workIdMap {
-					result.CarWorkIds += workId + ","
+					result.CarWorkIds += fmt.Sprintf("%v,", workId)
 				}
 			}
 			// 閲庣氦
-			if bad, ok := badSilkQuantityMap[carNumber]; ok {
+			if badSilk, ok := badSilkQuantityMap[carNumber]; ok {
 				quantityTmp := 0
 				totalAmount := decimal.NewFromInt32(0)
-				for s := range bad {
-					quantityTmp = quantityTmp + bad[s]
+				for finenessGrade := range badSilk {
+					quantityTmp += badSilk[finenessGrade]
 					for _, price := range priceStandards {
-						if price.MarketId == result.MarketId && price.RawSilkGrade == s {
+						if price.MarketId == result.MarketId && price.RawSilkGrade == finenessGrade {
 							result.BadSilkUnitAmount = price.PayStandard
-							totalAmount = totalAmount.Add(result.BadSilkUnitAmount.Mul(decimal.NewFromInt32(int32(bad[s]))))
+							totalAmount = totalAmount.Add(result.BadSilkUnitAmount.Mul(decimal.NewFromInt32(int32(badSilk[finenessGrade]))))
 							continue
 						}
 					}
-					result.BadSilkType += s + ","
+					result.BadSilkType += fmt.Sprintf("%v,", finenessGrade)
 				}
 
 				result.BadSilkQuantity = decimal.NewFromInt32(int32(quantityTmp))
@@ -230,12 +288,13 @@
 
 	}
 	err = models.WithTransaction(func(db *gorm.DB) error {
-		err := models.NewPayrollProductionCarSearch().SetOrm(db).SetCycle(date).Delete()
-		if err != nil {
+		if len(productionCar) == 0 {
+			return nil
+		}
+		if err := models.NewPayrollProductionCarSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
 			return err
 		}
-		err = models.NewPayrollProductionCarSearch().SetOrm(db).CreateBatch(productionCar)
-		if err != nil {
+		if err = models.NewPayrollProductionCarSearch().SetOrm(db).CreateBatch(productionCar); err != nil {
 			return err
 		}
 		return nil
@@ -254,39 +313,59 @@
 	if err != nil {
 		return err
 	}
+	if len(productionCars) == 0 {
+		errors.New(date + ":杞﹀彴姣忓ぉ鐨勪骇閲忕粺璁′负绌�")
+	}
+
+	workingHours, err := models.NewPayrollWorkingHoursSearch().SetWorkTypeCode(constvar.JobTypeWeavers).SetCycle(date).FindNotTotal() // 鍛樺伐鐨勫伐鏃剁粺璁�
+	if err != nil {
+		return err
+	}
+	if len(workingHours) == 0 {
+		return errors.New(date + ":鎸¤溅宸ユ墦鍗′俊鎭负绌�")
+	}
+
+	groupWorkingHourMap := make(map[string]map[string]bool)
+	for _, workingHour := range workingHours {
+		key := fmt.Sprintf("%v%v", workingHour.WorkshopNumber, workingHour.GroupNumber)
+		if temp, ok := groupWorkingHourMap[key]; ok {
+			temp[workingHour.WorkerID] = true
+			groupWorkingHourMap[key] = temp
+		} else {
+			groupWorkingHourMap[key] = map[string]bool{workingHour.WorkerID: true}
+		}
+	}
 
 	productionGroupList := make([]*models.PayrollProductionGroup, 0)
-	var counter int
 	for i := 0; i < len(productionCars); i++ {
-		counter = 0
-		silkQuantity := decimal.NewFromInt32(0)
-		silkAvgQuantity := decimal.NewFromInt32(0)
-		silkTotalAmount := decimal.NewFromInt32(0)
-		silkTotalAvgAmount := decimal.NewFromInt32(0)
-		badSilkQuantity := decimal.NewFromInt32(0)
-		badSilkTotalAmount := decimal.NewFromInt32(0)
-		badSilkTotalAvgAmount := decimal.NewFromInt32(0)
-		finishTotalAmount := decimal.NewFromInt32(0)
-		finishTotalAvgAmount := decimal.NewFromInt32(0)
-		fallingSilkBucket := decimal.NewFromInt32(0)
+		group := models.PayrollProductionGroup{
+			Cycle:          date,
+			WorkshopId:     productionCars[i].WorkshopId,
+			WorkshopNumber: productionCars[i].WorkshopNumber,
+			GroupNumber:    productionCars[i].GroupNumber,
+		}
 
 		for j := i; j < len(productionCars); j++ {
 			if productionCars[i].WorkshopNumber == productionCars[j].WorkshopNumber &&
 				productionCars[i].GroupNumber == productionGroupList[j].GroupNumber {
+				counter := 1
+				key := fmt.Sprintf("%v%v", productionGroupList[j].WorkshopNumber, productionGroupList[j].GroupNumber)
+				if le := len(groupWorkingHourMap[key]); le > 0 {
+					counter = le
+				}
 				// 涓�杞﹀浜猴紝绠楀钩鍧�
-				//population := decimal.NewFromInt32(int32(productionCars[j].CarWorkQuantity))
-				silkQuantity = silkQuantity.Add(productionCars[j].SilkQuantity)
-				silkAvgQuantity = silkAvgQuantity.Add(productionCars[j].SilkAvgQuantity)
-				silkTotalAmount = silkTotalAmount.Add(productionCars[j].SilkTotalAmount)
-				silkTotalAvgAmount = silkTotalAvgAmount.Add(productionCars[j].SilkTotalAvgAmount)
-				badSilkQuantity = badSilkQuantity.Add(productionCars[j].BadSilkQuantity)
-				badSilkTotalAmount = badSilkTotalAmount.Add(productionCars[j].BadSilkTotalAmount)
-				badSilkTotalAvgAmount = badSilkTotalAvgAmount.Add(productionCars[j].BadSilkTotalAvgAmount)
-				finishTotalAmount = finishTotalAmount.Add(productionCars[j].FinishTotalAmount)
-				finishTotalAvgAmount = finishTotalAvgAmount.Add(productionCars[j].FinishTotalAvgAmount)
-				fallingSilkBucket = fallingSilkBucket.Add(productionCars[j].FallingSilkBucket)
+				counterD := decimal.NewFromInt32(int32(counter))
+				group.SilkQuantity = group.SilkQuantity.Add(productionCars[j].SilkQuantity)
+				group.SilkAvgQuantity = group.SilkAvgQuantity.Add(productionCars[j].SilkAvgQuantity).Div(counterD)
+				group.SilkTotalAmount = group.SilkTotalAmount.Add(productionCars[j].SilkTotalAmount)
+				group.SilkTotalAvgAmount = group.SilkTotalAvgAmount.Add(productionCars[j].SilkTotalAvgAmount).Div(counterD)
+				group.BadSilkQuantity = group.BadSilkQuantity.Add(productionCars[j].BadSilkQuantity)
+				group.BadSilkTotalAmount = group.BadSilkTotalAmount.Add(productionCars[j].BadSilkTotalAmount)
+				group.BadSilkTotalAvgAmount = group.BadSilkTotalAvgAmount.Add(productionCars[j].BadSilkTotalAvgAmount).Div(counterD)
+				group.FinishTotalAmount = group.FinishTotalAmount.Add(productionCars[j].FinishTotalAmount)
+				group.FinishTotalAvgAmount = group.FinishTotalAvgAmount.Add(productionCars[j].FinishTotalAvgAmount).Div(counterD)
+				group.FallingSilkBucket = group.FallingSilkBucket.Add(productionCars[j].FallingSilkBucket)
 
-				counter += 1
 				// 璺宠繃閲嶅椤�
 				if i != j {
 					i += 1
@@ -294,31 +373,17 @@
 			}
 
 		}
-		counterD := decimal.NewFromInt32(int32(counter))
-		productionGroupList = append(productionGroupList, &models.PayrollProductionGroup{
-			Cycle:                 date,
-			WorkshopNumber:        productionCars[i].WorkshopNumber,
-			GroupNumber:           productionCars[i].GroupNumber,
-			FallingSilkBucket:     fallingSilkBucket,
-			SilkQuantity:          silkQuantity,
-			SilkAvgQuantity:       silkAvgQuantity.Div(counterD),
-			SilkTotalAmount:       silkTotalAmount,
-			SilkTotalAvgAmount:    silkTotalAmount.Div(counterD),
-			BadSilkQuantity:       badSilkQuantity,
-			BadSilkTotalAmount:    badSilkTotalAmount,
-			BadSilkTotalAvgAmount: badSilkTotalAmount.Div(counterD),
-			FinishTotalAmount:     finishTotalAmount,
-			FinishTotalAvgAmount:  finishTotalAmount.Div(counterD),
-		})
+		productionGroupList = append(productionGroupList, &group)
 	}
 
 	err = models.WithTransaction(func(db *gorm.DB) error {
-		err := models.NewPayrollProductionGroupSearch().SetOrm(db).SetCycle(date).Delete()
-		if err != nil {
+		if len(productionGroupList) == 0 {
+			return nil
+		}
+		if err := models.NewPayrollProductionGroupSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
 			return err
 		}
-		err = models.NewPayrollProductionGroupSearch().SetOrm(db).CreateBatch(productionGroupList)
-		if err != nil {
+		if err = models.NewPayrollProductionGroupSearch().SetOrm(db).CreateBatch(productionGroupList); err != nil {
 			return err
 		}
 		return nil
@@ -330,27 +395,22 @@
 	return nil
 }
 
-// 鏍规嵁涓婃姤璁$畻锛�
-//	1銆佽溅鍙板綋鏈堝叏绛夌骇涓濇�婚噺锛�
-//	2銆佽溅鍙板綋鏈堝悇绛夌骇涓濇�婚噺锛�
-//	3銆佽溅鍙版瘡鏈堢瓑绾у崰姣�=杞﹀彴褰撴湀鍚勭瓑绾т笣鎬婚噺/杞﹀彴褰撴湀鍏ㄧ瓑绾т笣鎬婚噺锛�
-//	4銆佽溅鍙版瘡鏈堟瘡浜哄钩鍧囦笣閲�=杞﹀彴褰撴湀鍏ㄧ瓑绾т笣鎬婚噺/杞﹀彴鎸¤溅宸ヤ汉鏁帮紱
-//	5銆佽溅鍙板綋鏈堝叏閲庣氦鎵i櫎閲戦锛�
-//	6銆佽溅鍙版瘡鏈堟瘡浜哄钩鍧囬噹绾ゆ墸闄ら噾棰�=褰撴湀鍏ㄩ噹绾ゆ墸闄ら噾棰�/杞﹀彴鎸¤溅宸ヤ汉鏁帮紱
-//	7銆佽溅鍙版瘡鏈堜笣閲忔�婚噾棰�
-//	8銆佽溅鍙版瘡鏈堜笣閲忔垚鍝侀噾棰�
-//	9銆佽溅鍙版瘡鏈堟瘡浜哄钩鍧囦笣閲忛噾棰�=杞﹀彴姣忔湀涓濋噺鎴愬搧閲戦/杞﹀彴鎸¤溅宸ヤ汉鏁�
-
-// ProductionEmployee 瀛樿〃锛� 姣忎汉姣忓ぉ鐨勪骇閲忕粺璁$櫥璁�
+// ProductionWeavers 瀛樿〃锛� 鎸¤溅宸ユ瘡浜烘瘡澶╃殑浜ч噺缁熻鐧昏
 func ProductionWeavers(date string) error {
 	workingHours, err := models.NewPayrollWorkingHoursSearch().SetWorkTypeCode(constvar.JobTypeWeavers).SetCycle(date).FindNotTotal() // 鍛樺伐鐨勫伐鏃剁粺璁�
 	if err != nil {
 		return err
 	}
+	if len(workingHours) == 0 {
+		return errors.New(date + ":鎸¤溅宸ユ墦鍗′俊鎭负绌�")
+	}
 
 	productionCars, err := models.NewPayrollProductionCarSearch().SetCycle(date).FindNotTotal()
 	if err != nil {
 		return err
+	}
+	if len(productionCars) == 0 {
+		return errors.New(date + ":杞﹀彴姣忓ぉ浜ч噺缁熻涓虹┖")
 	}
 
 	productionEmployee := make([]*models.PayrollProductionWeavers, 0)
@@ -359,6 +419,7 @@
 			Cycle:          date,
 			WorkTypeID:     worker.WorkTypeID,
 			WorkerID:       worker.WorkerID,
+			WorkshopId:     worker.WorkshopId,
 			WorkshopNumber: worker.WorkshopNumber,
 			GroupNumber:    worker.GroupNumber,
 		}
@@ -373,16 +434,20 @@
 				info.FinishTotalAmount = info.FinishTotalAmount.Add(car.FinishTotalAvgAmount)
 			}
 		}
+		if info.SilkQuantity.IsZero() {
+			continue
+		}
 		productionEmployee = append(productionEmployee, &info)
 	}
 
 	err = models.WithTransaction(func(db *gorm.DB) error {
-		err := models.NewPayrollProductionWeaversSearch().SetOrm(db).SetCycle(date).Delete()
-		if err != nil {
+		if len(productionEmployee) == 0 {
+			return nil
+		}
+		if err := models.NewPayrollProductionWeaversSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
 			return err
 		}
-		err = models.NewPayrollProductionWeaversSearch().SetOrm(db).CreateBatch(productionEmployee)
-		if err != nil {
+		if err = models.NewPayrollProductionWeaversSearch().SetOrm(db).CreateBatch(productionEmployee); err != nil {
 			return err
 		}
 		return nil
@@ -391,23 +456,27 @@
 	return nil
 }
 
-// 瀛樿〃锛氬伐璧勮绠楋紙鏃ユ湡锛堝勾鏈堬級銆佸伐绉嶃�佸憳宸ュ鍚嶃�佸皬缁勩�佽溅鍙般�佺敓浜у伐璧勩�佹弧鍕ゅ锛�=閰嶇疆锛夈�佽秴鏃跺伐璧勶紙=涓婄彮瓒呮椂灏忔椂*5+涓婄彮瓒呮椂澶�*6锛夈�佸姞鐝伐璧勶紙=鍗曠嫭鍔犵彮*80+鍏ㄨ溅闂村姞鐝�*75锛夈�佷氦閫氳ˉ璐达紙=1*鍑哄嫟澶╂暟锛夈�佸甫寰掕ˉ璐达紙=5*甯﹀緬澶╂暟锛夈��
-//				宀椾綅琛ヨ创锛�=閰嶇疆锛夈�佺ぞ淇濊ˉ璐达紙=閰嶇疆锛夈�佸伐榫勮ˉ璐达紙=閰嶇疆锛夈�佷笉杈句繚搴曪紙=閰嶇疆淇濆簳锛夈�佽川閲忓銆佸缃�1銆佸缃�2/娓呭噳琛ヨ创銆佸缃�3/鏃ュ父妫�鏌ャ�佸仠鏈鸿ˉ璐淬�佸簲鍙戝伐璧勩�佸娉級
+type SalaryParameter struct {
+	SilkQuantity       decimal.Decimal // 鏃ヤ骇涓濋噺
+	SilkUnitAmount     decimal.Decimal // 鐢熶笣鍗曚环
+	SilkTotalAmount    decimal.Decimal // 鐢熶笣鎬讳环锛�=鏃ヤ骇涓濋噺*鐢熶笣鍗曚环锛�
+	FallingSilkBucket  decimal.Decimal // 妗舵暟
+	BadSilkQuantity    decimal.Decimal // 閲庣氦鏁伴噺
+	BadSilkUnitAmount  decimal.Decimal // 閲庣氦鍗曚环
+	BadSilkTotalAmount decimal.Decimal // 閲庣氦鎬讳环
 
-// OtherSubsidies 瀛樿〃锛� 鍏跺畠琛ヨ创
-func OtherSubsidies(date string) error {
+	GroupCarHeadAvgAmount decimal.Decimal // 鍚岀粍杞﹀ご宸ュ伐璧�
+	GroupWeaversAvgAmount decimal.Decimal // 鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫
+	WorkingDay            decimal.Decimal // 涓�涓湀宸ヤ綔澶╂暟
+	JobDays               decimal.Decimal // 涓�涓湀鍑哄嫟澶╂暟
 
-	models.NewPayrollOtherSubsidiesSearch() // 鍏跺畠琛ヨ创
-
-	return nil
+	ShiftTimeout        decimal.Decimal // 宸ヤ綔鏃ュ姞鐝椂闀匡紙灏忔椂锛�
+	ShiftOvertime       decimal.Decimal // 浼戞伅鏃ュ姞鐝椂闀匡紙澶╋級
+	MentorDays          decimal.Decimal // 甯﹀緬澶╂暟
+	FullAttendanceAward decimal.Decimal // 婊″嫟濂�
+	LeaveDays           decimal.Decimal // 璇峰亣澶╂暟
+	Seniority           decimal.Decimal // 宸ラ緞
 }
-
-// 瀛樿〃锛氳嚜鍔ㄧ极杞﹂棿鍚勬尅杞︺�佽溅澶淬�佷繚鍏ㄧ敓浜у伐璧勮绠� 锛堟棩鏈燂紙骞存湀锛夈�佽溅闂淬�佺粍鍒�佽溅鍙般�佷釜浜轰骇閲忥紙杞﹀彴姣忔湀姣忎汉骞冲潎涓濋噺锛夈�佹尅杞﹀伐宸ヨ祫锛堣溅鍙版瘡鏈堟瘡浜哄钩鍧囦笣閲忛噾棰濓級锛�
-// 鏍规嵁涓婃姤璁$畻锛�
-// 	1銆佹尅杞﹀伐骞冲潎宸ヨ祫锛堜互缁勪负鍗曚綅锛�= 姣忔湀灏忕粍姣忚溅澶村伐璧勪箣鍜�/6锛�70缁級
-//	2銆佽溅澶村伐宸ヨ祫锛堜互缁勪负鍗曚綅锛�= 鎸¤溅宸ュ钩鍧囧伐璧�*1.09锛�1.09涓烘寚瀹氱郴鏁帮級
-//	3銆佷繚鍏ㄥ伐宸ヨ祫锛堜互缁勪负鍗曚綅锛�= 锛堟尅杞﹀伐骞冲潎宸ヨ祫+杞﹀ご宸ュ伐璧勶級/2*1.2锛�1.2涓烘寚瀹氱郴鏁帮級
-//	4銆佹姌100缁尅杞﹀钩鍧囧伐璧勶紙浠ョ粍涓哄崟浣嶏級= 姣忔湀灏忕粍姣忚溅澶村伐璧勪箣鍜�/4锛�100缁級
 
 // SalaryPlan 鐢熶骇宸ヨ祫璁$畻
 func SalaryPlan(date string) error {
@@ -416,84 +485,292 @@
 	} else {
 		date = date[:7]
 	}
+	dateTime, err := time.Parse("2006-01", date)
+	if err != nil {
+		return err
+	}
 
-	hours, err := models.NewPayrollWorkingHoursSearch().SetMonthly(date).FindNotTotal() // 鍛樺伐鐨勫伐鏃剁粺璁�
+	hours, err := models.NewPayrollWorkingHoursSearch().SetOrder("worker_id").SetMonthly(date).FindNotTotal() // 鍛樺伐鐨勫伐鏃剁粺璁�
 	if err != nil {
 		return err
 	}
-	groups, err := models.NewPayrollProductionGroupSearch().SetOrder("workshop_number,groupnumber").
-		SetMonthly(date).FindNotTotal() // 灏忕粍姣忓ぉ鐨勪骇閲忕粺璁�
-	if err != nil {
-		return err
+	if len(hours) == 0 {
+		return errors.New(date + ":鍛樺伐鎵撳崱淇℃伅涓虹┖")
 	}
-	// 姣忎釜灏忕粍鐨勫钩鍧囬噾棰�
-	groupAvgAmountMap := make(map[string]decimal.Decimal)    // map[杞﹂棿灏忕粍]骞冲潎閲戦
-	fallingSilkBucketMap := make(map[string]decimal.Decimal) // map[杞﹂棿灏忕粍] FallingSilkBucket
-	var counter int
-	for i := 0; i < len(groups); i++ {
-		counter = 0
-		groupAvgAmount := decimal.NewFromInt32(0)
-		fallingSilkBucket := decimal.NewFromInt32(0)
-		for j := i; j < len(groups); j++ {
-			if groups[i].WorkshopNumber == groups[j].WorkshopNumber && groups[i].GroupNumber == groups[j].GroupNumber {
-				groupAvgAmount = groupAvgAmount.Add(groups[j].FinishTotalAvgAmount)
-				fallingSilkBucket = fallingSilkBucket.Add(groups[j].FallingSilkBucket)
-				counter += 1
-				if i != j {
-					i += 1
-				}
-			}
+
+	jobQuantityMap := make(map[string]int)
+	shiftTimeoutMap := make(map[string]decimal.Decimal)
+	shiftOvertimeMap := make(map[string]decimal.Decimal)
+	for _, hour := range hours {
+		jobQuantityMap[hour.WorkerID] += 1
+		if hour.OvertimeType == constvar.ShiftOvertimeTypeOvertime {
+			shiftOvertimeMap[hour.WorkerID] = hour.OvertimeDuration.Add(shiftOvertimeMap[hour.WorkerID])
+		} else if hour.OvertimeType == constvar.ShiftOvertimeTypeTimeout {
+			shiftTimeoutMap[hour.WorkerID] = hour.OvertimeDuration.Add(shiftTimeoutMap[hour.WorkerID])
 		}
-		key := fmt.Sprintf("%v%v", groups[i].WorkshopNumber, groups[i].GroupNumber)
-		groupAvgAmountMap[key] = groupAvgAmount.Div(decimal.NewFromInt32(int32(counter)))
-		fallingSilkBucketMap[key] = fallingSilkBucket
+	}
+
+	workers, _ := models.NewWorkerSearch().FindNotTotal()
+	workerMap := make(map[string]*models.Worker)
+	for _, worker := range workers {
+		workerMap[worker.ID] = worker
+	}
+
+	mentors, _ := models.NewMentorSearch().SetMonth(date).FindNotTotal()
+	mentorMap := make(map[string]int)
+	for _, mentor := range mentors {
+		mentorMap[mentor.WorkerId] = mentor.Days
 	}
 
 	// 鎸¤溅宸ュ伐璧�
-	models.NewPayrollProductionWeaversSearch().Orm.Model(&models.PayrollProductionWeavers{}).
-		Select("worker_id,sum()").Where("cycle like ?", date+"%")
+	weaversAmountArr, err := models.NewPayrollProductionWeaversSearch().SetMonthly(date).FindNotTotal()
+	if err != nil {
+		return err
+	}
 
-	// 鏌ヨ鍗曚环
-	for _, hour := range hours {
-		key := fmt.Sprintf("%v%v", hour.WorkshopNumber, hour.GroupNumber)
+	weaversAmountMap := make(map[string]*models.PayrollProductionWeavers, len(weaversAmountArr))
+	for _, weaver := range weaversAmountArr {
+		key := fmt.Sprintf("%v%v", weaver.Cycle, weaver.WorkerID)
+		weaversAmountMap[key] = weaver
+	}
 
-		ready70 := decimal.NewFromInt32(6)
-		ready100 := decimal.NewFromInt32(4)
-		coefficient := decimal.NewFromInt32(1)
-		switch hour.WorkTypeCode {
-		case constvar.JobTypeWeavers: // 鏃ヤ骇閲忓伐璧�=锛堢敓涓濆崟浠�*鏃ヤ骇涓濋噺锛�-锛堥噹绾ゆ暟閲�*閲庣氦鍗曚环锛�   鏈堜骇閲忓伐璧�=鏃ヤ骇閲忓伐璧勪箣鍜�
-			coefficient.Mul(coefficient).Sub(coefficient.Mul(coefficient))
+	// 宸ョ宸ヨ祫鏂规 map[宸ョ]鏂规
+	salaryPlans, _ := models.NewWorkTypeManageSearch().FindNotTotal()
+	if len(salaryPlans) == 0 {
+		return errors.New(date + ":宸ヨ祫鏂规涓虹┖")
+	}
 
-		case constvar.JobTypeCarHead: // 鏈堝伐璧�=70缁尅杞﹀伐鏈堝钩鍧囧伐璧�*绯绘暟
-			groupAvgAmountMap[key].Div(ready70).Mul(coefficient)
+	salaryPlansMap := make(map[uint]*models.WorkTypeManage, len(salaryPlans))
+	for _, salaryPlan := range salaryPlans {
+		salaryPlansMap[salaryPlan.ID] = salaryPlan
+	}
 
-		case constvar.JobTypeMaintenance: // 鏈堝伐璧�=锛�70缁尅杞﹀伐鏈堝钩鍧囧伐璧勶級+杞﹀ご宸ュ伐璧勶級/2*绯绘暟 锛燂紵锛燂紵 excel涓婄殑鏄�愭尅杞﹀伐鏈堝钩鍧囧伐璧�*绯绘暟銆�
-			groupAvgAmountMap[key].Div(ready70).Mul(coefficient)
+	groups, err := models.NewPayrollProductionGroupSearch().SetMonthly(date).FindNotTotal()
+	if err != nil {
+		return err
+	}
+	if len(groups) == 0 {
+		return errors.New(date + ":灏忕粍姣忓ぉ鐨勪骇閲忎负绌�")
+	}
 
-		case constvar.JobTypeBoiled: // 鏃ュ伐璧�=妗舵暟*鐓導鍗曚环  鏈堝伐璧�=鏃ュ伐璧勪箣鍜�
-			fallingSilkBucketMap[key].Mul(coefficient)
+	groupMap := make(map[string]*models.PayrollProductionGroup, len(groups))
+	groupByMonthMap := make(map[string]*models.PayrollProductionGroup, len(groups))
+	for _, group := range groups {
+		key := fmt.Sprintf("%v%v%v", group.Cycle, group.WorkshopNumber, group.GroupNumber)
+		groupMap[key] = group
 
-		case constvar.JobTypeScoop: // 鏃ュ伐璧�=妗舵暟*鑸�鑼у崟浠� 鏈堝伐璧�=鏃ュ伐璧勪箣鍜�
-			fallingSilkBucketMap[key].Mul(coefficient)
-
-		case constvar.JobTypeTransport: // 鏃ュ伐璧�=妗舵暟*閫佽導鍗曚环   鏈堝伐璧�=鏃ュ伐璧勪箣鍜�
-			fallingSilkBucketMap[key].Mul(coefficient)
-
-		case constvar.JobTypeCleaner: // 鏈堝伐璧�=鍥哄畾宸ヨ祫*鍑哄嫟澶╂暟
-			coefficient.Mul(coefficient)
-
-		case constvar.JobTypeMachineCleaner: // 鏈堝伐璧�=鍥哄畾宸ヨ祫*鍑哄嫟澶╂暟
-			coefficient.Mul(coefficient)
-
-		case constvar.JobTypeAllPowerful: // 鏈堝伐璧�=鍥哄畾宸ヨ祫*鍑哄嫟澶╂暟
-			coefficient.Mul(coefficient)
-
-		case constvar.JobTypeMonitor: // 100缁尅杞﹀伐骞冲潎宸ヨ祫*绯绘暟
-			groupAvgAmountMap[key].Div(ready100).Mul(coefficient)
-
+		monthKey := fmt.Sprintf("%v%v", group.WorkshopNumber, group.GroupNumber)
+		if groupByM, ok := groupByMonthMap[monthKey]; ok {
+			groupByM.FallingSilkBucket = groupByM.FallingSilkBucket.Add(group.FallingSilkBucket)
+			groupByM.SilkQuantity = groupByM.SilkQuantity.Add(group.SilkQuantity)
+			groupByM.SilkAvgQuantity = groupByM.SilkAvgQuantity.Add(group.SilkAvgQuantity)
+			groupByM.SilkTotalAmount = groupByM.SilkTotalAmount.Add(group.SilkTotalAmount)
+			groupByM.SilkTotalAvgAmount = groupByM.SilkTotalAvgAmount.Add(group.SilkTotalAvgAmount)
+			groupByM.BadSilkQuantity = groupByM.BadSilkQuantity.Add(group.BadSilkQuantity)
+			groupByM.BadSilkTotalAmount = groupByM.BadSilkTotalAmount.Add(group.BadSilkTotalAmount)
+			groupByM.BadSilkTotalAvgAmount = groupByM.BadSilkTotalAvgAmount.Add(group.BadSilkTotalAvgAmount)
+			groupByM.FinishTotalAmount = groupByM.FinishTotalAmount.Add(group.FinishTotalAmount)
+			groupByM.FinishTotalAvgAmount = groupByM.FinishTotalAvgAmount.Add(group.FinishTotalAvgAmount)
+			groupByMonthMap[monthKey] = groupByM
+		} else {
+			groupByMonthMap[monthKey] = group
 		}
 
 	}
 
+	var productionByDay []*models.PayrollOtherSubsidies
+	// 鎸夊ぉ缁熻,姣忓ぉ鐨勫伐璧�
+	for _, hour := range hours {
+		production := models.PayrollOtherSubsidies{
+			Cycle:        hour.Cycle,
+			WorkerID:     hour.WorkerID,
+			WorkTypeID:   hour.WorkTypeID,
+			WorkTypeCode: hour.WorkTypeCode,
+			WorkTypeName: constvar.JobTypeMap[hour.WorkTypeCode],
+			//SalaryPlanIds:   "",
+			//Amount: decimal.NewFromInt32(0),
+		}
+
+		// 鎸夊ぉ绠楋細鏃ヤ骇涓濋噺銆佺敓涓濆崟浠枫�佹《鏁般�侀噹绾ゆ暟閲忋�侀噹绾ゅ崟浠�
+		groupKey := fmt.Sprintf("%v%v%v", hour.Cycle, hour.WorkshopNumber, hour.GroupNumber)
+		if group, ok := groupMap[groupKey]; ok {
+			weaversKey := fmt.Sprintf("%v%v", hour.Cycle, hour.WorkerID)
+			finishTotalAmount := decimal.NewFromInt32(0)
+			badSilkTotalAmount := decimal.NewFromInt32(0)
+			if weavers, ok := weaversAmountMap[weaversKey]; ok {
+				finishTotalAmount = weavers.FinishTotalAmount
+				badSilkTotalAmount = weavers.BadSilkTotalAmount
+			}
+
+			parameter := SalaryParameter{
+				SilkQuantity:       group.SilkQuantity,
+				SilkUnitAmount:     decimal.NewFromInt32(1),
+				SilkTotalAmount:    finishTotalAmount,
+				FallingSilkBucket:  group.FallingSilkBucket,
+				BadSilkQuantity:    group.BadSilkQuantity,
+				BadSilkUnitAmount:  decimal.NewFromInt32(1),
+				BadSilkTotalAmount: badSilkTotalAmount,
+			}
+			if workType, ok := salaryPlansMap[hour.WorkTypeID]; ok {
+				for _, salaryPlan := range workType.SalaryPlans {
+					if matched, _ := regexp.MatchString("(鏃ヤ骇涓濋噺)|(鐢熶笣鍗曚环)|(妗舵暟)|(閲庣氦鏁伴噺)|(閲庣氦鍗曚环)", salaryPlan.SalaryFormula); matched {
+						temp := production
+						formula, s := salaryCalculate(&parameter, salaryPlan)
+
+						temp.SalaryFormula = formula
+						temp.SalaryPlanId = salaryPlan.ID
+						temp.Amount = temp.Amount.Add(s)
+						productionByDay = append(productionByDay, &temp) // 姣忎釜浜虹殑鎵�鏈夋柟妗�
+					}
+
+				}
+			}
+		}
+
+	}
+
+	err = models.WithTransaction(func(db *gorm.DB) error {
+		if len(productionByDay) == 0 {
+			return nil
+		}
+		if err := models.NewPayrollOtherSubsidiesSearch().SetOrm(db).SetMonthly(date).Delete(); err != nil {
+			return err
+		}
+		if err = models.NewPayrollOtherSubsidiesSearch().SetOrm(db).CreateBatch(productionByDay); err != nil {
+			return err
+		}
+		return nil
+	})
+
+	var constituteByMonth []*models.PayrollConstitute
+	// 鎸夊ぉ绠楃殑鍚堝苟
+	productionByMonthMap := make(map[string]*models.PayrollOtherSubsidies)
+	for _, production := range productionByDay {
+		key := fmt.Sprintf("%%", production.WorkerID, production.SalaryPlanId) // 鐢ㄦ埛id/鏂规ID
+		if groupByM, ok := productionByMonthMap[key]; ok {
+			productionByMonthMap[key].Amount = groupByM.Amount.Add(production.Amount)
+		} else {
+			productionByMonthMap[key] = production
+		}
+	}
+	for _, production := range productionByMonthMap {
+		constituteByMonth = append(constituteByMonth, &models.PayrollConstitute{
+			Cycle:         date,
+			WorkerID:      production.WorkerID,
+			WorkTypeID:    production.WorkTypeID,
+			WorkTypeCode:  production.WorkTypeCode,
+			SalaryPlanId:  production.SalaryPlanId,
+			SalaryFormula: "",
+			Amount:        production.Amount,
+			CreatedBy:     "auto",
+		}) // 姣忎釜浜虹殑鎵�鏈夋柟妗�
+	}
+
+	// 鎸夋湀绠楃殑璁$畻
+	for hourId, dayCount := range jobQuantityMap {
+		worker := workerMap[hourId]        // 鍛樺伐淇℃伅
+		ready70 := decimal.NewFromInt32(6) // 70缁�
+		//ready100 := decimal.NewFromInt32(4)    // 100缁�
+		//coefficient := decimal.NewFromInt32(1) // 绯绘暟
+
+		constitute := models.PayrollConstitute{
+			Cycle:        date,
+			WorkerID:     hourId,
+			WorkTypeID:   worker.WorkTypeId,
+			WorkTypeCode: worker.WorkTypeCode,
+			//SalaryPlanId:,
+			//SalaryFormula:,
+			//Amount:,
+			CreatedBy: "auto",
+		}
+
+		firstDay, lastDay := utils.GetLastMonthPeriod(dateTime)
+		_, days := utils.CalcWorkHour(firstDay, lastDay, []time.Weekday{time.Sunday}, 12.0)
+		parameter := SalaryParameter{
+			WorkingDay:          decimal.NewFromInt32(int32(days)),
+			JobDays:             decimal.NewFromInt32(int32(dayCount)),
+			FullAttendanceAward: decimal.NewFromInt32(0), // 婊″嫟濂�
+			LeaveDays:           decimal.NewFromInt32(0), // 璇峰亣澶╂暟
+			Seniority:           decimal.NewFromInt32(0), // 宸ラ緞
+		}
+		monthKey := fmt.Sprintf("%v%v", worker.ShopNumber, worker.GroupNumber)
+		if group, ok := groupByMonthMap[monthKey]; ok {
+			parameter.FallingSilkBucket = group.FallingSilkBucket
+			parameter.GroupWeaversAvgAmount = group.FinishTotalAvgAmount
+			parameter.GroupCarHeadAvgAmount = group.FinishTotalAvgAmount.Div(ready70)
+		}
+		if timeout, ok := shiftTimeoutMap[hourId]; ok {
+			parameter.ShiftTimeout = timeout
+		}
+		if overtime, ok := shiftOvertimeMap[hourId]; ok {
+			parameter.ShiftOvertime = overtime
+		}
+		if mentorDays, ok := mentorMap[hourId]; ok {
+			parameter.MentorDays = decimal.NewFromInt32(int32(mentorDays))
+		}
+
+		// 鎸夋湀绠楋細鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫銆佸悓缁勮溅澶村伐宸ヨ祫銆佸嚭鍕ゅぉ鏁�
+		if workType, ok := salaryPlansMap[worker.WorkTypeId]; ok {
+			for _, salaryPlan := range workType.SalaryPlans {
+				if matched, _ := regexp.MatchString("(鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫)|(鍚岀粍杞﹀ご宸ュ伐璧�)|(鍑哄嫟澶╂暟)|(宸ヤ綔鏃ュ姞鐝椂闀�)|(浼戞伅鏃ュ姞鐝椂闀�)|(甯﹀緬澶╂暟)|(婊″嫟濂�)|(璇峰亣澶╂暟)|(宸ラ緞)", salaryPlan.SalaryFormula); matched {
+					temp := constitute
+					formula, s := salaryCalculate(&parameter, salaryPlan)
+					temp.SalaryFormula = formula
+					temp.SalaryPlanId = salaryPlan.ID
+					temp.Amount = temp.Amount.Add(s)
+					constituteByMonth = append(constituteByMonth, &temp) // 姣忎釜浜虹殑鎵�鏈夋柟妗�
+				}
+
+			}
+		}
+	}
+
+	err = models.WithTransaction(func(db *gorm.DB) error {
+		if len(constituteByMonth) == 0 {
+			return nil
+		}
+		if err := models.NewPayrollConstituteSearch().SetOrm(db).SetCycle(date).SetCreatedBy("auto").Delete(); err != nil {
+			return err
+		}
+		if err = models.NewPayrollConstituteSearch().SetOrm(db).CreateBatch(constituteByMonth); err != nil {
+			return err
+		}
+		return nil
+	})
+
 	return nil
 }
+
+// 鏍规嵁鏂规璁$畻鍚勫伐绉嶈柂璧�
+func salaryCalculate(parameter *SalaryParameter, salaryPlan *models.SalaryPlan) (string, decimal.Decimal) {
+	formula := strings.ReplaceAll(salaryPlan.SalaryFormula, ",", "")
+	formula = strings.ReplaceAll(salaryPlan.SalaryFormula, " ", "")
+	//var SplitFixedField = []string{"鏃ヤ骇涓濋噺", "鐢熶笣鍗曚环", "妗舵暟", "閲庣氦鏁伴噺", "閲庣氦鍗曚环", "鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫", "鍚岀粍杞﹀ご宸ュ伐璧�", "鍑哄嫟澶╂暟"}
+	formula = strings.Replace(formula, "鏃ヤ骇涓濋噺*鐢熶笣鍗曚环", parameter.SilkTotalAmount.String(), -1)
+	formula = strings.Replace(formula, "閲庣氦鏁伴噺*閲庣氦鍗曚环", parameter.BadSilkTotalAmount.String(), -1)
+	formula = strings.Replace(formula, "鏃ヤ骇涓濋噺", parameter.SilkQuantity.String(), -1)
+	formula = strings.Replace(formula, "鐢熶笣鍗曚环", parameter.SilkTotalAmount.String(), -1)
+	formula = strings.Replace(formula, "妗舵暟", parameter.FallingSilkBucket.String(), -1)
+	formula = strings.Replace(formula, "閲庣氦鏁伴噺", parameter.BadSilkQuantity.String(), -1)
+	formula = strings.Replace(formula, "閲庣氦鍗曚环", parameter.BadSilkUnitAmount.String(), -1)
+	formula = strings.Replace(formula, "鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫", parameter.GroupWeaversAvgAmount.String(), -1)
+	formula = strings.Replace(formula, "鍚岀粍杞﹀ご宸ュ伐璧�", parameter.GroupCarHeadAvgAmount.String(), -1)
+	formula = strings.Replace(formula, "鍑哄嫟澶╂暟", parameter.JobDays.String(), -1)
+
+	formula = strings.Replace(formula, "宸ヤ綔鏃ュ姞鐝椂闀�", parameter.ShiftTimeout.String(), -1)
+	formula = strings.Replace(formula, "浼戞伅鏃ュ姞鐝椂闀�", parameter.ShiftOvertime.String(), -1)
+	formula = strings.Replace(formula, "甯﹀緬澶╂暟", parameter.MentorDays.String(), -1)
+	formula = strings.Replace(formula, "婊″嫟濂�", parameter.FullAttendanceAward.String(), -1)
+	formula = strings.Replace(formula, "璇峰亣澶╂暟", parameter.LeaveDays.String(), -1)
+	formula = strings.Replace(formula, "宸ラ緞", parameter.Seniority.String(), -1)
+
+	logx.Debugf("salary formula: %v", formula)
+
+	result, err := calculator.ParseAndExec(formula)
+	if err != nil {
+		logx.Errorf("%s : %v", formula, err)
+	}
+	logx.Debugf("%s = %v", formula, result)
+
+	return formula, decimal.NewFromFloat(result)
+}

--
Gitblit v1.8.0