zhangqian
2024-03-15 2eb20330dfbda6136f1b8cc804cc21438ae4dc13
发货明细和准备发货接口
1个文件已添加
12个文件已修改
1117 ■■■■■ 已修改文件
api/v1/salesDetails.go 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/aps-crm.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/deliveryOrder.go 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/product.go 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/response/salesDetails.go 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory.proto 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/product_inventory.pb.go 497 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/product_inventory_grpc.pb.go 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/salesDetails.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/salesDetails.go 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/salesDetails.go
@@ -15,6 +15,7 @@
    "aps_crm/utils"
    "github.com/gin-gonic/gin"
    "github.com/shopspring/decimal"
    "gorm.io/gorm"
    "strconv"
    "strings"
)
@@ -240,7 +241,7 @@
// GetProductInventoryInfo
//
// @Tags        SalesDetails
// @Summary    获取产品库存信息
// @Summary    获取产品发货信息
// @Produce    application/json
// @Param        number    path        string    true    "明细编码"
// @Success    200    {object}    response.ListResponse
@@ -272,6 +273,172 @@
    ctx.OkWithDetailed(list)
}
type GetWarehouseProductInfoReq struct {
    SaleDetailID     int    `json:"saleDetailID,omitempty"`
    SaleDetailNumber string `json:"saleDetailNumber,omitempty"`
}
// GetDeliveryPrepareInfo
// @Tags        SalesDetails
// @Summary    获取产品入库信息
// @Produce    application/json
// @Param        object     body GetWarehouseProductInfoReq    true    "明细编码"
// @Success    200    {object}    response.ListResponse
// @Router        /api/salesDetails/getDeliveryPrepareInfo [post]
func (s *SalesDetailsApi) GetDeliveryPrepareInfo(c *gin.Context) {
    var params GetWarehouseProductInfoReq
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    if params.SaleDetailID == 0 {
        ctx.FailWithMsg(ecode.ParamsErr, "参数缺失")
        return
    }
    salesDetails, err := salesDetailsService.GetSalesDetails(params.SaleDetailID)
    if err == gorm.ErrRecordNotFound || salesDetails.Number != params.SaleDetailNumber {
        ctx.FailWithMsg(ecode.ParamsErr, "销售订单不存在")
        return
    }
    productMap := model.ProductMap(salesDetails.Products)
    client := product_inventory.NewProductInventoryServiceClient(grpc_init.ProductInventoryServiceConn)
    grpcResp, err := client.GetOrderInputAndOutputInfo(ctx.GetCtx(), &product_inventory.GetOrderInputAndOutputInfoRequest{
        Number: params.SaleDetailNumber,
    })
    if err != nil {
        if strings.Contains(err.Error(), "record not found") {
            ctx.Ok()
            return
        }
        logx.Errorf("GetOrderInputAndOutputInfo err: %v", err.Error())
        ctx.FailWithMsg(ecode.UnknownErr, "grpc调用错误")
        return
    }
    grpcOutputList := grpcResp.OutputList
    grpcInputList := grpcResp.InputList
    inputProductMap := make(map[string]*response.StoreInfo)
    outputProductMap := make(map[string]*response.OutputSimpleInfo)
    for _, v := range grpcOutputList {
        if outputProductMap[v.Number] == nil {
            simpleInfo := &response.OutputSimpleInfo{
                Number: v.Number,
            }
            amount, _ := decimal.NewFromString(v.Amount)
            simpleInfo.Amount = amount
            outputProductMap[v.Number] = simpleInfo
        } else {
            amount, _ := decimal.NewFromString(v.Amount)
            outputProductMap[v.Number].Amount = outputProductMap[v.Number].Amount.Add(amount)
        }
    }
    for _, v := range grpcInputList {
        if inputProductMap[v.Number] == nil {
            storeInfo := &response.StoreInfo{
                Number:      v.Number,
                Name:        v.Name,
                OrderAmount: productMap[v.Number].Amount,
            }
            finishAmount, _ := decimal.NewFromString(v.Amount)
            storeInfo.FinishAmount = finishAmount
            storeInfo.AvailableAmount = finishAmount
            storeInfo.LeftAmount = storeInfo.OrderAmount
            inputProductMap[v.Number] = storeInfo
        } else {
            finishAmount, _ := decimal.NewFromString(v.Amount)
            inputProductMap[v.Number].FinishAmount = inputProductMap[v.Number].FinishAmount.Add(finishAmount)
            inputProductMap[v.Number].AvailableAmount = inputProductMap[v.Number].FinishAmount
        }
    }
    storeList := make([]*response.StoreInfo, 0, len(salesDetails.Products))
    for _, product := range salesDetails.Products {
        storeInfo := inputProductMap[product.Number]
        if storeInfo == nil { //没有入库信息
            storeInfo = &response.StoreInfo{
                Name:            product.Number,
                Number:          product.Number,
                OrderAmount:     product.Amount,
                FinishAmount:    decimal.Decimal{},
                LeftAmount:      product.Amount,
                AvailableAmount: decimal.Decimal{},
            }
        } else { //有入库数量再查出库,算出未发货数量
            if outputProductMap[product.Number] != nil {
                outputInfo := outputProductMap[product.Number]
                storeInfo.LeftAmount = storeInfo.LeftAmount.Sub(outputInfo.Amount)           //剩余发货数量 = 订单数量 - 已发货数量
                storeInfo.AvailableAmount = storeInfo.AvailableAmount.Sub(outputInfo.Amount) //可用数量 = 入库完成数量 - 已发货数量
            }
        }
        storeList = append(storeList, storeInfo)
    }
    ctx.OkWithDetailed(storeList)
}
// GetDeliveryList
// @Tags        SalesDetails
// @Summary    发货明细
// @Produce    application/json
// @Param        object     body GetWarehouseProductInfoReq    true    "明细编码"
// @Success    200    {object}    response.ListResponse
// @Router        /api/salesDetails/getDeliveryList [post]
func (s *SalesDetailsApi) GetDeliveryList(c *gin.Context) {
    var params GetWarehouseProductInfoReq
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    if params.SaleDetailID == 0 {
        ctx.FailWithMsg(ecode.ParamsErr, "参数缺失")
        return
    }
    salesDetails, err := salesDetailsService.GetSalesDetails(params.SaleDetailID)
    if err == gorm.ErrRecordNotFound || salesDetails.Number != params.SaleDetailNumber {
        ctx.FailWithMsg(ecode.ParamsErr, "销售订单不存在")
        return
    }
    productMap := model.ProductMap(salesDetails.Products)
    client := product_inventory.NewProductInventoryServiceClient(grpc_init.ProductInventoryServiceConn)
    grpcResp, err := client.GetOrderInputAndOutputInfo(ctx.GetCtx(), &product_inventory.GetOrderInputAndOutputInfoRequest{
        Number: params.SaleDetailNumber,
    })
    if err != nil {
        if strings.Contains(err.Error(), "record not found") {
            ctx.Ok()
            return
        }
        logx.Errorf("GetOrderInputAndOutputInfo err: %v", err.Error())
        ctx.FailWithMsg(ecode.UnknownErr, "grpc调用错误")
        return
    }
    grpcOutputList := grpcResp.OutputList
    outputList := make([]*response.OutputInfo, 0, len(grpcOutputList))
    for _, v := range grpcOutputList {
        outputInfo := &response.OutputInfo{
            Number:      v.Number,
            Name:        v.Name,
            OrderAmount: productMap[v.Number].Amount.String(),
            Unit:        v.Unit,
            Invoice:     v.Invoice,
            Carrier:     v.Carrier,
            Waybill:     v.Waybill,
            SalePrice:   v.SalePrice,
            Valorem:     v.Valorem,
            Warehouse:   v.Warehouse,
            Amount:      v.Amount,
            Status:      int(v.Status),
            Specs:       productMap[v.Number].Specs,
            CreateTime:  v.CreateTime,
        }
        outputList = append(outputList, outputInfo)
    }
    ctx.OkWithDetailed(outputList)
}
// GetApsProjectList
//
// @Tags        SalesDetails
conf/aps-crm.json
@@ -51,7 +51,7 @@
  "GrpcServiceAddr": {
    "Aps": "192.168.20.119:9091",
    "Admin": "192.168.20.119:50051",
    "WMS": "192.168.20.119:8006"
    "WMS": "192.168.20.120:8006"
  }
}
docs/docs.go
@@ -7085,6 +7085,66 @@
                }
            }
        },
        "/api/salesDetails/getDeliveryList": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "SalesDetails"
                ],
                "summary": "发货明细",
                "parameters": [
                    {
                        "description": "明细编码",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/v1.GetWarehouseProductInfoReq"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/response.ListResponse"
                        }
                    }
                }
            }
        },
        "/api/salesDetails/getDeliveryPrepareInfo": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "SalesDetails"
                ],
                "summary": "获取产品入库信息",
                "parameters": [
                    {
                        "description": "明细编码",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/v1.GetWarehouseProductInfoReq"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/response.ListResponse"
                        }
                    }
                }
            }
        },
        "/api/salesDetails/getProductInventoryInfo/{number}": {
            "get": {
                "produces": [
@@ -7093,7 +7153,7 @@
                "tags": [
                    "SalesDetails"
                ],
                "summary": "获取产品库存信息",
                "summary": "获取产品发货信息",
                "parameters": [
                    {
                        "type": "string",
@@ -19919,6 +19979,17 @@
                    "type": "string"
                }
            }
        },
        "v1.GetWarehouseProductInfoReq": {
            "type": "object",
            "properties": {
                "saleDetailID": {
                    "type": "integer"
                },
                "saleDetailNumber": {
                    "type": "string"
                }
            }
        }
    }
}`
docs/swagger.json
@@ -7073,6 +7073,66 @@
                }
            }
        },
        "/api/salesDetails/getDeliveryList": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "SalesDetails"
                ],
                "summary": "发货明细",
                "parameters": [
                    {
                        "description": "明细编码",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/v1.GetWarehouseProductInfoReq"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/response.ListResponse"
                        }
                    }
                }
            }
        },
        "/api/salesDetails/getDeliveryPrepareInfo": {
            "post": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "SalesDetails"
                ],
                "summary": "获取产品入库信息",
                "parameters": [
                    {
                        "description": "明细编码",
                        "name": "object",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/v1.GetWarehouseProductInfoReq"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/response.ListResponse"
                        }
                    }
                }
            }
        },
        "/api/salesDetails/getProductInventoryInfo/{number}": {
            "get": {
                "produces": [
@@ -7081,7 +7141,7 @@
                "tags": [
                    "SalesDetails"
                ],
                "summary": "获取产品库存信息",
                "summary": "获取产品发货信息",
                "parameters": [
                    {
                        "type": "string",
@@ -19907,6 +19967,17 @@
                    "type": "string"
                }
            }
        },
        "v1.GetWarehouseProductInfoReq": {
            "type": "object",
            "properties": {
                "saleDetailID": {
                    "type": "integer"
                },
                "saleDetailNumber": {
                    "type": "string"
                }
            }
        }
    }
}
docs/swagger.yaml
@@ -6494,6 +6494,13 @@
      workOrderStatus:
        type: string
    type: object
  v1.GetWarehouseProductInfoReq:
    properties:
      saleDetailID:
        type: integer
      saleDetailNumber:
        type: string
    type: object
info:
  contact: {}
paths:
@@ -10850,6 +10857,44 @@
      summary: 获取aps项目列表
      tags:
      - SalesDetails
  /api/salesDetails/getDeliveryList:
    post:
      parameters:
      - description: 明细编码
        in: body
        name: object
        required: true
        schema:
          $ref: '#/definitions/v1.GetWarehouseProductInfoReq'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/response.ListResponse'
      summary: 发货明细
      tags:
      - SalesDetails
  /api/salesDetails/getDeliveryPrepareInfo:
    post:
      parameters:
      - description: 明细编码
        in: body
        name: object
        required: true
        schema:
          $ref: '#/definitions/v1.GetWarehouseProductInfoReq'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/response.ListResponse'
      summary: 获取产品入库信息
      tags:
      - SalesDetails
  /api/salesDetails/getProductInventoryInfo/{number}:
    get:
      parameters:
@@ -10865,7 +10910,7 @@
          description: OK
          schema:
            $ref: '#/definitions/response.ListResponse'
      summary: 获取产品库存信息
      summary: 获取产品发货信息
      tags:
      - SalesDetails
  /api/salesDetails/list:
model/deliveryOrder.go
New file
@@ -0,0 +1,90 @@
package model
import (
    "aps_crm/pkg/mysqlx"
    "github.com/shopspring/decimal"
    "gorm.io/gorm"
)
type (
    DeliveryOrder struct {
        Id              int             `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        MemberId        int             `json:"memberId" gorm:"column:member_id;type:int;comment:服务人员id"`
        SalesDetailsId  int             `json:"salesDetailsId" gorm:"column:sales_details_id;type:int;comment:销售明细id"`
        ProductID       uint            `json:"productID" gorm:"column:product_id"`
        Name            string          `json:"name" gorm:"column:name;type:varchar(255);comment:产品名称"`
        Number          string          `json:"number" gorm:"column:number;type:varchar(255);comment:产品编号"`  //产品编号
        Amount          decimal.Decimal `json:"amount" gorm:"column:amount;type:decimal(12,2);comment:产品数量"` //订单数量
        FinishAmount    decimal.Decimal `json:"finishAmount" gorm:"-"`                                       //订单完成数量
        AvailableAmount decimal.Decimal `json:"availableAmount" gorm:"-"`                                    //可用库存
        DeliveryAmount  decimal.Decimal `json:"deliveryAmount" gorm:"-"`                                     //本次发货数量
        LeftAmount      decimal.Decimal `json:"leftAmount" gorm:"column:left_amount;type:decimal(12,2);comment:剩余发货数量"`
        gorm.Model      `json:"-"`
    }
    DeliveryOrderSearch struct {
        DeliveryOrder
        Orm *gorm.DB
    }
)
func (DeliveryOrder) TableName() string {
    return "delivery_order"
}
func NewDeliveryOrderSearch() *DeliveryOrderSearch {
    return &DeliveryOrderSearch{
        Orm: mysqlx.GetDB(),
    }
}
func (css *DeliveryOrderSearch) build() *gorm.DB {
    var db = css.Orm.Model(&DeliveryOrder{})
    if css.Id != 0 {
        db = db.Where("id = ?", css.Id)
    }
    if css.SalesDetailsId != 0 {
        db = db.Where("sales_details_id = ?", css.SalesDetailsId)
    }
    return db
}
func (css *DeliveryOrderSearch) Create(record *DeliveryOrder) error {
    var db = css.build()
    return db.Create(record).Error
}
func (css *DeliveryOrderSearch) Update(record *DeliveryOrder) error {
    var db = css.build()
    return db.Updates(record).Error
}
func (css *DeliveryOrderSearch) Delete() error {
    var db = css.build()
    return db.Delete(&DeliveryOrder{}).Error
}
func (css *DeliveryOrderSearch) Find() (*DeliveryOrder, error) {
    var db = css.build()
    var record = &DeliveryOrder{}
    err := db.First(record).Error
    return record, err
}
func (css *DeliveryOrderSearch) FindAll() ([]*DeliveryOrder, error) {
    var db = css.build()
    var records = make([]*DeliveryOrder, 0)
    err := db.Find(&records).Error
    return records, err
}
func (css *DeliveryOrderSearch) SetId(id int) *DeliveryOrderSearch {
    css.Id = id
    return css
}
func (css *DeliveryOrderSearch) SetSalesDetailsID(id int) *DeliveryOrderSearch {
    css.SalesDetailsId = id
    return css
}
model/product.go
@@ -129,3 +129,11 @@
    var db = slf.build()
    return db.Updates(m).Error
}
func ProductMap(products []*Product) (pm map[string]*Product) {
    pm = make(map[string]*Product, len(products))
    for _, p := range products {
        pm[p.Number] = p
    }
    return pm
}
model/response/salesDetails.go
@@ -1,5 +1,10 @@
package response
import (
    "aps_crm/model"
    "github.com/shopspring/decimal"
)
type Info struct {
    MakeInfo        []WorkOrderInfo   `json:"makeInfo"`
    PurchaseInfo    []Purchase        `json:"purchaseInfo"`
@@ -62,3 +67,48 @@
    Amount          string `json:"amount"`          //在库数量
    AvailableNumber string `json:"availableNumber"` //可用库存
}
type OutputInfo struct {
    Number      string `json:"number"`
    Name        string `json:"name"`
    OrderAmount string `json:"orderAmount"` //订单数量
    Unit        string `json:"unit"`
    Invoice     string `json:"invoice"`   //发货单
    Carrier     string `json:"carrier"`   //承运商
    Waybill     string `json:"waybill"`   //运单号
    SalePrice   string `json:"salePrice"` //销售单价
    Valorem     string `json:"valorem"`   //价税合计
    Warehouse   string `json:"warehouse"`
    Amount      string `json:"amount"`     //在库数量
    Status      int    `json:"status"`     //0就绪 1完成
    Specs       string `json:"specs"`      //规格
    CreateTime  string `json:"createTime"` //创建时间
}
type StoreInfo struct {
    Name            string          `json:"name"`            //产品名称
    Number          string          `json:"number"`          //产品编号
    OrderAmount     decimal.Decimal `json:"orderAmount"`     //订单数量
    FinishAmount    decimal.Decimal `json:"finishAmount"`    //订单完成数量
    LeftAmount      decimal.Decimal `json:"leftAmount"`      //未发货数量
    AvailableAmount decimal.Decimal `json:"availableAmount"` //剩余可用数量
}
type OutputSimpleInfo struct {
    Number string          `json:"number"` //产品编号
    Amount decimal.Decimal `json:"amount"` //在库数量
    Status int             `json:"status"` //0就绪 1完成
}
type WarehouseProducts struct {
    WarehouseID    string         `protobuf:"bytes,1,opt,name=WarehouseID,proto3" json:"WarehouseID,omitempty"`
    WarehouseName  string         `protobuf:"bytes,2,opt,name=WarehouseName,proto3" json:"WarehouseName,omitempty"`
    ProductList    []*ProductInfo `protobuf:"bytes,3,rep,name=ProductList,proto3" json:"ProductList,omitempty"`
    ProductInfoMap map[string]*ProductInfo
}
type WarehouseProductInfo struct {
    WarehouseID   string                 `json:"WarehouseID,omitempty"`
    WarehouseName string                 `json:"WarehouseName,omitempty"`
    ProductList   []*model.DeliveryOrder `json:"ProductList,omitempty"`
}
proto/product_inventory.proto
@@ -6,6 +6,7 @@
  rpc CreateOperation(CreateOperationRequest) returns(CreateOperationResponse) {}
  rpc GetInventoryProductInfo(GetInventoryProductInfoRequest) returns (GetInventoryProductInfoResponse) {}
  rpc UpdateSalesDetailStatus(UpdateSalesDetailStatusRequest) returns (UpdateSalesDetailStatusResponse) {}
  rpc GetOrderInputAndOutputInfo(GetOrderInputAndOutputInfoRequest) returns (GetOrderInputAndOutputInfoResponse) {}
}
message CreateOperationRequest{
@@ -51,6 +52,11 @@
  string AvailableNumber = 12;//可用库存
}
enum FinishStatus {
  Ready = 0;
  Finish = 1;
}
message GetInventoryProductInfoResponse{
  int32   Code = 1;
  string  Msg = 2;
@@ -67,4 +73,33 @@
message UpdateSalesDetailStatusResponse{
  int32   Code = 1;
  string  Msg = 2;
}
//--------------------------------------------------
message InputAndOutputInfo{
  string Number = 1;
  string Name = 2;
  string OrderAmount = 3;//订单数量
  string Unit = 4;
  string Invoice = 5;//发货单
  string Carrier = 6;//承运商
  string Waybill = 7;//运单号
  string SalePrice = 8;//销售单价
  string Valorem = 9;//价税合计
  string Warehouse = 10;
  string Amount = 11; //数量
  FinishStatus Status = 13;
  string CreateTime = 14;
}
message GetOrderInputAndOutputInfoRequest {
  string Number = 1;//明细单编码
}
message GetOrderInputAndOutputInfoResponse {
  int32   Code = 1;
  string  Msg = 2;
  repeated InputAndOutputInfo InputList = 3;
  repeated InputAndOutputInfo OutputList = 4;
}
proto/product_inventory/product_inventory.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
//     protoc-gen-go v1.26.0
//     protoc        v4.24.0
//     protoc-gen-go v1.31.0
//     protoc        v3.19.0
// source: product_inventory.proto
package product_inventory
@@ -19,6 +19,52 @@
    // Verify that runtime/protoimpl is sufficiently up-to-date.
    _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type FinishStatus int32
const (
    FinishStatus_Ready  FinishStatus = 0
    FinishStatus_Finish FinishStatus = 1
)
// Enum value maps for FinishStatus.
var (
    FinishStatus_name = map[int32]string{
        0: "Ready",
        1: "Finish",
    }
    FinishStatus_value = map[string]int32{
        "Ready":  0,
        "Finish": 1,
    }
)
func (x FinishStatus) Enum() *FinishStatus {
    p := new(FinishStatus)
    *p = x
    return p
}
func (x FinishStatus) String() string {
    return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (FinishStatus) Descriptor() protoreflect.EnumDescriptor {
    return file_product_inventory_proto_enumTypes[0].Descriptor()
}
func (FinishStatus) Type() protoreflect.EnumType {
    return &file_product_inventory_proto_enumTypes[0]
}
func (x FinishStatus) Number() protoreflect.EnumNumber {
    return protoreflect.EnumNumber(x)
}
// Deprecated: Use FinishStatus.Descriptor instead.
func (FinishStatus) EnumDescriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{0}
}
type CreateOperationRequest struct {
    state         protoimpl.MessageState
@@ -596,6 +642,267 @@
    return ""
}
type InputAndOutputInfo struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Number      string       `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"`
    Name        string       `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
    OrderAmount string       `protobuf:"bytes,3,opt,name=OrderAmount,proto3" json:"OrderAmount,omitempty"` //订单数量
    Unit        string       `protobuf:"bytes,4,opt,name=Unit,proto3" json:"Unit,omitempty"`
    Invoice     string       `protobuf:"bytes,5,opt,name=Invoice,proto3" json:"Invoice,omitempty"`     //发货单
    Carrier     string       `protobuf:"bytes,6,opt,name=Carrier,proto3" json:"Carrier,omitempty"`     //承运商
    Waybill     string       `protobuf:"bytes,7,opt,name=Waybill,proto3" json:"Waybill,omitempty"`     //运单号
    SalePrice   string       `protobuf:"bytes,8,opt,name=SalePrice,proto3" json:"SalePrice,omitempty"` //销售单价
    Valorem     string       `protobuf:"bytes,9,opt,name=Valorem,proto3" json:"Valorem,omitempty"`     //价税合计
    Warehouse   string       `protobuf:"bytes,10,opt,name=Warehouse,proto3" json:"Warehouse,omitempty"`
    Amount      string       `protobuf:"bytes,11,opt,name=Amount,proto3" json:"Amount,omitempty"` //数量
    Status      FinishStatus `protobuf:"varint,13,opt,name=Status,proto3,enum=FinishStatus" json:"Status,omitempty"`
    CreateTime  string       `protobuf:"bytes,14,opt,name=CreateTime,proto3" json:"CreateTime,omitempty"`
}
func (x *InputAndOutputInfo) Reset() {
    *x = InputAndOutputInfo{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[8]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *InputAndOutputInfo) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*InputAndOutputInfo) ProtoMessage() {}
func (x *InputAndOutputInfo) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[8]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use InputAndOutputInfo.ProtoReflect.Descriptor instead.
func (*InputAndOutputInfo) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{8}
}
func (x *InputAndOutputInfo) GetNumber() string {
    if x != nil {
        return x.Number
    }
    return ""
}
func (x *InputAndOutputInfo) GetName() string {
    if x != nil {
        return x.Name
    }
    return ""
}
func (x *InputAndOutputInfo) GetOrderAmount() string {
    if x != nil {
        return x.OrderAmount
    }
    return ""
}
func (x *InputAndOutputInfo) GetUnit() string {
    if x != nil {
        return x.Unit
    }
    return ""
}
func (x *InputAndOutputInfo) GetInvoice() string {
    if x != nil {
        return x.Invoice
    }
    return ""
}
func (x *InputAndOutputInfo) GetCarrier() string {
    if x != nil {
        return x.Carrier
    }
    return ""
}
func (x *InputAndOutputInfo) GetWaybill() string {
    if x != nil {
        return x.Waybill
    }
    return ""
}
func (x *InputAndOutputInfo) GetSalePrice() string {
    if x != nil {
        return x.SalePrice
    }
    return ""
}
func (x *InputAndOutputInfo) GetValorem() string {
    if x != nil {
        return x.Valorem
    }
    return ""
}
func (x *InputAndOutputInfo) GetWarehouse() string {
    if x != nil {
        return x.Warehouse
    }
    return ""
}
func (x *InputAndOutputInfo) GetAmount() string {
    if x != nil {
        return x.Amount
    }
    return ""
}
func (x *InputAndOutputInfo) GetStatus() FinishStatus {
    if x != nil {
        return x.Status
    }
    return FinishStatus_Ready
}
func (x *InputAndOutputInfo) GetCreateTime() string {
    if x != nil {
        return x.CreateTime
    }
    return ""
}
type GetOrderInputAndOutputInfoRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Number string `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"` //明细单编码
}
func (x *GetOrderInputAndOutputInfoRequest) Reset() {
    *x = GetOrderInputAndOutputInfoRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[9]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetOrderInputAndOutputInfoRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetOrderInputAndOutputInfoRequest) ProtoMessage() {}
