'type' => 'textarea',
},
+ {
+ 'key' => 'invoice_latextopmargin',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice topmargin setting. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
+ {
+ 'key' => 'invoice_latexheadsep',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice headsep setting. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
+ {
+ 'key' => 'invoice_latexaddresssep',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice separation between invoice header
+and customer address. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
+ {
+ 'key' => 'invoice_latextextheight',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice textheight setting. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
{
'key' => 'invoice_latexnotes',
'section' => 'invoicing',
'per_agent' => 1,
},
+ {
+ 'key' => 'invoice_latexextracouponspace',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice textheight space to reserve for a tear off coupon. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
+ {
+ 'key' => 'invoice_latexcouponfootsep',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice separation between tear off coupon and footer. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
+ {
+ 'key' => 'invoice_latexcouponamountenclosedsep',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice separation between total due and amount enclosed line. Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+ {
+ 'key' => 'invoice_latexcoupontoaddresssep',
+ 'section' => 'invoicing',
+ 'description' => 'Optional LaTeX invoice separation between invoice data and the to address (usually invoice_latexreturnaddress). Include units.',
+ 'type' => 'text',
+ 'per_agent' => 1,
+ 'validate' => sub { shift =~
+ /^-?\d*\.?\d+(in|mm|cm|pt|em|ex|pc|bp|dd|cc|sp)$/
+ ? '' : 'Invalid LaTex length';
+ },
+ },
+
{
'key' => 'invoice_latexreturnaddress',
'section' => 'invoicing',
'type' => 'textarea',
},
+ {
+ 'key' => 'invoice_latexverticalreturnaddress',
+ 'section' => 'invoicing',
+ 'description' => 'Place the return address under the company logo rather than beside it.',
+ 'type' => 'checkbox',
+ 'per_agent' => 1,
+ },
+
+ {
+ 'key' => 'invoice_latexcouponaddcompanytoaddress',
+ 'section' => 'invoicing',
+ 'description' => 'Add the company name to the To address on the remittance coupon because the return address does not contain it.',
+ 'type' => 'checkbox',
+ 'per_agent' => 1,
+ },
+
{
'key' => 'invoice_latexsmallfooter',
'section' => 'invoicing',
}
+ my $agentnum = $self->cust_main->agentnum;
+
my %invoice_data = (
#invoice from info
- 'company_name' => scalar( $conf->config('company_name', $self->cust_main->agentnum) ),
- 'company_address' => join("\n", $conf->config('company_address', $self->cust_main->agentnum) ). "\n",
+ 'company_name' => scalar( $conf->config('company_name', $agentnum) ),
+ 'company_address' => join("\n", $conf->config('company_address', $agentnum) ). "\n",
'returnaddress' => $returnaddress,
'agent' => &$escape_function($cust_main->agent->agent),
'smallerfooter' => $conf->exists('invoice-smallerfooter'),
'balance_due_below_line' => $conf->exists('balance_due_below_line'),
+ #layout info -- would be fancy to calc some of this and bury the template
+ # here in the code
+ 'topmargin' => scalar($conf->config('invoice_latextopmargin', $agentnum)),
+ 'headsep' => scalar($conf->config('invoice_latexheadsep', $agentnum)),
+ 'textheight' => scalar($conf->config('invoice_latextextheight', $agentnum)),
+ 'extracouponspace' => scalar($conf->config('invoice_latexextracouponspace', $agentnum)),
+ 'couponfootsep' => scalar($conf->config('invoice_latexcouponfootsep', $agentnum)),
+ 'verticalreturnaddress' => $conf->exists('invoice_latexverticalreturnaddress', $agentnum),
+ 'addresssep' => scalar($conf->config('invoice_latexaddresssep', $agentnum)),
+ 'amountenclosedsep' => scalar($conf->config('invoice_latexcouponamountenclosedsep', $agentnum)),
+ 'coupontoaddresssep' => scalar($conf->config('invoice_latexcoupontoaddresssep', $agentnum)),
+ 'addcompanytoaddress' => $conf->exists('invoice_latexcouponaddcompanytoaddress', $agentnum),
+
# better hang on to conf_dir for a while (for old templates)
'conf_dir' => "$FS::UID::conf_dir/conf.$FS::UID::datasrc",
$invoice_data{'previous_balance'} = sprintf("%.2f", $pr_total);
$invoice_data{'balance'} = sprintf("%.2f", $balance_due);
- my $agentnum = $self->cust_main->agentnum;
-
my $summarypage = '';
if ( $conf->exists('invoice_usesummary', $agentnum) ) {
$summarypage = 1;
\r
\addtolength{\voffset}{-0.0cm} % top margin to top of header\r
\addtolength{\hoffset}{-0.6cm} % left margin on page\r
-\addtolength{\topmargin}{-1.25cm} % top margin to top of header\r
+\addtolength{\topmargin}{[@-- defined($topmargin) ? $topmargin : '-1.25cm' --@]}\r
\setlength{\headheight}{2.0cm} % height of header\r
-\setlength{\headsep}{1.0cm} % between header and text\r
+\setlength{\headsep}{[@-- defined($headsep) ? $headsep : '1.0cm' --@]}\r
\setlength{\footskip}{1.0cm} % bottom of footer from bottom of text\r
\r
%\addtolength{\textwidth}{2.1in} % width of text\r
\setlength{\textwidth}{19.5cm}\r
-\setlength{\textheight}{19.5cm}\r
+\setlength{\textheight}{[@-- defined($textheight) ? $textheight : '19.5cm' --@]}\r
\setlength{\oddsidemargin}{-0.9cm} % odd page left margin\r
\setlength{\evensidemargin}{-0.9cm} % even page left margin\r
\r
}\r
}\r
\r
-\newcommand{\extracouponspace}{3.6cm}\r
+\newcommand{\extracouponspace}{[@-- defined($extracouponspace) ? $extracouponspace : '3.6cm' --@]}\r
\r
% Adjust the inset of the mailing address\r
\newcommand{\addressinset}[1][]{\hspace{1.0cm}}\r
$OUT .= '\vspace{-\extracouponspace}';\r
$OUT .= '\rule[0.5em]{\textwidth}{\footrulewidth}\\\\';\r
$OUT .= $coupon;\r
+ $OUT .= '\vspace{'. $couponfootsep. '}' if defined($couponfootsep);\r
}\r
'';\r
--@] [@-- $smallerfooter ? '\scriptsize{' : '\small{' --@]\r
\returninset\r
\makebox{\r
\begin{tabular}{ll}\r
- \includegraphics{[@-- $logo_file --@]} &\r
+ \includegraphics{[@-- $logo_file --@]} & [@-- $verticalreturnaddress ? '\\\\' : '' --@]\r
\begin{minipage}[b]{5.5cm}\r
[@-- $returnaddress --@]\r
- \end{minipage}\r
+ \end{minipage}\\\r
\end{tabular}\r
}\r
}\r
\addressinset \rule{0.5cm}{0cm} \r
\makebox{\r
\begin{minipage}[t]{7.0cm}\r
-\vspace{0.25cm}\r
+\vspace{[@-- defined($addresssep) ? $addresssep : '0.25cm' --@]}\r
\textbf{[@-- $payname --@]}\\\r
\addressline{[@-- $company --@]}\r
\addressline{[@-- $address1 --@]}\r
\begin{tabular}{ll}\r
\returninset\r
\begin{tabular}{ll}\r
- \makebox{ \includegraphics{[@-- $logo_file --@]}} &\r
+ \makebox{ \includegraphics{[@-- $logo_file --@]}} & [@-- $verticalreturnaddress ? '\\\\' : '' --@]\r
\begin{minipage}[b]{5.5cm}\r
[@-- $returnaddress --@]\r
- \end{minipage}\r
+ \end{minipage}\\\r
\end{tabular}&\r
\begin{tabular}{r@{: }lr}\r
-Invoice date & \textbf{[@-- $date --@]} & \multirow{4}*{\r
+Invoice date & \textbf{[@-- $date --@]} & \multirow{4}*{[@-- $verticalreturnaddress ? '\\rule{1.5cm}{0cm}' : '' --@]\r
\makebox{\r
\begin{minipage}[t]{7.0cm}\r
\textbf{[@-- $payname --@]}\\\r
\end{minipage}}}\\\r
Customer\#& \textbf{[@-- $custnum --@]} & \\\r
Total Due & \textbf{[@-- $balance --@]} & \\\r
-\rule{0pt}{2.25em}Amount Enclosed & \rule{2cm}{1pt}& \\\r
+\rule{0pt}{[@-- defined($amountenclosedsep) ? $amountenclosedsep : '2.25em' --@]}Amount Enclosed & \rule{2cm}{1pt}& \\\r
\end{tabular}\\\r
-\rule{0pt}{1cm} &\\\r
+\rule{0pt}{[@-- defined($coupontoaddresssep) ? $coupontoaddresssep : '1cm' --@]} &\\\r
\end{tabular}\\\r
\begin{tabular}{ll}\r
\addressinset \rule{0.5cm}{0cm} &\r
\makebox{\r
\begin{minipage}[t]{7.0cm}\r
-[@-- $returnaddress --@]\r
+[@-- $addcompanytoaddress ? $company_name. '\\\\' : '' --@][@-- $returnaddress --@]\r
\end{minipage}}\r
\hfill\r
\end{tabular}\\\r
+%if ( scalar(@error) ) {
+%
+% my $url = popurl(1)."config.cgi";
+% if ( length($cgi->query_string) > 1920 ) { #stupid IE 2083 URL limit
+%
+% my $session = int(rand(4294967296)); #XXX
+% my $pref = new FS::access_user_pref({
+% 'usernum' => $FS::CurrentUser::CurrentUser->usernum,
+% 'prefname' => "redirect$session",
+% 'prefvalue' => $cgi->query_string,
+% 'expiration' => time + 3600, #1h? 1m?
+% });
+% my $pref_error = $pref->insert;
+% if ( $pref_error ) {
+% die "FATAL: couldn't even set redirect cookie: $pref_error".
+% " attempting to set redirect$session to ". $cgi->query_string."\n";
+% }
+%
+<% $cgi->redirect("$url?redirect=$session") %>
+%
+% } else {
+%
+<% $cgi->redirect("$url?". $cgi->query_string ) %>
+%
+% }
+%
+%} else {
<% header('Configuration set') %>
<SCRIPT TYPE="text/javascript">
% my $n = 0;
</SCRIPT>
</BODY>
</HTML>
+%}
<%once>
#false laziness w/config-view.cgi
my %namecol = (
my $key = $cgi->param('key');
my $i = $confitems{$key};
+my @error = ();
my @touch = ();
my @delete = ();
my $n = 0;
if ( $cgi->param($i->key.$n) ne '' ) {
my $value = $cgi->param($i->key.$n);
$value =~ s/\r\n/\n/g; #browsers?
+ my $error = &{$i->validate}($value, $n) if $i->validate;
+ push @error, $error if $error;
$conf->set($i->key, $value, $agentnum);
} else {
$conf->delete($i->key, $agentnum);
} elsif ( $type eq 'binary' || $type eq 'image' ) {
if ( defined($cgi->param($i->key.$n)) && $cgi->param($i->key.$n) ) {
my $fh = $cgi->upload($i->key.$n);
+ my $error = &{$i->validate}($fh, $n) if $i->validate;
+ push @error, $error if $error;
if (defined($fh)) {
local $/;
$conf->set_binary($i->key, <$fh>, $agentnum);
|| $i->multiple )
) {
if ( scalar(@{[ $cgi->param($i->key.$n) ]}) ) {
+ my $error = &{$i->validate}([ $cgi->param($i->key.$n) ], $n) if $i->validate;
+ push @error, $error if $error;
$conf->set($i->key, join("\n", @{[ $cgi->param($i->key.$n) ]} ), $agentnum);
} else {
$conf->delete($i->key, $agentnum);
}
} elsif ( $type =~ /^(text|select(-(sub|part_svc|part_pkg|pkg_class))?)$/ ) {
if ( $cgi->param($i->key.$n) ne '' ) {
+ my $error = &{$i->validate}($cgi->param($i->key.$n), $n) if $i->validate;
+ push @error, $error if $error;
$conf->set($i->key, $cgi->param($i->key.$n), $agentnum);
} else {
$conf->delete($i->key, $agentnum);
$conf->touch($_, $agentnum) foreach @touch;
$conf->delete($_, $agentnum) foreach @delete;
+if (scalar(@error)) {
+ $cgi->param('error', join(' ', @error));
+}
+
</%init>