Move toward the paperless office with images ready for accounting audits

Enhance accounting documentation with XML and PHP

Managers regularly provide auditors with supporting documentation. In a paper-based office, this can become an inconvenient and difficult task. Explore how XML, together with PHP and image functions, assists in the auditing process and also provides efficient and comprehensive indexing support to multiple managers.

Colin Beckingham, Writer and Researcher, Freelance

Colin Beckingham is a freelance researcher, writer, and programmer who lives in eastern Ontario, Canada. Holding degrees from Queen's University, Kingston, and the University of Windsor, he has worked in a rich variety of fields including banking, horticulture, horse racing, teaching, civil service, retail, and travel and tourism. The author of database applications and numerous newspaper, magazine, and online articles, his research interests include open source programming, VoIP, and voice-control applications on Linux. You can reach Colin at colbec@start.ca.



14 June 2011

Also available in Chinese Japanese Spanish

Suppose the company auditor approaches your paper-based office and requests the supporting documentation for a transaction shown in your accounts. This request is not a problem when the documents are few and easily found in your paper records. Audits, however, tend to be thorough, and transactions that merit an audit are often the complicated ones involving many documents that demand that you spend time tracing them. The probability that one or another testimonial goes astray increases with that complexity. If a single document is not traceable, the whole process takes on a shadow of doubt.

Frequently used acronyms

  • HTML: Hypertext Markup Language
  • PDF: Portable Document Format
  • XML: Extensible Markup Language

One reason documents become untraceable in a paper office is convoluted and competitive indexing systems. This manager wants a document stored in one file, and that manager wants the same document stored in a different file. Physical duplicates to satisfy both increase the bulk storage requirement. Arguments arise over which is the original, authoritative document.

A thoroughly professional accounting system allows details concerning related documents to be stored in the system with the transaction details so that retrieval is quick and easy. Where this facility is not provided, technology can still provide a workaround. This article explores how XML and PHP can provide the structure and retrieval mechanism to give this kind of auditing support.

An example transaction from the audit point of view

Documents associated with an accounting transaction might follow this pattern:

  • Board resolution containing decision to contract
  • Contract draft and discussion
  • One or more of these documents:
    • Manager's justification for sole sourcing
    • Multiple quotes obtained from qualified suppliers
    • Manager's justification of choice from quotes submitted
  • Signed contract with bid winner, together with supplemental agreements
  • Invoices, and for each:
    • Certification of work completed
    • Canceled cheque or other certification of payment and receipt
  • Final certification of work completed
  • Documents related to taxes paid

In this case, the executive branch makes a decision to expend funds. The manager draws up a contract that fulfills the requirements and initiates a bidding process by calling for tenders. A supplier is chosen according to board contracting rules, and the contract is signed. Payments to the contractors, each of which probably requires its own transaction in the accounts, call for a certification of work completed and the payment made. Each stage requires a physical document or authoritative substitute that the manager can present to the auditor.

A handwritten book or file containing details of documents is quite workable in small offices. In an auditing context, however, technology has the advantage of being both fast and scalable.


XML document database

You don't have to use XML as your back end, but an XML document is just a text file and so it is fully transparent and readable in small quantities. Consider the code in Listing 1.

Listing 1. The XML back end
<?xml version="1.0" encoding="UTF-8"?>
<auditList>
  <projects>
    <project projid="xyz987">
      <boardMinute>2011-04-07-xxxx</boardMinute>
      <draftContractA>2011-04-07-xxxx</draftContractA>
      <contractA>2011-04-07-xxxx</contractA>
      <contractB>2011-04-08-xxxx</contractB>
      <contractC>2011-04-09-xxxx</contractC>
      <workCertA>2011-04-11-xxxx</workCertA>
      <workCertB>2011-04-11-xxxx</workCertB>
      <workCertC>2011-04-11-xxxx</workCertC>
    </project>
  </projects>
  <transactions>
    <transaction accid="abc123" projid="xyz987">
      <soleSourceAuth></soleSourceAuth>
      <invoice>2011-04-11-xxxx</invoice>
      <cheque>2011-04-21-xxxx</cheque>
    </transaction>
    <transaction accid="def123" projid="xyz987">
      <sourceAuth>2011-04-07-xxxx</sourceAuth>
      <invoice>2011-04-11-xxxx</invoice>
      <cheque>2011-04-21-xxxx</cheque>
    </transaction>
    <transaction accid="ghi123" projid="xyz987">
      <sourceAuth>2011-04-07-xxxx</sourceAuth>
      <invoice>2011-04-11-xxxx</invoice>
      <cheque>2011-04-21-xxxx</cheque>
    </transaction>
  </transactions>
