zhangqian
2024-03-15 1cd1206c18ed14dd9ebf2baf477f46c847a271b0
merge
11个文件已修改
993 ■■■■■ 已修改文件
api/v1/product.go 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/aps-crm.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/config.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/response/salesDetails.go 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/crm_aps.proto 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/crm_aps/crm_aps.pb.go 622 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/crm_aps/crm_aps_grpc.pb.go 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/crm_aps/server.go 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/product.go
@@ -156,6 +156,31 @@
        ctx.Ok()
        return
    }
    first, err := model.NewSalesDetailsSearch().SetPreload(true).SetNumber(number).First()
    if err != nil {
        ctx.FailWithMsg(ecode.DBErr, "查询销售明细出错")
        return
    }
    productInfo := make([]response.SalesDetailsProductInfo, 0)
    amountMap := make(map[string]int64)
    overMap := make(map[string]int64)
    for _, p := range first.Products {
        amountMap[p.Number] = 0
        overMap[p.Number] = 0
        var sdpi response.SalesDetailsProductInfo
        sdpi.ProductId = p.Number
        sdpi.ProductName = p.Name
        sdpi.Specs = p.Specs
        sdpi.Unit = p.Unit
        sdpi.Amount = p.Amount
        sdpi.Cost = p.Cost
        sdpi.Price = p.Price
        sdpi.Total = p.Total
        sdpi.Profit = p.Profit
        sdpi.Margin = p.Margin
        productInfo = append(productInfo, sdpi)
    }
    client := product.NewProductServiceClient(grpc_init.CrmApsGrpcServiceConn)
    info, err := client.GetProductOrder(ctx.GetCtx(), &product.GetProductOrderRequest{SalesDetailsNumber: number})
    if err != nil {
@@ -164,6 +189,7 @@
        return
    }
    var result response.Info
    //制造信息
    var list []response.WorkOrderInfo
    for _, orderInfo := range info.List {
        var wo response.WorkOrderInfo
@@ -179,10 +205,22 @@
        wo.Unit = orderInfo.Unit
        wo.Amount = orderInfo.Amount
        wo.FinishAmount = orderInfo.FinishAmount
        at := amountMap[orderInfo.ProductId] + orderInfo.Amount
        amountMap[orderInfo.ProductId] = at
        fat := overMap[orderInfo.ProductId] + orderInfo.FinishAmount
        overMap[orderInfo.ProductId] = fat
        list = append(list, wo)
    }
    for i := 0; i < len(productInfo); i++ {
        productInfo[i].MakeAmount = amountMap[productInfo[i].ProductId]
        amountMap[productInfo[i].ProductId] = 0
        productInfo[i].MakeFinishAmount = overMap[productInfo[i].ProductId]
        productInfo[i].FinishAmount = productInfo[i].FinishAmount + overMap[productInfo[i].ProductId]
        overMap[productInfo[i].ProductId] = 0
    }
    result.MakeInfo = list
    //采购信息
    var purchaseInfo []response.Purchase
    for _, pl := range info.PurchaseList {
        var p response.Purchase
@@ -197,10 +235,22 @@
        p.Unit = pl.Unit
        p.Amount = pl.Amount
        p.FinishAmount = pl.FinishAmount
        at := amountMap[pl.ProductId] + pl.Amount
        amountMap[pl.ProductId] = at
        fat := overMap[pl.ProductId] + pl.FinishAmount
        overMap[pl.ProductId] = fat
        purchaseInfo = append(purchaseInfo, p)
    }
    for i := 0; i < len(productInfo); i++ {
        productInfo[i].PurchaseAmount = amountMap[productInfo[i].ProductId]
        amountMap[productInfo[i].ProductId] = 0
        productInfo[i].PurchaseFinishAmount = overMap[productInfo[i].ProductId]
        productInfo[i].FinishAmount = productInfo[i].FinishAmount + overMap[productInfo[i].ProductId]
        overMap[productInfo[i].ProductId] = 0
    }
    result.PurchaseInfo = purchaseInfo
    //委外信息
    var outsourcingList []response.OutsourcingInfo
    for _, outsourcingInfo := range info.OutsourcingList {
        var oi response.OutsourcingInfo
@@ -215,8 +265,20 @@
        oi.Unit = outsourcingInfo.Unit
        oi.Amount = outsourcingInfo.Amount
        oi.FinishAmount = outsourcingInfo.FinishAmount
        at := amountMap[outsourcingInfo.ProductId] + outsourcingInfo.Amount
        amountMap[outsourcingInfo.ProductId] = at
        fat := overMap[outsourcingInfo.ProductId] + outsourcingInfo.FinishAmount
        overMap[outsourcingInfo.ProductId] = fat
        outsourcingList = append(outsourcingList, oi)
    }
    for i := 0; i < len(productInfo); i++ {
        productInfo[i].OutsourcingAmount = amountMap[productInfo[i].ProductId]
        amountMap[productInfo[i].ProductId] = 0
        productInfo[i].OutsourcingFinishAmount = overMap[productInfo[i].ProductId]
        productInfo[i].FinishAmount = productInfo[i].FinishAmount + overMap[productInfo[i].ProductId]
        overMap[productInfo[i].ProductId] = 0
    }
    result.OutsourcingInfo = outsourcingList
    result.ProductInfo = productInfo
    ctx.OkWithDetailed(result)
}
conf/aps-crm.json
@@ -51,7 +51,8 @@
  "GrpcServiceAddr": {
    "Aps": "192.168.20.119:9091",
    "Admin": "192.168.20.119:50051",
    "WMS": "192.168.20.120:8006"
    "WMS": "192.168.20.119:8006",
    "SRM": "192.168.20.119:9093"
  }
}
conf/config.go
@@ -63,6 +63,7 @@
        Aps   string // aps服务地址
        Admin string // admin服务地址
        WMS   string //wms服务地址
        SRM   string //srm服务地址
    }
    config struct {
@@ -137,6 +138,10 @@
    if len(GrpcPort) > 0 {
        Conf.GrpcServiceAddr.WMS = GrpcPort
    }
    srmPort := os.Getenv("SRM_GRPC")
    if len(srmPort) > 0 {
        Conf.GrpcServiceAddr.SRM = srmPort
    }
    ApsGrpc := os.Getenv("GRPC_PORT")
    Host := os.Getenv("HOST")
docs/docs.go
@@ -7173,6 +7173,34 @@
                }
            }
        },
        "/api/salesDetails/getSalesDetailsProductInfo/{number}": {
            "get": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "SalesDetails"
                ],
                "summary": "获取销售明细产品信息",
                "parameters": [
                    {
                        "type": "string",
                        "description": "明细编码",
                        "name": "number",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/response.ListResponse"
                        }
                    }
                }
            }
        },
        "/api/salesDetails/list": {
            "post": {
                "produces": [
docs/swagger.json
@@ -7161,6 +7161,34 @@
                }
            }
        },
        "/api/salesDetails/getSalesDetailsProductInfo/{number}": {
            "get": {
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "SalesDetails"
                ],
                "summary": "获取销售明细产品信息",
                "parameters": [
                    {
                        "type": "string",
                        "description": "明细编码",
                        "name": "number",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/response.ListResponse"
                        }
                    }
                }
            }
        },
        "/api/salesDetails/list": {
            "post": {
                "produces": [
docs/swagger.yaml
@@ -10913,6 +10913,24 @@
      summary: 获取产品发货信息
      tags:
      - SalesDetails
  /api/salesDetails/getSalesDetailsProductInfo/{number}:
    get:
      parameters:
      - description: 明细编码
        in: path
        name: number
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/response.ListResponse'
      summary: 获取销售明细产品信息
      tags:
      - SalesDetails
  /api/salesDetails/list:
    post:
      parameters:
model/response/salesDetails.go
@@ -6,9 +6,10 @@
)
type Info struct {
    MakeInfo        []WorkOrderInfo   `json:"makeInfo"`
    PurchaseInfo    []Purchase        `json:"purchaseInfo"`
    OutsourcingInfo []OutsourcingInfo `json:"outsourcingInfo"`
    MakeInfo        []WorkOrderInfo           `json:"makeInfo"`
    PurchaseInfo    []Purchase                `json:"purchaseInfo"`
    OutsourcingInfo []OutsourcingInfo         `json:"outsourcingInfo"`
    ProductInfo     []SalesDetailsProductInfo `json:"productInfo"`
}
type WorkOrderInfo struct {
@@ -67,7 +68,6 @@
    Amount          string `json:"amount"`          //在库数量
    AvailableNumber string `json:"availableNumber"` //可用库存
}
type OutputInfo struct {
    Number      string `json:"number"`
    Name        string `json:"name"`
@@ -112,3 +112,24 @@
    WarehouseName string                 `json:"WarehouseName,omitempty"`
    ProductList   []*model.DeliveryOrder `json:"ProductList,omitempty"`
}
type SalesDetailsProductInfo struct {
    ProductId               string          `json:"productId"`
    ProductName             string          `json:"productName"`
    Specs                   string          `json:"specs"`                   //物料规格
    Unit                    string          `json:"unit"`                    //单位
    Amount                  decimal.Decimal `json:"amount"`                  //订单数量
    FinishAmount            int64           `json:"finishAmount"`            //完成数量
    DeliveryAmount          int64           `json:"deliveryAmount"`          //发货数量
    PurchaseAmount          int64           `json:"purchaseAmount"`          //采购数量
    PurchaseFinishAmount    int64           `json:"purchaseFinishAmount"`    //采购完成数量
    MakeAmount              int64           `json:"makeAmount"`              //制造数量
    MakeFinishAmount        int64           `json:"makeFinishAmount"`        //制造完成数量
    OutsourcingAmount       int64           `json:"outsourcingAmount"`       //委外数量
    OutsourcingFinishAmount int64           `json:"outsourcingFinishAmount"` //委外完成数量
    Cost                    string          `json:"cost"`                    //产品成本
    Price                   decimal.Decimal `json:"price"`                   //产品价格
    Total                   decimal.Decimal `json:"total"`                   //产品总价
    Profit                  string          `json:"profit"`                  //毛利
    Margin                  string          `json:"margin"`                  //毛利率
}
proto/crm_aps.proto
@@ -9,7 +9,9 @@
  rpc SendSalesDetailsAndProjectToCrm(SendSalesDetailsAndProjectToCrmRequest) returns(SendSalesDetailsAndProjectToCrmResponse) {}
  rpc GetClientList(GetClientListRequest) returns(GetClientListResponse) {}
  rpc UpdateSalesDetail(UpdateSalesDetailRequest) returns(UpdateSalesDetailResponse) {}
  rpc RemoveSalesDetail(RemoveSalesDetailRequest) returns(RemoveSalesDetailRequest) {}
  rpc RemoveSalesDetail(RemoveSalesDetailRequest) returns(RemoveSalesDetailResponse) {}
  rpc CrmGetMakeAndOutsourcingProductInfo(CrmGetMakeAndOutsourcingProductInfoRequest) returns(CrmGetMakeAndOutsourcingProductInfoResponse) {}
  rpc GetCrmSalesDetailsProductInfo(GetCrmSalesDetailsProductInfoRequest) returns(GetCrmSalesDetailsProductInfoResponse) {}
}
//-----------------------------------------------------GetApsProjectList--------------------------------------
@@ -113,4 +115,40 @@
  string number = 1;//销售明细单号
}
message RemoveSalesDetailResponse {}
message RemoveSalesDetailResponse {}
message CrmGetMakeAndOutsourcingProductInfoRequest{
  string SalesDetailsNumber = 1;
}
message CrmGetMakeAndOutsourcingProductInfo {
  int64 Amount = 1;
  int64 FinishAmount = 2;
  string ProductId = 3;
  int64 Type = 4;
}
message CrmGetMakeAndOutsourcingProductInfoResponse{
  repeated CrmGetMakeAndOutsourcingProductInfo Info = 1;
}
message GetCrmSalesDetailsProductInfoRequest{
  string SalesDetailsNumber = 1;
}
message CrmSalesDetailsProductInfo{
  string ProductId = 1;
  string ProductName = 2;
  string Specs = 3;
  string Unit = 4;
  int64 Amount = 5;
  string Cost = 6; //产品成本
  int64 Price = 7; //产品价格
  int64 Total = 8;//产品总价
  string Profit = 9;//毛利
  string Margin = 10;//毛利率
}
message GetCrmSalesDetailsProductInfoResponse{
  repeated CrmSalesDetailsProductInfo List = 1;
}
proto/crm_aps/crm_aps.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
//     protoc-gen-go v1.31.0
//     protoc        v3.19.0
//     protoc-gen-go v1.26.0
//     protoc        v4.24.0
// source: crm_aps.proto
package crm_aps
@@ -1029,6 +1029,384 @@
    return file_crm_aps_proto_rawDescGZIP(), []int{17}
}
type CrmGetMakeAndOutsourcingProductInfoRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    SalesDetailsNumber string `protobuf:"bytes,1,opt,name=SalesDetailsNumber,proto3" json:"SalesDetailsNumber,omitempty"`
}
func (x *CrmGetMakeAndOutsourcingProductInfoRequest) Reset() {
    *x = CrmGetMakeAndOutsourcingProductInfoRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_crm_aps_proto_msgTypes[18]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *CrmGetMakeAndOutsourcingProductInfoRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*CrmGetMakeAndOutsourcingProductInfoRequest) ProtoMessage() {}
