作者 yangfu

feat: 版本 1.0.3

- 工时优化
- 撤回生产记录
@@ -4,4 +4,25 @@ @@ -4,4 +4,25 @@
4 create UNIQUE INDEX idx_unq_product_material_group_company_id_org_id_material_group_number on manufacture.product_material_group using btree(company_id,org_id,material_group_number,deleted_at); 4 create UNIQUE INDEX idx_unq_product_material_group_company_id_org_id_material_group_number on manufacture.product_material_group using btree(company_id,org_id,material_group_number,deleted_at);
5 5
6 -- 表product_material 增加唯一索引 idx_unq_product_material_company_id_material_number 6 -- 表product_material 增加唯一索引 idx_unq_product_material_company_id_material_number
7 -create UNIQUE INDEX idx_unq_product_material_company_id_material_number on manufacture.product_material using btree(company_id,material_number,deleted_at);  
  7 +create UNIQUE INDEX idx_unq_product_material_company_id_material_number on manufacture.product_material using btree(company_id,material_number,deleted_at);
  8 +
  9 +
  10 +-- 菜单脚本
  11 +
  12 +INSERT INTO "users"."menu"("menu_id", "parent_id", "menu_name", "code", "access_code", "menu_type", "icon", "sort", "remark", "category", "parent_path", "is_publish", "enable_status", "link") VALUES (269, 175, '物料信息', 'BUSINESS_ALLIED-MANUFACTURING_BASIC_MATERIAL', '', 'menu', 'https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20220302/object/1646211608_CH2pTwT56j6TXfRdYhGxBfKRNFfpzWKE.png', 3, '', '7', '38,174,175', 1, 0, NULL);
  13 +
  14 +INSERT INTO "users"."menu"("menu_id", "parent_id", "menu_name", "code", "access_code", "menu_type", "icon", "sort", "remark", "category", "parent_path", "is_publish", "enable_status", "link") VALUES (270, 269, '删除', 'BUSINESS_ALLIED-MANUFACTURING_BASIC_MATERIAL_DEL', '', 'button', '', 1, '', '7', '38,174,175,269', 1, 2, NULL);
  15 +
  16 +INSERT INTO "users"."menu"("menu_id", "parent_id", "menu_name", "code", "access_code", "menu_type", "icon", "sort", "remark", "category", "parent_path", "is_publish", "enable_status", "link") VALUES (271, 269, '新增', 'BUSINESS_ALLIED-MANUFACTURING_BASIC_MATERIAL_ADD', '', 'button', '', 1, '', '7', '38,174,175,269', 1, 2, NULL);
  17 +
  18 +INSERT INTO "users"."menu"("menu_id", "parent_id", "menu_name", "code", "access_code", "menu_type", "icon", "sort", "remark", "category", "parent_path", "is_publish", "enable_status", "link") VALUES (272, 269, '编辑', 'BUSINESS_ALLIED-MANUFACTURING_BASIC_MATERIAL_EDIT', '', 'button', '', 1, '', '7', '38,174,175,269', 1, 2, NULL);
  19 +
  20 +INSERT INTO "users"."menu"("menu_id", "parent_id", "menu_name", "code", "access_code", "menu_type", "icon", "sort", "remark", "category", "parent_path", "is_publish", "enable_status", "link") VALUES (273, 269, '查看', 'BUSINESS_ALLIED-MANUFACTURING_BASIC_MATERIAL_VIEW', '', 'button', '', 1, '', '7', '38,174,175,269', 1, 2, NULL);
  21 +
  22 +UPDATE "users"."menu" SET "parent_id" = 175, "menu_name" = '产品管理', "code" = 'BUSINESS_ALLIED-MANUFACTURING_BASIC_PRODUCT', "access_code" = '', "menu_type" = 'menu', "icon" = 'https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20220302/object/1646211429_wMrRfxYMyhBySwWkysZaXBbfDapSppBs.png', "sort" = 4, "remark" = '', "category" = '7', "parent_path" = '38,174,175', "is_publish" = 1, "enable_status" = 0, "link" = NULL WHERE "menu_id" = 186;
  23 +
  24 +UPDATE "users"."menu" SET "parent_id" = 175, "menu_name" = '设备档案', "code" = 'BUSINESS_ALLIED-MANUFACTURING_BASIC_DEVICE', "access_code" = '', "menu_type" = 'menu', "icon" = 'https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20220302/object/1646211439_WaAKb65X7wX2zjsMExDyy56XRnTRAmPD.png', "sort" = 5, "remark" = '', "category" = '7', "parent_path" = '38,174,175', "is_publish" = 1, "enable_status" = 0, "link" = NULL WHERE "menu_id" = 193;
  25 +
  26 +UPDATE "users"."menu" SET "parent_id" = 175, "menu_name" = '工厂日历', "code" = 'BUSINESS_ALLIED-MANUFACTURING_BASIC_CALENDAR', "access_code" = '', "menu_type" = 'menu', "icon" = 'https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20220302/object/1646211448_GBY3HhbPpNnNpnGPWGE6wETW6F6THfr4.png', "sort" = 6, "remark" = '', "category" = '7', "parent_path" = '38,174,175', "is_publish" = 1, "enable_status" = 0, "link" = NULL WHERE "menu_id" = 199;
  27 +
  28 +UPDATE "users"."menu" SET "parent_id" = 175, "menu_name" = '单位换算', "code" = 'BUSINESS_ALLIED-MANUFACTURING_BASIC_UNIT-CONVERSION', "access_code" = '', "menu_type" = 'menu', "icon" = 'https://timeless-world.oss-cn-shenzhen.aliyuncs.com/open-api/dev_online/20220302/object/1646211456_cKxKHHXHQnM3e7RZNxdkZ3n7ZXJjdKba.png', "sort" = 7, "remark" = '', "category" = '7', "parent_path" = '38,174,175', "is_publish" = 1, "enable_status" = 0, "link" = NULL WHERE "menu_id" = 203;
