adelosa / cardutil

Payment cards tools including ISO8583 parser and Mastercard IPM files processing
MIT License
25 stars 4 forks source link

CSV to IPM: Padding data #12

Closed kirk-daries closed 1 year ago

kirk-daries commented 1 year ago

Firstly, thank you for making this cardutil available.

When specifying data in csv, is the assumption that the data will be converted as is and not touched by cardutil? or Will cardUtil pad zeroes / blanks to fill up the field to the correct ISO length?

adelosa commented 1 year ago

Thats a great question. The answer lies in the code of course and depends on the type of field which is determined from the bit config.

For a fixed length field, the field will be padded. If its a string field, padding is spaces, and zeros if numeric. It will also be truncated if longer than the field length and not in a nice way for numbers so be careful.

        self.assertEqual(
            b'4564320012321122    ', _field_to_iso8583({'field_type': 'FIXED', 'field_length': 20}, "4564320012321122"))
        self.assertEqual(
            b'00000000000000001234', _field_to_iso8583(
                {'field_type': 'FIXED', 'field_python_type': 'int', 'field_length': 20}, 1234))
        self.assertEqual(
            b'123', _field_to_iso8583({'field_type': 'FIXED', 'field_python_type': 'int', 'field_length': 3}, 1234))
        self.assertEqual(
            b'01234', _field_to_iso8583({'field_type': 'FIXED', 'field_python_type': 'int', 'field_length': 5}, 1234))
        self.assertEqual(
            b'0000000000000123.432', _field_to_iso8583(
                {'field_type': 'FIXED', 'field_python_type': 'decimal', 'field_length': 20},
                decimal.Decimal("123.432")))
        self.assertEqual(
            b'140102151610', _field_to_iso8583(
                {'field_type': 'FIXED', 'field_python_type': 'datetime',
                 'field_length': 12, "field_date_format": "%y%m%d%H%M%S"},
                datetime.datetime(2014, 1, 2, 15, 16, 10)))

For LLVAR and LLLVAR variable length fields, it will just put the content in as is for the length provided.

        self.assertEqual(b'164564320012321122', _field_to_iso8583({'field_type': 'LLVAR'}, "4564320012321122"))
        self.assertEqual(
            b'164564320012321122', _field_to_iso8583({'field_type': 'LLVAR', 'field_length': 0}, "4564320012321122"))
        self.assertEqual(b'0164564320012321122', _field_to_iso8583({'field_type': 'LLLVAR'}, "4564320012321122"))
        self.assertEqual(
            b'0164564320012321122', _field_to_iso8583({'field_type': 'LLLVAR', 'field_length': 0}, "4564320012321122"))
        self.assertEqual(
            b'041234', _field_to_iso8583({'field_type': 'LLVAR', 'field_python_type': 'int'}, 1234))
        self.assertEqual(
            b'041234', _field_to_iso8583({'field_type': 'LLVAR', 'field_python_type': 'int'}, '1234'))
        # TODO Exception if field overflow
        self.assertEqual(
            b'041234', _field_to_iso8583({'field_type': 'LLVAR', 'field_python_type': 'int', 'field_length': 0}, 1234))

Let me know if this answers your question, or if you have a situation where it is behaving different than this.

kirk-daries commented 1 year ago

So when creating the input file, I just need to manage the padding of the variable length fields (as per your response)... and cardUtil will take care of the fixed length fields.

:) thank you

kirk-daries commented 1 year ago

Reading further:

It would seem that cardUtil takes care of most of the grunt work for me.

I'll leave this comment as confirmation of my understanding:

Whenever a PDS field contains any 'sub fields', since i'm specifying the full PDS value in the CSV file (no custom field definitions to break out subfields i.e. as you've done with DE43), i'll need to format each subfield's data correctly to fully make up the PDS field value (see PDS0052, PDS0105, etc)

adelosa commented 1 year ago

If you are doing csv to ISO then for de43 you need to provide DE43 rather than the components. For PDS fields you can either only provide PDS or DE fields that contain PDS but not both. See https://adelosa.github.io/cardutil/cli.html#mastercard-ipm-tools