Module CustomFields Cases

From Dolibarr ERP CRM Wiki
Revision as of 23:09, 29 August 2012 by Lrq3000 (talk | contribs) (Added how to make a generic customfields pdf template)
Jump to navigation Jump to search

This page lists a compilation of concrete, practical examples uses of CustomFields and of its various features.

If you had an experience with CustomFields, you can also add here your case as an example for others to get inspired.

How to make a generic PDF template listing all custom fields

To make a generic PDF template listing all custom fields, you just need to take an existing PDF template, then you need to follow these 3 steps:

1/ Edit the class name (required, else it will conflict with the original template).

Eg: if we take the crabe template for invoices, we change:

class pdf_crabe extends ModelePDFFactures {
// ... php code ...
  function __constructor($db) {
// ... php code ...
    $this->name = "crabe";

into:

class pdf_customfields extends ModelePDFFactures {
// ... php code ...
  function __constructor($db) {
// ... php code ...
    $this->name = "customfields";

2/ Copy this generic function at the end of the PDF:

/**
 *   	\brief      Show the customfields in a new page
 *   	\param      pdf     		PDF factory
 * 		\param		object			Object invoice/propale/order/etc... (CustomFields simpler functions will automatically adapt)
 *      \param      outputlangs		Object lang for output
 */
function _pagecustomfields(&$pdf,$object,$outputlangs)
{
    global $conf;
    $default_font_size = pdf_getPDFFontSize($outputlangs); // set default PDF font size

    // Init and main vars
    include_once(DOL_DOCUMENT_ROOT.'/customfields/lib/customfields_aux.lib.php');

    // Filling the $object with customfields (you can then access customfields by doing $object->customfields->cf_yourfield)
    $customfields = customfields_fill_object($object, null, $outputlangs, null, true);

    // Setting the starting position of the text cursor
    $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $pdf->GetY()+4);
    $pdf->SetY($pdf->GetY()+1);

    // Printing the customfields
    foreach ($object->customfields as $label=>$value) { // $value is already formatted!
        // Get translated label
        $translatedlabel = $customfields->findLabelPDF($label, $outputlangs); // translated label of the customfield (not translated by default in customfields_fill_object() because a field should always be accessible by a base name, whatever the translation is)

        // PDF formatting, placement and printing
        $pdf->SetFont('','B', $default_font_size);
        $pdf->MultiCell(0,3, $translatedlabel.' ($object->customfields->'.$label.'): '.$value, 0, 'L'); // printing the customfield
        $pdf->SetY($pdf->GetY()+1); // line return for the next printing
    }

    return 1;
}

3/ Call the _pagecustomfields function at the right place (generally, after _pagefoot and just before $pdf->Close()):

// Pied de page
$this->_pagefoot($pdf,$object,$outputlangs);
$pdf->AliasNbPages();

// CustomFields
if ($conf->global->MAIN_MODULE_CUSTOMFIELDS) { // if the customfields module is activated...
        // Add a page with the customfields
        $pdf->AddPage();
        $this->_pagecustomfields($pdf,$object,$outputlangs);
        $pagenb++;
}

$pdf->Close(); // you should first search for this, you should only find one occurrence

Then go to the module's admin panel (eg: invoice admin panel) and enable the template you've just created.

You can now use it to test if your customfields work.

Conditions on fields selection

Conditions can be categorized into 3 types:

  • static (view on only prospect)
  • semi-dynamic (static table but based on the value of another field/customfield, like manub/rossy)
  • dynamic (based on another subfield of a field of the current module, like mermoz)

Overloading functions

The goal is to show two custom fields on the Third-Party module: one which gives the zone (secteur) of the third-party (Isere, Alpes du sud, Haute-Savoie...) and the other which gives relative to the zone the list of all the ski resorts (station_a) inside the selected zone.

We have one table llx_k_station (rowid, station (char50), secteur(char50)) which contains the following:

1,les 2 alpes,isère
2,chamrousse,isère
3,alpe d'huez,isère
4,vars,alpes du sud
5,risoul,alpes du sud
etc...

In CustomFields's admin panel, we create two custom fields: 1-secteur: returns the list of all zones - type DropdownBox: enum('- Aucun','Alpes du Sud','export','Haute-Savoie','Isère', etc...) 2-station_a: returns the list of all ski resorts - type constraint on llx_k_station

Here is the code to put in customfields_fields_extend.lib.php that will allow to show only the ski resorts corresponding to the selected zone:

function customfields_field_editview_societe_station_a (&$currentmodule, &$object, &$parameters, &$action, &$user, &$idvar, &$rightok, &$customfields, &$field, &$name, &$value) {
  global $db; // allow to access database functions
  $sql="SELECT llx_k_station.station, llx_k_station.rowid FROM llx_societe_customfields INNER JOIN llx_k_station ON llx_societe_customfields.Secteur = llx_k_station.secteur WHERE llx_societe_customfields.fk_societe=".$object->id;
$result=$db->query($sql);
 
  if ($result) {
    $num = $db->num_rows($result);
    $i = 0;
    $myarray = array();
    while ($i < $num)
    {
      $obj = $db->fetch_object($result);
      $myarray []=array('id'=>$obj->rowid, 'value'=>$obj->station);
      $i++;
    }
    $value = $myarray; 
    $db->free($result);
  }
}

Thank's to manub for giving this case.