</auditList>

The markup in Listing 1 describes a basic system that is useful to both the accounting department and the project manager. The auditList element is the root and has two child elements—projects and transactions—each of which is a container for details relevant to the eponymous department. The original physical documents are kept in a binder with a separate binder for each day. As documents are added to the binder, they are given a unique consecutive number. Based on the date and the number, you can easily find any single document. The work for this project calls for three separate contractors—one is sole-sourced, and the others are sourced competitively. The project manager sees all the contracts as part of the same record because he thinks on a project-wide basis. The accounting manager needs a transaction-based list, so his records will refer to only one payment. The accid attribute will be the unique transaction ID number that the accounting system assigns to that transaction. This ID provides the positive link between the accounting and filing systems. Transactions also contain an attribute that relates to the project manager's list (projid), and this also works in the reverse direction, enabling the linking of project records to transactions.

Note: The sole-source authorization for contract A is missing: This omission will be a red flag for the auditor. This authorization is deliberately left blank at this point as a trap for a verification check.

This file can be visually read and interpreted without further technology, provided the list is short. In more extensive lists, you need some way of retrieving the information efficiently. There are many ways of doing this; one way is with PHP and the SimpleXML library of functions.


PHP document retrieval

From the accounting point of view, the key into the list is the unique ID that the accounting system assigns to the transaction. The code in Listing 2 is intended to pull from the list either all transactions if no filter is specified or a single transaction together with the related project information.

Listing 2. Accounting query
<?php
$transFilter = $argv[1];
$xml = simplexml_load_file("backend.xml");
echo "=====\nSummary for accounts section\n";
if (isset($transFilter)) {
  echo "=====\nTransaction filter $transFilter\n=====\n";
} else {
  echo "=====\nNo filter - showing all transactions\n=====\n";
}
foreach ($xml->transactions->transaction as $t) {
  if (!$transFilter or $t['accid'] == $transFilter) {
    if ($t['accid'] == $transFilter) {
      $projectFilter = trim($t['projid']);
    }
    echo "Detail for transaction ".$t['accid']."\n";
    foreach ($t->children() as $tc) {
      echo $tc->getName()." : ".$tc."\n";
    }
  }
}
if (isset($projectFilter)) {
  echo "=====\nAssociated project $projectFilter\n=====\n";
  foreach ($xml->projects->project as $p) {
    if ($p['projid'] == trim($projectFilter)) {
      echo "Detail for project ".$p['projid']."\n";
      foreach ($p->children() as $pc) {
          echo $pc->getName()." : ".$pc."\n";
      }
    }
  }
}
echo "=====\nEnd of search\n=====\n";
?>

The code in Listing 2 first looks for a parameter passed in the $argv array. There might be one, or there might not. Then, the XML from Listing 1 is loaded into an object for further processing. Because the query is submitted by the accounting section, it goes straight to the transactions section and, depending on whether a filter is present, loops through all the transactions or looks for the transaction that matches the requested identifier. If the correct accid is found, the associated projid or project attribute is saved in a variable for later reference. If a specific transaction was requested, the second loop kicks in, examining the associated project details and printing them.

This script is called in the following way from the command line, where acct.php is the name of the script and def123 is the ID of the transaction obtained from the accounting system:

> php acct.php def123

Listing 3 shows the result of this query run against the data in Listing 1.

Listing 3. Output
=====
Summary for accounts section
=====
Transaction filter def123
=====
Detail for transaction def123
sourceAuth : 2011-04-07-xxxx
invoice : 2011-04-11-xxxx
cheque : 2011-04-21-xxxx
=====
Associated project xyz987
=====
Detail for project xyz987
boardMinute : 2011-04-07-xxxx
draftContractA : 2011-04-07-xxxx
contractA : 2011-04-07-xxxx
contractB : 2011-04-08-xxxx
contractC : 2011-04-09-xxxx
workCertA : 2011-04-11-xxxx
workCertB : 2011-04-11-xxxx
workCertC : 2011-04-11-xxxx
=====
End of search
=====

This output provides the information required to retrieve the stored physical copies of the documents. It returns both the detailed keys for the specific transaction plus the project context. The auditor then has access to the board resolution, the contract, the source authorization, invoice, work certification, and canceled cheque. If the documents are all where they should be, this is the whole story—everyone is happy, and the auditor goes away impressed with your efficiency and organization.


PHP integrity checking

