Jump to content


Photo

PDF Report / Print Out


  • Please log in to reply
33 replies to this topic

#1 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 25 February 2012 - 06:18 AM

I know reports is on the road map but in the meantime I was looking into ways of generating a PDF.

For example if I have:
Model A
Fields >> Name, NumX, DoOnDate,...
Relation >> has many Model B

Model B
Fields >> Name, Type....
Relation >> has one Model A

A simple pdf that would contain all information for a particular Module A->id

For Yii app I know we could use TCPDF extension or others. I though I would ask your opinions before I commit myself. Any sample code (or links) would be greatly appreciated.

Thanks :)

#2 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 25 February 2012 - 02:34 PM

Hi,
Are you trying to export a list of models? Like a grid of data into a PDF? Or are you trying to just export one models's data?

Jason Green
Zurmo Team
Need support? Upgrade now


#3 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 25 February 2012 - 04:26 PM

Data from just one model, as well as data of related child entities.

You can think of it, like printing an invoice. It has some header information and detail line items, along few images and other text.

#4 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 26 February 2012 - 07:18 PM

Ok i understand what you are trying to do. The easiest way is probably to render a view that is normal html, then use TCPDF to turn the html into a pdf. This would be easier than trying to build the pdf from the string content of the model attributes etc. Do you have an example of this output you would like? How much different is the format than what is printed on the screen?

Jason Green
Zurmo Team
Need support? Upgrade now


#5 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 27 February 2012 - 03:57 AM

It's going to be different than what's printed on the screen. I think understand your recommendation. First build a view as needed and then use TCPDF to turn it into a pdf. Now it's just a mater of getting the view just right (layout, style...). I will work on it this coming week and report back.

Perhaps, I should use an invoice as an example. I will be easily able to apply the technique in my project and hopefully it will help others as well. I will mock up an sample invoice and start sample project (will post a bitbucket link). -- What do you think? Is that worth doing?

#6 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 27 February 2012 - 04:34 PM

It's going to be different than what's printed on the screen. I think understand your recommendation. First build a view as needed and then use TCPDF to turn it into a pdf. Now it's just a mater of getting the view just right (layout, style...). I will work on it this coming week and report back.

Perhaps, I should use an invoice as an example. I will be easily able to apply the technique in my project and hopefully it will help others as well. I will mock up an sample invoice and start sample project (will post a bitbucket link). -- What do you think? Is that worth doing?

I think your proposal is great. You can post a link to your bitbucket repo of this work. Then I can review and and recommend changes. We can also make a wiki article about it for others to learn from. Keep me posted!

Jason Green
Zurmo Team
Need support? Upgrade now


#7 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 05 March 2012 - 06:40 PM

I finally managed to get started on the sample project, still have lot of work to do before PDF can be created.

BitBucket Link: https://bitbucket.or...invoice-example


I am hopping besides the PDF printing, sample will show how to make a custom module with basic features that are widely used.

ERD:
Posted Image


Sample Invoice:
https://bitbucket.or...mpleInvoice.pdf


Files Modified:
Posted Image



