zhangqian
2024-03-15 5083f183f6f2695198c02027640c0f98e067522e
获取出入库信息grpc接口
4个文件已修改
1034 ■■■■■ 已修改文件
proto/product_inventory.proto 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/product_inventory.pb.go 728 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/product_inventory_grpc.pb.go 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/server.go 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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{
@@ -34,9 +35,6 @@
message GetInventoryProductInfoRequest {
  string Number = 1;//明细单编码
  bool   GroupByWarehouse = 2; //是否按仓库分组
  bool   IsOutput = 3; //查出库
  bool   IsInput = 4; //查入库
}
message ProductInfo{
@@ -54,19 +52,16 @@
  string AvailableNumber = 12;//可用库存
}
enum FinishStatus {
  Ready = 0;
  Finish = 1;
}
message GetInventoryProductInfoResponse{
  int32   Code = 1;
  string  Msg = 2;
  repeated ProductInfo ProductList = 3;
  repeated WarehouseProducts WarehouseProductsList = 4;
}
message WarehouseProducts {
  string WarehouseID = 1;
  string WarehouseName = 2;
  repeated ProductInfo ProductList = 3;
}
//------------------------------------------------------------
@@ -78,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
@@ -20,6 +20,52 @@
    _ = 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
    sizeCache     protoimpl.SizeCache
@@ -246,10 +292,7 @@
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Number           string `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"`                      //明细单编码
    GroupByWarehouse bool   `protobuf:"varint,2,opt,name=GroupByWarehouse,proto3" json:"GroupByWarehouse,omitempty"` //是否按仓库分组
    IsOutput         bool   `protobuf:"varint,3,opt,name=IsOutput,proto3" json:"IsOutput,omitempty"`                 //查出库
    IsInput          bool   `protobuf:"varint,4,opt,name=IsInput,proto3" json:"IsInput,omitempty"`                   //查入库
    Number string `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"` //明细单编码
}
func (x *GetInventoryProductInfoRequest) Reset() {
@@ -289,27 +332,6 @@
        return x.Number
    }
    return ""
}
func (x *GetInventoryProductInfoRequest) GetGroupByWarehouse() bool {
    if x != nil {
        return x.GroupByWarehouse
    }
    return false
}
func (x *GetInventoryProductInfoRequest) GetIsOutput() bool {
    if x != nil {
        return x.IsOutput
    }
    return false
}
func (x *GetInventoryProductInfoRequest) GetIsInput() bool {
    if x != nil {
        return x.IsInput
    }
    return false
}
type ProductInfo struct {
@@ -452,10 +474,9 @@
    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"`
    ProductList           []*ProductInfo       `protobuf:"bytes,3,rep,name=ProductList,proto3" json:"ProductList,omitempty"`
    WarehouseProductsList []*WarehouseProducts `protobuf:"bytes,4,rep,name=WarehouseProductsList,proto3" json:"WarehouseProductsList,omitempty"`
    Code        int32          `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
    Msg         string         `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
    ProductList []*ProductInfo `protobuf:"bytes,3,rep,name=ProductList,proto3" json:"ProductList,omitempty"`
}
func (x *GetInventoryProductInfoResponse) Reset() {
@@ -511,76 +532,6 @@
    return nil
}
func (x *GetInventoryProductInfoResponse) GetWarehouseProductsList() []*WarehouseProducts {
    if x != nil {
        return x.WarehouseProductsList
    }
    return nil
}
type WarehouseProducts struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    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"`
}
func (x *WarehouseProducts) Reset() {
    *x = WarehouseProducts{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[6]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *WarehouseProducts) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*WarehouseProducts) ProtoMessage() {}
func (x *WarehouseProducts) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[6]
    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 WarehouseProducts.ProtoReflect.Descriptor instead.
