[wiaflos-devel] COMMIT - r239 - in trunk: contrib/templates contrib/templates/reports soap/Plugins wiaflos/client/cmdline wiaflos/server

svn at linuxrulz.org svn at linuxrulz.org
Sun Aug 17 13:59:29 GMT 2008


Author: nkukard
Date: 2008-08-17 13:59:29 +0000 (Sun, 17 Aug 2008)
New Revision: 239

Added:
   trunk/contrib/templates/reports/
   trunk/contrib/templates/reports/chartofaccounts1.tt2
   trunk/contrib/templates/reports/readme.txt
Modified:
   trunk/soap/Plugins/Reporting.pm
   trunk/wiaflos/client/cmdline/Reporting.pm
   trunk/wiaflos/server/Reporting.pm
Log:
* Added chart of accounts reporting template
* Added ability to email reports


Added: trunk/contrib/templates/reports/chartofaccounts1.tt2
===================================================================
--- trunk/contrib/templates/reports/chartofaccounts1.tt2	                        (rev 0)
+++ trunk/contrib/templates/reports/chartofaccounts1.tt2	2008-08-17 13:59:29 UTC (rev 239)
@@ -0,0 +1,69 @@
+[% INCLUDE header.tt2 %]
+
+<head>
+	<title>Statement: [% StatementDate %]<title>
+	[% INCLUDE styles.tt2 %]
+</head>
+
+<body>
+
+
+<table id="page" width="100%">
+	<colgroup span="2" width="50%">
+	</colgroup>
+	[% INCLUDE companydetails.tt2 %]
+	<tr>
+		<td colspan="2" class="bigtext border centeralign bold">
+			C H A R T &nbsp;&nbsp;&nbsp; O F &nbsp;&nbsp;&nbsp; A C C O U N T S
+			<br />
+			[% StartDate %] to [% EndDate %]
+		</td>
+	</tr>
+	<tr>
+		<td colspan="2" class="smalltext">
+			<table width="100%">
+				<tr>
+					<td class="border centeralign">Account</td>
+					<td class="border centeralign">Description</td>
+					<td class="border centeralign">Debit</td>
+					<td class="border centeralign">Credit</td>
+				</tr>
+					[% FOREACH rwcatcode = [ '00', '20', '40', '60', '80' ] %]
+						<tr>
+							<td class="centeralign bold" colspan="4">
+								[% ReportWriterCategories.${rwcatcode}.Code %] - [% ReportWriterCategories.${rwcatcode}.Description %]
+							</td>
+						</tr>
+						[% FOREACH item = ReportWriterCategoryToAccounts.${rwcatcode} %]
+							<tr>
+								<td class="bold">[% item.Number %]</td>
+								<td class="bold">[% item.Name %]</td>
+								<td class="rightalign bold">[% item.DebitAmount %]</td>
+								<td class="rightalign bold">[% item.CreditAmount %]</td>
+							</tr>
+							[% IF item.Children %]
+								[% FOREACH child = item.Children %]
+									<tr>
+										<td>[% child.Number %]</td>
+										<td >[% child.Name %]</td>
+										<td class="rightalign">[% child.DebitAmount %]</td>
+										<td class="rightalign">[% child.CreditAmount %]</td>
+									</tr>
+								[% END %]
+							[% END %]
+						[% END %]
+					[% END %]
+				<tr>
+					<td class="centeralign" colspan="4">All values in <span class="bold">USD</span> funds.</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+<div class="smalltext centeralign">[% WiaflosString %]</div>
+
+
+
+</body>
+
+</html>

Added: trunk/contrib/templates/reports/readme.txt
===================================================================
--- trunk/contrib/templates/reports/readme.txt	                        (rev 0)
+++ trunk/contrib/templates/reports/readme.txt	2008-08-17 13:59:29 UTC (rev 239)
@@ -0,0 +1,55 @@
+Here are the variables defined:
+
+*
+* VARIABLES FOR INVOICE ITSELF
+*
+
+Misc:
+-----
+WiaflosString: text
+	- "Generated by $APPNAME ($APPURL)"
+
+
+
+Report Details:
+----------------
+
+StartDate: text
+	- Report start date
+
+EndDate: text
+	- End date
+
+
+
+Account items:
+--------------
+
+AccountBalances: hashes of account numbers
+	Number: text
+		- Account number
+
+	Name: text
+		- Account name
+
+	CreditAmount: text
+		- Credit amount
+
+	DebitAmount: text
+		- Debit amount
+
+	ReportWriterCategoryCode: text
+		- Report writer category code
+
+	Children: array of hashes
+		- Array of account children
+
+
+ReportWriterCategoryToAccounts: hash of report writer categories, each item is
+an array of accounts linked to this category code
+
+
+ReportWriterCategories: hash of report writer categories, keyed by the report
+writer category code
+
+

