Dockerfile
This commit is contained in:
201
service/procurement/purchase_inbound_service.go
Normal file
201
service/procurement/purchase_inbound_service.go
Normal file
@@ -0,0 +1,201 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"assets/consts/public"
|
||||
daoAsset "assets/dao/asset"
|
||||
daoProcurement "assets/dao/procurement"
|
||||
daoStock "assets/dao/stock"
|
||||
dtoProcurement "assets/model/dto/procurement"
|
||||
dtoStock "assets/model/dto/stock"
|
||||
serviceStock "assets/service/stock"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gitea.com/red-future/common/utils"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
type purchaseInbound struct{}
|
||||
|
||||
var PurchaseInbound = new(purchaseInbound)
|
||||
|
||||
// Create 创建采购入库
|
||||
func (s *purchaseInbound) Create(ctx context.Context, req *dtoProcurement.CreatePurchaseInboundReq) (res *dtoProcurement.CreatePurchaseInboundRes, err error) {
|
||||
// 1. 查询采购订单明细
|
||||
orderItem, err := daoProcurement.PurchaseOrderItem.GetOne(ctx, req.OrderItemId)
|
||||
if err != nil {
|
||||
return nil, errors.New("采购订单明细不存在")
|
||||
}
|
||||
if g.IsEmpty(orderItem) {
|
||||
return nil, errors.New("采购订单明细不存在")
|
||||
}
|
||||
|
||||
// 2. 校验+更新入库数量(原子操作,防止并发竞态)
|
||||
// 使用$inc + $expr条件:inboundQty + delta <= passQuantity
|
||||
if err = daoProcurement.PurchaseOrderItem.IncrementInboundQty(ctx, req.OrderItemId, req.InboundQty); err != nil {
|
||||
return nil, fmt.Errorf("入库数量校验失败: %v", err)
|
||||
}
|
||||
|
||||
// 3. 生成入库单号和批次号
|
||||
inboundNo, err := s.generateIncrSequence(ctx, public.StockInboundNoKeyPrefix)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("生成入库单号失败: %v", err)
|
||||
}
|
||||
batchNo, err := s.generateIncrSequence(ctx, public.StockBatchNoKeyPrefix)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("生成批次号失败: %v", err)
|
||||
}
|
||||
|
||||
// 4. 查询关联信息
|
||||
warehouseName, zoneName, locationName := s.getStorageNames(ctx, req.WarehouseId, req.ZoneId, req.LocationId)
|
||||
privateSkuName, privateCategoryPath := s.getPrivateSkuInfo(ctx, req.PrivateSkuId, req.PrivateCategoryId)
|
||||
|
||||
// 5. 创建入库记录
|
||||
inboundReq := &dtoProcurement.CreatePurchaseInboundReq{
|
||||
OrderItemId: req.OrderItemId,
|
||||
InboundQty: req.InboundQty,
|
||||
WarehouseId: req.WarehouseId,
|
||||
ZoneId: req.ZoneId,
|
||||
LocationId: req.LocationId,
|
||||
PrivateSkuId: req.PrivateSkuId,
|
||||
PrivateCategoryId: req.PrivateCategoryId,
|
||||
Remark: req.Remark,
|
||||
}
|
||||
|
||||
ids, err := daoProcurement.PurchaseInbound.Insert(ctx, inboundReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建入库记录失败: %v", err)
|
||||
}
|
||||
|
||||
inboundId := ids[0].(bson.ObjectID)
|
||||
|
||||
// 6. 更新入库记录的关联信息
|
||||
err = s.updateInboundDetails(ctx, &inboundId, orderItem.OrderId, inboundNo, batchNo,
|
||||
warehouseName, zoneName, locationName, privateSkuName, privateCategoryPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("更新入库记录失败: %v", err)
|
||||
}
|
||||
|
||||
// 7. 创建PrivateStock批次记录
|
||||
privateStockReq := &dtoStock.CreatePrivateStockReq{
|
||||
PrivateSkuID: req.PrivateSkuId,
|
||||
BatchNo: batchNo,
|
||||
BatchQty: req.InboundQty,
|
||||
AvailableQty: req.InboundQty,
|
||||
WarehouseId: req.WarehouseId,
|
||||
ZoneId: req.ZoneId,
|
||||
LocationId: req.LocationId,
|
||||
PrivateCategoryPath: privateCategoryPath,
|
||||
}
|
||||
privateStockIds, err := daoStock.PrivateStock.Insert(ctx, privateStockReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建库存批次失败: %v", err)
|
||||
}
|
||||
|
||||
privateStockId := privateStockIds[0].(bson.ObjectID)
|
||||
|
||||
// 8. 触发库位容量更新(异步,失败不影响入库)
|
||||
if req.LocationId != nil && !req.LocationId.IsZero() {
|
||||
if capErr := serviceStock.Capacity.UpdateLocationCapacity(ctx, req.LocationId); capErr != nil {
|
||||
g.Log().Warningf(ctx, "更新库位容量失败(不影响入库): %v", capErr)
|
||||
}
|
||||
}
|
||||
|
||||
// 9. 更新入库记录关联的库存ID
|
||||
err = s.updateInboundPrivateStockId(ctx, &inboundId, &privateStockId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("更新入库记录库存ID失败: %v", err)
|
||||
}
|
||||
|
||||
// 10. 入库数量已在步骤2原子更新,无需重复操作
|
||||
|
||||
return &dtoProcurement.CreatePurchaseInboundRes{
|
||||
Id: &inboundId,
|
||||
InboundNo: inboundNo,
|
||||
BatchNo: batchNo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetOne 获取入库详情
|
||||
func (s *purchaseInbound) GetOne(ctx context.Context, req *dtoProcurement.GetPurchaseInboundReq) (res *dtoProcurement.GetPurchaseInboundRes, err error) {
|
||||
one, err := daoProcurement.PurchaseInbound.GetOne(ctx, req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = utils.Struct(one, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// List 获取入库列表
|
||||
func (s *purchaseInbound) List(ctx context.Context, req *dtoProcurement.ListPurchaseInboundReq) (res *dtoProcurement.ListPurchaseInboundRes, err error) {
|
||||
list, total, err := daoProcurement.PurchaseInbound.List(ctx, req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res = &dtoProcurement.ListPurchaseInboundRes{
|
||||
Total: total,
|
||||
}
|
||||
err = utils.Struct(list, &res.List)
|
||||
return
|
||||
}
|
||||
|
||||
// generateInboundNo 生成入库单号(Redis自增,按天重置)
|
||||
func (s *purchaseInbound) generateIncrSequence(ctx context.Context, keyPrefix string) (string, error) {
|
||||
seq, err := utils.IncrSequence(ctx, keyPrefix, 6, "-")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return seq, nil
|
||||
}
|
||||
|
||||
// getStorageNames 获取仓储名称
|
||||
func (s *purchaseInbound) getStorageNames(ctx context.Context, warehouseId, zoneId, locationId *bson.ObjectID) (warehouseName, zoneName, locationName string) {
|
||||
if !g.IsEmpty(warehouseId) {
|
||||
warehouse, _ := daoStock.Warehouse.GetOne(ctx, &dtoStock.GetWarehouseReq{Id: warehouseId})
|
||||
if !g.IsEmpty(warehouse) {
|
||||
warehouseName = warehouse.WarehouseName
|
||||
}
|
||||
}
|
||||
if !g.IsEmpty(zoneId) {
|
||||
zone, _ := daoStock.Zone.GetOne(ctx, &dtoStock.GetZoneReq{Id: zoneId})
|
||||
if !g.IsEmpty(zone) {
|
||||
zoneName = zone.ZoneName
|
||||
}
|
||||
}
|
||||
if !g.IsEmpty(locationId) {
|
||||
location, _ := daoStock.Location.GetOne(ctx, &dtoStock.GetLocationReq{Id: locationId})
|
||||
if !g.IsEmpty(location) {
|
||||
locationName = location.LocationName
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// getPrivateSkuInfo 获取私域SKU信息
|
||||
func (s *purchaseInbound) getPrivateSkuInfo(ctx context.Context, privateSkuId, privateCategoryId *bson.ObjectID) (privateSkuName, privateCategoryPath string) {
|
||||
if !g.IsEmpty(privateSkuId) {
|
||||
privateSku, err := daoAsset.PrivateSku.GetOne(ctx, privateSkuId)
|
||||
if err == nil && !g.IsEmpty(privateSku) {
|
||||
privateSkuName = privateSku.SkuName
|
||||
}
|
||||
}
|
||||
if !g.IsEmpty(privateCategoryId) {
|
||||
privateCategory, err := daoAsset.PrivateCategory.GetOne(ctx, privateCategoryId)
|
||||
if err == nil && !g.IsEmpty(privateCategory) {
|
||||
privateCategoryPath = privateCategory.Path
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// updateInboundDetails 更新入库记录详细信息
|
||||
func (s *purchaseInbound) updateInboundDetails(ctx context.Context, inboundId, orderId *bson.ObjectID, inboundNo, batchNo, warehouseName, zoneName, locationName, privateSkuName, privateCategoryPath string) (err error) {
|
||||
return daoProcurement.PurchaseInbound.UpdateDetails(ctx, inboundId, orderId, inboundNo, batchNo,
|
||||
warehouseName, zoneName, locationName, privateSkuName, privateCategoryPath)
|
||||
}
|
||||
|
||||
// updateInboundPrivateStockId 更新入库记录关联的库存ID
|
||||
func (s *purchaseInbound) updateInboundPrivateStockId(ctx context.Context, inboundId, privateStockId *bson.ObjectID) (err error) {
|
||||
return daoProcurement.PurchaseInbound.UpdatePrivateStockId(ctx, inboundId, privateStockId)
|
||||
}
|
||||
182
service/procurement/purchase_order_item_service.go
Normal file
182
service/procurement/purchase_order_item_service.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"assets/dao/procurement"
|
||||
"assets/model/dto/procurement"
|
||||
"assets/model/entity/procurement"
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
type purchaseOrderItem struct{}
|
||||
|
||||
// PurchaseOrderItem 采购订单明细服务
|
||||
var PurchaseOrderItem = new(purchaseOrderItem)
|
||||
|
||||
// CreatePurchaseOrderItem 创建采购订单明细
|
||||
func (s *purchaseOrderItem) CreatePurchaseOrderItem(ctx context.Context, req *dto.CreatePurchaseOrderItemReq) (*dto.CreatePurchaseOrderItemRes, error) {
|
||||
// 自动计算总价(如果未提供)
|
||||
if req.TotalPrice == 0 {
|
||||
req.TotalPrice = req.UnitPrice * req.Quantity
|
||||
}
|
||||
// 默认折扣价为单价(如果未提供)
|
||||
if req.DiscountPrice == 0 {
|
||||
req.DiscountPrice = req.UnitPrice
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
ids, err := dao.PurchaseOrderItem.Insert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "创建采购订单明细失败")
|
||||
}
|
||||
|
||||
var id *bson.ObjectID
|
||||
if len(ids) > 0 {
|
||||
if objectID, ok := ids[0].(bson.ObjectID); ok {
|
||||
id = &objectID
|
||||
}
|
||||
}
|
||||
|
||||
return &dto.CreatePurchaseOrderItemRes{ID: id}, nil
|
||||
}
|
||||
|
||||
// BatchCreatePurchaseOrderItems 批量创建采购订单明细
|
||||
func (s *purchaseOrderItem) BatchCreatePurchaseOrderItems(ctx context.Context, req *dto.BatchCreatePurchaseOrderItemsReq) (*dto.BatchCreatePurchaseOrderItemsRes, error) {
|
||||
// 自动计算总价和设置默认折扣价
|
||||
for i := range req.Items {
|
||||
if req.Items[i].TotalPrice == 0 {
|
||||
req.Items[i].TotalPrice = req.Items[i].UnitPrice * req.Items[i].Quantity
|
||||
}
|
||||
if req.Items[i].DiscountPrice == 0 {
|
||||
req.Items[i].DiscountPrice = req.Items[i].UnitPrice
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
ids, err := dao.PurchaseOrderItem.BatchInsert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "批量创建采购订单明细失败")
|
||||
}
|
||||
|
||||
// 转换ID列表
|
||||
idList := make([]*bson.ObjectID, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if objectID, ok := id.(bson.ObjectID); ok {
|
||||
idList = append(idList, &objectID)
|
||||
}
|
||||
}
|
||||
|
||||
return &dto.BatchCreatePurchaseOrderItemsRes{IDs: idList}, nil
|
||||
}
|
||||
|
||||
// UpdatePurchaseOrderItem 更新采购订单明细
|
||||
func (s *purchaseOrderItem) UpdatePurchaseOrderItem(ctx context.Context, req *dto.UpdatePurchaseOrderItemReq) error {
|
||||
// 自动计算总价(如果提供了数量和单价)
|
||||
if req.Quantity > 0 && req.UnitPrice > 0 && req.TotalPrice == 0 {
|
||||
req.TotalPrice = req.UnitPrice * req.Quantity
|
||||
}
|
||||
|
||||
// 更新到数据库
|
||||
err := dao.PurchaseOrderItem.Update(ctx, req)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "更新采购订单明细失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePurchaseOrderItem 删除采购订单明细
|
||||
func (s *purchaseOrderItem) DeletePurchaseOrderItem(ctx context.Context, id *bson.ObjectID) error {
|
||||
return dao.PurchaseOrderItem.DeleteFake(ctx, id)
|
||||
}
|
||||
|
||||
// GetPurchaseOrderItem 获取采购订单明细详情
|
||||
func (s *purchaseOrderItem) GetPurchaseOrderItem(ctx context.Context, id *bson.ObjectID) (*dto.GetPurchaseOrderItemRes, error) {
|
||||
item, err := dao.PurchaseOrderItem.GetOne(ctx, id)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取采购订单明细失败")
|
||||
}
|
||||
|
||||
// 转换为响应
|
||||
res := &dto.GetPurchaseOrderItemRes{
|
||||
ID: item.Id,
|
||||
OrderId: item.OrderId,
|
||||
AssetId: item.AssetId,
|
||||
AssetSkuId: item.AssetSkuId,
|
||||
ProductName: item.ProductName,
|
||||
Specification: item.Specification,
|
||||
Brand: item.Brand,
|
||||
Quantity: item.Quantity,
|
||||
Unit: item.Unit,
|
||||
UnitPrice: item.UnitPrice,
|
||||
TotalPrice: item.TotalPrice,
|
||||
DiscountPrice: item.DiscountPrice,
|
||||
RequirementDesc: item.RequirementDesc,
|
||||
DeliveryAddress: item.DeliveryAddress,
|
||||
CreatedAt: item.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: item.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ListPurchaseOrderItems 获取采购订单明细列表
|
||||
func (s *purchaseOrderItem) ListPurchaseOrderItems(ctx context.Context, req *dto.ListPurchaseOrderItemsReq) (*dto.ListPurchaseOrderItemsRes, error) {
|
||||
// 获取数据
|
||||
items, total, err := dao.PurchaseOrderItem.List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取采购订单明细列表失败")
|
||||
}
|
||||
|
||||
// 转换为响应
|
||||
listItems := make([]*dto.PurchaseOrderItemListItem, 0, len(items))
|
||||
for _, item := range items {
|
||||
listItems = append(listItems, &dto.PurchaseOrderItemListItem{
|
||||
ID: item.Id,
|
||||
OrderId: item.OrderId,
|
||||
AssetId: item.AssetId,
|
||||
AssetSkuId: item.AssetSkuId,
|
||||
ProductName: item.ProductName,
|
||||
Specification: item.Specification,
|
||||
Brand: item.Brand,
|
||||
Quantity: item.Quantity,
|
||||
Unit: item.Unit,
|
||||
UnitPrice: item.UnitPrice,
|
||||
TotalPrice: item.TotalPrice,
|
||||
DiscountPrice: item.DiscountPrice,
|
||||
RequirementDesc: item.RequirementDesc,
|
||||
DeliveryAddress: item.DeliveryAddress,
|
||||
CreatedAt: item.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: item.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
return &dto.ListPurchaseOrderItemsRes{
|
||||
List: listItems,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListByOrderId 根据订单ID获取采购订单明细列表
|
||||
func (s *purchaseOrderItem) ListByOrderId(ctx context.Context, orderId *bson.ObjectID) ([]*entity.PurchaseOrderItem, error) {
|
||||
items, err := dao.PurchaseOrderItem.ListByOrderId(ctx, orderId)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取订单明细列表失败")
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// GenerateTestData 生成测试数据
|
||||
func (s *purchaseOrderItem) GenerateTestData(ctx context.Context) error {
|
||||
|
||||
testData := &dto.BatchCreatePurchaseOrderItemsReq{}
|
||||
|
||||
_, err := s.BatchCreatePurchaseOrderItems(ctx, testData)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "生成测试数据失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
199
service/procurement/purchase_order_service.go
Normal file
199
service/procurement/purchase_order_service.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"assets/consts/procurement"
|
||||
"assets/dao/procurement"
|
||||
"assets/model/dto/procurement"
|
||||
"assets/model/entity/procurement"
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
type purchaseOrder struct{}
|
||||
|
||||
// PurchaseOrder 采购订单服务
|
||||
var PurchaseOrder = new(purchaseOrder)
|
||||
|
||||
// CreatePurchaseOrder 创建采购订单
|
||||
func (s *purchaseOrder) CreatePurchaseOrder(ctx context.Context, req *dto.CreatePurchaseOrderReq) (*dto.CreatePurchaseOrderRes, error) {
|
||||
|
||||
// 保存到数据库
|
||||
ids, err := dao.PurchaseOrder.Insert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "创建采购订单失败")
|
||||
}
|
||||
|
||||
var id *bson.ObjectID
|
||||
if len(ids) > 0 {
|
||||
if objectID, ok := ids[0].(bson.ObjectID); ok {
|
||||
id = &objectID
|
||||
}
|
||||
}
|
||||
|
||||
return &dto.CreatePurchaseOrderRes{ID: id}, nil
|
||||
}
|
||||
|
||||
// BatchCreatePurchaseOrders 批量创建采购订单
|
||||
func (s *purchaseOrder) BatchCreatePurchaseOrders(ctx context.Context, req *dto.BatchCreatePurchaseOrdersReq) (*dto.BatchCreatePurchaseOrdersRes, error) {
|
||||
// 保存到数据库
|
||||
ids, err := dao.PurchaseOrder.BatchInsert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "批量创建采购订单失败")
|
||||
}
|
||||
|
||||
// 转换ID列表
|
||||
idList := make([]*bson.ObjectID, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if objectID, ok := id.(bson.ObjectID); ok {
|
||||
idList = append(idList, &objectID)
|
||||
}
|
||||
}
|
||||
|
||||
return &dto.BatchCreatePurchaseOrdersRes{IDs: idList}, nil
|
||||
}
|
||||
|
||||
// UpdatePurchaseOrder 更新采购订单
|
||||
func (s *purchaseOrder) UpdatePurchaseOrder(ctx context.Context, req *dto.UpdatePurchaseOrderReq) error {
|
||||
// 更新到数据库
|
||||
err := dao.PurchaseOrder.Update(ctx, req)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "更新采购订单失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePurchaseOrder 删除采购订单
|
||||
func (s *purchaseOrder) DeletePurchaseOrder(ctx context.Context, id *bson.ObjectID) error {
|
||||
return dao.PurchaseOrder.DeleteFake(ctx, id)
|
||||
}
|
||||
|
||||
// GetPurchaseOrder 获取采购订单详情
|
||||
func (s *purchaseOrder) GetPurchaseOrder(ctx context.Context, id *bson.ObjectID) (*dto.GetPurchaseOrderRes, error) {
|
||||
order, err := dao.PurchaseOrder.GetOne(ctx, id)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取采购订单失败")
|
||||
}
|
||||
|
||||
// 转换为响应
|
||||
res := &dto.GetPurchaseOrderRes{
|
||||
ID: order.Id,
|
||||
OrderNo: order.OrderNo,
|
||||
Title: order.Title,
|
||||
Description: order.Description,
|
||||
OrderType: order.OrderType,
|
||||
BuyerId: order.BuyerId,
|
||||
BuyerName: order.BuyerName,
|
||||
BuyerType: order.BuyerType,
|
||||
Status: order.Status,
|
||||
StatusText: consts.GetPurchaseOrderStatusText(order.Status),
|
||||
Priority: order.Priority,
|
||||
ExpectedDelivery: formatGTime(order.ExpectedDelivery),
|
||||
ExpiryTime: formatGTime(order.ExpiryTime),
|
||||
CreatedAt: order.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: order.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
// 转换指定供应商模式信息
|
||||
if order.DirectPurchase != nil {
|
||||
res.DirectPurchase = &dto.DirectPurchaseInfoRes{
|
||||
SupplierId: order.DirectPurchase.SupplierId,
|
||||
SupplierName: order.DirectPurchase.SupplierName,
|
||||
SupplierCode: order.DirectPurchase.SupplierCode,
|
||||
AssignReason: order.DirectPurchase.AssignReason,
|
||||
DeliveryAddress: order.DirectPurchase.DeliveryAddress,
|
||||
ContactPerson: order.DirectPurchase.ContactPerson,
|
||||
ContactPhone: order.DirectPurchase.ContactPhone,
|
||||
ResponseStatus: order.DirectPurchase.ResponseStatus,
|
||||
AssignedAt: formatGTime(order.DirectPurchase.AssignedAt),
|
||||
AcceptedAt: formatGTime(order.DirectPurchase.AcceptedAt),
|
||||
RejectedAt: formatGTime(order.DirectPurchase.RejectedAt),
|
||||
DeliveredAt: formatGTime(order.DirectPurchase.DeliveredAt),
|
||||
}
|
||||
}
|
||||
|
||||
// 转换竞价模式信息
|
||||
if order.BiddingInfo != nil {
|
||||
res.BiddingInfo = &dto.BiddingInfoRes{
|
||||
BidMode: order.BiddingInfo.BidMode,
|
||||
BidModeText: consts.GetBidModeText(order.BiddingInfo.BidMode),
|
||||
MinSuppliers: order.BiddingInfo.MinSuppliers,
|
||||
MaxSuppliers: order.BiddingInfo.MaxSuppliers,
|
||||
BidDuration: order.BiddingInfo.BidDuration,
|
||||
BidSupplierCount: order.BiddingInfo.BidSupplierCount,
|
||||
BidStartAt: formatGTime(order.BiddingInfo.BidStartAt),
|
||||
BidEndAt: formatGTime(order.BiddingInfo.BidEndAt),
|
||||
ResultPublishedAt: formatGTime(order.BiddingInfo.ResultPublishedAt),
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ListPurchaseOrders 获取采购订单列表
|
||||
func (s *purchaseOrder) ListPurchaseOrders(ctx context.Context, req *dto.ListPurchaseOrdersReq) (*dto.ListPurchaseOrdersRes, error) {
|
||||
// 获取数据
|
||||
orders, total, err := dao.PurchaseOrder.List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取采购订单列表失败")
|
||||
}
|
||||
|
||||
// 转换为响应
|
||||
listItems := make([]*dto.PurchaseOrderListItem, 0, len(orders))
|
||||
for _, order := range orders {
|
||||
listItems = append(listItems, &dto.PurchaseOrderListItem{
|
||||
ID: order.Id,
|
||||
OrderNo: order.OrderNo,
|
||||
Title: order.Title,
|
||||
OrderType: order.OrderType,
|
||||
OrderTypeText: consts.GetPurchaseOrderTypeText(order.OrderType),
|
||||
BuyerName: order.BuyerName,
|
||||
BuyerType: order.BuyerType,
|
||||
Status: order.Status,
|
||||
StatusText: consts.GetPurchaseOrderStatusText(order.Status),
|
||||
Priority: order.Priority,
|
||||
ExpectedDelivery: formatGTime(order.ExpectedDelivery),
|
||||
ExpiryTime: formatGTime(order.ExpiryTime),
|
||||
CreatedAt: order.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: order.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
return &dto.ListPurchaseOrdersRes{
|
||||
List: listItems,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListByBuyerId 根据采购方ID获取采购订单列表
|
||||
func (s *purchaseOrder) ListByBuyerId(ctx context.Context, buyerId *bson.ObjectID) ([]*entity.PurchaseOrder, error) {
|
||||
orders, err := dao.PurchaseOrder.ListByBuyerId(ctx, buyerId)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取订单列表失败")
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
// GenerateTestData 生成测试数据
|
||||
func (s *purchaseOrder) GenerateTestData(ctx context.Context) error {
|
||||
|
||||
testData := &dto.BatchCreatePurchaseOrdersReq{}
|
||||
|
||||
_, err := s.BatchCreatePurchaseOrders(ctx, testData)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "生成测试数据失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// formatGTime 格式化时间
|
||||
func formatGTime(t *gtime.Time) string {
|
||||
if t == nil {
|
||||
return ""
|
||||
}
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
172
service/procurement/supplier_service.go
Normal file
172
service/procurement/supplier_service.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"assets/consts/procurement"
|
||||
"assets/dao/procurement"
|
||||
"assets/model/dto/procurement"
|
||||
"assets/model/entity/procurement"
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
type supplier struct{}
|
||||
|
||||
// Supplier 供应商服务
|
||||
var Supplier = new(supplier)
|
||||
|
||||
// CreateSupplier 创建供应商
|
||||
func (s *supplier) CreateSupplier(ctx context.Context, req *dto.CreateSupplierReq) (*dto.CreateSupplierRes, error) {
|
||||
// 转换为实体
|
||||
_ = &entity.Supplier{
|
||||
Name: req.Name,
|
||||
Code: req.Code,
|
||||
Phone: req.Phone,
|
||||
Mobile: req.Mobile,
|
||||
Email: req.Email,
|
||||
Address: req.Address,
|
||||
Status: consts.SupplierStatus(1), // 默认活跃状态
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
ids, err := dao.Supplier.Insert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "创建供应商失败")
|
||||
}
|
||||
|
||||
var id *bson.ObjectID
|
||||
if len(ids) > 0 {
|
||||
if objectID, ok := ids[0].(bson.ObjectID); ok {
|
||||
id = &objectID
|
||||
}
|
||||
}
|
||||
|
||||
return &dto.CreateSupplierRes{ID: id}, nil
|
||||
}
|
||||
|
||||
// BatchCreateSuppliers 批量创建供应商
|
||||
func (s *supplier) BatchCreateSuppliers(ctx context.Context, req *dto.BatchCreateSuppliersReq) (*dto.BatchCreateSuppliersRes, error) {
|
||||
// 保存到数据库
|
||||
ids, err := dao.Supplier.BatchInsert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "批量创建供应商失败")
|
||||
}
|
||||
|
||||
// 转换ID列表
|
||||
idList := make([]*bson.ObjectID, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if objectID, ok := id.(bson.ObjectID); ok {
|
||||
idList = append(idList, &objectID)
|
||||
}
|
||||
}
|
||||
|
||||
return &dto.BatchCreateSuppliersRes{IDs: idList}, nil
|
||||
}
|
||||
|
||||
// UpdateSupplier 更新供应商
|
||||
func (s *supplier) UpdateSupplier(ctx context.Context, req *dto.UpdateSupplierReq) error {
|
||||
// 更新到数据库
|
||||
err := dao.Supplier.Update(ctx, req)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "更新供应商失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteSupplier 删除供应商
|
||||
func (s *supplier) DeleteSupplier(ctx context.Context, id *bson.ObjectID) error {
|
||||
return dao.Supplier.DeleteFake(ctx, id)
|
||||
}
|
||||
|
||||
// GetSupplier 获取供应商详情
|
||||
func (s *supplier) GetSupplier(ctx context.Context, id *bson.ObjectID) (*dto.GetSupplierRes, error) {
|
||||
supplier, err := dao.Supplier.GetOne(ctx, id)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取供应商失败")
|
||||
}
|
||||
|
||||
// 转换为响应
|
||||
res := &dto.GetSupplierRes{
|
||||
ID: supplier.Id,
|
||||
Name: supplier.Name,
|
||||
Code: supplier.Code,
|
||||
Phone: supplier.Phone,
|
||||
Mobile: supplier.Mobile,
|
||||
Email: supplier.Email,
|
||||
Website: supplier.Website,
|
||||
Address: supplier.Address,
|
||||
Status: supplier.Status,
|
||||
StatusText: consts.GetSupplierStatusText(supplier.Status),
|
||||
Rating: supplier.Rating,
|
||||
CreatedAt: supplier.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: supplier.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ListSuppliers 获取供应商列表
|
||||
func (s *supplier) ListSuppliers(ctx context.Context, req *dto.ListSuppliersReq) (*dto.ListSuppliersRes, error) {
|
||||
// 获取数据
|
||||
suppliers, total, err := dao.Supplier.List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取供应商列表失败")
|
||||
}
|
||||
|
||||
// 转换为响应
|
||||
listItems := make([]*dto.SupplierListItem, 0, len(suppliers))
|
||||
for _, supplier := range suppliers {
|
||||
listItems = append(listItems, &dto.SupplierListItem{
|
||||
ID: supplier.Id,
|
||||
Name: supplier.Name,
|
||||
Code: supplier.Code,
|
||||
Phone: supplier.Phone,
|
||||
Mobile: supplier.Mobile,
|
||||
Email: supplier.Email,
|
||||
Address: supplier.Address,
|
||||
Status: supplier.Status,
|
||||
StatusText: consts.GetSupplierStatusText(supplier.Status),
|
||||
Rating: supplier.Rating,
|
||||
CreatedAt: supplier.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: supplier.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
return &dto.ListSuppliersRes{
|
||||
List: listItems,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetSupplierOptions 获取供应商选项(用于下拉选择)
|
||||
func (s *supplier) GetSupplierOptions(ctx context.Context) ([]*dto.SupplierListItem, error) {
|
||||
suppliers, err := dao.Supplier.FindActiveSuppliers(ctx)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取供应商选项失败")
|
||||
}
|
||||
|
||||
options := make([]*dto.SupplierListItem, 0, len(suppliers))
|
||||
for _, supplier := range suppliers {
|
||||
options = append(options, &dto.SupplierListItem{
|
||||
ID: supplier.Id,
|
||||
Name: supplier.Name,
|
||||
Code: supplier.Code,
|
||||
})
|
||||
}
|
||||
|
||||
return options, nil
|
||||
}
|
||||
|
||||
// GenerateTestData 生成测试数据
|
||||
func (s *supplier) GenerateTestData(ctx context.Context) error {
|
||||
testData := &dto.BatchCreateSuppliersReq{}
|
||||
|
||||
_, err := s.BatchCreateSuppliers(ctx, testData)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "生成测试数据失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user