From fc263806f5e475559a0c4cfdb70a5f1cefe0ffa3 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Wed, 27 May 2020 13:39:47 -0700 Subject: [PATCH] deposit slips --- FS/FS/Conf.pm | 28 ++ FS/FS/Mason.pm | 2 +- FS/FS/Misc/DepositSlip.pm | 376 +++++++++++++++++++++ FS/MANIFEST | 1 + Makefile | 1 + debian/control | 2 +- debian/rules | 1 + etc/GnuMICR.otf | Bin 0 -> 4424 bytes httemplate/docs/credits.html | 8 +- httemplate/docs/license.html | 10 +- httemplate/search/elements/grouped-search.html | 2 +- .../search/elements/grouped-search/deposit_slip | 8 + httemplate/search/elements/grouped-search/html | 6 +- .../search/elements/search-deposit_slip.html | 17 + httemplate/search/elements/search.html | 9 +- 15 files changed, 460 insertions(+), 11 deletions(-) create mode 100644 FS/FS/Misc/DepositSlip.pm create mode 100644 etc/GnuMICR.otf create mode 100644 httemplate/search/elements/grouped-search/deposit_slip create mode 100644 httemplate/search/elements/search-deposit_slip.html diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 3ac22ca62..cbccffb94 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -6065,6 +6065,34 @@ and customer address. Include units.', 'type' => 'checkbox', }, + { + 'key' => 'deposit_slip-bank_name', + 'section' => 'payments', #XXX payment_deposit_slips + 'description' => 'Bank name to print on check deposit slips', + 'type' => 'text', + }, + + { + 'key' => 'deposit_slip-bank_address', + 'section' => 'payments', #XXX payment_deposit_slips + 'description' => 'Bank address to print on check deposit slips', + 'type' => 'textarea', + }, + + { + 'key' => 'deposit_slip-bank_routingnumber', + 'section' => 'payments', #XXX payment_deposit_slips + 'description' => '9 digit bank routing number to print on check deposit slips', + 'type' => 'text', + }, + + { + 'key' => 'deposit_slip-bank_accountnumber', + 'section' => 'payments', #XXX payment_deposit_slips + 'description' => 'Bank account number to print on check deposit slips', + 'type' => 'text', + }, + # for internal use only; test databases should declare this option and # everyone else should pretend it doesn't exist diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 5b8242b77..8dd72ac79 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -387,7 +387,6 @@ if ( -e $addl_handler_use_file ) { use FS::export_batch_item; use FS::part_pkg_fcc_option; use FS::state; - use FS::state; use FS::queue_stat; use FS::deploy_zone; use FS::deploy_zone_block; @@ -424,6 +423,7 @@ if ( -e $addl_handler_use_file ) { use FS::saved_search; use FS::sector_coverage; use FS::svc_group; + use FS::Misc::DepositSlip qw( deposit_slip_pdf ); # Sammath Naur if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Misc/DepositSlip.pm b/FS/FS/Misc/DepositSlip.pm new file mode 100644 index 000000000..b687691ef --- /dev/null +++ b/FS/FS/Misc/DepositSlip.pm @@ -0,0 +1,376 @@ +package FS::Misc::DepositSlip; +use base 'Exporter'; + +use strict; +use warnings; +use vars qw( @EXPORT_OK ); + +#use Date::Format; +use IPC::Run qw( run timeout ); # for _xelatex +use Text::Template; + +@EXPORT_OK = qw( deposit_slip_pdf ); + +=item deposit_slip_pdf + +=cut + +sub deposit_slip_pdf { + my %arg = @_; + my $conf = $arg{'conf'}; + my @cust_pay = @{ $arg{'cust_pay'} }; + + if ( scalar(@cust_pay) > 25 ) { + return 'ERROR: Maxiumum of 25 items per deposit slip at this time'; + } + + my $text_template = new Text::Template( + TYPE => 'STRING', + SOURCE => slip_template(), + DELIMITERS => [ '[@--', '--@]' ], + ); + + $text_template->compile() or die $Text::Template::ERROR; + + my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc; + chdir($dir); + + #my $date = time2str( $self->conf->config('date_format_long') || '%b %o, %Y', + # time #XXX future deposit date + # ); + + my $total = 0; + foreach my $cust_pay (@cust_pay) { + $total += $cust_pay->paid; + } + $total = sprintf('%.2f', $total + 0.00000001); #so FP math errors round out + my ($total_dollars, $total_cents) = split(/\./, $total); + + my $gtotal = sprintf('%11.2f', $total); + $gtotal =~ s/\.//; + my @gtotal = split('', $gtotal); + + #XXX agent virt for company name, address + my %fill_in = ( + 'company_name' => _latex_escape($conf->config('company_name')), + 'company_address' => join('\\\\', map _latex_escape($_), + $conf->config('company_address') ), + + 'bank_name' => _latex_escape($conf->config('deposit_slip-bank_name')), + 'bank_address' => join('\\\\', map _latex_escape($_), + $conf->config('deposit_slip-bank_address') ), + + 'bank_routingnumber' => _latex_escape( + $conf->config('deposit_slip-bank_routingnumber')), + 'bank_accountnumber' => _latex_escape( + $conf->config('deposit_slip-bank_accountnumber')), + + #already defaulting to today + #'depositdate' => _latex_escape($date), + + 'currency_dollars' => '', + 'currency_cents' => '', + 'coin_dollars' => '', + 'coin_cents' => '', + 'checks_dollars' => '', + 'checks_cents' => '', + + 'reverse_dollars' => '', + 'reverse_cents' => '', + 'total_dollars' => $total_dollars, + 'total_cents' => $total_cents, + + 'cust_pay' => \@cust_pay, + + 'totalitems' => scalar(@cust_pay), + + 'grandtotalboxone' => $gtotal[0], + 'grandtotalboxtwo' => $gtotal[1], + 'grandtotalboxthree' => $gtotal[2], + 'grandtotalboxfour' => $gtotal[3], + 'grandtotalboxfive' => $gtotal[4], + 'grandtotalboxsix' => $gtotal[5], + 'grandtotalboxseven' => $gtotal[6], + 'grandtotalboxeight' => $gtotal[7], + 'grandtotalboxnine' => $gtotal[8], + 'grandtotalboxten' => $gtotal[9], + ); + + #XXX better unique filename + my $file = "deposit$$"; + + open(DEPOSIT_TEX, ">$file.tex") or die $!; + print DEPOSIT_TEX $text_template->fill_in( HASH => \%fill_in ); + close DEPOSIT_TEX or die $!; + + _xelatex($file); + + #XXX use File::Slurp + my $pdf = ''; + open(PDF, "<$file.pdf") or die $!; + + unlink("$file.log", "$file.aux", "$file.pdf", "$file.tex"); + + while () { + $pdf .= $_; + } + close PDF; + + return $pdf; + +} + +#some false laziness w/_pslatex in Misc.pm +sub _xelatex { + my $file = shift; + + #my $sfile = shell_quote $file; + + my @cmd = ( + 'xelatex', + '-interaction=batchmode', + "$file.tex" + ); + + my $timeout = 30; #? should be more than enough + + for ( 1, 2 ) { + + local($SIG{CHLD}) = sub {}; + run( \@cmd, '>'=>'/dev/null', '2>'=>'/dev/null', timeout($timeout) ) + or warn "bad exit status from xelatex pass $_\n"; + + } + + return if -e "$file.pdf" && -s "$file.pdf"; + die "xelatex $file.tex failed, see $file.log for details?\n"; + +} + +#false laxiness w/Template_Mixin.pm +sub _latex_escape { + my $value = shift; + $value =~ s/([#\$%&~_\^{}])( )?/"\\$1". ( ( defined($2) && length($2) ) ? "\\$2" : '' )/ge; + $value =~ s/([<>])/\$$1\$/g; + $value; +} + +sub slip_template { <<'__END__'; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Freeside Deposit Slip +% LaTeX Template +% Version 1.1 (May 9, 2020) +% +% This template was created by: +% Vel (enquiries@latextypesetting.com) +% LaTeXTypesetting.com +% +%!TEX program = xelatex +% Note: this template must be compiled with XeLaTeX rather than PDFLaTeX +% due to the custom fonts used. The line above should ensure this happens +% automatically, but if it doesn't, your LaTeX editor should have a simple toggle +% to switch to using XeLaTeX. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%---------------------------------------------------------------------------------------- +% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS +%---------------------------------------------------------------------------------------- + +\documentclass{article} + +%---------------------------------------------------------------------------------------- +% REQUIRED PACKAGES AND MISC CONFIGURATIONS +%---------------------------------------------------------------------------------------- + +\setlength{\parindent}{0pt} % Stop paragraph indentation + +\usepackage{tikz} % Required for custom graphics +\usetikzlibrary{calc} % Required for coordinate calculations within TikZ + +% Suppress hyphenation across the whole document +\hyphenpenalty=10000 +\exhyphenpenalty=10000 + +%---------------------------------------------------------------------------------------- +% MARGINS +%---------------------------------------------------------------------------------------- + +\usepackage[ + paperwidth=8.5in, + paperheight=3.25in, + top=0cm, % Top margin + bottom=1cm, % Bottom margin + left=1cm, % Left margin + right=1cm, % Right margin + footskip=0.6cm, % Space from the bottom margin to the baseline of the footer + headsep=0.8cm, % Space from the top margin to the baseline of the header + headheight=0.5cm, % Height of the header + %showframe % Uncomment to show the frames around the margins for debugging purposes +]{geometry} + +%---------------------------------------------------------------------------------------- +% FONTS +%---------------------------------------------------------------------------------------- + +\usepackage{fontspec} % Required for specifying custom fonts + +\defaultfontfeatures{Ligatures=TeX} % To support LaTeX ligatures (`` and --) +\defaultfontfeatures{Path=/usr/local/etc/freeside/} % Specify the location of font files + +\newfontface\GNUMicr{GnuMICR.otf} % MICR font from file + +\usepackage[default]{sourcesanspro} % Use the Source Sans Pro font for the document body + +%---------------------------------------------------------------------------------------- +% HEADERS AND FOOTERS +%---------------------------------------------------------------------------------------- + +\usepackage{fancyhdr} % Required for customising headers and footers +\pagestyle{fancy} % Enable custom headers and footers + +\renewcommand{\headrulewidth}{0pt} % Remove default top horizontal rule + +\fancyhf{} % Clear default headers/footers + +\fancyfoot[C]{{\Large\GNUMicr\MICR}} % Centre footer + +%---------------------------------------------------------------------------------------- +% TABLES +%---------------------------------------------------------------------------------------- + +\usepackage{booktabs} % Required for better horizontal rules in tables + +\usepackage{array} % Required for manipulating table columns + +\renewcommand{\arraystretch}{1.35} % Increase the space between table rows + +\newcolumntype{R}[1]{>{\raggedleft\arraybackslash}p{#1}} % Define a new right-aligned paragraph column type +\newcolumntype{L}[1]{>{\raggedright\arraybackslash}p{#1}} % Define a new left-aligned (no justification) paragraph column type +\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}} % Define a new centred paragraph column type + +%---------------------------------------------------------------------------------------- +% CUSTOM COMMANDS +%---------------------------------------------------------------------------------------- + +\newcommand{\MICR}[1]{\renewcommand{\MICR}{#1}} +\newcommand{\disclaimer}[1]{\renewcommand{\disclaimer}{#1}} +\newcommand{\companyaddress}[1]{\renewcommand{\companyaddress}{#1}} +\newcommand{\bankaddress}[1]{\renewcommand{\bankaddress}{#1}} +\newcommand{\totalitems}[1]{\renewcommand{\totalitems}{#1}} +\newcommand{\grandtotalboxone}[1]{\renewcommand{\grandtotalboxone}{#1}} +\newcommand{\grandtotalboxtwo}[1]{\renewcommand{\grandtotalboxtwo}{#1}} +\newcommand{\grandtotalboxthree}[1]{\renewcommand{\grandtotalboxthree}{#1}} +\newcommand{\grandtotalboxfour}[1]{\renewcommand{\grandtotalboxfour}{#1}} +\newcommand{\grandtotalboxfive}[1]{\renewcommand{\grandtotalboxfive}{#1}} +\newcommand{\grandtotalboxsix}[1]{\renewcommand{\grandtotalboxsix}{#1}} +\newcommand{\grandtotalboxseven}[1]{\renewcommand{\grandtotalboxseven}{#1}} +\newcommand{\grandtotalboxeight}[1]{\renewcommand{\grandtotalboxeight}{#1}} +\newcommand{\grandtotalboxnine}[1]{\renewcommand{\grandtotalboxnine}{#1}} +\newcommand{\grandtotalboxten}[1]{\renewcommand{\grandtotalboxten}{#1}} +\newcommand{\depositdate}[1]{\renewcommand{\depositdate}{#1}} + +%\newcommand{\command}[1]{\renewcommand{\command}{#1}} + +%---------------------------------------------------------------------------------------- +% DEPOSIT SLIP INFORMATION +%---------------------------------------------------------------------------------------- + +\MICR{A[@-- $bank_routingnumber --@]A [@-- $bank_accountnumber --@]C} % Displayed at the bottom of the slip + +\disclaimer{Checks and other items are received for deposit subject to the provisions of the Uniform Commercial Code and any applicable collection agreement. Deposits May Not Be Available For Immediate Withdrawal.} + +\companyaddress{\textbf{[@-- $company_name --@]}\\[@-- $company_address --@]} + +\bankaddress{\textbf{[@-- $bank_name --@]}\\ [@-- $bank_address --@]} + +\totalitems{[@-- $totalitems --@]} + +\grandtotalboxone{[@-- $grandtotalboxone --@]} +\grandtotalboxtwo{[@-- $grandtotalboxtwo --@]} +\grandtotalboxthree{[@-- $grandtotalboxthree --@]} +\grandtotalboxfour{[@-- $grandtotalboxfour --@]} +\grandtotalboxfive{[@-- $grandtotalboxfive --@]} +\grandtotalboxsix{[@-- $grandtotalboxsix --@]} +\grandtotalboxseven{[@-- $grandtotalboxseven --@]} +\grandtotalboxeight{[@-- $grandtotalboxeight --@]} +\grandtotalboxnine{[@-- $grandtotalboxnine --@]} +\grandtotalboxten{[@-- $grandtotalboxten --@]} + +\depositdate{\today} + +%---------------------------------------------------------------------------------------- + +\begin{document} + +%---------------------------------------------------------------------------------------- +% DEPOSIT SLIP +%---------------------------------------------------------------------------------------- + +\begin{tikzpicture}[remember picture, overlay] + \node [anchor=north, rotate=90, xshift=-0.5\paperheight, yshift=-0.4cm, inner sep=0pt] (title) at (current page.north west) {\textbf{DEPOSIT TICKET}}; % Deposit ticket title text + + \node [anchor=north, rotate=90, yshift=-0.4cm, inner sep=0pt] (dateline) at (title.south) {DATE: \rule{0.58\paperheight}{1pt}}; % Date line + \node [anchor=south, rotate=90, yshift=-0.2cm, inner sep=0pt] (date) at (dateline.north) {\depositdate}; % Date + + \node [anchor=north west, rotate=90, yshift=-0.25cm, text width=0.8\paperheight, inner sep=0pt] (disclaimer) at (dateline.south west) {\fontsize{6pt}{7pt}\selectfont \disclaimer\par}; % Disclaimer text + + \node [anchor=north east, rotate=90, inner sep=0pt] (table) at (disclaimer.south east) {% Table + \begin{tabular}{| L{1.8cm} | L{1cm} | L{0.5cm}} + \cline{2-3} + \multicolumn{1}{R{1.8cm} |}{} & \scriptsize DOLLARS & \scriptsize CENTS \\\cline{2-3} + \multicolumn{1}{R{1.8cm} |}{\scriptsize CURRENCY} & [@-- $currency_dollars --@] & [@-- $currency_cents --@]\\\cline{2-3} + \multicolumn{1}{R{1.8cm} |}{\scriptsize COIN} & [@-- $coin_dollars --@] & [@-- $coin_cents --@]\\\cline{2-3} + \multicolumn{1}{| R{1.8cm} |}{\vspace{-1.2\baselineskip}\scriptsize CHECKS \newline \tiny (ENTER SEPARATELY)} & [@-- $checks_dollars --@] & [@-- $checks_cents --@]\\[-3pt]\cline{1-3} +[@-- + for (0 .. 24) { + if ( scalar(@cust_pay) ) { + my $cust_pay = shift @cust_pay; + my ($dollars, $cents) = split(/\./, $cust_pay->paid); + $OUT .= $cust_pay->payinfo. " & $dollars & $cents". '\\\\\\cline{1-3}'. "\n"; + } else { + $OUT .= ' & & \\\\\\cline{1-3}'. "\n"; + } + } +--@] + \fontsize{6pt}{6pt}\selectfont TOTAL OF \newline REVERSE SIDE & [@-- $reverse_dollars --@] & [@-- $reverse_cents --@] \\\cline{1-3} + \fontsize{10pt}{10pt}\selectfont\textbf{TOTAL} \newline DEPOSIT & [@-- $total_dollars --@] & [@-- $total_cents --@] \\\cline{1-3} + \end{tabular} + }; % Table + \node [anchor=north east, rotate=90, yshift=-0.07cm, inner sep=0pt] (totalguidetext) at (table.south east) {\fontsize{6pt}{6pt}\selectfont PLEASE ENTER TOTAL HERE}; % Total guide text + \draw [->] ($(totalguidetext.west)-(0, 0.1cm)$) -- ($(totalguidetext.west)-(0cm, 2.7cm)$); % Total guide text arrow + + \node [anchor=south west, xshift=0.3cm, text width=0.3\paperwidth, inner sep=0pt] (companyaddress) at (disclaimer.south west) {\Large\companyaddress\par}; % Company and address + + \node [anchor=north west, text width=0.3\paperwidth, inner sep=0pt] (bankaddress) at (companyaddress.north east) {\footnotesize\bankaddress\par}; % Financial institution address + + \node [anchor=south west, xshift=0.5cm, yshift=1.4cm, text width=0.75cm, inner sep=0pt] (totalitemstext) at (current page.south) {\fontsize{6pt}{6pt}\selectfont TOTAL ITEMS\par}; % Total items text + \node [rectangle, anchor=west, draw=black, line width=1pt, minimum width=1cm, minimum height=0.5cm, inner sep=0pt] (totalitemsbox) at (totalitemstext.east) {\totalitems}; % Total items box + + \node [anchor=west, xshift=1cm, text width=0.4cm, inner sep=0pt] (dollarsign) at (totalitemsbox.east) {\Large\textbf{\$}}; % Dollar sign text + \node [rectangle, anchor=west, fill=black!7, minimum width=6.7cm, minimum height=1.25cm, inner sep=0pt] (totalbox) at (dollarsign.east) {}; % Grand total grey box + \node [rectangle, anchor=west, fill=white, xshift=0.3cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxone) at (totalbox.west) {\grandtotalboxone}; % White box 1 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxtwo) at (whiteboxone.east) {\grandtotalboxtwo}; % White box 2 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxthree) at (whiteboxtwo.east) {\grandtotalboxthree}; % White box 3 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxfour) at (whiteboxthree.east) {\grandtotalboxfour}; % White box 4 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxfive) at (whiteboxfour.east) {\grandtotalboxfive}; % White box 5 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxsix) at (whiteboxfive.east) {\grandtotalboxsix}; % White box 6 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxseven) at (whiteboxsix.east) {\grandtotalboxseven}; % White box 7 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxeight) at (whiteboxseven.east) {\grandtotalboxeight}; % White box 8 + \node [anchor=west, xshift=-0.5pt, inner sep=0pt] (centsperiod) at (whiteboxeight.south east) {.}; % Cents period + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxnine) at (whiteboxeight.east) {\grandtotalboxnine}; % White box 9 + \node [rectangle, anchor=west, fill=white, xshift=0.05cm, minimum width=0.55cm, minimum height=0.55cm, inner sep=0pt] (whiteboxten) at (whiteboxnine.east) {\grandtotalboxten}; % White box 10 + \draw [fill=white, draw=white] ($(whiteboxtwo.south east)+(0.02cm, 0cm)$) -- ($(whiteboxtwo.south east)-(0.03cm, 0.1cm)$) -- ($(whiteboxtwo.south east)+(0.07cm, -0.1cm)$) -- cycle; % Triangle 1 + \draw [fill=white, draw=white] ($(whiteboxfive.south east)+(0.02cm, 0cm)$) -- ($(whiteboxfive.south east)-(0.03cm, 0.1cm)$) -- ($(whiteboxfive.south east)+(0.07cm, -0.1cm)$) -- cycle; % Triangle 2 +\end{tikzpicture} + +%---------------------------------------------------------------------------------------- + +\end{document} + +__END__ + +} + +1; diff --git a/FS/MANIFEST b/FS/MANIFEST index 17100cdf9..1e26a3c69 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -879,3 +879,4 @@ FS/access_user_session_log.pm t/access_user_session_log.t FS/svc_group.pm FS/h_svc_group.pm +FS/Misc/DepositSlip.pm diff --git a/Makefile b/Makefile index 802632e4b..7055c292b 100644 --- a/Makefile +++ b/Makefile @@ -264,6 +264,7 @@ install-texmf: install -D -o freeside -m 444 etc/*.sty \ /usr/local/share/texmf/tex/latex/ texhash /usr/local/share/texmf + install -D -o root -m 444 etc/GnuMICR.otf /usr/local/etc/freeside install-init: #[ -e ${INIT_FILE} ] || install -o root -g ${INSTALLGROUP} -m 711 init.d/freeside-init ${INIT_FILE} diff --git a/debian/control b/debian/control index 5b8c02158..28ff88061 100644 --- a/debian/control +++ b/debian/control @@ -64,7 +64,7 @@ Depends: aspell-en,gnupg,ghostscript,gsfonts,gzip, mime-support, ntp,ntpdate,perl,perl-base,perl-modules,postgresql,postgresql-client,psutils, rsync,openssh-client,texlive,texlive-latex-recommended,texlive-latex-extra, - texinfo,ttf-bitstream-vera, + texinfo,ttf-bitstream-vera,texlive-xetex,texlive-fonts-extra, fonts-dustin,libdatetime-perl,libdatetime-format-strptime-perl, libfile-slurp-perl,libspreadsheet-parseexcel-perl,libauthen-passphrase-perl, libnet-domain-tld-perl,libbusiness-us-usps-webtools-perl,libxml-simple-perl, diff --git a/debian/rules b/debian/rules index 153f17751..e32910f1c 100755 --- a/debian/rules +++ b/debian/rules @@ -171,6 +171,7 @@ install-stamp: build-stamp # Install tex install -d ${TEXMF_PATH} install -o freeside -m 444 etc/*.sty ${TEXMF_PATH} + install -o root -m 444 etc/GnuMICR.otf /usr/local/etc/freeside # Create Apache configurations install -d $(APACHE_CONF) diff --git a/etc/GnuMICR.otf b/etc/GnuMICR.otf new file mode 100644 index 0000000000000000000000000000000000000000..8fd182331be7a55a5ba09b3804ef8f2bb3e1e5c5 GIT binary patch literal 4424 zcmd5=Z){sv6+iEfpA*-0(=0X+Qu`?zsDsA5BovLQD}^-cI(2PHOH1|v;w7(fs@RDf z8*kYb>P;0AuTX8;Yt=537sezET0g81A)!p-Q$Yl2L4fcVSUw;SUxqfe_o8$Pzx&6I zn`9IamAEhW-E;q)^E7c~{~Z&B|_XY!Bt{2{cT zsO2s6AIhX2pQP5~5Xnb1vZ;)HBe^FJT|-3LcP1yM@@r-4A=rz%IsNN@Kl??TOlr`#94@p_anzK?4 zP>Y(AvVrkuflSex0gmAmvcM^1fm6r=r;r6sAq$*B7C8H8f+pz+%F!5&QkwGMWj77e zy=Z&L;!l^9dT9?v`}x{oNGB*oSsEc5PZs@sG5p^u|$BSZ718iM>L94sssoY~I??mBAVl*v~Y~9OBkYBu{}JgC=Ixq$9j#2$@#q zL6JX6i7p8(Imkp}|08sm`hbP#D4)py&p3L=VJijiN1%_f)D6@Y+WS#&-6_VpG24Yz z-FOQod$+K03Yc<0HU?XaL&12Gdbwn7-qANP`9yAPG@Unh58rF{SeDg=SMMIPKQ}gP zo=9a!Y&&c2n-W6TXtt0U8_pe&{bbh8?@yZMfIV)frtA^3fb}^upSI1soy$y_6K8nm zP_|$mFFZC5l}E;g?d+7j$1E0$NvKOsB9qsa*M771tF=+N7gMY#20PHAC`_nz z(xE1HcF?CgLUt?eE$q?|hKqEGUZPj}24o=rFY;3QCL5WYU{s-<_&m9b+9*mf`UriL zK1S`-Nq5sd^a=W*@-1R{^smaMPn%kPu#X8=kRNv}cEW;q?`-V+59L-7Se;IRkB=)C zmA|N8QGc&Jr2SFv*MA=PY~U56t*N6a{(dClRQ>s?@=n!nuWH`qm^WiAFD)%6{Py5- z|I*(0>Ws0szkhGyW_xh&QvY(ist={F&9mwGYuD!ESU!I(J;bJm(&-_#JmQr7UwX}o z-&@uEFjF`;J3E)~W`c9mvxWErMq!$D7uUPfg~Uj(FgrarH#=R3ubvJTrl$+6LLDEE z1En{^{uJ-eRnMwwZEvlsW@;0wmegwnnYp-UNwd-pfN`y`lHhYNx@vJtalV)J7lYrJ zoqjof;oE_AgMP`gV9t9Z<}FH}oFx?a zDiX$stmv?P8HQone>5ht?@G{l@r5f_pKJ1HK5+H97p^!jHhCAMiJE)J2cCrtP(vCq zPn(0zlg~W;)cK}W`dZ+r^Upl(JlRyEV?9~kLFi^gzI4X?wDftae5sjywISIdb9OE1 zVm%ZrmmBG}3~x~v{MDkhc?r&;_fv6Z5D129J*8H3;rY$>4+*S1cYeFh`QMlq4PYV; zbmLK&@9W2O;oc<6O* zeP|N3iv&myMny){qQb73I`iJy8uZ5din&|6iM)52L6%(bwQZ7n%N0src^cw6l%W*q zxAmMivrdA%9qT02&7GG1F&Bls)3<@>&D@p*c_@TYd2j^c$buWKxJB1>OK#cC3>w#C zu4|y zQa>Daw*BtXufyA&a0Fi_?_ytFlz-rtIsOZPI;y^{d|6fv{hvT?Y%$Nq*t%P4i0R

Core Team

-Christopher Burger
-Mitch Jackson
-Jim Lucas
Ivan Kohler

@@ -64,6 +61,7 @@ Stephen Bechard
Eric Bosrup
Dickie Bradford
Alex Brelsfoard
+Christopher Burger
Dave Burgess
Joe Camadine
Chris Cappuccio
@@ -76,6 +74,7 @@ Dave Denney
Serge Dolgov
Scott Edwards
Kenny Elliott
+Velimir Gayevskiy
Joshua Goodman
Donald Greer
Joel Griffiths
@@ -85,12 +84,14 @@ Troy Hammonds
Sean Hanson
Dale Hege
Kelly Hickel
+Mitch Jackson
Mark James
Gary Jones
Fernando M. Kiernan
Frederico Caldeira Knabben
Greg Kuhnert
Steven Levithan
+Jim Lucas
Randall Lucas
Foteos Macrides
Roger Mangraviti
@@ -100,6 +101,7 @@ David Peters
Matt Peterson
Luke Pfeifer
Alan Phipps
+Eric Sandeen
Ricardo Signes
Steve Simitzis
Stanislav Sinyagin
diff --git a/httemplate/docs/license.html b/httemplate/docs/license.html index 1b9d10a53..267692005 100644 --- a/httemplate/docs/license.html +++ b/httemplate/docs/license.html @@ -6,7 +6,7 @@

-Copyright © 2005-2017 Freeside Internet Services, Inc.
+Copyright © 2005-2020 Freeside Internet Services, Inc.
Copyright © 2000-2005 Ivan Kohler
Copyright © 1999 Silicon Interactive Software Design
All rights reserved
@@ -152,6 +152,9 @@ licensed under the terms of MIT License. Contains the leaflet JavaScript library Leaflet JS by Vladimir Agafonkin, licensed under the terms of MIT License. +

+Contains a deposit slip template by Vel from LaTeX Typesetting. +

@@ -170,7 +173,6 @@ http://www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org/Actions-documen licensed under GNU Lesser General Public License

-

Contains icons from iconfinder.com @@ -178,5 +180,9 @@ by Cole Bemis, licensed under the terms of the Creative Commons Attribution 3.0 License.

+

+Contains the GnuMICR font +by Eric Sandeen, licensed under the terms of the GNU GPL. + diff --git a/httemplate/search/elements/grouped-search.html b/httemplate/search/elements/grouped-search.html index 56fc88d38..80a931983 100644 --- a/httemplate/search/elements/grouped-search.html +++ b/httemplate/search/elements/grouped-search.html @@ -42,7 +42,7 @@ <%init> my $type = 'html'; -if ($cgi->param('type') =~ /^(html|html-print|xls)$/) { +if ($cgi->param('type') =~ /^(html|html-print|xls|deposit_slip)$/) { $type = $1; } diff --git a/httemplate/search/elements/grouped-search/deposit_slip b/httemplate/search/elements/grouped-search/deposit_slip new file mode 100644 index 000000000..6e69662c4 --- /dev/null +++ b/httemplate/search/elements/grouped-search/deposit_slip @@ -0,0 +1,8 @@ +<& /search/elements/search-deposit_slip.html, rows=>\@rows, &>\ +<%init> +my %opt = @_; +my $group_info = $m->comp('core', %opt); +#just the first group +my $query = $group_info->{queries}[0]; +my @rows = $query->qsearch; + diff --git a/httemplate/search/elements/grouped-search/html b/httemplate/search/elements/grouped-search/html index ae8086512..24cf50e96 100644 --- a/httemplate/search/elements/grouped-search/html +++ b/httemplate/search/elements/grouped-search/html @@ -114,9 +114,13 @@ my $money = $conf->config('money_char') || '$'; %# download links

<% emt('Download results:') %> % $cgi->param('type', 'xls'); -<% emt('Spreadsheet') %> |  +<% emt('Spreadsheet') %> | % $cgi->param('type', 'html-print'); <% emt('webpage') %> +% if ( ref($query) && $query->{table} eq 'cust_pay' ) { +% $cgi->param('type', 'deposit_slip'); + | <% emt('deposit slip') %> +% } % $cgi->delete('type');

% } diff --git a/httemplate/search/elements/search-deposit_slip.html b/httemplate/search/elements/search-deposit_slip.html new file mode 100644 index 000000000..c7a6cbb18 --- /dev/null +++ b/httemplate/search/elements/search-deposit_slip.html @@ -0,0 +1,17 @@ +<% $deposit_pdf %>\ +<%init> + +my %args = @_; +my $rows = $args{'rows'}; + +my $deposit_pdf = deposit_slip_pdf( + conf => FS::Conf->new, + cust_pay => $rows, +); + +http_header('Content-Type' => 'application/pdf'); +http_header('Content-Disposition' => "filename=deposit.pdf" ); +http_header('Content-Length' => length($deposit_pdf) ); +http_header('Cache-control' => 'max-age=60' ); + + diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html index 730a51aa3..60548e28e 100644 --- a/httemplate/search/elements/search.html +++ b/httemplate/search/elements/search.html @@ -198,6 +198,10 @@ Example: % <% include('search-xml.html', rows=>$rows, opt=>\%opt ) %> % +% } elsif ( $type eq 'deposit_slip' ) { +% +<% include('search-deposit_slip.html', rows=>$rows, opt=>\%opt ) %> +% % } else { % <% include('search-html.html', @@ -224,8 +228,9 @@ my $curuser = $FS::CurrentUser::CurrentUser; $m->comp('/elements/handle_uri_query'); -my $type = $cgi->param('_type') =~ /^(csv|\w*\.xls|xml|select|html(-print)?)$/ - ? $1 : 'html' ; +my $type = $cgi->param('_type') + =~ /^(csv|\w*\.xls|xml|select|html(-print)?|deposit_slip)$/ + ? $1 : 'html' ; if ( !$curuser->access_right('Download report data') ) { $opt{'disable_download'} = 1; -- 2.11.0