enterprise/server/service/staff_salary.go

323 lines
11 KiB
Go

package service
import (
"encoding/json"
butil "enterprise/base/util"
"enterprise/common/config"
"enterprise/common/dao"
"enterprise/common/model"
"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 (s *StaffSalary) History(ctx *gin.Context) {
username := ctx.Query("username")
staffSalarys, err := dao.NewStaffSalaryDao().Query("", username, nil)
if err != nil {
panic(config.ErrDb.New().Append(err))
}
header := []string{"月份", "基本工资", "绩效工资", "出勤工资", "奖金", "社保扣除", "公积金扣除", "个税扣除", "应出勤天数", "实际出勤天数", "补卡天数", "请假天数", "实发工资"}
datas := make([][]string, 0)
for _, staff := range staffSalarys {
baseInfo, err := dao.NewStaffInfoDao().GetByUsername(staff.Username)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
if baseInfo == nil {
continue
}
extra := make(map[string]interface{})
json.Unmarshal([]byte(staff.Extra), &extra)
item := make([]string, 0)
item = append(item, cast.ToString(staff.Month))
item = append(item, cast.ToString(staff.BaseSalary))
item = append(item, cast.ToString(butil.FloatCut(staff.PerfSalary)))
item = append(item, cast.ToString(butil.FloatCut(staff.AttendSalary)))
item = append(item, cast.ToString(butil.FloatCut(staff.AwardSalary)))
item = append(item, cast.ToString(staff.SocialInsurence))
item = append(item, cast.ToString(staff.HouseFund))
item = append(item, cast.ToString(staff.PersonalTax))
item = append(item, cast.ToString(staff.TotalDay))
item = append(item, cast.ToString(staff.RealDay))
item = append(item, cast.ToString(extra["approvalCheckinDay"]))
item = append(item, cast.ToString(staff.Holiday))
item = append(item, cast.ToString(staff.GetRealSalary()))
datas = append(datas, item)
}
ctx.HTML(http.StatusOK, "salary.html", gin.H{
"title": username + "工资汇总",
"header": header,
"data": datas,
})
}
func (s *StaffSalary) Agent(month string, ctx *gin.Context) {
xls := ctx.Query("xls")
staffSalarys, err := dao.NewStaffSalaryDao().Query(month, "", nil)
if err != nil {
panic(config.ErrDb.New().Append(err))
}
header := []string{"姓名", "身份证号", "电话", "应发工资", "社保扣除", "公积金扣除", "个税扣除", "实发工资"}
datas := make([][]string, 0)
for _, staff := range staffSalarys {
baseInfo, err := dao.NewStaffInfoDao().GetByUsername(staff.Username)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
if baseInfo == nil {
continue
}
if staff.BaseSalary == 0 {
continue
}
item := make([]string, 0)
item = append(item, baseInfo.Realname)
item = append(item, cast.ToString(baseInfo.Idno))
item = append(item, cast.ToString(baseInfo.Phone))
item = append(item, cast.ToString(staff.GetShouldSalary()))
item = append(item, cast.ToString(staff.SocialInsurence))
item = append(item, cast.ToString(staff.HouseFund))
item = append(item, cast.ToString(staff.PersonalTax))
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",
"name": "下载",
})
links = append(links, map[string]string{
"url": "/staff/salary?type=bank",
"name": "银行",
})
links = append(links, map[string]string{
"url": "/staff/salary?type=summary",
"name": "汇总",
})
ctx.HTML(http.StatusOK, "salary.html", gin.H{
"title": month + "工资汇总",
"header": header,
"data": datas,
"link": links,
})
}
}
func (s *StaffSalary) Bank(month string, ctx *gin.Context) {
xls := ctx.Query("xls")
staffSalarys, err := dao.NewStaffSalaryDao().Query(month, "", nil)
if err != nil {
panic(config.ErrDb.New().Append(err))
}
header := []string{"账号", "户名", "金额", "开户行", "开户地", "收款备注"}
datas := make([][]string, 0)
for _, staff := range staffSalarys {
baseInfo, err := dao.NewStaffInfoDao().GetByUsername(staff.Username)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
if baseInfo == nil {
continue
}
if staff.BaseSalary == 0 {
continue
}
item := make([]string, 0)
item = append(item, baseInfo.BankCard)
item = append(item, baseInfo.Realname)
item = append(item, cast.ToString(staff.GetRealSalary()))
item = append(item, cast.ToString(baseInfo.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",
"name": "下载",
})
links = append(links, map[string]string{
"url": "/staff/salary?type=summary",
"name": "汇总",
})
links = append(links, map[string]string{
"url": "/staff/salary?type=agent",
"name": "代理",
})
ctx.HTML(http.StatusOK, "salary.html", gin.H{
"title": month + "工资汇总",
"header": header,
"data": datas,
"link": links,
})
}
}
func (s *StaffSalary) Summary(month string, ctx *gin.Context) {
xls := ctx.Query("xls")
masterBank := ""
staffSalarys, err := dao.NewStaffSalaryDao().Query(month, "", &masterBank)
if err != nil {
panic(config.ErrDb.New().Append(err))
}
sort.Sort(model.StaffSalarySort(staffSalarys))
header := []string{"姓名", "身份证号", "入职日期", "转正日期", "基本工资", "绩效工资", "出勤工资", "附属工资", "奖金", "社保扣除", "公积金扣除", "个税扣除", "应出勤天数", "实际出勤天数", "出勤率", "补卡天数", "请假天数", "实发工资", "状态"}
datas := make([][]string, 0)
summary := new(model.StaffSalary)
totalCount := 0
totalSlaveSalary := float64(0)
for _, staff := range staffSalarys {
baseInfo, err := dao.NewStaffInfoDao().GetByUsername(staff.Username)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
if baseInfo == nil {
continue
}
extra := make(map[string]interface{})
json.Unmarshal([]byte(staff.Extra), &extra)
item := make([]string, 0)
item = append(item, baseInfo.Realname)
item = append(item, cast.ToString(baseInfo.Idno))
item = append(item, cast.ToString(baseInfo.EntryDate))
item = append(item, cast.ToString(baseInfo.OfficialDate))
item = append(item, cast.ToString(staff.BaseSalary))
item = append(item, cast.ToString(butil.FloatCut(staff.PerfSalary)))
item = append(item, cast.ToString(butil.FloatCut(staff.AttendSalary)))
slaveSalary := float64(0)
info, _ := dao.NewStaffInfoDao().GetByUsername(staff.Username)
if info != nil {
slaveSalary = service.NewStaff(info, nil).GetSlaveSalary(month)
}
item = append(item, cast.ToString(butil.FloatCut(slaveSalary)))
item = append(item, cast.ToString(butil.FloatCut(staff.AwardSalary)))
item = append(item, cast.ToString(staff.SocialInsurence))
item = append(item, cast.ToString(staff.HouseFund))
item = append(item, cast.ToString(staff.PersonalTax))
item = append(item, cast.ToString(staff.TotalDay))
item = append(item, cast.ToString(staff.RealDay))
item = append(item, fmt.Sprintf("%d%%", int(100*staff.RealDay/staff.TotalDay)))
item = append(item, cast.ToString(extra["approvalCheckinDay"]))
item = append(item, cast.ToString(staff.Holiday))
item = append(item, cast.ToString(staff.GetRealSalary()+slaveSalary))
if staff.TotalDay != cast.ToFloat64(staff.RealDay)+cast.ToFloat64(staff.Holiday) {
item = append(item, "【异常】")
} else {
item = append(item, "")
}
//item = append(item, fmt.Sprintf("https://e.batiao8.com/staff/salary/history?username=%s", baseInfo.Username))
totalCount += 1
totalSlaveSalary += slaveSalary
datas = append(datas, item)
summary.BaseSalary += staff.BaseSalary
summary.PerfSalary += staff.PerfSalary
summary.AttendSalary += staff.AttendSalary
summary.AwardSalary += staff.AwardSalary
summary.SocialInsurence += staff.SocialInsurence
summary.PersonalTax += staff.PersonalTax
summary.Holiday += staff.Holiday
summary.HouseFund += staff.HouseFund
}
summary.Holiday = butil.FloatCut(summary.Holiday)
summary.BaseSalary = butil.FloatCut(summary.BaseSalary)
summary.PerfSalary = butil.FloatCut(summary.PerfSalary)
summary.AttendSalary = butil.FloatCut(summary.AttendSalary)
summary.AwardSalary = butil.FloatCut(summary.AwardSalary)
summary.SocialInsurence = butil.FloatCut(summary.SocialInsurence)
summary.HouseFund = butil.FloatCut(summary.HouseFund)
summary.PersonalTax = butil.FloatCut(summary.PersonalTax)
datas = append(datas, []string{"合计", cast.ToString(totalCount), "-", "-",
cast.ToString(summary.BaseSalary), cast.ToString(summary.PerfSalary), cast.ToString(summary.AttendSalary), cast.ToString(totalSlaveSalary),
cast.ToString(summary.AwardSalary), cast.ToString(summary.SocialInsurence), cast.ToString(summary.HouseFund),
cast.ToString(summary.PersonalTax), "-", "-", "-", "-", cast.ToString(summary.Holiday),
cast.ToString(butil.FloatCut(summary.GetRealSalary() + totalSlaveSalary)), "-"})
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",
"name": "银行",
})
links = append(links, map[string]string{
"url": "/staff/salary?type=agent",
"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)
}