<?php

namespace PHPMaker2023\Jack_Jill_school;

use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;

/**
 * Table class for Ciities Report
 */
class CiitiesReport extends ReportTable
{
    protected $SqlFrom = "";
    protected $SqlSelect = null;
    protected $SqlSelectList = null;
    protected $SqlWhere = "";
    protected $SqlGroupBy = "";
    protected $SqlHaving = "";
    protected $SqlOrderBy = "";
    public $DbErrorMessage = "";
    public $UseSessionForListSql = true;

    // Column CSS classes
    public $LeftColumnClass = "col-sm-4 col-form-label ew-label";
    public $RightColumnClass = "col-sm-8";
    public $OffsetColumnClass = "col-sm-8 offset-sm-4";
    public $TableLeftColumnClass = "w-col-4";
    public $ShowGroupHeaderAsRow = false;
    public $ShowCompactSummaryFooter = true;

    // Ajax / Modal
    public $UseAjaxActions = false;
    public $ModalSearch = false;
    public $ModalView = false;
    public $ModalAdd = false;
    public $ModalEdit = false;
    public $ModalUpdate = false;
    public $InlineDelete = false;
    public $ModalGridAdd = false;
    public $ModalGridEdit = false;
    public $ModalMultiEdit = false;
    public $CITIESCHART;

    // Fields
    public $volontaireID;
    public $NIP;
    public $Carte_No;
    public $Nom;
    public $Prenom;
    public $Photo;
    public $Sexe;
    public $DateNaissance;
    public $Lieu;
    public $Groupe_Sanguin;
    public $Delivree;
    public $Expire;
    public $Prevenir;
    public $Prevenir_Tel;
    public $Unique_QR;
    public $EmployeeID;
    public $Localite;
    public $Statut;
    public $Reference;

    // Page ID
    public $PageID = ""; // To be overridden by subclass

