diff --git a/Gopkg.lock b/Gopkg.lock index 0a3c91c..a6c979e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,25 +3,87 @@ [[projects]] branch = "master" + digest = "1:d60fdea623cbe445d3831aed9b1a27f9cff2ba2dcb99c0866d79515b6b1b2e4f" name = "github.com/casualcode/soap" packages = ["."] + pruneopts = "" revision = "44eefde542392077c89292f04065d3e7d8852750" [[projects]] - branch = "master" - name = "github.com/fiorix/wsdl2go" + digest = "1:5c0fdc3abd05f58604f4faa6123f999a138865da63ccdd77bbae13304c15e122" + name = "github.com/devimteam/wsdl2go" packages = ["soap"] - revision = "57713bd6b8f5601000fca5e518a5013c4afbfae0" + pruneopts = "" + revision = "5c4e6c7ba9d9355bba952997eb0c639cb90f672e" + +[[projects]] + digest = "1:10c7813de846fa10aad0ea9bca34a3c20815d51250e48ba1a3c3c7572184aea8" + name = "github.com/gofrs/uuid" + packages = ["."] + pruneopts = "" + revision = "370558f003bfe29580cd0f698d8640daccdcc45c" + version = "v3.1.1" + +[[projects]] + digest = "1:a6ddc18062f456217783668182e8c5fa3ff73b279d143a96faae5c13db60dc76" + name = "github.com/l-vitaly/gounit" + packages = [ + ".", + "gounitсonstraint", + ] + pruneopts = "" + revision = "d9d8b2917fdd427061d3dc23ae52fc29a2ed860f" + version = "v1.0.5" [[projects]] - name = "github.com/satori/go.uuid" + digest = "1:9ea83adf8e96d6304f394d40436f2eb44c1dc3250d223b74088cc253a6cd0a1c" + name = "github.com/mattn/go-colorable" packages = ["."] - revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3" - version = "v1.2.0" + pruneopts = "" + revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" + version = "v0.0.9" + +[[projects]] + digest = "1:3140e04675a6a91d2a20ea9d10bdadf6072085502e6def6768361260aee4b967" + name = "github.com/mattn/go-isatty" + packages = ["."] + pruneopts = "" + revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" + version = "v0.0.4" + +[[projects]] + branch = "master" + digest = "1:50416da10e189bc201e122e20078fb8e680a439cbdd24aaece06c434b4415b60" + name = "github.com/mgutz/ansi" + packages = ["."] + pruneopts = "" + revision = "9520e82c474b0a04dd04f8a40959027271bab992" + +[[projects]] + digest = "1:7365acd48986e205ccb8652cc746f09c8b7876030d53710ea6ef7d0bd0dcd7ca" + name = "github.com/pkg/errors" + packages = ["."] + pruneopts = "" + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + branch = "master" + digest = "1:630da6b685efd0155076e77c082a4fb297a5fd49a722d28fb4c728cd8656e060" + name = "golang.org/x/sys" + packages = ["unix"] + pruneopts = "" + revision = "dad3d9fb7b6e83d0f9ac8f54670f6334c3a287b4" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f95b140d432b0fec0aa99b2030894d29258b75da4ce45c6d550ec080f8fdab23" + input-imports = [ + "github.com/casualcode/soap", + "github.com/devimteam/wsdl2go/soap", + "github.com/gofrs/uuid", + "github.com/l-vitaly/gounit", + "github.com/pkg/errors", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 7d5dcc1..6461406 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -3,8 +3,8 @@ branch = "master" [[constraint]] - name = "github.com/fiorix/wsdl2go" - branch = "master" + name = "github.com/devimteam/wsdl2go" + revision = "5c4e6c7ba9d9355bba952997eb0c639cb90f672e" [[constraint]] name = "github.com/satori/go.uuid" diff --git a/internal/connector/soap.go b/internal/connector/soap.go deleted file mode 100644 index 0beabfc..0000000 --- a/internal/connector/soap.go +++ /dev/null @@ -1,98 +0,0 @@ -package connector - -import ( - "time" - - "github.com/devimteam/creditinfo/pkg/request" - "github.com/devimteam/creditinfo/pkg/response" - "github.com/fiorix/wsdl2go/soap" - "github.com/pkg/errors" -) - -// Namespace was auto-generated from WSDL. -var Namespace = "http://creditinfo.com/schemas/2012/09/MultiConnector" - -// NewMultiConnectorService creates an initializes a MultiConnectorService. -func NewMultiConnectorService(cli *soap.Client) MultiConnectorService { - return &multiConnectorService{cli} -} - -// MultiConnectorService was auto-generated from WSDL -// and defines interface for the remote service. Useful for testing. -type MultiConnectorService interface { - // Query was auto-generated from WSDL. - Query(parameters *Query) (*response.ResultResponse, error) -} - -// Char was auto-generated from WSDL. -type Char int - -// Duration was auto-generated from WSDL. -type Duration time.Duration - -// Guid was auto-generated from WSDL. -type Guid string - -// FailedAuthentication was auto-generated from WSDL. -type FailedAuthentication struct { -} - -// InProgress was auto-generated from WSDL. -type InProgress struct { -} - -// Query was auto-generated from WSDL. -type Query struct { - Request *request.MultiConnectorRequest `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector request,omitempty" json:"request,omitempty" yaml:"request,omitempty"` -} - -// QueryResponse was auto-generated from WSDL. -type QueryResponse struct { - QueryResult *response.MultiConnectorResponse `xml:"QueryResult,omitempty" json:"QueryResult,omitempty" yaml:"QueryResult,omitempty"` -} - -// Operation wrapper for Query. -// OperationMultiConnectorService_Query_InputMessage was auto-generated -// from WSDL. -type OperationMultiConnectorService_Query_InputMessage struct { - Parameters *Query `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector Query,omitempty" json:"Query,omitempty" yaml:"Query,omitempty"` -} - -// Operation wrapper for Query. -// OperationMultiConnectorService_Query_OutputMessage was auto-generated -// from WSDL. -type OperationMultiConnectorService_Query_OutputMessage struct { - Parameters *QueryResponse `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector QueryResponse,omitempty" json:"QueryResponse,omitempty" yaml:"QueryResponse,omitempty"` -} - -// multiConnectorService implements the MultiConnectorService interface. -type multiConnectorService struct { - cli *soap.Client -} - -// Query was auto-generated from WSDL. -func (p *multiConnectorService) Query(parameters *Query) (*response.ResultResponse, error) { - intput := struct { - OperationMultiConnectorService_Query_InputMessage `xml:"tns:Query"` - }{ - OperationMultiConnectorService_Query_InputMessage{ - parameters, - }, - } - - out := struct { - OperationMultiConnectorService_Query_OutputMessage `xml:"tns:QueryResponse"` - }{} - if err := p.cli.RoundTripWithAction("http://creditinfo.com/schemas/2012/09/MultiConnector/MultiConnectorService/Query", intput, &out); err != nil { - return nil, err - } - if err := out.Parameters.QueryResult.ResponseXml.Response.Connector.Error; err != nil { - return nil, errors.New(err.Message) - } - - if status := out.Parameters.QueryResult.ResponseXml.Response.Connector.Data.Response.Status; status != "ok" { - return nil, errors.New(status) - } - - return out.Parameters.QueryResult.ResponseXml.Response.Connector.Data.Response, nil -} diff --git a/pkg/client/client.go b/pkg/client/client.go index b806f64..c9c8e49 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -1,26 +1,32 @@ package client import ( + "context" + "net/http" "time" wsse "github.com/casualcode/soap" - "github.com/devimteam/creditinfo/internal/connector" + "github.com/devimteam/creditinfo/pkg/connector" "github.com/devimteam/creditinfo/pkg/request" "github.com/devimteam/creditinfo/pkg/response" - "github.com/fiorix/wsdl2go/soap" - "github.com/satori/go.uuid" + "github.com/devimteam/wsdl2go/soap" + "github.com/gofrs/uuid" ) //Soap Client provides an interface for getting data out creditinfo service type Client interface { - GetIndividualReport(nationalId *string, phone *string, birthDate *time.Time) (*response.ResultResponse, error) + GetIndividualReport(ctx context.Context, nationalId *string, phone *string, birthDate *time.Time) (*response.ResultResponse, error) + GetIndividualReportBeginQuery(ctx context.Context, nationalId *string, phone *string, birthDate *time.Time) (ticket *connector.MultiConnectorTicket, err error) + EndQuery(ctx context.Context, ticket *connector.MultiConnectorTicket) (*response.ResultResponse, error) } + type CreditInfoParams struct { Username string Password string ConnectorId string StrategyId string Endpoint string + Timeout *time.Duration } type creditInfo struct { @@ -29,13 +35,15 @@ type creditInfo struct { } // NewClient returns a Client interface for given soap api creditinfo -func NewCreditInfoClient(params CreditInfoParams) Client { +func NewCreditInfoClient(params CreditInfoParams, pre func(context.Context, *http.Request), post func(context.Context, *http.Response)) *creditInfo { svc := connector.NewMultiConnectorService(&soap.Client{ URL: params.Endpoint, Header: getWsseHeader(params.Username, params.Password), Namespace: connector.Namespace, ExcludeActionNamespace: true, + Pre: pre, + Post: post, }) return &creditInfo{ @@ -44,42 +52,88 @@ func NewCreditInfoClient(params CreditInfoParams) Client { } } -func (client creditInfo) GetIndividualReport(nationalId *string, phone *string, birthDate *time.Time) (*response.ResultResponse, error) { - messageId := uuid.NewV4().String() - dataId := uuid.NewV4().String() - connectorGuuid := client.params.ConnectorId - var birthDdateFormat string +func (client *creditInfo) GetIndividualReport(ctx context.Context, nationalId *string, phone *string, birthDate *time.Time) (response *response.ResultResponse, err error) { + messageId, err := uuid.NewV4() + if err != nil { + return nil, err + } + dataId, err := uuid.NewV4() + if err != nil { + return nil, err + } + + var bdate *request.Date if birthDate != nil { - birthDdateFormat = birthDate.Format("2006-01-02") + t := request.Date(*birthDate) + bdate = &t } - return client.svc.Query(&connector.Query{ - Request: &request.MultiConnectorRequest{ - MessageId: &messageId, - RequestXml: &request.RequestXml{ - RequestXmlItem: &request.RequestXmlItem{ - Connector: &request.ConnectorRequest{ - Id: &connectorGuuid, - Data: &request.ConnectorDataRequest{ - Id: &dataId, - Request: &request.Request{ - Strategy: &request.Strategy{ - Id: client.params.StrategyId, - }, - Cb5SearchParameters: request.Cb5SearchParameters{ - NationalId: nationalId, - }, - CustomFields: &request.CustomFields{ - MobilePhone: phone, - DateOfBirth: &birthDdateFormat, - }, - Consent: true, + return client.svc.Query(ctx, &connector.Query{ + Request: client.getMultiConnectorRequest( + messageId.String(), + dataId.String(), + *nationalId, + &request.CustomFields{ + MobilePhone: phone, + DateOfBirth: bdate, + }, + ), + }) +} + +func (client *creditInfo) getMultiConnectorRequest(messageId, dataId, nationalId string, customFields *request.CustomFields) *request.MultiConnectorRequest { + return &request.MultiConnectorRequest{ + MessageId: &messageId, + Timeout: request.NilDuration(client.params.Timeout), + RequestXml: &request.RequestXml{ + RequestXmlItem: &request.RequestXmlItem{ + Connector: &request.ConnectorRequest{ + Id: &client.params.ConnectorId, + Data: &request.ConnectorDataRequest{ + Id: &dataId, + Request: &request.Request{ + Strategy: &request.Strategy{ + Id: client.params.StrategyId, }, + Cb5SearchParameters: request.Cb5SearchParameters{ + NationalId: &nationalId, + }, + CustomFields: customFields, + Consent: true, }, }, }, }, }, + } +} +func (client *creditInfo) GetIndividualReportBeginQuery(ctx context.Context, nationalId *string, phone *string, birthDate *time.Time) (ticket *connector.MultiConnectorTicket, err error) { + messageId, err := uuid.NewV4() + if err != nil { + return nil, err + } + dataId, err := uuid.NewV4() + if err != nil { + return nil, err + } + + var bdate *request.Date + if birthDate != nil { + t := request.Date(*birthDate) + bdate = &t + } + + return client.svc.BeginQuery(ctx, &connector.BeginQuery{ + Request: client.getMultiConnectorRequest(messageId.String(), dataId.String(), *nationalId, &request.CustomFields{ + MobilePhone: phone, + DateOfBirth: bdate, + }), + }) +} + +func (client *creditInfo) EndQuery(ctx context.Context, ticket *connector.MultiConnectorTicket) (*response.ResultResponse, error) { + return client.svc.EndQuery(ctx, &connector.EndQuery{ + Ticket: ticket, }) } diff --git a/pkg/connector/soap.go b/pkg/connector/soap.go new file mode 100644 index 0000000..af9c66d --- /dev/null +++ b/pkg/connector/soap.go @@ -0,0 +1,204 @@ +package connector + +import ( + "context" + "fmt" + "time" + + "github.com/devimteam/creditinfo/pkg/request" + "github.com/devimteam/creditinfo/pkg/response" + "github.com/devimteam/wsdl2go/soap" + "github.com/pkg/errors" +) + +// Namespace was auto-generated from WSDL. +var Namespace = "http://creditinfo.com/schemas/2012/09/MultiConnector" + +// NewMultiConnectorService creates an initializes a MultiConnectorService. +func NewMultiConnectorService(cli *soap.Client) MultiConnectorService { + return &multiConnectorService{cli} +} + +// MultiConnectorService was auto-generated from WSDL +// and defines interface for the remote service. Useful for testing. +type MultiConnectorService interface { + // BeginQuery was auto-generated from WSDL. + BeginQuery(ctx context.Context, parameters *BeginQuery) (*MultiConnectorTicket, error) + // EndQuery was auto-generated from WSDL. + EndQuery(ctx context.Context, parameters *EndQuery) (*response.ResultResponse, error) + // Query was auto-generated from WSDL. + Query(ctx context.Context, parameters *Query) (*response.ResultResponse, error) +} + +// Char was auto-generated from WSDL. +type Char int + +// Duration was auto-generated from WSDL. +type Duration time.Duration + +// Guid was auto-generated from WSDL. +type Guid string + +// FailedAuthentication was auto-generated from WSDL. +type FailedAuthentication struct { +} + +// InProgress was auto-generated from WSDL. +type InProgress struct { +} + +// BeginQuery was auto-generated from WSDL. +type BeginQuery struct { + Request *request.MultiConnectorRequest `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector request,omitempty" json:"request,omitempty" yaml:"request,omitempty"` +} + +// BeginQueryResponse was auto-generated from WSDL. +type BeginQueryResponse struct { + BeginQueryResult *MultiConnectorTicket `xml:"BeginQueryResult,omitempty" json:"BeginQueryResult,omitempty" yaml:"BeginQueryResult,omitempty"` +} + +// EndQuery was auto-generated from WSDL. +type EndQuery struct { + Ticket *MultiConnectorTicket `xml:"ticket,omitempty" json:"ticket,omitempty" yaml:"ticket,omitempty"` +} + +// EndQueryResponse was auto-generated from WSDL. +type EndQueryResponse struct { + EndQueryResult *response.MultiConnectorResponse `xml:"EndQueryResult,omitempty" json:"EndQueryResult,omitempty" yaml:"EndQueryResult,omitempty"` +} + +// MultiConnectorTicket was auto-generated from WSDL. +type MultiConnectorTicket struct { + MessageId *Guid `xml:"MessageId,omitempty" json:"MessageId,omitempty" yaml:"MessageId,omitempty"` +} + +// Operation wrapper for BeginQuery. +// OperationMultiConnectorService_BeginQuery_InputMessage was auto-generated +// from WSDL. +type OperationMultiConnectorService_BeginQuery_InputMessage struct { + Parameters *BeginQuery `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector BeginQuery,omitempty" json:"BeginQuery,omitempty" yaml:"BeginQuery,omitempty"` +} + +// Operation wrapper for BeginQuery. +// OperationMultiConnectorService_BeginQuery_OutputMessage was +// auto-generated from WSDL. +type OperationMultiConnectorService_BeginQuery_OutputMessage struct { + Parameters *BeginQueryResponse `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector BeginQueryResponse,omitempty" json:"BeginQueryResponse,omitempty" yaml:"BeginQueryResponse,omitempty"` +} + +// Operation wrapper for EndQuery. +// OperationMultiConnectorService_EndQuery_InputMessage was auto-generated +// from WSDL. +type OperationMultiConnectorService_EndQuery_InputMessage struct { + Parameters *EndQuery `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector EndQuery,omitempty" json:"EndQuery,omitempty" yaml:"EndQuery,omitempty"` +} + +// Operation wrapper for EndQuery. +// OperationMultiConnectorService_EndQuery_OutputMessage was auto-generated +// from WSDL. +type OperationMultiConnectorService_EndQuery_OutputMessage struct { + Parameters *EndQueryResponse `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector EndQueryResponse,omitempty" json:"EndQueryResponse,omitempty" yaml:"EndQueryResponse,omitempty"` +} + +// Query was auto-generated from WSDL. +type Query struct { + Request *request.MultiConnectorRequest `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector request,omitempty" json:"request,omitempty" yaml:"request,omitempty"` +} + +// QueryResponse was auto-generated from WSDL. +type QueryResponse struct { + QueryResult *response.MultiConnectorResponse `xml:"QueryResult,omitempty" json:"QueryResult,omitempty" yaml:"QueryResult,omitempty"` +} + +// Operation wrapper for Query. +// OperationMultiConnectorService_Query_InputMessage was auto-generated +// from WSDL. +type OperationMultiConnectorService_Query_InputMessage struct { + Parameters *Query `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector Query,omitempty" json:"Query,omitempty" yaml:"Query,omitempty"` +} + +// Operation wrapper for Query. +// OperationMultiConnectorService_Query_OutputMessage was auto-generated +// from WSDL. +type OperationMultiConnectorService_Query_OutputMessage struct { + Parameters *QueryResponse `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector QueryResponse,omitempty" json:"QueryResponse,omitempty" yaml:"QueryResponse,omitempty"` +} + +// multiConnectorService implements the MultiConnectorService interface. +type multiConnectorService struct { + cli *soap.Client +} + +// Query was auto-generated from WSDL. +func (p *multiConnectorService) Query(ctx context.Context, parameters *Query) (*response.ResultResponse, error) { + intput := struct { + OperationMultiConnectorService_Query_InputMessage `xml:"tns:Query"` + }{ + OperationMultiConnectorService_Query_InputMessage{ + parameters, + }, + } + + out := struct { + OperationMultiConnectorService_Query_OutputMessage `xml:"tns:QueryResponse"` + }{} + if err := p.cli.RoundTripWithActionContext(ctx, "http://creditinfo.com/schemas/2012/09/MultiConnector/MultiConnectorService/Query", intput, &out); err != nil { + return nil, err + } + if err := out.Parameters.QueryResult.ResponseXml.Response.Connector.Error; err != nil { + return nil, errors.New(err.Message) + } + + if status := out.Parameters.QueryResult.ResponseXml.Response.Connector.Data.Response.Status; status != "ok" { + return nil, fmt.Errorf("status: %s; message: %s", status, out.Parameters.QueryResult.ResponseXml.Response.Connector.Data.Response.Infomsg) + } + + return out.Parameters.QueryResult.ResponseXml.Response.Connector.Data.Response, nil +} + +// BeginQuery was auto-generated from WSDL. +func (p *multiConnectorService) BeginQuery(ctx context.Context, parameters *BeginQuery) (*MultiConnectorTicket, error) { + input := struct { + OperationMultiConnectorService_BeginQuery_InputMessage `xml:"tns:BeginQuery"` + }{ + OperationMultiConnectorService_BeginQuery_InputMessage{ + parameters, + }, + } + + out := struct { + OperationMultiConnectorService_BeginQuery_OutputMessage `xml:"tns:BeginQueryResponse"` + }{} + if err := p.cli.RoundTripWithActionContext(ctx, "http://creditinfo.com/schemas/2012/09/MultiConnector/MultiConnectorService/BeginQuery", input, &out); err != nil { + return nil, err + } + return out.Parameters.BeginQueryResult, nil +} + +// EndQuery was auto-generated from WSDL. +func (p *multiConnectorService) EndQuery(ctx context.Context, parameters *EndQuery) (*response.ResultResponse, error) { + input := struct { + OperationMultiConnectorService_EndQuery_InputMessage `xml:"tns:EndQuery"` + }{ + OperationMultiConnectorService_EndQuery_InputMessage{ + parameters, + }, + } + + out := struct { + OperationMultiConnectorService_EndQuery_OutputMessage `xml:"tns:EndQueryResponse"` + }{} + if err := p.cli.RoundTripWithActionContext(ctx, "http://creditinfo.com/schemas/2012/09/MultiConnector/MultiConnectorService/EndQuery", input, &out); err != nil { + return nil, err + } + + if err := out.Parameters.EndQueryResult.ResponseXml.Response.Connector.Error; err != nil { + return nil, errors.New(err.Message) + } + + if status := out.Parameters.EndQueryResult.ResponseXml.Response.Connector.Data.Response.Status; status != "ok" { + return nil, errors.New(status) + } + + return out.Parameters.EndQueryResult.ResponseXml.Response.Connector.Data.Response, nil +} diff --git a/pkg/request/request.go b/pkg/request/request.go index 7ae2e27..c31cd4b 100644 --- a/pkg/request/request.go +++ b/pkg/request/request.go @@ -1,20 +1,42 @@ package request import ( + "bytes" "encoding/xml" + "strconv" "time" ) // DateTime in WSDL format. type DateTime string +type Duration time.Duration + +func (d Duration) String() string { + buf := bytes.NewBufferString("PT") + buf.WriteString(strconv.Itoa(int(time.Duration(d).Seconds()))) + buf.WriteString("S") + return buf.String() +} + +func NilDuration(d *time.Duration) *Duration { + if d == nil { + return nil + } + x := Duration(*d) + return &x +} + +func (d Duration) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + return e.EncodeElement(d.String(), start) +} // MultiConnectorRequest was auto-generated from WSDL. type MultiConnectorRequest struct { - MessageId *string `xml:"MessageId,omitempty" json:"MessageId,omitempty" yaml:"MessageId,omitempty"` - OperationCode *string `xml:"OperationCode,omitempty" json:"OperationCode,omitempty" yaml:"OperationCode,omitempty"` - RequestXml *RequestXml `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector RequestXml,omitempty" json:"RequestXml,omitempty" yaml:"RequestXml,omitempty"` - ScheduledTime *DateTime `xml:"ScheduledTime,omitempty" json:"ScheduledTime,omitempty" yaml:"ScheduledTime,omitempty"` - Timeout *time.Duration `xml:"Timeout,omitempty" json:"Timeout,omitempty" yaml:"Timeout,omitempty"` + MessageId *string `xml:"MessageId,omitempty" json:"MessageId,omitempty" yaml:"MessageId,omitempty"` + OperationCode *string `xml:"OperationCode,omitempty" json:"OperationCode,omitempty" yaml:"OperationCode,omitempty"` + RequestXml *RequestXml `xml:"http://creditinfo.com/schemas/2012/09/MultiConnector RequestXml,omitempty" json:"RequestXml,omitempty" yaml:"RequestXml,omitempty"` + ScheduledTime *DateTime `xml:"ScheduledTime,omitempty" json:"ScheduledTime,omitempty" yaml:"ScheduledTime,omitempty"` + Timeout *Duration `xml:"Timeout,omitempty" json:"Timeout,omitempty" yaml:"Timeout,omitempty"` } type RequestXmlItem struct { @@ -68,5 +90,28 @@ type Cb5SearchParameters struct { type CustomFields struct { MobilePhone *string `xml:"MobilePhone,omitempty" json:"Timeout,omitempty" yaml:"Timeout,omitempty"` - DateOfBirth *string `xml:"DateOfBirth,omitempty" json:"DateOfBirth,omitempty" yaml:"DateOfBirth,omitempty"` + DateOfBirth *Date `xml:"DateOfBirth,omitempty" json:"DateOfBirth,omitempty" yaml:"DateOfBirth,omitempty"` +} + +const xsdDateFormat = "2006-01-02" + +type Date time.Time + +func (d Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + t := time.Time(d).Format(xsdDateFormat) + return e.EncodeElement(t, start) +} + +func (d *Date) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error { + var temp string + err := dec.DecodeElement(&temp, &start) + if err != nil { + return err + } + t, err := time.Parse(xsdDateFormat, temp) + if err != nil { + return err + } + *d = Date(t) + return nil } diff --git a/pkg/response/response.go b/pkg/response/response.go index 097e7ba..109c207 100644 --- a/pkg/response/response.go +++ b/pkg/response/response.go @@ -1,6 +1,9 @@ package response -import "time" +import ( + "encoding/xml" + "time" +) type MultiConnectorResponse struct { MessageId *string `xml:"MessageId,omitempty" json:"MessageId,omitempty" yaml:"MessageId,omitempty"` @@ -42,32 +45,49 @@ type ResultResponse struct { PolicyRules *PolicyRule `xml:"PolicyRules,omitempty"` KenCb5Data *KenCb5Data `xml:"KenCb5_data,omitempty"` Strategy *StrategyResponse `xml:"Strategy,omitempty"` + Extract *Extract `xml:"Extract,omitempty"` } type GeneralInformation struct { - SubjectIDNumber string `xml:"SubjectIDNumber,omitempty"` - RequestDate time.Time `xml:"RequestDate,omitempty"` - ReferenceNumber string `xml:"ReferenceNumber,omitempty"` - RecommendedDecision string `xml:"RecommendedDecision,omitempty"` - BrokenRules int32 `xml:"BrokenRules,omitempty"` - CreditLimit int32 `xml:"CreditLimit,omitempty"` + SubjectIDNumber *string `xml:"SubjectIDNumber,omitempty"` + RequestDate *time.Time `xml:"RequestDate,omitempty"` + ReferenceNumber *string `xml:"ReferenceNumber,omitempty"` + RecommendedDecision *string `xml:"RecommendedDecision,omitempty"` + BrokenRules *int32 `xml:"BrokenRules,omitempty"` + CreditLimit *int32 `xml:"CreditLimit,omitempty"` } type PersonalInformation struct { - FullName string `xml:"FullName,omitempty"` - DateOfBirth time.Time `xml:"DateOfBirth,omitempty"` - Age uint32 `xml:"Age,omitempty"` - Gender string `xml:"Gender,omitempty"` - MaritalStatus string `xml:"MaritalStatus,omitempty"` - EmploymentStatus string `xml:"EmploymentStatus,omitempty"` + FullName *string `xml:"FullName,omitempty"` + DateOfBirth *time.Time `xml:"DateOfBirth,omitempty"` + Age *int64 `xml:"Age,omitempty"` + Gender *string `xml:"Gender,omitempty"` + MaritalStatus *string `xml:"MaritalStatus,omitempty"` + NumberOfDependents *int64 `xml:"NumberOfDependents,omitempty"` + Education *string `xml:"Education,omitempty"` + EmploymentStatus *string `xml:"EmploymentStatus,omitempty"` + CompanyName *string `xml:"CompanyName,omitempty"` + DateOfEstablishment *string `xml:"DateOfEstablishment,omitempty"` + YearsInOperation *int64 `xml:"YearsInOperation,omitempty"` + LegalForm *string `xml:"LegalForm,omitempty"` } type ScoringAnalysis struct { - CIPScore int32 `xml:"CIPScore,omitempty"` - CIPRiskGrade string `xml:"CIPRiskGrade,omitempty"` - MobileScore int32 `xml:"MobileScore,omitempty"` - MobileScoreRiskGrade string `xml:"MobileScoreRiskGrade,omitempty"` - Conclusion string `xml:"Conclusion,omitempty"` - PolicyRules *PolicyRule `xml:"PolicyRules,omitempty"` + CIPScore *int64 `xml:"CIPScore,omitempty"` + CIPRiskGrade *string `xml:"CIPRiskGrade,omitempty"` + MobileScore *int64 `xml:"MobileScore,omitempty"` + MobileScoreRiskGrade *string `xml:"MobileScoreRiskGrade,omitempty"` + FactorsAffectingScores *FactorsAffectingScores `xml:"FactorsAffectingScores,omitempty"` + Conclusion *string `xml:"Conclusion,omitempty"` + PolicyRules *PolicyRule `xml:"PolicyRules,omitempty"` +} + +type FactorsAffectingScores struct { + Factor []Factor `xml:"Factor,omitempty"` +} + +type Factor struct { + Code string `xml:"code,attr,omitempty"` + Factor string `xml:"Factor,omitempty"` } type RuleItem struct { @@ -81,54 +101,116 @@ type PolicyRule struct { } type InquiriesAnalysis struct { - TotalLast7Days int32 `xml:"TotalLast7Days,omitempty"` - TotalLast1Month int32 `xml:"TotalLast1Month,omitempty"` - NonBankingLast1Month int32 `xml:"NonBankingLast1Month,omitempty"` + TotalLast7Days int64 `xml:"TotalLast7Days,omitempty"` + TotalLast1Month int64 `xml:"TotalLast1Month,omitempty"` + NonBankingLast1Month int64 `xml:"NonBankingLast1Month,omitempty"` PolicyRules *PolicyRule `xml:"PolicyRules,omitempty"` - Conclusion string `xml:"Conclusion,omitempty"` + Conclusion *string `xml:"Conclusion,omitempty"` } -type BankingData struct { - Positive int32 `xml:"Positive,omitempty"` - Negative int32 `xml:"Negative,omitempty"` - Balance float64 `xml:"Balance,omitempty"` - BalanceAtRisk int32 `xml:"BalanceAtRisk,omitempty"` +type CurrentContracts struct { + CurrentBanking *ContractsSummary `xml:"CurrentBanking,omitempty"` + CurrentNonBanking *ContractsSummary `xml:"CurrentNonBanking,omitempty"` + Total *ContractsSummary `xml:"Total,omitempty"` } -type CurrentContracts struct { - CurrentBanking *BankingData `xml:"CurrentBanking,omitempty"` - CurrentNonBanking *BankingData `xml:"CurrentNonBanking,omitempty"` - Total *BankingData `xml:"Total,omitempty"` +type ContractsSummary struct { + Positive int64 `xml:"Positive,omitempty"` + Negative int64 `xml:"Negative,omitempty"` + Balance float64 `xml:"Balance,omitempty"` + BalanceAtRisk float64 `xml:"BalanceAtRisk,omitempty"` } type PastDueInformation struct { - TotalCurrentPastDue int32 `xml:"TotalCurrentPastDue,omitempty"` - TotalCurrentDaysPastDue int32 `xml:"TotalCurrentDaysPastDue,omitempty"` - MonthsWithoutArrearsLast12Months int32 `xml:"MonthsWithoutArrearsLast12Months,omitempty"` - TotalMonthsWithHistoryLast12Months int32 `xml:"TotalMonthsWithHistoryLast12Months,omitempty"` - PercMonthsWithoutArrearsLast12Months int32 `xml:"PercMonthsWithoutArrearsLast12Months,omitempty"` + TotalCurrentPastDue *float64 `xml:"TotalCurrentPastDue,omitempty"` + TotalCurrentDaysPastDue *int64 `xml:"TotalCurrentDaysPastDue,omitempty"` + WorstCurrentPastDue *float64 `xml:"WorstCurrentPastDue,omitempty"` + WorstCurrentDaysPastDue *int64 `xml:"WorstCurrentDaysPastDue,omitempty"` + WorstPastDueLast12Months *float64 `xml:"WorstPastDueLast12Months,omitempty"` + WorstPastDueDaysLast12Months *int64 `xml:"WorstPastDueDaysLast12Months,omitempty"` + MonthsWithoutArrearsLast12Months *int64 `xml:"MonthsWithoutArrearsLast12Months,omitempty"` + TotalMonthsWithHistoryLast12Months *int64 `xml:"TotalMonthsWithHistoryLast12Months,omitempty"` + PercMonthsWithoutArrearsLast12Months *float64 `xml:"PercMonthsWithoutArrearsLast12Months,omitempty"` } type RepaymentInformation struct { - TotalMonthlyPayment int32 `xml:"TotalMonthlyPayment,omitempty"` - ClosedContracts int32 `xml:"ClosedContracts,omitempty"` + TotalMonthlyPayment *float64 `xml:"TotalMonthlyPayment,omitempty"` + NextContractMaturesInMonths *int64 `xml:"NextContractMaturesInMonths,omitempty"` + AllContractsMatureInMonths *int64 `xml:"AllContractsMatureInMonths,omitempty"` + LastContractOpened *Date `xml:"LastContractOpened,omitempty"` + LastContractClosed *Date `xml:"LastContractClosed,omitempty"` + ClosedContracts *int64 `xml:"ClosedContracts,omitempty"` +} + +const xsdDateFormat = "2006-01-02" + +type Date time.Time + +func (d Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + t := time.Time(d).Format(xsdDateFormat) + return e.EncodeElement(t, start) +} + +func (d *Date) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error { + var temp string + err := dec.DecodeElement(&temp, &start) + if err != nil { + return err + } + t, err := time.Parse(xsdDateFormat, temp) + if err != nil { + return err + } + *d = Date(t) + return nil } type KenCb5Data struct { - CIP *KenCb5DataCIP `xml:"CIP,omitempty"` - CIQ *KenCb5DataCIQ `xml:"CIQ,omitempty"` - ContractOverview *ContractOverview `xml:"ContractOverview,omitempty"` - ContractSummary *ContractSummary `xml:"ContractSummary,omitempty"` - Contracts *Contracts `xml:"Contracts,omitempty"` - CurrentRelations *CurrentRelations `xml:"CurrentRelations,omitempty"` - Dashboard *Dashboard `xml:"Dashboard,omitempty"` - Disputes *Disputes `xml:"Disputes,omitempty"` - Individual *Individual `xml:"Individual,omitempty"` - Inquiries *Inquiries `xml:"Inquiries,omitempty"` - Parameters *Parameters `xml:"Parameters,omitempty"` - PaymentIncidentList *PaymentIncidentList `xml:"PaymentIncidentList,omitempty"` - ReportInfo *ReportInfo `xml:"ReportInfo,omitempty"` - SubjectInfoHistory *SubjectInfoHistory `xml:"SubjectInfoHistory,omitempty"` + RawData []byte `xml:",innerxml"` +} + +type Extract struct { + NationalId *string `xml:"NationalId,omitempty"` + Date *time.Time `xml:"Date,omitempty"` + Decision *string `xml:"Decision,omitempty"` + CreditLimit *float64 `xml:"CreditLimit,omitempty"` + PotentialCreditLimit *float64 `xml:"PotentialCreditLimit,omitempty"` + MobileScore *float64 `xml:"MobileScore,omitempty"` + MobileGrade *string `xml:"MobileGrade,omitempty"` + CIPScore *float64 `xml:"CIPScore,omitempty"` + CIPGrade *string `xml:"CIPGrade,omitempty"` + SCR1Result *string `xml:"SCR1Result,omitempty"` + SCR1Parameter *string `xml:"SCR1Parameter,omitempty"` + SCR1Value *string `xml:"SCR1Value,omitempty"` + SCR3Result *string `xml:"SCR3Result,omitempty"` + SCR3Parameter *string `xml:"SCR3Parameter,omitempty"` + SCR3Value *string `xml:"SCR3Value,omitempty"` + INQ2Result *string `xml:"INQ2Result,omitempty"` + INQ2Parameter *float64 `xml:"INQ2Parameter,omitempty"` + INQ2Value *float64 `xml:"INQ2Value,omitempty"` + RSK2Result *string `xml:"RSK2Result,omitempty"` + RSK2Parameter *float64 `xml:"RSK2Parameter,omitempty"` + RSK2Value *float64 `xml:"RSK2Value,omitempty"` + RSK3Result *string `xml:"RSK3Result,omitempty"` + RSK3Parameter *float64 `xml:"RSK3Parameter,omitempty"` + RSK3Value *float64 `xml:"RSK3Value,omitempty"` + RSK4Result *string `xml:"RSK4Result,omitempty"` + RSK4Parameter *float64 `xml:"RSK4Parameter,omitempty"` + RSK4Value *float64 `xml:"RSK4Value,omitempty"` + RSK6Result *string `xml:"RSK6Result,omitempty"` + RSK6Parameter *float64 `xml:"RSK6Parameter,omitempty"` + RSK6Value *float64 `xml:"RSK6Value,omitempty"` + RSK7Result *string `xml:"RSK7Result,omitempty"` + RSK7Parameter *float64 `xml:"RSK7Parameter,omitempty"` + RSK7Value *float64 `xml:"RSK7Value,omitempty"` + RSK8Result *string `xml:"RSK8Result,omitempty"` + RSK8Parameter *float64 `xml:"RSK8Parameter,omitempty"` + RSK8Value *float64 `xml:"RSK8Value,omitempty"` + RSK11Result *string `xml:"RSK11Result,omitempty"` + RSK11Parameter *float64 `xml:"RSK11Parameter,omitempty"` + RSK11Value *float64 `xml:"RSK11Value,omitempty"` + RSK12Result *string `xml:"RSK12Result,omitempty"` + MobilePhone *string `xml:"MobilePhone,omitempty"` } type Record struct { @@ -340,7 +422,7 @@ type MainAddress struct { District string `xml:"District,omitempty"` Region string `xml:"Region,omitempty"` PlotNumber string `xml:"PlotNumber,omitempty"` - PostalCode int32 `xml:"PostalCode,omitempty"` + PostalCode string `xml:"PostalCode,omitempty"` Street string `xml:"Street,omitempty"` Town string `xml:"Town,omitempty"` } diff --git a/test/integration/client_test.go b/test/integration/client_test.go index 02d99d3..b4d7703 100644 --- a/test/integration/client_test.go +++ b/test/integration/client_test.go @@ -1,7 +1,9 @@ package unit import ( + "context" "testing" + "time" "github.com/devimteam/creditinfo/pkg/client" "github.com/l-vitaly/gounit" @@ -19,12 +21,11 @@ func TestGetIndividualReportSuccess(t *testing.T) { Endpoint: "https://endpoint.example.com", } - creditInfo := client.NewCreditInfoClient(params) + creditInfo := client.NewCreditInfoClient(params, nil, nil) nationalId := "12345678" phone := "25411111111" - response, err := creditInfo.GetIndividualReport(&nationalId, &phone, nil) - - t.Log(response.GeneralInformation.RecommendedDecision) + birthday := time.Now() + response, err := creditInfo.GetIndividualReport(context.Background(), &nationalId, &phone, &birthday) unit.AssertNil(err, "err not nil") unit.AssertEquals(response.Status, "ok", "status not equal 'ok'") @@ -42,10 +43,10 @@ func TestGetIndividualReportFail(t *testing.T) { Endpoint: "https://endpoint.example.com", } - creditInfo := client.NewCreditInfoClient(params) + creditInfo := client.NewCreditInfoClient(params, nil, nil) nationalId := "0" phone := "25411111111" - response, err := creditInfo.GetIndividualReport(&nationalId, &phone, nil) + response, err := creditInfo.GetIndividualReport(context.Background(), &nationalId, &phone, nil) unit.AssertNotNil(err, "err nil") unit.AssertNil(response, "err nil")