package requestmodel import ( "fmt" "net/url" "time" "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/constants" dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types" ) type ( Balance struct { RawBalance int64 `json:"raw_balance"` CleanBalance int64 `json:"clean_balance"` } ) func (b *Balance) From(msg *dbtypes.Balance) *Balance { if msg == nil { return nil } res := &Balance{ RawBalance: msg.RawBalance, CleanBalance: msg.CleanBalance, } return res } type ( BalanceGetRequest struct { OwnerId string } BalanceGetResponse struct { Balance *Balance `json:"balance"` } ) func (r *BalanceGetRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } return nil } func (r *BalanceGetResponse) From(msg *dbtypes.BalanceGetResponse) *BalanceGetResponse { if msg == nil { return nil } return &BalanceGetResponse{ Balance: new(Balance).From(msg.Balance), } } type TransactionStatus string const ( TransactionStatusNew TransactionStatus = "new" TransactionStatusPending TransactionStatus = "pending" TransactionStatusApproved TransactionStatus = "approved" TransactionStatusRejected TransactionStatus = "rejected" ) func (s *TransactionStatus) NullString() *string { if s == nil { return nil } return (*string)(s) } type TransactionType string const ( TransactionTypeDeposit TransactionType = "deposit" TransactionTypeWithdrawal TransactionType = "withdrawal" ) func (t *TransactionType) NullString() *string { if t == nil { return nil } return (*string)(t) } type ( Transaction struct { Id string `json:"id"` OwnerInfo *TransactionOwnerInfo `json:"owner_info"` BankAccountInfo *BankAccountInfo `json:"bank_account_info"` Type TransactionType `json:"type"` Status TransactionStatus `json:"status"` Amount int64 `json:"amount"` Currency string `json:"currency"` CreatedAt string `json:"created_at"` Payload *TransactionPayload `json:"payload"` } BankAccountInfo struct { Id string `json:"id"` AccountNumber string `json:"account_number"` AccountName string `json:"account_name"` BankName string `json:"bank_name"` Bik string `json:"bik"` CorrespondentAccount string `json:"correspondent_account"` OwnerType string `json:"owner_type"` } TransactionOwnerInfo struct { Id string `json:"id"` Name string `json:"name"` } TransactionPayload struct { Origin string `json:"origin"` CompanyId string `json:"company_id"` CompanyName string `json:"company_name"` VacancyId string `json:"vacancy_id"` VacancyName string `json:"vacancy_name"` } ) func (t *TransactionOwnerInfo) From(msg *dbtypes.TransactionOwnerInfo) *TransactionOwnerInfo { if msg == nil { return nil } res := &TransactionOwnerInfo{ Id: msg.Id, Name: msg.Name, } return res } func (t *BankAccountInfo) From(msg *dbtypes.BankAccountInfo) *BankAccountInfo { if msg == nil { return nil } res := &BankAccountInfo{ Id: msg.Id, AccountNumber: msg.AccountNumber, AccountName: msg.AccountName, BankName: msg.BankName, Bik: msg.Bik, CorrespondentAccount: msg.CorrespondentAccount, OwnerType: msg.OwnerType, } return res } func (t *TransactionPayload) From(msg *dbtypes.TransactionPayload) *TransactionPayload { if msg == nil { return nil } res := &TransactionPayload{ Origin: msg.Origin, CompanyId: msg.CompanyId, CompanyName: msg.CompanyName, VacancyId: msg.VacancyId, VacancyName: msg.VacancyName, } return res } func (t *Transaction) From(msg *dbtypes.Transaction) *Transaction { if msg == nil { return nil } res := &Transaction{ Id: msg.Id, OwnerInfo: new(TransactionOwnerInfo).From(msg.OwnerInfo), BankAccountInfo: new(BankAccountInfo).From(msg.BankAccountInfo), Type: TransactionType(msg.Type), Status: TransactionStatus(msg.Status), Amount: msg.Amount, Currency: msg.Currency, CreatedAt: msg.CreatedAt.Format(time.RFC3339), Payload: new(TransactionPayload).From(msg.Payload), } return res } type ( TransactionListGetRequest struct { OwnerId string Filters *TransactionListFilters Page uint64 PageSize uint64 } TransactionListFilters struct { Type *TransactionType Status *TransactionStatus BankAccountId *string } TransactionListGetResponse struct { Transactions []Transaction `json:"transactions"` } ) func (r *TransactionListGetRequest) FromQuery(query url.Values) (*TransactionListGetRequest, error) { if query == nil { return nil, nil } var filters TransactionListFilters if val, ok := query["type"]; ok { typ := TransactionType(val[0]) filters.Type = &typ } if val, ok := query["status"]; ok { status := TransactionStatus(val[0]) filters.Status = &status } if val, ok := query["bank_account_id"]; ok { filters.BankAccountId = &val[0] } res := &TransactionListGetRequest{ Filters: &filters, Page: constants.DefaultPaginationPage, PageSize: constants.DefaultPaginationPageSize, } if val, ok := query["page"]; ok { intVal, err := parseUint64(val[0]) if err != nil { return nil, fmt.Errorf("invalid page param: %w", err) } res.Page = intVal } if val, ok := query["page_size"]; ok { intVal, err := parseUint64(val[0]) if err != nil { return nil, fmt.Errorf("invalid page_size param: %w", err) } res.PageSize = intVal } return res, nil } func (r *TransactionListGetRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } if r.Filters != nil { if r.Filters.Type != nil && !(*r.Filters.Type == TransactionTypeDeposit || *r.Filters.Type == TransactionTypeWithdrawal) { return fmt.Errorf("%w: invalid type: %v", ErrValidation, *r.Filters.Type) } if r.Filters.Status != nil && !(*r.Filters.Status == TransactionStatusNew || *r.Filters.Status == TransactionStatusPending || *r.Filters.Status == TransactionStatusApproved || *r.Filters.Status == TransactionStatusRejected) { return fmt.Errorf("%w: invalid status: %v", ErrValidation, *r.Filters.Status) } } return nil } func (r *TransactionListGetResponse) From(msg *dbtypes.TransactionListGetResponse) *TransactionListGetResponse { if msg == nil { return nil } res := &TransactionListGetResponse{ Transactions: make([]Transaction, len(msg.Transactions)), } for i, trans := range msg.Transactions { res.Transactions[i] = *new(Transaction).From(&trans) } return res } type ( TransactionCreateRequest struct { OwnerId string Amount int64 `json:"amount"` Currency string `json:"currency"` BankAccountId *string `json:"bank_account_id"` Payload *TransactionPayload `json:"payload"` RequestId string `json:"request_id"` } TransactionCreateResponse struct { Id string `json:"id"` } ) func (r *TransactionCreateRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.RequestId == "" { return fmt.Errorf("%w: RequestID is required", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } if r.Amount == 0 { return fmt.Errorf("%w: Amount is required", ErrValidation) } if r.Currency == "" { return fmt.Errorf("%w: Currency is required", ErrValidation) } return nil } func (r *TransactionCreateResponse) From(msg *dbtypes.TransactionCreateResponse) *TransactionCreateResponse { if msg == nil { return nil } return &TransactionCreateResponse{ Id: msg.Id, } } type ( BankAccount struct { Id string `json:"id"` OwnerId string `json:"owner_id"` AccountNumber string `json:"account_number"` AccountName string `json:"account_name"` BankName string `json:"bank_name"` Bik string `json:"bik"` CorrespondentAccount string `json:"correspondent_account"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } ) func (b *BankAccount) From(msg *dbtypes.BankAccount) *BankAccount { if msg == nil { return nil } res := &BankAccount{ Id: msg.Id, OwnerId: msg.OwnerId, AccountNumber: msg.AccountNumber, AccountName: msg.AccountName, BankName: msg.BankName, Bik: msg.Bik, CorrespondentAccount: msg.CorrespondentAccount, CreatedAt: msg.CreatedAt.Format(time.RFC3339), UpdatedAt: msg.UpdatedAt.Format(time.RFC3339), } return res } type ( BankAccountListGetRequest struct { OwnerId string } BankAccountListGetResponse struct { BankAccounts []BankAccount `json:"bank_accounts"` } ) func (r *BankAccountListGetRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } return nil } func (r *BankAccountListGetResponse) From(msg *dbtypes.BankAccountListGetResponse) *BankAccountListGetResponse { if msg == nil { return nil } res := &BankAccountListGetResponse{ BankAccounts: make([]BankAccount, len(msg.BankAccounts)), } for i, bankAccount := range msg.BankAccounts { res.BankAccounts[i] = *new(BankAccount).From(&bankAccount) } return res } type ( BankAccountCreateRequest struct { OwnerId string AccountNumber *string `json:"account_number"` AccountName *string `json:"account_name"` BankName *string `json:"bank_name"` Bik *string `json:"bik"` CorrespondentAccount *string `json:"correspondent_account"` IsPrimary *bool `json:"is_primary"` } BankAccountCreateResponse struct { Id string `json:"id"` } ) func (r *BankAccountCreateRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } return nil } func (r *BankAccountCreateResponse) From(msg *dbtypes.BankAccountCreateResponse) *BankAccountCreateResponse { if msg == nil { return nil } return &BankAccountCreateResponse{ Id: msg.Id, } } type ( BankAccountUpdateRequest struct { Id string OwnerId string AccountNumber *string `json:"account_number"` AccountName *string `json:"account_name"` BankName *string `json:"bank_name"` Bik *string `json:"bik"` CorrespondentAccount *string `json:"correspondent_account"` IsPrimary *bool `json:"is_primary"` } BankAccountUpdateResponse struct{} ) func (r *BankAccountUpdateRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.Id == "" { return fmt.Errorf("%w: ID is required", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } if r.AccountNumber == nil && r.AccountName == nil && r.BankName == nil && r.Bik == nil && r.CorrespondentAccount == nil { return fmt.Errorf("%w: nothing to update", ErrValidation) } return nil } type ( BankAccountDeleteRequest struct { Id string OwnerId string } BankAccountDeleteResponse struct{} ) func (r *BankAccountDeleteRequest) Validate() error { if r == nil { return fmt.Errorf("%w: request is nil", ErrValidation) } if r.Id == "" { return fmt.Errorf("%w: ID is required", ErrValidation) } if r.OwnerId == "" { return fmt.Errorf("%w: OwnerID is required", ErrValidation) } return nil }