Modified: trunk/soap/Plugins/Reporting.pm
===================================================================
--- trunk/soap/Plugins/Reporting.pm	2008-08-17 13:21:33 UTC (rev 238)
+++ trunk/soap/Plugins/Reporting.pm	2008-08-17 13:59:29 UTC (rev 239)
@@ -43,6 +43,9 @@
 
 
 	Auth::aclAdd('Reporting','getChartOfAccounts','Reporting/ChartOfAccounts/Show');
+
+	# should be split up
+	Auth::aclAdd('Reporting','sendReport','Reporting/ChartOfAccounts/Show');
 }
 
 
@@ -103,6 +106,43 @@
 }
 
 
+# Send report
+# Parameters:
+#		Template	- Report template to use
+#		SendTo		- Send statement to here
+#		StartDate	- Start date
+#		EndDate		- End date
+#		Subject		- Statement subject
+sub sendReport {
+	my (undef,$data) = @_;
 
+
+	# Check params
+	if (!defined($data->{'Template'}) || $data->{'Template'} eq "") {
+		return SOAPResponse(RES_ERROR,ERR_S_PARAM,"Parameter 'Template' invalid");
+	}
+
+	if (!defined($data->{'SendTo'}) || $data->{'SendTo'} eq "") {
+		return SOAPResponse(RES_ERROR,ERR_S_PARAM,"Parameter 'SendTo' invalid");
+	}
+
+	# Do transaction
+	my $detail;
+	$detail->{'Template'} = $data->{'Template'};
+	$detail->{'SendTo'} = $data->{'SendTo'};
+	$detail->{'StartDate'} = $data->{'StartDate'};
+	$detail->{'EndDate'} = $data->{'EndDate'};
+	$detail->{'Subject'} = $data->{'Subject'};
+	my $res = wiaflos::server::Reporting::sendReport($detail);
+
+	if ($res < 0) {
+		return SOAPResponse(RES_ERROR,$res,wiaflos::server::Reporting::Error());
+	}
+
+	return SOAPResponse(RES_OK,$res);
+}
+
+
+
 1;
 # vim: ts=4

Modified: trunk/wiaflos/client/cmdline/Reporting.pm
===================================================================
--- trunk/wiaflos/client/cmdline/Reporting.pm	2008-08-17 13:21:33 UTC (rev 238)
+++ trunk/wiaflos/client/cmdline/Reporting.pm	2008-08-17 13:59:29 UTC (rev 239)
@@ -47,9 +47,16 @@
 					MenuItem 	=> "ShowChartOfAccounts",
 					Regex		=> "show(?:chartofaccounts|coa)",
 					Desc		=> "Display chart of accounts",
-					Help		=> 'showChartOfAccounts',
+					Help		=> 'showChartOfAccounts [start=<yyyy-mm-dd>] [end=<yyyy-mm-dd>] [levels=<levels to display>]',
 					Function	=> \&show,
 				},
+				{
+					MenuItem 	=> "Send",
+					Regex		=> "send",
+					Desc		=> "Send report",
+					Help		=> 'send template="<template>" start="<yyyy-mm-dd>" [subject="<subject>"] sendto="<email[:addy1,addy2...] or file:filename>"',
+					Function	=> \&send,
+				},
 			],
 		},
 	],
@@ -57,7 +64,7 @@
 
 
 
-# Show client statement
+# Show report
 sub show
 {
 	my ($OUT, at args) = @_;
@@ -116,6 +123,17 @@
 END
 		}
 
+		print swrite(<<'END',"Equity");
+| @||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |
+END
+		foreach my $entry (@{$byRwCat{'40'}}) {
+			$debit->badd($entry->{'DebitAmount'});
+			$credit->badd($entry->{'CreditAmount'});
+			print swrite(<<'END', $entry->{'Number'}, $entry->{'Name'}, defined($entry->{'DebitAmount'}) ? sprintf('%.2f',$entry->{'DebitAmount'}) : '', defined($entry->{'CreditAmount'}) ? sprintf('%.2f',$entry->{'CreditAmount'}) : '');
+| @<<<<<<<<<<<<<<<< | @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | @>>>>>>>>>>>>> | @>>>>>>>>>>>>> |
+END
+		}
+
 		print swrite(<<'END',"Income");
 | @||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |
 END
@@ -153,6 +171,40 @@
 }
 
 