A script can not only retrieve document information but also advise when documentation is incomplete. As noted earlier, it is important for compliance with board rules that either a justification for sole source exists or an appropriate choice is selected from multiple submitted bids. The code in Listing 4 provides such a check.

Listing 4. Integrity check
<?php
$xml = simplexml_load_file("backend.xml");
echo "=====\nIntegrity check\n=====\n";
$i = 0;
foreach ($xml->transactions->transaction as $t) {
  if ($t['accid'] == "" or !$t['accid']) {
    $accid = "# $i #";
    echo "Transaction accid missing at transaction $accid\n";
  } else {
    $accid = $t['accid'];
  }
  if (!$t['projid']) echo "Project id missing at transaction $accid\n";
  if ($t->soleSourceAuth=="" and $t->sourceAuth=="") 
      echo "Authorization problem at $accid\n";
  $i++;
}
echo "=====\nEnd of search\n=====\n";
?>

The script in Listing 4 begins by loading the XML back end into an object. It then looks at each transaction to determine whether an accid attribute is present. If that attribute is missing, the script prints a warning together with a count of the record examined. It then checks for an associated project ID number and prints a warning if one is absent. Finally, the code verifies that either a soleSourceAuth or a sourceAuth element is present and has a valid value, which in this case is not an empty string. If this test fails, the script prints a warning. You can perform this kind of integrity checking in other ways, but SimpleXML offers a quick and easy programmatic method.

Call this script in the following way, without arguments, because the code checks the whole list:

> php integrity.php

This call results in the warning provided in Listing 5 because you are checking the data in Listing 1, which has a known document reference missing.

Listing 5. Output from Listing 4
=====
Integrity check
=====
Authorization problem at abc123
=====
End of search
=====

Documents as images

Now that you have basic access to your audit information, a further profitable step is to ensure that all documents are available as images. Then, when an auditor requests the information, you quickly send the auditor a link to the online document collection together with a polite invitation for the auditor to contact you if further detail is required and get on with the far more important business of keeping your records up to date.

Here is Listing 1 again, this time with image information (see Listing 6).

Listing 6. XML back end with image attributes
<?xml version="1.0" encoding="UTF-8"?>
<auditList>
  <projects>
    <project projid="xyz987">
      <boardMinute image="minute987.pdf">2011-04-07-xxxx</boardMinute>
      <draftContractA image="contractdraft987.pdf">2011-04-07-xxxx</draftContractA>
      <contractA image="contract987A.jpg">2011-04-07-xxxx</contractA>
      <contractB image="contract987B.jpg">2011-04-08-xxxx</contractB>
      <contractC image="contract987C.jpg">2011-04-09-xxxx</contractC>
      <workCertA image="workcert987A.pdf">2011-04-11-xxxx</workCertA>
      <workCertB image="workcert987B.pdf">2011-04-11-xxxx</workCertB>
      <workCertC image="workcert987C.pdf">2011-04-11-xxxx</workCertC>
    </project>
  </projects>
  <transactions>
    <transaction accid="abc123" projid="xyz987">
      <soleSourceAuth image="ssauth987A.odt"></soleSourceAuth>
      <invoice image="invoice987A.png">2011-04-11-xxxx</invoice>
      <cheque image="cheque987A.jpg"></cheque>
    </transaction>
    <transaction accid="def123" projid="xyz987">
      <sourceAuth image="sourceauth987B.odt">2011-04-07-xxxx</sourceAuth>
      <invoice image="invoice987B.png">2011-04-11-xxxx</invoice>
      <cheque image="cheque987B.jpg"></cheque>
    </transaction>
    <transaction accid="ghi123" projid="xyz987">
      <sourceAuth image="sourceauth987C.odt">2011-04-07-xxxx</sourceAuth>
      <invoice image="invoice987C.png">2011-04-11-xxxx</invoice>
      <cheque image="cheque987C.jpg"></cheque>
    </transaction>
  </transactions>
</auditList>

Listing 6 is basically the same as Listing 1, with a bit more detail added. Some elements now have an attribute image, which contains the name of an image or document stored as a PDF, JPG, ODT, or PNG file. Note that in this case, the bank does not return physical cheques but provides JPG images online after the cheques have been through the clearing system. Therefore, images are available, but no physical documents are stored.

The availability of images calls for the accounting department to make modifications to the query for the benefit of the auditor. Listing 7 shows the updated query.

