service/salary_plan.go
@@ -9,13 +9,19 @@
   "silkserver/constvar"
   "silkserver/models"
   "silkserver/pkg/logx"
   "silkserver/utils"
   "silkserver/utils/calculator"
   "strconv"
   "strings"
   "time"
)
// 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 {
@@ -59,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 {
@@ -456,7 +467,15 @@
   GroupCarHeadAvgAmount decimal.Decimal // 同组车头工工资
   GroupWeaversAvgAmount decimal.Decimal // 同组挡车工月平均工资
   JobDays               decimal.Decimal // 出勤天数
   WorkingDay            decimal.Decimal // 一个月工作天数
   JobDays               decimal.Decimal // 一个月出勤天数
   ShiftTimeout        decimal.Decimal // 工作日加班时长(小时)
   ShiftOvertime       decimal.Decimal // 休息日加班时长(天)
   MentorDays          decimal.Decimal // 带徒天数
   FullAttendanceAward decimal.Decimal // 满勤奖
   LeaveDays           decimal.Decimal // 请假天数
   Seniority           decimal.Decimal // 工龄
}
// SalaryPlan 生产工资计算
@@ -465,6 +484,10 @@
      return errors.New("请传入正确的查询时间!")
   } else {
      date = date[:7]
   }
   dateTime, err := time.Parse("2006-01", date)
   if err != nil {
      return err
   }
   hours, err := models.NewPayrollWorkingHoursSearch().SetOrder("worker_id").SetMonthly(date).FindNotTotal() // 员工的工时统计
@@ -475,15 +498,28 @@
      return errors.New(date + ":员工打卡信息为空")
   }
   jobQuantityMap := make(map[string]int) // 员工出勤统计
   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])
      }
   }
   workers, err := models.NewWorkerSearch().FindNotTotal()
   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
   }
   // 挡车工工资
@@ -648,24 +684,35 @@
         CreatedBy: "auto",
      }
      monthKey := fmt.Sprintf("%v%v", worker.ShopNumber, worker.GroupNumber)
      fallingSilkBucket := decimal.NewFromInt(0)
      finishTotalAvgAmount := decimal.NewFromInt(0)
      if group, ok := groupByMonthMap[monthKey]; ok {
         fallingSilkBucket = group.FallingSilkBucket
         finishTotalAvgAmount = group.FinishTotalAvgAmount
      }
      firstDay, lastDay := utils.GetLastMonthPeriod(dateTime)
      _, days := utils.CalcWorkHour(firstDay, lastDay, []time.Weekday{time.Sunday}, 12.0)
      parameter := SalaryParameter{
         FallingSilkBucket:     fallingSilkBucket,
         GroupWeaversAvgAmount: finishTotalAvgAmount,
         GroupCarHeadAvgAmount: finishTotalAvgAmount.Div(ready70),
         JobDays:               decimal.NewFromInt32(int32(dayCount)),
         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 {
            if matched, _ := regexp.MatchString("(同组挡车工月平均工资)|(同组车头工工资)|(出勤天数)|(工作日加班时长)|(休息日加班时长)|(带徒天数)|(满勤奖)|(请假天数)|(工龄)", salaryPlan.SalaryFormula); matched {
               temp := constitute
               formula, s := salaryCalculate(&parameter, salaryPlan)
               temp.SalaryFormula = formula
@@ -710,6 +757,13 @@
   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)