Add header record using Fixy and DryRB Validation gems#5
Add header record using Fixy and DryRB Validation gems#5SmileAndCompile merged 22 commits intomainfrom
Conversation
lib/mt9/header_record.rb
Outdated
| attr_reader :file_type, :account_number, :due_date, :client_short_name | ||
|
|
||
| field :file_type, 2, "1-2", :file_type | ||
| field :account_number, 15, "3-17", :account_number |
There was a problem hiding this comment.
should we split this to
- bank number 2
- branch number 4
- account number 7
or at least
- bank + branch number 6
- account number 7
There was a problem hiding this comment.
If we do want to split up the account number, we'll have to split out the suffix as well. However for ease of use I think we should keep the branch/branch number, unique number and suffix together, as that is how most New Zealanders use it, and I don't see much benefit in doing so (apart from keeping close relation to the fields in the ASB docs)
There was a problem hiding this comment.
ah, I dont hv experience of dealing wih NZ bank transfer
coz in our split app's bank_account model, we have branch_code and account_number (used as BSB and A/C), so I would imagine we could do sth similar for NZ
if we decide to use one field for all related account number in the gem, then we need to figure out the mapping in our adapter
There was a problem hiding this comment.
Yeah I think we'll figure out that mapping in the app. It should be pretty simple (just concatenating the two numbers together). We'll already be doing the reverse (splitting the branch_code and account_number from a larger account number) as we've decided on only showing the account number in the UI/API when in NZ
chris-teague
left a comment
There was a problem hiding this comment.
A few thoughts:
- Fixy seems to suit what we're doing well
- It's a small & relatively inactive gem, which concerns me a little
- but, it's codebase is small, easy enough to follow & something we could easily extend / support if needed
- I'm not sure I like using Fixy formatters for validations - it's going to get clunky & have a lot of repetition once we add the DetailRecords too.
- To that end - I'm thinking that we should probably use DryRB Validations in the initializer (i.e. have a Contract for HeaderRecord, DetailRecord etc, if it isn't met, return the error object)
PR Updated to reflect new approach. I like this a lot more compared to just using Fixy. I've raised a validation error for when the data is invalid so it fails fast. We still need to figure out how we can share the account number schema/rule between the header and detail record. |
0649bf3 to
07a98a1
Compare
ff43a0f to
7fd5cd1
Compare
| Enabled: false | ||
|
|
||
| Layout/LineLength: | ||
| Max: 120 |
There was a problem hiding this comment.
we should probs copy the current rubocop yml we have in zfp and split(main zepto) repos
| AllCops: | ||
| NewCops: enable | ||
| TargetRubyVersion: 2.6 | ||
| TargetRubyVersion: 2.7 |
There was a problem hiding this comment.
This was the version specified in the gemspec, and I think it's best if the gem can support as wide a range of Ruby versions as possible (albeit support for 2.7 will be dropped in 10 months)
| field :filler109, 109, "52-160", :alphanumeric | ||
|
|
||
| field_value :filler5, SPACE * 5 | ||
| field_value :filler109, SPACE * 109 |
There was a problem hiding this comment.
lots of "magic numbers" here. I would try to name them here and make them constants. i.e. 109 could be SOMETHING_FILLER_COUNT / MAYBE_FILLER_PADDING or something so when we use them, it kinda sort of gives us context what it is (and that we should not be able to change it easily):
| field_value :filler109, SPACE * 109 | |
| field_value :filler109, SPACE * MAYBE_FILLER_PADDING |
chris-teague
left a comment
There was a problem hiding this comment.
Great work @zachingle! Just a couple of small suggestions / things to look into, but nothing that should block merging from my perspective - we can always raise a seperate PR if needed. 🔥
|
|
||
| rule(:account_number).validate(:is_account_number?) | ||
|
|
||
| rule(:due_date) do |
There was a problem hiding this comment.
I'm thinking we should also have a check to see whether a valid due date has been supplied.
There was a problem hiding this comment.
In that case, to simplify validation we could change due_date to receive a Date object instead of a string
| required(:file_type).filled(:string, included_in?: MT9::Values::FILE_TYPES) | ||
| required(:account_number).filled(:string) | ||
| required(:due_date).filled(:string) | ||
| optional(:client_short_name).value(:string, size?: 0..20) |
There was a problem hiding this comment.
I'm wondering whether we want to make this required, even though this isn't strictly the case when looking at the docs? It'd be good to know whether it's a big no-no to send a file without a short name & add a little protection if so
There was a problem hiding this comment.
Might be a @henripryde400 question to ask to the ASB guys
| module Validators | ||
| class BaseContract < Dry::Validation::Contract | ||
| register_macro(:is_account_number?) do | ||
| key.failure("must be 15 or 16 numeric characters") unless /^(\d{15}|\d{16})$/.match(value) |
There was a problem hiding this comment.
| key.failure("must be 15 or 16 numeric characters") unless /^(\d{15}|\d{16})$/.match(value) | |
| key.failure("must be 15 or 16 numeric characters") unless /^(\d{15,16})$/.match(value) |
nitpick, but shorter :) See: https://rubular.com/r/PAUYXnL7M2LDDv
| rule(:account_number).validate(:is_account_number?) | ||
|
|
||
| rule(:due_date) do | ||
| key.failure("must be 6 or 8 numeric characters") unless /^(\d{6}|\d{8})$/.match(value) |
There was a problem hiding this comment.
| key.failure("must be 6 or 8 numeric characters") unless /^(\d{6}|\d{8})$/.match(value) | |
| key.failure("must be 6 or 8 numeric characters") unless /^(\d{6,8}$/.match(value) |
There was a problem hiding this comment.
This notation is used for a range (i.e 6 to 8 digits). Here we want either 6 or 8, but not 7 digits
| RESERVED_BANK_CODES = %w[99].freeze | ||
|
|
||
| DIRECT_CREDIT = "12" | ||
| DIRECT_DEBIT = "20" |
There was a problem hiding this comment.
curious why they are strings and not integers?
There was a problem hiding this comment.
Thought process here was that we don't perform any integer-like operations on these numbers and these are identifiers, just like the account number, and so are better represented as strings
This PR uses both the fixy and dry-validation gems to generate and validate the header record. dry-validation is used on the header record's initialisation to validate the data coming into the object. We then use fixy to format the data to ASB specs.
Specs for the MT9 file format can be found on page 42 and 62 of the ASB File Formats Technical Guide or the MT9 File Formats found in our GDrive
A macro is used for the account number so the rules can be shared with the detail record.
Seems like there is an issue for fixy subclass records not properly inheriting the line ending and record fields: OmarSkalli/fixy#25 but I don't think this is a big blocker. It'll just mean duplicating the
set_line_endingline across the records.