github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/caixa/caixa.go (about)

     1  package caixa
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"sync"
     7  
     8  	"github.com/mundipagg/boleto-api/metrics"
     9  
    10  	"github.com/PMoneda/flow"
    11  
    12  	"github.com/mundipagg/boleto-api/config"
    13  	"github.com/mundipagg/boleto-api/log"
    14  	"github.com/mundipagg/boleto-api/models"
    15  	"github.com/mundipagg/boleto-api/tmpl"
    16  	"github.com/mundipagg/boleto-api/util"
    17  	"github.com/mundipagg/boleto-api/validations"
    18  )
    19  
    20  var o = &sync.Once{}
    21  var m map[string]string
    22  
    23  type bankCaixa struct {
    24  	validate *models.Validator
    25  	log      *log.Log
    26  }
    27  
    28  func New() bankCaixa {
    29  	b := bankCaixa{
    30  		validate: models.NewValidator(),
    31  		log:      log.CreateLog(),
    32  	}
    33  	b.validate.Push(validations.ValidateAmount)
    34  	b.validate.Push(validations.ValidateExpireDate)
    35  	b.validate.Push(validations.ValidateBuyerDocumentNumber)
    36  	b.validate.Push(validations.ValidateRecipientDocumentNumber)
    37  	b.validate.Push(validations.ValidatePayeeGuarantorDocumentNumber)
    38  	b.validate.Push(validations.ValidatePayeeGuarantorName)
    39  	b.validate.Push(caixaValidateAgency)
    40  	b.validate.Push(validadeOurNumber)
    41  	b.validate.Push(caixaValidateBoletoType)
    42  	b.validate.Push(validations.ValidateInterest)
    43  	b.validate.Push(validations.ValidateFine)
    44  	return b
    45  }
    46  
    47  //Log retorna a referencia do log
    48  func (b bankCaixa) Log() *log.Log {
    49  	return b.log
    50  }
    51  func (b bankCaixa) RegisterBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
    52  
    53  	boleto.Title.BoletoType, boleto.Title.BoletoTypeCode = getBoletoType(boleto)
    54  
    55  	r := flow.NewFlow()
    56  	urlCaixa := config.Get().URLCaixaRegisterBoleto
    57  	from := getResponseCaixa()
    58  	to := getAPIResponseCaixa()
    59  
    60  	bod := r.From("message://?source=inline", boleto, getRequestCaixa(), tmpl.GetFuncMaps())
    61  	bod = bod.To("log://?type=request&format=xml&url="+urlCaixa, b.log)
    62  	duration := util.Duration(func() {
    63  		bod = bod.To(urlCaixa, map[string]string{"method": "POST", "insecureSkipVerify": "true", "timeout": config.Get().TimeoutDefault})
    64  	})
    65  	metrics.PushTimingMetric("caixa-register-time", duration.Seconds())
    66  	bod = bod.To("log://?type=response&format=xml&url="+urlCaixa, b.log)
    67  	ch := bod.Choice()
    68  	ch = ch.When(flow.Header("status").IsEqualTo("200"))
    69  	ch = ch.To("transform://?format=xml", from, to, tmpl.GetFuncMaps())
    70  	ch = ch.Otherwise()
    71  	ch = ch.To("log://?type=response&url="+urlCaixa, b.log).To("apierro://")
    72  
    73  	switch t := bod.GetBody().(type) {
    74  	case string:
    75  		response := util.ParseJSON(t, new(models.BoletoResponse)).(*models.BoletoResponse)
    76  		return *response, nil
    77  	case models.BoletoResponse:
    78  		return t, nil
    79  	}
    80  	return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Internal error")
    81  }
    82  func (b bankCaixa) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
    83  	errs := b.ValidateBoleto(boleto)
    84  	if len(errs) > 0 {
    85  		return models.BoletoResponse{Errors: errs}, nil
    86  	}
    87  
    88  	boleto.Title.OurNumber = b.FormatOurNumber(boleto.Title.OurNumber)
    89  
    90  	checkSum := b.getCheckSumCode(*boleto)
    91  
    92  	boleto.Authentication.AuthorizationToken = b.getAuthToken(checkSum)
    93  	return b.RegisterBoleto(boleto)
    94  }
    95  
    96  func (b bankCaixa) ValidateBoleto(boleto *models.BoletoRequest) models.Errors {
    97  	return models.Errors(b.validate.Assert(boleto))
    98  }
    99  
   100  func (b bankCaixa) FormatOurNumber(ourNumber uint) uint {
   101  
   102  	if ourNumber != 0 {
   103  		ourNumberFormatted := 14000000000000000 + ourNumber
   104  
   105  		return ourNumberFormatted
   106  	}
   107  
   108  	return ourNumber
   109  }
   110  
   111  //getCheckSumCode Código do Cedente (7 posições) + Nosso Número (17 posições) + Data de Vencimento (DDMMAAAA) + Valor (15 posições) + CPF/CNPJ (14 Posições)
   112  func (b bankCaixa) getCheckSumCode(boleto models.BoletoRequest) string {
   113  
   114  	return fmt.Sprintf("%07d%017d%s%015d%014s",
   115  		boleto.Agreement.AgreementNumber,
   116  		boleto.Title.OurNumber,
   117  		boleto.Title.ExpireDateTime.Format("02012006"),
   118  		boleto.Title.AmountInCents,
   119  		boleto.Recipient.Document.Number)
   120  }
   121  
   122  func (b bankCaixa) getAuthToken(info string) string {
   123  	return util.Sha256(info, "base64")
   124  }
   125  
   126  //GetBankNumber retorna o codigo do banco
   127  func (b bankCaixa) GetBankNumber() models.BankNumber {
   128  	return models.Caixa
   129  }
   130  
   131  func (b bankCaixa) GetBankNameIntegration() string {
   132  	return "Caixa"
   133  }
   134  
   135  func (b bankCaixa) GetErrorsMap() map[string]int {
   136  	return nil
   137  }
   138  
   139  func caixaBoletoTypes() map[string]string {
   140  	o.Do(func() {
   141  		m = make(map[string]string)
   142  
   143  		m["OUT"] = "99" //Duplicata Mercantil p/ Indicação
   144  	})
   145  	return m
   146  }
   147  
   148  func getBoletoType(boleto *models.BoletoRequest) (bt string, btc string) {
   149  	if len(boleto.Title.BoletoType) < 1 {
   150  		return "OUT", "99"
   151  	}
   152  	btm := caixaBoletoTypes()
   153  
   154  	if btm[strings.ToUpper(boleto.Title.BoletoType)] == "" {
   155  		return "OUT", "99"
   156  	}
   157  
   158  	return boleto.Title.BoletoType, btm[strings.ToUpper(boleto.Title.BoletoType)]
   159  }