]> git.agnieray.net Git - galette.git/commitdiff
Rework PDF models patterns and replacements
authorJohan Cwiklinski <johan@x-tnd.be>
Sat, 21 Nov 2020 10:43:28 +0000 (11:43 +0100)
committerJohan Cwiklinski <johan@x-tnd.be>
Sat, 5 Dec 2020 08:44:52 +0000 (09:44 +0100)
refs #1393

Factorize patterns, add tests
Add contribution amount in letters; closes #1520
Add support for contributions and transactions dynamic fields
Set a width on date fields to fix a display issue

14 files changed:
galette/lib/Galette/Controllers/PdfController.php
galette/lib/Galette/Entity/DynamicFieldsHandle.php
galette/lib/Galette/Entity/PdfAdhesionFormModel.php
galette/lib/Galette/Entity/PdfContribution.php [new file with mode: 0644]
galette/lib/Galette/Entity/PdfInvoice.php
galette/lib/Galette/Entity/PdfModel.php
galette/lib/Galette/Entity/PdfReceipt.php
galette/lib/Galette/IO/PdfAdhesionForm.php
galette/lib/Galette/IO/PdfAttendanceSheet.php
galette/lib/Galette/IO/PdfContribution.php
galette/lib/Galette/Repository/PdfModels.php
tests/Galette/Entity/tests/units/PdfModel.php [new file with mode: 0644]
tests/Galette/Repository/tests/units/PdfModels.php
tests/coverage.php

index 449ce98e57b88e9a126eac9fa54bc02c58413377..40af0130c617ef111b28e9c193de41fa42599f40 100644 (file)
@@ -539,7 +539,7 @@ class PdfController extends AbstractController
         }
 
         $tpl = null;
-        $params = [];
+        $params = ['model' => $model];
 
         //Render directly template if we called from ajax,
         //render in a full page otherwise