@@ -130,8 +130,8 @@ func (productMaterialGroupService *ProductMaterialGroupService) ListProductMater @@ -130,8 +130,8 @@ func (productMaterialGroupService *ProductMaterialGroupService) ListProductMater
130 } 130 }
131 131
132 // 移除物料分组服务 132 // 移除物料分组服务
133 -func (productMaterialGroupService *ProductMaterialGroupService) RemoveProductMaterialGroup(removeProductMaterialGroupCommand *command.RemoveProductMaterialGroupCommand) (interface{}, error) {  
134 - if err := removeProductMaterialGroupCommand.ValidateCommand(); err != nil { 133 +func (productMaterialGroupService *ProductMaterialGroupService) RemoveProductMaterialGroup(operateInfo *domain.OperateInfo, cmd *command.RemoveProductMaterialGroupCommand) (interface{}, error) {
  134 + if err := cmd.ValidateCommand(); err != nil {
135 return nil, application.ThrowError(application.ARG_ERROR, err.Error()) 135 return nil, application.ThrowError(application.ARG_ERROR, err.Error())
136 } 136 }
137 transactionContext, err := factory.CreateTransactionContext(nil) 137 transactionContext, err := factory.CreateTransactionContext(nil)
@@ -144,29 +144,37 @@ func (productMaterialGroupService *ProductMaterialGroupService) RemoveProductMat @@ -144,29 +144,37 @@ func (productMaterialGroupService *ProductMaterialGroupService) RemoveProductMat
144 defer func() { 144 defer func() {
145 transactionContext.RollbackTransaction() 145 transactionContext.RollbackTransaction()
146 }() 146 }()
147 - var productMaterialGroupRepository domain.ProductMaterialGroupRepository  
148 - if value, err := factory.CreateProductMaterialGroupRepository(map[string]interface{}{  
149 - "transactionContext": transactionContext,  
150 - }); err != nil { 147 +
  148 + materialService, _ := domainService.NewPGMaterialService(transactionContext.(*pgTransaction.TransactionContext))
  149 + _, ids, err := materialService.AllMaterialGroupChild(operateInfo, cmd.ProductMaterialGroupId)
  150 + if err != nil {
151 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 151 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
152 - } else {  
153 - productMaterialGroupRepository = value  
154 } 152 }
155 - productMaterialGroup, err := productMaterialGroupRepository.FindOne(map[string]interface{}{"productMaterialGroupId": removeProductMaterialGroupCommand.ProductMaterialGroupId}) 153 + if len(ids) == 0 {
  154 + return nil, nil
  155 + }
  156 + productMaterialRepository, _, _ := factory.FastProductMaterial(transactionContext, 0)
  157 + count, _, err := productMaterialRepository.Find(map[string]interface{}{"productMaterialGroupIds": ids, "limit": 1})
156 if err != nil { 158 if err != nil {
157 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 159 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
158 } 160 }
159 - if productMaterialGroup == nil {  
160 - return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("已删除 %s", string(removeProductMaterialGroupCommand.ProductMaterialGroupId))) 161 + if count >= 1 {
  162 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "请处理当前分组下存在的物料信息")
161 } 163 }
162 - if productMaterialGroup, err := productMaterialGroupRepository.Remove(productMaterialGroup); err != nil {  
163 - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())  
164 - } else {  
165 - if err := transactionContext.CommitTransaction(); err != nil {  
166 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 164 +
  165 + for _, id := range ids {
  166 + productMaterialGroupRepository, productMaterialGroup, err := factory.FastProductMaterialGroup(transactionContext, id)
  167 + if err != nil {
  168 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  169 + }
  170 + if _, err = productMaterialGroupRepository.Remove(productMaterialGroup); err != nil {
  171 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
167 } 172 }
168 - return productMaterialGroup, nil  
169 } 173 }
  174 + if err := transactionContext.CommitTransaction(); err != nil {
  175 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  176 + }
  177 + return nil, nil
