github.com/moov-io/imagecashletter@v0.10.1/routingNumberSummary.go (about) 1 // Copyright 2020 The Moov Authors 2 // Use of this source code is governed by an Apache License 3 // license that can be found in the LICENSE file. 4 5 package imagecashletter 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "strings" 11 "unicode/utf8" 12 ) 13 14 // RoutingNumberSummary Record 15 type RoutingNumberSummary struct { 16 // ID is a client defined string used as a reference to this record. 17 ID string `json:"id"` 18 // RecordType defines the type of record. 19 recordType string 20 // CashLetterRoutingNumber 21 CashLetterRoutingNumber string `json:"cashLetterRoutingNumber"` 22 // RoutingNumberTotalAmount 23 RoutingNumberTotalAmount int `json:"routingNumberTotalAmount"` 24 // RoutingNumberItemCount 25 RoutingNumberItemCount int `json:"routingNumberItemCount"` 26 // UserField identifies a field used at the discretion of users of the standard. 27 UserField string `json:"userField"` 28 // reserved is a field reserved for future use. Reserved should be blank. 29 reserved string 30 // validator is composed for imagecashletter data validation 31 validator 32 // converters is composed for imagecashletter to golang Converters 33 converters 34 } 35 36 // NewRoutingNumberSummary returns a new RoutingNumberSummary with default values for non exported fields 37 func NewRoutingNumberSummary() *RoutingNumberSummary { 38 rns := &RoutingNumberSummary{} 39 rns.setRecordType() 40 return rns 41 } 42 43 func (rns *RoutingNumberSummary) setRecordType() { 44 if rns == nil { 45 return 46 } 47 rns.recordType = "85" 48 } 49 50 // Parse takes the input record string and parses the ImageViewDetail values 51 func (rns *RoutingNumberSummary) Parse(record string) { 52 if utf8.RuneCountInString(record) < 55 { 53 return // line too short 54 } 55 56 // Character position 1-2, Always "85" 57 rns.setRecordType() 58 // 03-11 59 rns.CashLetterRoutingNumber = rns.parseStringField(record[2:11]) 60 // 12-25 61 rns.RoutingNumberTotalAmount = rns.parseNumField(record[11:25]) 62 // 26-31 63 rns.RoutingNumberItemCount = rns.parseNumField(record[26:31]) 64 // 32-55 65 rns.UserField = rns.parseStringField(record[31:55]) 66 // 56-80 67 rns.reserved = " " 68 } 69 70 func (rns *RoutingNumberSummary) UnmarshalJSON(data []byte) error { 71 type Alias RoutingNumberSummary 72 aux := struct { 73 *Alias 74 }{ 75 (*Alias)(rns), 76 } 77 if err := json.Unmarshal(data, &aux); err != nil { 78 return err 79 } 80 rns.setRecordType() 81 return nil 82 } 83 84 // String writes the ImageViewDetail struct to a string. 85 func (rns *RoutingNumberSummary) String() string { 86 if rns == nil { 87 return "" 88 } 89 90 var buf strings.Builder 91 buf.Grow(80) 92 buf.WriteString(rns.recordType) 93 buf.WriteString(rns.CashLetterRoutingNumberField()) 94 buf.WriteString(rns.RoutingNumberTotalAmountField()) 95 buf.WriteString(rns.RoutingNumberItemCountField()) 96 buf.WriteString(rns.UserFieldField()) 97 buf.WriteString(rns.reservedField()) 98 return buf.String() 99 } 100 101 // Validate performs imagecashletter format rule checks on the record and returns an error if not Validated 102 // The first error encountered is returned and stops the parsing. 103 func (rns *RoutingNumberSummary) Validate() error { 104 if err := rns.fieldInclusion(); err != nil { 105 return err 106 } 107 if rns.recordType != "85" { 108 msg := fmt.Sprintf(msgRecordType, 85) 109 return &FieldError{FieldName: "recordType", Value: rns.recordType, Msg: msg} 110 } 111 if err := rns.isAlphanumericSpecial(rns.UserField); err != nil { 112 return &FieldError{FieldName: "UserField", 113 Value: rns.UserField, Msg: err.Error()} 114 } 115 return nil 116 } 117 118 // fieldInclusion validate mandatory fields are not default values. If fields are 119 // invalid the Electronic Exchange will be returned. 120 func (rns *RoutingNumberSummary) fieldInclusion() error { 121 if rns.recordType == "" { 122 return &FieldError{FieldName: "recordType", 123 Value: rns.recordType, 124 Msg: msgFieldInclusion + ", did you use RoutingNumberSummary()?"} 125 } 126 if rns.CashLetterRoutingNumber == "" { 127 return &FieldError{FieldName: "CashLetterRoutingNumber", 128 Value: rns.CashLetterRoutingNumber, 129 Msg: msgFieldInclusion + ", did you use RoutingNumberSummary()?"} 130 } 131 return nil 132 } 133 134 // CashLetterRoutingNumberField gets the CashLetterRoutingNumber routing number field 135 func (rns *RoutingNumberSummary) CashLetterRoutingNumberField() string { 136 return rns.stringField(rns.CashLetterRoutingNumber, 9) 137 } 138 139 // RoutingNumberTotalAmountField gets a string of RoutingNumberTotalAmount zero padded 140 func (rns *RoutingNumberSummary) RoutingNumberTotalAmountField() string { 141 return rns.numericField(rns.RoutingNumberTotalAmount, 14) 142 } 143 144 // RoutingNumberItemCountField gets a string of RoutingNumberItemCount zero padded 145 func (rns *RoutingNumberSummary) RoutingNumberItemCountField() string { 146 return rns.numericField(rns.RoutingNumberItemCount, 6) 147 } 148 149 // UserFieldField gets the UserField field 150 func (rns *RoutingNumberSummary) UserFieldField() string { 151 return rns.alphaField(rns.UserField, 24) 152 } 153 154 // reservedField gets the reserved field 155 func (rns *RoutingNumberSummary) reservedField() string { 156 return rns.alphaField(rns.reserved, 25) 157 }