From edf3066724ad442d6929210c830cb67c17277690 Mon Sep 17 00:00:00 2001
From: yinbentan <yinbentan@live.com>
Date: 星期四, 01 八月 2024 11:46:33 +0800
Subject: [PATCH] 添加工资计算自动任务
---
models/payroll_working_hours.go | 4
task/salary_plan.go | 101 ++++++++++++++++++++
task/task_init.go | 4
service/salary_plan.go | 170 +++++++++++++++++++++++++++-------
4 files changed, 244 insertions(+), 35 deletions(-)
diff --git a/models/payroll_working_hours.go b/models/payroll_working_hours.go
index caff2b4..86dc8bd 100644
--- a/models/payroll_working_hours.go
+++ b/models/payroll_working_hours.go
@@ -133,6 +133,10 @@
db = db.Where("work_type_id = ?", slf.WorkTypeID)
}
+ if slf.WorkTypeCode != "" {
+ db = db.Where("work_type_code = ?", slf.WorkTypeCode)
+ }
+
if slf.WorkerID != "" {
db = db.Where("worker_id = ?", slf.WorkerID)
}
diff --git a/service/salary_plan.go b/service/salary_plan.go
index c7f7aca..399be70 100644
--- a/service/salary_plan.go
+++ b/service/salary_plan.go
@@ -25,9 +25,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 {
@@ -70,6 +79,9 @@
}
err = models.WithTransaction(func(db *gorm.DB) error {
+ if len(list) == 0 {
+ return nil
+ }
if err := models.NewPayrollWorkingHoursSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
return err
}
@@ -88,10 +100,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
@@ -101,8 +121,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
@@ -111,6 +138,9 @@
workingHours, err := models.NewPayrollWorkingHoursSearch().SetWorkTypeCode(constvar.JobTypeWeavers).SetCycle(date).FindNotTotal() // 鍛樺伐鐨勫伐鏃剁粺璁�
if err != nil {
return err
+ }
+ if len(workingHours) == 0 {
+ return errors.New(date + ":鎸¤溅宸ユ墦鍗′俊鎭负绌�")
}
// 杞﹀彴鎸¤溅宸ラ噸澶嶄汉鍛樻爣璁�
@@ -133,7 +163,13 @@
}
for _, workingHour := range workingHourArr {
key := fmt.Sprintf("%v%v%v", workingHour.WorkshopNumber, workingHour.GroupNumber, workingHour.StartCarNumber)
- carEmployeeMap[key][workingHour.WorkerID] = true
+ if temp, ok := carEmployeeMap[key]; ok {
+ temp[workingHour.WorkerID] = true
+ carEmployeeMap[key] = temp
+ } else {
+ carEmployeeMap[key] = map[string]bool{workingHour.WorkerID: true}
+ }
+
}
// 鏂规2 鏍规嵁绾ゅ害鐧昏鏉ユ煡浜烘暟
@@ -241,6 +277,9 @@
}
err = models.WithTransaction(func(db *gorm.DB) error {
+ if len(productionCar) == 0 {
+ return nil
+ }
if err := models.NewPayrollProductionCarSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
return err
}
@@ -263,16 +302,27 @@
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)
- groupWorkingHourMap[key][workingHour.WorkerID] = true
+ 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)
@@ -316,12 +366,13 @@
}
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
@@ -339,10 +390,16 @@
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)
@@ -366,10 +423,16 @@
info.FinishTotalAmount = info.FinishTotalAmount.Add(car.FinishTotalAvgAmount)
}
}
+ if info.SilkQuantity.IsZero() {
+ continue
+ }
productionEmployee = append(productionEmployee, &info)
}
err = models.WithTransaction(func(db *gorm.DB) error {
+ if len(productionEmployee) == 0 {
+ return nil
+ }
if err := models.NewPayrollProductionWeaversSearch().SetOrm(db).SetCycle(date).Delete(); err != nil {
return err
}
@@ -408,6 +471,10 @@
if err != nil {
return err
}
+ if len(hours) == 0 {
+ return errors.New(date + ":鍛樺伐鎵撳崱淇℃伅涓虹┖")
+ }
+
jobQuantityMap := make(map[string]int) // 鍛樺伐鍑哄嫟缁熻
for _, hour := range hours {
jobQuantityMap[hour.WorkerID] += 1
@@ -420,7 +487,11 @@
}
// 鎸¤溅宸ュ伐璧�
- weaversAmountArr, _ := models.NewPayrollProductionWeaversSearch().SetMonthly(date).FindNotTotal()
+ weaversAmountArr, err := models.NewPayrollProductionWeaversSearch().SetMonthly(date).FindNotTotal()
+ if err != nil {
+ return err
+ }
+
weaversAmountMap := make(map[string]*models.PayrollProductionWeavers, len(weaversAmountArr))
for _, weaver := range weaversAmountArr {
key := fmt.Sprintf("%v%v", weaver.Cycle, weaver.WorkerID)
@@ -429,12 +500,23 @@
// 宸ョ宸ヨ祫鏂规 map[宸ョ]鏂规
salaryPlans, _ := models.NewWorkTypeManageSearch().FindNotTotal()
+ if len(salaryPlans) == 0 {
+ return errors.New(date + ":宸ヨ祫鏂规涓虹┖")
+ }
+
salaryPlansMap := make(map[uint]*models.WorkTypeManage, len(salaryPlans))
for _, salaryPlan := range salaryPlans {
salaryPlansMap[salaryPlan.ID] = salaryPlan
}
groups, err := models.NewPayrollProductionGroupSearch().SetMonthly(date).FindNotTotal()
+ if err != nil {
+ return err
+ }
+ if len(groups) == 0 {
+ return errors.New(date + ":灏忕粍姣忓ぉ鐨勪骇閲忎负绌�")
+ }
+
groupMap := make(map[string]*models.PayrollProductionGroup, len(groups))
groupByMonthMap := make(map[string]*models.PayrollProductionGroup, len(groups))
for _, group := range groups {
@@ -475,36 +557,46 @@
// 鎸夊ぉ绠楋細鏃ヤ骇涓濋噺銆佺敓涓濆崟浠枫�佹《鏁般�侀噹绾ゆ暟閲忋�侀噹绾ゅ崟浠�
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(¶meter, salaryPlan)
+ 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
+ }
- temp.SalaryFormula = formula
- temp.SalaryPlanId = salaryPlan.ID
- temp.Amount = temp.Amount.Add(s)
- productionByDay = append(productionByDay, &temp) // 姣忎釜浜虹殑鎵�鏈夋柟妗�
+ 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(¶meter, 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
}
@@ -557,11 +649,16 @@
}
monthKey := fmt.Sprintf("%v%v", worker.ShopNumber, worker.GroupNumber)
- group := groupByMonthMap[monthKey]
+ fallingSilkBucket := decimal.NewFromInt(0)
+ finishTotalAvgAmount := decimal.NewFromInt(0)
+ if group, ok := groupByMonthMap[monthKey]; ok {
+ fallingSilkBucket = group.FallingSilkBucket
+ finishTotalAvgAmount = group.FinishTotalAvgAmount
+ }
parameter := SalaryParameter{
- FallingSilkBucket: group.FallingSilkBucket,
- GroupWeaversAvgAmount: group.FinishTotalAvgAmount,
- GroupCarHeadAvgAmount: group.FinishTotalAvgAmount.Div(ready70),
+ FallingSilkBucket: fallingSilkBucket,
+ GroupWeaversAvgAmount: finishTotalAvgAmount,
+ GroupCarHeadAvgAmount: finishTotalAvgAmount.Div(ready70),
JobDays: decimal.NewFromInt32(int32(dayCount)),
}
@@ -582,6 +679,9 @@
}
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
}
diff --git a/task/salary_plan.go b/task/salary_plan.go
new file mode 100644
index 0000000..d982645
--- /dev/null
+++ b/task/salary_plan.go
@@ -0,0 +1,101 @@
+package task
+
+import (
+ "silkserver/models"
+ "silkserver/pkg/logx"
+ "silkserver/service"
+ "silkserver/utils"
+)
+
+func WorkingHours() {
+ //鍔犻攣锛屽彧闇�瑕佷竴涓繘绋嬭繍琛屾浠诲姟
+ var (
+ lockName = "WorkingHours"
+ serviceID = "WorkingHoursServer"
+ )
+ err := models.NewLockSearch().AcquireLock(lockName, serviceID)
+ if err != nil {
+ logx.Errorf("MonthStats AcquireLock err:%v", err)
+ return
+ }
+ defer func() {
+ err := models.NewLockSearch().ReleaseLock(lockName, serviceID)
+ if err != nil {
+ logx.Errorf("MonthStats ReleaseLock err:%v", err)
+ }
+ }()
+
+ firstDay, lastDay := utils.GetLastMonthPeriod(utils.GetMonthByOffset(-1))
+ for i := firstDay.Day() - 1; i <= lastDay.Day(); i++ {
+ localDay := firstDay.AddDate(0, 0, i-1).Format("2006-01-02")
+ err = service.WorkingHours(localDay)
+ if err != nil {
+ logx.Error(err.Error())
+ }
+ }
+
+}
+
+func ProductionCar() {
+ //鍔犻攣锛屽彧闇�瑕佷竴涓繘绋嬭繍琛屾浠诲姟
+ var (
+ lockName = "ProductionCar"
+ serviceID = "ProductionCarServer"
+ )
+ err := models.NewLockSearch().AcquireLock(lockName, serviceID)
+ if err != nil {
+ logx.Errorf("MonthStats AcquireLock err:%v", err)
+ return
+ }
+ defer func() {
+ err := models.NewLockSearch().ReleaseLock(lockName, serviceID)
+ if err != nil {
+ logx.Errorf("MonthStats ReleaseLock err:%v", err)
+ }
+ }()
+
+ firstDay, lastDay := utils.GetLastMonthPeriod(utils.GetMonthByOffset(-1))
+ for i := 0; i < lastDay.Day(); i++ {
+ localDay := firstDay.AddDate(0, 0, i).Format("2006-01-02")
+ err = service.ProductionCar(localDay)
+ if err != nil {
+ logx.Error(err.Error())
+ }
+ err = service.ProductionGroup(localDay)
+ if err != nil {
+ logx.Error(err.Error())
+ }
+ err = service.ProductionWeavers(localDay)
+ if err != nil {
+ logx.Error(err.Error())
+ }
+ }
+
+}
+
+func SalaryPlan() {
+ //鍔犻攣锛屽彧闇�瑕佷竴涓繘绋嬭繍琛屾浠诲姟
+ var (
+ lockName = "SalaryPlan"
+ serviceID = "SalaryPlanServer"
+ )
+ err := models.NewLockSearch().AcquireLock(lockName, serviceID)
+ if err != nil {
+ logx.Errorf("MonthStats AcquireLock err:%v", err)
+ return
+ }
+ defer func() {
+ err := models.NewLockSearch().ReleaseLock(lockName, serviceID)
+ if err != nil {
+ logx.Errorf("MonthStats ReleaseLock err:%v", err)
+ }
+ }()
+
+ lastMonth := utils.GetMonthByOffset(-1).Format("2006-01")
+
+ err = service.SalaryPlan(lastMonth)
+ if err != nil {
+ logx.Error(err.Error())
+ }
+
+}
diff --git a/task/task_init.go b/task/task_init.go
index 2008b43..3e95573 100644
--- a/task/task_init.go
+++ b/task/task_init.go
@@ -17,5 +17,9 @@
logx.Errorf("init task err:%v", err)
panic(err)
}
+ s.Every(1).Month(1).Do(WorkingHours)
+ s.Every(1).Month(1).Do(ProductionCar)
+ s.Every(1).Month(1).Do(SalaryPlan)
+
s.StartAsync()
}
--
Gitblit v1.8.0