func (x *CrmGetMakeAndOutsourcingProductInfoRequest) ProtoReflect() protoreflect.Message {
    mi := &file_crm_aps_proto_msgTypes[18]
    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 CrmGetMakeAndOutsourcingProductInfoRequest.ProtoReflect.Descriptor instead.
func (*CrmGetMakeAndOutsourcingProductInfoRequest) Descriptor() ([]byte, []int) {
    return file_crm_aps_proto_rawDescGZIP(), []int{18}
}
func (x *CrmGetMakeAndOutsourcingProductInfoRequest) GetSalesDetailsNumber() string {
    if x != nil {
        return x.SalesDetailsNumber
    }
    return ""
}
type CrmGetMakeAndOutsourcingProductInfo struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Amount       int64  `protobuf:"varint,1,opt,name=Amount,proto3" json:"Amount,omitempty"`
    FinishAmount int64  `protobuf:"varint,2,opt,name=FinishAmount,proto3" json:"FinishAmount,omitempty"`
    ProductId    string `protobuf:"bytes,3,opt,name=ProductId,proto3" json:"ProductId,omitempty"`
    Type         int64  `protobuf:"varint,4,opt,name=Type,proto3" json:"Type,omitempty"`
}
func (x *CrmGetMakeAndOutsourcingProductInfo) Reset() {
    *x = CrmGetMakeAndOutsourcingProductInfo{}
    if protoimpl.UnsafeEnabled {
        mi := &file_crm_aps_proto_msgTypes[19]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *CrmGetMakeAndOutsourcingProductInfo) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*CrmGetMakeAndOutsourcingProductInfo) ProtoMessage() {}
