Showing posts with label pdf. Show all posts
Showing posts with label pdf. Show all posts

Friday, August 14, 2009

Symfony batch and i18n + pdf generation

A few months ago, I wrote a post about i18n in batch and pdf generation. At that time I could not find a way to manage translation in symfony batch (for example when you need to send email to customers, etc...). In Symfony 1.2, batches are depreciated in favor of tasks but my project is still in symfony 1.0 (and I guess the same can be applicable in 1.2). Anyway, I finally found a way to do it:
sfLoader::loadHelpers('I18N');
$I18N = sfContext::getInstance()->getI18N();
$I18N->setMessageSourceDir(SF_ROOT_DIR.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'i18n', $culture);
echo __('text to translate');

I am not sure if it is the best solution, but it definitively works.

On the pdf side, I was mentioning that in order to generate invoices in pdf, I created some pdf invoice templates with Open Office Draw. Following this step, I was able with Zend_Pdf to generate PDF files on the fly based on my templates. The big problem with this solution is that you have to positionned all your text at the pixel and cannot manage things like multiple lines text and so on. You end up writing a lot of stupid code and anything you want to modify you have to try again and make sure it works (and when you manage several languages it can even be more complex). Anyway I managed to do it like this for the billing system used in East-Timor but I always wanted another solution. I did find some promising project but nothing yet reach a usable state to my knowledge. However, I found to interesting projects:

  • odtPHP: it is not as such a pdf generator but it looks fantastic to generate open documents easily with a templating system. It is great and I am sure I will use it soon. Once you have an open document, it is a piece of cake for anybody to save it as pdf...even my grandma could do this ;-)

  • Podr: it's a kind of open office server to generate document on the server, including pdf. However it seems only working on windows and quite heavy installation, I am not sure if it is a good solution. Anyone using it?


odtPHP looks like a clean and nice php class and it should be easy to integrate in symfony. On the client side, if you do not have open office (or any odt compatible solution) you can simply install a plugin for Microsoft Office to support open document formats (it seems it is even native support in Office 2007 service pack 2): http://www.sun.com/software/star/odf_plugin/ or http://sourceforge.net/projects/odf-converter/.

Tuesday, January 6, 2009

Invoicr (former CS-4U), what's new?

Long time I have not talk about my project that I used to name "CS-4U". As you might know, this web-based billing system for utilities, developed with my favorite PHP5 framework (should I mentioned it..symfony 1.0 at that time), is actually in use for about 3 years already in East-Timor for the electricity company.
I recently went back there to make an upgrade and add a lot of new features, this is what I want to share in this post.
This application was my very first project with symfony and when I dived again in the code for all those new features I realized how much I learned in the past years... There are lot of things that I would do differently today (and I am not even considering here the use of symfony 1.2)!

Here is a quick list of what has been added in version 1.1:
  • PDF support with Zend_Pdf. This allow to generate invoices and reports in PDF (mainly using templates). Zend_Pdf is stable and easy to integrate in symfony, the drawback of these kind of solution is their limitation and the cost of maintenance: you must draw everything per line and position each line on the page. I created some simple methods to right align or draw a simple table over several pages but it is really a pain! It seems some guys are working on improving Zend_Pdf (they actually released an alpha framework RE) to add to it some more advanced functions such as multiline content, table and so on. I hope it can come out soon...
  • A new receipt system. Basically the new receipt system will split a payment into sub-receipts over several invoices if necessary and still keep track of the "physical" payment main receipt. With this we clearly identify where is the money, there are no more "floating" money in the contract balance. All supplementary payments are made against the oldest debt of the contract and the system cannot accept payment over the total balance.
  • Some new modules: Fines & Products module to add one-shot cost in upcoming invoice for a customer. Some admin generated modules to easily modify some of the data (status, districts, categories...)
  • Barcode support. You can now add a barcode in the invoice pdf file to ease payment and avoid human errors. This is not yet use in Timor because they do not have yet barcode reader but they seems very interested by this solution.
  • Javascript switch: from Prototype to jQuery. To ease some development I simply switch to jQuery library instead of Prototype and we use a little bit more ajax call in the app when it make sens. I still want to add more in the future...probably when I start to migrate to sf1.2...not for tomorrow though...
  • New UI design. Not big changes but still an improvement compare to before. It is still very "light web style" since I am not yet convince to go to a more rich UI. I am kind of fan of "Google style".
  • More actions to give more flexibility to users to correct mistakes mainly: change tariffs, modify meter-contract relation information, re-calculate invoice...
  • Bugs, bugs, bugs.
What will come next (no particular order):
Business side:
  • new tariff system to allow more complex tariff calculation.
  • Dashboard. At login, user will see its own dashboard according to its authorization level. It will show some KPI and latest info/actions.
  • Reporting. Change the reporting into a more user-controlled solution where the user can define the report she/he wants and get it in pdf (no idea yet on this ;-) or OpenDocument format.
Technology side:
  • use of admin generator instead of manual dev for most of "master data" modules with a lot of ajax (more on this later as I am working on a new admin generator theme for this).
  • Messaging Service. To ease communication between users or from system to users with memo, task assignment or system message. This is a symfony plugin I want to do for quite sometime already (including an event/calendar system too).
  • Reporting. I want to make the reporting much easier and flexible for user to get the report he wants (not only pre-coded report). I also want to switch from the existing flash graph library to canvas based charts and/or open flash chart.
  • Migrate to sf1.2 and write unit and functional test.





Monday, December 22, 2008

Symfony batch in my i18n nightmares

I was working on a new version of the billing system for utilities (used by the national electricity company in East-Timor), adding a bunch of new features including PDF generation for invoice and some reports. I decided to use Zend_Pdf and I believe it is a good choice.

Generating PDF is not something really fun. I used a template pdf and feed it with all the customer information I want. For each single piece of data you want to add, you must provide the position in the page, the style (if you want to change it)...a real pain! I wish we can have a more powerful templating system. It seems some guys have some plans (and codes) but nothing yet release (see mailing list here)...hey! (almost) good news: while I was looking for the link I found that they did release their PDF library (not yet in Zend, nor compatible with Zend_Pdf) named "RE Framework". I need to have a look one of this day...

Anyway, I was thinking to generate all invoices (in DB + PDF version) through a batch in symfony. I started working on it when I faced a "simple" problem: I need to use i18n for each invoices (invoice in the language of the customer), but from a batch I am always getting an error message since it does not have a user and culture define. I tried to initalize a fake one...but no luck. I need to try harder... ;-)

Any ideas?