From 389dffb0b6218f05277b8755bb82b61b6a316528 Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期四, 14 三月 2024 20:06:13 +0800
Subject: [PATCH] 按仓库返回销售明细单对应产品完成入库且可用数量

---
 proto/product_inventory/server.go |  127 +++++++++++++++++++++++++++++++-----------
 1 files changed, 93 insertions(+), 34 deletions(-)

diff --git a/proto/product_inventory/server.go b/proto/product_inventory/server.go
index 28310a3..14fa029 100644
--- a/proto/product_inventory/server.go
+++ b/proto/product_inventory/server.go
@@ -5,11 +5,11 @@
 	"errors"
 	"github.com/shopspring/decimal"
 	"strconv"
-	"strings"
 	"time"
 	"wms/constvar"
 	"wms/models"
 	"wms/pkg/timex"
+	"wms/service"
 )
 
 type Server struct {
@@ -17,12 +17,14 @@
 }
 
 type ProductAndLocationInfo struct {
-	ProductId     string          `json:"productId"`
-	Amount        decimal.Decimal `json:"amount"`
-	LocationId    int             `json:"locationId"`
-	Number        string          `json:"number"`
-	WaybillNumber string          `json:"waybillNumber"`
-	Name          string          `json:"name"`
+	ProductId      string          `json:"productId"`
+	Amount         decimal.Decimal `json:"amount"`
+	LocationId     int             `json:"locationId"`
+	FromLocationId int             `json:"fromLocationId"`
+	ToLocationId   int             `json:"toLocationId"`
+	Number         string          `json:"number"`
+	WaybillNumber  string          `json:"waybillNumber"`
+	Name           string          `json:"name"`
 }
 
 func (s *Server) GetInventoryProductInfo(ctx context.Context, req *GetInventoryProductInfoRequest) (*GetInventoryProductInfoResponse, error) {
@@ -33,49 +35,47 @@
 	var details []ProductAndLocationInfo
 	var productIds []string
 	resp := new(GetInventoryProductInfoResponse)
-	err := models.NewOperationDetailsSearch().Orm.Model(&models.OperationDetails{}).
-		Select("wms_operation_details.product_id,wms_operation_details.amount,wms_operation.from_location_id as location_id,"+
+	search := models.NewOperationDetailsSearch().Orm.Model(&models.OperationDetails{}).
+		Select("wms_operation_details.product_id,wms_operation_details.amount,wms_operation_details.from_location_id,wms_operation_details.to_location_id"+
 			"wms_operation.number,wms_operation.waybill_number, logistic_company.name").
 		Joins("left join wms_operation on wms_operation.id = wms_operation_details.operation_id").
 		Joins("left join logistic_company on logistic_company.id = wms_operation.logistic_company_id").
-		Where("wms_operation.source_number = ?", req.Number).Find(&details).Error
+		Where("wms_operation.source_number = ?", req.Number)
+	if req.IsInput {
+		search.Where("wms_operation.base_operation_type = ?", constvar.BaseOperationTypeIncoming)
+	}
+	if req.IsOutput {
+		search.Where("wms_operation.base_operation_type = ?", constvar.BaseOperationTypeOutgoing)
+	}
+	err := search.Find(&details).Error
 	if err != nil {
 		return nil, err
 	}
 	if len(details) == 0 {
 		return resp, nil
 	}
+	var locationIds []int
 	var locationId int
 	for _, detail := range details {
 		productIds = append(productIds, detail.ProductId)
-		locationId = detail.LocationId
+		if req.IsInput { //鍙煡鍏ュ簱
+			locationIds = append(locationIds, detail.ToLocationId)
+		} else if req.IsOutput { //鍙煡鍑哄簱
+			locationIds = append(locationIds, detail.FromLocationId)
+		}
+		locationId = detail.FromLocationId
 	}
 	//鏌ヨ浜у搧淇℃伅
 	materials, err := models.NewMaterialSearch().SetIDs(productIds).FindNotTotal()
 	if err != nil {
 		return nil, err
 	}
-	//鏌ヨ浣嶇疆淇℃伅
-	location, err := models.NewLocationSearch().SetID(locationId).First()
+	locationHouseMap, houseLocations, houseMap, err := service.GetWarehouseByLocationIds(locationIds)
 	if err != nil {
 		return nil, err
 	}
-	//鏍规嵁浠撳簱缂╁啓鏌ヨ浠撳簱
-	code := strings.Split(location.JointName, "/")[0]
-	warehouse, err := models.NewWarehouseSearch().SetCode(code).First()
-	if err != nil {
-		return nil, err
-	}
-	//缁熻浠撳簱涓嬫墍鏈変綅缃殑浜у搧鍦ㄥ簱鏁伴噺
-	locations, err := models.NewLocationSearch().SetJointName(code).FindNotTotal()
-	if err != nil {
-		return nil, err
-	}
-	var locationIds []int
-	for _, l := range locations {
-		locationIds = append(locationIds, l.Id)
-	}
-	amounts, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).SetLocationIds(locationIds).Find()
+	warehouse := locationHouseMap[locationId]
+	amounts, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).SetLocationIds(locationIds).SetPreload(true).Find()
 	if err != nil {
 		return nil, err
 	}