func (x *CrmGetMakeAndOutsourcingProductInfo) ProtoReflect() protoreflect.Message {
    mi := &file_crm_aps_proto_msgTypes[19]
    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 CrmGetMakeAndOutsourcingProductInfo.ProtoReflect.Descriptor instead.
func (*CrmGetMakeAndOutsourcingProductInfo) Descriptor() ([]byte, []int) {
    return file_crm_aps_proto_rawDescGZIP(), []int{19}
}
func (x *CrmGetMakeAndOutsourcingProductInfo) GetAmount() int64 {
    if x != nil {
        return x.Amount
    }
    return 0
}
func (x *CrmGetMakeAndOutsourcingProductInfo) GetFinishAmount() int64 {
    if x != nil {
        return x.FinishAmount
    }
    return 0
}
func (x *CrmGetMakeAndOutsourcingProductInfo) GetProductId() string {
    if x != nil {
        return x.ProductId
    }
    return ""
}
func (x *CrmGetMakeAndOutsourcingProductInfo) GetType() int64 {
    if x != nil {
        return x.Type
    }
    return 0
}
type CrmGetMakeAndOutsourcingProductInfoResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Info []*CrmGetMakeAndOutsourcingProductInfo `protobuf:"bytes,1,rep,name=Info,proto3" json:"Info,omitempty"`
}
func (x *CrmGetMakeAndOutsourcingProductInfoResponse) Reset() {
    *x = CrmGetMakeAndOutsourcingProductInfoResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_crm_aps_proto_msgTypes[20]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *CrmGetMakeAndOutsourcingProductInfoResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*CrmGetMakeAndOutsourcingProductInfoResponse) ProtoMessage() {}
func (x *CrmGetMakeAndOutsourcingProductInfoResponse) ProtoReflect() protoreflect.Message {
    mi := &file_crm_aps_proto_msgTypes[20]
    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 CrmGetMakeAndOutsourcingProductInfoResponse.ProtoReflect.Descriptor instead.
func (*CrmGetMakeAndOutsourcingProductInfoResponse) Descriptor() ([]byte, []int) {
    return file_crm_aps_proto_rawDescGZIP(), []int{20}
}
func (x *CrmGetMakeAndOutsourcingProductInfoResponse) GetInfo() []*CrmGetMakeAndOutsourcingProductInfo {
    if x != nil {
        return x.Info
    }
    return nil
}
type GetCrmSalesDetailsProductInfoRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    SalesDetailsNumber string `protobuf:"bytes,1,opt,name=SalesDetailsNumber,proto3" json:"SalesDetailsNumber,omitempty"`
}
func (x *GetCrmSalesDetailsProductInfoRequest) Reset() {
    *x = GetCrmSalesDetailsProductInfoRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_crm_aps_proto_msgTypes[21]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetCrmSalesDetailsProductInfoRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetCrmSalesDetailsProductInfoRequest) ProtoMessage() {}
func (x *GetCrmSalesDetailsProductInfoRequest) ProtoReflect() protoreflect.Message {
    mi := &file_crm_aps_proto_msgTypes[21]
    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 GetCrmSalesDetailsProductInfoRequest.ProtoReflect.Descriptor instead.
func (*GetCrmSalesDetailsProductInfoRequest) Descriptor() ([]byte, []int) {
    return file_crm_aps_proto_rawDescGZIP(), []int{21}
}
func (x *GetCrmSalesDetailsProductInfoRequest) GetSalesDetailsNumber() string {
    if x != nil {
        return x.SalesDetailsNumber
    }
    return ""
}
type CrmSalesDetailsProductInfo struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    ProductId   string `protobuf:"bytes,1,opt,name=ProductId,proto3" json:"ProductId,omitempty"`
    ProductName string `protobuf:"bytes,2,opt,name=ProductName,proto3" json:"ProductName,omitempty"`
    Specs       string `protobuf:"bytes,3,opt,name=Specs,proto3" json:"Specs,omitempty"`
    Unit        string `protobuf:"bytes,4,opt,name=Unit,proto3" json:"Unit,omitempty"`
    Amount      int64  `protobuf:"varint,5,opt,name=Amount,proto3" json:"Amount,omitempty"`
    Cost        string `protobuf:"bytes,6,opt,name=Cost,proto3" json:"Cost,omitempty"`      //产品成本
    Price       int64  `protobuf:"varint,7,opt,name=Price,proto3" json:"Price,omitempty"`   //产品价格
    Total       int64  `protobuf:"varint,8,opt,name=Total,proto3" json:"Total,omitempty"`   //产品总价
    Profit      string `protobuf:"bytes,9,opt,name=Profit,proto3" json:"Profit,omitempty"`  //毛利
    Margin      string `protobuf:"bytes,10,opt,name=Margin,proto3" json:"Margin,omitempty"` //毛利率
}
func (x *CrmSalesDetailsProductInfo) Reset() {
    *x = CrmSalesDetailsProductInfo{}
    if protoimpl.UnsafeEnabled {
        mi := &file_crm_aps_proto_msgTypes[22]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *CrmSalesDetailsProductInfo) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*CrmSalesDetailsProductInfo) ProtoMessage() {}
