From b94bef381946e22fd1038f24e6d9de911d194640 Mon Sep 17 00:00:00 2001
From: yinbentan <yinbentan@live.com>
Date: 星期三, 31 七月 2024 23:33:48 +0800
Subject: [PATCH] 功能修改,工资计算调整,通过前端配置公式进行计算

---
 service/salary_plan.go |  466 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 293 insertions(+), 173 deletions(-)

diff --git a/service/salary_plan.go b/service/salary_plan.go
index df0f491..c7f7aca 100644
--- a/service/salary_plan.go
+++ b/service/salary_plan.go
@@ -5,21 +5,14 @@
 	"fmt"
 	"github.com/shopspring/decimal"
 	"gorm.io/gorm"
+	"regexp"
 	"silkserver/constvar"
 	"silkserver/models"
+	"silkserver/pkg/logx"
+	"silkserver/utils/calculator"
 	"strconv"
 	"strings"
 )
-
-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 {
@@ -77,10 +70,12 @@
 	}
 
 	err = models.WithTransaction(func(db *gorm.DB) error {
-
-		models.NewPayrollWorkingHoursSearch().SetOrm(db).SetCycle(date).Delete()
-
-		models.NewPayrollWorkingHoursSearch().SetOrm(db).CreateBatch(list)
+		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
 	})
 
@@ -119,26 +114,47 @@
 	}
 
 	// 杞﹀彴鎸¤溅宸ラ噸澶嶄汉鍛樻爣璁�
-	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)
+		carEmployeeMap[key][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 +191,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 +206,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 +241,10 @@
 
 	}
 	err = models.WithTransaction(func(db *gorm.DB) error {
-		err := models.NewPayrollProductionCarSearch().SetOrm(db).SetCycle(date).Delete()
-		if err != 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
@@ -255,38 +264,47 @@
 		return err
 	}
 
+	workingHours, err := models.NewPayrollWorkingHoursSearch().SetWorkTypeCode(constvar.JobTypeWeavers).SetCycle(date).FindNotTotal() // 鍛樺伐鐨勫伐鏃剁粺璁�
+	if err != nil {
+		return err
+	}
+
+	groupWorkingHourMap := make(map[string]map[string]bool)
+	for _, workingHour := range workingHours {
+		key := fmt.Sprintf("%v%v", workingHour.WorkshopNumber, workingHour.GroupNumber)
+		groupWorkingHourMap[key][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,22 +312,7 @@
 			}
 
 		}
-		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 {
@@ -330,18 +333,7 @@
 	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 {
@@ -359,6 +351,7 @@
 			Cycle:          date,
 			WorkTypeID:     worker.WorkTypeID,
 			WorkerID:       worker.WorkerID,
+			WorkshopId:     worker.WorkshopId,
 			WorkshopNumber: worker.WorkshopNumber,
 			GroupNumber:    worker.GroupNumber,
 		}
@@ -377,12 +370,10 @@
 	}
 
 	err = models.WithTransaction(func(db *gorm.DB) error {
-		err := models.NewPayrollProductionWeaversSearch().SetOrm(db).SetCycle(date).Delete()
-		if err != 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 +382,19 @@
 	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 {
-
-	models.NewPayrollOtherSubsidiesSearch() // 鍏跺畠琛ヨ创
-
-	return nil
+	GroupCarHeadAvgAmount decimal.Decimal // 鍚岀粍杞﹀ご宸ュ伐璧�
+	GroupWeaversAvgAmount decimal.Decimal // 鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫
+	JobDays               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 {
@@ -417,83 +404,216 @@
 		date = date[:7]
 	}
 
-	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
+	jobQuantityMap := make(map[string]int) // 鍛樺伐鍑哄嫟缁熻
+	for _, hour := range hours {
+		jobQuantityMap[hour.WorkerID] += 1
 	}
-	// 姣忎釜灏忕粍鐨勫钩鍧囬噾棰�
-	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
-				}
-			}
-		}
-		key := fmt.Sprintf("%v%v", groups[i].WorkshopNumber, groups[i].GroupNumber)
-		groupAvgAmountMap[key] = groupAvgAmount.Div(decimal.NewFromInt32(int32(counter)))
-		fallingSilkBucketMap[key] = fallingSilkBucket
+
+	workers, err := models.NewWorkerSearch().FindNotTotal()
+	workerMap := make(map[string]*models.Worker)
+	for _, worker := range workers {
+		workerMap[worker.ID] = worker
 	}
 
 	// 鎸¤溅宸ュ伐璧�
-	models.NewPayrollProductionWeaversSearch().Orm.Model(&models.PayrollProductionWeavers{}).
-		Select("worker_id,sum()").Where("cycle like ?", date+"%")
+	weaversAmountArr, _ := models.NewPayrollProductionWeaversSearch().SetMonthly(date).FindNotTotal()
+	weaversAmountMap := make(map[string]*models.PayrollProductionWeavers, len(weaversAmountArr))
+	for _, weaver := range weaversAmountArr {
+		key := fmt.Sprintf("%v%v", weaver.Cycle, weaver.WorkerID)
+		weaversAmountMap[key] = weaver
+	}
 
-	// 鏌ヨ鍗曚环
-	for _, hour := range hours {
-		key := fmt.Sprintf("%v%v", hour.WorkshopNumber, hour.GroupNumber)
+	// 宸ョ宸ヨ祫鏂规 map[宸ョ]鏂规
+	salaryPlans, _ := models.NewWorkTypeManageSearch().FindNotTotal()
+	salaryPlansMap := make(map[uint]*models.WorkTypeManage, len(salaryPlans))
+	for _, salaryPlan := range salaryPlans {
+		salaryPlansMap[salaryPlan.ID] = salaryPlan
+	}
 
-		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))
+	groups, err := models.NewPayrollProductionGroupSearch().SetMonthly(date).FindNotTotal()
+	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.JobTypeCarHead: // 鏈堝伐璧�=70缁尅杞﹀伐鏈堝钩鍧囧伐璧�*绯绘暟
-			groupAvgAmountMap[key].Div(ready70).Mul(coefficient)
-
-		case constvar.JobTypeMaintenance: // 鏈堝伐璧�=锛�70缁尅杞﹀伐鏈堝钩鍧囧伐璧勶級+杞﹀ご宸ュ伐璧勶級/2*绯绘暟 锛燂紵锛燂紵 excel涓婄殑鏄�愭尅杞﹀伐鏈堝钩鍧囧伐璧�*绯绘暟銆�
-			groupAvgAmountMap[key].Div(ready70).Mul(coefficient)
-
-		case constvar.JobTypeBoiled: // 鏃ュ伐璧�=妗舵暟*鐓導鍗曚环  鏈堝伐璧�=鏃ュ伐璧勪箣鍜�
-			fallingSilkBucketMap[key].Mul(coefficient)
-
-		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)
+		group := groupMap[groupKey]
+		weaversKey := fmt.Sprintf("%v%v", hour.Cycle, hour.WorkerID)
+		weavers := weaversAmountMap[weaversKey]
+		parameter := SalaryParameter{
+			SilkQuantity:       group.SilkQuantity,
+			SilkUnitAmount:     decimal.NewFromInt32(1),
+			SilkTotalAmount:    weavers.FinishTotalAmount,
+			FallingSilkBucket:  group.FallingSilkBucket,
+			BadSilkQuantity:    group.BadSilkQuantity,
+			BadSilkUnitAmount:  decimal.NewFromInt32(1),
+			BadSilkTotalAmount: weavers.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 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",
+		}
+
+		monthKey := fmt.Sprintf("%v%v", worker.ShopNumber, worker.GroupNumber)
+		group := groupByMonthMap[monthKey]
+		parameter := SalaryParameter{
+			FallingSilkBucket:     group.FallingSilkBucket,
+			GroupWeaversAvgAmount: group.FinishTotalAvgAmount,
+			GroupCarHeadAvgAmount: group.FinishTotalAvgAmount.Div(ready70),
+			JobDays:               decimal.NewFromInt32(int32(dayCount)),
+		}
+
+		// 鎸夋湀绠楋細鍚岀粍鎸¤溅宸ユ湀骞冲潎宸ヨ祫銆佸悓缁勮溅澶村伐宸ヨ祫銆佸嚭鍕ゅぉ鏁�
+		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 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, " ", "")
+	//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)
+
+	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