func (*WarehouseProducts) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{6}
}
func (x *WarehouseProducts) GetWarehouseID() string {
    if x != nil {
        return x.WarehouseID
    }
    return ""
}
func (x *WarehouseProducts) GetWarehouseName() string {
    if x != nil {
        return x.WarehouseName
    }
    return ""
}
func (x *WarehouseProducts) GetProductList() []*ProductInfo {
    if x != nil {
        return x.ProductList
    }
    return nil
}
type UpdateSalesDetailStatusRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
@@ -593,7 +544,7 @@
func (x *UpdateSalesDetailStatusRequest) Reset() {
    *x = UpdateSalesDetailStatusRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[7]
        mi := &file_product_inventory_proto_msgTypes[6]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
@@ -606,7 +557,7 @@
func (*UpdateSalesDetailStatusRequest) ProtoMessage() {}
func (x *UpdateSalesDetailStatusRequest) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[7]
    mi := &file_product_inventory_proto_msgTypes[6]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
@@ -619,7 +570,7 @@
// Deprecated: Use UpdateSalesDetailStatusRequest.ProtoReflect.Descriptor instead.
func (*UpdateSalesDetailStatusRequest) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{7}
    return file_product_inventory_proto_rawDescGZIP(), []int{6}
}
func (x *UpdateSalesDetailStatusRequest) GetNumber() string {
@@ -648,7 +599,7 @@
func (x *UpdateSalesDetailStatusResponse) Reset() {
    *x = UpdateSalesDetailStatusResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[8]
        mi := &file_product_inventory_proto_msgTypes[7]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
@@ -661,7 +612,7 @@
func (*UpdateSalesDetailStatusResponse) ProtoMessage() {}
func (x *UpdateSalesDetailStatusResponse) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[8]
    mi := &file_product_inventory_proto_msgTypes[7]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
@@ -674,7 +625,7 @@
// Deprecated: Use UpdateSalesDetailStatusResponse.ProtoReflect.Descriptor instead.
func (*UpdateSalesDetailStatusResponse) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{8}
    return file_product_inventory_proto_rawDescGZIP(), []int{7}
}
func (x *UpdateSalesDetailStatusResponse) GetCode() int32 {
@@ -689,6 +640,267 @@
        return x.Msg
    }
    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
@@ -722,90 +934,118 @@
    0x74, 0x69, 0x6f, 0x6e, 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, 0x22, 0x9a, 0x01, 0x0a, 0x1e, 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, 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, 0x2a, 0x0a,
    0x10, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x79, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73,
    0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x79,
    0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x73, 0x4f,
    0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x49, 0x73, 0x4f,
    0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x73, 0x49, 0x6e, 0x70, 0x75, 0x74,
    0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x49, 0x73, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x22,
    0xd5, 0x02, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12,
    0x73, 0x67, 0x22, 0x38, 0x0a, 0x1e, 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, 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, 0xd5, 0x02, 0x0a,
    0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 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, 0x28, 0x0a, 0x0f, 0x41, 0x76,
    0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0c, 0x20,
    0x01, 0x28, 0x09, 0x52, 0x0f, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x75,
    0x6d, 0x62, 0x65, 0x72, 0x22, 0x77, 0x0a, 0x1f, 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, 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, 0x2e, 0x0a,
    0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03,
    0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f,
    0x52, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x66, 0x0a,
    0x1e, 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, 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, 0x28, 0x0a,
    0x0f, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
    0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c,
    0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xc1, 0x01, 0x0a, 0x1f, 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, 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, 0x2e, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74,
    0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
    0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73,
    0x74, 0x12, 0x48, 0x0a, 0x15, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x50, 0x72,
    0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
    0x32, 0x12, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x64,
    0x75, 0x63, 0x74, 0x73, 0x52, 0x15, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x50,
    0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x8b, 0x01, 0x0a, 0x11,
    0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
    0x73, 0x12, 0x20, 0x0a, 0x0b, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x49, 0x44,
    0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73,
    0x65, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x0d, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65,
    0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x57, 0x61, 0x72, 0x65,
    0x68, 0x6f, 0x75, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x0b, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c,
    0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x50, 0x72,
    0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x66, 0x0a, 0x1e, 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, 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, 0x2c, 0x0a, 0x11, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61,
    0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11,
    0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75,
    0x73, 0x22, 0x47, 0x0a, 0x1f, 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, 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,
    0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x11, 0x53, 0x61, 0x6c, 0x65, 0x73,
    0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
    0x28, 0x09, 0x52, 0x11, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x53,
    0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x47, 0x0a, 0x1f, 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, 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, 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 (
@@ -820,34 +1060,41 @@
    return file_product_inventory_proto_rawDescData
}
var file_product_inventory_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
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
    (*WarehouseProducts)(nil),               // 6: WarehouseProducts
    (*UpdateSalesDetailStatusRequest)(nil),  // 7: UpdateSalesDetailStatusRequest
    (*UpdateSalesDetailStatusResponse)(nil), // 8: 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
    6, // 2: GetInventoryProductInfoResponse.WarehouseProductsList:type_name -> WarehouseProducts
    4, // 3: WarehouseProducts.ProductList:type_name -> ProductInfo
    0, // 4: productInventoryService.CreateOperation:input_type -> CreateOperationRequest
    3, // 5: productInventoryService.GetInventoryProductInfo:input_type -> GetInventoryProductInfoRequest
    7, // 6: productInventoryService.UpdateSalesDetailStatus:input_type -> UpdateSalesDetailStatusRequest
    2, // 7: productInventoryService.CreateOperation:output_type -> CreateOperationResponse
    5, // 8: productInventoryService.GetInventoryProductInfo:output_type -> GetInventoryProductInfoResponse
    8, // 9: productInventoryService.UpdateSalesDetailStatus:output_type -> UpdateSalesDetailStatusResponse
    7, // [7:10] is the sub-list for method output_type
    4, // [4:7] is the sub-list for method input_type
    4, // [4:4] is the sub-list for extension type_name
    4, // [4:4] is the sub-list for extension extendee
    0, // [0:4] 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() }
@@ -929,18 +1176,6 @@
            }
        }
        file_product_inventory_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*WarehouseProducts); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*UpdateSalesDetailStatusRequest); i {
            case 0:
                return &v.state
@@ -952,8 +1187,44 @@
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
        file_product_inventory_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*UpdateSalesDetailStatusResponse); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                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:
@@ -970,13 +1241,14 @@
        File: protoimpl.DescBuilder{
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_product_inventory_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   9,
            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
@@ -19,9 +19,10 @@
const _ = grpc.SupportPackageIsVersion7
const (
    ProductInventoryService_CreateOperation_FullMethodName         = "/productInventoryService/CreateOperation"
    ProductInventoryService_GetInventoryProductInfo_FullMethodName = "/productInventoryService/GetInventoryProductInfo"
    ProductInventoryService_UpdateSalesDetailStatus_FullMethodName = "/productInventoryService/UpdateSalesDetailStatus"
    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.
@@ -31,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 {
@@ -68,6 +70,15 @@
    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
    }
    return out, nil
}
// ProductInventoryServiceServer is the server API for ProductInventoryService service.
// All implementations must embed UnimplementedProductInventoryServiceServer
// for forward compatibility
@@ -75,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()
}
@@ -90,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() {
}
@@ -159,6 +174,24 @@
    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)
}
// ProductInventoryService_ServiceDesc is the grpc.ServiceDesc for ProductInventoryService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -178,6 +211,10 @@
            MethodName: "UpdateSalesDetailStatus",
            Handler:    _ProductInventoryService_UpdateSalesDetailStatus_Handler,
        },
        {
            MethodName: "GetOrderInputAndOutputInfo",
            Handler:    _ProductInventoryService_GetOrderInputAndOutputInfo_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "product_inventory.proto",
proto/product_inventory/server.go
@@ -5,6 +5,7 @@
    "errors"
    "github.com/shopspring/decimal"
    "strconv"
    "strings"
    "time"
    "wms/constvar"
    "wms/models"
@@ -17,14 +18,12 @@
}
type ProductAndLocationInfo struct {
    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"`
    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"`
}
func (s *Server) GetInventoryProductInfo(ctx context.Context, req *GetInventoryProductInfoRequest) (*GetInventoryProductInfoResponse, error) {
@@ -35,47 +34,49 @@
    var details []ProductAndLocationInfo
    var productIds []string
    resp := new(GetInventoryProductInfoResponse)
    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"+
    err := models.NewOperationDetailsSearch().Orm.Model(&models.OperationDetails{}).
        Select("wms_operation_details.product_id,wms_operation_details.amount,wms_operation_details.from_location_id as 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)
    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
        Where("wms_operation.source_number = ?", req.Number).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)
        if req.IsInput { //只查入库
            locationIds = append(locationIds, detail.ToLocationId)
        } else if req.IsOutput { //只查出库
            locationIds = append(locationIds, detail.FromLocationId)
        }
        locationId = detail.FromLocationId
        locationId = detail.LocationId
    }
    //查询产品信息
    materials, err := models.NewMaterialSearch().SetIDs(productIds).FindNotTotal()
    if err != nil {
        return nil, err
    }
    locationHouseMap, houseLocations, houseMap, err := service.GetWarehouseByLocationIds(locationIds)
    //查询位置信息
    location, err := models.NewLocationSearch().SetID(locationId).First()
    if err != nil {
        return nil, err
    }
    warehouse := locationHouseMap[locationId]
    amounts, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).SetLocationIds(locationIds).SetPreload(true).Find()
    //根据仓库缩写查询仓库
    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()
    if err != nil {
        return nil, err
    }