@@ -549,13 +549,11 @@ class PdfController extends AbstractController
             && $request->getQueryParams()['ajax'] == 'true'
         ) {
             $tpl = 'gestion_pdf_content.tpl';
-            $params['model'] = $model;
         } else {
             $tpl = 'gestion_pdf.tpl';
-            $params = [
+            $params += [
                 'page_title'        => _T("PDF models"),
-                'models'            => $models,
-                'model'             => $model
+                'models'            => $models
             ];
         }
 
index d9cf901bf732a6dad1736b78b8690f328a805a10..8021181cda30081972040baec24fca7d20f063d0 100644 (file)
@@ -79,6 +79,7 @@ class DynamicFieldsHandle
     private $errors = array();
 
     private $zdb;
+    private $login;
 
     private $insert_stmt;
     private $update_stmt;
@@ -134,8 +135,6 @@ class DynamicFieldsHandle
             $results = $this->getCurrentFields();
 
             if ($results->count() > 0) {
-                $dfields = array();
-
                 foreach ($results as $f) {
                     if (isset($this->dynamic_fields[$f->{DynamicField::PK}])) {
                         $field = $this->dynamic_fields[$f->{DynamicField::PK}];
@@ -145,7 +144,7 @@ class DynamicFieldsHandle
                         }
                         $this->current_values[$f->{DynamicField::PK}][] = array_filter(
                             (array)$f,
-                            function ($k) {
+                            static function ($k) {
                                 return $k != DynamicField::PK;
                             },
                             ARRAY_FILTER_USE_KEY
@@ -176,7 +175,7 @@ class DynamicFieldsHandle
      *
      * @return array
      */
-    public function getErrors()
+    public function getErrors(): array
     {
         return $this->errors;
     }
@@ -186,7 +185,7 @@ class DynamicFieldsHandle
      *
      * @return array
      */
-    public function getFields()
+    public function getFields(): array
     {
         return $this->dynamic_fields;
     }
@@ -198,7 +197,7 @@ class DynamicFieldsHandle
      *
      * @return array
      */
-    public function getValues($field)
+    public function getValues($field): array
     {
         if (!isset($this->current_values[$field])) {
             $this->current_values[$field][] = [
@@ -319,8 +318,10 @@ class DynamicFieldsHandle
             );
             return false;
         } finally {
-            unset($this->update_stmt);
-            unset($this->insert_stmt);
+            unset(
+                $this->update_stmt,
+                $this->insert_stmt
+            );
         }
     }
 
index 5685687b03f8136ec2a5bca2478c60f19ae8c4f2..a8b455a04232e0666e17e33b039760ad321b88ea 100644 (file)
@@ -63,5 +63,6 @@ class PdfAdhesionFormModel extends PdfModel
     public function __construct($zdb, $preferences, $args = null)
     {
         parent::__construct($zdb, $preferences, self::ADHESION_FORM_MODEL, $args);
+        $this->setPatterns($this->getMemberPatterns());
     }
 }
diff --git a/galette/lib/Galette/Entity/PdfContribution.php b/galette/lib/Galette/Entity/PdfContribution.php
new file mode 100644 (file)
index 0000000..0ce73b3
--- /dev/null
@@ -0,0 +1,181 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * PDF contributions model
+ *
+ * PHP version 5
+ *
+ * Copyright © 2020 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Entity
+ * @package   Galette
+ *
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2020 The Galette Team
+ * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      http://galette.tuxfamily.org
+ * @since     2020-11-21
+ */
+
+namespace Galette\Entity;
+
+use Analog\Analog;
+use Galette\Core\Db;
+use Galette\Core\Preferences;
+use Galette\Entity\Contribution;
+use NumberFormatter;
+
+/**
+ * PDF contribution model
+ *
+ * @category  Entity
+ * @name      PdfContribution
+ * @package   Galette
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2020 The Galette Team
+ * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      http://galette.tuxfamily.org
+ * @since     2020-11-21
+ */
+
+abstract class PdfContribution extends PdfModel
+{
+    /**
+     * Main constructor
+     *
+     * @param Db          $zdb         Database instance
+     * @param Preferences $preferences Galette preferences
+     * @param int         $type        Model type
+     * @param mixed       $args        Arguments
+     */
+    public function __construct(Db $zdb, Preferences $preferences, int $type, $args = null)
+    {
+        parent::__construct($zdb, $preferences, $type, $args);
+
+        $this->setPatterns(
+            $this->getMemberPatterns() + $this->getContributionPatterns()
+        );
+    }
+
+    /**
+     * Get patterns for a contribution
+     *
+     * @return array
+     */
+    protected function getContributionPatterns(): array
+    {
+        $dynamic_patterns = $this->getDynamicPatterns('contrib');
+
+        $c_patterns = [
+            'contrib_label'     => [
+                'title'     => _T('Contribution label'),
+                'pattern'   => '/{CONTRIB_LABEL}/',
+            ],
+            'contrib_amount'    => [
+                'title'     => _T('Contribution amount'),
+                'pattern'   => '/{CONTRIB_AMOUNT}/',
+            ],
+            'contrib_amount_letters' => [
+                'title'     => _T('Contribution amount (in letters)'),
+                'pattern'   => '/{CONTRIB_AMOUNT_LETTERS}/',
+            ],
+            'contrib_date'      => [
+                'title'     => _T('Contribution full date'),
+                'pattern'   => '/{CONTRIB_DATE}/',
+            ],
+            'contrib_year'      => [
+                'title'     => _T('Contribution year'),
+                'pattern'   => '/{CONTRIB_YEAR}/',
+            ],
+            'contrib_comment'   => [
+                'title'     => _T('Contribution comment'),
+                'pattern'   => '/{CONTRIB_COMMENT}/',
+            ],
+            'contrib_bdate'     => [
+                'title'     => _T('Contribution begin date'),
+                'pattern'   => '/{CONTRIB_BEGIN_DATE}/',
+            ],
+            'contrib_edate'     => [
+                'title'     => _T('Contribution end date'),
+                'pattern'   => '/{CONTRIB_END_DATE}/',
+            ],
+            'contrib_id'        => [
+                'title'     => _T('Contribution id'),
+                'pattern'   => '/{CONTRIB_ID}/',
+            ],
+            'contrib_payment'   => [
+                'title'     => _T('Contribution payment type'),
+                'pattern'   => '/{CONTRIB_PAYMENT_TYPE}/'
+            ]
+        ];
+
+        foreach ($c_patterns as $key => $pattern) {
+            $nkey = '_' . $key;
+            $pattern['pattern'] = str_replace(
+                'CONTRIB_',
+                'CONTRIBUTION_',
+                $pattern['pattern']
+            );
+            $c_patterns[$nkey] = $pattern;
+        }
+
+        return $c_patterns + $dynamic_patterns;
+    }
+
+    /**
+     * Set contribution and proceed related replacements
+     *
+     * @param Contribution $contrib Contribution
+     *
+     * @return PdfModel
+     */
+    public function setContribution(Contribution $contrib): PdfContribution
+    {
+        global $login, $i18n;
+
+        $formatter = new NumberFormatter($i18n->getID(), NumberFormatter::SPELLOUT);
+
+        $c_replacements = [
+            'contrib_label'     => $contrib->type->libelle,
+            'contrib_amount'    => $contrib->amount,
+            'contrib_amount_letters' => $formatter->format($contrib->amount),
+            'contrib_date'      => $contrib->date,
+            'contrib_year'      => $contrib->raw_date->format('Y'),
+            'contrib_comment'   => $contrib->info,
+            'contrib_bdate'     => $contrib->begin_date,
+            'contrib_edate'     => $contrib->end_date,
+            'contrib_id'        => $contrib->id,
+            'contrib_payment'   => $contrib->spayment_type,
+        ];
+
+        foreach ($c_replacements as $key => $replacement) {
+            $nkey = '_' . $key;
+            $c_replacements[$nkey] = $replacement;
+        }
+        $this->setReplacements($c_replacements);
+
+        /** the list of all dynamic fields */
+        $fields = new \Galette\Repository\DynamicFieldsSet($this->zdb, $login);
+        $dynamic_fields = $fields->getList('contrib');
+        $this->setDynamicFields('contrib', $dynamic_fields, $contrib);
+
+        return $this;
+    }
+}
index e1189945e05c1e58307d6bd7f263db3e399df08f..e1c96b4035129f3856ec8c15fa11e3c1a83101de 100644 (file)
@@ -51,7 +51,7 @@ use Analog\Analog;
  * @since     Available since 0.7.5dev - 2013-02-25
  */
 
-class PdfInvoice extends PdfModel
+class PdfInvoice extends PdfContribution
 {
     /**
      * Main constructor
index e1259e16473f17461faebae22bfe3b305239f9f7..bf6895992e4e6a057f79be7a98a50da6cfb8e36c 100644 (file)
@@ -39,6 +39,8 @@ namespace Galette\Entity;
 use Throwable;
 use Galette\Core;
 use Galette\Core\Db;
+use Galette\Core\Preferences;
+use Galette\DynamicFields\DynamicField;
 use Galette\Repository\PdfModels;
 use Analog\Analog;
 use Laminas\Db\Sql\Expression;
@@ -66,7 +68,7 @@ abstract class PdfModel
     public const RECEIPT_MODEL = 3;
     public const ADHESION_FORM_MODEL = 4;
 
-    private $zdb;
+    protected $zdb;
 
     private $id;
     private $name;
@@ -79,8 +81,9 @@ abstract class PdfModel
     private $styles;
     private $parent;
 
-    private $patterns;
-    private $replaces;
+    private $patterns = [];
+    private $replaces = [];
+    private $dynamic_patterns = [];
 
     /**
      * Main constructor
@@ -90,17 +93,10 @@ abstract class PdfModel
      * @param int         $type        Model type
      * @param mixed       $args        Arguments
      */
-    public function __construct(Db $zdb, $preferences, $type, $args = null)
+    public function __construct(Db $zdb, Preferences $preferences, $type, $args = null)
     {
         global $container;
         $router = $container->get('router');
-
-        if (!$zdb) {
-            throw new \RuntimeException(
-                get_class($this) . ' Database instance required!'
-            );
-        }
-
         $this->zdb = $zdb;
         $this->type = $type;
 
@@ -108,17 +104,11 @@ abstract class PdfModel
             $this->load($args, $preferences);
         } elseif ($args !== null && is_object($args)) {
             $this->loadFromRs($args, $preferences);
+        } else {
+            $this->load($type, $preferences);
         }
 
-        $this->patterns = array(
-            'asso_name'          => '/{ASSO_NAME}/',
-            'asso_slogan'        => '/{ASSO_SLOGAN}/',
-            'asso_address'       => '/{ASSO_ADDRESS}/',
-            'asso_address_multi' => '/{ASSO_ADDRESS_MULTI}/',
-            'asso_website'       => '/{ASSO_WEBSITE}/',
-            'asso_logo'          => '/{ASSO_LOGO}/',
-            'date_now'           => '/{DATE_NOW}/'
-        );
+        $this->setPatterns($this->getMainPatterns());
 
         $address = $preferences->getPostalAddress();
         $address_multi = preg_replace("/\n/", "<br>", $address);
@@ -158,6 +148,8 @@ abstract class PdfModel
      */
     protected function load($id, $preferences, $init = true)
     {
+        global $login;
+
         try {
             $select = $this->zdb->select(self::TABLE);
             $select->limit(1)
@@ -168,7 +160,7 @@ abstract class PdfModel
             $count = $results->count();
             if ($count === 0) {
                 if ($init === true) {
-                    $models = new PdfModels($this->zdb, $preferences, $this->login);
+                    $models = new PdfModels($this->zdb, $preferences, $login);
                     $models->installInit();
                     $this->load($id, $preferences, false);
                 } else {
@@ -183,6 +175,7 @@ abstract class PdfModel
                 $e->getMessage(),
                 Analog::ERROR
             );
+            throw $e;
         }
     }
 
@@ -359,13 +352,30 @@ abstract class PdfModel
     }
 
     /**
-     * Extract patterns
+     * Get dynamic patterns, extract them if needed
+     *
+     * @param string $form_name Dynamic form name
      *
      * @return array
      */
-    public function extractDynamicPatterns()
+    public function getDynamicPatterns($form_name): array
     {
+        if (!isset($this->dynamic_patterns[$form_name])) {
+            $this->dynamic_patterns[$form_name] = $this->extractDynamicPatterns($form_name);
+        }
+        return $this->dynamic_patterns[$form_name];
+    }
 
+    /**
+     * Extract patterns
+     *
+     * @param string $form_name Dynamic form name
+     *
+     * @return array
+     */
+    public function extractDynamicPatterns($form_name)
+    {
+        $form_name = strtoupper($form_name);
         $patterns = array();
         $parts    = array('header', 'footer', 'title', 'subtitle', 'body');
         foreach ($parts as $part) {
@@ -373,13 +383,18 @@ abstract class PdfModel
 
             $matches = array();
             preg_match_all(
-                '/{((LABEL|INPUT)?_DYNFIELD_[0-9]+_ADH)}/',
+                '/{((LABEL|INPUT)?_DYNFIELD_[0-9]+_' . $form_name . ')}/',
                 $content,
                 $matches
             );
-            $patterns = array_merge($patterns, $matches[1]);
 
-            Analog::log("dynamic patterns found in $part: " . join(",", $matches[1]), Analog::DEBUG);
+            foreach ($matches[1] as $pattern) {
+                $patterns[$pattern] = [
+                    'pattern'   => sprintf('/{%s}/', $pattern)
+                ];
+            }
+
+            Analog::log("dynamic patterns found for $form_name in $part: " . join(",", $matches[1]), Analog::DEBUG);
         }
 
         return $patterns;
@@ -392,12 +407,23 @@ abstract class PdfModel
      *
      * @return void
      */
-    public function setPatterns($patterns)
+    protected function setPatterns($patterns): PdfModel
     {
+        $toset = [];
+        foreach ($patterns as $key => $info) {
+            if (is_array($info)) {
+                $toset[$key] = $info['pattern'];
+            } else {
+                $toset[$key] = $info;
+            }
+        }
+
         $this->patterns = array_merge(
             $this->patterns,
-            $patterns
+            $toset
         );
+
+        return $this;
     }
 
     /**
@@ -436,6 +462,8 @@ abstract class PdfModel
             case 'subtitle':
             case 'type':
             case 'styles':
+            case 'patterns':
+            case 'replaces':
                 return $this->$name;
                 break;
             case 'hstyles':
@@ -463,16 +491,16 @@ abstract class PdfModel
                 //get header and footer from parent if not defined in current model
                 if (
                     $this->id > self::MAIN_MODEL
-                    && trim($prop_value) === ''
                     && $this->parent !== null
                     && ($pname === 'footer'
                     || $pname === 'header')
+                    && trim($prop_value) === ''
                 ) {
                     $prop_value = $this->parent->$pname;
                 }
 
                 //handle translations
-                $callback = function ($matches) {
+                $callback = static function ($matches) {
                     return _T($matches[1]);
                 };
                 $value = preg_replace_callback(
@@ -567,12 +595,12 @@ abstract class PdfModel
             case 'header':
             case 'footer':
             case 'body':
-                if ($value == null || trim($value) == '') {
-                    if (get_class($this) === 'PdfMain' && $name !== 'body') {
+                if ($value === null || trim($value) === '') {
+                    if ($name !== 'body' && get_class($this) === 'PdfMain') {
                         throw new \UnexpectedValueException(
                             _T("header and footer should not be empty!")
                         );
-                    } elseif (get_class($this) !== 'PdfMain' && $name === 'body') {
+                    } elseif ($name === 'body' && get_class($this) !== 'PdfMain') {
                         throw new \UnexpectedValueException(
                             _T("body should not be empty!")
                         );
@@ -608,4 +636,309 @@ abstract class PdfModel
                 break;
         }
     }
+
+    /**
+     * Get main patterns
+     *
+     * @return array
+     */
+    protected function getMainPatterns(): array
+    {
+        return [
+            'asso_name'             => [
+                'title' => _T('Your organisation name'),
+                'pattern'   => '/{ASSO_NAME}/'
+            ],
+            'asso_slogan'           => [
+                'title'     => _T('Your organisation slogan'),
+                'pattern'   => '/{ASSO_SLOGAN}/'
+            ],
+            'asso_address'          => [
+                'title'     => _T('Your organisation address'),
+                'pattern'   => '/{ASSO_ADDRESS}/',
+            ],
+            'asso_address_multi'    => [
+                'title'     => sprintf('%s (%s)', _T('Your organisation address'), _T('with break lines')),
+                'pattern'   => '/{ASSO_ADDRESS_MULTI}/',
+            ],
+            'asso_website'          => [
+                'title'     => _T('Your organisation website'),
+                'pattern'   => '/{ASSO_WEBSITE}/',
+            ],
+            'asso_logo'             => [
+                'title'     => _T('Your organisation logo'),
+                'pattern'          => '/{ASSO_LOGO}/',
+            ],
+            'date_now'              => [
+                'title'     => _T('Current date (Y-m-d)'),
+                'pattern'   => '/{DATE_NOW}/'
+            ]
+        ];
+    }
+
+    /**
+     * Get patterns for a member
+     *
+     * @return array
+     */
+    protected function getMemberPatterns(): array
+    {
+        $dynamic_patterns = $this->getDynamicPatterns('adh');
+        return [
+            'adh_title'         => [
+                'title'     => '',
+                'pattern'   => '/{TITLE_ADH}/',
+            ],
+            'adh_id'            =>  [
+                'title'     => _T("Member's ID"),
+                'pattern'   => '/{ID_ADH}/',
+            ],
+            'adh_name'          =>  [
+                'title'     => _T("Member's name"),
+                'pattern'    => '/{NAME_ADH}/',
+            ],
+            'adh_last_name'     =>  [
+                'title'     => '',
+                'pattern'   => '/{LAST_NAME_ADH}/',
+            ],
+            'adh_first_name'    =>  [
+                'title'     => '',
+                'pattern'   => '/{FIRST_NAME_ADH}/',
+            ],
+            'adh_nickname'      =>  [
+                'title'     => '',
+                'pattern'   => '/{NICKNAME_ADH}/',
+            ],
+            'adh_gender'        =>  [
+                'title'     => '',
+                'pattern'   => '/{GENDER_ADH}/',
+            ],
+            'adh_birth_date'    =>  [
+                'title'     => '',
+                'pattern'   => '/{ADH_BIRTH_DATE}/',
+            ],
+            'adh_birth_place'   =>  [
+                'title'     => '',
+                'pattern'   => '/{ADH_BIRTH_PLACE}/',
+            ],
+            'adh_profession'    =>  [
+                'title'     => '',
+                'pattern'   => '/{PROFESSION_ADH}/',
+            ],
+            'adh_company'       => [
+                'title'     => _T("Company name"),
+                'pattern'   => '/{COMPANY_ADH}/',
+            ],
+            'adh_address'       =>  [
+                'title'     => _T("Member's address"),
+                'pattern'   => '/{ADDRESS_ADH}/',
+            ],
+            'adh_zip'           =>  [
+                'title'     => _T("Member's zipcode"),
+                'pattern'   => '/{ZIP_ADH}/',
+            ],
+            'adh_town'          =>  [
+                'title'     => _T("Member's town"),
+                'pattern'   => '/{TOWN_ADH}/',
+            ],
+            'adh_country'       =>  [
+                'title'     => '',
+                'pattern'   => '/{COUNTRY_ADH}/',
+            ],
+            'adh_phone'         =>  [
+                'title'     => '',
+                'pattern'   => '/{PHONE_ADH}/',
+            ],
+            'adh_mobile'        =>  [
+                'title'     => '',
+                'pattern'   => '/{MOBILE_ADH}/',
+            ],
+            'adh_email'         =>  [
+                'title'     => '',
+                'pattern'   => '/{EMAIL_ADH}/',
+            ],
+            'adh_login'         =>  [
+                'title'     => '',
+                'pattern'   => '/{LOGIN_ADH}/',
+            ],
+            'adh_main_group'    =>  [
+                'title'     => _T("Member's main group"),
+                'pattern'   => '/{GROUP_ADH}/',
+            ],
+            'adh_groups'        =>  [
+                'title'     => _T("Member's groups (as list)"),
+                'pattern'   => '/{GROUPS_ADH}/'
+            ],
+        ] + $dynamic_patterns;
+    }
+
+    /**
+     * Set member and proceed related replacements
+     *
+     * @param Adherent $member Member
+     *
+     * @return PdfModel
+     */
+    public function setMember(Adherent $member): PdfModel
+    {
+        global $login;
+
+        $address = $member->address;
+        if ($member->address_continuation != '') {
+            $address .= '<br/>' . $member->address_continuation;
+        }
+
+        if ($member->isMan()) {
+            $gender = _T("Man");
+        } elseif ($member->isWoman()) {
+            $gender = _T("Woman");
+        } else {
+            $gender = _T("Unspecified");
+        }
+
+        $member_groups = $member->groups;
+        $main_group = _T("None");
+        $group_list = _T("None");
+        if (is_array($member_groups) && count($member_groups) > 0) {
+            $main_group = $member_groups[0]->getName();
+            $group_list = '<ul>';
+            foreach ($member_groups as $group) {
+                $group_list .= '<li>' . $group->getName() . '</li>';
+            }
+            $group_list .= '</ul>';
+        }
+
+        $this->setReplacements(
+            array(
+                'adh_title'         => $member->stitle,
+                'adh_id'            => $member->id,
+                'adh_name'          => $member->sfullname,
+                'adh_last_name'     => $member->name,
+                'adh_first_name'    => $member->surname,
+                'adh_nickname'      => $member->nickname,
+                'adh_gender'        => $gender,
+                'adh_birth_date'    => $member->birthdate,
+                'adh_birth_place'   => $member->birth_place,
+                'adh_profession'    => $member->job,
+                'adh_company'       => $member->company_name,
+                'adh_address'       => $address,
+                'adh_zip'           => $member->zipcode,
+                'adh_town'          => $member->town,
+                'adh_country'       => $member->country,
+                'adh_phone'         => $member->phone,
+                'adh_mobile'        => $member->gsm,
+                'adh_email'         => $member->email,
+                'adh_login'         => $member->login,
+                'adh_main_group'    => $main_group,
+                'adh_groups'        => $group_list
+            )
+        );
+
+        /** the list of all dynamic fields */
+        $fields = new \Galette\Repository\DynamicFieldsSet($this->zdb, $login);
+        $dynamic_fields = $fields->getList('adh');
+        $this->setDynamicFields('adh', $dynamic_fields, $member);
+
+        return $this;
+    }
+
+    /**
+     * Set dynamic fields and proceed related replacements
+     *
+     * @param string $form_name      Form name
+     * @param array  $dynamic_fields Dynamic fields
+     * @param mixed  $object         Related object (Adherent, Contribution, ...)
+     *
+     * @return PdfModel
+     */
+    public function setDynamicFields($form_name, $dynamic_fields, $object): PdfModel
+    {
+        $uform_name = strtoupper($form_name);
+        $dynamic_patterns = $this->getDynamicPatterns($form_name);
+        foreach ($dynamic_patterns as $dynamic_pattern) {
+            $pattern = trim($dynamic_pattern['pattern'], '/');
+            $key   = strtolower(rtrim(ltrim($pattern, '{'), '}'));
+            $value = '';
+            if (preg_match("/^{DYNFIELD_([0-9]+)_$uform_name}$/", $pattern, $match)) {
+                /** dynamic field first value */
+                $field_id = $match[1];
+                if ($object !== null) {
+                    $values = $object->getDynamicFields()->getValues($field_id);
+                    $value  = $values[1];
+                }
+            }
+            if (preg_match("/^{LABEL_DYNFIELD_([0-9]+)_$uform_name}$/", $pattern, $match)) {
+                /** dynamic field label */
+                $field_id = $match[1];
+                $value    = $dynamic_fields[$field_id]->getName();
+            }
+            if (preg_match("/^{INPUT_DYNFIELD_([0-9]+)_$uform_name}$/", $pattern, $match)) {
+                /** dynamic field input form element */
+                $field_id    = $match[1];
+                $field_name  = $dynamic_fields[$field_id]->getName();
+                $field_type  = $dynamic_fields[$field_id]->getType();
+                $field_value = ['field_val' => ''];
+                if ($object !== null) {
+                    $field_values = $object->getDynamicFields()->getValues($field_id);
+                    $field_value  = $field_values[0];
+                }
+                switch ($field_type) {
+                    case DynamicField::TEXT:
+                        $value .= '<textarea' .
+                            ' id="' . $field_name . '"' .
+                            ' name="' . $field_name . '"' .
+                            ' value="' . $field_value['field_val'] . '"' .
+                            '/>';
+                        break;
+                    case DynamicField::LINE:
+                        $value .= '<input type="text"' .
+                            ' id="' . $field_name . '"' .
+                            ' name="' . $field_name . '"' .
+                            ' value="' . $field_value['field_val'] . '"' .
+                            ' size="20" maxlength="30"/>';
+                        break;
+                    case DynamicField::CHOICE:
+                        $choice_values = $dynamic_fields[$field_id]->getValues();
+                        foreach ($choice_values as $choice_idx => $choice_value) {
+                            $value .= '<input type="radio"' .
+                                ' id="' . $field_name . '"' .
+                                ' name="' . $field_name . '"' .
+                                ' value="' . $choice_value . '"';
+                            if ($choice_idx == $field_values[0]['field_val']) {
+                                $value .= ' checked="checked"';
+                            }
+                            $value .= '/>';
+                            $value .= $choice_value;
+                            $value .= '&nbsp;';
+                        }
+                        break;
+                    case DynamicField::DATE:
+                        $value .= '<input type="text" name="' .
+                            $field_name . '" value="' .
+                            $field_value['field_val'] .
+                            '" size="10" />';
+                        break;
+                    case DynamicField::BOOLEAN:
+                        $value .= '<input type="checkbox"' .
+                            ' name="' . $field_name . '"' .
+                            ' value="1"';
+                        if ($field_value['field_val'] == 1) {
+                            $value .= ' checked="checked"';
+                        }
+                        $value .= '/>';
+                        break;
+                    case DynamicField::FILE:
+                        $value .= '<input type="text" name="' .
+                            $field_name . '" value="' .
+                            $field_value['field_val'] . '" />';
+                        break;
+                }
+            }
+
+            $this->setReplacements(array($key => $value));
+            Analog::log("adding dynamic replacement $key => $value", Analog::DEBUG);
+        }
+
+        return $this;
+    }
 }
index b518bc15b897d753650a47ff5c9ecea20c5a2002..0b653eead5c537002142ae1fb1c077fb7a71b8a7 100644 (file)
@@ -51,7 +51,7 @@ use Analog\Analog;
  * @since     Available since 0.7.5dev - 2013-02-25
  */
 
-class PdfReceipt extends PdfModel
+class PdfReceipt extends PdfContribution
 {
     /**
      * Main constructor
index 0a7cde15dee0d537a5917f9854ea840b4633607e..7554395778ec3d8ffd46668b836b149a542da52d 100644 (file)
@@ -38,11 +38,9 @@ namespace Galette\IO;
 
 use Galette\Core\Db;
 use Galette\Core\Preferences;
-use Galette\DynamicFields\DynamicField;
 use Galette\Entity\Adherent;
 use Galette\Entity\PdfModel;
 use Galette\Entity\PdfAdhesionFormModel;
-use Galette\Entity\DynamicFieldsHandle;
 use Galette\IO\Pdf;
 use Analog\Analog;
 
@@ -103,182 +101,8 @@ class PdfAdhesionForm extends Pdf
      */
     protected function getModel()
     {
-        global $login;
-
-        $model = new PdfAdhesionFormModel($this->zdb, $this->prefs, PdfModel::ADHESION_FORM_MODEL);
-        $dynamic_patterns = $model->extractDynamicPatterns();
-
-        $model->setPatterns(
-            array(
-                'adh_title'         => '/{TITLE_ADH}/',
-                'adh_id'            => '/{ID_ADH}/',
-                'adh_name'          => '/{NAME_ADH}/',
-                'adh_last_name'     => '/{LAST_NAME_ADH}/',
-                'adh_first_name'    => '/{FIRST_NAME_ADH}/',
-                'adh_nick_name'     => '/{NICKNAME_ADH}/',
-                'adh_gender'        => '/{GENDER_ADH}/',
-                'adh_birth_date'    => '/{ADH_BIRTH_DATE}/',
-                'adh_birth_place'   => '/{ADH_BIRTH_PLACE}/',
-                'adh_profession'    => '/{PROFESSION_ADH}/',
-                'adh_company'       => '/{COMPANY_ADH}/',
-                'adh_address'       => '/{ADDRESS_ADH}/',
-                'adh_zip'           => '/{ZIP_ADH}/',
-                'adh_town'          => '/{TOWN_ADH}/',
-                'adh_country'       => '/{COUNTRY_ADH}/',
-                'adh_phone'         => '/{PHONE_ADH}/',
-                'adh_mobile'        => '/{MOBILE_ADH}/',
-                'adh_email'         => '/{EMAIL_ADH}/',
-                'adh_login'         => '/{LOGIN_ADH}/',
-                'adh_main_group'    => '/{GROUP_ADH}/',
-                'adh_groups'        => '/{GROUPS_ADH}/'
-            )
-        );
-
-        foreach ($dynamic_patterns as $pattern) {
-            $key = strtolower($pattern);
-            $model->setPatterns(array($key => "/\{$pattern\}/"));
-            Analog::log("adding dynamic pattern $key => {" . $pattern . "}", Analog::DEBUG);
-        }
-
-        if ($this->adh !== null) {
-            $address = $this->adh->address;
-            if ($this->adh->address_continuation != '') {
-                $address .= '<br/>' . $this->adh->address_continuation;
-            }
-
-            if ($this->adh->isMan()) {
-                $gender = _T("Man");
-            } elseif ($this->adh->isWoman()) {
-                $gender = _T("Woman");
-            } else {
-                $gender = _T("Unspecified");
-            }
-
-            $member_groups = $this->adh->groups;
-            $main_group = _T("None");
-            $group_list = _T("None");
-            if (is_array($member_groups) && count($member_groups) > 0) {
-                $main_group = $member_groups[0]->getName();
-                $group_list = '<ul>';
-                foreach ($member_groups as $group) {
-                    $group_list .= '<li>' . $group->getName() . '</li>';
-                }
-                $group_list .= '</ul>';
-            }
-
-            $model->setReplacements(
-                array(
-                    'adh_title'         => $this->adh->stitle,
-                    'adh_id'            => $this->adh->id,
-                    'adh_name'          => $this->adh->sfullname,
-                    'adh_last_name'     => $this->adh->name,
-                    'adh_first_name'    => $this->adh->surname,
-                    'adh_nickname'      => $this->adh->nickname,
-                    'adh_gender'        => $gender,
-                    'adh_birth_date'    => $this->adh->birthdate,
-                    'adh_birth_place'   => $this->adh->birth_place,
-                    'adh_profession'    => $this->adh->job,
-                    'adh_company'       => $this->adh->company_name,
-                    'adh_address'       => $address,
-                    'adh_zip'           => $this->adh->zipcode,
-                    'adh_town'          => $this->adh->town,
-                    'adh_country'       => $this->adh->country,
-                    'adh_phone'         => $this->adh->phone,
-                    'adh_mobile'        => $this->adh->gsm,
-                    'adh_email'         => $this->adh->email,
-                    'adh_login'         => $this->adh->login,
-                    'adh_main_group'    => $main_group,
-                    'adh_groups'        => $group_list
-                )
-            );
-        }
-
-        /** the list of all dynamic fields */
-        $fields =
-            new \Galette\Repository\DynamicFieldsSet($this->zdb, $login);
-        $dynamic_fields = $fields->getList('adh');
-
-        foreach ($dynamic_patterns as $pattern) {
-            $key   = strtolower($pattern);
-            $value = '';
-            if (preg_match('/^DYNFIELD_([0-9]+)_ADH$/', $pattern, $match)) {
-                /** dynamic field first value */
-                $field_id = $match[1];
-                if ($this->adh !== null) {
-                    $values = $this->adh->getDynamicFields()->getValues($field_id);
-                    $value  = $values[1];
-                }
-            }
-            if (preg_match('/^LABEL_DYNFIELD_([0-9]+)_ADH$/', $pattern, $match)) {
-                /** dynamic field label */
-                $field_id = $match[1];
-                $value    = $dynamic_fields[$field_id]->getName();
-            }
-            if (preg_match('/^INPUT_DYNFIELD_([0-9]+)_ADH$/', $pattern, $match)) {
-                /** dynamic field input form element */
-                $field_id    = $match[1];
-                $field_name  = $dynamic_fields[$field_id]->getName();
-                $field_type  = $dynamic_fields[$field_id]->getType();
-                $field_value = ['field_val' => ''];
-                if ($this->adh !== null) {
-                    $field_values = $this->adh->getDynamicFields()->getValues($field_id);
-                    $field_value  = $field_values[0];
-                }
-                switch ($field_type) {
-                    case DynamicField::TEXT:
-                        $value .= '<textarea' .
-                            ' id="' . $field_name . '"' .
-                            ' name="' . $field_name . '"' .
-                            ' value="' . $field_value['field_val'] . '"' .
-                            '/>';
-                        break;
-                    case DynamicField::LINE:
-                        $value .= '<input type="text"' .
-                            ' id="' . $field_name . '"' .
-                            ' name="' . $field_name . '"' .
-                            ' value="' . $field_value['field_val'] . '"' .
-                            ' size="20" maxlength="30"/>';
-                        break;
-                    case DynamicField::CHOICE:
-                        $choice_values = $dynamic_fields[$field_id]->getValues();
-                        foreach ($choice_values as $choice_idx => $choice_value) {
-                            $value .= '<input type="radio"' .
-                                ' id="' . $field_name . '"' .
-                                ' name="' . $field_name . '"' .
-                                ' value="' . $choice_value . '"';
-                            if ($choice_idx == $field_values[0]['field_val']) {
-                                $value .= ' checked="checked"';
-                            }
-                            $value .= '/>';
-                            $value .= $choice_value;
-                            $value .= '&nbsp;';
-                        }
-                        break;
-                    case DynamicField::DATE:
-                        $value .= '<input type="text" name="' .
-                            $field_name . '" value="' .
-                            $field_value . '" />';
-                        break;
-                    case DynamicField::BOOLEAN:
-                        $value .= '<input type="checkbox"' .
-                            ' name="' . $field_name . '"' .
-                            ' value="1"';
-                        if ($field_value['field_val'] == 1) {
-                            $value .= ' checked="checked"';
-                        }
-                        $value .= '/>';
-                        break;
-                    case DynamicField::FILE:
-                        $value .= '<input type="text" name="' .
-                            $field_name . '" value="' .
-                            $field_value['field_val'] . '" />';
-                        break;
-                }
-            }
-
-            $model->setReplacements(array($key => $value));
-            Analog::log("adding dynamic replacement $key => $value", Analog::DEBUG);
-        }
+        $model = new PdfAdhesionFormModel($this->zdb, $this->prefs);
+        $model->setMember($this->adh);
 
         return $model;
     }
index 80ca1afa3f33f33ffbd73dea0e41ed77ec175fdc..b300f76c1c8c18673751cba73f0aa5d1531fc950 100644 (file)
@@ -103,7 +103,7 @@ class PdfAttendanceSheet extends Pdf
     {
         $this->filename = __('attendance_sheet') . '.pdf';
         $class = PdfModel::getTypeClass(__CLASS__);
-        $model = new $class($zdb, $prefs, PdfModel::MAIN_MODEL);
+        $model = new $class($zdb, $prefs);
 
         // Set document and model information
         $this->doc_title = $data['doc_title'];
index e54a273289c9042156d30fc71021deccbf3b4a52..acdc38ffb538c503c898dc6b7804f8a248a6773b 100644 (file)
@@ -74,70 +74,12 @@ class PdfContribution extends Pdf
         $this->contrib = $contrib;
 
         $class = PdfModel::getTypeClass($this->contrib->model);
-        $this->model = new $class($zdb, $prefs, $this->contrib->model);
+        $this->model = new $class($zdb, $prefs);
 
         $member = new Adherent($zdb, $this->contrib->member);
 
-        $this->model->setPatterns(
-            array(
-                'adh_id'            => '/{ID_ADH}/',
-                'adh_name'          => '/{NAME_ADH}/',
-                'adh_address'       => '/{ADDRESS_ADH}/',
-                'adh_zip'           => '/{ZIP_ADH}/',
-                'adh_town'          => '/{TOWN_ADH}/',
-                'adh_main_group'    => '/{GROUP_ADH}/',
-                'adh_groups'        => '/{GROUPS_ADH}/',
-                'adh_company'       => '/{COMPANY_ADH}/',
-                'contrib_label'     => '/{CONTRIBUTION_LABEL}/',
-                'contrib_amount'    => '/{CONTRIBUTION_AMOUNT}/',
-                'contrib_date'      => '/{CONTRIBUTION_DATE}/',
-                'contrib_year'      => '/{CONTRIBUTION_YEAR}/',
-                'contrib_comment'   => '/{CONTRIBUTION_COMMENT}/',
-                'contrib_bdate'     => '/{CONTRIBUTION_BEGIN_DATE}/',
-                'contrib_edate'     => '/{CONTRIBUTION_END_DATE}/',
-                'contrib_id'        => '/{CONTRIBUTION_ID}/',
-                'contrib_payment'   => '/{CONTRIBUTION_PAYMENT_TYPE}/'
-            )
-        );
-
-        $address = $member->getAddress();
-        if ($member->getAddressContinuation() != '') {
-            $address .= '<br/>' . $member->getAddressContinuation();
-        }
-
-        $member_groups = $member->groups;
-        $main_group = _T("None");
-        $group_list = _T("None");
-        if (count($member_groups) > 0) {
-            $main_group = $member_groups[0]->getName();
-            $group_list = '<ul>';
-            foreach ($member_groups as $group) {
-                $group_list .= '<li>' . $group->getName() . '</li>';
-            }
-            $group_list .= '</ul>';
-        }
-
-        $this->model->setReplacements(
-            array(
-                'adh_id'            => $this->contrib->member,
-                'adh_name'          => $member->sfullname,
-                'adh_address'       => $address,
-                'adh_zip'           => $member->getZipcode(),
-                'adh_town'          => $member->getTown(),
-                'adh_main_group'    => $main_group,
-                'adh_groups'        => $group_list,
-                'adh_company'       => $member->company_name,
-                'contrib_label'     => $this->contrib->type->libelle,
-                'contrib_amount'    => $this->contrib->amount,
-                'contrib_date'      => $this->contrib->date,
-                'contrib_year'      => $this->contrib->raw_date->format('Y'),
-                'contrib_comment'   => $this->contrib->info,
-                'contrib_bdate'     => $this->contrib->begin_date,
-                'contrib_edate'     => $this->contrib->end_date,
-                'contrib_id'        => $this->contrib->id,
-                'contrib_payment'   => $this->contrib->spayment_type
-            )
-        );
+        $this->model->setMember($member);
+        $this->model->setContribution($this->contrib);
 
         $this->filename = __("contribution");
         $this->filename .= '_' . $this->contrib->id . '_';
index 11d6eb9814b2d9145486f15f58eef5f686ff256c..b7d39664c1c16a7114a41321ee3890fac74a57a5 100644 (file)
@@ -81,6 +81,7 @@ class PdfModels extends Repository
                 'Cannot list pdf models | ' . $e->getMessage(),
                 Analog::WARNING
             );
+            throw $e;
         }
     }
 
diff --git a/tests/Galette/Entity/tests/units/PdfModel.php b/tests/Galette/Entity/tests/units/PdfModel.php
new file mode 100644 (file)
index 0000000..1755afa
--- /dev/null
@@ -0,0 +1,499 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * PDF model tests
+ *
+ * PHP version 5
+ *
+ * Copyright © 2020 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Entity
+ * @package   GaletteTests
+ *
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2020 The Galette Team
+ * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @version   SVN: $Id$
+ * @link      http://galette.tuxfamily.org
+ * @since     2020-11-21
+ */
+
+namespace Galette\Entity\test\units;
+
+use atoum;
+use Galette\Entity\Adherent;
+use Galette\DynamicFields\DynamicField;
+
+/**
+ * PDF model tests
+ *
+ * @category  Entity
+ * @name      PdfModel
+ * @package   GaletteTests
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2020 The Galette Team
+ * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      http://galette.tuxfamily.org
+ * @since     2020-11-21
+ */
+class PdfModel extends atoum
+{
+    private $zdb;
+    private $preferences;
+    private $session;
+    private $login;
+    private $remove = [];
+    private $i18n;
+    private $container;
+    private $seed = 95842354;
+    private $history;
+
+    private $adh;
+    private $contrib;
+    private $members_fields;
+
+    /**
+     * Set up tests
+     *
+     * @param string $testMethod Calling method
+     *
+     * @return void
+     */
+    public function beforeTestMethod($testMethod)
+    {
+        $this->zdb = new \Galette\Core\Db();
+        $this->preferences = new \Galette\Core\Preferences($this->zdb);
+        $this->i18n = new \Galette\Core\I18n(
+            \Galette\Core\I18n::DEFAULT_LANG
+        );
+        $this->session = new \RKA\Session();
+        $this->login = new \Galette\Core\Login($this->zdb, $this->i18n, $this->session);
+
+        $models = new \Galette\Repository\PdfModels($this->zdb, $this->preferences, $this->login);
+        $res = $models->installInit(false);
+        $this->boolean($res)->isTrue();
+
+        $container = new class {
+            /**
+             * Get (only router)
+             *
+             * @param string $name Param name
+             *
+             * @return mixed
+             */
+            public function get($name)
+            {
+                $router = new class {
+                    /**
+                     * Get path ('')
+                     *
+                     * @param sttring $name Route name
+                     *
+                     * @return string
+                     */
+                    public function pathFor($name)
+                    {
+                        return '';
+                    }
+                };
+                return $router;
+            }
+        };
+        $_SERVER['HTTP_HOST'] = '';
+        $this->container = $container;
+
+        $this->history = new \Galette\Core\History($this->zdb, $this->login, $this->preferences);
+
+        include_once GALETTE_ROOT . 'includes/fields_defs/members_fields.php';
+        $this->members_fields = $members_fields;
+
+        $this->adh = new \Galette\Entity\Adherent($this->zdb);
+        $this->adh->setDependencies(
+            $this->preferences,
+            $this->members_fields,
+            $this->history
+        );
+    }
+
+    /**
+     * Tear down tests
+     *
+     * @param string $testMethod Calling method
+     *
+     * @return void
+     */
+    public function afterTestMethod($testMethod)
+    {
+        $delete = $this->zdb->delete(\Galette\Entity\Contribution::TABLE);
+        $delete->where(['info_cotis' => 'FAKER' . $this->seed]);
+        $this->zdb->execute($delete);
+        $delete = $this->zdb->delete(\Galette\Entity\Adherent::TABLE);
+        $this->zdb->execute($delete);
+        $delete = $this->zdb->delete(\Galette\Entity\DynamicFieldsHandle::TABLE);
+        $this->zdb->execute($delete);
+        $delete = $this->zdb->delete(DynamicField::TABLE);
+        $this->zdb->execute($delete);
+        //cleanup dynamic translations
+        $delete = $this->zdb->delete(\Galette\Core\L10n::TABLE);
+        $delete->where([
+            'text_orig' => [
+                'Dynamic choice field',
+                'Dynamic date field',
+                'Dynamic text field'
+            ]
+        ]);
+        $this->zdb->execute($delete);
+
+        /*if ($this->contents_table !== null) {
+            $this->zdb->drop($this->contents_table);
+        }*/
+    }
+
+    /**
+     * Test expected patterns
+     *
+     * @return void
+     */
+    public function testExpectedPatterns()
+    {
+        global $container, $zdb;
+        $zdb = $this->zdb; //globals '(
+        $container = $this->container; //globals '(
+        $model = new class ($this->zdb, $this->preferences, 1) extends \Galette\Entity\PdfModel {
+        };
+
+        $main_expected = [
+            'asso_name'          => '/{ASSO_NAME}/',
+            'asso_slogan'        => '/{ASSO_SLOGAN}/',
+            'asso_address'       => '/{ASSO_ADDRESS}/',
+            'asso_address_multi' => '/{ASSO_ADDRESS_MULTI}/',
+            'asso_website'       => '/{ASSO_WEBSITE}/',
+            'asso_logo'          => '/{ASSO_LOGO}/',
+            'date_now'           => '/{DATE_NOW}/'
+        ];
+        $this->array($model->patterns)->isIdenticalTo($main_expected);
+
+        $model = new \Galette\Entity\PdfMain($this->zdb, $this->preferences);
+        $this->array($model->patterns)->isIdenticalTo($main_expected);
+
+        $expected = $main_expected + [
+            'adh_title'         => '/{TITLE_ADH}/',
+            'adh_id'            => '/{ID_ADH}/',
+            'adh_name'          => '/{NAME_ADH}/',
+            'adh_last_name'     => '/{LAST_NAME_ADH}/',
+            'adh_first_name'    => '/{FIRST_NAME_ADH}/',
+            'adh_nickname'      => '/{NICKNAME_ADH}/',
+            'adh_gender'        => '/{GENDER_ADH}/',
+            'adh_birth_date'    => '/{ADH_BIRTH_DATE}/',
+            'adh_birth_place'   => '/{ADH_BIRTH_PLACE}/',
+            'adh_profession'    => '/{PROFESSION_ADH}/',
+            'adh_company'       => '/{COMPANY_ADH}/',
+            'adh_address'       => '/{ADDRESS_ADH}/',
+            'adh_zip'           => '/{ZIP_ADH}/',
+            'adh_town'          => '/{TOWN_ADH}/',
+            'adh_country'       => '/{COUNTRY_ADH}/',
+            'adh_phone'         => '/{PHONE_ADH}/',
+            'adh_mobile'        => '/{MOBILE_ADH}/',
+            'adh_email'         => '/{EMAIL_ADH}/',
+            'adh_login'         => '/{LOGIN_ADH}/',
+            'adh_main_group'    => '/{GROUP_ADH}/',
+            'adh_groups'        => '/{GROUPS_ADH}/'
+        ];
+        $model = new \Galette\Entity\PdfAdhesionFormModel($this->zdb, $this->preferences);
+        $this->array($model->patterns)->isIdenticalTo($expected);
+
+        $expected = $expected + [
+            'contrib_label'     => '/{CONTRIB_LABEL}/',
+            'contrib_amount'    => '/{CONTRIB_AMOUNT}/',
+            'contrib_amount_letters' => '/{CONTRIB_AMOUNT_LETTERS}/',
+            'contrib_date'      => '/{CONTRIB_DATE}/',
+            'contrib_year'      => '/{CONTRIB_YEAR}/',
+            'contrib_comment'   => '/{CONTRIB_COMMENT}/',
+            'contrib_bdate'     => '/{CONTRIB_BEGIN_DATE}/',
+            'contrib_edate'     => '/{CONTRIB_END_DATE}/',
+            'contrib_id'        => '/{CONTRIB_ID}/',
+            'contrib_payment'   => '/{CONTRIB_PAYMENT_TYPE}/',
+            '_contrib_label'     => '/{CONTRIBUTION_LABEL}/',
+            '_contrib_amount'    => '/{CONTRIBUTION_AMOUNT}/',
+            '_contrib_amount_letters' => '/{CONTRIBUTION_AMOUNT_LETTERS}/',
+            '_contrib_date'      => '/{CONTRIBUTION_DATE}/',
+            '_contrib_year'      => '/{CONTRIBUTION_YEAR}/',
+            '_contrib_comment'   => '/{CONTRIBUTION_COMMENT}/',
+            '_contrib_bdate'     => '/{CONTRIBUTION_BEGIN_DATE}/',
+            '_contrib_edate'     => '/{CONTRIBUTION_END_DATE}/',
+            '_contrib_id'        => '/{CONTRIBUTION_ID}/',
+            '_contrib_payment'   => '/{CONTRIBUTION_PAYMENT_TYPE}/'
+        ];
+        $model = new \Galette\Entity\PdfInvoice($this->zdb, $this->preferences);
+        $this->array($model->patterns)->isIdenticalTo($expected);
+
+        $model = new \Galette\Entity\PdfReceipt($this->zdb, $this->preferences);
+        $this->array($model->patterns)->isIdenticalTo($expected);
+    }
+
+    /**
+     * Types provider
+     *
+     * @return array
+     */
+    protected function typesProvider(): array
+    {
+        return [
+            [
+                'type'  => \Galette\Entity\PdfModel::MAIN_MODEL,
+                'expected'  => 'Galette\Entity\PdfMain'
+            ], [
+                'type'  => \Galette\Entity\PdfModel::INVOICE_MODEL,
+                'expected'  => 'Galette\Entity\PdfInvoice'
+            ], [
+                'type'  => \Galette\Entity\PdfModel::RECEIPT_MODEL,
+                'expected'  => 'Galette\Entity\PdfReceipt'
+            ], [
+                'type'  => \Galette\Entity\PdfModel::ADHESION_FORM_MODEL,
+                'expected'  => 'Galette\Entity\PdfAdhesionFormModel'
+            ], [
+                'type'  => 0,
+                'expected'  => 'Galette\Entity\PdfMain'
+            ]
+        ];
+    }
+
+    /**
+     * Tets getTypeClass
+     * @dataProvider typesProvider
+     *
+     * @param integer $type     Requested type
+     * @param string  $expected Expected class name
+     *
+     * @return void
+     */
+    public function testGetypeClass($type, $expected)
+    {
+        $this->string(\Galette\Entity\PdfModel::getTypeClass($type))->isIdenticalTo($expected);
+    }
+
+    /**
+     * Test model replacements
+     *
+     * @return void
+     */
+    public function testReplacements()
+    {
+        global $container, $zdb;
+        $zdb = $this->zdb; //globals '(
+        $container = $this->container; //globals '(
+
+        //create dynamic fields
+        $field_data = [
+            'form_name'        => 'adh',
+            'field_name'        => 'Dynamic text field',
+            'field_perm'        => DynamicField::PERM_USER_WRITE,
+            'field_type'        => DynamicField::TEXT,
+            'field_required'    => 1,
+            'field_repeat'      => 1
+        ];
+
+        $adf = DynamicField::getFieldType($this->zdb, $field_data['field_type']);
+
+        $stored = $adf->store($field_data);
+        $error_detected = $adf->getErrors();
+        $warning_detected = $adf->getWarnings();
+        $this->boolean($stored)->isTrue(
+            implode(
+                ' ',
+                $adf->getErrors() + $adf->getWarnings()
+            )
+        );
+        $this->array($error_detected)->isEmpty(implode(' ', $adf->getErrors()));
+        $this->array($warning_detected)->isEmpty(implode(' ', $adf->getWarnings()));
+
+        $field_data = [
+            'form_name'         => 'contrib',
+            'field_form'        => 'contrib',
+            'field_name'        => 'Dynamic date field',
+            'field_perm'        => DynamicField::PERM_USER_WRITE,
+            'field_type'        => DynamicField::DATE,
+            'field_required'    => 1,
+            'field_repeat'      => 1
+        ];
+
+        $cdf = DynamicField::getFieldType($this->zdb, $field_data['field_type']);
+
+        $stored = $cdf->store($field_data);
+        $error_detected = $cdf->getErrors();
+        $warning_detected = $cdf->getWarnings();
+        $this->boolean($stored)->isTrue(
+            implode(
+                ' ',
+                $cdf->getErrors() + $cdf->getWarnings()
+            )
+        );
+        $this->array($error_detected)->isEmpty(implode(' ', $cdf->getErrors()));
+        $this->array($warning_detected)->isEmpty(implode(' ', $cdf->getWarnings()));
+
+        //prepare model
+        $rs = new \stdClass();
+        $pk = \Galette\Entity\PdfModel::PK;
+        $rs->$pk = 42;
+        $rs->model_name = 'Test model';
+        $rs->model_title = 'A simple tmodel for tests';
+        $rs->model_subtitle = 'The subtitle';
+        $rs->model_header = null;
+        $rs->model_footer = null;
+        $rs->model_body = 'name: {NAME_ADH} login: {LOGIN_ADH} birthdate: {ADH_BIRTH_DATE} dynlabel: {LABEL_DYNFIELD_' .
+            $adf->getId() . '_ADH} dynvalue: {INPUT_DYNFIELD_' . $adf->getId() . '_ADH} ' .
+            '- enddate: {CONTRIB_END_DATE} amount: {CONTRIB_AMOUNT} ({CONTRIB_AMOUNT_LETTERS}) dynlabel: ' .
+            '{LABEL_DYNFIELD_' . $cdf->getId() . '_CONTRIB} dynvalue: {INPUT_DYNFIELD_' . $cdf->getId() . '_CONTRIB}';
+        $rs->model_styles = null;
+        $rs->model_parent = \Galette\Entity\PdfModel::MAIN_MODEL;
+
+        $model = new \Galette\Entity\PdfInvoice($this->zdb, $this->preferences, $rs);
+
+        $this->string($model->hheader)->isIdenticalTo("<table>
+    <tr>
+        <td id=\"pdf_assoname\"><strong id=\"asso_name\">Galette</strong><br/></td>
+        <td id=\"pdf_logo\"><img src=\"http://\" width=\"129\" height=\"60\"/></td>
+    </tr>
+</table>");
+
+        $this->string($model->hfooter)->isIdenticalTo('<div id="pdf_footer">
+    Association Galette - Galette
+Palais des Papes
+Au milieu
+84000 Avignon - France<br/>
+    
+</div>');
+
+        $data = [
+            'nom_adh' => 'Durand',
+            'prenom_adh' => 'René',
+            'ville_adh' => 'Martel',
+            'cp_adh' => '39 069',
+            'adresse_adh' => '66, boulevard De Oliveira',
+            'email_adh' => 'meunier.josephine@ledoux.com',
+            'login_adh' => 'arthur.hamon',
+            'mdp_adh' => 'J^B-()f',
+            'mdp_adh2' => 'J^B-()f',
+            'bool_admin_adh' => false,
+            'bool_exempt_adh' => false,
+            'bool_display_info' => true,
+            'sexe_adh' => 0,
+            'prof_adh' => 'Chef de fabrication',
+            'titre_adh' => null,
+            'ddn_adh' => '1937-12-26',
+            'lieu_naissance' => 'Gonzalez-sur-Meunier',
+            'pseudo_adh' => 'ubertrand',
+            'pays_adh' => 'Antarctique',
+            'tel_adh' => '0439153432',
+            'url_adh' => 'http://bouchet.com/',
+            'activite_adh' => true,
+            'id_statut' => 9,
+            'date_crea_adh' => '2020-06-10',
+            'pref_lang' => 'en_US',
+            'fingerprint' => 'FAKER' . $this->seed,
+            'info_field_' . $adf->getId() . '_1' => 'My value (:'
+        ];
+        $this->createMember($data);
+        $model->setMember($this->adh);
+
+        $this->createContribution($cdf);
+        $model->setContribution($this->contrib);
+
+        $this->string($model->hbody)->isEqualTo(
+            'name: DURAND René login: arthur.hamon birthdate: 1937-12-26 dynlabel: Dynamic text field dynvalue: ' .
+            '<textarea id="Dynamic text field" name="Dynamic text field" value="My value (:"/> ' .
+            '- enddate: ' . $this->contrib->end_date . ' amount: 92 (ninety-two) dynlabel: Dynamic date field ' .
+            'dynvalue: <input type="text" name="Dynamic date field" value="2020-12-03" size="10" />'
+        );
+    }
+
+    /**
+     * Create member from data
+     *
+     * @param array $data Data to use to create member
+     *
+     * @return \Galette\Entity\Adherent
+     */
+    public function createMember(array $data)
+    {
+        $adh = $this->adh;
+        $check = $adh->check($data, [], []);
+        if (is_array($check)) {
+            var_dump($check);
+        }
+        $this->boolean($check)->isTrue();
+
+        $store = $adh->store();
+        $this->boolean($store)->isTrue();
+    }
+
+    /**
+     * Create test contribution in database
+     *
+     * @param DynamicField $cdf Contribution dynamic field
+     *
+     * @return void
+     */
+    private function createContribution($cdf)
+    {
+        $bdate = new \DateTime(); // 2020-11-07
+        $bdate->sub(new \DateInterval('P5M')); // 2020-06-07
+        $bdate->add(new \DateInterval('P3D')); // 2020-06-10
+
+        $edate = clone $bdate;
+        $edate->add(new \DateInterval('P1Y'));
+
+        $dyndate = new \DateTime('2020-12-03 22:56:53');
+
+        $data = [
+            'id_adh' => $this->adh->id,
+            'id_type_cotis' => 1,
+            'montant_cotis' => 92,
+            'type_paiement_cotis' => 3,
+            'info_cotis' => 'FAKER' . $this->seed,
+            'date_enreg' => $bdate->format('Y-m-d'),
+            'date_debut_cotis' => $bdate->format('Y-m-d'),
+            'date_fin_cotis' => $edate->format('Y-m-d'),
+            'info_field_' . $cdf->getId() . '_1' => $dyndate->format('Y-m-d')
+        ];
+        $this->createContrib($data);
+    }
+
+    /**
+     * Create contribution from data
+     *
+     * @param array $data Data to use to create contribution
+     *
+     * @return \Galette\Entity\Contribution
+     */
+    public function createContrib(array $data)
+    {
+        $this->contrib = new \Galette\Entity\Contribution($this->zdb, $this->login);
+        $contrib = $this->contrib;
+        $check = $contrib->check($data, [], []);
+        if (is_array($check)) {
+            var_dump($check);
+        }
+        $this->boolean($check)->isTrue();
+
+        $store = $contrib->store();
+        $this->boolean($store)->isTrue();
+    }
+}
index 94b2f4cc09d5c52750020bc879a2272661ee5e44..f5374337c3db37082cab6648909c9e2f06cb96b6 100644 (file)
@@ -77,8 +77,8 @@ class PdfModels extends atoum
         $this->session = new \RKA\Session();
         $this->login = new \Galette\Core\Login($this->zdb, $this->i18n, $this->session);
 
-        $types = new \Galette\Repository\PdfModels($this->zdb, $this->preferences, $this->login);
-        $res = $types->installInit(false);
+        $models = new \Galette\Repository\PdfModels($this->zdb, $this->preferences, $this->login);
+        $res = $models->installInit(false);
         $this->boolean($res)->isTrue();
     }
 
index 4d255a6a0c5e436ab35c8f8443d5bdc614495836..6690626ddd4d056a6fd6a7b6f879e61130aee979 100644 (file)
@@ -38,7 +38,7 @@
  * @since     2013-01-13
  */
 
-use mageekguy\atoum;
+use atoum\atoum;
 
 $coverageField = new atoum\report\fields\runner\coverage\html(
     'Galette',