+# Send report
+sub send
+{
+	my ($OUT, at args) = @_;
 
+
+	my $parms = parseArgs(@args);
+
+	if (!defined($parms->{'template'})) {
+		print($OUT "  => ERROR: Parameter 'template' not defined\n");
+		return ERR_C_PARAM;
+	}
+
+	if (!defined($parms->{'sendto'})) {
+		print($OUT "  => ERROR: Parameter 'sendto' not defined\n");
+		return ERR_C_PARAM;
+	}
+
+
+	my $detail;
+	$detail->{'Template'} = $parms->{'template'};
+	$detail->{'StartDate'} = $parms->{'start'};
+	$detail->{'EndDate'} = $parms->{'end'};
+	$detail->{'SendTo'} = $parms->{'sendto'};
+	$detail->{'Subject'} = $parms->{'subject'};
+	my $res = soapCall($OUT,"Reporting","sendReport",$detail);
+	if ($res->{'Result'} != RES_OK) {
+		soapDebug($OUT,$res);
+	}
+
+	return $res->{'Result'};
+}
+
+
+
 1;
 # vim: ts=4

Modified: trunk/wiaflos/server/Reporting.pm
===================================================================
--- trunk/wiaflos/server/Reporting.pm	2008-08-17 13:21:33 UTC (rev 238)
+++ trunk/wiaflos/server/Reporting.pm	2008-08-17 13:59:29 UTC (rev 239)
@@ -29,6 +29,7 @@
 use wiaflos::constants;
 use wiaflos::server::config;
 use wiaflos::server::dblayer;
+use wiaflos::server::templating;
 use wiaflos::server::GL;
 
 use Math::BigFloat;
@@ -158,7 +159,226 @@
 }
 
 