@@ -135,60 +136,6 @@
        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
}
@@ -256,3 +203,109 @@
    resp := new(CreateOperationResponse)
    return resp, err
}
type InputAndOutputDetails struct {
    ProductId         string                     `json:"productId"`
    Amount            decimal.Decimal            `json:"amount"`
    FromLocationId    int                        `json:"fromLocationId"`
    ToLocationId      int                        `json:"toLocationId"`
    Number            string                     `json:"number"`
    WaybillNumber     string                     `json:"waybillNumber"`
    Name              string                     `json:"name"`
    BaseOperationType constvar.BaseOperationType `json:"baseOperationType"`
    Status            constvar.OperationStatus   `json:"status"`
    CreatedAt         time.Time
}
func (s *Server) GetOrderInputAndOutputInfo(ctx context.Context, req *GetOrderInputAndOutputInfoRequest) (*GetOrderInputAndOutputInfoResponse, error) {
    if req.Number == "" {
        return nil, errors.New("参数不能为空")
    }
    var details []InputAndOutputDetails
    var productIds []string
    resp := new(GetOrderInputAndOutputInfoResponse)
    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, wms_operation.base_operation_type, wms_operation.status, wms_operation.created_at").
        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).
        Where("wms_operation.base_operation_type in ?", []constvar.BaseOperationType{
            constvar.BaseOperationTypeIncoming, constvar.BaseOperationTypeOutgoing}).
        Where("wms_operation.status in ?", []constvar.OperationStatus{constvar.OperationStatus_Ready, constvar.OperationStatus_Finish})
    err := search.Find(&details).Error
    if err != nil {
        return nil, err
    }
    if len(details) == 0 {
        return resp, nil
    }
    var locationIds []int
    productInputMap := make(map[string]decimal.Decimal)
    productOutputMap := make(map[string]decimal.Decimal)
    for _, detail := range details {
        productIds = append(productIds, detail.ProductId)
        if detail.BaseOperationType == constvar.BaseOperationTypeIncoming {
            productInputMap[detail.ProductId] = productInputMap[detail.ProductId].Add(detail.Amount)
            locationIds = append(locationIds, detail.ToLocationId) //入库位置
        }
        if detail.BaseOperationType == constvar.BaseOperationTypeOutgoing {
            productOutputMap[detail.ProductId] = productOutputMap[detail.ProductId].Add(detail.Amount)
        }
    }
    //查询产品信息
    materials, err := models.NewMaterialSearch().SetIDs(productIds).FindNotTotal()
    if err != nil {
        return nil, err
    }
    locationHouseMap, _, _, err := service.GetWarehouseByLocationIds(locationIds)
    if err != nil {
        return nil, err
    }
    materialsMap := service.MaterialMap(materials)
    inputList := make([]*InputAndOutputInfo, 0)
    outputList := make([]*InputAndOutputInfo, 0)
    for _, detail := range details {
        if materialsMap[detail.ProductId] == nil {
            continue
        }
        material := materialsMap[detail.ProductId]
        var info InputAndOutputInfo
        info.Number = material.ID
        info.Name = material.Name
        info.OrderAmount = detail.Amount.String()
        info.Valorem = detail.Amount.Mul(material.SalePrice).String()
        info.Invoice = detail.Number
        info.Carrier = detail.Name
        info.Waybill = detail.WaybillNumber
        info.Unit = material.Unit
        info.SalePrice = material.SalePrice.String()
        info.Amount = detail.Amount.String()
        info.CreateTime = detail.CreatedAt.Format("2006-01-02 15:04")
        if detail.Status == constvar.OperationStatus_Finish { //是否完成
            info.Status = FinishStatus_Finish
        } else {
            info.Status = FinishStatus_Ready
        }
        if detail.BaseOperationType == constvar.BaseOperationTypeIncoming && detail.Status == constvar.OperationStatus_Finish {
            if locationHouseMap[detail.ToLocationId] != nil {
                info.Warehouse = locationHouseMap[detail.ToLocationId].Name //入库仓库名
            }
            inputList = append(inputList, &info)
        } else if detail.BaseOperationType == constvar.BaseOperationTypeOutgoing {
            if locationHouseMap[detail.FromLocationId] != nil {
                info.Warehouse = locationHouseMap[detail.FromLocationId].Name //发货仓库名
            }
            outputList = append(outputList, &info)
        }
    }
    resp.InputList = inputList
    resp.OutputList = outputList
    return resp, nil
}