func (x *GetOrderInputAndOutputInfoRequest) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[9]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use GetOrderInputAndOutputInfoRequest.ProtoReflect.Descriptor instead.
func (*GetOrderInputAndOutputInfoRequest) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{9}
}
func (x *GetOrderInputAndOutputInfoRequest) GetNumber() string {
    if x != nil {
        return x.Number
    }
    return ""
}
type GetOrderInputAndOutputInfoResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Code       int32                 `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
    Msg        string                `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
    InputList  []*InputAndOutputInfo `protobuf:"bytes,3,rep,name=InputList,proto3" json:"InputList,omitempty"`
    OutputList []*InputAndOutputInfo `protobuf:"bytes,4,rep,name=OutputList,proto3" json:"OutputList,omitempty"`
}
func (x *GetOrderInputAndOutputInfoResponse) Reset() {
    *x = GetOrderInputAndOutputInfoResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[10]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetOrderInputAndOutputInfoResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetOrderInputAndOutputInfoResponse) ProtoMessage() {}
func (x *GetOrderInputAndOutputInfoResponse) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[10]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use GetOrderInputAndOutputInfoResponse.ProtoReflect.Descriptor instead.
func (*GetOrderInputAndOutputInfoResponse) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{10}
}
func (x *GetOrderInputAndOutputInfoResponse) GetCode() int32 {
    if x != nil {
        return x.Code
    }
    return 0
}
func (x *GetOrderInputAndOutputInfoResponse) GetMsg() string {
    if x != nil {
        return x.Msg
    }
    return ""
}
func (x *GetOrderInputAndOutputInfoResponse) GetInputList() []*InputAndOutputInfo {
    if x != nil {
        return x.InputList
    }
    return nil
}
func (x *GetOrderInputAndOutputInfoResponse) GetOutputList() []*InputAndOutputInfo {
    if x != nil {
        return x.OutputList
    }
    return nil
}
var File_product_inventory_proto protoreflect.FileDescriptor
var file_product_inventory_proto_rawDesc = []byte{
@@ -670,28 +977,75 @@
    0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
    0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65,
    0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03,
    0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x32, 0xa1,
    0x02, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74,
    0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x0f, 0x43, 0x72,
    0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x2e,
    0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
    0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f,
    0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
    0x22, 0x00, 0x12, 0x5e, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f,
    0x72, 0x79, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x2e,
    0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x64,
    0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
    0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
    0x22, 0x00, 0x12, 0x5e, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6c, 0x65,
    0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e,
    0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69,
    0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
    0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61,
    0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
    0x22, 0x00, 0x42, 0x15, 0x5a, 0x13, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f,
    0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
    0x33,
    0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x22, 0xf9,
    0x02, 0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75,
    0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
    0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a,
    0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d,
    0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
    0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x41, 0x6d, 0x6f,
    0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
    0x09, 0x52, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69,
    0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63,
    0x65, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01,
    0x28, 0x09, 0x52, 0x07, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x57,
    0x61, 0x79, 0x62, 0x69, 0x6c, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x57, 0x61,
    0x79, 0x62, 0x69, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x61, 0x6c, 0x65, 0x50, 0x72, 0x69,
    0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x61, 0x6c, 0x65, 0x50, 0x72,
    0x69, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x61, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x18, 0x09,
    0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x61, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x12, 0x1c, 0x0a,
    0x09, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
    0x52, 0x09, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x41,
    0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x41, 0x6d, 0x6f,
    0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0d, 0x20,
    0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74,
    0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x72,
    0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
    0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x3b, 0x0a, 0x21, 0x47, 0x65,
    0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75,
    0x74, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
    0x16, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
    0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xb2, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f,
    0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70,
    0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12,
    0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x43, 0x6f,
    0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
    0x03, 0x4d, 0x73, 0x67, 0x12, 0x31, 0x0a, 0x09, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73,
    0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41,
    0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x49, 0x6e,
    0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x0a, 0x4f, 0x75, 0x74, 0x70, 0x75,
    0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x49, 0x6e,
    0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f,
    0x52, 0x0a, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x2a, 0x25, 0x0a, 0x0c,
    0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05,
    0x52, 0x65, 0x61, 0x64, 0x79, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x69, 0x6e, 0x69, 0x73,
    0x68, 0x10, 0x01, 0x32, 0x8a, 0x03, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
    0x46, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
    0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61,
    0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x43, 0x72,
    0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x49, 0x6e,
    0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e,
    0x66, 0x6f, 0x12, 0x1f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72,
    0x79, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75,
    0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f,
    0x72, 0x79, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73,
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74,
    0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74,
    0x75, 0x73, 0x12, 0x1f, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73,
    0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
    0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6c, 0x65,
    0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, 0x72,
    0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75,
    0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72,
    0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x49, 0x6e,
    0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x47, 0x65, 0x74, 0x4f,
    0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70,
    0x75, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
    0x42, 0x15, 0x5a, 0x13, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x6e,
    0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -706,31 +1060,41 @@
    return file_product_inventory_proto_rawDescData
}
var file_product_inventory_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_product_inventory_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_product_inventory_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_product_inventory_proto_goTypes = []interface{}{
    (*CreateOperationRequest)(nil),          // 0: CreateOperationRequest
    (*InventoryProduct)(nil),                // 1: InventoryProduct
    (*CreateOperationResponse)(nil),         // 2: CreateOperationResponse
    (*GetInventoryProductInfoRequest)(nil),  // 3: GetInventoryProductInfoRequest
    (*ProductInfo)(nil),                     // 4: ProductInfo
    (*GetInventoryProductInfoResponse)(nil), // 5: GetInventoryProductInfoResponse
    (*UpdateSalesDetailStatusRequest)(nil),  // 6: UpdateSalesDetailStatusRequest
    (*UpdateSalesDetailStatusResponse)(nil), // 7: UpdateSalesDetailStatusResponse
    (FinishStatus)(0),                          // 0: FinishStatus
    (*CreateOperationRequest)(nil),             // 1: CreateOperationRequest
    (*InventoryProduct)(nil),                   // 2: InventoryProduct
    (*CreateOperationResponse)(nil),            // 3: CreateOperationResponse
    (*GetInventoryProductInfoRequest)(nil),     // 4: GetInventoryProductInfoRequest
    (*ProductInfo)(nil),                        // 5: ProductInfo
    (*GetInventoryProductInfoResponse)(nil),    // 6: GetInventoryProductInfoResponse
    (*UpdateSalesDetailStatusRequest)(nil),     // 7: UpdateSalesDetailStatusRequest
    (*UpdateSalesDetailStatusResponse)(nil),    // 8: UpdateSalesDetailStatusResponse
    (*InputAndOutputInfo)(nil),                 // 9: InputAndOutputInfo
    (*GetOrderInputAndOutputInfoRequest)(nil),  // 10: GetOrderInputAndOutputInfoRequest
    (*GetOrderInputAndOutputInfoResponse)(nil), // 11: GetOrderInputAndOutputInfoResponse
}
var file_product_inventory_proto_depIdxs = []int32{
    1, // 0: CreateOperationRequest.ProductList:type_name -> InventoryProduct
    4, // 1: GetInventoryProductInfoResponse.ProductList:type_name -> ProductInfo
    0, // 2: productInventoryService.CreateOperation:input_type -> CreateOperationRequest
    3, // 3: productInventoryService.GetInventoryProductInfo:input_type -> GetInventoryProductInfoRequest
    6, // 4: productInventoryService.UpdateSalesDetailStatus:input_type -> UpdateSalesDetailStatusRequest
    2, // 5: productInventoryService.CreateOperation:output_type -> CreateOperationResponse
    5, // 6: productInventoryService.GetInventoryProductInfo:output_type -> GetInventoryProductInfoResponse
    7, // 7: productInventoryService.UpdateSalesDetailStatus:output_type -> UpdateSalesDetailStatusResponse
    5, // [5:8] is the sub-list for method output_type
    2, // [2:5] is the sub-list for method input_type
    2, // [2:2] is the sub-list for extension type_name
    2, // [2:2] is the sub-list for extension extendee
    0, // [0:2] is the sub-list for field type_name
    2,  // 0: CreateOperationRequest.ProductList:type_name -> InventoryProduct
    5,  // 1: GetInventoryProductInfoResponse.ProductList:type_name -> ProductInfo
    0,  // 2: InputAndOutputInfo.Status:type_name -> FinishStatus
    9,  // 3: GetOrderInputAndOutputInfoResponse.InputList:type_name -> InputAndOutputInfo
    9,  // 4: GetOrderInputAndOutputInfoResponse.OutputList:type_name -> InputAndOutputInfo
    1,  // 5: productInventoryService.CreateOperation:input_type -> CreateOperationRequest
    4,  // 6: productInventoryService.GetInventoryProductInfo:input_type -> GetInventoryProductInfoRequest
    7,  // 7: productInventoryService.UpdateSalesDetailStatus:input_type -> UpdateSalesDetailStatusRequest
    10, // 8: productInventoryService.GetOrderInputAndOutputInfo:input_type -> GetOrderInputAndOutputInfoRequest
    3,  // 9: productInventoryService.CreateOperation:output_type -> CreateOperationResponse
    6,  // 10: productInventoryService.GetInventoryProductInfo:output_type -> GetInventoryProductInfoResponse
    8,  // 11: productInventoryService.UpdateSalesDetailStatus:output_type -> UpdateSalesDetailStatusResponse
    11, // 12: productInventoryService.GetOrderInputAndOutputInfo:output_type -> GetOrderInputAndOutputInfoResponse
    9,  // [9:13] is the sub-list for method output_type
    5,  // [5:9] is the sub-list for method input_type
    5,  // [5:5] is the sub-list for extension type_name
    5,  // [5:5] is the sub-list for extension extendee
    0,  // [0:5] is the sub-list for field type_name
}
func init() { file_product_inventory_proto_init() }
@@ -835,19 +1199,56 @@
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*InputAndOutputInfo); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetOrderInputAndOutputInfoRequest); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetOrderInputAndOutputInfoResponse); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
    }
    type x struct{}
    out := protoimpl.TypeBuilder{
        File: protoimpl.DescBuilder{
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_product_inventory_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   8,
            NumEnums:      1,
            NumMessages:   11,
            NumExtensions: 0,
            NumServices:   1,
        },
        GoTypes:           file_product_inventory_proto_goTypes,
        DependencyIndexes: file_product_inventory_proto_depIdxs,
        EnumInfos:         file_product_inventory_proto_enumTypes,
        MessageInfos:      file_product_inventory_proto_msgTypes,
    }.Build()
    File_product_inventory_proto = out.File
