360 lines
12 KiB
Go
360 lines
12 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"psi/database"
|
|
"psi/models"
|
|
systemReq "psi/models/request"
|
|
systemRes "psi/models/response"
|
|
"psi/utils"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type SalesService struct{}
|
|
|
|
// GetSalesOrderList 获取销售订单列表
|
|
func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.SalesOrderListResponse, 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.SalesOrder{}).Where("sales_order.is_del = ?", 0)
|
|
if role == 128 {
|
|
query = query.Where("sales_order.sales_person_id = ?", creatorID)
|
|
}
|
|
|
|
if req.Status > 0 {
|
|
query = query.Where("sales_order.status = ?", req.Status)
|
|
}
|
|
if req.CustomerID > 0 {
|
|
query = query.Where("sales_order.customer_id = ?", req.CustomerID)
|
|
}
|
|
if req.WarehouseID > 0 {
|
|
query = query.Where("sales_order.warehouse_id = ?", req.WarehouseID)
|
|
}
|
|
if req.SoNo != "" {
|
|
query = query.Where("sales_order.so_no LIKE ?", "%"+req.SoNo+"%")
|
|
}
|
|
if req.StartDate > 0 {
|
|
query = query.Where("sales_order.created_at >= ?", req.StartDate)
|
|
}
|
|
if req.EndDate > 0 {
|
|
query = query.Where("sales_order.created_at <= ?", req.EndDate)
|
|
}
|
|
|
|
if req.AssociationOrderNo != "" {
|
|
query = query.Where("sales_order.association_order_no LIKE ?", "%"+req.AssociationOrderNo+"%")
|
|
}
|
|
if req.LogisticsNo != "" {
|
|
subQuery := databaseConn.Model(&models.SalesOrderItem{}).
|
|
Select("sales_order_id").
|
|
Where("logistics_no LIKE ? AND is_del = 0", "%"+req.LogisticsNo+"%")
|
|
query = query.Where("sales_order.id IN (?)", subQuery)
|
|
}
|
|
if req.ShopType > 0 {
|
|
query = query.Where("sales_order.shop_type = ?", req.ShopType)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, utils.NewError("查询总数失败")
|
|
}
|
|
|
|
if total == 0 {
|
|
return &systemRes.SalesOrderListResponse{
|
|
List: []systemRes.SalesOrderItem{},
|
|
Total: 0,
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
}, nil
|
|
}
|
|
|
|
var orders []systemRes.SalesOrderWithInfo
|
|
offset := (req.Page - 1) * req.PageSize
|
|
if err := query.Select("sales_order.*, c.name as customer_name, w.name as warehouse_name").
|
|
Joins("LEFT JOIN customer c ON sales_order.customer_id = c.id AND c.is_del = 0").
|
|
Joins("LEFT JOIN warehouse w ON sales_order.warehouse_id = w.id AND w.is_del = 0").
|
|
Order("sales_order.created_at DESC").
|
|
Offset(offset).
|
|
Limit(req.PageSize).
|
|
Find(&orders).Error; err != nil {
|
|
return nil, utils.NewError("查询销售订单列表失败")
|
|
}
|
|
|
|
// 收集订单ID用于批量查询物流单号
|
|
orderIDs := make([]int64, len(orders))
|
|
for i, order := range orders {
|
|
orderIDs[i] = order.ID
|
|
}
|
|
|
|
type logRow struct {
|
|
SalesOrderID int64 `gorm:"column:sales_order_id"`
|
|
LogisticsNos string `gorm:"column:logistics_nos"`
|
|
}
|
|
var logRows []logRow
|
|
databaseConn.Table("sales_order_item").
|
|
Select("sales_order_id, COALESCE(GROUP_CONCAT(DISTINCT logistics_no SEPARATOR ', '), '') as logistics_nos").
|
|
Where("sales_order_id IN ? AND is_del = ? AND logistics_no != ''", orderIDs, 0).
|
|
Group("sales_order_id").
|
|
Scan(&logRows)
|
|
|
|
logByOrderID := make(map[int64]string, len(logRows))
|
|
for _, row := range logRows {
|
|
logByOrderID[row.SalesOrderID] = row.LogisticsNos
|
|
}
|
|
|
|
orderItems := make([]systemRes.SalesOrderItem, 0, len(orders))
|
|
for _, order := range orders {
|
|
orderItems = append(orderItems, systemRes.ConvertSalesOrderToItem(
|
|
order.SalesOrder,
|
|
order.CustomerName,
|
|
order.WarehouseName,
|
|
logByOrderID[order.ID],
|
|
))
|
|
}
|
|
|
|
return &systemRes.SalesOrderListResponse{
|
|
List: orderItems,
|
|
Total: total,
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
}, nil
|
|
}
|
|
|
|
// GetSalesOrderDetailList 获取分页的销售订单详情列表(含明细)
|
|
func (s *SalesService) GetSalesOrderDetailList(req systemReq.GetSalesOrderDetailListRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.SalesOrderDetailListResponse, 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.SalesOrder{}).Where("sales_order.is_del = ?", 0)
|
|
if role == 128 {
|
|
query = query.Where("sales_order.sales_person_id = ?", creatorID)
|
|
}
|
|
//if req.Status > 0 {
|
|
// query = query.Where("sales_order.status = ?", req.Status)
|
|
//}
|
|
//if req.CustomerID > 0 {
|
|
// query = query.Where("sales_order.customer_id = ?", req.CustomerID)
|
|
//}
|
|
//if req.WarehouseID > 0 {
|
|
// query = query.Where("sales_order.warehouse_id = ?", req.WarehouseID)
|
|
//}
|
|
//if req.SoNo != "" {
|
|
// query = query.Where("sales_order.so_no LIKE ?", "%"+req.SoNo+"%")
|
|
//}
|
|
//if req.StartDate > 0 {
|
|
// query = query.Where("sales_order.created_at >= ?", req.StartDate)
|
|
//}
|
|
//if req.EndDate > 0 {
|
|
// query = query.Where("sales_order.created_at <= ?", req.EndDate)
|
|
//}
|
|
if req.Status > 0 {
|
|
query = query.Where("sales_order.status = ?", req.Status)
|
|
}
|
|
if req.CustomerID > 0 {
|
|
query = query.Where("sales_order.customer_id = ?", req.CustomerID)
|
|
}
|
|
if req.WarehouseID > 0 {
|
|
query = query.Where("sales_order.warehouse_id = ?", req.WarehouseID)
|
|
}
|
|
if req.SoNo != "" {
|
|
query = query.Where("sales_order.so_no LIKE ?", "%"+req.SoNo+"%")
|
|
}
|
|
if req.StartDate > 0 {
|
|
query = query.Where("sales_order.created_at >= ?", req.StartDate)
|
|
}
|
|
if req.EndDate > 0 {
|
|
query = query.Where("sales_order.created_at <= ?", req.EndDate)
|
|
}
|
|
if req.AssociationOrderNo != "" {
|
|
query = query.Where("sales_order.association_order_no LIKE ?", "%"+req.AssociationOrderNo+"%")
|
|
}
|
|
if req.LogisticsNo != "" {
|
|
subQuery := databaseConn.Model(&models.SalesOrderItem{}).
|
|
Select("sales_order_id").
|
|
Where("logistics_no LIKE ? AND is_del = 0", "%"+req.LogisticsNo+"%")
|
|
query = query.Where("sales_order.id IN (?)", subQuery)
|
|
}
|
|
if req.ShopType > 0 {
|
|
query = query.Where("sales_order.shop_type = ?", req.ShopType)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, utils.NewError("查询总数失败")
|
|
}
|
|
|
|
if total == 0 {
|
|
return &systemRes.SalesOrderDetailListResponse{
|
|
List: []systemRes.SalesOrderDetailResponse{},
|
|
Total: 0,
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
}, nil
|
|
}
|
|
|
|
// 查询分页的销售订单
|
|
var orders []systemRes.SalesOrderWithInfo
|
|
offset := (req.Page - 1) * req.PageSize
|
|
if err := query.Select("sales_order.*, c.name as customer_name, w.name as warehouse_name").
|
|
Joins("LEFT JOIN customer c ON sales_order.customer_id = c.id AND c.is_del = 0").
|
|
Joins("LEFT JOIN warehouse w ON sales_order.warehouse_id = w.id AND w.is_del = 0").
|
|
Order("sales_order.created_at DESC").
|
|
Offset(offset).
|
|
Limit(req.PageSize).
|
|
Find(&orders).Error; err != nil {
|
|
return nil, utils.NewError("查询销售订单列表失败")
|
|
}
|
|
|
|
// 提取订单ID列表
|
|
orderIDs := make([]int64, len(orders))
|
|
for i, order := range orders {
|
|
orderIDs[i] = order.ID
|
|
}
|
|
|
|
// 批量查询所有订单的明细项(含商品信息)
|
|
var allItems []systemRes.SalesOrderItemWithProduct
|
|
if err := databaseConn.Model(&models.SalesOrderItem{}).
|
|
Select("sales_order_item.*, p.name as product_name, p.barcode as product_code, p.category_id, p.sale_price as product_sale_price, c.name as category_name, p.live_image ,lt.code as location_code").
|
|
Joins("LEFT JOIN product p ON sales_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 inventory_detail de on p.id = de.product_id AND de.is_del = 0").
|
|
Joins("LEFT JOIN location lt on de.location_id = lt.id").
|
|
Where("sales_order_item.sales_order_id IN ? AND sales_order_item.is_del = ?", orderIDs, 0).
|
|
Find(&allItems).Error; err != nil {
|
|
return nil, utils.NewError("查询订单明细失败")
|
|
}
|
|
|
|
// 按订单ID分组明细项
|
|
itemMap := make(map[int64][]systemRes.SalesOrderItemWithProduct)
|
|
for _, item := range allItems {
|
|
itemMap[item.SalesOrderID] = append(itemMap[item.SalesOrderID], item)
|
|
}
|
|
|
|
// 组装响应
|
|
detailList := make([]systemRes.SalesOrderDetailResponse, 0, len(orders))
|
|
for _, order := range orders {
|
|
items := itemMap[order.ID]
|
|
detailItems := make([]systemRes.SalesOrderDetailItem, 0, len(items))
|
|
for _, item := range items {
|
|
var imageList []string
|
|
if len(item.LiveImage) > 0 {
|
|
json.Unmarshal(item.LiveImage, &imageList)
|
|
}
|
|
detailItems = append(detailItems, systemRes.SalesOrderDetailItem{
|
|
ID: item.ID,
|
|
SalesOrderID: item.SalesOrderID,
|
|
ProductID: item.ProductID,
|
|
ProductName: item.ProductName,
|
|
ProductCode: item.ProductCode,
|
|
ProductSalePrice: item.ProductSalePrice,
|
|
CategoryID: item.CategoryID,
|
|
CategoryName: item.CategoryName,
|
|
LiveImage: imageList,
|
|
Quantity: item.Quantity,
|
|
AllocatedQuantity: item.AllocatedQuantity,
|
|
ShippedQuantity: item.ShippedQuantity,
|
|
UnitPrice: item.UnitPrice,
|
|
Amount: item.Amount,
|
|
ReceiverName: item.ReceiverName,
|
|
ReceiverPhone: item.ReceiverPhone,
|
|
ReceiverAddress: item.ReceiverAddress,
|
|
LogisticsCompany: item.LogisticsCompany,
|
|
LogisticsNo: item.LogisticsNo,
|
|
LocationCode: item.LocationCode,
|
|
CreatedAt: item.CreatedAt,
|
|
UpdatedAt: item.UpdatedAt,
|
|
})
|
|
}
|
|
detail := systemRes.ConvertSalesOrderToDetail(order.SalesOrder, order.CustomerName, order.WarehouseName, detailItems)
|
|
detailList = append(detailList, detail)
|
|
}
|
|
|
|
return &systemRes.SalesOrderDetailListResponse{
|
|
List: detailList,
|
|
Total: total,
|
|
Page: req.Page,
|
|
PageSize: req.PageSize,
|
|
}, nil
|
|
}
|
|
|
|
// GetSalesOrderDetail 获取销售订单详情
|
|
func (s *SalesService) GetSalesOrderDetail(id int64, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.SalesOrderDetailResponse, error) {
|
|
databaseConn := database.OptionalDB(db...)
|
|
|
|
query := databaseConn.Model(&models.SalesOrder{}).
|
|
Select("sales_order.*, c.name as customer_name, w.name as warehouse_name").
|
|
Joins("LEFT JOIN customer c ON sales_order.customer_id = c.id AND c.is_del = 0").
|
|
Joins("LEFT JOIN warehouse w ON sales_order.warehouse_id = w.id AND w.is_del = 0").
|
|
Where("sales_order.id = ? AND sales_order.is_del = ?", id, 0)
|
|
|
|
if role == 128 {
|
|
query = query.Where("sales_order.sales_person_id = ?", creatorID)
|
|
}
|
|
|
|
var order systemRes.SalesOrderWithInfo
|
|
result := query.First(&order)
|
|
|
|
if result.Error != nil {
|
|
return nil, utils.NewError("销售订单不存在")
|
|
}
|
|
|
|
var items []systemRes.SalesOrderItemWithProduct
|
|
databaseConn.Model(&models.SalesOrderItem{}).
|
|
Select("sales_order_item.*, p.name as product_name, p.barcode as product_code, p.category_id,p.sale_price as product_sale_price, c.name as category_name, p.live_image, lt.code as location_code").
|
|
Joins("LEFT JOIN product p ON sales_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 inventory_detail de on p.id = de.product_id AND de.is_del = 0").
|
|
Joins("LEFT JOIN location lt on de.location_id = lt.id").
|
|
Where("sales_order_item.sales_order_id = ? AND sales_order_item.is_del = ?", order.ID, 0).
|
|
Find(&items)
|
|
|
|
detailItems := make([]systemRes.SalesOrderDetailItem, 0, len(items))
|
|
for _, item := range items {
|
|
var imageList []string
|
|
if len(item.LiveImage) > 0 {
|
|
json.Unmarshal(item.LiveImage, &imageList)
|
|
}
|
|
|
|
detailItems = append(detailItems, systemRes.SalesOrderDetailItem{
|
|
ID: item.ID,
|
|
SalesOrderID: item.SalesOrderID,
|
|
ProductID: item.ProductID,
|
|
ProductName: item.ProductName,
|
|
ProductCode: item.ProductCode,
|
|
ProductSalePrice: item.ProductSalePrice,
|
|
CategoryID: item.CategoryID,
|
|
CategoryName: item.CategoryName,
|
|
LiveImage: imageList,
|
|
Quantity: item.Quantity,
|
|
AllocatedQuantity: item.AllocatedQuantity,
|
|
ShippedQuantity: item.ShippedQuantity,
|
|
UnitPrice: item.UnitPrice,
|
|
Amount: item.Amount,
|
|
ReceiverName: item.ReceiverName,
|
|
ReceiverPhone: item.ReceiverPhone,
|
|
ReceiverAddress: item.ReceiverAddress,
|
|
LogisticsCompany: item.LogisticsCompany,
|
|
LogisticsNo: item.LogisticsNo,
|
|
LocationCode: item.LocationCode,
|
|
CreatedAt: item.CreatedAt,
|
|
UpdatedAt: item.UpdatedAt,
|
|
})
|
|
}
|
|
|
|
detail := systemRes.ConvertSalesOrderToDetail(order.SalesOrder, order.CustomerName, order.WarehouseName, detailItems)
|
|
return &detail, nil
|
|
}
|