Printed Forms: Difference between revisions

From IHRIS Wiki
No edit summary
 
(47 intermediate revisions by 5 users not shown)
Line 1: Line 1:
This is a design document for the printed forms module.
This tutorial describes how to create "standardized" or "official" PDF forms based on the data in the system.  This could be useful for generating training certificates, generating form letters on a position change, or validating who works in a facility or district.


The printed forms module is used to print "standardized" or "official" forms based upon the data in the system. For example, it might be the registration number for a nurse.
This module first appears in version 4.0.5 of the iHRIS Suite.


The output will be either PDF (which Carl prefers) or html (which Luke prefers).
Depending on your needs, you may wish to look at these other methods for standardized form generation:
*[[Printed Forms form Relationships (ODT)]]
*[[Standardized Letters (ODT)]]
*[[Printed Forms with Reports (ODT)]]


==Source Data==
==Source Data==
Line 10: Line 13:
==Page Interaction==
==Page Interaction==
===Print===
===Print===
At the first phase of this module, the only interaction is to produces the printed forms based on what is stored in [[#Magic Data Details|magic data]].  There will be no "document design" component.  The standard form will be accessed through a URL with the name of the standardized form and a GET/POST variable containing one or more of the id's for the primary form in the form relationship.  For example:
At the first phase of this module, the only interaction is to produce the printed forms based on what is stored in [[#Magic Data Details|magic data]].  There will be no "document design" component.  The standard form will be accessed through a URL with the name of the standardized form and a GET/POST variable containing one or more of the id's for the primary form in the form relationship.  For example:
  http://'''<SITE_URL>'''/PrintedForms/print/'''registration'''?ids[]=person|12&ids[]=person|14&ids=[]person|22
  http://'''<SITE_URL>'''/PrintedForms/print/'''registration'''?ids[]=person|12&ids[]=person|14&ids=[]person|22


Line 37: Line 40:
It will:
It will:
*check to see if 'generated_form' is a child form of person.  If not execution stops.
*check to see if 'generated_form' is a child form of person.  If not execution stops.
*for each of the id's it will created the PDF form (only on each page!) and save it as a child ''generated_doc'' form
*for each of the id's it will created the PDF form (only one on each page/document) and save it as a child ''generated_doc'' form
 
===View Person===
There should be links added to the view person page to the appropriate menu page as well as showing a list of the archived forms for that person sorted by type and date.


==Magic Data Details==
==Magic Data Details==
Line 50: Line 50:
The details for a specific form are as follows (all measurements are in mm):
The details for a specific form are as follows (all measurements are in mm):
*relationship: Required scalar node. the name of the form relationship that this form is based off of.  It needs to be the name of a child node of ''/modules/CustomReports/relationships''
*relationship: Required scalar node. the name of the form relationship that this form is based off of.  It needs to be the name of a child node of ''/modules/CustomReports/relationships''
*displayName: Optional scalar node.  The name of the printed letter as displayed to the end user.
*archive: Optional scalar node.  If set it should be a named form in the relationship.  If it is a valid named form, then it will enable archiving of this printed letter as a child form of the corresponding named form.  You should ensure that this form has ''generated_doc'' as a valid [[Defining Forms | child form]].
*layout_details: Optional parent node describing the page layout details for the form.  It contains the following child nodes.
*layout_details: Optional parent node describing the page layout details for the form.  It contains the following child nodes.
**encoding:  Optional scalar node. The encoding used by the renderer(PDF). Defaults to ASCII
**encoding:  Optional scalar node. The encoding used by the renderer(PDF). Defaults to ASCII
Line 69: Line 71:
**bg_color: Optional background color. Use html style hex colors.  Defaults to 'none' for transparent.
**bg_color: Optional background color. Use html style hex colors.  Defaults to 'none' for transparent.
**style: Optional scalar node.  Default to blank.  Can contain any of the following characters, B for bold, U for underline, I for italic
**style: Optional scalar node.  Default to blank.  Can contain any of the following characters, B for bold, U for underline, I for italic
*elements: Parent node.  Children should be numerically indexed.  Elements are added to the standard document in increasing numeric order of the node name of the element. Elements can be composed of sub-elements which can be composed in turn of sub-sub-elements, which can be composed of in turn of sub-sub-elements..The properties of an element are inherited by all of its sub-elements. Each of the child nodes will contain the following:
*elements: Parent node.  Children should be numerically indexed.  Elements are added to the standard document in increasing numeric order of the node name of the element.  Each of the child nodes will contain the following:
**elements: An optional parent node containing a list of all its sub-elements.  The details of a sub-element are as above.
**text_properties: An optional parent node defining the properties which applies to this node and all of its sub-elements of this.  The definition is the same as above.
**text_properties: An optional parent node defining the properties which applies to this node and all of its sub-elements of this.  The definition is the same as above.
**element:  An optional parent node which describe some visual element to be placed:
**type: Required scalar node.  Should be one of 'text' 'image' or 'value'     
***type: Required scalar node.  Should be one of 'text' 'image' or 'value'     
**definition:  Depends on the type.  See below.  
***definition:  Depends on the type.  See below.  


===Definition for type: Text===
===Definition for type: Text===
Line 82: Line 82:
**'''formname'''+'''field''': a report form fields to substitute into the printf.  E.g. "person+surname,person+fisrtname,registation+number":
**'''formname'''+'''field''': a report form fields to substitute into the printf.  E.g. "person+surname,person+fisrtname,registation+number":
**+'''relationshipFunction''':  The evaluation of the named function in the the form relationship.  Example +age65 which be the year the person turns 65 in the staff relationship
**+'''relationshipFunction''':  The evaluation of the named function in the the form relationship.  Example +age65 which be the year the person turns 65 in the staff relationship
**++date('''XYZ'''): The data formatted according to '''XYZ'''  (unquoted) via [http://us2.php.net/manual/en/function.strftime.php: strfrtime] functions.  Example ++date(%Y) is the four digit year
**++date('''XYZ'''): The data formatted according to '''XYZ'''  (unquoted) via [http://us2.php.net/manual/en/function.strftime.php strfrtime] functions.  Example ++date(%Y) is the four digit year
**++date:  The date.  This is the same as ++date(%x).     
**++date:  The date.  This is the same as ++date(%x).     
**++user:  The name of the user printing the form
**++user:  The name of the user printing the form
Line 92: Line 92:


===Definition for Type: Image===
===Definition for Type: Image===
*image: Required standard node. the name of the image file to place.  the search path used is "PDF_IMAGES"
*image: Required standard node. the name of the image file to place.  It can either be:
**A file name, in which case the search path used is "PDF_IMAGES"
**A string like "form://'''form+field'''"  where form is a named form in the relationship and field is a field of time IMAGE (e.g. "form://passport+image")
*horiz_min:  Required numeric scalar node. The left most coordinate to place the image.
*horiz_min:  Required numeric scalar node. The left most coordinate to place the image.
*vert_min: Required numeric scalar node.  The  top most coordinate to place the image
*vert_min: Required numeric scalar node.  The  top most coordinate to place the image
Line 98: Line 100:
*vert_max: Optional numeric scalar node.  The  bottom most coordinate to place the image.  If set, image is rescaled if needed.
*vert_max: Optional numeric scalar node.  The  bottom most coordinate to place the image.  If set, image is rescaled if needed.


==Processing Content==
==Example==  
The standardized form should be produced on the standardized form class by something like:
===Defining the Printed Form features===
<source lang='php'>
For example, to produce a Staff Hire Letter in iHRIS Manage you could define it as:
function processContent($output_type, $layout_details, $contentNode, $ids) {
<source lang='xml'>
     $outputClass = "PrintedForms_Output_$output_type";   
  <configurationGroup name="sample-hire-letter" path="/modules/PrintedForms/forms/sample_hire_letter">
     $outputObj  = new $outputClass($layout_details);
    <configuration name="relationship">
     foreach ($ids as $id) {
      <value>staff</value>
       if (!$this->report->hasRow($id)) {
    </configuration>
         continue;
     <configuration name="archive">
       }
      <value>person</value>
       $outputObj->setValues($this->report->getRow($id));
    </configuration>
       $outputObj->addContent($contentNode);
     <configuration name="displayName">
  }
      <value>Staff Hire Letter</value>
  return $outputObj
    </configuration>
  }
     <configurationGroup name="elements">
</source>
      <configurationGroup name="0">
        <configuration name="type">
          <value>image</value>
        </configuration>
        <configuration name="definition" values='many' type='delimited'>
          <value>image:iHRISManage_logo_whiteBG.png</value>
          <value>horiz_min:5</value>
          <value>vert_min:1</value>
        </configuration>
      </configurationGroup>
      <configurationGroup name="50">
        <configuration name="type">
          <value>text</value>
        </configuration>
        <configuration name="text_properties" values='many' type='delimited'>
          <value>style:I</value>
        </configuration>
        <configuration name="definition" values='many' type='delimited'>
          <value>horiz_min:33</value>
          <value>vert_min:6</value>
          <value>printf:Certification of Employment</value>
        </configuration>
      </configurationGroup>
       <configurationGroup name="51">
        <configuration name="type">
          <value>text</value>
        </configuration>
        <configuration name="text_properties" values='many' type='delimited'>
          <value>style:BU</value>
        </configuration>
        <configuration name="definition" values='many' type='delimited'>
          <value>horiz_min:33</value>
          <value>vert_min:12</value>
          <value>printf:Ministry of Health</value>
         </configuration>
       </configurationGroup>
 
       <configurationGroup name="52">
        <configuration name="type">
          <value>text</value>
        </configuration>
        <configuration name="definition" values='many' type='delimited'>
          <value>horiz_min:160</value>
          <value>vert_min:6</value>
          <value>printf:%s</value>
        </configuration>
        <configuration name="printf_args" path='definition/printf_args' values='many' type='delimited'>
          <value>0:++date(%e %B %Y)</value>
</configuration>
      </configurationGroup>
 
       <configurationGroup name="100">
        <configuration name="type">
          <value>text</value>
        </configuration>
        <configuration name="definition" values='many' type='delimited'>
          <value>horiz_min:3</value>
          <value>vert_min:50</value>
          <value>printf:Dir Sir/Madam,
 
Please accept this letter as certification of employment for %s %s.


The standardized form output base class should have something like:
On %s, employment began as %s in the %s department of %s.
<source lang='php'>
  public function addConennt($contentNode) {
    $this->beginNewForm();  //goes to the space in the document to put a form
    $this->processContent($contentNode);   
  }


  protected function processConent($contentNode, $properties = array()) {
Sincerely,  
    $t_properties = array();
%s</value>
    $contentNode->getAsArray($t_properties,'properties',true);
        </configuration>
    $properties = I2CE_Util::array_merge($properties,$t_properties);  //something like this
        <configuration name="printf_args" path='definition/printf_args' values='many' type='delimited'>
    $this->addElement($contentNode,$properties)
          <value>0:person+firstname</value>
    if ($contentNode->is_parent('elements')) {
          <value>1:person+surname</value>
        $keys = $contentNode->getChildNames('elements'));
          <value>2:staff+start_date</value>
        sort($keys)
          <value>3:position+title</value>
         foreach ($keys as $key) {
          <value>4:department+name</value>
          if (!$contentNode->is_parent("elements/$key")) {
          <value>5:facility+name</value>
              continue;
          <value>6:++user</value>
          }
         </configuration>
          $this->_processConent($contentNode->elements-$key,$properties);
      </configurationGroup>
        }
    </configurationGroup>
    }
   </configurationGroup>
   }
</source>
</source>


The addElement() method  will (after some validity checking) class should call something like the following methods:
===Creating a link to print the form===
*$this->add_Element_text($properties,$definition)
After that is set, then you need to open the view template for the form where you wish to place the link to print the PrinteForm.
*$this->add_Element_value($properties,$definition)
<source lang="xml">
*$this->add_Element_image($properties,$definition)
<span type="module" name="PrintedForms" ifenabled="true">
this is so that new element types and output can be added in as modules.
  <span type="module" if="PrintedForms->hasValidForms('sample_hire_letter')">
    <li task="printed_forms_can_access"><span type="form" href="PrintedForms/menu?id=" name="person:id">Sample Hire Letter</span></li>
  </span>
</span>
</source>
The above would mean the name of the PrintedForm is sample_hire_letter and its parent form is person.


This piece of code should be inserted favorably below the link to update the information of a form. (view_form_name.html)


==Web Interface/GUI Editor==
[[Category:Standardized Forms]][[Category:Review2013]]
This would be the last phase of this module and wouldy be on the "wish-list" side of things.  It would be a web interface to layout these printed forms, and the text, upload images etc.  This would be accomplished using the SwissConfig API.

Latest revision as of 13:35, 8 November 2013

This tutorial describes how to create "standardized" or "official" PDF forms based on the data in the system. This could be useful for generating training certificates, generating form letters on a position change, or validating who works in a facility or district.

This module first appears in version 4.0.5 of the iHRIS Suite.

Depending on your needs, you may wish to look at these other methods for standardized form generation:

Source Data

The source data for the printed form will be based on a form relationship.

Page Interaction

Print

At the first phase of this module, the only interaction is to produce the printed forms based on what is stored in magic data. There will be no "document design" component. The standard form will be accessed through a URL with the name of the standardized form and a GET/POST variable containing one or more of the id's for the primary form in the form relationship. For example:

http://<SITE_URL>/PrintedForms/print/registration?ids[]=person|12&ids[]=person|14&ids=[]person|22

Hitting this URL would cause the following to happen:

  • verify that a standardized form called registration exists
  • verify that the user has the appropriate permission to view this standardized form:
    • Check to see if the user has the task 'printed_forms_all_generate'
    • If not, check to see if the task 'printed_forms_generate_registration' exists and the user has this task
  • for each of the ids, person|12, person|14, person|22 fill out the details of the standardized report by using the corresponding row in the report table if it exists (see below).

Menu

One should be able to see which forms can be generated for a given id. Calling

http://<SITE_URL>/PrintedForms/menu?id=person|12

will show all the printed forms whose primary form is person. Then for each of these you will have a link to the corresponding print page.

You should also link to the corresponding archive page and show which PDF forms have already been archived for that person sorted by type and date.

Archive

You should also create a form, say generated_doc which contains the following fields:

  • document: A binary field which will contain the PDF it
  • date: the date it was generated by
  • type: the print standard form (e.g. registration in the above example)

When calling the archive page as:

http://<SITE_URL>/PrintedForms/archive/registration?ids[]=person|12&ids[]=person|14&ids=[]person|22

It will:

  • check to see if 'generated_form' is a child form of person. If not execution stops.
  • for each of the id's it will created the PDF form (only one on each page/document) and save it as a child generated_doc form

Magic Data Details

All standardized forms will be stored under the magic data node:

/modules/PrintedForms/forms

In the example above the details defining the registration form would stored under:

/modules/PrintedForms/forms/registration

The details for a specific form are as follows (all measurements are in mm):

  • relationship: Required scalar node. the name of the form relationship that this form is based off of. It needs to be the name of a child node of /modules/CustomReports/relationships
  • displayName: Optional scalar node. The name of the printed letter as displayed to the end user.
  • archive: Optional scalar node. If set it should be a named form in the relationship. If it is a valid named form, then it will enable archiving of this printed letter as a child form of the corresponding named form. You should ensure that this form has generated_doc as a valid child form.
  • layout_details: Optional parent node describing the page layout details for the form. It contains the following child nodes.
    • encoding: Optional scalar node. The encoding used by the renderer(PDF). Defaults to ASCII
    • hyphenation_file: Optional scalar node. File used for hyphenation. Defaults to hyph_en_US.dic'
    • orientation: Optional scalar node. Defaults to 'P' for portrait. The other option is 'L' for landscape
    • size: Optional scalar node. Defaults to 'A4' to describe the paper to be used. Should be one of the ISO 216 standard paper sizes, e.g. 'A4', or one of the North American paper sizes, e.g. 'letter' or 'legal'
    • rows: Optional scalar node: Defaults to 1. The number of rows of forms to be printed on the page.
    • cols: Optional scalar node: Defaults to 1. The number of columns of forms to be printed on the page.
    • border: Optional scalar node. Defaults to 0 if rows and columns are 1, otherwise it to defaults to 1. The width of the border drawn around the forms.
    • vert_pad: Optional scalar node. Defaults to 10. The vertical padding used on the page boundary
    • horiz_pad: Optional scalar node. Defaults to 10. The horizontal padding used on the page boundary
    • vert_pad_border: Defaults to 0. The vertical padding used between forms
    • horiz_pad_border: Defaults to 0. The vertical padding used between forms
  • text_properties: An optional parent node defining the default text properties of the element types of the document. Child node names are the name of the element types (image or text). Possible values are:
    • font: Optional scalar node. Defaults to helvetica. Should be limited to one of the standard pdf fonts: times,helvetica, courier
    • size: Optional positive integer node.Size in points of font. Defaults to 12.
    • alignment: Optional scalar node. Defaults to 'L' for left. Can be 'R' or 'J', 'L' or 'C'
    • color: Optional color foreground/text color. Use html style hex colors. Defaults to black #000000 ,
    • bg_color: Optional background color. Use html style hex colors. Defaults to 'none' for transparent.
    • style: Optional scalar node. Default to blank. Can contain any of the following characters, B for bold, U for underline, I for italic
  • elements: Parent node. Children should be numerically indexed. Elements are added to the standard document in increasing numeric order of the node name of the element. Each of the child nodes will contain the following:
    • text_properties: An optional parent node defining the properties which applies to this node and all of its sub-elements of this. The definition is the same as above.
    • type: Required scalar node. Should be one of 'text' 'image' or 'value'
    • definition: Depends on the type. See below.

Definition for type: Text

The text element is just certain text to be placed in the document. It should consist of the following nodes:

  • printf: Optional scalar node. The a printf string to be placed here. Defaults to . Example: "%s, %s has registation number %s"
  • printf_args: Optional parent node. An array of arguments to subsititute into the printf as follows
    • formname+field: a report form fields to substitute into the printf. E.g. "person+surname,person+fisrtname,registation+number":
    • +relationshipFunction: The evaluation of the named function in the the form relationship. Example +age65 which be the year the person turns 65 in the staff relationship
    • ++date(XYZ): The data formatted according to XYZ (unquoted) via strfrtime functions. Example ++date(%Y) is the four digit year
    • ++date: The date. This is the same as ++date(%x).
    • ++user: The name of the user printing the form
    • ++eval(XYZ): Evaluate the php code XYZ. Example is ++eval(strftime("%Y")+60) would add 60 to the current year
  • horiz_min: Required numeric scalar node. If the alignment is 'L' it is the left most coordinate to place this text. If the alignment is 'R' it is the right-most cooridnate of the text
  • horiz_max: Optional numeric scalar node. If not set and the allignment is 'J' then the alignment reverts to 'L'. If set and allignment if 'L' is the right-most coordinate. If set and alignment is 'R' then it is the left-most coordinate. If set and alignment is 'J' then the this is the right-most coordinate and horiz-min is the left-most coodinate.
  • vert_max: Optional numeric scalar node. The bottom most coordinate to place this text.
  • vert_min: Required numeric scalar value. The top most coordinate to place this text.

Definition for Type: Image

  • image: Required standard node. the name of the image file to place. It can either be:
    • A file name, in which case the search path used is "PDF_IMAGES"
    • A string like "form://form+field" where form is a named form in the relationship and field is a field of time IMAGE (e.g. "form://passport+image")
  • horiz_min: Required numeric scalar node. The left most coordinate to place the image.
  • vert_min: Required numeric scalar node. The top most coordinate to place the image
  • horiz_max: Optional numeric scalar node. The right most coordinate to place the image. If set, image is rescaled if needed.
  • vert_max: Optional numeric scalar node. The bottom most coordinate to place the image. If set, image is rescaled if needed.

Example

Defining the Printed Form features

For example, to produce a Staff Hire Letter in iHRIS Manage you could define it as: <source lang='xml'>

 <configurationGroup name="sample-hire-letter" path="/modules/PrintedForms/forms/sample_hire_letter">
   <configuration name="relationship">
     <value>staff</value>
   </configuration>
   <configuration name="archive">
     <value>person</value>
   </configuration>
   <configuration name="displayName">
     <value>Staff Hire Letter</value>
   </configuration>
   <configurationGroup name="elements">
     <configurationGroup name="0">
       <configuration name="type">
         <value>image</value>
       </configuration>
       <configuration name="definition" values='many' type='delimited'>
         <value>image:iHRISManage_logo_whiteBG.png</value>
         <value>horiz_min:5</value>
         <value>vert_min:1</value>
       </configuration>
     </configurationGroup>
     <configurationGroup name="50">
       <configuration name="type">
         <value>text</value>
       </configuration>
       <configuration name="text_properties" values='many' type='delimited'>
         <value>style:I</value>
       </configuration>
       <configuration name="definition" values='many' type='delimited'>
         <value>horiz_min:33</value>
         <value>vert_min:6</value>
         <value>printf:Certification of Employment</value>
       </configuration>
     </configurationGroup>
     <configurationGroup name="51">
       <configuration name="type">
         <value>text</value>
       </configuration>
       <configuration name="text_properties" values='many' type='delimited'>
         <value>style:BU</value>
       </configuration>
       <configuration name="definition" values='many' type='delimited'>
         <value>horiz_min:33</value>
         <value>vert_min:12</value>
         <value>printf:Ministry of Health</value>
       </configuration>
     </configurationGroup>
     <configurationGroup name="52">
       <configuration name="type">
         <value>text</value>
       </configuration>
       <configuration name="definition" values='many' type='delimited'>
         <value>horiz_min:160</value>
         <value>vert_min:6</value>
         <value>printf:%s</value>
       </configuration>
       <configuration name="printf_args" path='definition/printf_args' values='many' type='delimited'>
         <value>0:++date(%e %B %Y)</value>

</configuration>

     </configurationGroup>
     <configurationGroup name="100">
       <configuration name="type">
         <value>text</value>
       </configuration>
       <configuration name="definition" values='many' type='delimited'>
         <value>horiz_min:3</value>
         <value>vert_min:50</value>
         <value>printf:Dir Sir/Madam, 
Please accept this letter as certification of employment for %s %s. 

On %s, employment began as %s in the %s department of %s.

Sincerely, %s</value>

       </configuration>
       <configuration name="printf_args" path='definition/printf_args' values='many' type='delimited'>
         <value>0:person+firstname</value>
         <value>1:person+surname</value>
         <value>2:staff+start_date</value>
         <value>3:position+title</value>
         <value>4:department+name</value>
         <value>5:facility+name</value>
         <value>6:++user</value>
       </configuration>
     </configurationGroup>
   </configurationGroup>
 </configurationGroup>

</source>

Creating a link to print the form

After that is set, then you need to open the view template for the form where you wish to place the link to print the PrinteForm. <source lang="xml">

 hasValidForms('sample_hire_letter')">
  • Sample Hire Letter
  • </source> The above would mean the name of the PrintedForm is sample_hire_letter and its parent form is person. This piece of code should be inserted favorably below the link to update the information of a form. (view_form_name.html)