+# Send report
+# Parameters:
+# 		Template	- Report template
+#		StartDate	- Start date
+#		EndDate		- Start date
+#		SendTo		- Send to,  email:  ,  file:  , return
+# Optional:
+#		Subject		- Subject of the report
+sub sendReport
+{
+	my ($detail) = @_;
 
+	
+	# Verify Template
+	if (!defined($detail->{'Template'}) || $detail->{'Template'} eq "") {
+		setError("Template was not provided");
+		return ERR_PARAM;
+	}
 
+	# Verify SendTo
+	if (!defined($detail->{'SendTo'}) || $detail->{'SendTo'} eq "") {
+		setError("SendTo was not provided");
+		return ERR_PARAM;
+	}
+
+	# GL search criteria
+	my $search;
+	$search->{'StartDate'} = $detail->{'StartDate'};
+	$search->{'EndDate'} = $detail->{'EndDate'};
+	my $entries = getChartOfAccounts($search);
+	if (ref $entries ne "ARRAY") {
+		setError(Error());
+		return $entries;
+	}
+
+	# Pull in config
+	my $config = wiaflos::server::config::getConfig();
+
+	# Check if subject was overridden
+	my $subject = (defined($detail->{'Subject'}) && $detail->{'Subject'} ne "") ? $detail->{'Subject'} : "Chart of accounts";
+
+	# Build array of stuff we can use
+	my $vars = {
+		'WiaflosString' => $GENSTRING,
+
+		# Client
+		'StartDate' => defined($detail->{'StartDate'}) ? $detail->{'StartDate'} : "-",
+		'EndDate' => defined($detail->{'EndDate'}) ? $detail->{'EndDate'} : "CURRENT",
+	};
+
+	# Load invoice line items
+	foreach my $item (@{$entries}) {
+		my $titem;
+
+		# Fix some stuff up
+		$titem->{'Number'} = $item->{'Number'};
+		$titem->{'Name'} = $item->{'Name'};
+		$titem->{'DebitAmount'} = defined($item->{'DebitAmount'}) ? sprintf('%.2f',$item->{'DebitAmount'}) : undef;
+		$titem->{'CreditAmount'} = defined($item->{'CreditAmount'}) ? sprintf('%.2f',$item->{'CreditAmount'}) : undef;
+		
+		$titem->{'ReportWriterCategoryCode'} = $item->{'RwCatCode'};
+		
+		$titem->{'Children'} = $item->{'Children'};
+
+		# File under account number
+		$vars->{'AccountBalances'}{$titem->{'Number'}} = $titem;
+		# File under report write category code
+		push(@{$vars->{'ReportWriterCategoryToAccounts'}{$titem->{'ReportWriterCategoryCode'}}},$titem);
+	}
+	
+	# Load report write categories
+	$entries = wiaflos::server::GL::getGLRwCats();
+	if (ref($entries) ne "ARRAY") {
+		setError(wiaflos::server::GL::Error());
+		return $entries;
+	}
+	foreach my $item (@{$entries}) {
+		$vars->{'ReportWriterCategories'}{$item->{'Code'}} = $item;
+	}
+	use Data::Dumper; print (STDERR Dumper($vars));
+
+	# Set template to use
+	my $template = $detail->{'Template'};
+
+	# Check where report must go
+	if ($detail->{'SendTo'} =~ /^file:(\S+)/i) {
+		my $filename = $1;
+
+		# Load template
+		my $res = loadTemplate($template,$vars,$filename);
+		if (!$res) {
+			setError("Failed to load template '$template': ".wiaflos::server::templating::Error());
+			return ERR_SRVTEMPLATE;	
+		}
+
+	# Write out using email
+	} elsif ($detail->{'SendTo'} =~ /^email(?:\:(\S+))?/i) {
+		# Pull in email address user specified
+		my $emailAddy = $1;
+
+		# Verify SMTP server is set
+		my $server = $config->{'mail'}{'server'};
+		if (!defined($server) || $server eq "") {
+			setError("Cannot use report emailing if we do not have an SMTP server defined");
+			return ERR_SRVPARAM;
+		}
+
+		# Check if we have a email addy
+		if (!defined($emailAddy) || $emailAddy eq "") {
+			setError("No email address defined to send reports to");
+			return ERR_PARAM;
+		}
+
+		# Report filename
+		(my $reportFilename = "report.html") =~ s,/,-,g;
+		# Report signature filename
+		my $rprtSignFilename = $reportFilename . ".asc";
+
+
+		# If we must, pull in email body
+		my $message_template = $config->{'reports'}{'email_message_template'};
+		my $emailBody = "";
+		if (defined($message_template) && $message_template ne "") {
+			# Variables for our template
+			my $vars2 = {
+				'ReportFilename' => $reportFilename,
+				'ReportSignatureFilename' => $rprtSignFilename,
+			};
+			# Load template
+			my $res = loadTemplate($message_template,$vars2,\$emailBody);
+			if (!$res) {
+				setError("Failed to load template '$message_template': ".wiaflos::server::templating::Error());
+				return ERR_SRVTEMPLATE;	
+			}
+
+			$emailBody =~ s/(?<!\r)\n/\r\n/sg; # Sanitize eol for crypt-gpg
+		}
+
+		# This is our entire report
+		my $reportData = "";
+		my $res = loadTemplate($template,$vars,\$reportData);
+		if (!$res) {
+			setError("Failed to load template '$template': ".wiaflos::server::templating::Error());
+			return ERR_SRVTEMPLATE;	
+		}
+		$reportData =~ s/(?<!\r)\n/\r\n/sg; # Sanitize eol, needed to fix bug in crypt-gpg where it mangles \n
+
+		# See if we must use GPG
+		my $use_gpg_key = $config->{'reports'}{'use_gpg_key'};
+		my $sign;
+		if (defined($use_gpg_key) && $use_gpg_key ne "") {
+			# Setup GnuPG
+			my $gpg = new Crypt::GPG;
+			$gpg->gpgbin('/usr/bin/gpg');
+			$gpg->secretkey($use_gpg_key);
+			$gpg->armor(1);
+			$gpg->comment("$APPNAME v$VERSION ($APPURL)");
+			# Sign report
+			$sign = $gpg->sign($reportData);
+			if (!defined($sign)) {
+				setError("Failed to sign report");
+				return ERR_SRVEXEC;
+			}
+		}
+
+		# Create message
+		my $msg = MIME::Lite->new(
+				From	=> $config->{'reports'}{'email_from'},
+				To		=> $emailAddy,
+				Bcc		=> $config->{'reports'}{'email_bcc'},
+				Subject	=> $subject,
+				Type	=> 'multipart/mixed'
+		);
+
+		# Attach body
+		$msg->attach(
+				Type	=> 'TEXT',
+				Encoding 	=> 'quoted-printable',
+				Data	=> $emailBody,
+		);
+
+		# Attach report
+		$msg->attach(
+				Type	=> 'text/html',
+				Encoding	=> 'quoted-printable',
+				Data	=> $reportData,
+				Disposition	=> 'attachment',
+				Filename	=> $reportFilename
+		);
+
+		# If we have signature, sign report
+		if (defined($sign)) {
+			# Attach signature
+			$msg->attach(
+					Type	=> 'text/plain',
+					Encoding	=> 'quoted-printable',
+					Data	=> $sign,
+					Disposition	=> 'attachment',
+					Filename	=> $rprtSignFilename
+			);
+		}
+
+		# Send email
+		my @SMTPParams;
+		if (!(my $res = $msg->send("smtp",$server))) {
+			setError("Failed to send report via email server '$server'");
+			return ERR_SRVEXEC;
+		}
+	
+	} else {
+		setError("Invalid SendTo method provided");
+		return ERR_PARAM;
+	}
+
+
+	return RES_OK;
+}
+
+
+
+
 1;
 # vim: ts=4



More information about the wiaflos-devel mailing list