Listing 7. PHP query with images
<?php
$transFilter = $argv[1];
if (!$transFilter) die ('No transaction specified\n');
$path2images = "/path/to/images/";
echo "=====\nAudit response HTML\n=====\n";
$xml = simplexml_load_file("backend2.xml");
echo "=====\nTransaction $transFilter\n=====\n";
foreach ($xml->transactions->transaction as $t) {
  if ($t['accid'] == $transFilter) {
    $projectFilter = trim($t['projid']);
    echo "Detail for accounting transaction '".$t['accid']."'\n";
    foreach ($t->children() as $tc) {
      echo $tc->getName()." : ".$tc." image "
	."<a href='$path2images".$tc['image']."'>".$tc['image']."</a>\n";
    }
  }
}
foreach ($xml->projects->project as $p) {
  if ($p['projid'] == $projectFilter) {
    echo "Detail for project ".$p['projid']."\n";
    foreach ($p->children() as $pc) {
      echo $pc->getName()." : ".$pc." image "
	."<a href='$path2images".$pc['image']."'>".$pc['image']."</a>\n";
    }
  }
}
echo "=====\nEnd of list\n=====\n";
?>

Listing 7 begins by expecting that the search is for a specific transaction. If no accounting ID is specified as a parameter, the script stops with a warning. Otherwise, it loads the modified back end into a SimpleXML object and searches the transactions for that accounting ID. When it is found, the associated project ID is stored for later use. The script then prints the information for associated documents. Now, the output contains both a reference to the physical document (where one exists) and a link embedded in HTML tags to the image stored somewhere on the network.

The following command-line interface command:

> php auditresponsehtml.php def123

produces the output in Listing 8.

Listing 8. PHP query with images
=====
Audit response HTML
=====
=====
Transaction def123
=====
Detail for accounting transaction 'def123'
sourceAuth : 2011-04-07-xxxx image 
  <a href='/path/to/images/sourceauth987B.odt'>sourceauth987B.odt</a>
invoice : 2011-04-11-xxxx image 
  <a href='/path/to/images/invoice987B.png'>invoice987B.png</a>
cheque :  image 
  <a href='/path/to/images/cheque987B.jpg'>cheque987B.jpg</a>
Detail for project xyz987
boardMinute : 2011-04-07-xxxx image
  <a href='/path/to/images/minute987.pdf'>minute987.pdf</a>
draftContractA : 2011-04-07-xxxx image
  <a href='/path/to/images/contractdraft987.pdf'>contractdraft987.pdf</a>
contractA : 2011-04-07-xxxx image
  <a href='/path/to/images/contract987A.jpg'>contract987A.jpg</a>
contractB : 2011-04-08-xxxx image
  <a href='/path/to/images/contract987B.jpg'>contract987B.jpg</a>
contractC : 2011-04-09-xxxx image
  <a href='/path/to/images/contract987C.jpg'>contract987C.jpg</a>
workCertA : 2011-04-11-xxxx image
  <a href='/path/to/images/workcert987A.pdf'>workcert987A.pdf</a>
workCertB : 2011-04-11-xxxx image
  <a href='/path/to/images/workcert987B.pdf'>workcert987B.pdf</a>
workCertC : 2011-04-11-xxxx image
  <a href='/path/to/images/workcert987C.pdf'>workcert987C.pdf</a>
=====
End of list
=====

A number of assumptions are made here to keep things simple. First, the script assumes that all the files are there and correctly named; second, it assumes that the auditor understands the indexing system. And third, it assumes that the auditor's browser can handle the document type, perhaps as a download, as an add-on, or opened by an application.


PHP and image functions

You can also manipulate images in some way before they are delivered to the reader. Say the image needs to be marked so that if printed, the new document cannot be mistaken for the original archive copy. PHP offers a number of image functions that can, for example, print a large "VOID" across the document or maybe the transaction ID in one corner.

Listing 9 provides an example PHP fragment for adding a string to a document before it is streamed to a browser.

Listing 9. Add detail to images
<?php
$im = imagecreatefromjpeg("/path/to/images/contract987C.jpg");
$textcolor = imagecolorallocate($im, 0, 0, 100);
imagestring($im, 5, 55, 55, 'Archive: 2011-04-11-XXXX', $textcolor);
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

In this code, the image is created from the original document, the overlay text colour is defined, and then the string Archive: 2011-04-11-XXXX is printed in the top left corner as part of the image, overprinting anything that was in that location before, 55 pixels down and across. The text colour should ideally take into account the colour of the background on which it will appear to make it clearly legible. The final image is then delivered to the browser.

Other PHP image functions include testing the image to see how large it is and, if the size is over a certain recommended limit, scaling the image to a more reasonable size for the auditor's screen.


