Announcement

Collapse
No announcement yet.

Custom Template PDF File Names

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Custom Template PDF File Names

    I don't know if this is of interest to anyone but I thought I'd share it.

    As we are implementing more and more business functions within EspoCRM, we are producing more and more Templates which are ultimately being turned into PDF files (orders, job sheets, inventory, etc, etc). Once of the needs we have is to be able to generate a PDF from a template and save it to our company network with a given file name format (depending on the type of information within the file).

    Natively, EspoCRM doesn't seem to allow you to be able to generate a file name format for each individual entity so I've managed to bake my own system. Its not upgrade-proof but for us, that does not matter. Someone may want to take this forward to make it so.

    The following implementation is what I did to allow us to generate file names specific to an entity:

    1. Edit the application\Espo\Services\Pdf.php file, replacing the buildFromTemplate function with below

    Code:
    public function buildFromTemplate(Entity $entity, Entity $template, $displayInline = false)
    {
        $entityType = $entity->getEntityType();
        // Get the name field from the entity for a default file name
        $name = $entity->get('name');
    
        if ($this->getServiceFactory()->checkExists($entityType)) {
            $service = $this->getServiceFactory()->create($entityType);
        } else {
            $service = $this->getServiceFactory()->create('Record');
        }
    
        $service->loadAdditionalFields($entity);
    
        if (method_exists($service, 'loadAdditionalFieldsForPdf')) {
            $service->loadAdditionalFieldsForPdf($entity);
        }
    
        // Pull the file name from the service, if the function exists
        if (method_exists($service, 'getFileNameForPdf')) {
            $name = $service->getFileNameForPdf($entity);
        }
    
        if ($template->get('entityType') !== $entityType) {
            throw new Forbidden();
        }
    
        if (!$this->getAcl()->check($entity, 'read') || !$this->getAcl()->check($template, 'read')) {
            throw new Forbidden();
        }
    
        $htmlizer = $this->createHtmlizer();
        $pdf = new \Espo\Core\Pdf\Tcpdf();
    
        $this->printEntity($entity, $template, $htmlizer, $pdf);
    
        if ($displayInline) {
            $name = \Espo\Core\Utils\Util::sanitizeFileName($name);
            $fileName = $name . '.pdf';
    
            $pdf->output($fileName, 'I');
            return;
        }
    
        return $pdf->output('', 'S');
    }
    The main change above is that a service function called `getFileNameForPdf` will get called if it exists.

    Next, we need to go into the relevant `Services\EntityName.php` file and add the function as below:

    Code:
    public function getFileNameForPdf(Entity $entity)
    {
        return $entity->get('name') . ' - ' . $entity->get('accountName');
    }
    And voila, we now have customisable file names on an Entity-by-Entity basis.

  • #2
    Thanks for sharing blueprint !

    Here's a possible way to make your customization "update-safe" although a little elaborate:

    1) create new view client/custom/src/views/record/detail.js
    Code:
    define('custom:views/record/detail', ['views/record/detail'], function (Dep, ViewRecordHelper) {
    
        return Dep.extend({
    
            actionPrintPdf: function () {
                this.createView('pdfTemplate', 'views/modals/select-template', {
                    entityType: this.model.name
                }, function (view) {
                    view.render();
                    this.listenToOnce(view, 'select', function (model) {
                        this.clearView('pdfTemplate');
                        window.open('?entryPoint=pdfCustomFileName&entityType='+this.model.name+'&entityId='+this.model.id+'&templateId=' + model.id, '_blank');
                    }, this);
                });
            }
    
        });
    });
    2) create new entry point file custom/Espo/Custom/EntryPoints/PdfCustomFileName.php
    Code:
    <?php
    
    namespace Espo\Custom\EntryPoints;
    
    use \Espo\Core\Exceptions\NotFound;
    use \Espo\Core\Exceptions\BadRequest;
    
    class PdfCustomFileName extends \Espo\Core\EntryPoints\Base
    {
        public static $authRequired = true;
    
        // default action
        public function run()
        {
    
            if (empty($_GET['entityId']) || empty($_GET['entityType']) || empty($_GET['templateId'])) {
                throw new BadRequest();
            }
            $entityId = $_GET['entityId'];
            $entityType = $_GET['entityType'];
            $templateId = $_GET['templateId'];
            $isPortal = $_GET['isPortal'];
    
            $entity = $this->getEntityManager()->getEntity($entityType, $entityId);
            $template = $this->getEntityManager()->getEntity('Template', $templateId);
    
            if (!$entity || !$template) {
                throw new NotFound();
            }
    
            $this->getContainer()->get('serviceFactory')->create('PdfCustomFileNameService')->buildFromTemplate($entity, $template, $isPortal);
    
            exit;
        }
    }
    3) Create new service file custom/Espo/Custom/Services/PdfCustomFileNameService.php
    Code:
    namespace Espo\Custom\Services
    use \Espo\Core\Exceptions\Forbidden;
    use \Espo\Core\Exceptions\NotFound;
    use \Espo\Core\Exceptions\Error;
    use \Espo\ORM\Entity;
    //use \Espo\Core\Htmlizer\Htmlizer;
    use \Espo\Custom\Htmlizer\CustomHtmlizer;
    
    class PdfCustomFileNameService extends \Espo\Core\Services\Base
    {
    // copy the entire contents of your modified application\Espo\Services\Pdf.php file
    }
    4) Not sure why but when I invoke the standard Htmilizer file from the custom service above I get an error :-( ??? (if anyone can provide some guidance it will be highly appreciated it), so I commented this line and created a "CustomHtmilizer" custom/Espo/Custom/Htmilzer/CustomHtmiler.php that essentially clones Espo\Core\Htmlizer\Htmlizer (see the code above)
    Code:
    namespace Espo\Custom\Htmlizer;
    
    class CustomHtmlizer extends \Espo\Core\Htmlizer\Htmlizer
    {
    
    }
    5) Create a custom clientDef file for each entity class where you want to have the custom pdf capability and specify the custom record view there (for example at custom/Espo/Custom/Resources/metadata/clientDefs/Contact.json)
    Code:
    {
        "recordViews": {
            "detail": "custom:views/record/detail"
        }
    }
    Last edited by telecastg; 01-16-2020, 02:28 AM.

    Comment


    • #3
      Originally posted by telecastg View Post

      Here's a possible way to make your customization "update-safe" although a little elaborate:
      Nice one, that's perfect!

      Comment


      • #4
        This is awesome, looking forward to a pull request on the Git.

        Off-topic: How you you even make good looking PDF template with the current PDF library? All my PDF doesn't look the way it is formated in the Template design.
        Last edited by esforim; 01-17-2020, 03:44 AM.

        Comment


        • #5
          Originally posted by espcrm View Post
          Off-topic: How you you even make good looking PDF template with the current PDF library? All my PDF doesn't look the way it is formatted in the Template design.
          Honestly, I couldn't. I became very frustrated with TCPDF and decided that the best way was to print everything to the main section of Espo screen, to take advantage of the existing css styles or to define my own styles and display in a new window and then "print" using my browser's PDF engine, so I can get a document exactly as I styled it.

          It could be that I just don't get how TCPDF can work, but I decided to move on since I had accomplished my goal.

          Comment


          • esforim
            esforim commented
            Editing a comment
            Yes, the current Print through web browser is pretty good. Perhaps we need the Report function to property print information.

        • #6
          Hello,
          other possibility (i need word) .. i use phpOffice library :
          i create a template (word docx) .. i put in folder ..
          so with phpWord, i read template docx .. inject all data to docx and output as pdf or docx if needed.

          Regards

          Comment


          • esforim
            esforim commented
            Editing a comment
            I'm a bit confused. Is this what you are doing currently or what you are hoping to be able to do.

            I haven't find any Open Source CRM that is capable of Mailmerge and producing Word type of template. It always as PDF, most of which I can never make it look good or work as intended (could not merge the data I want).

        • #7
          Originally posted by espcrm View Post
          Off-topic: How you you even make good looking PDF template with the current PDF library? All my PDF doesn't look the way it is formated in the Template design.
          Well, it actually is possible - it just takes a lot of tinkering time.

          The CSS rules are really really hit-and-miss but once you get used to the foibles of the TCPDF library, you can create some really decent templates. That said, it is a pain in the backside and takes far far longer (especially when you have to create really nice public-facing PDFs) so any 3rd party implementation of a better PDF engine can't come soon enough.

          Comment


          • #8
            Did anyone find a good way to create like for like pdf exports - With CSS using transparency in color and layouts of fonts variations its very hard to match like for like.

            Although gathering the data was straight forward in the template designer

            My Users complain of washed out PDF files.

            Comment


            • #9
              It very hard to make it look nice. You have to either you a separate HTML editor to create it then do a copy/paste. But if there complex layout it won't look good or align when you do export.

              There is a brief mention of other using some other PDF library but I'm not quite sure how did they go with that.

              Comment


              • #10
                We had similar issue. After we change few things in pdf engine, now we have 46 different PDF templates

                We've managed to create document like this:



                Among others we added fonts from Google Fonts and icons.
                I'm not sure is it nice enough, but it works for us

                Sorry for white blanks, but i had to cover confidential information

                Comment


                • rabii
                  rabii commented
                  Editing a comment
                  hey @emillod

                  Do you care to share what have you changed in the PDF engine to make such beautiful templates.

                  Thanks

                • emillod
                  emillod commented
                  Editing a comment
                  rabii it's not that easy. On our production we just working on HTML templates which are coded on FTP. We started working on additional extension but there are limits in editor. We'll probably go back to this in the future, but there is no date, because on daily basis we're working on clients projects..

                • rabii
                  rabii commented
                  Editing a comment
                  Thanks for your reply and good luck with your clients’ work.

              • #11
                How did you do that, looks very good.

                Comment


                • #12
                  shalmaxb i'll speak with my business partner to publish this as free extension

                  Comment


                  • partomas
                    partomas commented
                    Editing a comment
                    what was conclusion? Might be I can find it already somewhere?

                • #13
                  Hi, thank you.
                  Regarding the creation of PDF besides the built in TCPDF, perhaps this: https://github.com/mikehaertl/phpwkhtmltopdf could be a solution. I am not a developer, but perhaps someone with the appropriate skills might be able to use it.

                  or this one: https://github.com/dompdf/dompdf
                  Last edited by shalmaxb; 09-09-2020, 08:40 AM.

                  Comment


                  • #14
                    Originally posted by emillod View Post
                    We had similar issue. After we change few things in pdf engine, now we have 46 different PDF templates

                    We've managed to create document like this:

                    Sorry for white blanks, but i had to cover confidential information
                    Wow! I don't believe that is being made from EspoCRM. But is it possible to create that from the Front End GUI using the WYSIWYG with your current implementation? Or require external magic and/or full use of the <code view>?

                    Comment


                    • #15
                      esforim first version required creating template in HTML files through ftp server.
                      Second version allow users to prepare whole template through WEB GUI of EspoCRM in html editor.

                      I know, it's not ideal.
                      It's possible that we also share with community not only an extension but also some examples of our templates.

                      Comment


                      • partomas
                        partomas commented
                        Editing a comment
                        It would be amazing. When we can expect that?

                      • emillod
                        emillod commented
                        Editing a comment
                        partomas -that's great question. I thought that we'll be able to publish it in few days, but we have too much work. First priority for us is release new version of dark theme which will not only fix few issues in vertical version but also add me dark horizontal version.

                        I hope I'll be able to release Darryl theme in few days or weeks. To publish PDF extension we need more time and help from our workers so I can't tell you specific deadline

                      • shootify
                        shootify commented
                        Editing a comment
                        hello Sir, would you plz share it, it will be highly appreciated. thanks
                    Working...
                    X