daShangDao_psiServer/service/purchase.go
Administrator 4253c6ade0 1.商品实现多图/api/product/list
2.在商品管理下的商品列表接口里 分别统计:已落位 locatedCount, 未落位 unlocatedCount, 启用中 enabledCount, 已禁用 disabledCount 4个字段并进行返回
3.新增一个接口 对商品名称字段进行修改,对实拍图字段修改,实拍图可以为单图或者多图
4.波次任务列表- 缺少统计信息:分别为今日入库波次数 today_inbound_waves,
昨日入库波次数 ,yesterday_inbound_waves
 今日入库数量,today_inbound_qty
昨日入库数量,yesterday_inbound_qty
今日出库数量,today_outbound_qty
昨日出库数量 yesterday_outbound_qty
5.采购单列表- 缺少导出到旺店通功能
2026-06-22 16:14:10 +08:00

350 lines
11 KiB
Go

package service
import (
"encoding/json"
"psi/constant"
"fmt"
"psi/config"
"psi/database"
"psi/models"
systemReq "psi/models/request"
systemRes "psi/models/response"
"psi/utils"
"time"
"github.com/xuri/excelize/v2"
"gorm.io/gorm"
)
type PurchaseService struct{}
// ExportPurchaseOrderToWDT 导出采购单到旺店通
func (s *PurchaseService) ExportPurchaseOrderToWDT(req systemReq.ExportPurchaseOrderToWDTRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.ExportProductResponse, error) {
databaseConn := database.OptionalDB(db...)
query := databaseConn.Model(&models.PurchaseOrder{}).Where("purchase_order.is_del = ?", 0)
if role == 128 {
query = query.Where("purchase_order.creator_id = ?", creatorID)
}
if len(req.IDs) > 0 {
query = query.Where("purchase_order.id IN ?", req.IDs)
}
if req.Status > 0 {
query = query.Where("purchase_order.status = ?", req.Status)
}
if req.SupplierID > 0 {
query = query.Where("purchase_order.supplier_id = ?", req.SupplierID)
}
if req.WarehouseID > 0 {
query = query.Where("purchase_order.warehouse_id = ?", req.WarehouseID)
}
if req.PoNo != "" {
query = query.Where("purchase_order.po_no LIKE ?", "%"+req.PoNo+"%")
}
if req.StartDate > 0 {
query = query.Where("purchase_order.created_at >= ?", req.StartDate)
}
if req.EndDate > 0 {
query = query.Where("purchase_order.created_at <= ?", req.EndDate)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, utils.NewError("查询总数失败")
}
if total == 0 {
return nil, fmt.Errorf("没有符合条件的采购单数据")
}
type PurchaseOrderExportData struct {
PoNo string `gorm:"column:po_no"`
SupplierName string `gorm:"column:supplier_name"`
WarehouseName string `gorm:"column:warehouse_name"`
ProductName string `gorm:"column:product_name"`
Barcode string `gorm:"column:barcode"`
Quantity int64 `gorm:"column:quantity"`
UnitPrice int64 `gorm:"column:unit_price"`
Amount int64 `gorm:"column:amount"`
OrderDate int64 `gorm:"column:order_date"`
ExpectedArrivalDate int64 `gorm:"column:expected_arrival_date"`
Status int8 `gorm:"column:status"`
Creator string `gorm:"column:creator"`
Remark string `gorm:"column:remark"`
}
var orders []PurchaseOrderExportData
if err := query.Select(`purchase_order.po_no,
s.name as supplier_name,
w.name as warehouse_name,
p.name as product_name,
p.barcode,
poi.quantity,
poi.unit_price,
poi.amount,
purchase_order.order_date,
purchase_order.expected_arrival_date,
purchase_order.status,
purchase_order.creator,
purchase_order.remark`).
Joins("LEFT JOIN supplier s ON purchase_order.supplier_id = s.id AND s.is_del = 0").
Joins("LEFT JOIN warehouse w ON purchase_order.warehouse_id = w.id AND w.is_del = 0").
Joins("LEFT JOIN purchase_order_item poi ON poi.purchase_order_id = purchase_order.id AND poi.is_del = 0").
Joins("LEFT JOIN product p ON poi.product_id = p.id AND p.is_del = 0").
Order("purchase_order.created_at DESC").
Find(&orders).Error; err != nil {
return nil, utils.NewError("查询采购单数据失败")
}
f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{
"source": "关闭Excel文件",
"error": fmt.Sprintf("关闭失败: %v", err),
})
}
}()
sheetName := "Sheet1"
f.SetSheetName("Sheet1", sheetName)
headers := []string{"采购单号", "供应商", "仓库", "商品名称", "ISBN/条码", "采购数量", "单价(元)", "金额(元)", "订单日期", "预计到货日期", "状态", "创建人", "备注"}
for i, header := range headers {
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
f.SetCellValue(sheetName, cell, header)
}
headerStyle, _ := f.NewStyle(&excelize.Style{
Font: &excelize.Font{
Bold: true,
Size: 12,
},
Alignment: &excelize.Alignment{
Horizontal: "center",
Vertical: "center",
},
Fill: excelize.Fill{
Type: "pattern",
Color: []string{"#E0E0E0"},
Pattern: 1,
},
})
f.SetCellStyle(sheetName, "A1", "M1", headerStyle)
statusMap := map[int8]string{
1: "草稿",
2: "已提交",
3: "已审核",
4: "部分收货",
5: "已收货",
6: "已取消",
}
for idx, order := range orders {
row := idx + 2
f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), order.PoNo)
f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), order.SupplierName)
f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), order.WarehouseName)
f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), order.ProductName)
f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), order.Barcode)
f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), order.Quantity)
f.SetCellValue(sheetName, fmt.Sprintf("G%d", row), float64(order.UnitPrice)/100.0)
f.SetCellValue(sheetName, fmt.Sprintf("H%d", row), float64(order.Amount)/100.0)
orderDateStr := time.Unix(order.OrderDate, 0).Format("2006-01-02")
f.SetCellValue(sheetName, fmt.Sprintf("I%d", row), orderDateStr)
expectedDateStr := time.Unix(order.ExpectedArrivalDate, 0).Format("2006-01-02")
f.SetCellValue(sheetName, fmt.Sprintf("J%d", row), expectedDateStr)
statusText := statusMap[order.Status]
if statusText == "" {
statusText = "未知"
}
f.SetCellValue(sheetName, fmt.Sprintf("K%d", row), statusText)
f.SetCellValue(sheetName, fmt.Sprintf("L%d", row), order.Creator)
f.SetCellValue(sheetName, fmt.Sprintf("M%d", row), order.Remark)
}
colWidths := map[string]float64{
"A": 20,
"B": 15,
"C": 15,
"D": 30,
"E": 15,
"F": 12,
"G": 12,
"H": 12,
"I": 15,
"J": 15,
"K": 12,
"L": 12,
"M": 30,
}
for col, width := range colWidths {
f.SetColWidth(sheetName, col, col, width)
}
now := time.Now()
fileName := fmt.Sprintf("purchase_order_wdt_%s.xlsx", now.Format("20060102150405"))
filePath := fmt.Sprintf("excel/%s", fileName)
if err := f.SaveAs(filePath); err != nil {
return nil, fmt.Errorf("保存Excel文件失败: %v", err)
}
return &systemRes.ExportProductResponse{
Total: total,
FileName: fileName,
FilePath: config.AppConfig.Server.Host + filePath,
}, nil
}
// GetPurchaseOrderList 获取采购订单列表
func (s *PurchaseService) GetPurchaseOrderList(req systemReq.GetPurchaseOrderListRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.PurchaseOrderListResponse, error) {
databaseConn := database.OptionalDB(db...)
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 || req.PageSize > 100 {
req.PageSize = 20
}
query := databaseConn.Model(&models.PurchaseOrder{}).Where("purchase_order.is_del = ?", 0)
if role == 128 {
query = query.Where("purchase_order.creator_id = ?", creatorID)
}
if req.Status > 0 {
query = query.Where("purchase_order.status = ?", req.Status)
}
if req.SupplierID > 0 {
query = query.Where("purchase_order.supplier_id = ?", req.SupplierID)
}
if req.WarehouseID > 0 {
query = query.Where("purchase_order.warehouse_id = ?", req.WarehouseID)
}
if req.PoNo != "" {
query = query.Where("purchase_order.po_no LIKE ?", "%"+req.PoNo+"%")
}
if req.StartDate > 0 {
query = query.Where("purchase_order.created_at >= ?", req.StartDate)
}
if req.EndDate > 0 {
query = query.Where("purchase_order.created_at <= ?", req.EndDate)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, utils.NewError("查询总数失败")
}
if total == 0 {
return &systemRes.PurchaseOrderListResponse{
List: []systemRes.PurchaseOrderItem{},
Total: 0,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
var orders []systemRes.OrderWithInfo
offset := (req.Page - 1) * req.PageSize
if err := query.Select("purchase_order.*, s.name as supplier_name, w.name as warehouse_name").
Joins("LEFT JOIN supplier s ON purchase_order.supplier_id = s.id AND s.is_del = 0").
Joins("LEFT JOIN warehouse w ON purchase_order.warehouse_id = w.id AND w.is_del = 0").
Order("purchase_order.created_at DESC").
Offset(offset).
Limit(req.PageSize).
Find(&orders).Error; err != nil {
return nil, utils.NewError("查询采购订单列表失败")
}
orderItems := make([]systemRes.PurchaseOrderItem, 0, len(orders))
for _, order := range orders {
orderItems = append(orderItems, systemRes.ConvertPurchaseOrderToItem(
order.PurchaseOrder,
order.SupplierName,
order.WarehouseName,
))
}
return &systemRes.PurchaseOrderListResponse{
List: orderItems,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// GetPurchaseOrderDetail 获取采购订单详情
func (s *PurchaseService) GetPurchaseOrderDetail(id int64, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.PurchaseOrderDetailResponse, error) {
databaseConn := database.OptionalDB(db...)
query := databaseConn.Model(&models.PurchaseOrder{}).
Select("purchase_order.*, s.name as supplier_name, w.name as warehouse_name").
Joins("LEFT JOIN supplier s ON purchase_order.supplier_id = s.id AND s.is_del = 0").
Joins("LEFT JOIN warehouse w ON purchase_order.warehouse_id = w.id AND w.is_del = 0").
Where("purchase_order.id = ? AND purchase_order.is_del = ?", id, 0)
if role == 128 {
query = query.Where("purchase_order.creator_id = ?", creatorID)
}
var order systemRes.OrderWithInfo
result := query.First(&order)
if result.Error != nil {
return nil, utils.NewError("采购订单不存在")
}
var items []systemRes.ItemWithProduct
databaseConn.Model(&models.PurchaseOrderItem{}).
Select("purchase_order_item.*, p.name as product_name, p.barcode as product_code, p.category_id,p.sale_price, c.name as category_name, p.live_image, roi.location_id, l.code as location_code").
Joins("LEFT JOIN product p ON purchase_order_item.product_id = p.id AND p.is_del = 0").
Joins("LEFT JOIN product_category c ON p.category_id = c.id AND c.is_del = 0").
Joins("LEFT JOIN receiving_order ro ON ro.purchase_order_id = purchase_order_item.purchase_order_id AND ro.is_del = 0").
Joins("LEFT JOIN receiving_order_item roi ON roi.receiving_order_id = ro.id AND roi.product_id = purchase_order_item.product_id AND roi.is_del = 0").
Joins("LEFT JOIN location l ON roi.location_id = l.id AND l.is_del = 0").
Where("purchase_order_item.purchase_order_id = ? AND purchase_order_item.is_del = ?", order.ID, 0).
Find(&items)
detailItems := make([]systemRes.PurchaseOrderDetailItem, 0, len(items))
for _, item := range items {
var imageList []string
if len(item.LiveImage) > 0 {
json.Unmarshal(item.LiveImage, &imageList)
}
detailItems = append(detailItems, systemRes.PurchaseOrderDetailItem{
ID: item.ID,
PurchaseOrderID: item.PurchaseOrderID,
ProductID: item.ProductID,
ProductName: item.ProductName,
ProductCode: item.ProductCode,
SalePrice: item.SalePrice,
CategoryID: item.CategoryID,
CategoryName: item.CategoryName,
LiveImage: imageList,
Quantity: item.Quantity,
ReceivedQuantity: item.ReceivedQuantity,
UnitPrice: item.UnitPrice,
Amount: item.Amount,
LocationID: item.LocationID,
LocationCode: item.LocationCode,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}
detail := systemRes.ConvertPurchaseOrderToDetail(order.PurchaseOrder, order.SupplierName, order.WarehouseName, detailItems)
return &detail, nil
}