| | |
| | | FileTemplateCategory_JialianOutput = 15 //嘉联出库 |
| | | FileTemplateCategory_JialianAttendance = 16 //嘉联-员工考勤 |
| | | ) |
| | | |
| | | const ( |
| | | DailySilkProduction = "日产丝量" |
| | | WasteSilkQuantity = "野纤数量" |
| | | RawSilkUnitPrice = "生丝单价" |
| | | WasteSilkUnitPrice = "野纤单价" |
| | | BucketCount = "桶数(日)" |
| | | AttendanceDays = "出勤天数" |
| | | GroupAverageMonthlyWage = "同组挡车工月平均工资" |
| | | GroupCarHeadWage = "同组车头工工资" |
| | | WeekdayOvertimeHours = "工作日加班时长" |
| | | FullAttendanceAward = "满勤奖" |
| | | WeekendOvertimeHours = "休息日加班时长" |
| | | LeaveDays = "请假天数" |
| | | ApprenticeDays = "带徒天数" |
| | | TotalAttendanceDays = "出勤天数" |
| | | Seniority = "工龄" |
| | | ) |
| | |
| | | for _, worker := range workers { |
| | | if attendance.WorkerId == worker.ID { |
| | | attendance.WorkTypeId = worker.WorkTypeId |
| | | attendance.PhoneNum = worker.PhoneNum |
| | | break |
| | | } |
| | | } |
New file |
| | |
| | | package controllers |
| | | |
| | | import ( |
| | | "github.com/gin-gonic/gin" |
| | | ) |
| | | |
| | | type ReportFormsController struct { |
| | | } |
| | | |
| | | // SalaryReportForms |
| | | // |
| | | // @Tags 报表管理 |
| | | // @Summary 薪资报表 |
| | | // @Produce application/json |
| | | // @Param object body request.SalaryReportForms true "参数" |
| | | // @Param Authorization header string true "token" |
| | | // @Success 200 {object} util.ResponseList{data=[]models.WorkTypeManage} "成功" |
| | | // @Router /api-jl/v1/forms/salaryReportForms [post] |
| | | func (slf ReportFormsController) SalaryReportForms(c *gin.Context) { |
| | | //var params request.SalaryReportForms |
| | | //err := c.BindJSON(¶ms) |
| | | //if err != nil { |
| | | // util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") |
| | | // return |
| | | //} |
| | | //workers, err := models.NewWorkerSearch().SetPage(params.Page, params.PageSize).FindNotTotal() |
| | | //if err != nil { |
| | | // util.ResponseFormat(c, code.RequestParamError, err) |
| | | // return |
| | | //} |
| | | |
| | | } |
New file |
| | |
| | | package request |
| | | |
| | | type SalaryReportForms struct { |
| | | PageInfo |
| | | Month string `json:"month"` |
| | | } |
| | |
| | | } |
| | | |
| | | type SalaryTypeValue struct { |
| | | Id uint `json:"id"` |
| | | Name string `json:"name"` //名称 |
| | | IsDefault bool `json:"isDefault"` //是否可编辑 |
| | | } |
New file |
| | |
| | | package response |
| | | |
| | | type SalaryReportForms struct { |
| | | WorkerName string `json:"workerName"` |
| | | WorkerId string `json:"workerId"` |
| | | Phone string `json:"phone"` |
| | | WorkType string `json:"workType"` |
| | | } |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "类型不能为空") |
| | | return |
| | | } |
| | | types := make([]*models.MiniDict, 0) |
| | | for _, value := range params.Values { |
| | | miniDicts, err := models.NewMiniDictSearch().SetType(params.Type).FindNotTotal() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, err) |
| | | return |
| | | } |
| | | dicts := params.Values |
| | | add := make([]*models.MiniDict, 0) |
| | | del := make([]uint, 0) |
| | | update := make([]*models.MiniDict, 0) |
| | | for _, mini := range miniDicts { |
| | | flag := true |
| | | for i, value := range dicts { |
| | | var dict models.MiniDict |
| | | dict.Name = value.Name |
| | | dict.IsDefault = value.IsDefault |
| | | dict.Type = params.Type |
| | | if value.Id == 0 { |
| | | add = append(add, &dict) |
| | | flag = false |
| | | if i < len(dicts)-1 { |
| | | dicts = append(dicts[:i], dicts[i+1:]...) |
| | | } else { |
| | | dicts = dicts[:i] |
| | | } |
| | | break |
| | | } else if value.Id == mini.ID { |
| | | update = append(update, &dict) |
| | | flag = false |
| | | if i < len(dicts)-1 { |
| | | dicts = append(dicts[:i], dicts[i+1:]...) |
| | | } else { |
| | | dicts = dicts[:i] |
| | | } |
| | | break |
| | | } |
| | | } |
| | | if flag { |
| | | del = append(del, mini.ID) |
| | | } |
| | | } |
| | | //新增的 |
| | | for _, value := range dicts { |
| | | var dict models.MiniDict |
| | | dict.Name = value.Name |
| | | dict.IsDefault = value.IsDefault |
| | | dict.Type = params.Type |
| | | types = append(types, &dict) |
| | | add = append(add, &dict) |
| | | } |
| | | |
| | | err = models.WithTransaction(func(db *gorm.DB) error { |
| | | err = models.NewMiniDictSearch().SetOrm(db).SetType(params.Type).Delete() |
| | | if err != nil { |
| | | return err |
| | | if len(del) > 0 { |
| | | err = models.NewMiniDictSearch().SetOrm(db).SetIds(del).Delete() |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | err = models.NewMiniDictSearch().SetOrm(db).CreateBatch(types) |
| | | if err != nil { |
| | | return err |
| | | if len(update) > 0 { |
| | | err = models.NewMiniDictSearch().SetOrm(db).SaveBatch(update) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | if len(add) > 0 { |
| | | err = models.NewMiniDictSearch().SetOrm(db).CreateBatch(add) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | } |
| | | |
| | | return nil |
| | | }) |
| | | if err != nil { |
| | |
| | | |
| | | require ( |
| | | basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25 |
| | | github.com/Knetic/govaluate v3.0.0+incompatible |
| | | github.com/dgrijalva/jwt-go v3.2.0+incompatible |
| | | github.com/gin-gonic/gin v1.9.1 |
| | | github.com/golang-jwt/jwt/v4 v4.5.0 |
| | | github.com/nsqio/go-nsq v1.1.0 |
| | | github.com/shopspring/decimal v1.3.1 |
| | | github.com/spf13/cast v1.6.0 |
| | | github.com/spf13/viper v1.18.2 |
| | | github.com/swaggo/files v1.0.1 |
| | | github.com/swaggo/gin-swagger v1.6.0 |
| | |
| | | github.com/sagikazarmark/slog-shim v0.1.0 // indirect |
| | | github.com/sourcegraph/conc v0.3.0 // indirect |
| | | github.com/spf13/afero v1.11.0 // indirect |
| | | github.com/spf13/cast v1.6.0 // indirect |
| | | github.com/spf13/pflag v1.0.5 // indirect |
| | | github.com/subosito/gotenv v1.6.0 // indirect |
| | | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect |
| | |
| | | basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25 h1:sZyNfIISgP1eoY94LG48Kav6HYVLem6EzaEbCeXlcXQ= |
| | | basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25/go.mod h1:1RnwEtePLR7ATQorQTxdgvs1o7uuUy1Vw8W7GYtVnoY= |
| | | github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= |
| | | github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= |
| | | github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= |
| | | github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= |
| | | github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= |
| | |
| | | WorkType WorkTypeManage `json:"workType" gorm:"foreignKey:WorkTypeId"` |
| | | Status constvar.AttendanceStatus `json:"status" gorm:"type:int(11);comment:状态"` |
| | | OverTimeDuration decimal.Decimal `json:"overTimeDuration" gorm:"type:decimal(20,2);comment:加班时长"` |
| | | PhoneNum string `gorm:"type:varchar(191);comment:手机号" json:"phoneNum"` |
| | | } |
| | | AttendanceManageSearch struct { |
| | | AttendanceManage |
| | |
| | | MiniDictSearch struct { |
| | | MiniDict |
| | | Order string |
| | | Ids []uint |
| | | PageNum int |
| | | PageSize int |
| | | Orm *gorm.DB |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *MiniDictSearch) SetIds(ids []uint) *MiniDictSearch { |
| | | slf.Ids = ids |
| | | return slf |
| | | } |
| | | |
| | | func (slf *MiniDictSearch) SetType(tp constvar.MiniDictType) *MiniDictSearch { |
| | | slf.Type = tp |
| | | return slf |
| | |
| | | |
| | | if slf.ID > 0 { |
| | | db = db.Where("id = ?", slf.ID) |
| | | } |
| | | |
| | | if len(slf.Ids) > 0 { |
| | | db = db.Where("id in (?)", slf.Ids) |
| | | } |
| | | |
| | | if slf.Type > 0 { |
| | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *MiniDictSearch) SaveBatch(record []*MiniDict) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Omit("CreatedAt").Save(record).Error; err != nil { |
| | | return fmt.Errorf("save err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *MiniDictSearch) UpdateByMap(upMap map[string]interface{}) error { |
| | | var ( |
| | | db = slf.build() |
| | |
| | | } |
| | | RawSilkPriceStandardSearch struct { |
| | | RawSilkPriceStandard |
| | | Order string |
| | | PageNum int |
| | | PageSize int |
| | | Orm *gorm.DB |
| | | Order string |
| | | PageNum int |
| | | PageSize int |
| | | MarketNames []string |
| | | Orm *gorm.DB |
| | | } |
| | | ) |
| | | |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *RawSilkPriceStandardSearch) SetMarketNames(names []string) *RawSilkPriceStandardSearch { |
| | | slf.MarketNames = names |
| | | return slf |
| | | } |
| | | |
| | | func (slf *RawSilkPriceStandardSearch) build() *gorm.DB { |
| | | db := slf.Orm.Table(slf.TableName()) |
| | | |
| | |
| | | db = db.Where("id = ?", slf.ID) |
| | | } |
| | | |
| | | if len(slf.MarketNames) > 0 { |
| | | db = db.Where("market_name in (?)", slf.MarketNames) |
| | | } |
| | | |
| | | return db |
| | | } |
| | | |
New file |
| | |
| | | package models |
| | | |
| | | import ( |
| | | "fmt" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | "silkserver/pkg/mysqlx" |
| | | ) |
| | | |
| | | type ( |
| | | //SalaryDetails 薪资明细表 |
| | | SalaryDetails struct { |
| | | gorm.Model |
| | | SalaryDetailsId uint `json:"SalaryDetailsId" gorm:"type:int(11);comment:薪资报表id"` |
| | | SalaryTypeId uint `json:"salaryTypeId" gorm:"type:int(11);comment:薪资类型id"` |
| | | SalaryType MiniDict `json:"salaryType" gorm:"foreignKey:SalaryTypeId;references:ID"` |
| | | Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,3);comment:工资值"` |
| | | } |
| | | SalaryDetailsSearch struct { |
| | | SalaryDetails |
| | | PageNum int |
| | | PageSize int |
| | | Preload bool |
| | | Orm *gorm.DB |
| | | } |
| | | ) |
| | | |
| | | func (slf SalaryDetails) TableName() string { |
| | | return "salary_details" |
| | | } |
| | | |
| | | func NewSalaryDetailsSearch() *SalaryDetailsSearch { |
| | | return &SalaryDetailsSearch{Orm: mysqlx.GetDB()} |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) SetOrm(tx *gorm.DB) *SalaryDetailsSearch { |
| | | slf.Orm = tx |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) SetPage(page, size int) *SalaryDetailsSearch { |
| | | slf.PageNum, slf.PageSize = page, size |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) SetPreload(preload bool) *SalaryDetailsSearch { |
| | | slf.Preload = preload |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) build() *gorm.DB { |
| | | var db = slf.Orm.Table(slf.TableName()) |
| | | |
| | | if slf.Preload { |
| | | db = db.Model(SalaryDetails{}).Preload("SalaryType") |
| | | } |
| | | |
| | | return db |
| | | } |
| | | |
| | | // Create 单条插入 |
| | | func (slf *SalaryDetailsSearch) Create(record *SalaryDetails) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Create(record).Error; err != nil { |
| | | return fmt.Errorf("create err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | // CreateBatch 批量插入 |
| | | func (slf *SalaryDetailsSearch) CreateBatch(record []*SalaryDetails) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Create(record).Error; err != nil { |
| | | return fmt.Errorf("create err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) Save(record *SalaryDetails) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Omit("CreatedAt").Save(record).Error; err != nil { |
| | | return fmt.Errorf("save err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) UpdateByMap(upMap map[string]interface{}) error { |
| | | var ( |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Updates(upMap).Error; err != nil { |
| | | return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) Delete() error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Unscoped().Delete(&SalaryDetails{}).Error; err != nil { |
| | | return err |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) Find() ([]*SalaryDetails, int64, error) { |
| | | var ( |
| | | records = make([]*SalaryDetails, 0) |
| | | total int64 |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Count(&total).Error; err != nil { |
| | | return records, total, fmt.Errorf("find count err: %v", err) |
| | | } |
| | | if slf.PageNum*slf.PageSize > 0 { |
| | | db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) |
| | | } |
| | | if err := db.Find(&records).Error; err != nil { |
| | | return records, total, fmt.Errorf("find records err: %v", err) |
| | | } |
| | | |
| | | return records, total, nil |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) FindNotTotal() ([]*SalaryDetails, error) { |
| | | var ( |
| | | records = make([]*SalaryDetails, 0) |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Find(&records).Error; err != nil { |
| | | return records, fmt.Errorf("find records err: %v", err) |
| | | } |
| | | |
| | | return records, nil |
| | | } |
| | | |
| | | func (slf *SalaryDetailsSearch) Count() (int64, error) { |
| | | var ( |
| | | total int64 |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Count(&total).Error; err != nil { |
| | | return total, fmt.Errorf("find count err: %v", err) |
| | | } |
| | | return total, nil |
| | | } |
| | |
| | | //SalaryPlan 薪资方案 |
| | | SalaryPlan struct { |
| | | gorm.Model |
| | | Name string `json:"name" gorm:"type:varchar(255);comment:薪资方案名称"` |
| | | SalaryType string `json:"salaryType" gorm:"type:varchar(255);comment:薪资类型"` |
| | | Name string `json:"name" gorm:"type:varchar(255);comment:薪资方案名称"` |
| | | SalaryTypeId uint `json:"salaryTypeId" gorm:"type:int(11);comment:薪资类型id"` |
| | | SalaryType MiniDict `json:"salaryType" gorm:"foreignKey:SalaryTypeId;references:ID"` |
| | | //SalaryType string `json:"salaryType" gorm:"type:varchar(255);comment:薪资类型"` |
| | | SalaryFormula string `json:"salaryFormula" gorm:"type:varchar(255);comment:薪资公式"` |
| | | Cycle string `json:"cycle" gorm:"type:varchar(255);comment:周期"` |
| | | CreateTime string `json:"createTime" gorm:"type:varchar(255);comment:添加时间"` |
| | |
| | | } |
| | | |
| | | if slf.Preload { |
| | | db = db.Model(&SalaryPlan{}).Preload("WorkTypes") |
| | | db = db.Model(&SalaryPlan{}).Preload("WorkTypes").Preload("SalaryType") |
| | | } |
| | | |
| | | return db |
New file |
| | |
| | | package models |
| | | |
| | | import ( |
| | | "fmt" |
| | | "github.com/shopspring/decimal" |
| | | "gorm.io/gorm" |
| | | "silkserver/pkg/mysqlx" |
| | | ) |
| | | |
| | | type ( |
| | | // SalaryReportForm 薪资报表 |
| | | SalaryReportForm struct { |
| | | gorm.Model |
| | | WorkerId string `json:"workerId" gorm:"type:varchar(255);comment:人员id"` |
| | | WorkerName string `json:"workerName" gorm:"type:varchar(255);comment:人员姓名"` |
| | | Phone string `json:"phone" gorm:"type:varchar(255);comment:电话"` |
| | | WorkTypeId uint `json:"workTypeId" gorm:"type:int(11);comment:工种类型id"` |
| | | WorkType WorkTypeManage `json:"workType" gorm:"foreignKey:WorkTypeId;references:ID"` |
| | | Month string `json:"month" gorm:"type:varchar(255);comment:月份"` |
| | | IssueSalary decimal.Decimal `json:"issueSalary" gorm:"type:decimal(20,3);comment:应发工资"` |
| | | Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"` |
| | | Details []SalaryDetails `json:"details" gorm:"foreignKey:SalaryReportFormId;references:Id"` |
| | | } |
| | | SalaryReportFormSearch struct { |
| | | SalaryReportForm |
| | | PageNum int |
| | | PageSize int |
| | | Preload bool |
| | | Orm *gorm.DB |
| | | } |
| | | ) |
| | | |
| | | func (slf SalaryReportForm) TableName() string { |
| | | return "salary_report_form" |
| | | } |
| | | |
| | | func NewSalaryReportFormSearch() *SalaryReportFormSearch { |
| | | return &SalaryReportFormSearch{Orm: mysqlx.GetDB()} |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) SetOrm(tx *gorm.DB) *SalaryReportFormSearch { |
| | | slf.Orm = tx |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) SetPage(page, size int) *SalaryReportFormSearch { |
| | | slf.PageNum, slf.PageSize = page, size |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) SetPreload(preload bool) *SalaryReportFormSearch { |
| | | slf.Preload = preload |
| | | return slf |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) build() *gorm.DB { |
| | | var db = slf.Orm.Table(slf.TableName()) |
| | | |
| | | if slf.Preload { |
| | | db = db.Model(SalaryReportForm{}).Preload("Details").Preload("WorkType") |
| | | } |
| | | |
| | | return db |
| | | } |
| | | |
| | | // Create 单条插入 |
| | | func (slf *SalaryReportFormSearch) Create(record *SalaryReportForm) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Create(record).Error; err != nil { |
| | | return fmt.Errorf("create err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | // CreateBatch 批量插入 |
| | | func (slf *SalaryReportFormSearch) CreateBatch(record []*SalaryReportForm) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Create(record).Error; err != nil { |
| | | return fmt.Errorf("create err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) Save(record *SalaryReportForm) error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Omit("CreatedAt").Save(record).Error; err != nil { |
| | | return fmt.Errorf("save err: %v, record: %+v", err, record) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) UpdateByMap(upMap map[string]interface{}) error { |
| | | var ( |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Updates(upMap).Error; err != nil { |
| | | return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) Delete() error { |
| | | var db = slf.build() |
| | | |
| | | if err := db.Unscoped().Delete(&SalaryReportForm{}).Error; err != nil { |
| | | return err |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) Find() ([]*SalaryReportForm, int64, error) { |
| | | var ( |
| | | records = make([]*SalaryReportForm, 0) |
| | | total int64 |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Count(&total).Error; err != nil { |
| | | return records, total, fmt.Errorf("find count err: %v", err) |
| | | } |
| | | if slf.PageNum*slf.PageSize > 0 { |
| | | db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) |
| | | } |
| | | if err := db.Find(&records).Error; err != nil { |
| | | return records, total, fmt.Errorf("find records err: %v", err) |
| | | } |
| | | |
| | | return records, total, nil |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) FindNotTotal() ([]*SalaryReportForm, error) { |
| | | var ( |
| | | records = make([]*SalaryReportForm, 0) |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Find(&records).Error; err != nil { |
| | | return records, fmt.Errorf("find records err: %v", err) |
| | | } |
| | | |
| | | return records, nil |
| | | } |
| | | |
| | | func (slf *SalaryReportFormSearch) Count() (int64, error) { |
| | | var ( |
| | | total int64 |
| | | db = slf.build() |
| | | ) |
| | | |
| | | if err := db.Count(&total).Error; err != nil { |
| | | return total, fmt.Errorf("find count err: %v", err) |
| | | } |
| | | return total, nil |
| | | } |
| | |
| | | ) |
| | | |
| | | type ( |
| | | //WorkTypeManage 工种管理 |
| | | WorkTypeManage struct { |
| | | gorm.Model |
| | | WorkName string `json:"workName" gorm:"type:varchar(255);comment:工种名称"` |
| | |
| | | PageNum int |
| | | PageSize int |
| | | Preload bool |
| | | Ids []uint |
| | | Orm *gorm.DB |
| | | } |
| | | ) |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *WorkTypeManageSearch) SetIds(ids []uint) *WorkTypeManageSearch { |
| | | slf.Ids = ids |
| | | return slf |
| | | } |
| | | |
| | | func (slf *WorkTypeManageSearch) build() *gorm.DB { |
| | | var db = slf.Orm.Table(slf.TableName()) |
| | | |
| | |
| | | db = db.Where("id = ?", slf.ID) |
| | | } |
| | | |
| | | if len(slf.Ids) > 0 { |
| | | db = db.Where("id in (?)", slf.Ids) |
| | | } |
| | | |
| | | if slf.Preload { |
| | | db = db.Model(WorkTypeManage{}).Preload("SalaryPlans") |
| | | } |
| | |
| | | } |
| | | YieldRegisterItemSearch struct { |
| | | YieldRegisterItem |
| | | Orm *gorm.DB |
| | | YieldRegisterIds []uint |
| | | CarNumbers []int |
| | | Orm *gorm.DB |
| | | } |
| | | ) |
| | | |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *YieldRegisterItemSearch) SetYieldRegisterIds(ids []uint) *YieldRegisterItemSearch { |
| | | slf.YieldRegisterIds = ids |
| | | return slf |
| | | } |
| | | func (slf *YieldRegisterItemSearch) SetCarNumbers(carNumbers []int) *YieldRegisterItemSearch { |
| | | slf.CarNumbers = carNumbers |
| | | return slf |
| | | } |
| | | |
| | | func (slf *YieldRegisterItemSearch) build() *gorm.DB { |
| | | db := slf.Orm.Table(slf.TableName()) |
| | | |
| | |
| | | db = db.Where("yield_register_id = ?", slf.YieldRegisterId) |
| | | } |
| | | |
| | | if len(slf.YieldRegisterIds) > 0 { |
| | | db = db.Where("yield_register_id in (?)", slf.YieldRegisterIds) |
| | | } |
| | | |
| | | if len(slf.CarNumbers) > 0 { |
| | | db = db.Where("car_number in (?)", slf.CarNumbers) |
| | | } |
| | | |
| | | return db |
| | | } |
| | | |
New file |
| | |
| | | package task |
| | | |
| | | import ( |
| | | "github.com/shopspring/decimal" |
| | | "silkserver/constvar" |
| | | "silkserver/models" |
| | | "silkserver/pkg/logx" |
| | | "silkserver/utils" |
| | | "strings" |
| | | "time" |
| | | ) |
| | | |
| | | func SalaryStatistics() { |
| | | lastMonthStart, lastMonthEnd := GetLastMonthPeriod() |
| | | month := lastMonthStart.Format("2006-01") |
| | | |
| | | //查询考勤统计 |
| | | startStr := lastMonthStart.Format("2006-01-02") |
| | | endStr := lastMonthEnd.Format("2006-01-02") |
| | | attendances, err := models.NewAttendanceManageSearch().SetMonth(month).FindNotTotal() |
| | | if err != nil { |
| | | logx.Error("SalaryStatistics 查询考勤统计 err: " + err.Error()) |
| | | return |
| | | } |
| | | |
| | | var reportForms []*models.SalaryReportForm |
| | | workTypeIdMap := make(map[uint]uint) |
| | | dataMap := make(map[string]utils.SalaryCalculateData) |
| | | for _, attendance := range attendances { |
| | | var rf models.SalaryReportForm |
| | | var data utils.SalaryCalculateData |
| | | if _, ok := dataMap[attendance.WorkerId]; ok { |
| | | data = dataMap[attendance.WorkerId] |
| | | } |
| | | rf.WorkerId = attendance.WorkerId |
| | | rf.WorkerName = attendance.WorkerName |
| | | rf.WorkTypeId = attendance.WorkTypeId |
| | | rf.Month = month |
| | | rf.Phone = attendance.PhoneNum |
| | | if attendance.WorkTypeId > 0 { |
| | | workTypeIdMap[attendance.WorkTypeId] = attendance.WorkTypeId |
| | | } |
| | | //工作日加班时长 |
| | | data.WeekdayOvertimeHours = data.WeekdayOvertimeHours.Add(attendance.OverTimeDuration) |
| | | //出勤天数 |
| | | if attendance.Status != constvar.Vacation { |
| | | data.TotalAttendanceDays = data.TotalAttendanceDays + 1 |
| | | } |
| | | dataMap[attendance.WorkerId] = data |
| | | reportForms = append(reportForms, &rf) |
| | | } |
| | | workTypeIds := make([]uint, 0) |
| | | for _, v := range workTypeIdMap { |
| | | workTypeIds = append(workTypeIds, v) |
| | | } |
| | | |
| | | //查询工种的薪资方案和新增类型 |
| | | workTypeManages, err := models.NewWorkTypeManageSearch().SetIds(workTypeIds).SetPreload(true).FindNotTotal() |
| | | if err != nil { |
| | | logx.Error("SalaryStatistics 查询工种的薪资方案和新增类型 err: " + err.Error()) |
| | | return |
| | | } |
| | | for _, form := range reportForms { |
| | | details := make([]models.SalaryDetails, 0) |
| | | issueSalary := decimal.NewFromInt(0) |
| | | for _, manage := range workTypeManages { |
| | | if form.WorkTypeId == manage.ID { |
| | | data := dataMap[form.WorkerId] |
| | | for _, plan := range manage.SalaryPlans { |
| | | formula := strings.ReplaceAll(plan.SalaryFormula, ",", "") |
| | | var detail models.SalaryDetails |
| | | detail.SalaryTypeId = plan.SalaryTypeId |
| | | amount := decimal.NewFromInt(0) |
| | | f := constvar.DailySilkProduction + "*" + constvar.RawSilkUnitPrice |
| | | if strings.Contains(formula, f) { |
| | | data, err = GetDailySilkProduction(startStr, endStr, form.WorkerId, data) |
| | | if err != nil { |
| | | logx.Error("SalaryStatistics 统计薪资出错 err: " + err.Error()) |
| | | } else { |
| | | amount, err = utils.CalculateSalary(data, formula) |
| | | if err != nil { |
| | | logx.Error("SalaryStatistics 计算薪资出错 err: " + err.Error()) |
| | | } |
| | | } |
| | | } |
| | | detail.Amount = amount |
| | | issueSalary = issueSalary.Add(amount) |
| | | details = append(details, detail) |
| | | } |
| | | } |
| | | } |
| | | form.Details = details |
| | | form.IssueSalary = issueSalary |
| | | } |
| | | |
| | | //插入数据库 |
| | | err = models.NewSalaryReportFormSearch().CreateBatch(reportForms) |
| | | if err != nil { |
| | | logx.Error("SalaryStatistics 插入数据库出错 err: " + err.Error()) |
| | | } |
| | | } |
| | | |
| | | func GetDailySilkProduction(start, end, workerId string, data utils.SalaryCalculateData) (utils.SalaryCalculateData, error) { |
| | | //查询机台管理 |
| | | var cars []models.WorkerPosition |
| | | err := models.NewWorkerPositionSearch().Orm.Table("silk_worker_position").Where("worker_id = ? and start_date >= ? and "+ |
| | | "end_date <= ?", workerId, start, end).Find(&cars).Error |
| | | if err != nil { |
| | | return data, err |
| | | } |
| | | endCarMap := make(map[int]int) |
| | | groupMap := make(map[int]int) |
| | | workshopMap := make(map[string]string) |
| | | for _, car := range cars { |
| | | endCarMap[car.EndWorkerPosition] = car.EndWorkerPosition |
| | | groupMap[car.WorkshopGroup] = car.WorkshopGroup |
| | | workshopMap[car.Workshop] = car.Workshop |
| | | } |
| | | groups := make([]int, 0) |
| | | workshops := make([]string, 0) |
| | | endCars := make([]int, 0) |
| | | for _, v := range endCarMap { |
| | | endCars = append(endCars, v) |
| | | } |
| | | for _, v := range workshopMap { |
| | | workshops = append(workshops, v) |
| | | } |
| | | for _, v := range groupMap { |
| | | groups = append(groups, v) |
| | | } |
| | | |
| | | //查询产量登记表 |
| | | var yield []models.YieldRegister |
| | | err = models.NewYieldRegisterSearch().Orm.Table("silk_yield_register").Where("workshop_number in (?) and group_number "+ |
| | | "in (?) and create_time >= ? and create_time <= ?", workshops, groups, start, end).Find(&yield).Error |
| | | if err != nil { |
| | | return data, err |
| | | } |
| | | yieldRegisterIds := make([]uint, 0) |
| | | for _, register := range yield { |
| | | yieldRegisterIds = append(yieldRegisterIds, register.ID) |
| | | } |
| | | yieldMap := make(map[string]decimal.Decimal) |
| | | items, err := models.NewYieldRegisterItemSearch().SetYieldRegisterIds(yieldRegisterIds).SetCarNumbers(endCars).FindNotTotal() |
| | | if err != nil { |
| | | return data, err |
| | | } |
| | | for _, register := range yield { |
| | | for _, item := range items { |
| | | if register.ID == item.YieldRegisterId { |
| | | yieldMap[register.CreateTime] = item.PeopleYield |
| | | } |
| | | } |
| | | } |
| | | //查询纤度登记表 |
| | | var fineness []models.FinenessRegister |
| | | markets := make([]string, 0) |
| | | err = models.NewFinenessRegisterSearch().Orm.Table("silk_fineness_register").Where("workshop in (?) and workshop_group "+ |
| | | "in (?) and finish_date >= ? and finish_date <= ?", workshops, groups, start, end).Find(&fineness).Error |
| | | if err != nil { |
| | | return data, err |
| | | } |
| | | finenessIds := make([]uint, 0) |
| | | for _, register := range fineness { |
| | | finenessIds = append(finenessIds, register.ID) |
| | | markets = append(markets, register.Market) |
| | | } |
| | | var checkItems []models.FinenessCheckItem |
| | | err = models.NewFinenessCheckItemSearch().Orm.Table("silk_fineness_check_item").Where("fineness_register_id in (?) and "+ |
| | | "position in (?)", finenessIds, endCars).Find(&checkItems).Error |
| | | if err != nil { |
| | | return data, err |
| | | } |
| | | checkMap := make(map[string]string) |
| | | marketMap := make(map[string]string) |
| | | for _, item := range checkItems { |
| | | for _, register := range fineness { |
| | | if item.FinenessRegisterID == register.ID { |
| | | checkMap[register.FinishDate] = item.FinenessGrade |
| | | marketMap[register.FinishDate] = register.Market |
| | | break |
| | | } |
| | | } |
| | | } |
| | | //查询不同庄口下的生丝定价 |
| | | find, _, err := models.NewRawSilkPriceStandardSearch().SetMarketNames(markets).Find() |
| | | if err != nil { |
| | | return data, err |
| | | } |
| | | //计算每日工资 |
| | | total := decimal.NewFromInt(0) |
| | | for date, amount := range yieldMap { |
| | | grade := checkMap[date] |
| | | market := marketMap[date] |
| | | for _, standard := range find { |
| | | if standard.MarketName == market && standard.RawSilkGrade == grade { |
| | | h := amount.Mul(standard.PayStandard) |
| | | total = total.Add(h) |
| | | break |
| | | } |
| | | } |
| | | } |
| | | data.DailySilkProduction = total |
| | | data.RawSilkUnitPrice = decimal.NewFromInt(1) |
| | | return data, nil |
| | | } |
| | | |
| | | // GetLastMonthPeriod 返回上个月的月初时间和月末时间 |
| | | func GetLastMonthPeriod() (time.Time, time.Time) { |
| | | // 获取当前时间 |
| | | now := time.Now() |
| | | |
| | | // 计算上个月的年份和月份 |
| | | lastMonth := now.AddDate(0, -1, 0) |
| | | lastYear, lastMonthNum, _ := lastMonth.Date() |
| | | |
| | | // 获取上个月的第一天的日期(即上个月月初) |
| | | firstDayOfLastMonth := time.Date(lastYear, lastMonthNum, 1, 0, 0, 0, 0, now.Location()) |
| | | |
| | | // 获取本月第一天的日期(即本月月初) |
| | | firstDayOfThisMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) |
| | | |
| | | // 上个月月末时间即为本月月初减去一秒 |
| | | lastDayOfLastMonth := firstDayOfThisMonth.Add(-time.Second) |
| | | |
| | | return firstDayOfLastMonth, lastDayOfLastMonth |
| | | } |
New file |
| | |
| | | package utils |
| | | |
| | | import ( |
| | | "github.com/Knetic/govaluate" |
| | | "github.com/shopspring/decimal" |
| | | "strconv" |
| | | "strings" |
| | | ) |
| | | |
| | | // 薪资计算数据 |
| | | type SalaryCalculateData struct { |
| | | DailySilkProduction decimal.Decimal `json:"dailySilkProduction"` // 日产丝量 |
| | | WasteSilkQuantity decimal.Decimal `json:"wasteSilkQuantity"` // 野纤数量 |
| | | RawSilkUnitPrice decimal.Decimal `json:"rawSilkUnitPrice"` // 生丝单价 |
| | | WasteSilkUnitPrice decimal.Decimal `json:"wasteSilkUnitPrice"` // 野纤单价 |
| | | BucketCount decimal.Decimal `json:"bucketCount"` //桶数(日) |
| | | AttendanceDays int `json:"attendanceDays"` // 出勤天数 |
| | | GroupAverageMonthlyWage decimal.Decimal `json:"groupAverageMonthlyWage"` //同组挡车工月平均工资 |
| | | GroupCarHeadWage decimal.Decimal `json:"groupCarHeadWage"` //同组车头工工资 |
| | | |
| | | WeekdayOvertimeHours decimal.Decimal `json:"weekdayOvertimeHours"` // 工作日加班时长 |
| | | FullAttendanceAward int `json:"FullAttendanceAward"` // 满勤奖 |
| | | WeekendOvertimeHours decimal.Decimal `json:"weekendOvertimeHours"` // 休息日加班时长 |
| | | LeaveDays decimal.Decimal `json:"LeaveDays"` //请假天数 |
| | | ApprenticeDays decimal.Decimal `json:"apprenticeDays"` // 带徒天数 |
| | | TotalAttendanceDays int `json:"totalAttendanceDays"` // 出勤天数 |
| | | Seniority decimal.Decimal `json:"seniority"` // 工龄 |
| | | } |
| | | |
| | | // CalculateSalary 计算工资的函数 |
| | | func CalculateSalary(date SalaryCalculateData, formula string) (decimal.Decimal, error) { |
| | | // 替换公式中的变量 |
| | | formula = strings.ReplaceAll(formula, "日产丝量", date.DailySilkProduction.String()) |
| | | formula = strings.ReplaceAll(formula, "野纤数量", date.WasteSilkQuantity.String()) |
| | | formula = strings.ReplaceAll(formula, "生丝单价", date.RawSilkUnitPrice.String()) |
| | | formula = strings.ReplaceAll(formula, "野纤单价", date.WasteSilkUnitPrice.String()) |
| | | formula = strings.ReplaceAll(formula, "桶数(日)", date.BucketCount.String()) |
| | | formula = strings.ReplaceAll(formula, "出勤天数", strconv.Itoa(date.AttendanceDays)) |
| | | formula = strings.ReplaceAll(formula, "同组挡车工月平均工资", date.GroupAverageMonthlyWage.String()) |
| | | formula = strings.ReplaceAll(formula, "同组车头工工资", date.GroupCarHeadWage.String()) |
| | | |
| | | formula = strings.ReplaceAll(formula, "工作日加班时长", date.WeekdayOvertimeHours.String()) |
| | | formula = strings.ReplaceAll(formula, "满勤奖", strconv.Itoa(date.FullAttendanceAward)) |
| | | formula = strings.ReplaceAll(formula, "休息日加班时长", date.WeekendOvertimeHours.String()) |
| | | formula = strings.ReplaceAll(formula, "请假天数", date.LeaveDays.String()) |
| | | formula = strings.ReplaceAll(formula, "带徒天数", date.ApprenticeDays.String()) |
| | | formula = strings.ReplaceAll(formula, "出勤天数", strconv.Itoa(date.TotalAttendanceDays)) |
| | | formula = strings.ReplaceAll(formula, "工龄", date.Seniority.String()) |
| | | |
| | | // 使用 govaluate 库计算表达式 |
| | | wage := decimal.NewFromInt(0) |
| | | expression, err := govaluate.NewEvaluableExpression(formula) |
| | | if err != nil { |
| | | return wage, err |
| | | } |
| | | parameters := make(map[string]interface{}) |
| | | result, err := expression.Evaluate(parameters) |
| | | if err != nil { |
| | | return wage, err |
| | | } |
| | | wage = decimal.NewFromFloat(result.(float64)) |
| | | return wage, nil |
| | | } |