package models import ( "errors" "fmt" orm "go-admin/common/global" "go-admin/logger" "gorm.io/gorm" "math/rand" "time" ) const ( ErpPurchaseOrderUnAudit = 1 // 待审核 ErpPurchaseOrderWaitInventory = 2 // 待入库 ErpPurchaseOrderWaitReject = 3 // 待退货 ErpPurchaseOrderFinished = 4 // 已完成 ErpPurchaseOrderEnd = 5 // 已终止 ErpPurchaseOrderInInventory = 6 // 入库中,部分入库 ErpPurchaseOrderInReject = 7 // 退货中,部分退货 ErpProcureOrder = "procure" // 采购入库订单 ErpRejectOrder = "reject" // 采购退货订单 ) // ErpPurchaseOrder 采购订单表 type ErpPurchaseOrder struct { Model SerialNumber string `json:"serial_number" gorm:"index"` // 单据编号 PurchaseType string `json:"purchase_type"` // 类型:procure-采购 reject-退货 StoreId uint32 `json:"store_id" gorm:"index"` // 门店id StoreName string `json:"store_name"` // 门店名称 ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 供应商id ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称 MakerTime time.Time `json:"maker_time"` // 制单时间 MakerId uint32 `json:"maker_id" gorm:"index"` // 制单人id MakerName string `json:"maker_name"` // 制单人名称 AuditTime time.Time `json:"audit_time"` // 审核时间 AuditorId uint32 `json:"auditor_id" gorm:"index"` // 审核人id AuditorName string `json:"auditor_name"` // 审核人名称 State uint32 `json:"state"` // 1-待审核 2-待入库 3-待退货 4-已完成 5-已终止 RejectedPurchaseOrderId uint32 `json:"rejected_purchase_order_id"` // 退货采购订单id ErpCashierId uint32 `json:"erp_cashier_id"` // 付款方式/收款方式id ErpCashierName string `json:"erp_cashier_name"` // 付款方式/收款方式名称 AccountHolder string `json:"account_holder"` // 收款人 OpeningBank string `json:"opening_bank"` // 开户行 BankAccount string `json:"bank_account"` // 银行卡号 DeliveryTime string `json:"delivery_time"` // 交货日期 Commodities []ErpPurchaseCommodity `json:"commodities" gorm:"-"` } // ErpPurchaseCommodity 采购订单商品表 type ErpPurchaseCommodity struct { Model ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" gorm:"index"` // 采购订单id ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码 IMEI string `json:"imei"` // 商品串码 Count uint32 `json:"count"` // 计划采购数量 Price uint32 `json:"price"` // 计划采购单价 Amount uint32 `json:"amount"` // 计划采购金额 Remark string `json:"remark"` // 备注 RejectedPrice uint32 `json:"rejected_price"` // 计划退货单价 RejectedCount uint32 `json:"rejected_count"` // 计划退货数量 RejectedAmount uint32 `json:"rejected_amount"` // 计划退货金额 InventoryCount int32 `json:"inventory_count"` // 入库数量(=执行数量) ExecutionCount uint32 `json:"execute_count" gorm:"-"` // 执行数量 ExecutionPrice uint32 `json:"execute_price" gorm:"-"` // 平均采购单价 ExecutionEmployeePrice uint32 `json:"execute_employee_price" gorm:"-"` // 平均员工成本价 ExecutionAmount uint32 `json:"execute_amount" gorm:"-"` // 执行金额 } // ErpPurchaseInventory 采购入库执行表 type ErpPurchaseInventory struct { Model SerialNumber string `json:"serial_number" gorm:"index"` // 入库编号 InventoryType string `json:"inventory_type"` // 采购类型:procure-采购 reject-退货 ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" gorm:"index"` // 商品采购订单id ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码 IMEI string `json:"imei"` // 商品串码 Count uint32 `json:"count"` // 数量 Price uint32 `json:"price"` // 采购单价 ImplementationPrice uint32 `json:"implementation_price"` // 执行单价 EmployeePrice uint32 `json:"employee_price"` // 员工成本价 InventoryCount int32 `json:"inventory_count"` // 入库数量 Amount uint32 `json:"amount"` // 入库金额 Remark string `json:"remark"` // 备注 //ErpPurchaseCommodity *ErpPurchaseCommodity `json:"erp_purchase_commodity" gorm:"-"` } // ErpInventoryCommodity 采购入库执行商品表 type ErpInventoryCommodity struct { Model SerialNumber string `json:"serial_number" gorm:"index"` // 入库编号 InventoryType string `json:"inventory_type"` // ErpPurchaseInventoryId uint32 `json:"erp_purchase_inventory_id"` // 商品采购入库id ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 商品采购订单id ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 CommoditySerialNumber string `json:"commodity_serial_number"` // 商品编码 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码 IMEI string `json:"imei"` // 串码 Count uint32 `json:"count"` // Price uint32 `json:"price"` // EmployeePrice uint32 `json:"employee_price"` // 员工成本 ImplementationPrice uint32 `json:"implementation_price"` // Amount uint32 `json:"amount"` // Remark string `json:"remark"` // 备注 } type ErpPurchaseCreateReq struct { PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货 PurchaseOrderSn string `json:"purchase_order_sn"` // 采购退货订单号 StoreId uint32 `json:"store_id" binding:"required"` // 门店id DeliveryAddress string `json:"delivery_address" binding:"required"` // 交货地址 MakerId uint32 `json:"maker_id" binding:"required"` // 经手人 ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 供应商id ErpCashierId uint32 `json:"erp_cashier_id" binding:"required"` // 付款方式 AccountHolder string `json:"account_holder"` // 收款人 OpeningBank string `json:"opening_bank" validate:"required"` // 开户行 BankAccount string `json:"bank_account" validate:"required"` // 银行卡号 DeliveryTime string `json:"delivery_time" binding:"required"` // 交货日期 Remark string `json:"remark"` // 备注 ErpPurchaseCommodities []ErpPurchaseCommodity `json:"erp_purchase_commodities" binding:"required"` // 采购商品信息 } type ErpPurchaseEditReq struct { ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id PurchaseType string `json:"purchase_type" binding:"required"` // 采购类型:procure-采购 reject-退货 PurchaseOrderSn string `json:"purchase_order_sn"` // 采购退货订单号 StoreId uint32 `json:"store_id" binding:"required"` // 门店id DeliveryAddress string `json:"delivery_address" binding:"required"` // 交货地址 MakerId uint32 `json:"maker_id" binding:"required"` // 经手人 ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 供应商id ErpCashierId uint32 `json:"erp_cashier_id" binding:"required"` // 付款方式 AccountHolder string `json:"account_holder"` // 收款人 OpeningBank string `json:"opening_bank" validate:"required"` // 开户行 BankAccount string `json:"bank_account" validate:"required"` // 银行卡号 DeliveryTime string `json:"delivery_time" binding:"required"` // 交货日期 Remark string `json:"remark"` // 备注 ErpPurchaseCommodities []ErpPurchaseCommodity `json:"erp_purchase_commodities" binding:"required"` // 采购商品信息 } type ErpPurchaseOrderListReq struct { SerialNumber string `json:"serial_number"` // 单据编号 PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货 StoreId uint32 `json:"store_id"` // 门店id ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id AuditTimeStart string `json:"audit_time_start"` // 审核开始时间 AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间 State uint32 `json:"state"` // 状态:1-待审核 2-待入库 3-待退货 4-已完成 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 } type ErpPurchaseOrderListResp struct { List []ErpPurchaseOrder `json:"list"` Total int `json:"total"` // 总条数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 } type ErpPurchaseDetailReq struct { ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id } // ErpPurchaseInventoryReq 入库(退货)入参;执行(入库/退货)入参 type ErpPurchaseInventoryReq struct { ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" binding:"required"` // 采购订单id InventoryType string `json:"inventory_type" binding:"required"` // 采购类型:procure-采购 reject-退货 Inventories []ErpPurchaseInventory `json:"inventories" binding:"required"` // 采购入库执行信息 //Commodities []ErpInventoryCommodity `json:"commodities" binding:"required"` } // ErpPurchaseAuditReq 审核采购订单入参 type ErpPurchaseAuditReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 State int `json:"state" binding:"required"` // 审核操作: 1-审核 2-取消审核 } // ErpPurchaseTerminateReq 终止采购入参 type ErpPurchaseTerminateReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 } // ErpPurchaseExecuteResp 执行(入库/退货)出参 type ErpPurchaseExecuteResp struct { List []ExecuteData `json:"list"` Total int `json:"total"` // 总条数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 } type ExecuteData struct { ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id" gorm:"index"` // 商品采购订单id ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码 IMEI string `json:"imei"` // 商品串码 Count uint32 `json:"count"` // 数量 ImplementationPrice uint32 `json:"implementation_price"` // 执行单价 EmployeePrice uint32 `json:"employee_price"` // 员工成本价 } func (m *ErpPurchaseOrderListReq) List() (*ErpPurchaseOrderListResp, error) { resp := &ErpPurchaseOrderListResp{ PageIndex: m.PageIndex, PageSize: m.PageSize, } page := m.PageIndex - 1 if page < 0 { page = 0 } if m.PageSize == 0 { m.PageSize = 10 } qs := orm.Eloquent.Table("erp_purchase_order") if m.SerialNumber != "" { qs = qs.Where("serial_number=?", m.SerialNumber) } else { if m.PurchaseType != "" { qs = qs.Where("purchase_type=?", m.PurchaseType) } if m.StoreId != 0 { qs = qs.Where("store_id=?", m.StoreId) } if m.ErpSupplierId != 0 { qs = qs.Where("erp_supplier_id=?", m.ErpSupplierId) } if m.State != 0 { qs = qs.Where("state=?", m.State) } if m.AuditTimeStart != "" { parse, err := time.Parse(QueryTimeFormat, m.AuditTimeStart) if err != nil { logger.Errorf("erpPurchaseOrderList err:", err) return nil, err } qs = qs.Where("audit_time > ?", parse) } if m.AuditTimeEnd != "" { parse, err := time.Parse(QueryTimeFormat, m.AuditTimeEnd) if err != nil { logger.Errorf("erpPurchaseOrderList err:", err) return nil, err } parse = parse.AddDate(0, 0, 1) qs = qs.Where("audit_time < ?", parse) } } var count int64 err := qs.Count(&count).Error if err != nil { logger.Error("count err:", logger.Field("err", err)) return resp, err } resp.Total = int(count) var orders []ErpPurchaseOrder err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error if err != nil && err != RecordNotFound { logger.Error("erp commodity list err:", logger.Field("err", err)) return resp, err } resp.List = orders return resp, nil } // NewErpPurchaseSn 生成采购订单号 func NewErpPurchaseSn() string { nowTime := time.Now() rand.Seed(nowTime.UnixNano()) max := 1 for { if max > 5 { logger.Error("create sn err") return "" } random := rand.Int31n(9999) + 1000 sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random) exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_order WHERE serial_number='%s'", sn)) if err != nil { logger.Error("exist sn err") } if !exist { return sn } max++ } } func ErpPurchaseCommodityListPerfectInfo(purchaseCommodities []ErpPurchaseCommodity) error { commodityIds := make([]uint32, 0, len(purchaseCommodities)) for i, _ := range purchaseCommodities { commodityIds = append(commodityIds, purchaseCommodities[i].ID) } commodityMap, err := GetErpCommodityMap(commodityIds) if err != nil { logger.Error("purchase commodities err:", logger.Field("err", err)) return err } for i, _ := range purchaseCommodities { v, ok := commodityMap[purchaseCommodities[i].ErpCommodityId] if ok { purchaseCommodities[i].CommoditySerialNumber = v.SerialNumber purchaseCommodities[i].IMEIType = v.IMEIType //purchaseCommodities[i].IMEI = v.IMEI purchaseCommodities[i].ErpCommodityName = v.Name if purchaseCommodities[i].Count != 0 { purchaseCommodities[i].Amount = purchaseCommodities[i].Count * purchaseCommodities[i].Price } if purchaseCommodities[i].RejectedCount != 0 { purchaseCommodities[i].RejectedAmount = purchaseCommodities[i].RejectedCount * purchaseCommodities[i].RejectedPrice } } } return nil } // IdInit 添加商户和供应商信息 func (m *ErpPurchaseOrder) IdInit() error { if m.StoreId != 0 { store, err := GetStore(m.StoreId) if err != nil { logger.Error("get store err:", logger.Field("err", err)) return err } m.StoreName = store.Name } if m.ErpSupplierId != 0 { supplier, err := GetErpSupplier(m.ErpSupplierId) if err != nil { logger.Error("get supplier err:", logger.Field("err", err)) return err } m.ErpSupplierName = supplier.Name } if m.ErpCashierId != 0 { cashier, err := GetAccountDetail(int(m.ErpCashierId)) if err != nil { logger.Error("get cashier err:", logger.Field("err", err)) return err } m.ErpCashierName = cashier.Name } return nil } // GetPurchaseInventorySn 生成入库编号 func GetPurchaseInventorySn() string { count := 0 for { if count > 5 { return "" } nowTime := time.Now() sn := nowTime.Format("060102") sn += fmt.Sprintf("%d", nowTime.Unix()%100) rand.Seed(nowTime.UnixNano()) sn += fmt.Sprintf("%d", rand.Int31n(100)) exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_inventory WHERE serial_number='%s'", sn)) if err != nil { logger.Error("sn err:", logger.Field("err", err)) count++ continue } if err == nil && !exist { return sn } return "" } } func GetErpPurchaseOrderPurchaseCommodityMap(orderId uint32) (map[uint32]ErpPurchaseCommodity, error) { commodityMap := make(map[uint32]ErpPurchaseCommodity, 0) if orderId == 0 { return commodityMap, nil } var commodities []ErpPurchaseCommodity err := orm.Eloquent.Table("erp_purchase_commodity").Where("erp_purchase_order_id=?", orderId).Find(&commodities).Error if err != nil { logger.Error("commodities err:", logger.Field("err", err)) return commodityMap, err } for i, _ := range commodities { commodityMap[commodities[i].ErpCommodityId] = commodities[i] } return commodityMap, nil } func ErpPurchaseInventoryListIdInit(inventories []ErpPurchaseInventory /*commodities []ErpInventoryCommodity,*/, orderId uint32, inventoryType string) error { //inventorySn := GetPurchaseInventorySn() ids := make([]uint32, 0, len(inventories)) for i, _ := range inventories { ids = append(ids, inventories[i].ErpCommodityId) } commodityMap, err := GetErpCommodityMap(ids) if err != nil { logger.Error("commodity map err:", logger.Field("err", err)) return err } purchaseCommodityMap, err := GetErpPurchaseOrderPurchaseCommodityMap(orderId) if err != nil { logger.Error("purchase commodity map err:", logger.Field("err", err)) return err } commodityCountMap := make(map[uint32]uint32, 0) //for i, _ := range commodities { // purchaseCommodity, _ := purchaseCommodityMap[inventories[i].ErpCommodityId] // v, ok := commodityMap[commodities[i].ErpCommodityId] // if ok { // commodities[i].SerialNumber = inventorySn // commodities[i].InventoryType = inventoryType // commodities[i].ErpPurchaseOrderId = orderId // commodities[i].ErpCommodityName = v.Name // commodities[i].CommoditySerialNumber = v.SerialNumber // commodities[i].IMEIType = v.IMEIType // commodities[i].Price = purchaseCommodity.Price // commodities[i].Amount = commodities[i].Count * commodities[i].ImplementationPrice // if v.IMEIType == 1 { // commodityCountMap[v.ID] += commodities[i].Count // } else { // commodityCountMap[v.ID] += 1 // } // // //commodities[i].InventoryCount = int32(inventories[i].Count) // } //} for i, _ := range inventories { purchaseCommodity, _ := purchaseCommodityMap[inventories[i].ErpCommodityId] commodityCount, _ := commodityCountMap[inventories[i].ErpCommodityId] v, ok := commodityMap[inventories[i].ErpCommodityId] if ok { inventories[i].ErpPurchaseOrderId = orderId inventories[i].InventoryType = inventoryType inventories[i].ErpCommodityName = v.Name inventories[i].CommoditySerialNumber = v.SerialNumber inventories[i].IMEIType = v.IMEIType inventories[i].Price = purchaseCommodity.Price inventories[i].Count = commodityCount inventories[i].Amount = inventories[i].Count * inventories[i].ImplementationPrice inventories[i].InventoryCount = purchaseCommodity.InventoryCount + int32(inventories[i].Count) if int32(purchaseCommodity.Count) < inventories[i].InventoryCount { return errors.New(fmt.Sprintf("order id:%d purchase commodity id:%d inventory count err", orderId, purchaseCommodity.ID)) } } } return nil } // CreateErpPurchaseOrder 新增采购订单 func CreateErpPurchaseOrder(req *ErpPurchaseCreateReq, sysUser *SysUser) (*ErpPurchaseOrder, error) { var err error nowTime := time.Now() purchaseOrder := &ErpPurchaseOrder{} if req.PurchaseType == ErpProcureOrder { // 采购入库订单 purchaseOrder = &ErpPurchaseOrder{ SerialNumber: "cgr" + NewErpPurchaseSn(), PurchaseType: req.PurchaseType, StoreId: req.StoreId, ErpSupplierId: req.ErpSupplierId, MakerTime: nowTime, MakerId: uint32(sysUser.UserId), MakerName: sysUser.NickName, State: ErpPurchaseOrderUnAudit, // 1-待审核 ErpCashierId: req.ErpCashierId, AccountHolder: req.AccountHolder, OpeningBank: req.OpeningBank, BankAccount: req.BankAccount, DeliveryTime: req.DeliveryTime, } err = purchaseOrder.IdInit() } else if req.PurchaseType == ErpRejectOrder { // 采购退货订单 var erpPurchaseOrder ErpPurchaseOrder err = orm.Eloquent.Table("erp_purchase_order").Where("serial_number=?", req.PurchaseOrderSn).Find(&erpPurchaseOrder).Error if err != nil { logger.Error("purchase order err:", logger.Field("err", err)) return nil, err } purchaseOrder = &ErpPurchaseOrder{ SerialNumber: "cgt" + NewErpPurchaseSn(), PurchaseType: req.PurchaseType, StoreId: erpPurchaseOrder.StoreId, ErpSupplierId: erpPurchaseOrder.ErpSupplierId, MakerTime: nowTime, MakerId: uint32(req.MakerId), //MakerName: sysUser.NickName, State: ErpPurchaseOrderUnAudit, // 1-待审核 ErpCashierId: req.ErpCashierId, } err = purchaseOrder.IdInit() } else { logger.Errorf("purchase_type err:", req.PurchaseType) return nil, errors.New("操作失败:采购类型有误") } if err != nil { logger.Error("info err:", logger.Field("err", err)) return nil, err } err = ErpPurchaseCommodityListPerfectInfo(req.ErpPurchaseCommodities) if err != nil { logger.Error("info err:", logger.Field("err", err)) return nil, err } begin := orm.Eloquent.Begin() err = begin.Create(purchaseOrder).Error if err != nil { begin.Rollback() logger.Error("create purchase order err:", logger.Field("err", err)) return nil, err } for i, _ := range req.ErpPurchaseCommodities { req.ErpPurchaseCommodities[i].ErpPurchaseOrderId = purchaseOrder.ID req.ErpPurchaseCommodities[i].InventoryCount = 0 // todo 数量待核实 err = begin.Create(&req.ErpPurchaseCommodities[i]).Error if err != nil { begin.Rollback() logger.Error("create purchase commodity err:", logger.Field("err", err)) return nil, err } } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("commit purchase commodity err:", logger.Field("err", err)) return nil, err } return purchaseOrder, nil } // EditErpPurchaseOrder 编辑采购订单 func EditErpPurchaseOrder(req *ErpPurchaseEditReq, sysUser *SysUser) (*ErpPurchaseOrder, error) { // 查询订单信息 var purchaseOrder ErpPurchaseOrder err := orm.Eloquent.Table("erp_purchase_order").Where("id=?", req.ErpPurchaseOrderId).Find(&purchaseOrder).Error if err != nil { logger.Error("purchase order err:", logger.Field("err", err)) return nil, err } if purchaseOrder.State != ErpPurchaseOrderUnAudit { // 只有待审核的订单才能编辑 return nil, errors.New("订单不是待审核状态") } begin := orm.Eloquent.Begin() // 1-更新采购订单信息 purchaseOrder.StoreId = req.StoreId purchaseOrder.ErpSupplierId = req.ErpSupplierId purchaseOrder.MakerId = req.MakerId purchaseOrder.ErpCashierId = req.ErpCashierId purchaseOrder.AccountHolder = req.AccountHolder purchaseOrder.OpeningBank = req.OpeningBank purchaseOrder.BankAccount = req.BankAccount purchaseOrder.DeliveryTime = req.DeliveryTime err = purchaseOrder.IdInit() if err != nil { logger.Error("purchase IdInit err:", logger.Field("err", err)) return nil, err } err = begin.Model(&ErpPurchaseOrder{}).Where("id = ?", req.ErpPurchaseOrderId).Updates(purchaseOrder).Error if err != nil { begin.Rollback() logger.Error("update erp_order err:", logger.Field("err", err)) return nil, err } // 2-更新采购订单商品表 err = updatePurchaseCommodityData(begin, req.ErpPurchaseOrderId, req) if err != nil { begin.Rollback() logger.Error("update erp_purchase_commodity err:", logger.Field("err", err)) return nil, err } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("commit err:", logger.Field("err", err)) return nil, err } return &purchaseOrder, nil } // updatePurchaseCommodityData 更新采购订单商品信息 func updatePurchaseCommodityData(gdb *gorm.DB, orderId uint32, req *ErpPurchaseEditReq) error { // 查询现有的零售订单信息 var commodities []ErpPurchaseCommodity err := orm.Eloquent.Table("erp_purchase_commodity").Where("erp_purchase_order_id = ?", orderId).Find(&commodities).Error if err != nil { logger.Error("query erp_purchase_commodity err:", logger.Field("err", err)) return err } var newCommodities []ErpPurchaseCommodity var deletedCommodities []ErpPurchaseCommodity var matchingCommodities []ErpPurchaseCommodity // 找到新增的商品 for i, reqCommodity := range req.ErpPurchaseCommodities { // 订单商品表信息添加零售订单id req.ErpPurchaseCommodities[i].ErpPurchaseOrderId = orderId var found bool for _, dbCommodity := range commodities { if reqCommodity.ErpCommodityId == dbCommodity.ErpCommodityId { found = true break } } if !found { newCommodities = append(newCommodities, reqCommodity) } } // 找到删除的商品 for _, dbCommodity := range commodities { var found bool for _, reqCommodity := range req.ErpPurchaseCommodities { if reqCommodity.ID == dbCommodity.ID { found = true // 找到匹配的商品,加入匹配列表 matchingCommodities = append(matchingCommodities, reqCommodity) break } } if !found { deletedCommodities = append(deletedCommodities, dbCommodity) } } // 2-更新商品订单信息-更新 for _, commodity := range matchingCommodities { if err := gdb.Model(&ErpPurchaseCommodity{}).Where("id = ?", commodity.ID).Updates(commodity).Error; err != nil { logger.Error("更新商品订单信息-更新 error") return errors.New("操作失败:" + err.Error()) } } // 2-更新商品订单信息-新增 if len(newCommodities) != 0 { err = gdb.Create(&newCommodities).Error if err != nil { logger.Error("更新商品订单信息-新增 error") return errors.New("操作失败:" + err.Error()) } } //2-更新商品订单信息-删除 if len(deletedCommodities) != 0 { err = gdb.Delete(&deletedCommodities).Error if err != nil { logger.Error("更新商品订单信息-删除 error") return errors.New("操作失败:" + err.Error()) } } return nil } // InventoryErpPurchase 采购订单入库 func InventoryErpPurchase(req *ErpPurchaseInventoryReq) error { err := checkPurchaseInventory(req) if err != nil { logger.Error("checkPurchaseInventoryReq err:", logger.Field("err", err)) return err } begin := orm.Eloquent.Begin() for _, v := range req.Inventories { // 更新采购商品表的执行数量 err = begin.Model(&ErpPurchaseCommodity{}). Where("erp_purchase_order_id = ? AND erp_commodity_id = ?", v.ErpPurchaseOrderId, v.ErpCommodityId). UpdateColumn("inventory_count", gorm.Expr("inventory_count + ?", v.InventoryCount)).Error if err != nil { begin.Rollback() logger.Error("update inventory count err:", logger.Field("err", err)) return err } // 新建采购入库记录 err = begin.Create(&v).Error if err != nil { begin.Rollback() logger.Error("create erp inventory commodity err:", logger.Field("err", err)) return err } // todo 更新库存信息表 } err = begin.Commit().Error if err != nil { begin.Rollback() logger.Error("commit err:", logger.Field("err", err)) return err } return nil } // 校验入参数据,执行数量是否超过总数;串码商品的串码是否重复 func checkPurchaseInventory(req *ErpPurchaseInventoryReq) error { // 查询现有的零售订单信息 var commodities []ErpPurchaseCommodity err := orm.Eloquent.Table("erp_purchase_commodity").Where("erp_purchase_order_id = ?", req.ErpPurchaseOrderId).Find(&commodities).Error if err != nil { logger.Error("query erp_purchase_commodity err:", logger.Field("err", err)) return err } countMap := make(map[uint32]int32) for _, inventory := range req.Inventories { countMap[inventory.ErpCommodityId] += inventory.InventoryCount // 如果该商品是串码商品,判断其串码是否会重复 if inventory.IMEI != "" { exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET(%s, imei) > 0", inventory.IMEI)) if err != nil { logger.Error("exist sn err") } if exist { return fmt.Errorf("串码重复[%s]", inventory.IMEI) } } } // 入库的商品信息有误,不在之前的商品列表中 for commodityID := range countMap { found := false for _, commodity := range commodities { if commodity.ErpCommodityId == commodityID { found = true break } } if !found { return fmt.Errorf("商品编号[%d]不属于该采购订单", commodityID) } } // 本次入库的数量超出该商品未入库数量 for _, commodity := range commodities { if inventoryCount, ok := countMap[commodity.ErpCommodityId]; ok { if int32(commodity.Count)-commodity.InventoryCount < inventoryCount { return fmt.Errorf("本次入库商品[%s]数量[%d]超出该商品未入库数量[%d]", commodity.ErpCommodityName, inventoryCount, int32(commodity.Count)-commodity.InventoryCount) } } } return nil } // ExecuteErpPurchase 执行(入库/退货) func ExecuteErpPurchase(req *ErpPurchaseInventoryReq) (*ErpPurchaseExecuteResp, error) { err := checkPurchaseInventory(req) if err != nil { logger.Error("checkPurchaseInventoryReq err:", logger.Field("err", err)) return nil, err } resp := &ErpPurchaseExecuteResp{ List: make([]ExecuteData, 0), } for _, inventory := range req.Inventories { if inventory.IMEIType == 2 { // 如果是串码商品,根据 InventoryCount 拆分成对应数量的数据 for i := 0; i < int(inventory.InventoryCount); i++ { // 调用函数B生成商品串码 imei, err := generateIMEI(inventory.ErpCommodityId) if err != nil { return nil, err } // 将拆分后的商品信息添加到执行响应中 resp.List = append(resp.List, ExecuteData{ ErpPurchaseOrderId: inventory.ErpPurchaseOrderId, ErpCommodityId: inventory.ErpCommodityId, ErpCommodityName: inventory.ErpCommodityName, CommoditySerialNumber: inventory.CommoditySerialNumber, IMEIType: inventory.IMEIType, IMEI: imei, Count: 1, ImplementationPrice: inventory.ImplementationPrice, EmployeePrice: inventory.EmployeePrice, }) } } else if inventory.IMEIType == 1 { // 如果是非串码商品,只需拆分为1条数据 resp.List = append(resp.List, ExecuteData{ ErpPurchaseOrderId: inventory.ErpPurchaseOrderId, ErpCommodityId: inventory.ErpCommodityId, ErpCommodityName: inventory.ErpCommodityName, CommoditySerialNumber: inventory.CommoditySerialNumber, IMEIType: inventory.IMEIType, IMEI: "", Count: inventory.Count, ImplementationPrice: inventory.ImplementationPrice, EmployeePrice: inventory.EmployeePrice, }) } } return resp, nil } func generateIMEI(commodityId uint32) (string, error) { commodity, err := GetCommodity(commodityId) if err != nil { return "", err } return GenerateSerialCode(commodity.ErpCategoryId) }