package service import ( butil "enterprise/base/util" "enterprise/common/config" "enterprise/common/dao" "enterprise/common/model" "enterprise/server/api" "enterprise/server/session" CommonService "enterprise/service" "fmt" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "github.com/spf13/cast" excelize "github.com/xuri/excelize/v2" "os" "sort" "time" "net/http" ) var ( StaffSalaryTypeBank = "bank" StaffSalaryTypeSummary = "summary" StaffSalaryTypeAgent = "agent" ) type StaffSalary struct { } func NewStaffSalary() *StaffSalary { return &StaffSalary{} } func (s *StaffSalary) List(sess *session.AdminSession, req *api.ListSalaryReq) (int64, interface{}, interface{}) { salarys, total, err := dao.NewStaffSalaryDao().QueryAdmin(1, -1, sess.GetCorpId(), req.Username, req.StartMonth, req.EndMonth) session.CheckDBError(err) start := (req.Page - 1) * req.Size end := start + req.Size items := make([]*api.Salary, 0) summary := new(api.Salary) for pos, m := range salarys { staffSalary := new(api.Salary) staffSalary.From(m) summary.Add(staffSalary) if pos < start || pos >= end { continue } staffUser, err := dao.NewStaffUserDao().Get(m.UserId) session.CheckDBError(err) if staffUser != nil { userSalary := staffUser.GetSalary() staffSalary.Realname = staffUser.Realname staffSalary.TargetSalary = userSalary.Target staffSalary.BaseSalary = userSalary.Base } items = append(items, staffSalary) } return total, summary, items } func (s *StaffSalary) Create(sess *session.AdminSession, req *api.CreateSalaryReq) { users, _, err := dao.NewStaffUserDao().Query(1, -1, sess.GetCorpId(), 0, req.Username, "", "", "") session.CheckDBError(err) for _, user := range users { //离职的且离职时间不在当月的不在计算工资 if user.Status == model.StaffUserStatusOffline { leaveDate, _ := time.ParseInLocation("2006-01-02", user.LeaveDate, time.Local) if leaveDate.Month() != time.Now().Month() { continue } } salary, err := dao.NewStaffSalaryDao().GetBy(sess.GetCorpId(), user.Id, req.Month) session.CheckDBError(err) salaryServ := CommonService.NewStaffSalary(user) salary, err = salaryServ.CalcSalary(salary, req.Month) if err != nil { log.Errorf("CalcSalary error :%s", err.Error()) continue } if salary == nil { continue } if salary.Id == 0 { _, err = dao.NewStaffSalaryDao().Create(salary) } else { err = dao.NewStaffSalaryDao().Update(salary) } session.CheckDBError(err) } return } func (s *StaffSalary) Update(sess *session.AdminSession, req *api.UpdateSalaryReq) { salary, err := dao.NewStaffSalaryDao().Get(cast.ToInt64(req.Id)) session.CheckDBError(err) session.CheckNilError(salary, "工资单不存在") if req.OtherIncome != "" { salary.OtherSalary = cast.ToFloat64(req.OtherIncome) } if req.OtherDeduct != "" { salary.OtherDeduct = cast.ToFloat64(req.OtherDeduct) } err = dao.NewStaffSalaryDao().Update(salary) session.CheckDBError(err) } func (s *StaffSalary) Agent(cid int64, month string, ctx *gin.Context) { xls := ctx.Query("xls") staffSalarys, err := dao.NewStaffSalaryDao().QueryAll(cid, month) if err != nil { panic(config.ErrDb.New().Append(err)) } header := []string{"姓名", "身份证号", "电话", "应发工资", "社保扣除", "公积金扣除", "个税扣除", "实发工资"} datas := make([][]string, 0) for _, staff := range staffSalarys { userInfo, err := dao.NewStaffUserDao().Get(staff.UserId) if err != nil { log.Errorf("db error :%s", err.Error()) continue } if userInfo == nil { continue } userSalary := userInfo.GetSalary() if userSalary.Base == "" { continue } item := make([]string, 0) item = append(item, userInfo.Realname) item = append(item, cast.ToString(userInfo.Idno)) item = append(item, cast.ToString(userInfo.Phone)) item = append(item, cast.ToString(staff.GetShouldSalary())) item = append(item, cast.ToString(staff.SocialDeduct)) item = append(item, cast.ToString(staff.HouseDeduct)) item = append(item, cast.ToString(staff.PersonalDeduct)) item = append(item, cast.ToString(staff.GetRealSalary())) datas = append(datas, item) } if xls != "" { filename := fmt.Sprintf("agent_%s.xlsx", time.Now().Format("20060102_150405")) s.toExcel(filename, header, datas, ctx) os.Remove(filename) } else { links := make([]map[string]string, 0) links = append(links, map[string]string{ "url": "/staff/salary?type=agent&xls=1&cid=" + cast.ToString(cid), "name": "下载", }) links = append(links, map[string]string{ "url": "/staff/salary?type=bank&cid=" + cast.ToString(cid), "name": "银行", }) links = append(links, map[string]string{ "url": "/staff/salary?type=summary&cid=" + cast.ToString(cid), "name": "汇总", }) ctx.HTML(http.StatusOK, "salary.html", gin.H{ "title": month + "工资汇总", "header": header, "data": datas, "link": links, }) } } func (s *StaffSalary) Bank(cid int64, month string, ctx *gin.Context) { xls := ctx.Query("xls") staffSalarys, err := dao.NewStaffSalaryDao().QueryAll(cid, month) if err != nil { panic(config.ErrDb.New().Append(err)) } header := []string{"账号", "户名", "金额", "开户行", "开户地", "收款备注"} datas := make([][]string, 0) for _, staff := range staffSalarys { userInfo, err := dao.NewStaffUserDao().Get(staff.UserId) if err != nil { log.Errorf("db error :%s", err.Error()) continue } if userInfo == nil { continue } userSalary := userInfo.GetSalary() userPayee := userInfo.GetPayee() if userSalary.Base == "" { continue } item := make([]string, 0) item = append(item, userPayee.BankCard) item = append(item, userInfo.Realname) item = append(item, cast.ToString(staff.GetRealSalary())) item = append(item, cast.ToString(userPayee.BankName)) item = append(item, "重庆市") item = append(item, fmt.Sprintf("%s工资", month)) datas = append(datas, item) } if xls != "" { filename := fmt.Sprintf("bank_%s.xlsx", time.Now().Format("20060102_150405")) s.toExcel(filename, header, datas, ctx) os.Remove(filename) } else { links := make([]map[string]string, 0) links = append(links, map[string]string{ "url": "/staff/salary?type=bank&xls=1&cid=" + cast.ToString(cid), "name": "下载", }) links = append(links, map[string]string{ "url": "/staff/salary?type=summary&cid=" + cast.ToString(cid), "name": "汇总", }) links = append(links, map[string]string{ "url": "/staff/salary?type=agent&cid=" + cast.ToString(cid), "name": "代理", }) ctx.HTML(http.StatusOK, "salary.html", gin.H{ "title": month + "工资汇总", "header": header, "data": datas, "link": links, }) } } func (s *StaffSalary) Summary(cid int64, month string, ctx *gin.Context) { xls := ctx.Query("xls") staffSalarys, err := dao.NewStaffSalaryDao().QueryAll(cid, month) if err != nil { panic(config.ErrDb.New().Append(err)) } sort.Sort(model.StaffSalarySort(staffSalarys)) var header []string if cid == 1002 { header = []string{"姓名", "入职日期", "转正日期", "基本工资", "绩效工资", "出勤收入", "绩效收入", "奖金收入", "其他收入", "应出勤天数", "实际出勤天数", "请假天数", "实发工资", "状态"} } else { header = []string{"姓名", "入职日期", "转正日期", "基本工资", "绩效工资", "出勤收入", "绩效收入", "奖金收入", "其他收入", "社保扣除", "公积金扣除", "个税扣除", "应出勤天数", "实际出勤天数", "请假天数", "实发工资", "状态"} } datas := make([][]string, 0) summary := new(model.StaffSalary) totalCount := 0 for _, salary := range staffSalarys { userInfo, err := dao.NewStaffUserDao().Get(salary.UserId) if err != nil { log.Errorf("db error :%s", err.Error()) continue } if userInfo == nil { continue } userSalary := userInfo.GetSalary() //extra := make(map[string]interface{}) //json.Unmarshal([]byte(salary.Extra), &extra) item := make([]string, 0) item = append(item, userInfo.Realname) item = append(item, cast.ToString(userInfo.EntryDate)) item = append(item, cast.ToString(userInfo.OfficialDate)) item = append(item, userSalary.Base) item = append(item, userSalary.Target) item = append(item, cast.ToString(butil.FloatCut(salary.AttendSalary))) item = append(item, cast.ToString(butil.FloatCut(salary.TargetSalary))) item = append(item, cast.ToString(butil.FloatCut(salary.AwardSalary))) item = append(item, cast.ToString(butil.FloatCut(salary.OtherSalary))) if cid != 1002 { item = append(item, cast.ToString(butil.FloatCut(salary.SocialDeduct))) item = append(item, cast.ToString(butil.FloatCut(salary.HouseDeduct))) item = append(item, cast.ToString(butil.FloatCut(salary.PersonalDeduct))) } item = append(item, cast.ToString(salary.ShouldDay)) item = append(item, cast.ToString(butil.FloatCut(salary.AttendDay))) item = append(item, cast.ToString(butil.FloatCut(salary.HolidayDay))) item = append(item, cast.ToString(salary.GetRealSalary())) if cast.ToFloat64(salary.ShouldDay) != cast.ToFloat64(salary.AttendDay)+cast.ToFloat64(salary.HolidayDay) { item = append(item, "【异常】") } else { item = append(item, "") } totalCount += 1 datas = append(datas, item) summary.Salary += salary.Salary summary.TargetSalary += salary.TargetSalary summary.AttendSalary += salary.AttendSalary summary.AwardSalary += salary.AwardSalary summary.OtherSalary += salary.OtherSalary summary.SocialDeduct += salary.SocialDeduct summary.HouseDeduct += salary.HouseDeduct summary.PersonalDeduct += salary.PersonalDeduct summary.OtherDeduct += salary.OtherDeduct summary.AttendDay += salary.AttendDay summary.HolidayDay += salary.HolidayDay } summary.HolidayDay = butil.FloatCut(summary.HolidayDay) summary.Salary = butil.FloatCut(summary.Salary) summary.TargetSalary = butil.FloatCut(summary.TargetSalary) summary.AttendSalary = butil.FloatCut(summary.AttendSalary) summary.AwardSalary = butil.FloatCut(summary.AwardSalary) summary.SocialDeduct = butil.FloatCut(summary.SocialDeduct) summary.HouseDeduct = butil.FloatCut(summary.HouseDeduct) summary.PersonalDeduct = butil.FloatCut(summary.PersonalDeduct) summary.OtherDeduct = butil.FloatCut(summary.OtherDeduct) if cid != 1002 { datas = append(datas, []string{"合计", cast.ToString(totalCount), "-", cast.ToString(summary.Salary), "-", cast.ToString(summary.AttendSalary), cast.ToString(summary.TargetSalary), cast.ToString(summary.AwardSalary), cast.ToString(summary.OtherSalary), cast.ToString(summary.SocialDeduct), cast.ToString(summary.HouseDeduct), cast.ToString(summary.PersonalDeduct), "-", "-", cast.ToString(summary.HolidayDay), cast.ToString(butil.FloatCut(summary.GetRealSalary())), "-"}) } else { datas = append(datas, []string{"合计", cast.ToString(totalCount), "-", cast.ToString(summary.Salary), "-", cast.ToString(summary.AttendSalary), cast.ToString(summary.TargetSalary), cast.ToString(summary.AwardSalary), cast.ToString(summary.OtherSalary), "-", "-", cast.ToString(summary.HolidayDay), cast.ToString(butil.FloatCut(summary.GetRealSalary())), "-"}) } if xls != "" { filename := fmt.Sprintf("summary_%s.xlsx", time.Now().Format("20060102_150405")) s.toExcel(filename, header, datas, ctx) os.Remove(filename) } else { links := make([]map[string]string, 0) links = append(links, map[string]string{ "url": "/staff/salary?type=bank&cid=" + cast.ToString(cid), "name": "银行", }) links = append(links, map[string]string{ "url": "/staff/salary?type=agent&cid=" + cast.ToString(cid), "name": "代理", }) ctx.HTML(http.StatusOK, "salary.html", gin.H{ "title": month + "工资汇总", "header": header, "data": datas, "link": links, }) } } func (s *StaffSalary) toExcel(filePath string, header []string, datas [][]string, ctx *gin.Context) { f := excelize.NewFile() //声明工作表的名称 sheetName := "工资单" f.SetSheetName("Sheet1", sheetName) f.SetSheetRow(sheetName, "A1", &header) for i, data := range datas { f.SetSheetRow(sheetName, fmt.Sprintf("A%d", i+2), &data) } if err := f.SaveAs(filePath); err != nil { panic(config.ErrInternal.New().Append(err)) } ctx.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filePath)) ctx.Writer.Header().Add("Content-Type", "application/msexcel") ctx.File(filePath) }