From 2e909d2f52f43f15e4ef89327be9b9a7d30cd4d9 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Tue, 31 Jul 2012 23:16:16 -0700 Subject: [PATCH] initial commit --- .gitignore | 6 + Changes | 4 + MANIFEST | 8 + Makefile.PL | 22 ++ Makefile.old | 798 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README | 55 ++++ TD_EFT.pm | 414 +++++++++++++++++++++++++++++ ignore.txt | 13 + t/00-load.t | 9 + t/boilerplate.t | 56 ++++ t/manifest.t | 13 + t/pod.t | 12 + 12 files changed, 1410 insertions(+) create mode 100644 .gitignore create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 Makefile.old create mode 100644 README create mode 100644 TD_EFT.pm create mode 100644 ignore.txt create mode 100644 t/00-load.t create mode 100644 t/boilerplate.t create mode 100644 t/manifest.t create mode 100644 t/pod.t diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9788afa --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +blib/ +*.sw? +Makefile +Makefile.old +MYMETA.yml +pm_to_blib diff --git a/Changes b/Changes new file mode 100644 index 0000000..3daf8d4 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +Revision history for Business-BatchPayment-TD_EFT + +0.01 unreleased + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..16de07f --- /dev/null +++ b/MANIFEST @@ -0,0 +1,8 @@ +Changes +TD_EFT.pm +Makefile.PL +MANIFEST This list of files +README +t/00-load.t +t/manifest.t +t/pod.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..e895b0d --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,22 @@ +use 5.006; +use strict; +use warnings; +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'Business::BatchPayment::TD_EFT', + AUTHOR => q{Mark Wells }, + VERSION_FROM => 'TD_EFT.pm', + ABSTRACT_FROM => 'TD_EFT.pm', + ($ExtUtils::MakeMaker::VERSION >= 6.3002 + ? ('LICENSE'=> 'perl') + : ()), + PL_FILES => {}, + PREREQ_PM => { + 'Business::BatchPayment' => 0, + 'Moose' => 2.000, + 'Test::More' => 0, + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'Business-BatchPayment-TD_EFT-*' }, +); diff --git a/Makefile.old b/Makefile.old new file mode 100644 index 0000000..5d4a66b --- /dev/null +++ b/Makefile.old @@ -0,0 +1,798 @@ +# This Makefile is for the Business::BatchPayment::TD_EFT extension to perl. +# +# It was generated automatically by MakeMaker version +# 6.57_05 (Revision: 65705) from the contents of +# Makefile.PL. Don't edit this file, edit Makefile.PL instead. +# +# ANY CHANGES MADE HERE WILL BE LOST! +# +# MakeMaker ARGV: () +# + +# MakeMaker Parameters: + +# ABSTRACT_FROM => q[TD_EFT.pm] +# AUTHOR => [q[Mark Wells ]] +# BUILD_REQUIRES => { } +# LICENSE => q[perl] +# NAME => q[Business::BatchPayment::TD_EFT] +# PL_FILES => { } +# PREREQ_PM => { Test::More=>q[0], Business::BatchPayment=>q[0], Moose=>q[2] } +# VERSION_FROM => q[TD_EFT.pm] +# clean => { FILES=>q[Business-BatchPayment-TD_EFT-*] } +# dist => { COMPRESS=>q[gzip -9f], SUFFIX=>q[gz] } + +# --- MakeMaker post_initialize section: + + +# --- MakeMaker const_config section: + +# These definitions are from config.sh (via /usr/lib/perl/5.14/Config.pm). +# They may have been overridden via Makefile.PL or on the command line. +AR = ar +CC = cc +CCCDLFLAGS = -fPIC +CCDLFLAGS = -Wl,-E +DLEXT = so +DLSRC = dl_dlopen.xs +EXE_EXT = +FULL_AR = /usr/bin/ar +LD = cc +LDDLFLAGS = -shared -L/usr/local/lib -fstack-protector +LDFLAGS = -fstack-protector -L/usr/local/lib +LIBC = +LIB_EXT = .a +OBJ_EXT = .o +OSNAME = linux +OSVERS = 2.6.32-5-686-bigmem +RANLIB = : +SITELIBEXP = /usr/local/share/perl/5.14.2 +SITEARCHEXP = /usr/local/lib/perl/5.14.2 +SO = so +VENDORARCHEXP = /usr/lib/perl5 +VENDORLIBEXP = /usr/share/perl5 + + +# --- MakeMaker constants section: +AR_STATIC_ARGS = cr +DIRFILESEP = / +DFSEP = $(DIRFILESEP) +NAME = Business::BatchPayment::TD_EFT +NAME_SYM = Business_BatchPayment_TD_EFT +VERSION = 0.01 +VERSION_MACRO = VERSION +VERSION_SYM = 0_01 +DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\" +XS_VERSION = 0.01 +XS_VERSION_MACRO = XS_VERSION +XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\" +INST_ARCHLIB = blib/arch +INST_SCRIPT = blib/script +INST_BIN = blib/bin +INST_LIB = blib/lib +INST_MAN1DIR = blib/man1 +INST_MAN3DIR = blib/man3 +MAN1EXT = 1p +MAN3EXT = 3pm +INSTALLDIRS = site +DESTDIR = +PREFIX = /usr +PERLPREFIX = $(PREFIX) +SITEPREFIX = $(PREFIX)/local +VENDORPREFIX = $(PREFIX) +INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.14 +DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB) +INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.14.2 +DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB) +INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5 +DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB) +INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.14 +DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB) +INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.14.2 +DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH) +INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5 +DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH) +INSTALLBIN = $(PERLPREFIX)/bin +DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN) +INSTALLSITEBIN = $(SITEPREFIX)/bin +DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN) +INSTALLVENDORBIN = $(VENDORPREFIX)/bin +DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN) +INSTALLSCRIPT = $(PERLPREFIX)/bin +DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT) +INSTALLSITESCRIPT = $(SITEPREFIX)/bin +DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT) +INSTALLVENDORSCRIPT = $(VENDORPREFIX)/bin +DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT) +INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1 +DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR) +INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1 +DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR) +INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1 +DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR) +INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3 +DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR) +INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3 +DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR) +INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3 +DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR) +PERL_LIB = /usr/share/perl/5.14 +PERL_ARCHLIB = /usr/lib/perl/5.14 +LIBPERL_A = libperl.a +FIRST_MAKEFILE = Makefile +MAKEFILE_OLD = Makefile.old +MAKE_APERL_FILE = Makefile.aperl +PERLMAINCC = $(CC) +PERL_INC = /usr/lib/perl/5.14/CORE +PERL = /usr/bin/perl +FULLPERL = /usr/bin/perl +ABSPERL = $(PERL) +PERLRUN = $(PERL) +FULLPERLRUN = $(FULLPERL) +ABSPERLRUN = $(ABSPERL) +PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +PERL_CORE = 0 +PERM_DIR = 755 +PERM_RW = 644 +PERM_RWX = 755 + +MAKEMAKER = /usr/share/perl/5.14/ExtUtils/MakeMaker.pm +MM_VERSION = 6.57_05 +MM_REVISION = 65705 + +# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). +# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) +# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) +# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. +MAKE = make +FULLEXT = Business/BatchPayment/TD_EFT +BASEEXT = TD_EFT +PARENT_NAME = Business::BatchPayment +DLBASE = $(BASEEXT) +VERSION_FROM = TD_EFT.pm +OBJECT = +LDFROM = $(OBJECT) +LINKTYPE = dynamic +BOOTDEP = + +# Handy lists of source code files: +XS_FILES = +C_FILES = +O_FILES = +H_FILES = +MAN1PODS = +MAN3PODS = TD_EFT.pm + +# Where is the Config information that we are using/depend on +CONFIGDEP = $(PERL_ARCHLIB)$(DFSEP)Config.pm $(PERL_INC)$(DFSEP)config.h + +# Where to build things +INST_LIBDIR = $(INST_LIB)/Business/BatchPayment +INST_ARCHLIBDIR = $(INST_ARCHLIB)/Business/BatchPayment + +INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT) +INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT) + +INST_STATIC = +INST_DYNAMIC = +INST_BOOT = + +# Extra linker info +EXPORT_LIST = +PERL_ARCHIVE = +PERL_ARCHIVE_AFTER = + + +TO_INST_PM = TD_EFT.pm + +PM_TO_BLIB = TD_EFT.pm \ + $(INST_LIB)/Business/BatchPayment/TD_EFT.pm + + +# --- MakeMaker platform_constants section: +MM_Unix_VERSION = 6.57_05 +PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc + + +# --- MakeMaker tool_autosplit section: +# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto +AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)' -- + + + +# --- MakeMaker tool_xsubpp section: + + +# --- MakeMaker tools_other section: +SHELL = /bin/sh +CHMOD = chmod +CP = cp +MV = mv +NOOP = $(TRUE) +NOECHO = @ +RM_F = rm -f +RM_RF = rm -rf +TEST_F = test -f +TOUCH = touch +UMASK_NULL = umask 0 +DEV_NULL = > /dev/null 2>&1 +MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' -- +EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' -- +FALSE = false +TRUE = true +ECHO = echo +ECHO_N = echo -n +UNINST = 0 +VERBINST = 0 +MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' -- +DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' -- +UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' -- +WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' -- +MACROSTART = +MACROEND = +USEMAKEFILE = -f +FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' -- + + +# --- MakeMaker makemakerdflt section: +makemakerdflt : all + $(NOECHO) $(NOOP) + + +# --- MakeMaker dist section: +TAR = tar +TARFLAGS = cvf +ZIP = zip +ZIPFLAGS = -r +COMPRESS = gzip -9f +SUFFIX = gz +SHAR = shar +PREOP = $(NOECHO) $(NOOP) +POSTOP = $(NOECHO) $(NOOP) +TO_UNIX = $(NOECHO) $(NOOP) +CI = ci -u +RCS_LABEL = rcs -Nv$(VERSION_SYM): -q +DIST_CP = best +DIST_DEFAULT = tardist +DISTNAME = Business-BatchPayment-TD_EFT +DISTVNAME = Business-BatchPayment-TD_EFT-0.01 + + +# --- MakeMaker macro section: + + +# --- MakeMaker depend section: + + +# --- MakeMaker cflags section: + + +# --- MakeMaker const_loadlibs section: + + +# --- MakeMaker const_cccmd section: + + +# --- MakeMaker post_constants section: + + +# --- MakeMaker pasthru section: + +PASTHRU = LIBPERL_A="$(LIBPERL_A)"\ + LINKTYPE="$(LINKTYPE)"\ + LD="$(LD)"\ + PREFIX="$(PREFIX)" + + +# --- MakeMaker special_targets section: +.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT) + +.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir + + + +# --- MakeMaker c_o section: + + +# --- MakeMaker xs_c section: + + +# --- MakeMaker xs_o section: + + +# --- MakeMaker top_targets section: +all :: pure_all manifypods + $(NOECHO) $(NOOP) + + +pure_all :: config pm_to_blib subdirs linkext + $(NOECHO) $(NOOP) + +subdirs :: $(MYEXTLIB) + $(NOECHO) $(NOOP) + +config :: $(FIRST_MAKEFILE) blibdirs + $(NOECHO) $(NOOP) + +help : + perldoc ExtUtils::MakeMaker + + +# --- MakeMaker blibdirs section: +blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists + $(NOECHO) $(NOOP) + +# Backwards compat with 6.18 through 6.25 +blibdirs.ts : blibdirs + $(NOECHO) $(NOOP) + +$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_LIBDIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR) + $(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists + +$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_ARCHLIB) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB) + $(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists + +$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_AUTODIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR) + $(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists + +$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR) + $(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists + +$(INST_BIN)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_BIN) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN) + $(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists + +$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_SCRIPT) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT) + $(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists + +$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_MAN1DIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR) + $(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists + +$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_MAN3DIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR) + $(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists + + + +# --- MakeMaker linkext section: + +linkext :: $(LINKTYPE) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dlsyms section: + + +# --- MakeMaker dynamic section: + +dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dynamic_bs section: + +BOOTSTRAP = + + +# --- MakeMaker dynamic_lib section: + + +# --- MakeMaker static section: + +## $(INST_PM) has been moved to the all: target. +## It remains here for awhile to allow for old usage: "make static" +static :: $(FIRST_MAKEFILE) $(INST_STATIC) + $(NOECHO) $(NOOP) + + +# --- MakeMaker static_lib section: + + +# --- MakeMaker manifypods section: + +POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--" +POD2MAN = $(POD2MAN_EXE) + + +manifypods : pure_all \ + TD_EFT.pm + $(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) \ + TD_EFT.pm $(INST_MAN3DIR)/Business::BatchPayment::TD_EFT.$(MAN3EXT) + + + + +# --- MakeMaker processPL section: + + +# --- MakeMaker installbin section: + + +# --- MakeMaker subdirs section: + +# none + +# --- MakeMaker clean_subdirs section: +clean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker clean section: + +# Delete temporary files but do not touch installed files. We don't delete +# the Makefile here so a later make realclean still has a makefile to use. + +clean :: clean_subdirs + - $(RM_F) \ + *$(LIB_EXT) core \ + core.[0-9] $(INST_ARCHAUTODIR)/extralibs.all \ + core.[0-9][0-9] $(BASEEXT).bso \ + pm_to_blib.ts core.[0-9][0-9][0-9][0-9] \ + MYMETA.yml $(BASEEXT).x \ + $(BOOTSTRAP) perl$(EXE_EXT) \ + tmon.out *$(OBJ_EXT) \ + pm_to_blib $(INST_ARCHAUTODIR)/extralibs.ld \ + blibdirs.ts core.[0-9][0-9][0-9][0-9][0-9] \ + *perl.core core.*perl.*.? \ + $(MAKE_APERL_FILE) perl \ + $(BASEEXT).def core.[0-9][0-9][0-9] \ + mon.out lib$(BASEEXT).def \ + perlmain.c perl.exe \ + so_locations $(BASEEXT).exp + - $(RM_RF) \ + Business-BatchPayment-TD_EFT-* blib + - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL) + + +# --- MakeMaker realclean_subdirs section: +realclean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker realclean section: +# Delete temporary files (via clean) and also delete dist files +realclean purge :: clean realclean_subdirs + - $(RM_F) \ + $(MAKEFILE_OLD) $(FIRST_MAKEFILE) + - $(RM_RF) \ + $(DISTVNAME) + + +# --- MakeMaker metafile section: +metafile : create_distdir + $(NOECHO) $(ECHO) Generating META.yml + $(NOECHO) $(ECHO) '--- #YAML:1.0' > META_new.yml + $(NOECHO) $(ECHO) 'name: Business-BatchPayment-TD_EFT' >> META_new.yml + $(NOECHO) $(ECHO) 'version: 0.01' >> META_new.yml + $(NOECHO) $(ECHO) 'abstract: TD Commercial Banking EFT1464 batch format' >> META_new.yml + $(NOECHO) $(ECHO) 'author:' >> META_new.yml + $(NOECHO) $(ECHO) ' - Mark Wells ' >> META_new.yml + $(NOECHO) $(ECHO) 'license: perl' >> META_new.yml + $(NOECHO) $(ECHO) 'distribution_type: module' >> META_new.yml + $(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: 0' >> META_new.yml + $(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: 0' >> META_new.yml + $(NOECHO) $(ECHO) 'requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' Business::BatchPayment: 0' >> META_new.yml + $(NOECHO) $(ECHO) ' Moose: 2' >> META_new.yml + $(NOECHO) $(ECHO) ' Test::More: 0' >> META_new.yml + $(NOECHO) $(ECHO) 'no_index:' >> META_new.yml + $(NOECHO) $(ECHO) ' directory:' >> META_new.yml + $(NOECHO) $(ECHO) ' - t' >> META_new.yml + $(NOECHO) $(ECHO) ' - inc' >> META_new.yml + $(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.57_05' >> META_new.yml + $(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml + $(NOECHO) $(ECHO) ' url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml + $(NOECHO) $(ECHO) ' version: 1.4' >> META_new.yml + -$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml + + +# --- MakeMaker signature section: +signature : + cpansign -s + + +# --- MakeMaker dist_basics section: +distclean :: realclean distcheck + $(NOECHO) $(NOOP) + +distcheck : + $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck + +skipcheck : + $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck + +manifest : + $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest + +veryclean : realclean + $(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old + + + +# --- MakeMaker dist_core section: + +dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE) + $(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \ + -e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' -- + +tardist : $(DISTVNAME).tar$(SUFFIX) + $(NOECHO) $(NOOP) + +uutardist : $(DISTVNAME).tar$(SUFFIX) + uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu + +$(DISTVNAME).tar$(SUFFIX) : distdir + $(PREOP) + $(TO_UNIX) + $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(COMPRESS) $(DISTVNAME).tar + $(POSTOP) + +zipdist : $(DISTVNAME).zip + $(NOECHO) $(NOOP) + +$(DISTVNAME).zip : distdir + $(PREOP) + $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(POSTOP) + +shdist : distdir + $(PREOP) + $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar + $(RM_RF) $(DISTVNAME) + $(POSTOP) + + +# --- MakeMaker distdir section: +create_distdir : + $(RM_RF) $(DISTVNAME) + $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \ + -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');" + +distdir : create_distdir distmeta + $(NOECHO) $(NOOP) + + + +# --- MakeMaker dist_test section: +disttest : distdir + cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL + cd $(DISTVNAME) && $(MAKE) $(PASTHRU) + cd $(DISTVNAME) && $(MAKE) test $(PASTHRU) + + + +# --- MakeMaker dist_ci section: + +ci : + $(PERLRUN) "-MExtUtils::Manifest=maniread" \ + -e "@all = keys %{ maniread() };" \ + -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \ + -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});" + + +# --- MakeMaker distmeta section: +distmeta : create_distdir metafile + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \ + -e ' or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"' -- + + + +# --- MakeMaker distsignature section: +distsignature : create_distdir + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) } ' \ + -e ' or print "Could not add SIGNATURE to MANIFEST: $${'\''@'\''}\n"' -- + $(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE + cd $(DISTVNAME) && cpansign -s + + + +# --- MakeMaker install section: + +install :: pure_install doc_install + $(NOECHO) $(NOOP) + +install_perl :: pure_perl_install doc_perl_install + $(NOECHO) $(NOOP) + +install_site :: pure_site_install doc_site_install + $(NOECHO) $(NOOP) + +install_vendor :: pure_vendor_install doc_vendor_install + $(NOECHO) $(NOOP) + +pure_install :: pure_$(INSTALLDIRS)_install + $(NOECHO) $(NOOP) + +doc_install :: doc_$(INSTALLDIRS)_install + $(NOECHO) $(NOOP) + +pure__install : pure_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +doc__install : doc_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +pure_perl_install :: all + $(NOECHO) umask 022; $(MOD_INSTALL) \ + $(INST_LIB) $(DESTINSTALLPRIVLIB) \ + $(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \ + $(INST_BIN) $(DESTINSTALLBIN) \ + $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \ + $(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \ + $(INST_MAN3DIR) $(DESTINSTALLMAN3DIR) + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + $(SITEARCHEXP)/auto/$(FULLEXT) + + +pure_site_install :: all + $(NOECHO) umask 02; $(MOD_INSTALL) \ + read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \ + write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \ + $(INST_LIB) $(DESTINSTALLSITELIB) \ + $(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \ + $(INST_BIN) $(DESTINSTALLSITEBIN) \ + $(INST_SCRIPT) $(DESTINSTALLSITESCRIPT) \ + $(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \ + $(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR) + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + $(PERL_ARCHLIB)/auto/$(FULLEXT) + +pure_vendor_install :: all + $(NOECHO) umask 022; $(MOD_INSTALL) \ + $(INST_LIB) $(DESTINSTALLVENDORLIB) \ + $(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \ + $(INST_BIN) $(DESTINSTALLVENDORBIN) \ + $(INST_SCRIPT) $(DESTINSTALLVENDORSCRIPT) \ + $(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \ + $(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR) + +doc_perl_install :: all + +doc_site_install :: all + $(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod + -$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH) + -$(NOECHO) umask 02; $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" "$(INSTALLSITELIB)" \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> $(DESTINSTALLSITEARCH)/perllocal.pod + +doc_vendor_install :: all + + +uninstall :: uninstall_from_$(INSTALLDIRS)dirs + $(NOECHO) $(NOOP) + +uninstall_from_perldirs :: + +uninstall_from_sitedirs :: + $(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist + +uninstall_from_vendordirs :: + + + +# --- MakeMaker force section: +# Phony target to force checking subdirectories. +FORCE : + $(NOECHO) $(NOOP) + + +# --- MakeMaker perldepend section: + + +# --- MakeMaker makefile section: +# We take a very conservative approach here, but it's worth it. +# We move Makefile to Makefile.old here to avoid gnu make looping. +$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP) + $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?" + $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..." + -$(NOECHO) $(RM_F) $(MAKEFILE_OLD) + -$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + - $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL) + $(PERLRUN) Makefile.PL + $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <==" + $(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <==" + $(FALSE) + + + +# --- MakeMaker staticmake section: + +# --- MakeMaker makeaperl section --- +MAP_TARGET = perl +FULLPERL = /usr/bin/perl + +$(MAP_TARGET) :: static $(MAKE_APERL_FILE) + $(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@ + +$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib + $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) + $(NOECHO) $(PERLRUNINST) \ + Makefile.PL DIR= \ + MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ + MAKEAPERL=1 NORECURS=1 CCCDLFLAGS= + + +# --- MakeMaker test section: + +TEST_VERBOSE=0 +TEST_TYPE=test_$(LINKTYPE) +TEST_FILE = test.pl +TEST_FILES = t/*.t +TESTDB_SW = -d + +testdb :: testdb_$(LINKTYPE) + +test :: $(TEST_TYPE) subdirs-test + +subdirs-test :: + $(NOECHO) $(NOOP) + + +test_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES) + +testdb_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE) + +test_ : test_dynamic + +test_static :: test_dynamic +testdb_static :: testdb_dynamic + + +# --- MakeMaker ppd section: +# Creates a PPD (Perl Package Description) for a binary distribution. +ppd : + $(NOECHO) $(ECHO) '' > $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' TD Commercial Banking EFT1464 batch format' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' Mark Wells <mark@freeside.biz>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) '' >> $(DISTNAME).ppd + + +# --- MakeMaker pm_to_blib section: + +pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM) + $(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \ + TD_EFT.pm $(INST_LIB)/Business/BatchPayment/TD_EFT.pm + $(NOECHO) $(TOUCH) pm_to_blib + + +# --- MakeMaker selfdocument section: + + +# --- MakeMaker postamble section: + + +# End. diff --git a/README b/README new file mode 100644 index 0000000..157689a --- /dev/null +++ b/README @@ -0,0 +1,55 @@ +Business-BatchPayment-TD_EFT + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the README +file from a module distribution so that people browsing the archive +can use it to get an idea of the module's uses. It is usually a good idea +to provide version information here so that people can decide whether +fixes for the module are worth downloading. + + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + +SUPPORT AND DOCUMENTATION + +After installing, you can find documentation for this module with the +perldoc command. + + perldoc Business::BatchPayment::TD_EFT + +You can also look for information at: + + RT, CPAN's request tracker (report bugs here) + http://rt.cpan.org/NoAuth/Bugs.html?Dist=Business-BatchPayment-TD_EFT + + AnnoCPAN, Annotated CPAN documentation + http://annocpan.org/dist/Business-BatchPayment-TD_EFT + + CPAN Ratings + http://cpanratings.perl.org/d/Business-BatchPayment-TD_EFT + + Search CPAN + http://search.cpan.org/dist/Business-BatchPayment-TD_EFT/ + + +LICENSE AND COPYRIGHT + +Copyright (C) 2012 Mark Wells + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + diff --git a/TD_EFT.pm b/TD_EFT.pm new file mode 100644 index 0000000..ba9ee9f --- /dev/null +++ b/TD_EFT.pm @@ -0,0 +1,414 @@ +package Business::BatchPayment::TD_EFT; + +use 5.006; +use strict; +use warnings; +our $VERSION = '0.01'; + +=head1 NAME + +Business::BatchPayment::TD_EFT - TD Commercial Banking EFT1464 batch format + +=head1 VERSION + +Version 0.01 + +=head1 USAGE + +See L for general usage notes. + +=head2 SYNOPSIS + +use Business::BatchPayment; + +my @items = Business::BatchPayment::Item->new( ... ); + +my $processor = Business::BatchPayment->processor('TD_EFT', + originator => 'TDABC22334', + datacentre => '00400', + short_name => 'AcmeCorp', + long_name => 'The Acme Corporation', + return_branch => '10202', # 0004 + 5-digit branch number + return_account => '00124598951', # 11 digits + cpa_code => '120', + counter => 101, +); + +my $result = $processor->submit(@items); + +=head2 REQUIREMENTS + +Requires L and ssh (for file transfer). + +=head2 PROCESSOR ATTRIBUTES + +=over 4 + +=item originator - Originator ID, 10 characters + +=item datacentre - Your TD datacentre number, 5 digits + +=item short_name - Your company name in 15 characters or less. + +=item long_name - Your company name in 30 characters or less. + +=item return_account, return_branch - The account number and bank branch +to use for returned payments. + +=item cpa_code - Your 3-digit CPA industry code. + +=item counter - Batch sequence number. You MUST save this after submitting +a batch, and pass the same value back in in the next session. + +=back + +=cut + +use DateTime; +use Try::Tiny; + +use Moose; +use Moose::Util::TypeConstraints; + +with 'Business::BatchPayment::Processor'; + +has [ qw( originator short_name long_name + return_branch return_account cpa_code ) ] => ( + is => 'rw', + isa => 'Str', + required => 1, +); + +has 'datacentre' => ( + is => 'rw', + isa => enum([qw( 00400 00410 00420 00430 00470 00490)]), + required => 1, +); + +has 'counter' => ( + is => 'rw', + isa => 'Int', + default => 0, +); + +sub BUILD { + my $self = shift; + # should be a parametric string type or something + $self->originator( sprintf('%-10.10s', $self->originator) ); + $self->short_name( sprintf('%-15.15s', $self->short_name) ); + $self->long_name( sprintf('%-30.30s', $self->long_name) ); + $self->return_account( sprintf('%-11.11s', $self->return_account) ); + $self->return_branch ( '0004'. + sprintf('%-5.5s', $self->return_branch) ) + unless length($self->return_branch) == 9; +} + +before format_request => sub { + my ($self, $batch) = @_; + #shazam! + Business::BatchPayment::TD_EFT::Batch->meta->apply($batch); + + my $dt = DateTime->now; + $batch->create_date(sprintf('%03d%03d', $dt->year % 1000, $dt->day_of_year)); + + # a number from 1 to 9999 + $batch->fcn(sprintf('%04u', ($self->counter % 9999) + 1)); + # what should be a unique identifier + $batch->batch_id($batch->create_date . '-' . $batch->fcn); +}; + +after submit => sub { + my $self = shift; + $self->counter($self->counter + 1); +}; + +sub format_header { + my ($self, $batch) = @_; + my $header = + 'A' . #record type + '000000001' . #row number + $self->originator . + $batch->fcn . + $batch->create_date . + $self->datacentre; + sprintf('%-1464s', $header); +} + +sub format_item { + my ($self, $item, $batch) = @_; + + $batch->row($batch->row + 1); + my $cents = int($item->amount * 100); + if ( $item->action eq 'payment' ) { + $batch->total_payment( $batch->total_payment + $cents ); + $batch->count_payment( $batch->count_payment + 1 ); + } elsif ( $item->action eq 'credit' ) { + $batch->total_credit( $batch->total_credit + $cents ); + $batch->count_credit( $batch->count_credit + 1 ); + } + + # default to tomorrow + # (should this use Time::Business? Date::Holidays::CA?) + # (should we just require the merchant to specify a process date?) + my $process_date = $item->process_date; + $process_date ||= DateTime->today->add(days => 1); + + my $duedate = sprintf('%03d%03d', + $process_date->year % 1000, + $process_date->day_of_year); + # The 1464 byte format supports up to 5 payments per line, but we're + # only sending one. + my $row = + ($item->action eq 'credit' ? 'C' : 'D') . + sprintf('%09u', $batch->row) . + $self->originator . + $batch->fcn . + $self->cpa_code . + sprintf('%010u', $cents) . + $duedate . + sprintf('%09u', $item->routing_code) . + sprintf('%-12.12s', $item->account_number ) . + '0' x 22 . + '0' x 3 . + $self->short_name . + sprintf('%-30.30s', $item->first_name . ' ' . $item->last_name) . + $self->long_name . + $self->originator . + sprintf('%-19.19s', $item->tid) . #originator reference number + $self->return_branch . + $self->return_account . + ' ' x (15 + 22 + 2) . + '0' x 11 + ; + sprintf('%-1464s', $row); +} + +sub format_trailer { + my ($self, $batch) = @_; + my $trailer = + 'Z' . + sprintf('%09u', $batch->row + 1) . + $self->originator . + $batch->fcn . + sprintf('%014u', $batch->total_payment) . + sprintf('%08u', $batch->count_payment) . + sprintf('%014u', $batch->total_credit) . + sprintf('%08u', $batch->count_credit) + ; + sprintf('%-1464s', $trailer); +} + +sub parse_response { + # two different response formats to consider + my ($self, $response) = @_; + my $batch = Business::BatchPayment->create('Batch'); + Business::BatchPayment::TD_EFT::Batch->meta->apply($batch); + + my @rows = split("\n", $response); + if ( length($rows[0]) == 80 and $rows[0] =~ /^H/ ) { + return $self->parse_ret_80($batch, @rows); + } elsif ( length($rows[0]) == 264 and $rows[0] =~ /^A/ ) { + return $self->parse_ack_264($batch, @rows); + } else { + die "can't determine format of file starting with\n$rows[0]\n"; + } +} + +my @field_order = ( + # for error messages in the ACK file + '', + 'Record Type', + 'Record Count', + 'Originator ID', + 'File Creation Number', + 'CPA Code', + 'Payment Amount', + 'Due Date', + 'Financial Institution ID', + 'Payor/Payee Account Number', + '', + '', + 'Originator Short Name', + 'Payor/Payee Name', + 'Originator Long Name', + 'Originator ID', + 'Originator Reference', + 'Return Branch Number', + 'Return Account Number', + 'Originator Sundry', + '', + '', + '' +); + +sub parse_ack_264 { + # TD EFT 264-byte acknowledgement file + # One of these is sent for every batch. It reports any records + # that failed format screening. + my ($self, $batch, @rows) = @_; + warn "Acknowledgement file" if $self->debug; + my $payment_date; + foreach my $row (@rows) { + try { + if ( $row =~ /^A/ ) { + # Header record. + $row =~ /^(.{1})(.{9})(.{10})(.{4})(.{6})(.{5})(.{7})(.{10})(.{7})(.{10})(.{5})(.{1})(.{30})( {159})$/ or die "invalid header row\n"; + # Most of these fields aren't interesting to us. + $batch->fcn($4); + $batch->create_date($5); + $batch->batch_id($batch->create_date . '-' . $batch->fcn); + my $date = $10; + $date =~ /^(....)-(..)-(..)$/; # actual process date, YYYY-MM-DD + $payment_date = DateTime->new(year => $1, month => $2, day => $3); + } elsif ( $row =~ /^[CD]/ ) { + # Rejected item detail. + my @f = ($row =~ /^(.{1})(.{9})(.{14})(.{3})(.{10})(.{6})(.{9})(.{12})(.{25})(.{15})(.{30})(.{30})(.{10})(.{19})(.{9})(.{12})(.{15})(.{22})(.{2})(.{11})$/) + or die "invalid detail row\n"; + foreach (@f) { s/^\s+//; s/\s+$//; } + unshift @f, ''; # make field numbers line up + my $action; + if ( $f[1] eq 'C' ) { $action = 'credit' } + elsif ( $f[1] eq 'D' ) { $action = 'payment' } + + my $amount = + my $item = Business::BatchPayment->create('Item' => + action => $action, + payment_type => 'ECHECK', + approved => 0, + amount => sprintf('%.2f', $f[5] / 100), + payment_date => $payment_date, + routing_code => $f[7], + account_number => $f[8], + tid => $f[15], + ); + my @error_fields = map { $field_order[$_] } ($f[21] =~ /../g); + # yuck + $item->error_message('invalid fields: '.join(', ', @error_fields)); + $batch->push($item); + } elsif ( $row =~ /^R/ ) { + # um...this indicates the whole batch was rejected + # not quite sure what to do with that + $row =~ /^(.{1})(.{9})(.{10})(.{4})(.{5})(.{75})( {160})$/; + $row = ''; + die "batch rejected: $5 $6\n"; + } else { + # W, X, Z records + # not interesting + } + } catch { + $self->parse_error($row, $_); + }; + die "no valid header row found\n" unless $payment_date; + } #foreach $row + $batch; +} + +my %return_reason = ( + '00' => 'Edit Reject', + '01' => 'Insufficient Funds', + '02' => 'Cannot Trace', + '03' => 'Payment Stopped/Recalled', + '04' => 'Post/Stale Dated', + '05' => 'Account Closed', + '06' => 'Account Transferred', + '07' => 'No Chequing Privileges', + '08' => 'Funds Not Cleared', + #'09' => + '10' => 'Payor/Payee Deceased', + '11' => 'Account Frozen', + '12' => 'Invalid/Incorrect Account Number', + '13' => 'Contact Payor/Payee', + '14' => 'Incorrect Payor/Payee Name', + '15' => 'Refused by Payor/Payee', + '80' => 'Payment Recalled', +); + +sub parse_ret_80 { + # TD EFT 80 byte returned items file + # This reports unpostable and dishonored payments. + # This may be sent at any time after receiving the request. If there + # are no dishonored payments, no file will be sent. + my ($self, $batch, @rows) = @_; + warn "Returned item notification" if $self->debug; + my $action; + foreach my $row (@rows) { + try { + if ( $row =~ /^H/ ) { + # Header. + $row =~ /^(.{1})(.{10})(.{1})( {3})(.{6})(.{30})(.{12})( {8})$/ + or die "invalid header row\n"; + # the only field we care about is payment vs. credit + # and even that only minimally + if ( $3 eq 'I' ) { $action = 'credit' } + elsif ( $3 eq 'J') { $action = 'payment' } + } elsif ( $row =~ /^D/ ) { + # Detail. + my @f = ( $row =~ /^(.{1})(.{20})(.{2})(.{1})(.{6})(.{19})(.{9})(.{12})(.{10})$/ ) + or die "invalid detail row\n"; + foreach (@f) { s/^\s+//; s/\s+$//; } + unshift @f, ''; + my $item = Business::BatchPayment->create('Item' => + action => $action, + payment_type => 'ECHECK', + approved => 0, + amount => sprintf('%.2f', $f[9] / 100), + routing_code => $f[7], + account_number => $f[8], + tid => $f[6], + error_message => "$f[3] ".$return_reason{$f[3]}, + ); + $batch->push($item); + } else { + # T record + # not interesting, though we could use it as an error check + } + } catch { + $self->parse_error($row, $_); + } + die "no valid header row found\n" unless $action; + } + $batch; +} + +package Business::BatchPayment::TD_EFT::Batch; +use Moose::Role; +use List::Util qw(sum); + +has [qw( create_date fcn )] => ( is => 'rw', isa => 'Str' ); +has [qw( row total_payment total_credit count_payment count_credit )] => + ( is => 'rw', isa => 'Int', default => 0 ); + +=back + +=head1 AUTHOR + +Mark Wells, C<< >> + +=head1 BUGS + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc Business::BatchPayment::TD_EFT + +Commercial support is available from Freeside Internet Services, Inc. + +L + +=head1 ACKNOWLEDGEMENTS + +=head1 LICENSE AND COPYRIGHT + +Copyright 2012 Mark Wells. + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + + +=cut + +1; # End of Business::BatchPayment::TD_EFT diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..591909b --- /dev/null +++ b/ignore.txt @@ -0,0 +1,13 @@ +.git* +blib* +Makefile +Makefile.old +Build +Build.bat +_build* +pm_to_blib* +*.tar.gz +.lwpcookies +cover_db +pod2htm*.tmp +Business-BatchPayment-TD_EFT-* diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..dfece52 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,9 @@ +#!perl -T + +use Test::More tests => 1; + +BEGIN { + use_ok( 'Business::BatchPayment::TD_EFT' ) || print "Bail out!\n"; +} + +diag( "Testing Business::BatchPayment::TD_EFT $Business::BatchPayment::TD_EFT::VERSION, Perl $], $^X" ); diff --git a/t/boilerplate.t b/t/boilerplate.t new file mode 100644 index 0000000..7110c6e --- /dev/null +++ b/t/boilerplate.t @@ -0,0 +1,56 @@ +#!perl -T + +use 5.006; +use strict; +use warnings; +use Test::More tests => 3; + +sub not_in_file_ok { + my ($filename, %regex) = @_; + open( my $fh, '<', $filename ) + or die "couldn't open $filename for reading: $!"; + + my %violated; + + while (my $line = <$fh>) { + while (my ($desc, $regex) = each %regex) { + if ($line =~ $regex) { + push @{$violated{$desc}||=[]}, $.; + } + } + } + + if (%violated) { + fail("$filename contains boilerplate text"); + diag "$_ appears on lines @{$violated{$_}}" for keys %violated; + } else { + pass("$filename contains no boilerplate text"); + } +} + +sub module_boilerplate_ok { + my ($module) = @_; + not_in_file_ok($module => + 'the great new $MODULENAME' => qr/ - The great new /, + 'boilerplate description' => qr/Quick summary of what the module/, + 'stub function definition' => qr/function[12]/, + ); +} + +TODO: { + local $TODO = "Need to replace the boilerplate text"; + + not_in_file_ok(README => + "The README is used..." => qr/The README is used/, + "'version information here'" => qr/to provide version information/, + ); + + not_in_file_ok(Changes => + "placeholder date/time" => qr(Date/time) + ); + + module_boilerplate_ok('lib/Business/BatchPayment/TD_EFT.pm'); + + +} + diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..45eb83f --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,13 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +eval "use Test::CheckManifest 0.9"; +plan skip_all => "Test::CheckManifest 0.9 required" if $@; +ok_manifest(); diff --git a/t/pod.t b/t/pod.t new file mode 100644 index 0000000..ee8b18a --- /dev/null +++ b/t/pod.t @@ -0,0 +1,12 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok(); -- 2.11.0