170 } 178 }
171 179
172 // 更新物料分组服务 180 // 更新物料分组服务
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type CancelProductRecordCommand struct {
  12 + // 生产记录ID
  13 + ProductRecordId int `cname:"生产记录ID" json:"productRecordId" valid:"Required"`
  14 +}
  15 +
  16 +func (cancelProductRecordCommand *CancelProductRecordCommand) Valid(validation *validation.Validation) {
  17 + //validation.SetError("CustomValid", "未实现的自定义认证")
  18 +}
  19 +
  20 +func (cancelProductRecordCommand *CancelProductRecordCommand) ValidateCommand() error {
  21 + valid := validation.Validation{}
  22 + b, err := valid.Valid(cancelProductRecordCommand)
  23 + if err != nil {
  24 + return err
  25 + }
  26 + if !b {
  27 + elem := reflect.TypeOf(cancelProductRecordCommand).Elem()
  28 + for _, validErr := range valid.Errors {
  29 + field, isExist := elem.FieldByName(validErr.Field)
  30 + if isExist {
  31 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  32 + } else {
  33 + return fmt.Errorf(validErr.Message)
  34 + }
  35 + }
  36 + }
  37 + return nil
  38 +}
  1 +package dto
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/utils/xtime"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
  7 +)
  8 +
  9 +// HistoryProductRecord 历史生成记录
  10 +type HistoryProductRecord struct {
  11 + // 生产记录ID
  12 + ProductRecordId int `json:"productRecordId,omitempty"`
  13 + // 批号
  14 + BatchNumber string `json:"batchNumber,omitempty"`
  15 + // 计划的产品名称
  16 + PlanProductName string `json:"planProductName,omitempty"`
  17 + // 创建时间
  18 + CreatedAt string `json:"createdAt,omitempty"`
  19 + // 生产记录类型:1:领料 2:退料 4:称重 8:二级品称重
  20 + ProductRecordType int `json:"productRecordType"`
  21 + // 生产工人
  22 + ProductWorker *domain.User `json:"productWorker,omitempty"`
  23 + // 产能 - 审核前
  24 + Weight float64 `json:"weight"`
  25 + // 状态 1:未审核 2:已审核 3:已撤回 4:已记录
  26 + Status int `json:"status"`
  27 +}
  28 +
  29 +func (d *HistoryProductRecord) LoadDto(m *domain.ProductRecord) *HistoryProductRecord {
  30 + d.ProductRecordId = m.ProductRecordId
  31 + d.ProductWorker = m.ProductWorker
  32 + d.Weight = utils.Round(m.ProductRecordInfo.WeighBefore, 1)
  33 + d.Status = m.ProductRecordInfo.ApproveStatus
  34 + d.PlanProductName = m.ProductRecordInfo.PlanProductName
  35 + d.BatchNumber = m.ProductRecordInfo.BatchNumber
  36 + d.CreatedAt = m.CreatedAt.Local().Format("2006-01-02 15:04:05")
  37 + d.ProductRecordType = m.ProductRecordType
  38 + if m.ProductRecordType != domain.RecordTypeSecondLevelWeigh && m.ProductRecordInfo.ApproveStatus == domain.ProductRecordNotApprove && !xtime.BeginningOfDay().Equal(xtime.New(m.CreatedAt).BeginningOfDay()) {
  39 + d.Status = domain.ProductRecordLogged
  40 + }
  41 + return d
  42 +}
  1 +package query
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/linmadan/egglib-go/utils/xtime"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
  8 + "reflect"
  9 + "strings"
  10 + "time"
  11 +
  12 + "github.com/beego/beego/v2/core/validation"
  13 +)
  14 +
  15 +type HistoryProductRecordQuery struct {
  16 + // 查询偏离量
  17 + Offset int `cname:"查询偏离量" json:"offset"`
  18 + // 查询限制
  19 + Limit int `cname:"查询限制" json:"limit"`
  20 + // 当前公司
  21 + CompanyId int `cname:"当前公司" json:"companyId,omitempty" valid:"Required"`
  22 + // 当前登录的组织
  23 + OrgId int `cname:"当前登录的组织" json:"orgId,omitempty"`
  24 + // 匹配多个组织
  25 + InOrgIds []int `cname:"匹配多个组织" json:"inOrgIds,omitempty"`
  26 + // 页码
  27 + PageNumber int `cname:"页码" json:"pageNumber,omitempty"`
  28 + // 页数
  29 + PageSize int `cname:"页数" json:"pageSize,omitempty"`
  30 + // 车间名称
  31 + //WorkshopName string `cname:"车间名称" json:"workshopName"`
  32 + // 批号
  33 + //BatchNumber string `cname:"批号" json:"batchNumber"`
  34 + // 姓名
  35 + //UserName string `cname:"姓名" json:"userName"`
  36 + // 生产记录类型:1:领料 2:退料 4:称重 8:二级品称重
  37 + ProductRecordType int `cname:"生产记录类型:1:领料 2:退料 4:称重 8:二级品称重" json:"productRecordType"`
  38 + // 生产线名称
  39 + //LineName string `cname:"生产线名称" json:"lineName,omitempty"`
  40 + // 工段名称
  41 + //SectionName string `cname:"工段名称" json:"sectionName,omitempty"`
  42 + // 员工类型 1:固定 2:派遣 3.临时
  43 + //EmployeeType int `cname:"员工类型 1:固定 2:派遣 3.临时" json:"employeeType"`
  44 + // 开始时间
  45 + //BeginTime string `cname:"开始时间" json:"beginTime"`
  46 + // 结束时间
  47 + //EndTime string `cname:"结束时间" json:"endTime"`
  48 +
  49 + // 上一次记录ID
  50 + LastProductRecordId int `cname:"上一次记录ID" json:"lastProductRecordId"`
  51 + // 日期
  52 + Date string `cname:"日期" json:"date"`
  53 + // 生产员工ID
  54 + ProductWorkerId int `cname:"生产员工ID" json:"productWorkerId"`
  55 + // 状态 0:全部 1:未审核 2:已审核 3:已撤回 4:已记录
  56 + Status int `cname:"状态" json:"status"`
  57 +
  58 + // 开始时间
  59 + ProductBeginTime time.Time `cname:"开始时间" json:"productBeginTime"`
  60 + // 结束时间
  61 + ProductEndTime time.Time `cname:"结束时间" json:"productEndTime"`
  62 +}
  63 +
  64 +func (cmd *HistoryProductRecordQuery) Valid(validation *validation.Validation) {
  65 + cmd.Offset, cmd.Limit = domain.Pagination(cmd.PageNumber, cmd.PageSize)
  66 +
  67 + //var err error
  68 + //if len(cmd.BeginTime) > 0 {
  69 + // if cmd.ProductBeginTime, err = time.Parse("2006-01-02 15:04:05", cmd.BeginTime); err != nil {
  70 + // log.Logger.Error(err.Error())
  71 + // validation.Error("开始时间有误")
  72 + // return
  73 + // }
  74 + //}
  75 + //if len(cmd.EndTime) > 0 {
  76 + // if cmd.ProductEndTime, err = time.Parse("2006-01-02 15:04:05", cmd.EndTime); err != nil {
  77 + // log.Logger.Error(err.Error())
  78 + // validation.Error("结束时间有误")
  79 + // return
  80 + // }
  81 + // if cmd.ProductEndTime.Equal(cmd.ProductBeginTime) {
  82 + // cmd.ProductEndTime = cmd.ProductEndTime.Add(time.Hour * 24)
  83 + // }
  84 + //}
  85 + if len(cmd.Date) > 0 {
  86 + t, err := xtime.Parse(cmd.Date)
  87 + if err != nil {
  88 + log.Logger.Error(err.Error())
  89 + validation.Error("日期有误")
  90 + return
  91 + }
  92 + cmd.ProductBeginTime = t
  93 + cmd.ProductEndTime = t.AddDate(0, 0, 1)
  94 + }
  95 + if cmd.Status == domain.ProductRecordLogged {
  96 + cmd.Status = domain.ProductRecordNotApprove
  97 + if len(cmd.Date) == 0 && xtime.IsZero(cmd.ProductEndTime) {
  98 + cmd.ProductEndTime = xtime.BeginningOfDay()
  99 + }
  100 + }
  101 +}
  102 +
  103 +func (cmd *HistoryProductRecordQuery) ValidateQuery() error {
  104 + valid := validation.Validation{}
  105 + b, err := valid.Valid(cmd)
  106 + if err != nil {
  107 + return err
  108 + }
  109 + if !b {
  110 + elem := reflect.TypeOf(cmd).Elem()
  111 + for _, validErr := range valid.Errors {
  112 + field, isExist := elem.FieldByName(validErr.Field)
  113 + if isExist {
  114 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  115 + } else {
  116 + return fmt.Errorf(validErr.Message)
  117 + }
  118 + }
  119 + }
  120 + return nil
  121 +}