    // Constructor
    public function __construct()
    {
        parent::__construct();
        global $Language, $CurrentLanguage, $CurrentLocale;

        // Language object
        $Language = Container("language");
        $this->TableVar = "Ciities_Report";
        $this->TableName = 'Ciities Report';
        $this->TableType = "REPORT";
        $this->ReportSourceTable = 'volontaire'; // Report source table
        $this->Dbid = 'DB';
        $this->ExportAll = false;
        $this->ExportPageBreakCount = 0; // Page break per every n record (report only)

        // PDF
        $this->ExportPageOrientation = "portrait"; // Page orientation (PDF only)
        $this->ExportPageSize = "a4"; // Page size (PDF only)

        // PhpSpreadsheet
        $this->ExportExcelPageOrientation = \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_DEFAULT; // Page orientation (PhpSpreadsheet only)
        $this->ExportExcelPageSize = \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_A4; // Page size (PhpSpreadsheet only)

        // PHPWord
        $this->ExportWordPageOrientation = "portrait"; // Page orientation (PHPWord only)
        $this->ExportWordPageSize = "A4"; // Page orientation (PHPWord only)
        $this->ExportWordColumnWidth = null; // Cell width (PHPWord only)
        $this->UserIDAllowSecurity = Config("DEFAULT_USER_ID_ALLOW_SECURITY"); // Default User ID allowed permissions

        // volontaireID
        $this->volontaireID = new ReportField(
            $this, // Table
            'x_volontaireID', // Variable name
            'volontaireID', // Name
            '`volontaireID`', // Expression
            '`volontaireID`', // Basic search expression
            3, // Type
            11, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`volontaireID`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->volontaireID->InputTextType = "text";
        $this->volontaireID->IsPrimaryKey = true; // Primary key field
        $this->volontaireID->Nullable = false; // NOT NULL field
        $this->volontaireID->Required = true; // Required field
        $this->volontaireID->DefaultErrorMessage = $Language->phrase("IncorrectInteger");
        $this->volontaireID->SearchOperators = ["=", "<>", "IN", "NOT IN", "<", "<=", ">", ">=", "BETWEEN", "NOT BETWEEN"];
        $this->volontaireID->SourceTableVar = 'volontaire';
        $this->Fields['volontaireID'] = &$this->volontaireID;

        // NIP
        $this->NIP = new ReportField(
            $this, // Table
            'x_NIP', // Variable name
            'NIP', // Name
            '`NIP`', // Expression
            '`NIP`', // Basic search expression
            200, // Type
            57, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`NIP`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->NIP->InputTextType = "text";
        $this->NIP->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->NIP->SourceTableVar = 'volontaire';
        $this->Fields['NIP'] = &$this->NIP;

        // Carte_No
        $this->Carte_No = new ReportField(
            $this, // Table
            'x_Carte_No', // Variable name
            'Carte_No', // Name
            '`Carte_No`', // Expression
            '`Carte_No`', // Basic search expression
            200, // Type
            20, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Carte_No`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Carte_No->addMethod("getDefault", fn() => 2023-00);
        $this->Carte_No->InputTextType = "text";
        $this->Carte_No->Nullable = false; // NOT NULL field
        $this->Carte_No->Required = true; // Required field
        switch ($CurrentLanguage) {
            case "en-US":
                $this->Carte_No->Lookup = new Lookup('Carte_No', 'volontaire', true, 'Carte_No', ["Carte_No","","",""], '', '', [], [], [], [], [], [], '', '', "`Carte_No`");
                break;
            case "fr":
                $this->Carte_No->Lookup = new Lookup('Carte_No', 'volontaire', true, 'Carte_No', ["Carte_No","","",""], '', '', [], [], [], [], [], [], '', '', "`Carte_No`");
                break;
            default:
                $this->Carte_No->Lookup = new Lookup('Carte_No', 'volontaire', true, 'Carte_No', ["Carte_No","","",""], '', '', [], [], [], [], [], [], '', '', "`Carte_No`");
                break;
        }
        $this->Carte_No->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY"];
        $this->Carte_No->SourceTableVar = 'volontaire';
        $this->Fields['Carte_No'] = &$this->Carte_No;

        // Nom
        $this->Nom = new ReportField(
            $this, // Table
            'x_Nom', // Variable name
            'Nom', // Name
            '`Nom`', // Expression
            '`Nom`', // Basic search expression
            201, // Type
            260, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Nom`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Nom->InputTextType = "text";
        $this->Nom->Nullable = false; // NOT NULL field
        $this->Nom->Required = true; // Required field
        switch ($CurrentLanguage) {
            case "en-US":
                $this->Nom->Lookup = new Lookup('Nom', 'volontaire', true, 'Nom', ["Nom","","",""], '', '', [], [], [], [], [], [], '', '', "`Nom`");
                break;
            case "fr":
                $this->Nom->Lookup = new Lookup('Nom', 'volontaire', true, 'Nom', ["Nom","","",""], '', '', [], [], [], [], [], [], '', '', "`Nom`");
                break;
            default:
                $this->Nom->Lookup = new Lookup('Nom', 'volontaire', true, 'Nom', ["Nom","","",""], '', '', [], [], [], [], [], [], '', '', "`Nom`");
                break;
        }
        $this->Nom->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY"];
        $this->Nom->SourceTableVar = 'volontaire';
        $this->Fields['Nom'] = &$this->Nom;

        // Prenom
        $this->Prenom = new ReportField(
            $this, // Table
            'x_Prenom', // Variable name
            'Prenom', // Name
            '`Prenom`', // Expression
            '`Prenom`', // Basic search expression
            200, // Type
            60, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Prenom`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Prenom->InputTextType = "text";
        $this->Prenom->Nullable = false; // NOT NULL field
        $this->Prenom->Required = true; // Required field
        $this->Prenom->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY"];
        $this->Prenom->SourceTableVar = 'volontaire';
        $this->Fields['Prenom'] = &$this->Prenom;

        // Photo
        $this->Photo = new ReportField(
            $this, // Table
            'x_Photo', // Variable name
            'Photo', // Name
            '`Photo`', // Expression
            '`Photo`', // Basic search expression
            200, // Type
            60, // Size
            -1, // Date/Time format
            true, // Is upload field
            '`Photo`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'IMAGE', // View Tag
            'FILE' // Edit Tag
        );
        $this->Photo->addMethod("getUploadPath", fn() => "upload/volontaire/");
        $this->Photo->InputTextType = "text";
        $this->Photo->Required = true; // Required field
        $this->Photo->ImageResize = true;
        $this->Photo->SearchOperators = ["=", "<>", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->Photo->SourceTableVar = 'volontaire';
        $this->Fields['Photo'] = &$this->Photo;

        // Sexe
        $this->Sexe = new ReportField(
            $this, // Table
            'x_Sexe', // Variable name
            'Sexe', // Name
            '`Sexe`', // Expression
            '`Sexe`', // Basic search expression
            200, // Type
            12, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Sexe`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'RADIO' // Edit Tag
        );
        $this->Sexe->InputTextType = "text";
        switch ($CurrentLanguage) {
            case "en-US":
                $this->Sexe->Lookup = new Lookup('Sexe', 'Ciities_Report', false, '', ["","","",""], '', '', [], [], [], [], [], [], '', '', "");
                break;
            case "fr":
                $this->Sexe->Lookup = new Lookup('Sexe', 'Ciities_Report', false, '', ["","","",""], '', '', [], [], [], [], [], [], '', '', "");
                break;
            default:
                $this->Sexe->Lookup = new Lookup('Sexe', 'Ciities_Report', false, '', ["","","",""], '', '', [], [], [], [], [], [], '', '', "");
                break;
        }
        $this->Sexe->OptionCount = 2;
        $this->Sexe->SearchOperators = ["=", "<>", "IS NULL", "IS NOT NULL"];
        $this->Sexe->SourceTableVar = 'volontaire';
        $this->Fields['Sexe'] = &$this->Sexe;

        // DateNaissance
        $this->DateNaissance = new ReportField(
            $this, // Table
            'x_DateNaissance', // Variable name
            'DateNaissance', // Name
            '`DateNaissance`', // Expression
            CastDateFieldForLike("`DateNaissance`", 7, "DB"), // Basic search expression
            133, // Type
            10, // Size
            7, // Date/Time format
            false, // Is upload field
            '`DateNaissance`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->DateNaissance->InputTextType = "text";
        $this->DateNaissance->DefaultErrorMessage = str_replace("%s", DateFormat(7), $Language->phrase("IncorrectDate"));
        $this->DateNaissance->SearchOperators = ["=", "<>", "IN", "NOT IN", "<", "<=", ">", ">=", "BETWEEN", "NOT BETWEEN", "IS NULL", "IS NOT NULL"];
        $this->DateNaissance->SourceTableVar = 'volontaire';
        $this->Fields['DateNaissance'] = &$this->DateNaissance;

        // Lieu
        $this->Lieu = new ReportField(
            $this, // Table
            'x_Lieu', // Variable name
            'Lieu', // Name
            '`Lieu`', // Expression
            '`Lieu`', // Basic search expression
            200, // Type
            50, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Lieu`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Lieu->InputTextType = "text";
        $this->Lieu->Nullable = false; // NOT NULL field
        $this->Lieu->Required = true; // Required field
        switch ($CurrentLanguage) {
            case "en-US":
                $this->Lieu->Lookup = new Lookup('Lieu', 'volontaire', true, 'Lieu', ["Lieu","","",""], '', '', [], [], [], [], [], [], '', '', "`Lieu`");
                break;
            case "fr":
                $this->Lieu->Lookup = new Lookup('Lieu', 'volontaire', true, 'Lieu', ["Lieu","","",""], '', '', [], [], [], [], [], [], '', '', "`Lieu`");
                break;
            default:
                $this->Lieu->Lookup = new Lookup('Lieu', 'volontaire', true, 'Lieu', ["Lieu","","",""], '', '', [], [], [], [], [], [], '', '', "`Lieu`");
                break;
        }
        $this->Lieu->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY"];
        $this->Lieu->SourceTableVar = 'volontaire';
        $this->Fields['Lieu'] = &$this->Lieu;

        // Groupe_Sanguin
        $this->Groupe_Sanguin = new ReportField(
            $this, // Table
            'x_Groupe_Sanguin', // Variable name
            'Groupe_Sanguin', // Name
            '`Groupe_Sanguin`', // Expression
            '`Groupe_Sanguin`', // Basic search expression
            200, // Type
            23, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Groupe_Sanguin`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Groupe_Sanguin->InputTextType = "text";
        $this->Groupe_Sanguin->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->Groupe_Sanguin->SourceTableVar = 'volontaire';
        $this->Fields['Groupe_Sanguin'] = &$this->Groupe_Sanguin;

        // Delivree
        $this->Delivree = new ReportField(
            $this, // Table
            'x_Delivree', // Variable name
            'Delivree', // Name
            '`Delivree`', // Expression
            CastDateFieldForLike("`Delivree`", 7, "DB"), // Basic search expression
            133, // Type
            10, // Size
            7, // Date/Time format
            false, // Is upload field
            '`Delivree`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Delivree->InputTextType = "text";
        $this->Delivree->DefaultErrorMessage = str_replace("%s", DateFormat(7), $Language->phrase("IncorrectDate"));
        $this->Delivree->SearchOperators = ["=", "<>", "IN", "NOT IN", "<", "<=", ">", ">=", "BETWEEN", "NOT BETWEEN", "IS NULL", "IS NOT NULL"];
        $this->Delivree->SourceTableVar = 'volontaire';
        $this->Fields['Delivree'] = &$this->Delivree;

        // Expire
        $this->Expire = new ReportField(
            $this, // Table
            'x_Expire', // Variable name
            'Expire', // Name
            '`Expire`', // Expression
            CastDateFieldForLike("`Expire`", 7, "DB"), // Basic search expression
            133, // Type
            10, // Size
            7, // Date/Time format
            false, // Is upload field
            '`Expire`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Expire->InputTextType = "text";
        $this->Expire->DefaultErrorMessage = str_replace("%s", DateFormat(7), $Language->phrase("IncorrectDate"));
        $this->Expire->SearchOperators = ["=", "<>", "IN", "NOT IN", "<", "<=", ">", ">=", "BETWEEN", "NOT BETWEEN", "IS NULL", "IS NOT NULL"];
        $this->Expire->SourceTableVar = 'volontaire';
        $this->Fields['Expire'] = &$this->Expire;

        // Prevenir
        $this->Prevenir = new ReportField(
            $this, // Table
            'x_Prevenir', // Variable name
            'Prevenir', // Name
            '`Prevenir`', // Expression
            '`Prevenir`', // Basic search expression
            200, // Type
            70, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Prevenir`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Prevenir->InputTextType = "text";
        $this->Prevenir->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->Prevenir->SourceTableVar = 'volontaire';
        $this->Fields['Prevenir'] = &$this->Prevenir;

        // Prevenir_Tel
        $this->Prevenir_Tel = new ReportField(
            $this, // Table
            'x_Prevenir_Tel', // Variable name
            'Prevenir_Tel', // Name
            '`Prevenir_Tel`', // Expression
            '`Prevenir_Tel`', // Basic search expression
            200, // Type
            25, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Prevenir_Tel`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Prevenir_Tel->InputTextType = "text";
        $this->Prevenir_Tel->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->Prevenir_Tel->SourceTableVar = 'volontaire';
        $this->Fields['Prevenir_Tel'] = &$this->Prevenir_Tel;

        // Unique_QR
        $this->Unique_QR = new ReportField(
            $this, // Table
            'x_Unique_QR', // Variable name
            'Unique_QR', // Name
            '`Unique_QR`', // Expression
            '`Unique_QR`', // Basic search expression
            200, // Type
            12, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Unique_QR`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Unique_QR->InputTextType = "text";
        $this->Unique_QR->Required = true; // Required field
        switch ($CurrentLanguage) {
            case "en-US":
                $this->Unique_QR->Lookup = new Lookup('Unique_QR', 'volontaire', true, 'Unique_QR', ["Unique_QR","","",""], '', '', [], [], [], [], [], [], '', '', "`Unique_QR`");
                break;
            case "fr":
                $this->Unique_QR->Lookup = new Lookup('Unique_QR', 'volontaire', true, 'Unique_QR', ["Unique_QR","","",""], '', '', [], [], [], [], [], [], '', '', "`Unique_QR`");
                break;
            default:
                $this->Unique_QR->Lookup = new Lookup('Unique_QR', 'volontaire', true, 'Unique_QR', ["Unique_QR","","",""], '', '', [], [], [], [], [], [], '', '', "`Unique_QR`");
                break;
        }
        $this->Unique_QR->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->Unique_QR->SourceTableVar = 'volontaire';
        $this->Fields['Unique_QR'] = &$this->Unique_QR;

        // EmployeeID
        $this->EmployeeID = new ReportField(
            $this, // Table
            'x_EmployeeID', // Variable name
            'EmployeeID', // Name
            '`EmployeeID`', // Expression
            '`EmployeeID`', // Basic search expression
            16, // Type
            4, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`EmployeeID`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'SELECT' // Edit Tag
        );
        $this->EmployeeID->InputTextType = "text";
        $this->EmployeeID->Sortable = false; // Allow sort
        $this->EmployeeID->setSelectMultiple(false); // Select one
        $this->EmployeeID->UsePleaseSelect = true; // Use PleaseSelect by default
        $this->EmployeeID->PleaseSelectText = $Language->phrase("PleaseSelect"); // "PleaseSelect" text
        switch ($CurrentLanguage) {
            case "en-US":
                $this->EmployeeID->Lookup = new Lookup('EmployeeID', 'employees', false, 'EmployeeID', ["LastName","FirstName","",""], '', '', [], [], [], [], [], [], '', '', "CONCAT(COALESCE(`LastName`, ''),'" . ValueSeparator(1, $this->EmployeeID) . "',COALESCE(`FirstName`,''))");
                break;
            case "fr":
                $this->EmployeeID->Lookup = new Lookup('EmployeeID', 'employees', false, 'EmployeeID', ["LastName","FirstName","",""], '', '', [], [], [], [], [], [], '', '', "CONCAT(COALESCE(`LastName`, ''),'" . ValueSeparator(1, $this->EmployeeID) . "',COALESCE(`FirstName`,''))");
                break;
            default:
                $this->EmployeeID->Lookup = new Lookup('EmployeeID', 'employees', false, 'EmployeeID', ["LastName","FirstName","",""], '', '', [], [], [], [], [], [], '', '', "CONCAT(COALESCE(`LastName`, ''),'" . ValueSeparator(1, $this->EmployeeID) . "',COALESCE(`FirstName`,''))");
                break;
        }
        $this->EmployeeID->DefaultErrorMessage = $Language->phrase("IncorrectInteger");
        $this->EmployeeID->SearchOperators = ["=", "<>", "<", "<=", ">", ">=", "BETWEEN", "NOT BETWEEN", "IS NULL", "IS NOT NULL"];
        $this->EmployeeID->SourceTableVar = 'volontaire';
        $this->Fields['EmployeeID'] = &$this->EmployeeID;

        // Localite
        $this->Localite = new ReportField(
            $this, // Table
            'x_Localite', // Variable name
            'Localite', // Name
            '`Localite`', // Expression
            '`Localite`', // Basic search expression
            200, // Type
            60, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Localite`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Localite->InputTextType = "text";
        $this->Localite->GroupingFieldId = 1;
        $this->Localite->ShowGroupHeaderAsRow = $this->ShowGroupHeaderAsRow;
        $this->Localite->ShowCompactSummaryFooter = $this->ShowCompactSummaryFooter;
        $this->Localite->GroupByType = "";
        $this->Localite->GroupInterval = "0";
        $this->Localite->GroupSql = "";
        $this->Localite->Nullable = false; // NOT NULL field
        $this->Localite->Required = true; // Required field
        switch ($CurrentLanguage) {
            case "en-US":
                $this->Localite->Lookup = new Lookup('Localite', 'volontaire', true, 'Localite', ["Localite","","",""], '', '', [], [], [], [], [], [], '', '', "`Localite`");
                break;
            case "fr":
                $this->Localite->Lookup = new Lookup('Localite', 'volontaire', true, 'Localite', ["Localite","","",""], '', '', [], [], [], [], [], [], '', '', "`Localite`");
                break;
            default:
                $this->Localite->Lookup = new Lookup('Localite', 'volontaire', true, 'Localite', ["Localite","","",""], '', '', [], [], [], [], [], [], '', '', "`Localite`");
                break;
        }
        $this->Localite->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY"];
        $this->Localite->SourceTableVar = 'volontaire';
        $this->Fields['Localite'] = &$this->Localite;

        // Statut
        $this->Statut = new ReportField(
            $this, // Table
            'x_Statut', // Variable name
            'Statut', // Name
            '`Statut`', // Expression
            '`Statut`', // Basic search expression
            200, // Type
            50, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Statut`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Statut->InputTextType = "text";
        $this->Statut->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY", "IS NULL", "IS NOT NULL"];
        $this->Statut->SourceTableVar = 'volontaire';
        $this->Fields['Statut'] = &$this->Statut;

        // Reference
        $this->Reference = new ReportField(
            $this, // Table
            'x_Reference', // Variable name
            'Reference', // Name
            '`Reference`', // Expression
            '`Reference`', // Basic search expression
            200, // Type
            100, // Size
            -1, // Date/Time format
            false, // Is upload field
            '`Reference`', // Virtual expression
            false, // Is virtual
            false, // Force selection
            false, // Is Virtual search
            'FORMATTED TEXT', // View Tag
            'TEXT' // Edit Tag
        );
        $this->Reference->InputTextType = "text";
        $this->Reference->Nullable = false; // NOT NULL field
        $this->Reference->Required = true; // Required field
        $this->Reference->SearchOperators = ["=", "<>", "IN", "NOT IN", "STARTS WITH", "NOT STARTS WITH", "LIKE", "NOT LIKE", "ENDS WITH", "NOT ENDS WITH", "IS EMPTY", "IS NOT EMPTY"];
        $this->Reference->SourceTableVar = 'volontaire';
        $this->Fields['Reference'] = &$this->Reference;

        // CITIES CHART
        $this->CITIESCHART = new DbChart($this, 'CITIESCHART', 'CITIES CHART', 'Localite', 'Localite', 1004, '', 0, 'COUNT', 1000, 9999);
        $this->CITIESCHART->Position = 4;
        $this->CITIESCHART->PageBreakType = "before";
        $this->CITIESCHART->YAxisFormat = [""];
        $this->CITIESCHART->YFieldFormat = [""];
        $this->CITIESCHART->SortType = 1;
        $this->CITIESCHART->SortSequence = "";
        $this->CITIESCHART->SqlSelect = $this->getQueryBuilder()->select("`Localite`", "''", "COUNT(`Localite`)");
        $this->CITIESCHART->SqlGroupBy = "`Localite`";
        $this->CITIESCHART->SqlOrderBy = "`Localite` ASC";
        $this->CITIESCHART->SeriesDateType = "";
        $this->CITIESCHART->ID = "Ciities_Report_CITIESCHART"; // Chart ID
        $this->CITIESCHART->setParameters([
            ["type", "1004"],
            ["seriestype", "0"]
        ]); // Chart type / Chart series type
        $this->CITIESCHART->setParameters([
            ["caption", $this->CITIESCHART->caption()],
            ["xaxisname", $this->CITIESCHART->xAxisName()]
        ]); // Chart caption / X axis name
        $this->CITIESCHART->setParameter("yaxisname", $this->CITIESCHART->yAxisName()); // Y axis name
        $this->CITIESCHART->setParameters([
            ["shownames", "1"],
            ["showvalues", "1"],
            ["showhovercap", "1"]
        ]); // Show names / Show values / Show hover
        $this->CITIESCHART->setParameter("alpha", "50"); // Chart alpha
        $this->CITIESCHART->setParameter("colorpalette", "#5899DA,#E8743B,#19A979,#ED4A7B,#945ECF,#13A4B4,#525DF4,#BF399E,#6C8893,#EE6868,#2F6497"); // Chart color palette
        $this->CITIESCHART->setParameters([["options.animation.duration",10],["options.animation.easing","linear"]]);
        $this->Charts[$this->CITIESCHART->ID] = &$this->CITIESCHART;

        // Add Doctrine Cache
        $this->Cache = new ArrayCache();
        $this->CacheProfile = new \Doctrine\DBAL\Cache\QueryCacheProfile(0, $this->TableVar);

        // Call Table Load event
        $this->tableLoad();
    }

    // Field Visibility
    public function getFieldVisibility($fldParm)
    {
        global $Security;
        return $this->$fldParm->Visible; // Returns original value
    }

    // Single column sort
    protected function updateSort(&$fld)
    {
        if ($this->CurrentOrder == $fld->Name) {
            $sortField = $fld->Expression;
            $lastSort = $fld->getSort();
            if (in_array($this->CurrentOrderType, ["ASC", "DESC", "NO"])) {
                $curSort = $this->CurrentOrderType;
            } else {
                $curSort = $lastSort;
            }
            $fld->setSort($curSort);
            $lastOrderBy = in_array($lastSort, ["ASC", "DESC"]) ? $sortField . " " . $lastSort : "";
            $curOrderBy = in_array($curSort, ["ASC", "DESC"]) ? $sortField . " " . $curSort : "";
            if ($fld->GroupingFieldId == 0) {
                $this->setDetailOrderBy($curOrderBy); // Save to Session
            }
        } else {
            if ($fld->GroupingFieldId == 0) {
                $fld->setSort("");
            }
        }
    }

    // Get Sort SQL
    protected function sortSql()
    {
        $dtlSortSql = $this->getDetailOrderBy(); // Get ORDER BY for detail fields from session
        $argrps = [];
        foreach ($this->Fields as $fld) {
            if (in_array($fld->getSort(), ["ASC", "DESC"])) {
                $fldsql = $fld->Expression;
                if ($fld->GroupingFieldId > 0) {
                    if ($fld->GroupSql != "") {
                        $argrps[$fld->GroupingFieldId] = str_replace("%s", $fldsql, $fld->GroupSql) . " " . $fld->getSort();
                    } else {
                        $argrps[$fld->GroupingFieldId] = $fldsql . " " . $fld->getSort();
                    }
                }
            }
        }
        $sortSql = "";
        foreach ($argrps as $grp) {
            if ($sortSql != "") {
                $sortSql .= ", ";
            }
            $sortSql .= $grp;
        }
        if ($dtlSortSql != "") {
            if ($sortSql != "") {
                $sortSql .= ", ";
            }
            $sortSql .= $dtlSortSql;
        }
        return $sortSql;
    }

    // Table Level Group SQL
    private $sqlFirstGroupField = "";
    private $sqlSelectGroup = null;
    private $sqlOrderByGroup = "";

    // First Group Field
    public function getSqlFirstGroupField($alias = false)
    {
        if ($this->sqlFirstGroupField != "") {
            return $this->sqlFirstGroupField;
        }
        $firstGroupField = &$this->Localite;
        $expr = $firstGroupField->Expression;
        if ($firstGroupField->GroupSql != "") {
            $expr = str_replace("%s", $firstGroupField->Expression, $firstGroupField->GroupSql);
            if ($alias) {
                $expr .= " AS " . QuotedName($firstGroupField->getGroupName(), $this->Dbid);
            }
        }
        return $expr;
    }

    public function setSqlFirstGroupField($v)
    {
        $this->sqlFirstGroupField = $v;
    }

    // Select Group
    public function getSqlSelectGroup()
    {
        return $this->sqlSelectGroup ?? $this->getQueryBuilder()->select($this->getSqlFirstGroupField(true))->distinct();
    }

    public function setSqlSelectGroup($v)
    {
        $this->sqlSelectGroup = $v;
    }

    // Order By Group
    public function getSqlOrderByGroup()
    {
        if ($this->sqlOrderByGroup != "") {
            return $this->sqlOrderByGroup;
        }
        return $this->getSqlFirstGroupField() . " ASC";
    }

    public function setSqlOrderByGroup($v)
    {
        $this->sqlOrderByGroup = $v;
    }

    // Summary properties
    private $sqlSelectAggregate = null;
    private $sqlAggregatePrefix = "";
    private $sqlAggregateSuffix = "";
    private $sqlSelectCount = null;

    // Select Aggregate
    public function getSqlSelectAggregate()
    {
        return $this->sqlSelectAggregate ?? $this->getQueryBuilder()->select("*");
    }

    public function setSqlSelectAggregate($v)
    {
        $this->sqlSelectAggregate = $v;
    }

    // Aggregate Prefix
    public function getSqlAggregatePrefix()
    {
        return ($this->sqlAggregatePrefix != "") ? $this->sqlAggregatePrefix : "";
    }

    public function setSqlAggregatePrefix($v)
    {
        $this->sqlAggregatePrefix = $v;
    }

    // Aggregate Suffix
    public function getSqlAggregateSuffix()
    {
        return ($this->sqlAggregateSuffix != "") ? $this->sqlAggregateSuffix : "";
    }

    public function setSqlAggregateSuffix($v)
    {
        $this->sqlAggregateSuffix = $v;
    }

    // Select Count
    public function getSqlSelectCount()
    {
        return $this->sqlSelectCount ?? $this->getQueryBuilder()->select("COUNT(*)");
    }

    public function setSqlSelectCount($v)
    {
        $this->sqlSelectCount = $v;
    }

    // Render for lookup
    public function renderLookup()
    {
        $this->Carte_No->ViewValue = $this->Carte_No->CurrentValue;
        $this->Unique_QR->ViewValue = $this->Unique_QR->CurrentValue;
        $this->Localite->ViewValue = $this->Localite->CurrentValue;
    }

    // Render X Axis for chart
    public function renderChartXAxis($chartVar, $chartRow)
    {
        if ($chartVar == "CITIESCHART") {
            $this->Localite->CurrentValue = $chartRow[0];
            $this->Localite->ViewValue = $this->Localite->CurrentValue;
            $arwrk = [];
            $arwrk["lf"] = $this->Localite->CurrentValue;
            $arwrk["df"] = $this->Localite->CurrentValue;
            $arwrk = $this->Localite->Lookup->renderViewRow($arwrk, $this);
            $dispVal = $this->Localite->displayValue($arwrk);
            if ($dispVal != "") {
                $this->Localite->ViewValue = $dispVal;
            }
            $this->Localite->CssClass = "fw-bold";
            $chartRow[0] = is_object($this->Localite->ViewValue) ? $this->Localite->ViewValue->__toString() : $this->Localite->ViewValue;
        }
        return $chartRow;
    }

    // Table level SQL
    public function getSqlFrom() // From
    {
        return ($this->SqlFrom != "") ? $this->SqlFrom : "volontaire";
    }

    public function sqlFrom() // For backward compatibility
    {
        return $this->getSqlFrom();
    }

    public function setSqlFrom($v)
    {
        $this->SqlFrom = $v;
    }

    public function getSqlSelect() // Select
    {
        if ($this->SqlSelect) {
            return $this->SqlSelect;
        }
        $select = $this->getQueryBuilder()->select("*");
        $groupField = &$this->Localite;
        if ($groupField->GroupSql != "") {
            $expr = str_replace("%s", $groupField->Expression, $groupField->GroupSql) . " AS " . QuotedName($groupField->getGroupName(), $this->Dbid);
            $select->addSelect($expr);
        }
        return $select;
    }

    public function sqlSelect() // For backward compatibility
    {
        return $this->getSqlSelect();
    }

    public function setSqlSelect($v)
    {
        $this->SqlSelect = $v;
    }

    public function getSqlWhere() // Where
    {
        $where = ($this->SqlWhere != "") ? $this->SqlWhere : "";
        $this->DefaultFilter = "";
        AddFilter($where, $this->DefaultFilter);
        return $where;
    }

    public function sqlWhere() // For backward compatibility
    {
        return $this->getSqlWhere();
    }

    public function setSqlWhere($v)
    {
        $this->SqlWhere = $v;
    }

    public function getSqlGroupBy() // Group By
    {
        return ($this->SqlGroupBy != "") ? $this->SqlGroupBy : "";
    }

    public function sqlGroupBy() // For backward compatibility
    {
        return $this->getSqlGroupBy();
    }

    public function setSqlGroupBy($v)
    {
        $this->SqlGroupBy = $v;
    }

    public function getSqlHaving() // Having
    {
        return ($this->SqlHaving != "") ? $this->SqlHaving : "";
    }

    public function sqlHaving() // For backward compatibility
    {
        return $this->getSqlHaving();
    }

    public function setSqlHaving($v)
    {
        $this->SqlHaving = $v;
    }

    public function getSqlOrderBy() // Order By
    {
        return ($this->SqlOrderBy != "") ? $this->SqlOrderBy : "";
    }

    public function sqlOrderBy() // For backward compatibility
    {
        return $this->getSqlOrderBy();
    }

    public function setSqlOrderBy($v)
    {
        $this->SqlOrderBy = $v;
    }

    // Apply User ID filters
    public function applyUserIDFilters($filter, $id = "")
    {
        return $filter;
    }

    // Check if User ID security allows view all
    public function userIDAllow($id = "")
    {
        $allow = $this->UserIDAllowSecurity;
        switch ($id) {
            case "add":
            case "copy":
            case "gridadd":
            case "register":
            case "addopt":
                return (($allow & 1) == 1);
            case "edit":
            case "gridedit":
            case "update":
            case "changepassword":
            case "resetpassword":
                return (($allow & 4) == 4);
            case "delete":
                return (($allow & 2) == 2);
            case "view":
                return (($allow & 32) == 32);
            case "search":
                return (($allow & 64) == 64);
            case "lookup":
                return (($allow & 256) == 256);
            default:
                return (($allow & 8) == 8);
        }
    }

    /**
     * Get record count
     *
     * @param string|QueryBuilder $sql SQL or QueryBuilder
     * @param mixed $c Connection
     * @return int
     */
    public function getRecordCount($sql, $c = null)
    {
        $cnt = -1;
        $rs = null;
        if ($sql instanceof QueryBuilder) { // Query builder
            $sqlwrk = clone $sql;
            $sqlwrk = $sqlwrk->resetQueryPart("orderBy")->getSQL();
        } else {
            $sqlwrk = $sql;
        }
        $pattern = '/^SELECT\s([\s\S]+)\sFROM\s/i';
        // Skip Custom View / SubQuery / SELECT DISTINCT / ORDER BY
        if (
            ($this->TableType == 'TABLE' || $this->TableType == 'VIEW' || $this->TableType == 'LINKTABLE') &&
            preg_match($pattern, $sqlwrk) && !preg_match('/\(\s*(SELECT[^)]+)\)/i', $sqlwrk) &&
            !preg_match('/^\s*select\s+distinct\s+/i', $sqlwrk) && !preg_match('/\s+order\s+by\s+/i', $sqlwrk)
        ) {
            $sqlwrk = "SELECT COUNT(*) FROM " . preg_replace($pattern, "", $sqlwrk);
        } else {
            $sqlwrk = "SELECT COUNT(*) FROM (" . $sqlwrk . ") COUNT_TABLE";
        }
        $conn = $c ?? $this->getConnection();
        $cnt = $conn->fetchOne($sqlwrk);
        if ($cnt !== false) {
            return (int)$cnt;
        }

        // Unable to get count by SELECT COUNT(*), execute the SQL to get record count directly
        return ExecuteRecordCount($sql, $conn);
    }

    // Record filter WHERE clause
    protected function sqlKeyFilter()
    {
        return "`volontaireID` = @volontaireID@";
    }

    // Get Key
    public function getKey($current = false)
    {
        $keys = [];
        $val = $current ? $this->volontaireID->CurrentValue : $this->volontaireID->OldValue;
        if (EmptyValue($val)) {
            return "";
        } else {
            $keys[] = $val;
        }
        return implode(Config("COMPOSITE_KEY_SEPARATOR"), $keys);
    }

    // Set Key
    public function setKey($key, $current = false)
    {
        $this->OldKey = strval($key);
        $keys = explode(Config("COMPOSITE_KEY_SEPARATOR"), $this->OldKey);
        if (count($keys) == 1) {
            if ($current) {
                $this->volontaireID->CurrentValue = $keys[0];
            } else {
                $this->volontaireID->OldValue = $keys[0];
            }
        }
    }

    // Get record filter
    public function getRecordFilter($row = null, $current = false)
    {
        $keyFilter = $this->sqlKeyFilter();
        if (is_array($row)) {
            $val = array_key_exists('volontaireID', $row) ? $row['volontaireID'] : null;
        } else {
            $val = !EmptyValue($this->volontaireID->OldValue) && !$current ? $this->volontaireID->OldValue : $this->volontaireID->CurrentValue;
        }
        if (!is_numeric($val)) {
            return "0=1"; // Invalid key
        }
        if ($val === null) {
            return "0=1"; // Invalid key
        } else {
            $keyFilter = str_replace("@volontaireID@", AdjustSql($val, $this->Dbid), $keyFilter); // Replace key value
        }
        return $keyFilter;
    }

    // Return page URL
    public function getReturnUrl()
    {
        $referUrl = ReferUrl();
        $referPageName = ReferPageName();
        $name = PROJECT_NAME . "_" . $this->TableVar . "_" . Config("TABLE_RETURN_URL");
        // Get referer URL automatically
        if ($referUrl != "" && $referPageName != CurrentPageName() && $referPageName != "login") { // Referer not same page or login page
            $_SESSION[$name] = $referUrl; // Save to Session
        }
        return $_SESSION[$name] ?? GetUrl("");
    }

    // Set return page URL
    public function setReturnUrl($v)
    {
        $_SESSION[PROJECT_NAME . "_" . $this->TableVar . "_" . Config("TABLE_RETURN_URL")] = $v;
    }

    // Get modal caption
    public function getModalCaption($pageName)
    {
        global $Language;
        if ($pageName == "") {
            return $Language->phrase("View");
        } elseif ($pageName == "") {
            return $Language->phrase("Edit");
        } elseif ($pageName == "") {
            return $Language->phrase("Add");
        }
        return "";
    }

    // API page name
    public function getApiPageName($action)
    {
        return "CiitiesReportSummary";
    }

    // Current URL
    public function getCurrentUrl($parm = "")
    {
        $url = CurrentPageUrl(false);
        if ($parm != "") {
            $url = $this->keyUrl($url, $parm);
        } else {
            $url = $this->keyUrl($url, Config("TABLE_SHOW_DETAIL") . "=");
        }
        return $this->addMasterUrl($url);
    }

    // List URL
    public function getListUrl()
    {
        return "";
    }

    // View URL
    public function getViewUrl($parm = "")
    {
        if ($parm != "") {
            $url = $this->keyUrl("", $parm);
        } else {
            $url = $this->keyUrl("", Config("TABLE_SHOW_DETAIL") . "=");
        }
        return $this->addMasterUrl($url);
    }

    // Add URL
    public function getAddUrl($parm = "")
    {
        if ($parm != "") {
            $url = "?" . $parm;
        } else {
            $url = "";
        }
        return $this->addMasterUrl($url);
    }

    // Edit URL
    public function getEditUrl($parm = "")
    {
        $url = $this->keyUrl("", $parm);
        return $this->addMasterUrl($url);
    }

    // Inline edit URL
    public function getInlineEditUrl()
    {
        $url = $this->keyUrl("", "action=edit");
        return $this->addMasterUrl($url);
    }

    // Copy URL
    public function getCopyUrl($parm = "")
    {
        $url = $this->keyUrl("", $parm);
        return $this->addMasterUrl($url);
    }

    // Inline copy URL
    public function getInlineCopyUrl()
    {
        $url = $this->keyUrl("", "action=copy");
        return $this->addMasterUrl($url);
    }

    // Delete URL
    public function getDeleteUrl()
    {
        if ($this->UseAjaxActions && ConvertToBool(Param("infinitescroll")) && CurrentPageID() == "list") {
            return $this->keyUrl(GetApiUrl(Config("API_DELETE_ACTION") . "/" . $this->TableVar));
        } else {
            return $this->keyUrl("");
        }
    }

    // Add master url
    public function addMasterUrl($url)
    {
        return $url;
    }

    public function keyToJson($htmlEncode = false)
    {
        $json = "";
        $json .= "\"volontaireID\":" . JsonEncode($this->volontaireID->CurrentValue, "number");
        $json = "{" . $json . "}";
        if ($htmlEncode) {
            $json = HtmlEncode($json);
        }
        return $json;
    }

    // Add key value to URL
    public function keyUrl($url, $parm = "")
    {
        if ($this->volontaireID->CurrentValue !== null) {
            $url .= "/" . $this->encodeKeyValue($this->volontaireID->CurrentValue);
        } else {
            return "javascript:ew.alert(ew.language.phrase('InvalidRecord'));";
        }
        if ($parm != "") {
            $url .= "?" . $parm;
        }
        return $url;
    }

    // Render sort
    public function renderFieldHeader($fld)
    {
        global $Security, $Language, $Page;
        $sortUrl = "";
        $attrs = "";
        if ($fld->Sortable) {
            $sortUrl = $this->sortUrl($fld);
            $attrs = ' role="button" data-ew-action="sort" data-ajax="' . ($this->UseAjaxActions ? "true" : "false") . '" data-sort-url="' . $sortUrl . '" data-sort-type="1"';
            if ($this->ContextClass) { // Add context
                $attrs .= ' data-context="' . HtmlEncode($this->ContextClass) . '"';
            }
        }
        $html = '<div class="ew-table-header-caption"' . $attrs . '>' . $fld->caption() . '</div>';
        if ($sortUrl) {
            $html .= '<div class="ew-table-header-sort">' . $fld->getSortIcon() . '</div>';
        }
        if ($fld->UseFilter && $Security->canSearch()) {
            $html .= '<div class="ew-filter-dropdown-btn" data-ew-action="filter" data-table="' . $fld->TableVar . '" data-field="' . $fld->FieldVar .
                '"><div class="ew-table-header-filter" role="button" aria-haspopup="true">' . $Language->phrase("Filter") . '</div></div>';
        }
        $html = '<div class="ew-table-header-btn">' . $html . '</div>';
        if ($this->UseCustomTemplate) {
            $scriptId = str_replace("{id}", $fld->TableVar . "_" . $fld->Param, "tpc_{id}");
            $html = '<template id="' . $scriptId . '">' . $html . '</template>';
        }
        return $html;
    }

    // Sort URL
    public function sortUrl($fld)
    {
        global $DashboardReport;
        if (
            $this->CurrentAction || $this->isExport() ||
            $this->DrillDown ||
            in_array($fld->Type, [128, 204, 205])
        ) { // Unsortable data type
                return "";
        } elseif ($fld->Sortable) {
            $urlParm = "order=" . urlencode($fld->Name) . "&amp;ordertype=" . $fld->getNextSort();
            if ($DashboardReport) {
                $urlParm .= "&amp;dashboard=true";
            }
            return $this->addMasterUrl($this->CurrentPageName . "?" . $urlParm);
        } else {
            return "";
        }
    }

    // Get record keys from Post/Get/Session
    public function getRecordKeys()
    {
        $arKeys = [];
        $arKey = [];
        if (Param("key_m") !== null) {
            $arKeys = Param("key_m");
            $cnt = count($arKeys);
        } else {
            if (($keyValue = Param("volontaireID") ?? Route("volontaireID")) !== null) {
                $arKeys[] = $keyValue;
            } elseif (IsApi() && (($keyValue = Key(0) ?? Route(2)) !== null)) {
                $arKeys[] = $keyValue;
            } else {
                $arKeys = null; // Do not setup
            }

            //return $arKeys; // Do not return yet, so the values will also be checked by the following code
        }
        // Check keys
        $ar = [];
        if (is_array($arKeys)) {
            foreach ($arKeys as $key) {
                if (!is_numeric($key)) {
                    continue;
                }
                $ar[] = $key;
            }
        }
        return $ar;
    }

    // Get filter from records
    public function getFilterFromRecords($rows)
    {
        $keyFilter = "";
        foreach ($rows as $row) {
            if ($keyFilter != "") {
                $keyFilter .= " OR ";
            }
            $keyFilter .= "(" . $this->getRecordFilter($row) . ")";
        }
        return $keyFilter;
    }

    // Get filter from record keys
    public function getFilterFromRecordKeys($setCurrent = true)
    {
        $arKeys = $this->getRecordKeys();
        $keyFilter = "";
        foreach ($arKeys as $key) {
            if ($keyFilter != "") {
                $keyFilter .= " OR ";
            }
            if ($setCurrent) {
                $this->volontaireID->CurrentValue = $key;
            } else {
                $this->volontaireID->OldValue = $key;
            }
            $keyFilter .= "(" . $this->getRecordFilter() . ")";
        }
        return $keyFilter;
    }

    // Load recordset based on filter / sort
    public function loadRs($filter, $sort = "")
    {
        $sql = $this->getSql($filter, $sort); // Set up filter (WHERE Clause) / sort (ORDER BY Clause)
        $conn = $this->getConnection();
        return $conn->executeQuery($sql);
    }

    // Get file data
    public function getFileData($fldparm, $key, $resize, $width = 0, $height = 0, $plugins = [])
    {
        global $DownloadFileName;
        $width = ($width > 0) ? $width : Config("THUMBNAIL_DEFAULT_WIDTH");
        $height = ($height > 0) ? $height : Config("THUMBNAIL_DEFAULT_HEIGHT");

        // Set up field name / file name field / file type field
        $fldName = "";
        $fileNameFld = "";
        $fileTypeFld = "";
        if ($fldparm == 'Photo') {
            $fldName = "Photo";
            $fileNameFld = "Photo";
        } else {
            return false; // Incorrect field
        }

        // Set up key values
        $ar = explode(Config("COMPOSITE_KEY_SEPARATOR"), $key);
        if (count($ar) == 1) {
            $this->volontaireID->CurrentValue = $ar[0];
        } else {
            return false; // Incorrect key
        }

        // Set up filter (WHERE Clause)
        $filter = $this->getRecordFilter();
        $sql = $this->buildReportSql($this->getSqlSelect(), $this->getSqlFrom(), $this->getSqlWhere(), $this->getSqlGroupBy(), $this->getSqlHaving(), "", $filter, "");
        $conn = $this->getConnection();
        $dbtype = GetConnectionType($this->Dbid);
        if ($row = $conn->fetchAssociative($sql)) {
            $val = $row[$fldName];
            if (!EmptyValue($val)) {
                $fld = $this->Fields[$fldName];

                // Binary data
                if ($fld->DataType == DATATYPE_BLOB) {
                    if ($dbtype != "MYSQL") {
                        if (is_resource($val) && get_resource_type($val) == "stream") { // Byte array
                            $val = stream_get_contents($val);
                        }
                    }
                    if ($resize) {
                        ResizeBinary($val, $width, $height, $plugins);
                    }

                    // Write file type
                    if ($fileTypeFld != "" && !EmptyValue($row[$fileTypeFld])) {
                        AddHeader("Content-type", $row[$fileTypeFld]);
                    } else {
                        AddHeader("Content-type", ContentType($val));
                    }

                    // Write file name
                    $downloadPdf = !Config("EMBED_PDF") && Config("DOWNLOAD_PDF_FILE");
                    if ($fileNameFld != "" && !EmptyValue($row[$fileNameFld])) {
                        $fileName = $row[$fileNameFld];
                        $ext = strtolower($pathinfo["extension"] ?? "");
                        $isPdf = SameText($ext, "pdf");
                        if ($downloadPdf || !$isPdf) { // Skip header if not download PDF
                            AddHeader("Content-Disposition", "attachment; filename=\"" . $fileName . "\"");
                        }
                    } else {
                        $ext = ContentExtension($val);
                        $isPdf = SameText($ext, ".pdf");
                        if ($isPdf && $downloadPdf) { // Add header if download PDF
                            AddHeader("Content-Disposition", "attachment" . ($DownloadFileName ? "; filename=\"" . $DownloadFileName . "\"" : ""));
                        }
                    }

                    // Write file data
                    if (
                        StartsString("PK", $val) &&
                        ContainsString($val, "[Content_Types].xml") &&
                        ContainsString($val, "_rels") &&
                        ContainsString($val, "docProps")
                    ) { // Fix Office 2007 documents
                        if (!EndsString("\0\0\0", $val)) { // Not ends with 3 or 4 \0
                            $val .= "\0\0\0\0";
                        }
                    }

                    // Clear any debug message
                    if (ob_get_length()) {
                        ob_end_clean();
                    }

                    // Write binary data
                    Write($val);

                // Upload to folder
                } else {
                    if ($fld->UploadMultiple) {
                        $files = explode(Config("MULTIPLE_UPLOAD_SEPARATOR"), $val);
                    } else {
                        $files = [$val];
                    }
                    $data = [];
                    $ar = [];
                    if ($fld->hasMethod("getUploadPath")) { // Check field level upload path
                        $fld->UploadPath = $fld->getUploadPath();
                    }
                    foreach ($files as $file) {
                        if (!EmptyValue($file)) {
                            if (Config("ENCRYPT_FILE_PATH")) {
                                $ar[$file] = FullUrl(GetApiUrl(Config("API_FILE_ACTION") .
                                    "/" . $this->TableVar . "/" . Encrypt($fld->physicalUploadPath() . $file)));
                            } else {
                                $ar[$file] = FullUrl($fld->hrefPath() . $file);
                            }
                        }
                    }
                    $data[$fld->Param] = $ar;
                    WriteJson($data);
                }
            }
            return true;
        }
        return false;
    }

    // Table level events

    // Table Load event
    public function tableLoad()
    {
        // Enter your code here
    }

    // Email Sending event
    public function emailSending($email, &$args)
    {
        //var_dump($email, $args); exit();
        return true;
    }

    // Lookup Selecting event
    public function lookupSelecting($fld, &$filter)
    {
        //var_dump($fld->Name, $fld->Lookup, $filter); // Uncomment to view the filter
        // Enter your code here
    }

    // Row Rendering event
    public function rowRendering()
    {
        // Enter your code here
    }

    // Row Rendered event
    public function rowRendered()
    {
        // To view properties of field class, use:
        //var_dump($this-><FieldName>);
    }

    // User ID Filtering event
    public function userIdFiltering(&$filter)
    {
        // Enter your code here
    }
}