proto/product_inventory/product_inventory_grpc.pb.go
@@ -1,4 +1,8 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc             v3.19.0
// source: product_inventory.proto
package product_inventory
@@ -14,6 +18,13 @@
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
    ProductInventoryService_CreateOperation_FullMethodName            = "/productInventoryService/CreateOperation"
    ProductInventoryService_GetInventoryProductInfo_FullMethodName    = "/productInventoryService/GetInventoryProductInfo"
    ProductInventoryService_UpdateSalesDetailStatus_FullMethodName    = "/productInventoryService/UpdateSalesDetailStatus"
    ProductInventoryService_GetOrderInputAndOutputInfo_FullMethodName = "/productInventoryService/GetOrderInputAndOutputInfo"
)
// ProductInventoryServiceClient is the client API for ProductInventoryService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
@@ -21,6 +32,7 @@
    CreateOperation(ctx context.Context, in *CreateOperationRequest, opts ...grpc.CallOption) (*CreateOperationResponse, error)
    GetInventoryProductInfo(ctx context.Context, in *GetInventoryProductInfoRequest, opts ...grpc.CallOption) (*GetInventoryProductInfoResponse, error)
    UpdateSalesDetailStatus(ctx context.Context, in *UpdateSalesDetailStatusRequest, opts ...grpc.CallOption) (*UpdateSalesDetailStatusResponse, error)
    GetOrderInputAndOutputInfo(ctx context.Context, in *GetOrderInputAndOutputInfoRequest, opts ...grpc.CallOption) (*GetOrderInputAndOutputInfoResponse, error)
}
type productInventoryServiceClient struct {
@@ -33,7 +45,7 @@
func (c *productInventoryServiceClient) CreateOperation(ctx context.Context, in *CreateOperationRequest, opts ...grpc.CallOption) (*CreateOperationResponse, error) {
    out := new(CreateOperationResponse)
    err := c.cc.Invoke(ctx, "/productInventoryService/CreateOperation", in, out, opts...)
    err := c.cc.Invoke(ctx, ProductInventoryService_CreateOperation_FullMethodName, in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -42,7 +54,7 @@
func (c *productInventoryServiceClient) GetInventoryProductInfo(ctx context.Context, in *GetInventoryProductInfoRequest, opts ...grpc.CallOption) (*GetInventoryProductInfoResponse, error) {
    out := new(GetInventoryProductInfoResponse)
    err := c.cc.Invoke(ctx, "/productInventoryService/GetInventoryProductInfo", in, out, opts...)
    err := c.cc.Invoke(ctx, ProductInventoryService_GetInventoryProductInfo_FullMethodName, in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -51,7 +63,16 @@
func (c *productInventoryServiceClient) UpdateSalesDetailStatus(ctx context.Context, in *UpdateSalesDetailStatusRequest, opts ...grpc.CallOption) (*UpdateSalesDetailStatusResponse, error) {
    out := new(UpdateSalesDetailStatusResponse)
    err := c.cc.Invoke(ctx, "/productInventoryService/UpdateSalesDetailStatus", in, out, opts...)
    err := c.cc.Invoke(ctx, ProductInventoryService_UpdateSalesDetailStatus_FullMethodName, in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
func (c *productInventoryServiceClient) GetOrderInputAndOutputInfo(ctx context.Context, in *GetOrderInputAndOutputInfoRequest, opts ...grpc.CallOption) (*GetOrderInputAndOutputInfoResponse, error) {
    out := new(GetOrderInputAndOutputInfoResponse)
    err := c.cc.Invoke(ctx, ProductInventoryService_GetOrderInputAndOutputInfo_FullMethodName, in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -65,6 +86,7 @@
    CreateOperation(context.Context, *CreateOperationRequest) (*CreateOperationResponse, error)
    GetInventoryProductInfo(context.Context, *GetInventoryProductInfoRequest) (*GetInventoryProductInfoResponse, error)
    UpdateSalesDetailStatus(context.Context, *UpdateSalesDetailStatusRequest) (*UpdateSalesDetailStatusResponse, error)
    GetOrderInputAndOutputInfo(context.Context, *GetOrderInputAndOutputInfoRequest) (*GetOrderInputAndOutputInfoResponse, error)
    mustEmbedUnimplementedProductInventoryServiceServer()
}
@@ -80,6 +102,9 @@
}
func (UnimplementedProductInventoryServiceServer) UpdateSalesDetailStatus(context.Context, *UpdateSalesDetailStatusRequest) (*UpdateSalesDetailStatusResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method UpdateSalesDetailStatus not implemented")
}
func (UnimplementedProductInventoryServiceServer) GetOrderInputAndOutputInfo(context.Context, *GetOrderInputAndOutputInfoRequest) (*GetOrderInputAndOutputInfoResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method GetOrderInputAndOutputInfo not implemented")
}
func (UnimplementedProductInventoryServiceServer) mustEmbedUnimplementedProductInventoryServiceServer() {
}
@@ -105,7 +130,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/productInventoryService/CreateOperation",
        FullMethod: ProductInventoryService_CreateOperation_FullMethodName,
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductInventoryServiceServer).CreateOperation(ctx, req.(*CreateOperationRequest))
@@ -123,7 +148,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/productInventoryService/GetInventoryProductInfo",
        FullMethod: ProductInventoryService_GetInventoryProductInfo_FullMethodName,
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductInventoryServiceServer).GetInventoryProductInfo(ctx, req.(*GetInventoryProductInfoRequest))
@@ -141,10 +166,28 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/productInventoryService/UpdateSalesDetailStatus",
        FullMethod: ProductInventoryService_UpdateSalesDetailStatus_FullMethodName,
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductInventoryServiceServer).UpdateSalesDetailStatus(ctx, req.(*UpdateSalesDetailStatusRequest))
    }
    return interceptor(ctx, in, info, handler)
}
func _ProductInventoryService_GetOrderInputAndOutputInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(GetOrderInputAndOutputInfoRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(ProductInventoryServiceServer).GetOrderInputAndOutputInfo(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: ProductInventoryService_GetOrderInputAndOutputInfo_FullMethodName,
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductInventoryServiceServer).GetOrderInputAndOutputInfo(ctx, req.(*GetOrderInputAndOutputInfoRequest))
    }
    return interceptor(ctx, in, info, handler)
}
@@ -168,6 +211,10 @@
            MethodName: "UpdateSalesDetailStatus",
            Handler:    _ProductInventoryService_UpdateSalesDetailStatus_Handler,
        },
        {
            MethodName: "GetOrderInputAndOutputInfo",
            Handler:    _ProductInventoryService_GetOrderInputAndOutputInfo_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "product_inventory.proto",
router/salesDetails.go
@@ -21,5 +21,9 @@
        //salesDetailsRouter.POST("createOperation", salesDetailsApi.CreateOperation)                           // 创建产品出库信息
        salesDetailsRouter.GET("getApsProjectList", salesDetailsApi.GetApsProjectList)                          // 获取aps项目列表
        salesDetailsRouter.POST("sendSalesDetailsToOtherSystem", salesDetailsApi.SendSalesDetailsToOtherSystem) // 推送销售明细信息到其他系统                    // 创建产品出库信息
        salesDetailsRouter.POST("getDeliveryPrepareInfo", salesDetailsApi.GetDeliveryPrepareInfo) // 发货准备
        salesDetailsRouter.POST("getDeliveryList", salesDetailsApi.GetDeliveryList)               // 发货明细
    }
}
service/salesDetails.go
@@ -132,3 +132,13 @@
    }
    return contacts, total, ecode.OK
}
func (SalesDetailsService) GetSalesDetails(saleDetailID int) (*model.SalesDetails, error) {
    return model.NewSalesDetailsSearch().SetId(saleDetailID).SetPreload(true).First()
}
func (SalesDetailsService) GetDeliveryOrder(saleDetailID int) ([]*model.DeliveryOrder, error) {
    // get contact list
    orders, err := model.NewDeliveryOrderSearch().SetSalesDetailsID(saleDetailID).FindAll()
    return orders, err
}