|
|
package service
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
"github.com/linmadan/egglib-go/core/application"
|
|
|
"github.com/linmadan/egglib-go/utils/excel"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/ecelData/command"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils/converter"
|
|
|
)
|
|
|
|
|
|
type importAttendance struct {
|
|
|
ProductDate string `json:"productDate"` //日期
|
|
|
WorkshopName string `json:"workshopName"` //车间名称
|
|
|
LineName string `json:"lineName"` //线别名称
|
|
|
SectionName string `json:"sectionName"` //工位名称
|
|
|
WorkerName string `json:"workerName"` //工人姓名
|
|
|
AttendanceType string `json:"attendanceType"` //考勤类型 正常 支援
|
|
|
SignIn string `json:"signIn"` //上岗时间
|
|
|
SignOut string `json:"signOut"` //离岗时间
|
|
|
BreakTime string `json:"breakTime"` //休息时间
|
|
|
FailReason string `json:"failReason"` //数据校验失败的理由
|
|
|
}
|
|
|
|
|
|
func (data *importAttendance) validField() error {
|
|
|
if len(data.ProductDate) == 0 {
|
|
|
return errors.New("日期未填写。")
|
|
|
}
|
|
|
if len(data.WorkerName) == 0 {
|
|
|
return errors.New("车间名称未填写。")
|
|
|
}
|
|
|
if len(data.LineName) == 0 {
|
|
|
return errors.New("线别名称未填写。")
|
|
|
}
|
|
|
if len(data.SectionName) == 0 {
|
|
|
return errors.New("工位名称未填写。")
|
|
|
}
|
|
|
if len(data.WorkerName) == 0 {
|
|
|
return errors.New("工人姓名未填写。")
|
|
|
}
|
|
|
if len(data.AttendanceType) == 0 {
|
|
|
return errors.New("类型未填写。")
|
|
|
}
|
|
|
if len(data.SignIn) == 0 {
|
|
|
return errors.New("上岗时间未填写。")
|
|
|
}
|
|
|
if len(data.SignOut) == 0 {
|
|
|
return errors.New("下岗时间未填写。")
|
|
|
}
|
|
|
if len(data.BreakTime) == 0 {
|
|
|
return errors.New("休息时间未填写。")
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
func (srv ExcelDataService) ImportDataAttendance(importDataCommand *command.ImportDataCommand) (interface{}, error) {
|
|
|
excelImport := excel.NewExcelImport()
|
|
|
excelImport.RowBegin = 2 //第二行开始读取
|
|
|
excelImport.DataFields = []excel.DataField{
|
|
|
{EnName: "ProductDate", CnName: "日期"},
|
|
|
{EnName: "WorkshopName", CnName: "车间"},
|
|
|
{EnName: "LineName", CnName: "线别"},
|
|
|
{EnName: "SectionName", CnName: "工段"},
|
|
|
{EnName: "WorkerName", CnName: "姓名"},
|
|
|
{EnName: "AttendanceType", CnName: "类别"},
|
|
|
{EnName: "SignIn", CnName: "上岗时间"},
|
|
|
{EnName: "SignOut", CnName: "离岗时间"},
|
|
|
{EnName: "BreakTime", CnName: "休息时长(小时)"},
|
|
|
}
|
|
|
excelData, err := converter.OpenImportFileFromIoReader(excelImport, importDataCommand.Reader, importDataCommand.FileExt) //excelImport.OpenExcelFromIoReader(importDataCommand.Reader)
|
|
|
if err != nil {
|
|
|
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
|
|
|
}
|
|
|
items := make([]importAttendance, 0)
|
|
|
for _, v := range excelData {
|
|
|
item := importAttendance{
|
|
|
ProductDate: strings.TrimSpace(v["ProductDate"]),
|
|
|
WorkshopName: strings.TrimSpace(v["WorkshopName"]),
|
|
|
LineName: strings.TrimSpace(v["LineName"]),
|
|
|
SectionName: strings.TrimSpace(v["SectionName"]),
|
|
|
WorkerName: strings.TrimSpace(v["WorkerName"]),
|
|
|
AttendanceType: strings.TrimSpace(v["AttendanceType"]),
|
|
|
SignIn: strings.TrimSpace(v["SignIn"]),
|
|
|
SignOut: strings.TrimSpace(v["SignOut"]),
|
|
|
BreakTime: strings.TrimSpace(v["BreakTime"]),
|
|
|
FailReason: "",
|
|
|
}
|
|
|
items = append(items, item)
|
|
|
}
|
|
|
failRows, err := srv.BatchAddAttendance(*importDataCommand.Operator, items)
|
|
|
if err != nil {
|
|
|
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
|
|
|
}
|
|
|
return srv.importResultWithHeader(excelImport.DataFields, failRows, len(items)), nil
|
|
|
}
|
|
|
|
|
|
// BatchAddAttendance 工时管理,导入工时数据
|
|
|
func (srv ExcelDataService) BatchAddAttendance(operate domain.OperateInfo, param []importAttendance) (
|
|
|
failRows []interface{}, err error) {
|
|
|
transactionContext, err := factory.CreateTransactionContext(nil)
|
|
|
if err != nil {
|
|
|
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
|
|
|
}
|
|
|
if err := transactionContext.StartTransaction(); err != nil {
|
|
|
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
|
|
|
}
|
|
|
defer func() {
|
|
|
transactionContext.RollbackTransaction()
|
|
|
}()
|
|
|
//车间数据
|
|
|
//生产班组 数据
|
|
|
productGroupRepo, _ := factory.CreateProductGroupRepository(map[string]interface{}{
|
|
|
"transactionContext": transactionContext,
|
|
|
})
|
|
|
|
|
|
_, productGroupList, err := productGroupRepo.Find(map[string]interface{}{
|
|
|
"companyId": operate.CompanyId,
|
|
|
"orgId": operate.OrgId,
|
|
|
})
|
|
|
if err != nil {
|
|
|
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
|
|
|
}
|
|
|
//车间名称+/+线别名称+/+工段名称 作为键名
|
|
|
workStationMap := map[string]*domain.WorkStation{}
|
|
|
//车间名称+/+工人名 作为键名
|
|
|
workerMap := map[string][]*domain.User{}
|
|
|
for _, v := range productGroupList {
|
|
|
workStationName := strings.Join([]string{
|
|
|
v.WorkStation.WorkshopName, v.WorkStation.LineName, v.WorkStation.SectionName,
|
|
|
}, "/")
|
|
|
workStationMap[workStationName] = v.WorkStation
|
|
|
for _, vv := range v.GroupMembers {
|
|
|
k := v.WorkStation.WorkshopName + "/" + vv.UserName
|
|
|
isIn := false
|
|
|
for _, vvv := range workerMap[k] {
|
|
|
if vvv.UserId == vv.UserId {
|
|
|
isIn = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !isIn {
|
|
|
workerMap[k] = append(workerMap[k], vv)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
var attendanceList []*domain.ProductAttendanceRecord
|
|
|
nowTime := time.Now()
|
|
|
//检查导入的数据
|
|
|
for i := range param {
|
|
|
//检查字段值
|
|
|
err := param[i].validField()
|
|
|
if err != nil {
|
|
|
param[i].FailReason = err.Error()
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
//检查日期格式
|
|
|
productDate, err := time.ParseInLocation("2006-01-02", param[i].ProductDate, time.Local)
|
|
|
if err != nil {
|
|
|
param[i].FailReason = "日期格式错误,例 2006-01-02。"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
//检查类型
|
|
|
attendanceType := 0
|
|
|
// 考勤类型 1.正常 2.支援
|
|
|
if param[i].AttendanceType == "支援" {
|
|
|
attendanceType = 1
|
|
|
} else if param[i].AttendanceType == "正常" {
|
|
|
attendanceType = 2
|
|
|
} else {
|
|
|
param[i].FailReason = "类型内容异常。"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
//检查上岗时间格式
|
|
|
signIn, err := time.ParseInLocation("15:04:05", param[i].SignIn, time.Local)
|
|
|
if err != nil {
|
|
|
param[i].FailReason = "上岗时间格式错误,例 15:04:05。"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
signIn = productDate.Add(time.Duration(signIn.Second()) * time.Second)
|
|
|
//检查离岗时间格式
|
|
|
signOut, err := time.ParseInLocation("15:04:05", param[i].SignOut, time.Local)
|
|
|
if err != nil {
|
|
|
param[i].FailReason = "离岗时间格式错误,例 15:04:05。"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
signOut = productDate.Add(time.Duration(signOut.Second()) * time.Second)
|
|
|
//检查员工姓名
|
|
|
var worker *domain.User
|
|
|
workKey := param[i].WorkshopName + "/" + param[i].WorkerName
|
|
|
if u, ok := workerMap[workKey]; ok {
|
|
|
if len(u) > 1 {
|
|
|
param[i].FailReason = "当前车间存在重复的用户名"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
worker = u[0]
|
|
|
} else {
|
|
|
param[i].FailReason = "当前车间不存在用户" + param[i].WorkerName
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
//检查工位
|
|
|
var workStation *domain.WorkStation
|
|
|
workStationName := param[i].WorkerName + "/" + param[i].LineName + "/" + param[i].SectionName
|
|
|
if v, ok := workStationMap[workStationName]; ok {
|
|
|
workStation = v
|
|
|
} else {
|
|
|
param[i].FailReason = "车间、线别、工段不存在"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
//休息时间(小时)
|
|
|
beakTime, err := strconv.ParseFloat(param[i].BreakTime, 64)
|
|
|
if err != nil {
|
|
|
param[i].FailReason = "休息时长填写错误"
|
|
|
failRows = append(failRows, param[i])
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
tempItem := &domain.ProductAttendanceRecord{
|
|
|
ProductAttendanceId: 0,
|
|
|
CompanyId: operate.CompanyId,
|
|
|
OrgId: operate.OrgId,
|
|
|
AttendanceType: attendanceType,
|
|
|
ProductWorker: worker,
|
|
|
WorkStation: workStation,
|
|
|
SignIn: signIn,
|
|
|
SignOut: signOut,
|
|
|
AttendanceStatus: domain.AttendanceAutoApproved, //自动审核
|
|
|
WorkTimeBefore: 0.0,
|
|
|
WorkTimeAfter: 0.0,
|
|
|
CreatedAt: nowTime,
|
|
|
UpdatedAt: nowTime,
|
|
|
DeletedAt: time.Time{},
|
|
|
ProductDate: productDate,
|
|
|
}
|
|
|
//计算工时
|
|
|
workTime := tempItem.ComputeWorkTime(beakTime)
|
|
|
tempItem.WorkTimeAfter = workTime
|
|
|
tempItem.WorkTimeBefore = workTime
|
|
|
attendanceList = append(attendanceList, tempItem)
|
|
|
}
|
|
|
if len(failRows) > 0 {
|
|
|
return failRows, nil
|
|
|
}
|
|
|
attendanceRepo, _ := factory.CreateProductAttendanceRecordRepository(map[string]interface{}{
|
|
|
"transactionContext": transactionContext,
|
|
|
})
|
|
|
for i := range attendanceList {
|
|
|
_, err = attendanceRepo.Save(attendanceList[i])
|
|
|
if err != nil {
|
|
|
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
|
|
|
}
|
|
|
}
|
|
|
if err := transactionContext.CommitTransaction(); err != nil {
|
|
|
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
|
|
|
}
|
|
|
return nil, err
|
|
|
} |
...
|
...
|
|