| | |
| | | "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"` |
| | | } |
| | | |
| | | // 薪资计算 |
| | | // 纤度登记:silk_fineness_register silk_fineness_register_item |
| | | // 纤度检验:silk_fineness_check silk_fineness_check_item |
| | | // 产量登记登记:silk_yield_register_circle |
| | | |
| | | // WorkingHours 存表:工时计算(日期(年月日)、工种、员工姓名、小组、车台、产量工资、上班超时(小时)、上班超时(天)、加班(单独)、加班(全车间)、出勤(天)、带徒(天)、产量(KG)、其它) |
| | | func WorkingHours(date string) error { |
| | |
| | | } |
| | | |
| | | 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 |
| | | }) |
| | | |
| | |
| | | } |
| | | |
| | | // 车台挡车工重复人员标记 |
| | | 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, |
| | |
| | | // 野纤统计 |
| | | 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 |
| | | } |
| | | } |
| | | } |
| | |
| | | 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)) |
| | |
| | | |
| | | } |
| | | 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 |
| | |
| | | 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 |
| | |
| | | } |
| | | |
| | | } |
| | | 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 { |
| | |
| | | return nil |
| | | } |
| | | |
| | | // 根据上报计算: |
| | | // 1、车台当月全等级丝总量; |
| | | // 2、车台当月各等级丝总量; |
| | | // 3、车台每月等级占比=车台当月各等级丝总量/车台当月全等级丝总量; |
| | | // 4、车台每月每人平均丝量=车台当月全等级丝总量/车台挡车工人数; |
| | | // 5、车台当月全野纤扣除金额; |
| | | // 6、车台每月每人平均野纤扣除金额=当月全野纤扣除金额/车台挡车工人数; |
| | | // 7、车台每月丝量总金额 |
| | | // 8、车台每月丝量成品金额 |
| | | // 9、车台每月每人平均丝量金额=车台每月丝量成品金额/车台挡车工人数 |
| | | |
| | | // ProductionEmployee 存表: 每人每天的产量统计登记 |
| | | // ProductionWeavers 存表: 挡车工每人每天的产量统计登记 |
| | | func ProductionWeavers(date string) error { |
| | | workingHours, err := models.NewPayrollWorkingHoursSearch().SetWorkTypeCode(constvar.JobTypeWeavers).SetCycle(date).FindNotTotal() // 员工的工时统计 |
| | | if err != nil { |
| | |
| | | Cycle: date, |
| | | WorkTypeID: worker.WorkTypeID, |
| | | WorkerID: worker.WorkerID, |
| | | WorkshopId: worker.WorkshopId, |
| | | WorkshopNumber: worker.WorkshopNumber, |
| | | GroupNumber: worker.GroupNumber, |
| | | } |
| | |
| | | } |
| | | |
| | | 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 |
| | |
| | | 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 { |
| | |
| | | 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(¶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 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(¶meter, 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) |
| | | } |