society-self-service/sstreasury/aba.py

66 lines
3.7 KiB
Python
Raw Normal View History

2020-01-05 17:54:09 +11:00
# Society Self-Service
# Copyright © 2018–2020 Yingtong Li (RunasSudo)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# https://www.brad-smith.info/blog/archives/405
# https://www.cemtexaba.com/aba-format/cemtex-aba-file-format-details
# https://ddkonline.blogspot.com/2009/01/aba-bank-payment-file-format-australian.html
def write_descriptive(f, reel_seq=1, bank_name='', user_name='', bank_code=0, description='', date=None):
if reel_seq < 0 or reel_seq > 99 or len(bank_name) > 3 or len(user_name) > 26 or bank_code < 0 or bank_code > 999999 or len(description) > 12:
raise Exception('Invalid ABA data')
f.write(b'0') # Record Type 0
f.write(b' ' * 17) # Blank
f.write('{:02}'.format(reel_seq).encode('ascii')) # Reel Sequence Number
f.write('{: <3}'.format(bank_name).encode('ascii')) # Financial Institution abbreviation
f.write(b' ' * 7) # Blank
f.write('{: <26}'.format(user_name).encode('ascii')) # User Preferred Specification
f.write('{:06}'.format(bank_code).encode('ascii')) # User Identification Number
f.write('{: <12}'.format(description).encode('ascii')) # Description
f.write(date.strftime('%d%m%y').encode('ascii')) # Date
f.write(b' ' * 40) # Blank
f.write(b'\r\n')
def write_detail(f, dest_bsb='', dest_account='', indicator=' ', transaction_code=53, cents=0, dest_name='', reference='', src_bsb='', src_account='', src_name='', tax_withheld=0):
if len(dest_bsb.replace('-', '')) != 6 or len(dest_account) > 9 or len(indicator) != 1 or transaction_code < 0 or transaction_code > 99 or len(dest_name) > 32 or len(reference) > 18 or len(src_bsb.replace('-', '')) != 6 or len(src_account) > 9 or len(src_name) > 16:
raise Exception('Invalid ABA data')
f.write(b'1') # Record Type 1
f.write('{}-{}'.format(dest_bsb[:3], dest_bsb[-3:]).encode('ascii')) # BSB
f.write('{: >9}'.format(dest_account).encode('ascii')) # Account Number
f.write(indicator.encode('ascii')) # Indicator
f.write('{:02}'.format(transaction_code).encode('ascii')) # Transaction Code
f.write('{:010}'.format(cents).encode('ascii')) # Amount
f.write('{: <32}'.format(dest_name).encode('ascii')) # Title of Account
f.write('{: <18}'.format(reference).encode('ascii')) # Lodgement Reference
f.write('{}-{}'.format(src_bsb[:3], src_bsb[-3:]).encode('ascii')) # Trace BSB
f.write('{: >9}'.format(src_account).encode('ascii')) # Trace Account Number
f.write('{: <16}'.format(src_name).encode('ascii')) # Name of Remitter
f.write('{:08}'.format(tax_withheld).encode('ascii')) # Amount of Withholding Tax
f.write(b'\r\n')
def write_total(f, credit_cents=0, num_detail_records=0):
f.write(b'7') # Record Type 7
f.write(b'999-999') # BSB Format Filler
f.write(b' ' * 12) # Blank
f.write('{:010}'.format(credit_cents).encode('ascii')) # File (User) Net Total Amount
f.write('{:010}'.format(credit_cents).encode('ascii')) # File (User) Credit Total Amount
f.write(b'0' * 10) # File (User) Debit Total Amount
f.write(b' ' * 24) # Blank
f.write('{:06}'.format(num_detail_records).encode('ascii')) # File (user) count of Records Type 1
f.write(b' ' * 40) # Blank
f.write(b'\r\n')