@@ -274,6 +274,41 @@ func (productRecordService *ProductRecordService) SearchProductRecord(operateInf @@ -274,6 +274,41 @@ func (productRecordService *ProductRecordService) SearchProductRecord(operateInf
274 return count, result, nil 274 return count, result, nil
275 } 275 }
276 276
  277 +// 返回生产记录服务列表
  278 +func (productRecordService *ProductRecordService) HistoryProductRecord(operateInfo *domain.OperateInfo, query *query.HistoryProductRecordQuery) (int64, interface{}, error) {
  279 + if err := query.ValidateQuery(); err != nil {
  280 + return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error())
  281 + }
  282 + transactionContext, err := factory.CreateTransactionContext(nil)
  283 + if err != nil {
  284 + return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  285 + }
  286 + if err := transactionContext.StartTransaction(); err != nil {
  287 + return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  288 + }
  289 + defer func() {
  290 + transactionContext.RollbackTransaction()
  291 + }()
  292 + var productRecordRepository domain.ProductRecordRepository
  293 + productRecordRepository, _, _ = factory.FastPgProductRecord(transactionContext, 0)
  294 +
  295 + count, productRecords, err := productRecordRepository.Find(utils.ObjectToMap(query))
  296 + if err != nil {
  297 + return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  298 + }
  299 + if err := transactionContext.CommitTransaction(); err != nil {
  300 + return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  301 + }
  302 + var result = make([]*dto.HistoryProductRecord, 0)
  303 + for i := range productRecords {
  304 + item := productRecords[i]
  305 + newItem := &dto.HistoryProductRecord{}
  306 + newItem.LoadDto(item)
  307 + result = append(result, newItem)
  308 + }
  309 + return count, result, nil
  310 +}
  311 +