@@ -92,7 +92,7 @@
 		Select("wms_operation_details.product_id, wms_operation_details.amount").
 		Joins("left join wms_operation on wms_operation_details.operation_id = wms_operation.id").
 		Where("wms_operation_details.product_id in (?)", productIds).
-		Where("wms_operation.from_location_id in (?)", locationIds).Where("wms_operation.status = ?", constvar.OperationStatus_Ready).
+		Where("wms_operation_details.from_location_id in (?)", locationIds).Where("wms_operation.status = ?", constvar.OperationStatus_Ready).
 		Where("wms_operation.base_operation_type in (?)", []constvar.BaseOperationType{constvar.BaseOperationTypeOutgoing, constvar.BaseOperationTypeInternal, constvar.BaseOperationTypeDisuse}).
 		Find(&canUse).Error
 	if err != nil {
@@ -101,7 +101,7 @@
 	products := make([]*ProductInfo, 0)
 	for _, material := range materials {
 		var p ProductInfo
-		p.Id = material.ID
+		p.Number = material.ID
 		p.Name = material.Name
 		for _, detail := range details {
 			if material.ID == detail.ProductId {
@@ -135,6 +135,60 @@
 		products = append(products, &p)
 	}
 	resp.ProductList = products
+
+	if req.GroupByWarehouse {
+		canUseMap := make(map[int]map[string]decimal.Decimal) //map[locationID]map[productID]decimal
+		for _, v := range canUse {
+			if canUseMap[v.LocationId] == nil {
+				canUseMap[v.LocationId] = make(map[string]decimal.Decimal)
+			}
+			canUseMap[v.LocationId][v.ProductId] = canUseMap[v.LocationId][v.ProductId].Add(v.Amount)
+		}
+		locationProductAmounts := make(map[int][]*models.LocationProductAmount)
+		for _, v := range amounts {
+			if locationProductAmounts[v.LocationId] == nil {
+				locationProductAmounts[v.LocationId] = make([]*models.LocationProductAmount, 0)
+			}
+			locationProductAmounts[v.LocationId] = append(locationProductAmounts[v.LocationId], v)
+		}
+
+		materialMap := service.MaterialMap(materials)
+
+		var warehouseProductsList []*WarehouseProducts
+		for houseID, locationIDs := range houseLocations {
+			house := houseMap[houseID]
+			productAmountMap := make(map[string]decimal.Decimal, 0)
+			productAvailableNumberMap := make(map[string]decimal.Decimal, 0)
+			productInfoList := make([]*ProductInfo, 0)
+
+			houseProductAmounts := make([]*models.LocationProductAmount, 0)
+			for _, lid := range locationIDs {
+				houseProductAmounts = append(houseProductAmounts, locationProductAmounts[lid]...)
+			}
+			for _, v := range houseProductAmounts {
+				productAmountMap[v.ProductId] = productAmountMap[v.ProductId].Add(v.Amount)
+				productAvailableNumberMap[v.ProductId] = productAvailableNumberMap[v.ProductId].Add(canUseMap[v.LocationId][v.ProductId])
+			}
+			for productID, amount := range productAvailableNumberMap {
+				productInfoList = append(productInfoList, &ProductInfo{
+					Number:          productID,
+					Name:            materialMap[productID].Name,
+					Unit:            materialMap[productID].Unit,
+					Amount:          productAmountMap[productID].String(),
+					AvailableNumber: amount.String(),
+				})
+			}
+
+			warehouseProducts := &WarehouseProducts{
+				WarehouseID:   house.Code,
+				WarehouseName: house.Name,
+				ProductList:   productInfoList,
+			}
+			warehouseProductsList = append(warehouseProductsList, warehouseProducts)
+		}
+		resp.WarehouseProductsList = warehouseProductsList
+	}
+
 	return resp, nil
 }
 
@@ -160,23 +214,27 @@
 	if err != nil {
 		return nil, err
 	}
-	operation.FromLocationID = location.Id
+
 	first, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeCustomer)).First()
 	if err != nil {
 		return nil, err
 	}
-	operation.ToLocationID = first.Id
+	operation.LocationID = location.Id
 	operation.BaseOperationType = constvar.BaseOperationTypeOutgoing
 	operation.ReceiverName = req.Addressee
 	operation.ReceiverPhone = req.Phone
 	operation.ReceiverAddr = req.Address
 	operation.Source = req.Source
+	operation.CompanyID = int(req.ClientId)
+	operation.CompanyName = req.ClientName
 	if req.DeliverType == 1 {
 		for _, product := range req.ProductList {
 			var detail models.OperationDetails
 			detail.ProductId = product.Id
 			amount, _ := decimal.NewFromString(product.Amount)
 			detail.Amount = amount
+			detail.FromLocationID = location.Id
+			detail.ToLocationID = first.Id
 			details = append(details, &detail)
 		}
 		operation.Details = details
@@ -188,7 +246,8 @@
 			detail.ProductId = product.Id
 			amount, _ := decimal.NewFromString(product.Amount)
 			detail.Amount = amount
-			details = append(details, &detail)
+			detail.FromLocationID = location.Id
+			detail.ToLocationID = first.Id
 			newOperation.Details = append(newOperation.Details, &detail)
 			operations = append(operations, &newOperation)
 		}

--
Gitblit v1.8.0