func (x *CrmSalesDetailsProductInfo) ProtoReflect() protoreflect.Message {
    mi := &file_crm_aps_proto_msgTypes[22]
    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 CrmSalesDetailsProductInfo.ProtoReflect.Descriptor instead.
func (*CrmSalesDetailsProductInfo) Descriptor() ([]byte, []int) {
    return file_crm_aps_proto_rawDescGZIP(), []int{22}
}
func (x *CrmSalesDetailsProductInfo) GetProductId() string {
    if x != nil {
        return x.ProductId
    }
    return ""
}
func (x *CrmSalesDetailsProductInfo) GetProductName() string {
    if x != nil {
        return x.ProductName
    }
    return ""
}
func (x *CrmSalesDetailsProductInfo) GetSpecs() string {
    if x != nil {
        return x.Specs
    }
    return ""
}
func (x *CrmSalesDetailsProductInfo) GetUnit() string {
    if x != nil {
        return x.Unit
    }
    return ""
}
func (x *CrmSalesDetailsProductInfo) GetAmount() int64 {
    if x != nil {
        return x.Amount
    }
    return 0
}
func (x *CrmSalesDetailsProductInfo) GetCost() string {
    if x != nil {
        return x.Cost
    }
    return ""
}
func (x *CrmSalesDetailsProductInfo) GetPrice() int64 {
    if x != nil {
        return x.Price
    }
    return 0
}
func (x *CrmSalesDetailsProductInfo) GetTotal() int64 {
    if x != nil {
        return x.Total
    }
    return 0
}
func (x *CrmSalesDetailsProductInfo) GetProfit() string {
    if x != nil {
        return x.Profit
    }
    return ""
}
func (x *CrmSalesDetailsProductInfo) GetMargin() string {
    if x != nil {
        return x.Margin
    }
    return ""
}
type GetCrmSalesDetailsProductInfoResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    List []*CrmSalesDetailsProductInfo `protobuf:"bytes,1,rep,name=List,proto3" json:"List,omitempty"`
}
func (x *GetCrmSalesDetailsProductInfoResponse) Reset() {
    *x = GetCrmSalesDetailsProductInfoResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_crm_aps_proto_msgTypes[23]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetCrmSalesDetailsProductInfoResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetCrmSalesDetailsProductInfoResponse) ProtoMessage() {}