Current Issues (things I haven't figured out yet)
  • Using calculated fields: for example "totalprice" in invoice details should be a calculated field but haven't figured out the syntax.
  • Display material description in the invoice details relation view

Posted Image
  • Files/Image for a material
  • Invoice Details -> item number should be assigned by system
  • Invoice Details -> searching for material is only possible by name, would like to change that so it searches by name and number
Posted Image

Other thoughts
  • Company Information: not sure if some where in Administration area there is a place to store company information, for example name, address...
I think this sample project might be bit more work than I thought. I will continue on, I know it will help me and others in the long run.

#8 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 07 March 2012 - 04:23 AM

I will download from your repo tomorrow and install locally. Then i can try to answer some of these questions for you.

Jason Green
Zurmo Team
Need support? Upgrade now


#9 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 07 March 2012 - 04:53 PM

Ok i downloaded and installed it locally. Whenever you have time feel free to skype chat me. I also can go in the live chat today on our site.

Jason Green
Zurmo Team
Need support? Upgrade now


#10 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 08 March 2012 - 02:51 AM

Custom Fields - via Code

It's pretty easy to make a custom field using the designer; simply create a field then place it in a layout. Creating a custom field it in Code is very similar.

Step 1: Create the custom filed
	/*
	 * Called from resolveCustomMetadataAndLoad()
	 *  This will allow us to execute this function using " ?&resolveCustomData=1 " not just during installation
	*/
	class C_invoicedetailsCustomMetadata
	{
		public function make()
		{		  
			//Total Price Calcualted filed
			$attributeName = 'totalprice';
		   //Add attribute only it if doesn't exists
			try
			{
				//This will through an exception if field doesn't exist
				$attributeTest = CalculatedDerivedAttributeMetadata::getByNameAndModelClassName($attributeName, 'C_invoicedetail');
			}
			catch ( NotFoundException $e)
			{
				$attributeForm = new CalculatedNumberAttributeForm();
				$attributeForm->attributeName	= $attributeName;
				$attributeForm->attributeLabels  = array(
					'de' => 'Total Price de',
					'en' => 'Total Price',
					'es' => 'Total Price es',
					'fr' => 'Total Price fr',
					'it' => 'Total Price it',
				);
				$attributeForm->formula  = 'quantity * unitprice';
				$modelAttributesAdapterClassName = $attributeForm::getModelAttributeAdapterNameForSavingAttributeFormData();
 
 
				//Add the field to module -- C_invoicedetail
				$adapter = new $modelAttributesAdapterClassName(new C_invoicedetail());
				$adapter->setAttributeMetadataFromForm($attributeForm);
			  
			}
		}
	}
Other type of custom field (see link) http://zurmo.org/for...-customization/
// Example of another type of custom field
 
			$model = new Account();
			if (!$model->isAttribute($attributeName)
			{
					$attributeForm = new TextAttributeForm();
					$attributeForm->attributeName = $attributeName;
					$attributeForm->attributeLabels  = array(
							'de' => 'Test Text 2 de',
							'en' => 'Test Text 2 en',
							'es' => 'Test Text 2 es',
							'fr' => 'Test Text 2 fr',
							'it' => 'Test Text 2 it',
					);
					$attributeForm->isAudited	= true;
					$attributeForm->isRequired	= true;
					$attributeForm->maxLength	= 50;
					$attributeForm->defaultValue  = 'Kangaroo';
					$modelAttributesAdapterClassName = $attributeForm::getModelAttributeAdapterNameForSavingAttributeFormData();
					$adapter = new $modelAttributesAdapterClassName(new Account());
						 $adapter->setAttributeMetadataFromForm($attributeForm);
			}
 

Step 2: Add to view
a. Can modify the metadata for the views by just adding to the metadata and saving it.
​b. Or hard code it in the view as shown below

								array('cells' =>
									array(
										array(
											'elements' => array(
												array('attributeName' => 'totalprice' , 'type' => 'CalculatedNumber'),
											),
										),
									)
								),

Other Consideration: Hooking into Install Util

In InstallUtil call C_invoicedetailsCustomMetadata() as shown in code below.

	class CustomextInstallUtil
	{
		public static function resolveCustomMetadataAndLoad()
		{
			$shouldSaveZurmoModuleMetadata = false;
			$metadata					  = ZurmoModule::getMetadata();
		  
			//Add Invoice to Menu if it doesn't exist
			if(!in_array('c_invoicehdrs', $metadata['global']['tabMenuItemsModuleOrdering']))
			{
				$metadata['global']['tabMenuItemsModuleOrdering'][] = 'c_invoicehdrs';
				$shouldSaveZurmoModuleMetadata = true;
			}
		  
			if($shouldSaveZurmoModuleMetadata)
			{
				ZurmoModule::setMetadata($metadata);
				GeneralCache::forgetAll();
			}
			Yii::import('application.extensions.zurmoinc.framework.data.*');
			Yii::import('application.modules.c_materials.data.*');
			Yii::import('application.modules.c_invoicedetails.data.*');
			Yii::import('application.modules.c_invoicehdr.data.*');
		  
			//Make default data -- using resovleMetaData
			$metaDataMaker = new C_invoicedetailsCustomMetadata();
			$metaDataMaker->make();
		}
	}

Customizing zurmo wiki explains more details about the install utill http://zurmo.org/wik...stomizing-zurmo

#11 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 08 March 2012 - 03:17 AM

Who to add attachments (Files) to your custom module

Add a filed in module Model

// Model code
	class C_material extends Item
	{
	....
	....
	   public static function getDefaultMetadata()
		{
			$metadata = parent::getDefaultMetadata();
			$metadata[__CLASS__] = array(
			  
				'members' => array(
					'materialnum',
					'name',
					'description',
				),
			  
				'relations' => array(
					'files' => array(RedBeanModel::HAS_MANY,  'FileModel', RedBeanModel::OWNED),
				),
			  
				'rules' => array(
					......
				),
				'elements' => array(
					'files'			  => 'Files',
				),
			  
				....
				....
			);
			return $metadata;
		}

Add field in View

// Since Files is a derived field, add it to derived attributes type
					'derivedAttributeTypes' => array(
						'Files',
						'DateTimeCreatedUser',
						'DateTimeModifiedUser',
					),
//in layout
								array('cells' =>
									array(
										array(
											'elements' => array(
												array('attributeName' => 'null', 'type' => 'Files'),
											),
										),
									)
								),

Modify Default Controller of the module
		/**
		 * Override to handle incoming file upload information.
		 */
		protected function attemptToSaveModelFromPost($model, $redirectUrlParams = null, $redirect = true)
		{
			// Have to call this before parent::...
			$this->resolveModelsHasManyRelationsFromPost($model);
			parent::attemptToSaveModelFromPost($model, $redirectUrlParams, $redirect);
			return $model;
		}
	  
	  
		/**
		 * to handle incoming file upload information.
		 */
		protected function resolveModelsHasManyRelationsFromPost(& $model)
		{
		   // assert('$model C_material');
			FileModelUtil::resolveModelsHasManyFilesFromPost($model, 'files', 'filesIds');
		}


#12 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 08 March 2012 - 03:19 AM

Thanks Jason for help. I will keep adding as I learn form him :)

#13 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 09 March 2012 - 03:47 AM

Great, glad i could help!

Jason Green
Zurmo Team
Need support? Upgrade now


#14 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 10 March 2012 - 07:53 PM

C_invoicedetail - Material Description

At times we may need to display additional fields from a related entity, for instance in Invoice example we would like to display "Material Description" along with "Material Number". When adding a new derived field there are two components to address view (using ListViewColumnAdapter) and designer (using an element).

Lets add Material Description field in "C_invoicedetailsRelatedListView"

								array('cells' =>
									array(
										array(
											'elements' => array(
												array('attributeName' => 'null', 'type' => 'MaterialDescription'),
											),
										),
									)
								),

Now we need to create a MaterialDescriptionListViewColumnAdapter

	class MaterialDescriptionListViewColumnAdapter extends TextListViewColumnAdapter
	{
		public function renderGridViewData()
		{
			return array(
				//Since in the view we are passing "null" attribute we need to specify the attribute name here
				//in the view 'attributeName' => 'null' must be null
				'name'  => 'c_material', // $this->attribute,
 
				'header' => Yii::t('Default', 'Material Description'),			  
 
				//$data passed to view has field c_material of type C_material which as attribute description
				'value' => '$data->c_material->description',
				'type'  => 'raw',
			);
		}
	}
You check out other ListViewColumnAdapter for example as well.

Element
At this point our view will contain the material description but C_invoicedetailsRelatedListView layout in designer will be broken
(Admin -> Designer Home » Inv. Details » Layouts » Related List View - Inv. Details For Invoice).

To fix this we need to add "derivedAttributeTypes" in our view and MaterialDescriptionElement.

derivedAttributeTypes in View
					'derivedAttributeTypes' => array(
						'MaterialDescription',
					),

MaterialDescriptionElement
//
//Please note I am not 100% on the element code but it's working for me
//
   class MaterialDescriptionElement extends Element implements DerivedElementInterface
	{
		protected function renderEditable()
		{
			throw NotSupportedException();
		}
		protected function renderControlEditable()
		{
			throw NotSupportedException();
		}
		/**
		 * Render the full name as a non-editable display
		 * @return The element's content.
		 */
		protected function renderControlNonEditable()
		{
			assert('$this->attribute == "null"');
			assert('$this->model->{$this->attribute} instanceof C_material');
			$materialModel = $this->model->{$this->attribute};
			return Yii::app()->format->text($materialModel->description);
		}
	  
		protected function renderLabel()
		{
			return Yii::t('Default', 'Material Description');
		}
		public static function getDisplayName()
		{
			return Yii::t('Default', 'Material Description');
		}
		/**
		 * Get the attributeNames of attributes used in
		 * the derived element.
		 * @return array of model attributeNames used.
		 */
		public static function getModelAttributeNames()
		{
			return array();
		}
	  
		public static function isReadOnly()
		{
		   return true;
		}
	  
	}

End Result

Posted Image

#15 Jason

Jason

    Administrator

  • Administrators
  • 819 posts
  • LocationChicago

Posted 11 March 2012 - 08:16 PM

This is great. Once you have access to write wiki's you can convert this into a tutorial or a wiki article.

Jason Green
Zurmo Team
Need support? Upgrade now


#16 k1000o

k1000o

    Advanced Member

  • Members
  • PipPipPip
  • 112 posts
  • LocationMadrid

Posted 30 May 2012 - 10:25 PM

Hello Sanbrar

Thanks for your collaboration, it's been very useful. Have you managed to migrate this custo to the new interface?
I did it and I have a issue when trying to create invoice lines:
- The popup to select the material does not show, but we can type the code and fill it with auto complete.
- When click on the save button the line is not created.

I attached the 3 modules in case you can take a look and help us

Thanks

Attached Files



#17 k1000o

k1000o

    Advanced Member

  • Members
  • PipPipPip
  • 112 posts
  • LocationMadrid

Posted 31 May 2012 - 07:49 AM

I found it, the field itemnum was required but not present in the screen so the following 2 lines must be removed in the model.

array('itemnum', 'required'),
array('itemnum', 'type',	'type' => 'integer'),

Find attached the corrected modules

Attached Files



#18 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 20 June 2012 - 05:24 PM

Hi K1000o,

I have migrated the example to the new UI and have also create Wiki article to go along with.

http://zurmo.org/wik...invoice-example

It's still work in progress but it's getting there.


Repository Link: https://bitbucket.or...r/zurmo_invoice


Regards,

San

#19 k1000o

k1000o

    Advanced Member

  • Members
  • PipPipPip
  • 112 posts
  • LocationMadrid

Posted 20 June 2012 - 05:52 PM

Hi
Glad to hear from you.
Have you made more advances or is the same example?
Based on you initial code I am making a materials module for Opportunities. Find attached a screen shoot, let me know what you think.

Materials4Opportunities.png

#20 sanbrar

sanbrar

    Advanced Member

  • Members
  • PipPipPip
  • 69 posts

Posted 20 June 2012 - 09:05 PM

So far it's a same example, except for line item number is auto populated and invoice date defaults to today.

And popup's are working now.


Next thing I am going to work is exporting to PDF. Any suggestions?


Nice work on the Material for Opportunities. How did you get the total to appear on the top and what does "CBR" button do? Another thing I noticed that you have delete button for each item, my example doesn't.

Thanks,




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users