Indexing for other departments

Given that the examples here try to allow for both accounting and project department indexing of one set of physical files, it should be a simple matter to have other sections in the XML back end as children of the root element to act as containers for other departments. As long as the well-formedness of the overall document is maintained, PHP scripts can include or ignore other sections with ease.

If a new board manager wants to keep his board documents separate, this approach will call for some changes to Listing 1 and Listing 6. Taking the former as an example, see Listing 10.

Listing 10. XML back end with added section
<?xml version="1.0" encoding="UTF-8"?>
<auditList>
  <boardMinutes>
      <boardMinute boardMin="bm1234">2011-04-07-xxxx</boardMinute>
    ...
  </boardMinutes>
  <projects>
    <project projid="xyz987" boardMin="bm1234">
      <draftContractA>2011-04-07-xxxx</draftContractA>
      <contractA>2011-04-07-xxxx</contractA>
      ...
    </project>
  </projects>
  <transactions>
    ...
  </transactions>
  
</auditList>

In this modification of Listing 1, the board minute entry that used to be in the projects section has been moved to a new boardMinutes container, where an index boardMin has been added to a new boardMinute element in the new container and the same index has been added as an attribute to the related project element. Now, the projects section can find the related board information and vice versa. In this way, satisfying the needs of different managers is just a matter of appropriate container elements and indexing attributes.


Conclusion

In this article, you explored some tools for dealing with an auditor's request for supporting documentation. Clearly, PHP working in cooperation with a document list organized as an XML file can help ensure that you can locate and present required documents with minimal delay. Organizing information this way helps to shift the burden of the work from a stressful, time-limited situation when the audit request comes in to an ongoing task of careful document classification and retrieval.

The setup described in this article can become more complicated with the introduction of XML schemas and doctypes to control the addition and entry of items and to check for missing elements. PHP and SimpleXML functions are quite sensitive to the well-formedness of the XML, so hand-editing files with a plain editor is not as effective as a specialist application such as Eclipse (see Resources), which works to ensure that the resulting document after editing is well formed.

The totally paperless office is still a rarity in the business world. One reason is that actively participating offices need to be running compatible software. With all the elements of this type of system as open source and free, the barriers to full adoption then become employee training and managerial reluctance to change.

Resources

Learn

  • PHP and SimpleXML: Read more about this tool set that converts XML to an object that can be processed with normal property selectors and array iterators.
  • SimpleXML processing with PHP (Elliotte Rusty Harold, developerWorks, October 2006): Discover the SimpleXML extension, which is bundled with PHP version 5 and enables PHP pages to query, search, modify, and republish XML in a PHP-friendly syntax.
  • Get started with the Eclipse Platform (Chris Aniszczyk and David Gallardo, developerWorks, July 2007): Learn more about developing in Eclipse.
  • Getting started with Eclipse, from the DB2 on Campus book series: Check out the free eBook. Find out what Eclipse is all about and practice using hands-on exercises.
  • Introduction to XML (Doug Tidwell, developerWorks, August 2002): Get the basics about XML: what it is, why it was developed, and more in this tutorial.
  • Thinking XML: Analyze financial reporting using XBRL (Uche Ogbuji, developerWorks, January 2009): Read about more advanced uses of XML in accounting and learn to interpret Extensible Business Reporting Language well enough to make sense of financial filings.
  • XML development with Eclipse (Pawel Leszek, developerWorks, April 2003): Check out ideas on editing XML in a solid editor and harness the power of XML with Eclipse.
  • Scripting in PHP: Learn more about this widely-used, general-purpose scripting language that is especially suited for web development and can be embedded into HTML.
  • More articles by this author (Colin Beckingham, developerWorks, March 2009-current): Read articles about XML, voice recognition, XHTML, PHP, SMIL, and other technologies.
  • New to XML? Get the resources you need to learn XML.
  • XML area on developerWorks: Find the resources you need to advance your skills in the XML arena. See the XML technical library for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks
  • IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
  • developerWorks technical events and webcasts: Stay current with technology in these sessions.
  • developerWorks on Twitter: Join today to follow developerWorks tweets.
  • developerWorks podcasts: Listen to interesting interviews and discussions for software developers.
  • developerWorks on-demand demos: Watch demos ranging from product installation and setup for beginners to advanced functionality for experienced developers.

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into XML on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Industries, Open source
ArticleID=679172
ArticleTitle=Move toward the paperless office with images ready for accounting audits
publish-date=06142011