Announcement

Collapse
No announcement yet.

Custom Template PDF File Names

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

  • espcrm
    replied
    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.

    Leave a comment:


  • MATO
    replied
    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.

    Leave a comment:


  • espcrm
    commented on 's reply
    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).

  • espcrm
    commented on 's reply
    Yes, the current Print through web browser is pretty good. Perhaps we need the Report function to property print information.

  • blueprint
    replied
    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.

    Leave a comment:


  • item
    replied
    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

    Leave a comment:


  • telecastg
    replied
    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.

    Leave a comment:


  • espcrm
    replied
    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 espcrm; 01-17-2020, 02:44 AM.

    Leave a comment:


  • blueprint
    replied
    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!

    Leave a comment:


  • telecastg
    replied
    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, 01:28 AM.

    Leave a comment:


  • blueprint
    started a topic Custom Template PDF File Names

    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.
Working...
X