func (x *GetCrmSalesDetailsProductInfoResponse) ProtoReflect() protoreflect.Message {
    mi := &file_crm_aps_proto_msgTypes[23]
    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 GetCrmSalesDetailsProductInfoResponse.ProtoReflect.Descriptor instead.
func (*GetCrmSalesDetailsProductInfoResponse) Descriptor() ([]byte, []int) {
    return file_crm_aps_proto_rawDescGZIP(), []int{23}
}
func (x *GetCrmSalesDetailsProductInfoResponse) GetList() []*CrmSalesDetailsProductInfo {
    if x != nil {
        return x.List
    }
    return nil
}
var File_crm_aps_proto protoreflect.FileDescriptor
var file_crm_aps_proto_rawDesc = []byte{
@@ -1137,7 +1515,57 @@
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65,
    0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22,
    0x1b, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65,
    0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x85, 0x05, 0x0a,
    0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x0a, 0x2a,
    0x43, 0x72, 0x6d, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74,
    0x73, 0x6f, 0x75, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x53, 0x61,
    0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
    0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74,
    0x61, 0x69, 0x6c, 0x73, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x93, 0x01, 0x0a, 0x23, 0x43,
    0x72, 0x6d, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x73,
    0x6f, 0x75, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e,
    0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
    0x28, 0x03, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x46, 0x69,
    0x6e, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
    0x52, 0x0c, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c,
    0x0a, 0x09, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
    0x09, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
    0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65,
    0x22, 0x67, 0x0a, 0x2b, 0x43, 0x72, 0x6d, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e,
    0x64, 0x4f, 0x75, 0x74, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64,
    0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
    0x38, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
    0x43, 0x72, 0x6d, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74,
    0x73, 0x6f, 0x75, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x56, 0x0a, 0x24, 0x47, 0x65, 0x74,
    0x43, 0x72, 0x6d, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x50,
    0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
    0x74, 0x12, 0x2e, 0x0a, 0x12, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
    0x73, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x53,
    0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4e, 0x75, 0x6d, 0x62, 0x65,
    0x72, 0x22, 0x8e, 0x02, 0x0a, 0x1a, 0x43, 0x72, 0x6d, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65,
    0x74, 0x61, 0x69, 0x6c, 0x73, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f,
    0x12, 0x1c, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20,
    0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x20,
    0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
    0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65,
    0x12, 0x14, 0x0a, 0x05, 0x53, 0x70, 0x65, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
    0x05, 0x53, 0x70, 0x65, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x04,
    0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d,
    0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75,
    0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
    0x52, 0x04, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18,
    0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05,
    0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x54, 0x6f, 0x74,
    0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01,
    0x28, 0x09, 0x52, 0x06, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x61,
    0x72, 0x67, 0x69, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x61, 0x72, 0x67,
    0x69, 0x6e, 0x22, 0x58, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6d, 0x53, 0x61, 0x6c, 0x65,
    0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x4c,
    0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x43, 0x72, 0x6d, 0x53,
    0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x50, 0x72, 0x6f, 0x64, 0x75,
    0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x32, 0xfd, 0x06, 0x0a,
    0x14, 0x43, 0x72, 0x6d, 0x41, 0x6e, 0x64, 0x41, 0x70, 0x73, 0x47, 0x72, 0x70, 0x63, 0x53, 0x65,
    0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x70, 0x73, 0x50,
    0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x47, 0x65, 0x74,
@@ -1173,13 +1601,29 @@
    0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61,
    0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x55, 0x70, 0x64, 0x61,
    0x74, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73,
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76,
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76,
    0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x19, 0x2e, 0x52,
    0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
    0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65,
    0x73, 0x74, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x63, 0x72, 0x6d, 0x5f, 0x61, 0x70,
    0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
    0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
    0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x82, 0x01, 0x0a, 0x23, 0x43, 0x72, 0x6d, 0x47, 0x65, 0x74,
    0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x69,
    0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2b, 0x2e,
    0x43, 0x72, 0x6d, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74,
    0x73, 0x6f, 0x75, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x43, 0x72, 0x6d,
    0x47, 0x65, 0x74, 0x4d, 0x61, 0x6b, 0x65, 0x41, 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x73, 0x6f, 0x75,
    0x72, 0x63, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f,
    0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a, 0x1d, 0x47, 0x65,
    0x74, 0x43, 0x72, 0x6d, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
    0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x25, 0x2e, 0x47, 0x65,
    0x74, 0x43, 0x72, 0x6d, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
    0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
    0x73, 0x74, 0x1a, 0x26, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6d, 0x53, 0x61, 0x6c, 0x65, 0x73,
    0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e,
    0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09,
    0x2e, 0x2f, 0x63, 0x72, 0x6d, 0x5f, 0x61, 0x70, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
    0x33,
}
var (
@@ -1194,51 +1638,63 @@
    return file_crm_aps_proto_rawDescData
}
var file_crm_aps_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
var file_crm_aps_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
var file_crm_aps_proto_goTypes = []interface{}{
    (*GetApsProjectListRequest)(nil),                // 0: GetApsProjectListRequest
    (*ApsProject)(nil),                              // 1: ApsProject
    (*GetApsProjectListResponse)(nil),               // 2: GetApsProjectListResponse
    (*SalesDetailsProduct)(nil),                     // 3: SalesDetailsProduct
    (*SendSalesDetailsToApsProjectRequest)(nil),     // 4: SendSalesDetailsToApsProjectRequest
    (*SendSalesDetailsToApsProjectResponse)(nil),    // 5: SendSalesDetailsToApsProjectResponse
    (*GetCrmSalesDetailsListRequest)(nil),           // 6: GetCrmSalesDetailsListRequest
    (*CrmSalesDetails)(nil),                         // 7: CrmSalesDetails
    (*GetCrmSalesDetailsListResponse)(nil),          // 8: GetCrmSalesDetailsListResponse
    (*SendSalesDetailsAndProjectToCrmRequest)(nil),  // 9: SendSalesDetailsAndProjectToCrmRequest
    (*SendSalesDetailsAndProjectToCrmResponse)(nil), // 10: SendSalesDetailsAndProjectToCrmResponse
    (*GetClientListRequest)(nil),                    // 11: GetClientListRequest
    (*GetClientListResponse)(nil),                   // 12: GetClientListResponse
    (*Client)(nil),                                  // 13: Client
    (*UpdateSalesDetailRequest)(nil),                // 14: UpdateSalesDetailRequest
    (*UpdateSalesDetailResponse)(nil),               // 15: UpdateSalesDetailResponse
    (*RemoveSalesDetailRequest)(nil),                // 16: RemoveSalesDetailRequest
    (*RemoveSalesDetailResponse)(nil),               // 17: RemoveSalesDetailResponse
    (*GetApsProjectListRequest)(nil),                    // 0: GetApsProjectListRequest
    (*ApsProject)(nil),                                  // 1: ApsProject
    (*GetApsProjectListResponse)(nil),                   // 2: GetApsProjectListResponse
    (*SalesDetailsProduct)(nil),                         // 3: SalesDetailsProduct
    (*SendSalesDetailsToApsProjectRequest)(nil),         // 4: SendSalesDetailsToApsProjectRequest
    (*SendSalesDetailsToApsProjectResponse)(nil),        // 5: SendSalesDetailsToApsProjectResponse
    (*GetCrmSalesDetailsListRequest)(nil),               // 6: GetCrmSalesDetailsListRequest
    (*CrmSalesDetails)(nil),                             // 7: CrmSalesDetails
    (*GetCrmSalesDetailsListResponse)(nil),              // 8: GetCrmSalesDetailsListResponse
    (*SendSalesDetailsAndProjectToCrmRequest)(nil),      // 9: SendSalesDetailsAndProjectToCrmRequest
    (*SendSalesDetailsAndProjectToCrmResponse)(nil),     // 10: SendSalesDetailsAndProjectToCrmResponse
    (*GetClientListRequest)(nil),                        // 11: GetClientListRequest
    (*GetClientListResponse)(nil),                       // 12: GetClientListResponse
    (*Client)(nil),                                      // 13: Client
    (*UpdateSalesDetailRequest)(nil),                    // 14: UpdateSalesDetailRequest
    (*UpdateSalesDetailResponse)(nil),                   // 15: UpdateSalesDetailResponse
    (*RemoveSalesDetailRequest)(nil),                    // 16: RemoveSalesDetailRequest
    (*RemoveSalesDetailResponse)(nil),                   // 17: RemoveSalesDetailResponse
    (*CrmGetMakeAndOutsourcingProductInfoRequest)(nil),  // 18: CrmGetMakeAndOutsourcingProductInfoRequest
    (*CrmGetMakeAndOutsourcingProductInfo)(nil),         // 19: CrmGetMakeAndOutsourcingProductInfo
    (*CrmGetMakeAndOutsourcingProductInfoResponse)(nil), // 20: CrmGetMakeAndOutsourcingProductInfoResponse
    (*GetCrmSalesDetailsProductInfoRequest)(nil),        // 21: GetCrmSalesDetailsProductInfoRequest
    (*CrmSalesDetailsProductInfo)(nil),                  // 22: CrmSalesDetailsProductInfo
    (*GetCrmSalesDetailsProductInfoResponse)(nil),       // 23: GetCrmSalesDetailsProductInfoResponse
}
var file_crm_aps_proto_depIdxs = []int32{
    1,  // 0: GetApsProjectListResponse.List:type_name -> ApsProject
    3,  // 1: SendSalesDetailsToApsProjectRequest.Products:type_name -> SalesDetailsProduct
    7,  // 2: GetCrmSalesDetailsListResponse.SalesDetails:type_name -> CrmSalesDetails
    13, // 3: GetClientListResponse.list:type_name -> Client
    0,  // 4: CrmAndApsGrpcService.GetApsProjectList:input_type -> GetApsProjectListRequest
    4,  // 5: CrmAndApsGrpcService.SendSalesDetailsToApsProject:input_type -> SendSalesDetailsToApsProjectRequest
    6,  // 6: CrmAndApsGrpcService.GetCrmSalesDetailsList:input_type -> GetCrmSalesDetailsListRequest
    9,  // 7: CrmAndApsGrpcService.SendSalesDetailsAndProjectToCrm:input_type -> SendSalesDetailsAndProjectToCrmRequest
    11, // 8: CrmAndApsGrpcService.GetClientList:input_type -> GetClientListRequest
    14, // 9: CrmAndApsGrpcService.UpdateSalesDetail:input_type -> UpdateSalesDetailRequest
    16, // 10: CrmAndApsGrpcService.RemoveSalesDetail:input_type -> RemoveSalesDetailRequest
    2,  // 11: CrmAndApsGrpcService.GetApsProjectList:output_type -> GetApsProjectListResponse
    5,  // 12: CrmAndApsGrpcService.SendSalesDetailsToApsProject:output_type -> SendSalesDetailsToApsProjectResponse
    8,  // 13: CrmAndApsGrpcService.GetCrmSalesDetailsList:output_type -> GetCrmSalesDetailsListResponse
    10, // 14: CrmAndApsGrpcService.SendSalesDetailsAndProjectToCrm:output_type -> SendSalesDetailsAndProjectToCrmResponse
    12, // 15: CrmAndApsGrpcService.GetClientList:output_type -> GetClientListResponse
    15, // 16: CrmAndApsGrpcService.UpdateSalesDetail:output_type -> UpdateSalesDetailResponse
    16, // 17: CrmAndApsGrpcService.RemoveSalesDetail:output_type -> RemoveSalesDetailRequest
    11, // [11:18] is the sub-list for method output_type
    4,  // [4:11] 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
    19, // 4: CrmGetMakeAndOutsourcingProductInfoResponse.Info:type_name -> CrmGetMakeAndOutsourcingProductInfo
    22, // 5: GetCrmSalesDetailsProductInfoResponse.List:type_name -> CrmSalesDetailsProductInfo
    0,  // 6: CrmAndApsGrpcService.GetApsProjectList:input_type -> GetApsProjectListRequest
    4,  // 7: CrmAndApsGrpcService.SendSalesDetailsToApsProject:input_type -> SendSalesDetailsToApsProjectRequest
    6,  // 8: CrmAndApsGrpcService.GetCrmSalesDetailsList:input_type -> GetCrmSalesDetailsListRequest
    9,  // 9: CrmAndApsGrpcService.SendSalesDetailsAndProjectToCrm:input_type -> SendSalesDetailsAndProjectToCrmRequest
    11, // 10: CrmAndApsGrpcService.GetClientList:input_type -> GetClientListRequest
    14, // 11: CrmAndApsGrpcService.UpdateSalesDetail:input_type -> UpdateSalesDetailRequest
    16, // 12: CrmAndApsGrpcService.RemoveSalesDetail:input_type -> RemoveSalesDetailRequest
    18, // 13: CrmAndApsGrpcService.CrmGetMakeAndOutsourcingProductInfo:input_type -> CrmGetMakeAndOutsourcingProductInfoRequest
    21, // 14: CrmAndApsGrpcService.GetCrmSalesDetailsProductInfo:input_type -> GetCrmSalesDetailsProductInfoRequest
    2,  // 15: CrmAndApsGrpcService.GetApsProjectList:output_type -> GetApsProjectListResponse
    5,  // 16: CrmAndApsGrpcService.SendSalesDetailsToApsProject:output_type -> SendSalesDetailsToApsProjectResponse
    8,  // 17: CrmAndApsGrpcService.GetCrmSalesDetailsList:output_type -> GetCrmSalesDetailsListResponse
    10, // 18: CrmAndApsGrpcService.SendSalesDetailsAndProjectToCrm:output_type -> SendSalesDetailsAndProjectToCrmResponse
    12, // 19: CrmAndApsGrpcService.GetClientList:output_type -> GetClientListResponse
    15, // 20: CrmAndApsGrpcService.UpdateSalesDetail:output_type -> UpdateSalesDetailResponse
    17, // 21: CrmAndApsGrpcService.RemoveSalesDetail:output_type -> RemoveSalesDetailResponse
    20, // 22: CrmAndApsGrpcService.CrmGetMakeAndOutsourcingProductInfo:output_type -> CrmGetMakeAndOutsourcingProductInfoResponse
    23, // 23: CrmAndApsGrpcService.GetCrmSalesDetailsProductInfo:output_type -> GetCrmSalesDetailsProductInfoResponse
    15, // [15:24] is the sub-list for method output_type
    6,  // [6:15] is the sub-list for method input_type
    6,  // [6:6] is the sub-list for extension type_name
    6,  // [6:6] is the sub-list for extension extendee
    0,  // [0:6] is the sub-list for field type_name
}
func init() { file_crm_aps_proto_init() }
@@ -1463,6 +1919,78 @@
                return nil
            }
        }
        file_crm_aps_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*CrmGetMakeAndOutsourcingProductInfoRequest); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_crm_aps_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*CrmGetMakeAndOutsourcingProductInfo); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_crm_aps_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*CrmGetMakeAndOutsourcingProductInfoResponse); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_crm_aps_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetCrmSalesDetailsProductInfoRequest); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_crm_aps_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*CrmSalesDetailsProductInfo); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_crm_aps_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetCrmSalesDetailsProductInfoResponse); 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{
@@ -1470,7 +1998,7 @@
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_crm_aps_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   18,
            NumMessages:   24,
            NumExtensions: 0,
            NumServices:   1,
        },