277 // 生产记录统计 312 // 生产记录统计
278 func (productRecordService *ProductRecordService) ProductRecordStatics(cmd *command.ProductRecordStaticsCommand) (interface{}, error) { 313 func (productRecordService *ProductRecordService) ProductRecordStatics(cmd *command.ProductRecordStaticsCommand) (interface{}, error) {
279 if err := cmd.ValidateCommand(); err != nil { 314 if err := cmd.ValidateCommand(); err != nil {
@@ -308,6 +343,33 @@ func (productRecordService *ProductRecordService) ProductRecordStatics(cmd *comm @@ -308,6 +343,33 @@ func (productRecordService *ProductRecordService) ProductRecordStatics(cmd *comm
308 return nil, nil 343 return nil, nil
309 } 344 }
310 345
  346 +// 生产记录审核
  347 +func (productRecordService *ProductRecordService) CancelProductRecord(cmd *command.CancelProductRecordCommand) (interface{}, error) {
  348 + if err := cmd.ValidateCommand(); err != nil {
  349 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  350 + }
  351 + transactionContext, err := factory.CreateTransactionContext(nil)
  352 + if err != nil {
  353 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  354 + }
  355 + if err := transactionContext.StartTransaction(); err != nil {
  356 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  357 + }
  358 + defer func() {
  359 + transactionContext.RollbackTransaction()
  360 + }()
  361 +
  362 + svr, err := domainService.NewPGProductRecordService(transactionContext.(*pgTransaction.TransactionContext))
  363 + if _, err = svr.Cancel(cmd.ProductRecordId); err != nil {
  364 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  365 + }
  366 +
  367 + if err := transactionContext.CommitTransaction(); err != nil {
  368 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  369 + }
  370 + return struct{}{}, nil
  371 +}
  372 +
311 func NewProductRecordService(options map[string]interface{}) *ProductRecordService { 373 func NewProductRecordService(options map[string]interface{}) *ProductRecordService {
312 newProductRecordService := &ProductRecordService{} 374 newProductRecordService := &ProductRecordService{}
313 return newProductRecordService 375 return newProductRecordService
@@ -80,15 +80,32 @@ func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore(pr @@ -80,15 +80,32 @@ func (productAttendanceRecord *ProductAttendanceRecord) ComputeWorkTimeBefore(pr
80 if !productAttendanceRecord.SignOut.After(productAttendanceRecord.SignIn) { 80 if !productAttendanceRecord.SignOut.After(productAttendanceRecord.SignIn) {
81 return 0 81 return 0
82 } 82 }
83 - wt := utils.Round(productAttendanceRecord.SignOut.Sub(productAttendanceRecord.SignIn).Hours(), 1) 83 + wt := utils.Round(productAttendanceRecord.SignOut.Sub(productAttendanceRecord.SignIn).Hours(), 2)
84 if productCalendar == nil { 84 if productCalendar == nil {
85 - return wt 85 + return roundWorkTime(wt)
86 } 86 }
87 wt = wt - productAttendanceRecord.AttendanceBreakTime(productCalendar) 87 wt = wt - productAttendanceRecord.AttendanceBreakTime(productCalendar)
88 if wt < 0 { 88 if wt < 0 {
89 return 0 89 return 0
90 } 90 }
91 - return wt 91 + return roundWorkTime(wt)
  92 +}
  93 +
  94 +// roundWorkTime 工时取整[0:0.167]=> 0 \ [0.167,0.667]=> 0.5 \ [0.667,1]=>1
  95 +// 10/60 = 0.167 40/60 = 0.667
  96 +func roundWorkTime(wt float64) float64 {
  97 + i := float64(int(wt))
  98 + f := wt - i
  99 + if f < 0.167 {
  100 + return i
  101 + }
  102 + if f >= 0.167 && f < 0.667 {
  103 + return i + 0.5
  104 + }
  105 + if f >= 0.667 {
  106 + return i + 1
  107 + }
  108 + return i
92 } 109 }
93 110
94 func (productAttendanceRecord *ProductAttendanceRecord) SetProductTimeByProductCalendar(productCalendar *ProductCalendar) error { 111 func (productAttendanceRecord *ProductAttendanceRecord) SetProductTimeByProductCalendar(productCalendar *ProductCalendar) error {
@@ -17,6 +17,8 @@ const ( @@ -17,6 +17,8 @@ const (
17 const ( 17 const (
18 ProductRecordNotApprove = 1 // 未审核 18 ProductRecordNotApprove = 1 // 未审核
19 ProductRecordApproved = 2 // 已审核 19 ProductRecordApproved = 2 // 已审核
  20 + ProductRecordWithdraw = 3 // 已撤回
  21 + ProductRecordLogged = 4 // 已记录
20 ) 22 )
21 23
22 // 生产记录 24 // 生产记录
@@ -82,6 +84,21 @@ func (productRecord *ProductRecord) Approve(approveUser *User, weighAfter float6 @@ -82,6 +84,21 @@ func (productRecord *ProductRecord) Approve(approveUser *User, weighAfter float6
82 return nil 84 return nil
83 } 85 }
84 86
  87 +func (productRecord *ProductRecord) Cancel() error {
  88 + if productRecord.ProductRecordInfo.ApproveStatus == ProductRecordApproved {
  89 + return errors.New("已审核")
  90 + }
  91 + if productRecord.ProductRecordInfo.ApproveStatus == ProductRecordWithdraw {
  92 + return errors.New("已撤销")
  93 + }
  94 + //if xtime.BeforeEqual(productRecord.CreatedAt, xtime.BeginningOfDay()) {
  95 + // return errors.New("已记录")
  96 + //}
  97 + productRecord.ProductRecordInfo.ApproveStatus = ProductRecordWithdraw
  98 + productRecord.UpdatedAt = time.Now()
  99 + return nil
  100 +}
  101 +
85 func TaskKeyPatternProductRecordStatics() string { 102 func TaskKeyPatternProductRecordStatics() string {
86 return fmt.Sprintf("%v:task:product-record:statics", constant.CACHE_PREFIX) 103 return fmt.Sprintf("%v:task:product-record:statics", constant.CACHE_PREFIX)
87 } 104 }
@@ -101,8 +101,8 @@ func (ptr *PGCommonStatisticsService) HourProductiveStatistics(queryOptions map[ @@ -101,8 +101,8 @@ func (ptr *PGCommonStatisticsService) HourProductiveStatistics(queryOptions map[
101 endTime = time.Now() 101 endTime = time.Now()
102 ) 102 )
103 if !xtime.IsZero(request.Date.Time()) && !request.Date.Time().Equal(beginTime) { 103 if !xtime.IsZero(request.Date.Time()) && !request.Date.Time().Equal(beginTime) {
104 - beginTime = request.Date.Time().AddDate(0, 0, -1)  
105 - endTime = request.Date.Time() 104 + beginTime = request.Date.Time()
  105 + endTime = request.Date.Time().AddDate(0, 0, 1)
106 } 106 }
107 for _, v := range workshop.GetProductLines(domain.NotDeleted) { 107 for _, v := range workshop.GetProductLines(domain.NotDeleted) {
108 var result = make([]*record, 0) 108 var result = make([]*record, 0)
@@ -180,6 +180,30 @@ func (ptr *PGProductRecordService) Approve(productRecordId int, approveUserId in @@ -180,6 +180,30 @@ func (ptr *PGProductRecordService) Approve(productRecordId int, approveUserId in
180 return struct{}{}, nil 180 return struct{}{}, nil
181 } 181 }
182 182
  183 +// Approve 审核生产记录 (二级品审核)
  184 +func (ptr *PGProductRecordService) Cancel(productRecordId int) (interface{}, error) {
  185 + productRecordRepository, err := repository.NewProductRecordRepository(ptr.transactionContext)
  186 +
  187 + var productRecord *domain.ProductRecord
  188 + productRecord, err = productRecordRepository.FindOne(map[string]interface{}{"productRecordId": productRecordId})
  189 + if err != nil {
  190 + return nil, err
  191 + }
  192 +
  193 + if err = productRecord.Cancel(); err != nil {
  194 + return nil, err
  195 + }
  196 + if _, err = productRecordRepository.Save(productRecord); err != nil {
  197 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  198 + }
  199 + // 发送Job
  200 + productRecord.ProductRecordInfo.Weigh = -productRecord.ProductRecordInfo.Weigh
  201 + if err = SendProductRecordStaticsJob(productRecord); err != nil {
  202 + return nil, err
  203 + }
  204 + return struct{}{}, nil
  205 +}
  206 +
183 func (ptr *PGProductRecordService) BatchApprove(list []*domain.ProductRecord, approveUserId int, weight float64, status int) (interface{}, error) { 207 func (ptr *PGProductRecordService) BatchApprove(list []*domain.ProductRecord, approveUserId int, weight float64, status int) (interface{}, error) {
184 var productRecordRepository, _ = repository.NewProductRecordRepository(ptr.transactionContext) 208 var productRecordRepository, _ = repository.NewProductRecordRepository(ptr.transactionContext)
185 var record *domain.ProductRecord 209 var record *domain.ProductRecord
@@ -164,7 +164,7 @@ func (repository *ProductMaterialRepository) Find(queryOptions map[string]interf @@ -164,7 +164,7 @@ func (repository *ProductMaterialRepository) Find(queryOptions map[string]interf
164 query.Where("material_name like ?", fmt.Sprintf("%%%v%%", v)) 164 query.Where("material_name like ?", fmt.Sprintf("%%%v%%", v))
165 } 165 }
166 if v, ok := queryOptions["materialCategory"]; ok && v != "" { 166 if v, ok := queryOptions["materialCategory"]; ok && v != "" {
167 - query.Where(fmt.Sprintf(`material_category->>'category' like '%%%v%%'`, v)) 167 + query.Where(fmt.Sprintf(`material_category->>'category' = '%v'`, v))
168 } 168 }
169 if v, ok := queryOptions["materialNumbers"]; ok && len(v.([]string)) > 0 { 169 if v, ok := queryOptions["materialNumbers"]; ok && len(v.([]string)) > 0 {
170 query.Where("material_number in (?)", pg.In(v)) 170 query.Where("material_number in (?)", pg.In(v))
@@ -180,6 +180,12 @@ func (repository *ProductRecordRepository) Find(queryOptions map[string]interfac @@ -180,6 +180,12 @@ func (repository *ProductRecordRepository) Find(queryOptions map[string]interfac
180 if v, ok := queryOptions["productPlanId"]; ok && v.(int) > 0 { 180 if v, ok := queryOptions["productPlanId"]; ok && v.(int) > 0 {
181 query.Where(fmt.Sprintf(`product_record_info->>'productPlanId' = '%v'`, v)) 181 query.Where(fmt.Sprintf(`product_record_info->>'productPlanId' = '%v'`, v))
182 } 182 }
  183 + if v, ok := queryOptions["status"]; ok && v.(int) > 0 {
  184 + query.Where(fmt.Sprintf(`product_record_info->>'approveStatus' = '%v'`, v))
  185 + }
  186 + if v, ok := queryOptions["lastProductRecordId"]; ok && v.(int) > 0 {
  187 + query.Where(`product_record_id < ?`, v)
  188 + }
183 query.SetOffsetAndLimit(domain.MaxQueryRow) 189 query.SetOffsetAndLimit(domain.MaxQueryRow)
184 query.SetOrderDirect("product_record_id", "DESC") 190 query.SetOrderDirect("product_record_id", "DESC")
185 if count, err := query.SelectAndCount(); err != nil { 191 if count, err := query.SelectAndCount(); err != nil {
@@ -48,7 +48,8 @@ func (controller *ProductMaterialGroupController) RemoveProductMaterialGroup() { @@ -48,7 +48,8 @@ func (controller *ProductMaterialGroupController) RemoveProductMaterialGroup() {
48 controller.Unmarshal(removeProductMaterialGroupCommand) 48 controller.Unmarshal(removeProductMaterialGroupCommand)
49 productMaterialGroupId, _ := controller.GetInt(":productMaterialGroupId") 49 productMaterialGroupId, _ := controller.GetInt(":productMaterialGroupId")
50 removeProductMaterialGroupCommand.ProductMaterialGroupId = productMaterialGroupId 50 removeProductMaterialGroupCommand.ProductMaterialGroupId = productMaterialGroupId
51 - data, err := productMaterialGroupService.RemoveProductMaterialGroup(removeProductMaterialGroupCommand) 51 + operateInfo := ParseOperateInfo(controller.BaseController)
  52 + data, err := productMaterialGroupService.RemoveProductMaterialGroup(operateInfo, removeProductMaterialGroupCommand)
52 controller.Response(data, err) 53 controller.Response(data, err)
53 } 54 }
54 55
@@ -84,6 +84,26 @@ func (controller *ProductRecordController) SearchProductRecord() { @@ -84,6 +84,26 @@ func (controller *ProductRecordController) SearchProductRecord() {
84 ResponseGrid(controller.BaseController, total, data, err) 84 ResponseGrid(controller.BaseController, total, data, err)
85 } 85 }
86 86
  87 +func (controller *ProductRecordController) History() {
  88 + productPlanService := service.NewProductRecordService(nil)
  89 + cmd := &query.HistoryProductRecordQuery{}
  90 + Must(controller.Unmarshal(cmd))
  91 + operateInfo := ParseOperateInfo(controller.BaseController)
  92 + //cmd.OrgId = operateInfo.OrgId
  93 + cmd.CompanyId = operateInfo.CompanyId
  94 + cmd.InOrgIds = operateInfo.OrgIds
  95 + total, data, err := productPlanService.HistoryProductRecord(ParseOperateInfo(controller.BaseController), cmd)
  96 + ResponseGrid(controller.BaseController, total, data, err)
  97 +}
  98 +
  99 +func (controller *ProductRecordController) CancelProductRecord() {
  100 + productRecordService := service.NewProductRecordService(nil)
  101 + cmd := &command.CancelProductRecordCommand{}
  102 + controller.Unmarshal(cmd)
  103 + data, err := productRecordService.CancelProductRecord(cmd)
  104 + controller.Response(data, err)
  105 +}
  106 +
87 func (controller *ProductRecordController) SearchEmployeeProductRecord() { 107 func (controller *ProductRecordController) SearchEmployeeProductRecord() {
88 productPlanService := service.NewProductRecordService(nil) 108 productPlanService := service.NewProductRecordService(nil)
89 cmd := &query.SearchEmployeeProductRecordQuery{} 109 cmd := &query.SearchEmployeeProductRecordQuery{}
@@ -14,6 +14,8 @@ func init() { @@ -14,6 +14,8 @@ func init() {
14 web.Router("/product-records/approve", &controllers.ProductRecordController{}, "Post:ApproveProductRecord") 14 web.Router("/product-records/approve", &controllers.ProductRecordController{}, "Post:ApproveProductRecord")
15 web.Router("/product-records/search", &controllers.ProductRecordController{}, "Post:SearchProductRecord") 15 web.Router("/product-records/search", &controllers.ProductRecordController{}, "Post:SearchProductRecord")
16 web.Router("/product-records/second-level-record/search", &controllers.ProductRecordController{}, "Post:SearchProductRecord") 16 web.Router("/product-records/second-level-record/search", &controllers.ProductRecordController{}, "Post:SearchProductRecord")
  17 + web.Router("/product-records/history", &controllers.ProductRecordController{}, "Post:History")
  18 + web.Router("/product-records/cancel", &controllers.ProductRecordController{}, "Post:CancelProductRecord")
17 web.Router("/product-records/employee-productive/search", &controllers.ProductRecordController{}, "Post:SearchEmployeeProductRecord") 19 web.Router("/product-records/employee-productive/search", &controllers.ProductRecordController{}, "Post:SearchEmployeeProductRecord")
18 web.Router("/product-records/workshop-productive/search", &controllers.ProductRecordController{}, "Post:SearchWorkshopProductRecord") 20 web.Router("/product-records/workshop-productive/search", &controllers.ProductRecordController{}, "Post:SearchWorkshopProductRecord")
19 } 21 }