proto/crm_aps/crm_aps_grpc.pb.go
@@ -1,8 +1,4 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc             v3.19.0
// source: crm_aps.proto
package crm_aps
@@ -18,16 +14,6 @@
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
    CrmAndApsGrpcService_GetApsProjectList_FullMethodName               = "/CrmAndApsGrpcService/GetApsProjectList"
    CrmAndApsGrpcService_SendSalesDetailsToApsProject_FullMethodName    = "/CrmAndApsGrpcService/SendSalesDetailsToApsProject"
    CrmAndApsGrpcService_GetCrmSalesDetailsList_FullMethodName          = "/CrmAndApsGrpcService/GetCrmSalesDetailsList"
    CrmAndApsGrpcService_SendSalesDetailsAndProjectToCrm_FullMethodName = "/CrmAndApsGrpcService/SendSalesDetailsAndProjectToCrm"
    CrmAndApsGrpcService_GetClientList_FullMethodName                   = "/CrmAndApsGrpcService/GetClientList"
    CrmAndApsGrpcService_UpdateSalesDetail_FullMethodName               = "/CrmAndApsGrpcService/UpdateSalesDetail"
    CrmAndApsGrpcService_RemoveSalesDetail_FullMethodName               = "/CrmAndApsGrpcService/RemoveSalesDetail"
)
// CrmAndApsGrpcServiceClient is the client API for CrmAndApsGrpcService 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.
@@ -38,7 +24,9 @@
    SendSalesDetailsAndProjectToCrm(ctx context.Context, in *SendSalesDetailsAndProjectToCrmRequest, opts ...grpc.CallOption) (*SendSalesDetailsAndProjectToCrmResponse, error)
    GetClientList(ctx context.Context, in *GetClientListRequest, opts ...grpc.CallOption) (*GetClientListResponse, error)
    UpdateSalesDetail(ctx context.Context, in *UpdateSalesDetailRequest, opts ...grpc.CallOption) (*UpdateSalesDetailResponse, error)
    RemoveSalesDetail(ctx context.Context, in *RemoveSalesDetailRequest, opts ...grpc.CallOption) (*RemoveSalesDetailRequest, error)
    RemoveSalesDetail(ctx context.Context, in *RemoveSalesDetailRequest, opts ...grpc.CallOption) (*RemoveSalesDetailResponse, error)
    CrmGetMakeAndOutsourcingProductInfo(ctx context.Context, in *CrmGetMakeAndOutsourcingProductInfoRequest, opts ...grpc.CallOption) (*CrmGetMakeAndOutsourcingProductInfoResponse, error)
    GetCrmSalesDetailsProductInfo(ctx context.Context, in *GetCrmSalesDetailsProductInfoRequest, opts ...grpc.CallOption) (*GetCrmSalesDetailsProductInfoResponse, error)
}
type crmAndApsGrpcServiceClient struct {
@@ -51,7 +39,7 @@
func (c *crmAndApsGrpcServiceClient) GetApsProjectList(ctx context.Context, in *GetApsProjectListRequest, opts ...grpc.CallOption) (*GetApsProjectListResponse, error) {
    out := new(GetApsProjectListResponse)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_GetApsProjectList_FullMethodName, in, out, opts...)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/GetApsProjectList", in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -60,7 +48,7 @@
func (c *crmAndApsGrpcServiceClient) SendSalesDetailsToApsProject(ctx context.Context, in *SendSalesDetailsToApsProjectRequest, opts ...grpc.CallOption) (*SendSalesDetailsToApsProjectResponse, error) {
    out := new(SendSalesDetailsToApsProjectResponse)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_SendSalesDetailsToApsProject_FullMethodName, in, out, opts...)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/SendSalesDetailsToApsProject", in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -69,7 +57,7 @@
func (c *crmAndApsGrpcServiceClient) GetCrmSalesDetailsList(ctx context.Context, in *GetCrmSalesDetailsListRequest, opts ...grpc.CallOption) (*GetCrmSalesDetailsListResponse, error) {
    out := new(GetCrmSalesDetailsListResponse)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_GetCrmSalesDetailsList_FullMethodName, in, out, opts...)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/GetCrmSalesDetailsList", in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -78,7 +66,7 @@
func (c *crmAndApsGrpcServiceClient) SendSalesDetailsAndProjectToCrm(ctx context.Context, in *SendSalesDetailsAndProjectToCrmRequest, opts ...grpc.CallOption) (*SendSalesDetailsAndProjectToCrmResponse, error) {
    out := new(SendSalesDetailsAndProjectToCrmResponse)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_SendSalesDetailsAndProjectToCrm_FullMethodName, in, out, opts...)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/SendSalesDetailsAndProjectToCrm", in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -87,7 +75,7 @@
func (c *crmAndApsGrpcServiceClient) GetClientList(ctx context.Context, in *GetClientListRequest, opts ...grpc.CallOption) (*GetClientListResponse, error) {
    out := new(GetClientListResponse)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_GetClientList_FullMethodName, in, out, opts...)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/GetClientList", in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -96,16 +84,34 @@
func (c *crmAndApsGrpcServiceClient) UpdateSalesDetail(ctx context.Context, in *UpdateSalesDetailRequest, opts ...grpc.CallOption) (*UpdateSalesDetailResponse, error) {
    out := new(UpdateSalesDetailResponse)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_UpdateSalesDetail_FullMethodName, in, out, opts...)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/UpdateSalesDetail", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
func (c *crmAndApsGrpcServiceClient) RemoveSalesDetail(ctx context.Context, in *RemoveSalesDetailRequest, opts ...grpc.CallOption) (*RemoveSalesDetailRequest, error) {
    out := new(RemoveSalesDetailRequest)
    err := c.cc.Invoke(ctx, CrmAndApsGrpcService_RemoveSalesDetail_FullMethodName, in, out, opts...)
func (c *crmAndApsGrpcServiceClient) RemoveSalesDetail(ctx context.Context, in *RemoveSalesDetailRequest, opts ...grpc.CallOption) (*RemoveSalesDetailResponse, error) {
    out := new(RemoveSalesDetailResponse)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/RemoveSalesDetail", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
func (c *crmAndApsGrpcServiceClient) CrmGetMakeAndOutsourcingProductInfo(ctx context.Context, in *CrmGetMakeAndOutsourcingProductInfoRequest, opts ...grpc.CallOption) (*CrmGetMakeAndOutsourcingProductInfoResponse, error) {
    out := new(CrmGetMakeAndOutsourcingProductInfoResponse)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/CrmGetMakeAndOutsourcingProductInfo", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
func (c *crmAndApsGrpcServiceClient) GetCrmSalesDetailsProductInfo(ctx context.Context, in *GetCrmSalesDetailsProductInfoRequest, opts ...grpc.CallOption) (*GetCrmSalesDetailsProductInfoResponse, error) {
    out := new(GetCrmSalesDetailsProductInfoResponse)
    err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/GetCrmSalesDetailsProductInfo", in, out, opts...)
    if err != nil {
        return nil, err
    }
@@ -122,7 +128,9 @@
    SendSalesDetailsAndProjectToCrm(context.Context, *SendSalesDetailsAndProjectToCrmRequest) (*SendSalesDetailsAndProjectToCrmResponse, error)
    GetClientList(context.Context, *GetClientListRequest) (*GetClientListResponse, error)
    UpdateSalesDetail(context.Context, *UpdateSalesDetailRequest) (*UpdateSalesDetailResponse, error)
    RemoveSalesDetail(context.Context, *RemoveSalesDetailRequest) (*RemoveSalesDetailRequest, error)
    RemoveSalesDetail(context.Context, *RemoveSalesDetailRequest) (*RemoveSalesDetailResponse, error)
    CrmGetMakeAndOutsourcingProductInfo(context.Context, *CrmGetMakeAndOutsourcingProductInfoRequest) (*CrmGetMakeAndOutsourcingProductInfoResponse, error)
    GetCrmSalesDetailsProductInfo(context.Context, *GetCrmSalesDetailsProductInfoRequest) (*GetCrmSalesDetailsProductInfoResponse, error)
    mustEmbedUnimplementedCrmAndApsGrpcServiceServer()
}
@@ -148,8 +156,14 @@
func (UnimplementedCrmAndApsGrpcServiceServer) UpdateSalesDetail(context.Context, *UpdateSalesDetailRequest) (*UpdateSalesDetailResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method UpdateSalesDetail not implemented")
}
func (UnimplementedCrmAndApsGrpcServiceServer) RemoveSalesDetail(context.Context, *RemoveSalesDetailRequest) (*RemoveSalesDetailRequest, error) {
func (UnimplementedCrmAndApsGrpcServiceServer) RemoveSalesDetail(context.Context, *RemoveSalesDetailRequest) (*RemoveSalesDetailResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method RemoveSalesDetail not implemented")
}
func (UnimplementedCrmAndApsGrpcServiceServer) CrmGetMakeAndOutsourcingProductInfo(context.Context, *CrmGetMakeAndOutsourcingProductInfoRequest) (*CrmGetMakeAndOutsourcingProductInfoResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method CrmGetMakeAndOutsourcingProductInfo not implemented")
}
func (UnimplementedCrmAndApsGrpcServiceServer) GetCrmSalesDetailsProductInfo(context.Context, *GetCrmSalesDetailsProductInfoRequest) (*GetCrmSalesDetailsProductInfoResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method GetCrmSalesDetailsProductInfo not implemented")
}
func (UnimplementedCrmAndApsGrpcServiceServer) mustEmbedUnimplementedCrmAndApsGrpcServiceServer() {}
@@ -174,7 +188,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_GetApsProjectList_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/GetApsProjectList",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).GetApsProjectList(ctx, req.(*GetApsProjectListRequest))
@@ -192,7 +206,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_SendSalesDetailsToApsProject_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/SendSalesDetailsToApsProject",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).SendSalesDetailsToApsProject(ctx, req.(*SendSalesDetailsToApsProjectRequest))
@@ -210,7 +224,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_GetCrmSalesDetailsList_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/GetCrmSalesDetailsList",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).GetCrmSalesDetailsList(ctx, req.(*GetCrmSalesDetailsListRequest))
@@ -228,7 +242,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_SendSalesDetailsAndProjectToCrm_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/SendSalesDetailsAndProjectToCrm",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).SendSalesDetailsAndProjectToCrm(ctx, req.(*SendSalesDetailsAndProjectToCrmRequest))
@@ -246,7 +260,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_GetClientList_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/GetClientList",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).GetClientList(ctx, req.(*GetClientListRequest))
@@ -264,7 +278,7 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_UpdateSalesDetail_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/UpdateSalesDetail",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).UpdateSalesDetail(ctx, req.(*UpdateSalesDetailRequest))
@@ -282,10 +296,46 @@
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: CrmAndApsGrpcService_RemoveSalesDetail_FullMethodName,
        FullMethod: "/CrmAndApsGrpcService/RemoveSalesDetail",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).RemoveSalesDetail(ctx, req.(*RemoveSalesDetailRequest))
    }
    return interceptor(ctx, in, info, handler)
}
func _CrmAndApsGrpcService_CrmGetMakeAndOutsourcingProductInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(CrmGetMakeAndOutsourcingProductInfoRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(CrmAndApsGrpcServiceServer).CrmGetMakeAndOutsourcingProductInfo(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/CrmAndApsGrpcService/CrmGetMakeAndOutsourcingProductInfo",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).CrmGetMakeAndOutsourcingProductInfo(ctx, req.(*CrmGetMakeAndOutsourcingProductInfoRequest))
    }
    return interceptor(ctx, in, info, handler)
}
func _CrmAndApsGrpcService_GetCrmSalesDetailsProductInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(GetCrmSalesDetailsProductInfoRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(CrmAndApsGrpcServiceServer).GetCrmSalesDetailsProductInfo(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/CrmAndApsGrpcService/GetCrmSalesDetailsProductInfo",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(CrmAndApsGrpcServiceServer).GetCrmSalesDetailsProductInfo(ctx, req.(*GetCrmSalesDetailsProductInfoRequest))
    }
    return interceptor(ctx, in, info, handler)
}
@@ -325,6 +375,14 @@
            MethodName: "RemoveSalesDetail",
            Handler:    _CrmAndApsGrpcService_RemoveSalesDetail_Handler,
        },
        {
            MethodName: "CrmGetMakeAndOutsourcingProductInfo",
            Handler:    _CrmAndApsGrpcService_CrmGetMakeAndOutsourcingProductInfo_Handler,
        },
        {
            MethodName: "GetCrmSalesDetailsProductInfo",
            Handler:    _CrmAndApsGrpcService_GetCrmSalesDetailsProductInfo_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "crm_aps.proto",
proto/crm_aps/server.go
@@ -193,7 +193,7 @@
    return &UpdateSalesDetailResponse{}, nil
}
func (s *Server) RemoveSalesDetail(ctx context.Context, req *RemoveSalesDetailRequest) (*RemoveSalesDetailRequest, error) {
func (s *Server) RemoveSalesDetail(ctx context.Context, req *RemoveSalesDetailRequest) (*RemoveSalesDetailResponse, error) {
    if req.Number == "" {
        return nil, errors.New("销售明细编号为空")
    }
@@ -208,5 +208,33 @@
        return nil, errors.New("销售明细删除失败")
    }
    return &RemoveSalesDetailRequest{}, nil
    return &RemoveSalesDetailResponse{}, nil
}
func (s *Server) GetCrmSalesDetailsProductInfo(ctx context.Context, req *GetCrmSalesDetailsProductInfoRequest) (*GetCrmSalesDetailsProductInfoResponse, error) {
    if req.SalesDetailsNumber == "" {
        return nil, errors.New("销售明细编号为空")
    }
    first, err := model.NewSalesDetailsSearch().SetPreload(true).SetNumber(req.SalesDetailsNumber).First()
    if err != nil {
        return nil, err
    }
    list := make([]*CrmSalesDetailsProductInfo, 0)
    for _, product := range first.Products {
        var csp CrmSalesDetailsProductInfo
        csp.ProductId = product.Number
        csp.ProductName = product.Name
        csp.Specs = product.Specs
        csp.Unit = product.Unit
        csp.Amount = product.Amount.IntPart()
        csp.Cost = product.Cost
        csp.Price = product.Price.IntPart()
        csp.Total = product.Total.IntPart()
        csp.Profit = product.Profit
        csp.Margin = product.Margin
        list = append(list, &csp)
    }
    resp := new(GetCrmSalesDetailsProductInfoResponse)
    resp.List = list
    return resp, nil
}