Comment: | HelloAsso: member auto-registration support implemented |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dev |
Files: | files | file ages | folders |
SHA1: |
c43bba7fd958238da338f974e3b3da86 |
User & Date: | alinaar on 2023-05-31 16:43:33 |
Other Links: | branch diff | manifest | tags |
2023-05-31
| ||
16:44 | Merge with #28521d20d0 check-in: f83112263d user: alinaar tags: dev | |
16:43 | HelloAsso: member auto-registration support implemented check-in: c43bba7fd9 user: alinaar tags: dev | |
2023-05-28
| ||
18:53 | HelloAsso: Chargeable item label clarified (options and donations) check-in: e821445e61 user: alinaar tags: dev | |
Modified helloasso/admin/chargeable.php from [1b0737d81b] to [98c27e97a5].
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | $csrf_key = 'accounts_setting'; $form->runIf('save', function () use ($chargeable) { // ToDo: add a nice check $chargeable->set('id_credit_account', (int)array_keys($_POST['credit'])[0]); $chargeable->set('id_debit_account', (int)array_keys($_POST['debit'])[0]); $chargeable->save(); }, $csrf_key, 'chargeable.php?id=' . $id . '&ok'); $item = $chargeable->id_item ? EntityManager::findOneById(Item::class, $chargeable->id_item) : null; $form = EntityManager::findOneById(Form::class, $chargeable->id_form); $credit_account = $chargeable->id_credit_account ? EntityManager::findOneById(Account::class, (int)$chargeable->id_credit_account) : null; $debit_account = $chargeable->id_debit_account ? EntityManager::findOneById(Account::class, (int)$chargeable->id_debit_account) : null; | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | $csrf_key = 'accounts_setting'; $form->runIf('save', function () use ($chargeable) { // ToDo: add a nice check $chargeable->set('id_credit_account', (int)array_keys($_POST['credit'])[0]); $chargeable->set('id_debit_account', (int)array_keys($_POST['debit'])[0]); $chargeable->set('register_user', (int)isset($_POST['register_user'])); $chargeable->save(); }, $csrf_key, 'chargeable.php?id=' . $id . '&ok'); $item = $chargeable->id_item ? EntityManager::findOneById(Item::class, $chargeable->id_item) : null; $form = EntityManager::findOneById(Form::class, $chargeable->id_form); $credit_account = $chargeable->id_credit_account ? EntityManager::findOneById(Account::class, (int)$chargeable->id_credit_account) : null; $debit_account = $chargeable->id_debit_account ? EntityManager::findOneById(Account::class, (int)$chargeable->id_debit_account) : null; |
︙ | ︙ |
Modified helloasso/admin/config.php from [7bd10ad627] to [424b31d652].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php namespace Garradin; use Garradin\Plugin\HelloAsso\HelloAsso; use Garradin\Users\DynamicFields; $session->requireAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN); $ha = HelloAsso::getInstance(); if ((array_key_exists('tab', $_GET) && $_GET['tab'] === 'client') || !$ha->isConfigured()) Utils::redirect(PLUGIN_ADMIN_URL . 'config_client.php'); $csrf_key = sprintf('config_plugin_%s', $plugin->id); $form->runIf('save', function () use ($ha) { | > | | < < < | | | < | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <?php namespace Garradin; use Garradin\Plugin\HelloAsso\HelloAsso; use Garradin\Plugin\HelloAsso\API; use Garradin\Users\DynamicFields; $session->requireAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN); $ha = HelloAsso::getInstance(); if ((array_key_exists('tab', $_GET) && $_GET['tab'] === 'client') || !$ha->isConfigured()) Utils::redirect(PLUGIN_ADMIN_URL . 'config_client.php'); $csrf_key = sprintf('config_plugin_%s', $plugin->id); $form->runIf('save', function () use ($ha) { $ha->saveConfig(f('payer_map'), f('merge_names'), f('match_email_field')); }, $csrf_key, '?ok'); $match_options = [ 0 => 'Nom et prénom', 1 => 'Adresse e-mail', ]; $merge_names_options = $ha::MERGE_NAMES_OPTIONS; $payer_fields = API::PAYER_FIELDS; $dynamic_fields = [ null => '-- Ne pas importer', ]; $fields = DynamicFields::getInstance()->all(); foreach ($fields as $key => $config) { if (!isset($config->label)) { continue; } $dynamic_fields[$key] = $config->label; } $tpl->assign(compact('merge_names_options', 'match_options', 'csrf_key', 'payer_fields', 'dynamic_fields')); $tpl->display(PLUGIN_ROOT . '/templates/config.tpl'); |
Modified helloasso/admin/config_client.php from [9b42024a38] to [025f039dca].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php namespace Garradin; use Garradin\Plugin\HelloAsso\HelloAsso; use KD2\DB\EntityManager as EM; use Garradin\Entities\Accounting\Account; $session->requireAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN); $csrf_key = sprintf('config_plugin_%s', $plugin->id); $ha = HelloAsso::getInstance(); $form->runIf('save', function () use ($ha) { if ($client_secret = f('client_secret')) { $ha->saveClient(f('client_id'), $client_secret); } // ToDo: add a nice form check | > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | <?php namespace Garradin; use Garradin\Plugin\HelloAsso\HelloAsso; use Garradin\Plugin\HelloAsso\API; use KD2\DB\EntityManager as EM; use Garradin\Entities\Accounting\Account; use Garradin\Entities\Users\Category; use Garradin\Users\DynamicFields; $session->requireAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN); $csrf_key = sprintf('config_plugin_%s', $plugin->id); $ha = HelloAsso::getInstance(); $form->runIf('save', function () use ($ha) { if ($client_secret = f('client_secret')) { $ha->saveClient(f('client_id'), $client_secret); } // ToDo: add a nice form check $data = $_POST; $data['payer_map']['name'] = (int)$data['payer_map']['name']; foreach ($data['payer_map'] as $field => $value) { if ($value === 'null') { $data['payer_map'][$field] = null; } } $data['user_match_type'] = (int)$data['user_match_type']; $data['user_match_field'] = $data['user_match_field']; $ha->saveConfig($data); Utils::redirect('?ok=' . ($client_secret ? 'connection' : 'config')); }, $csrf_key, null); $credit_account = EM::findOneById(Account::class, (int)$plugin->getConfig()->id_credit_account); $debit_account = EM::findOneById(Account::class, (int)$plugin->getConfig()->id_debit_account); $categories = EM::getInstance(Category::class)->all('SELECT * FROM @TABLE'); $category_options = []; foreach ($categories as $category) { $category_options[(int)$category->id] = $category->name; } $dynamic_fields = $email_fields = [ 'null' => '-- Ne pas importer', ]; $user_match_fields = []; $fields = DynamicFields::getInstance()->all(); foreach ($fields as $key => $config) { if (!isset($config->label)) { continue; } $dynamic_fields[$key] = $config->label; } $payer_fields = API::PAYER_FIELDS; // The following fields have a specific process unset($payer_fields['firstName']); unset($payer_fields['lastName']); unset($payer_fields['email']); $fields = DynamicFields::getEmailFields(); foreach ($fields as $field) { $email_fields[$field] = $field; $user_match_fields[$field] = $field; } $fields = DynamicFields::getNameFields(); foreach ($fields as $field) { $user_match_fields[$field] = $field; } $tpl->assign([ 'client_id' => $ha->getClientId(), 'secret' => '', 'csrf_key' => $csrf_key, 'restricted' => $ha->isTrial(), 'chart_id' => Plugin\HelloAsso\HelloAsso::CHART_ID, // ToDo: make it dynamic 'default_credit_account' => (null !== $credit_account) ? [ $credit_account->id => $credit_account->code . ' — ' . $credit_account->label ] : null, 'default_debit_account' => (null !== $debit_account) ? [ $debit_account->id => $debit_account->code . ' — ' . $debit_account->label ] : null, 'category_options' => $category_options, 'payer_fields' => $payer_fields, 'dynamic_fields' => $dynamic_fields, 'email_fields' => $email_fields, 'user_match_fields' => $ha::USER_MATCH_TYPES, 'merge_names_options' => $ha::MERGE_NAMES_OPTIONS ]); $tpl->display(PLUGIN_ROOT . '/templates/config_client.tpl'); |
Modified helloasso/admin/order.php from [7ed6bfb7c3] to [edd8895eee].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php namespace Garradin; use Garradin\Plugin\HelloAsso\Orders; use Garradin\Plugin\HelloAsso\Payments; use Garradin\Plugin\HelloAsso\Items; use Garradin\Plugin\HelloAsso\Options; require __DIR__ . '/_inc.php'; $order = Orders::get((int)qg('id')); if (!$order) { throw new UserException('Commande inconnue'); } $payments = Payments::list($order); $items = Items::list($order); $options = Options::list($order); $payer_infos = $order->getPayerInfos(); //$found_user = $ha->findUserForPayment($order->payer); //$mapped_user = $ha->getMappedUser($order->payer); $found_user = $mapped_user = []; | > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?php namespace Garradin; use Garradin\Plugin\HelloAsso\Orders; use Garradin\Plugin\HelloAsso\Payments; use Garradin\Plugin\HelloAsso\Items; use Garradin\Plugin\HelloAsso\Options; use Garradin\Plugin\HelloAsso\HelloAsso as HA; use KD2\DB\EntityManager as EM; use Garradin\Entities\Users\User; require __DIR__ . '/_inc.php'; $order = Orders::get((int)qg('id')); if (!$order) { throw new UserException('Commande inconnue'); } $user = $order->id_user ? EM::findOneById(User::class, (int)$order->id_user) : null; $payments = Payments::list($order); $items = Items::list($order); $options = Options::list($order); $payer_infos = $order->getPayerInfos(); //$found_user = $ha->findUserForPayment($order->payer); //$mapped_user = $ha->getMappedUser($order->payer); $found_user = $mapped_user = []; $user_match_field_label = (int)$plugin->getConfig()->user_match_type; $tpl->assign(compact('order', 'user', 'payments', 'items', 'options', 'payer_infos', 'found_user', 'mapped_user', 'user_match_field_label')); $tpl->display(PLUGIN_ROOT . '/templates/order.tpl'); |
Modified helloasso/admin/sync.php from [24cb973245] to [bddd888e91].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php namespace Garradin; require __DIR__ . '/_inc.php'; use KD2\DB\EntityManager as EM; use Garradin\Entities\Accounting\Account; use Garradin\Plugin\HelloAsso\Forms; use Garradin\Plugin\HelloAsso\Entities\Chargeable; use Garradin\Plugin\HelloAsso\Chargeables; $csrf_key = 'sync'; | > | > | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php namespace Garradin; require __DIR__ . '/_inc.php'; use KD2\DB\EntityManager as EM; use Garradin\Entities\Accounting\Account; use Garradin\Plugin\HelloAsso\Forms; use Garradin\Plugin\HelloAsso\Items; use Garradin\Plugin\HelloAsso\Entities\Chargeable; use Garradin\Plugin\HelloAsso\Chargeables; $csrf_key = 'sync'; $form->runIf('sync', function() use ($ha, $tpl) { $ha->sync(); if (!$exceptions = Items::getExceptions()) { Utils::redirect(PLUGIN_ADMIN_URL . 'sync.php?ok=1'); } $tpl->assign('exceptions', $exceptions); }, $csrf_key); $default_ca = EM::findOneById(Account::class, (int)$plugin->getConfig()->id_credit_account); $default_da = EM::findOneById(Account::class, (int)$plugin->getConfig()->id_debit_account); $tpl->assign([ 'last_sync' => $ha->getLastSync(), 'csrf_key' => $csrf_key, |
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 | { $source[$id_item]['credit'] = (int)$id_credit_account; $source[$id_item]['debit'] = (int)$id_debit_account; } } Chargeables::setAccounts($source); } $ha->sync(); }, null, PLUGIN_ADMIN_URL . 'sync.php?ok=1'); $tpl->display(PLUGIN_ROOT . '/templates/sync.tpl'); | > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | { $source[$id_item]['credit'] = (int)$id_credit_account; $source[$id_item]['debit'] = (int)$id_debit_account; } } Chargeables::setAccounts($source); } if (array_key_exists('register_user', $_POST)) { Chargeables::setUserRegistrators(array_keys($_POST['register_user'])); } $ha->sync(); }, null, PLUGIN_ADMIN_URL . 'sync.php?ok=1'); $tpl->display(PLUGIN_ROOT . '/templates/sync.tpl'); |
Modified helloasso/lib/API.php from [9076f8fdd9] to [49de7a7f7a].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | use KD2\HTTP; use KD2\DB\EntityManager; class API { //const BASE_URL = 'https://api.helloasso.com/'; const BASE_URL = 'https://api.helloasso-sandbox.com/'; protected $ha; protected $oauth; protected $client_id; static protected $_instance = null; | > > > > > > > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | use KD2\HTTP; use KD2\DB\EntityManager; class API { //const BASE_URL = 'https://api.helloasso.com/'; const BASE_URL = 'https://api.helloasso-sandbox.com/'; const PAYER_FIELDS = [ 'firstName' => 'Prénom', 'lastName' => 'Nom', 'email' => 'Courriel', 'address' => 'Adresse', 'city' => 'Ville', 'zipCode' => 'Code postale', 'country' => 'Pays', 'dateOfBirth' => 'Date de naissance', 'company' => 'Association/entreprise' ]; protected $ha; protected $oauth; protected $client_id; static protected $_instance = null; |
︙ | ︙ |
Modified helloasso/lib/ChargeableInterface.php from [c5d759431e] to [eb05565996].
1 2 3 4 5 6 7 8 9 10 | <?php namespace Garradin\Plugin\HelloAsso; interface ChargeableInterface { public function getItemId(): ?int; public function getLabel(): string; public function getAmount(): ?int; } | > | 1 2 3 4 5 6 7 8 9 10 11 | <?php namespace Garradin\Plugin\HelloAsso; interface ChargeableInterface { public function getItemId(): ?int; public function getLabel(): string; public function getAmount(): ?int; public function setUserId(?int $id): void; } |
Modified helloasso/lib/Chargeables.php from [4bb6b22054] to [e6e3a29971].
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 'label' => 'Libellé', 'select' => 'c.label' ], 'amount' => [ 'label' => 'Montant', 'select' => 'c.amount' ], 'credit_account' => [ 'label' => 'Recette', 'select' => 'ca.code' ], 'id_credit_account' => [ 'select' => 'c.id_credit_account' ], | > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 'label' => 'Libellé', 'select' => 'c.label' ], 'amount' => [ 'label' => 'Montant', 'select' => 'c.amount' ], 'register_user' => [ 'label' => 'Inscrip. Auto', 'select' => 'c.register_user' ], 'credit_account' => [ 'label' => 'Recette', 'select' => 'ca.code' ], 'id_credit_account' => [ 'select' => 'c.id_credit_account' ], |
︙ | ︙ | |||
131 132 133 134 135 136 137 138 139 140 141 142 143 144 | $list->setTitle(sprintf('%s - Items', $for->name)); $list->setModifier(function ($row) { $row->type_label = ($row->id_item !== null) ? (Item::TYPES[$row->item_type] ?? 'Inconnu') : (Form::TYPES[$row->form_type] ?? 'Inconnu'); if ($row->type === Chargeable::OPTION_TYPE) { $row->type_label .= ' - ' . Chargeable::TYPES[$row->type]; } if (isset($row->custom_fields)) { $row->custom_fields = json_decode($row->custom_fields, true); } }); $list->setExportCallback(function (&$row) { | > > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | $list->setTitle(sprintf('%s - Items', $for->name)); $list->setModifier(function ($row) { $row->type_label = ($row->id_item !== null) ? (Item::TYPES[$row->item_type] ?? 'Inconnu') : (Form::TYPES[$row->form_type] ?? 'Inconnu'); if ($row->type === Chargeable::OPTION_TYPE) { $row->type_label .= ' - ' . Chargeable::TYPES[$row->type]; } $row->register_user = $row->register_user ? 'oui' : ''; if (isset($row->custom_fields)) { $row->custom_fields = json_decode($row->custom_fields, true); } }); $list->setExportCallback(function (&$row) { |
︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | { $chargeable = new Chargeable(); $chargeable->set('type', $type); $chargeable->set('id_form', $id_form); $chargeable->set('id_item', $entity->getItemId()); $chargeable->set('label', $entity->getLabel()); $chargeable->set('amount', ($type === Chargeable::ONLY_ONE_ITEM_FORM_TYPE ? null : $entity->getAmount())); $chargeable->save(); return $chargeable; } static public function setAccounts(array $source): void { foreach ($source as $id => $accounts) { if (DB::getInstance()->exec(sprintf('UPDATE %s SET id_credit_account = %d, id_debit_account = %d WHERE id = %d;', Chargeable::TABLE, $accounts['credit'], $accounts['debit'], (int)$id)) === false) { throw new \RuntimeException(sprintf('Cannot update %s plugin Items\' accounting accounts.', HelloAsso::PROVIDER_LABEL)); } } } | > | > > > > > > > > > > > > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | { $chargeable = new Chargeable(); $chargeable->set('type', $type); $chargeable->set('id_form', $id_form); $chargeable->set('id_item', $entity->getItemId()); $chargeable->set('label', $entity->getLabel()); $chargeable->set('amount', ($type === Chargeable::ONLY_ONE_ITEM_FORM_TYPE ? null : $entity->getAmount())); $chargeable->set('register_user', 0); $chargeable->save(); return $chargeable; } static public function setAccounts(array $source): void { foreach ($source as $id => $accounts) { if (DB::getInstance()->exec(sprintf('UPDATE %s SET id_credit_account = %d, id_debit_account = %d WHERE id = %d;', Chargeable::TABLE, $accounts['credit'], $accounts['debit'], (int)$id)) === false) { throw new \RuntimeException(sprintf('Cannot update %s plugin Items\' accounting accounts.', HelloAsso::PROVIDER_LABEL)); } } } static public function setUserRegistrators(array $ids): void { foreach ($ids as $id) { if (!is_int($id)) { throw new \InvalidArgumentException(sprintf('User (Chargeable) registrator ID must be an integer. "%s" provided.', $id)); } } if (DB::getInstance()->exec(sprintf('UPDATE %s SET register_user = 1 WHERE id IN (%s);', Chargeable::TABLE, implode(', ', $ids))) === false) { throw new \RuntimeException(sprintf('Cannot set %s plugin Chargeables\' user registrators.', HelloAsso::PROVIDER_LABEL)); } } } |
Modified helloasso/lib/Entities/Chargeable.php from [cd61ecfb35] to [a9128f3a79].
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | protected int $id_form; protected ?int $id_item; // ONLY_ONE_ITEM_FORM_TYPE forms/payments have always only one item so we do not care about its value protected ?int $id_credit_account; protected ?int $id_debit_account; protected int $type; protected string $label; protected ?int $amount; protected ?string $_form_name = null; protected ?string $_item_name = null; public function setForm_name(string $name): void { $this->_form_name = $name; | > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | protected int $id_form; protected ?int $id_item; // ONLY_ONE_ITEM_FORM_TYPE forms/payments have always only one item so we do not care about its value protected ?int $id_credit_account; protected ?int $id_debit_account; protected int $type; protected string $label; protected ?int $amount; protected int $register_user; protected ?string $_form_name = null; protected ?string $_item_name = null; public function setForm_name(string $name): void { $this->_form_name = $name; |
︙ | ︙ |
Modified helloasso/lib/Entities/Form.php from [5af3819487] to [0210547673].
︙ | ︙ | |||
45 46 47 48 49 50 51 | return $this->name; } public function getAmount(): ?int { return null; } | | > > | 45 46 47 48 49 50 51 52 53 54 | return $this->name; } public function getAmount(): ?int { return null; } public function setUserId(?int $id): void {} } |
Modified helloasso/lib/Entities/Item.php from [c17f6f487f] to [7f7435b0dd].
1 2 3 4 5 6 7 8 9 10 11 | <?php namespace Garradin\Plugin\HelloAsso\Entities; use Garradin\Entity; use Garradin\Plugin\HelloAsso\ChargeableInterface; class Item extends Entity implements ChargeableInterface { const TABLE = 'plugin_helloasso_items'; | | | | | | | | | | | | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php namespace Garradin\Plugin\HelloAsso\Entities; use Garradin\Entity; use Garradin\Plugin\HelloAsso\ChargeableInterface; class Item extends Entity implements ChargeableInterface { const TABLE = 'plugin_helloasso_items'; protected int $id; protected int $id_order; protected int $id_form; protected ?int $id_user; protected ?int $id_transaction; protected string $type; protected string $state; protected string $label; protected string $person; protected int $amount; protected int $has_options; /*protected ?string $custom_fields;*/ protected ?\stdClass $custom_fields; // Is a mix between real HelloAsso custom fields and plugin generated infos during sync protected string $raw_data; const TYPES = [ 'Donation' => 'Don', 'Payment' => 'Paiement', 'Registration' => 'Inscription', 'Membership' => 'Adhésion', 'MonthlyDonation' => 'Don mensuel', |
︙ | ︙ | |||
56 57 58 59 60 61 62 | return $this->label; } public function getAmount(): ?int { return $this->amount; } | | > > > > > | 57 58 59 60 61 62 63 64 65 66 67 68 69 | return $this->label; } public function getAmount(): ?int { return $this->amount; } public function setUserId(?int $id): void { $this->set('id_user', $id); } } |
Modified helloasso/lib/Entities/Option.php from [36ff74212e] to [64d137b929].
1 2 3 4 5 6 7 8 9 10 11 | <?php namespace Garradin\Plugin\HelloAsso\Entities; use Garradin\Entity; use Garradin\Plugin\HelloAsso\ChargeableInterface; class Option extends Entity implements ChargeableInterface { const TABLE = 'plugin_helloasso_item_options'; | | | | | > | | | | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php namespace Garradin\Plugin\HelloAsso\Entities; use Garradin\Entity; use Garradin\Plugin\HelloAsso\ChargeableInterface; class Option extends Entity implements ChargeableInterface { const TABLE = 'plugin_helloasso_item_options'; protected int $id; protected int $id_item; protected int $id_order; // Redundant but needed by DynamicList since it does not handle JOIN statement protected ?int $id_user; protected ?int $id_transaction; protected string $label; protected int $amount; protected ?\stdClass $custom_fields; protected string $raw_data; public function getItemId(): ?int { return $this->id_item; } public function getLabel(): string { return $this->label; } public function getAmount(): ?int { return $this->amount; } public function setUserId(?int $id): void { $this->set('id_user', $id); } } |
Modified helloasso/lib/Entities/Order.php from [8a884c7098] to [a5cda5cb7a].
︙ | ︙ | |||
46 47 48 49 50 51 52 | return $paid >= $total ? self::STATUS_PAID : self::STATUS_WAITING; } public function getPayerInfos(): array { $data = json_decode($this->raw_data); | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | return $paid >= $total ? self::STATUS_PAID : self::STATUS_WAITING; } public function getPayerInfos(): array { $data = json_decode($this->raw_data); return $data ? Payment::formatPersonInfos($data->payer) : []; } public function listItems(): array { return EM::getInstance(Item::class)->all('SELECT * FROM @TABLE WHERE id_order = ? ORDER BY id DESC;', $this->id()); } |
︙ | ︙ |
Modified helloasso/lib/Entities/Payment.php from [4b8457a9fe] to [8632806434].
︙ | ︙ | |||
53 54 55 56 57 58 59 | 'address' => 'Adresse postale', 'zipCode' => 'Code postal', 'city' => 'Ville', 'country' => 'Pays', 'dateOfBirth' => 'Date de naissance', ]; | | | | | | | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 'address' => 'Adresse postale', 'zipCode' => 'Code postal', 'city' => 'Ville', 'country' => 'Pays', 'dateOfBirth' => 'Date de naissance', ]; static public function getPersonName(\stdClass $person) { $names = [!empty($person->company) ? $person->company . ' — ' : null, $person->firstName ?? null, $person->lastName ?? null]; $names = array_filter($names); $names = implode(' ', $names); if (!empty($person->city)) { $names .= sprintf(' (%s)', $person->city); } return $names; } static public function formatPersonInfos(\stdClass $person) { $data = []; foreach (self::PAYER_FIELDS as $key => $name) { if (!isset($person->$key)) { continue; } $value = $person->$key; if ($key == 'dateOfBirth') { $value = new \DateTime($value); } $data[$name] = $value; } return $data; } } |
Modified helloasso/lib/HelloAsso.php from [da9f5f27f3] to [824267f35d].
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Config; use Garradin\DB; use Garradin\Entities\Plugin; use Garradin\Entities\Users\User; use Garradin\Entities\Payments\Payment; use KD2\DB\EntityManager; use Garradin\Plugin\HelloAsso\Entities\Form; | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Config; use Garradin\DB; use Garradin\Users\DynamicFields; use Garradin\Entities\Plugin; use Garradin\Entities\Users\User; use Garradin\Entities\Payments\Payment; use KD2\DB\EntityManager; use Garradin\Plugin\HelloAsso\Entities\Form; |
︙ | ︙ | |||
28 29 30 31 32 33 34 | const REDIRECTION_FILE = 'payer.php'; const PER_PAGE = 100; const MERGE_NAMES_FIRST_LAST = 0; const MERGE_NAMES_LAST_FIRST = 1; const MERGE_NAMES_OPTIONS = [ | < > > > > > | | > > > | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | const REDIRECTION_FILE = 'payer.php'; const PER_PAGE = 100; const MERGE_NAMES_FIRST_LAST = 0; const MERGE_NAMES_LAST_FIRST = 1; const MERGE_NAMES_OPTIONS = [ self::MERGE_NAMES_LAST_FIRST => 'Nom Prénom', self::MERGE_NAMES_FIRST_LAST => 'Prénom Nom' ]; const USER_MATCH_NAME = 0; const USER_MATCH_EMAIL = 1; const USER_MATCH_TYPES = [ self::USER_MATCH_NAME => 'Nom et prénom', self::USER_MATCH_EMAIL => 'Courriel' ]; protected $plugin; protected ?\stdClass $config; static protected ?array $_userMatchField = null; static protected int $_mergeNamesOption; static protected array $_existingUsersCache = []; static protected $_instance; static public function getInstance() { if (null === self::$_instance) { self::$_instance = new self; } |
︙ | ︙ | |||
122 123 124 125 126 127 128 129 130 131 132 133 | } public function initConfig(): bool { $this->plugin->setConfigProperty('accounting', self::ACCOUNTING_ENABLED); $this->plugin->setConfigProperty('client_id', ''); $this->plugin->setConfigProperty('id_credit_account', false); $this->plugin->setConfigProperty('id_debit_account', false); return $this->plugin->save(); } public function saveConfig(array $data): bool { | > < < < < < > > > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | } public function initConfig(): bool { $this->plugin->setConfigProperty('accounting', self::ACCOUNTING_ENABLED); $this->plugin->setConfigProperty('client_id', ''); $this->plugin->setConfigProperty('id_credit_account', false); $this->plugin->setConfigProperty('id_debit_account', false); $this->plugin->setConfigProperty('id_category', false); return $this->plugin->save(); } public function saveConfig(array $data): bool { $this->plugin->setConfigProperty('accounting', $data['accounting']); if (array_key_exists('default_credit', $data)) $this->plugin->setConfigProperty('id_credit_account', array_keys($data['default_credit'])[0]); if (array_key_exists('default_debit', $data)) $this->plugin->setConfigProperty('id_debit_account', array_keys($data['default_debit'])[0]); $this->plugin->setConfigProperty('id_category', (int)$data['id_category']); $this->plugin->setConfigProperty('payer_map', $data['payer_map']); $this->plugin->setConfigProperty('user_match_type', $data['user_match_type']); $this->plugin->setConfigProperty('user_match_field', $data['user_match_field']); return $this->plugin->save(); } public function isConfigured(): bool { return empty($this->config->oauth) ? false : true; } |
︙ | ︙ | |||
396 397 398 399 400 401 402 | return true; } else { return false; } } | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | return true; } else { return false; } } static public function guessUserIdentifier(\stdClass $source): ?string { if (self::getUserMatchField()[1] === 'name') { return self::guessUserName($source); } if (isset($source->email)) return $source->email; return $source->{self::getUserMatchField()[2]} ?? null; } static public function guessUserName(\stdClass $source): string { if (self::getInstance()->plugin()->getConfig()->payer_map->name === HelloAsso::MERGE_NAMES_FIRST_LAST) { return $source->firstName . ' ' . $source->lastName; } return $source->lastName . ' ' . $source->firstName; } static public function userAlreadyExists(string $identifier): bool { return (bool)self::getUserId($identifier); } static public function getUserId(string $identifier): ?int { if (array_key_exists($identifier, self::$_existingUsersCache)) { return self::$_existingUsersCache[$identifier]; } $id_user = EntityManager::getInstance(User::class)->col(sprintf('SELECT id FROM @TABLE WHERE %s = ?;', self::getUserMatchField()[0]), $identifier); self::$_existingUsersCache[$identifier] = (false === $id_user) ? null : $id_user; return self::$_existingUsersCache[$identifier]; } static public function addUserToCache(string $identifier, int $id_user): void { self::$_existingUsersCache[$identifier] = $id_user; } static public function getUserMatchField(): array { if (null === self::$_userMatchField) { if (self::getInstance()->plugin()->getConfig()->user_match_type === self::USER_MATCH_NAME) { self::$_userMatchField = [ DynamicFields::getFirstNameField(), 'name', null ]; } else { self::$_userMatchField = [ DynamicFields::getFirstEmailField(), 'email', self::getInstance()->plugin()->getConfig()->user_match_field ]; } } return self::$_userMatchField; } } |
Modified helloasso/lib/Items.php from [8e07481fa3] to [98194df7c2].
1 2 3 4 5 6 7 8 9 10 11 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Plugin\HelloAsso\Entities\Form; use Garradin\Plugin\HelloAsso\Entities\Item; use Garradin\Plugin\HelloAsso\Entities\Chargeable; use Garradin\Plugin\HelloAsso\Entities\Option; use Garradin\Plugin\HelloAsso\Entities\Order; use Garradin\Plugin\HelloAsso\Entities\Payment; use Garradin\Plugin\HelloAsso\API; | | > > > > > | > > > > > > > > > | > | > | > | > > > > > > > > > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Plugin\HelloAsso\Entities\Form; use Garradin\Plugin\HelloAsso\Entities\Item; use Garradin\Plugin\HelloAsso\Entities\Chargeable; use Garradin\Plugin\HelloAsso\Entities\Option; use Garradin\Plugin\HelloAsso\Entities\Order; use Garradin\Plugin\HelloAsso\Entities\Payment; use Garradin\Plugin\HelloAsso\API; use Garradin\Plugin\HelloAsso\HelloAsso as HA; use Garradin\Plugin\HelloAsso\ChargeableInterface; use Garradin\DB; use Garradin\DynamicList; use Garradin\Utils; use Garradin\Entities\Accounting\Transaction; use Garradin\Accounting\Years; use Garradin\Users\DynamicFields; use Garradin\Users\Users; use Garradin\Entities\Users\User; use Garradin\Plugin\HelloAsso\Payments; use KD2\DB\EntityManager as EM; use Garradin\Plugin\HelloAsso\Mock\MockItems; class Items { const TRANSACTION_PREFIX = 'Item'; const TRANSACTION_NOTE = 'Générée automatiquement par l\'extension ' . HA::PROVIDER_LABEL . '.'; const DONATION_LABEL = 'Don'; const CHECKOUT_LABEL = 'Commande #%d (%s)'; const DUPLICATE_MEMBER_PREFIX = 'Doublon-%s-'; static protected string $_nameField; static protected array $_userFieldsMap; static protected array $_userIdsByLoginCache = []; // Used when userMatchField is different from the Paheko login field static protected array $_exceptions = []; static public function get(int $id): ?Item { return EM::findOneById(Item::class, $id); } static public function list($for): DynamicList { $columns = [ 'id' => [ 'select' => 'i.id' ], 'id_chargeable' => [ 'label' => 'Référence', 'select' => 'c.id' ], 'id_transaction' => [ 'label' => 'Écriture' ], 'amount' => [ 'label' => 'Montant', 'select' => 'i.amount' ], 'type' => [ 'label' => 'Type', 'select' => 'i.type' ], 'label' => [ 'label' => 'Objet', 'select' => 'i.label' ], 'person' => [ 'label' => 'Personne' ], 'id_user' => [], 'user_name' => [ 'label' => 'Membre correspondant*', 'select' => 'u.nom' ], 'numero' => [ 'select' => 'u.numero' ], 'options' => [ 'label' => 'Options', 'select' => "(CASE WHEN has_options THEN 'oui' ELSE '-' END)" ], // sprintf("(SELECT (CASE WHEN COUNT(id) > 0 THEN 'oui' ELSE '-' END) FROM %s o WHERE o.id_item = %s.id)", Option::TABLE, Item::TABLE) 'custom_fields' => [ 'label' => 'Champs' ], 'state' => [ 'label' => 'Statut' ], 'id_order' => [], ]; $tables = Item::TABLE . ' i INNER JOIN ' . Chargeable::TABLE . ' c ON (c.id_form = i.id_form AND c.label = i.label AND c.amount = i.amount) LEFT JOIN ' . User::TABLE . ' u ON (u.id = i.id_user)'; if ($for instanceof Form) { unset($columns['custom_fields']); } $list = new DynamicList($columns, $tables); |
︙ | ︙ | |||
95 96 97 98 99 100 101 | } }); $list->setExportCallback(function (&$row) { $row->amount = $row->amount ? Utils::money_format($row->amount, '.', '', false) : null; // Serialize custom fields as a text field | | | > > > > > > > > > > > > > > > > > > > | > > > > | | > | > | | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | > > > > > | > > > > > < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > | | | < < | | < > > > > > > | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | } }); $list->setExportCallback(function (&$row) { $row->amount = $row->amount ? Utils::money_format($row->amount, '.', '', false) : null; // Serialize custom fields as a text field /*if (isset($row->custom_fields)) { $row->custom_fields = implode("\n", array_map(function ($v, $k) { return "$k: $v"; }, $row->custom_fields, array_keys($row->custom_fields))); }*/ }); $list->orderBy('id', true); return $list; } static protected function init(): void { self::$_nameField = DynamicFields::getFirstNameField(); self::setUserFieldsMap(); } static protected function setUserFieldsMap(): void { $map = clone HA::getInstance()->plugin()->getConfig()->payer_map; unset($map->name); // name has a specific process foreach ($map as $api_field => $user_field) { if (null === $user_field) { unset($map->$api_field); } } self::$_userFieldsMap = array_flip((array)$map); } static public function sync(string $org_slug, bool $accounting = true): void { self::init(); $params = [ 'pageSize' => HA::getPageSize(), ]; $page_count = 1; for ($i = 1; $i <= $page_count; $i++) { $params['pageIndex'] = $i; $result = API::getInstance()->listOrganizationItems($org_slug, $params); $page_count = $result->pagination->totalPages; //$result->data = MockItems::donationAndOptions(); //$result->data = MockItems::multipleSubscriptions(); foreach ($result->data as $order) { try { self::syncItem($order, $accounting); } catch (SyncException $e) { self::catchSyncException($e); } } if (HA::isTrial()) { break; } } } static protected function syncItem(\stdClass $data, bool $accounting): Item { $item = self::get($data->id) ?? new Item; $item->set('raw_data', json_encode($data)); $data = self::transform($data); self::setItem($item, $data); $item->save(); try { self::handleUserRegistration($data, (int)$item->id_form, $item, Chargeable::TYPE_FROM_FORM[$data->order->formType]); } catch (SyncException $e) { self::catchSyncException($e); } try { $optionEntities = self::syncOptions($data, $item, $accounting); } catch (SyncException $e) { self::catchSyncException($e); } try { self::handleAccounting($item, $data, $optionEntities, $accounting); } catch (SyncException $e) { self::catchSyncException($e); } return $item; } static protected function setItem(Item $item, \stdClass $data): void { // ToDo: add some cache for those checks if (!EM::getInstance(Order::class)->col(sprintf('SELECT id FROM @TABLE WHERE id = :id_order;'), $data->order_id)) { throw new SyncException(sprintf('Tried to synchronized the item (ID: %d) of an inexisting (never synchronized?) order #%d.', $data->id, $data->order_id)); } $id_form = Forms::getId($data->org_slug, $data->form_slug); if (!EM::getInstance(Form::class)->col(sprintf('SELECT id FROM @TABLE WHERE id = :id_order;'), $id_form)) { throw new SyncException(sprintf('Tried to synchronized the item (ID: %d) of an inexisting (never synchronized?) order #%d.', $data->id, $id_form)); } if (!$item->exists()) { $item->set('id', $data->id); $item->set('id_order', $data->order_id); $item->set('id_form', $id_form); } $item->set('amount', $data->amount); $item->set('state', $data->state); $item->set('type', $data->type); $item->set('person', $data->beneficiary_label ?? $data->payer_name); $item->set('label', self::generateLabel($data, (int)$item->id_form)); $item->set('custom_fields', count($data->fields) ? (object)$data->fields : null); $item->set('has_options', (int)isset($data->options)); $identifier = HA::guessUserIdentifier($data->beneficiary); if ($identifier && ($id_user = HA::getUserId($identifier))) { $item->set('id_user', $id_user); } } static protected function syncOptions(\stdClass $data, Item $item, int $accounting): array { if (!isset($data->options)) { return []; } $optionEntities = []; foreach ($data->options as $option) { $optionEntities[] = self::syncOption($option, $data, $item->id_form, $item->id, $accounting); } return $optionEntities; } static protected function syncOption(\stdClass $data, \stdClass $full_data, int $id_form, int $id_item, bool $accounting): Option { $option = EM::findOne(Option::class, 'SELECT * FROM @TABLE WHERE id_item = :id_item AND label = :name AND amount = :amount', $id_item, $data->name, $data->amount) ?? new Option; $option->set('raw_data', json_encode($data)); $data = self::transformOption($data); if (!$option->exists()) { $option->set('id_item', (int)$full_data->id); $option->set('id_order', (int)$full_data->order_id); } $option->set('amount', $data->amount); $option->set('label', $data->name ?? Forms::getName($id_form)); $option->set('custom_fields', count($data->fields) ? (object)$data->fields : null); $identifier = HA::guessUserIdentifier($full_data->beneficiary); if ($identifier && ($id_user = HA::getUserId($identifier))) { $option->set('id_user', $id_user); } $option->save(); self::handleUserRegistration($full_data, $id_form, $option, Chargeable::OPTION_TYPE); return $option; } static protected function handleAccounting(Item $item, \stdClass $data, array $optionEntities, int $accounting): void { // Creating a transaction only if payment is unique and already done (not pending) and accounts sets if ($accounting && !$item->id_transaction && (count($data->payments) === 1 && $data->payments[0]->state === Payments::AUTHORIZED_STATUS)) { if ($item->amount) { if ($data->order->formType !== 'Checkout') { // All cases except Checkout self::accountChargeable((int)$item->id_form, $item, Chargeable::TYPE_FROM_FORM[$data->order->formType], (int)$data->payments[0]->id, new \DateTime($data->payments[0]->date)); } else { if (!$payment = Payments::get((int)$data->payments[0]->id)) { throw new \RuntimeException(sprintf('Payment #%d matching checkout item #%d not found.', $data->payments[0]->id, $item->id)); } if (isset($payment->id_credit_account) && $payment->id_credit_account && $payment->id_debit_account) {// This feature will be available once the ChekoutIntent callback is fixed $transaction = self::createTransaction($item, [$payment->id_credit_account, $payment->id_debit_account], (int)$data->payments[0]->id, $payment->date); $payment->set('id_transaction', $transaction->id); } elseif (self::accountChargeable((int)$item->id_form, $item, Chargeable::TYPE_FROM_FORM[$data->order->formType], (int)$data->payments[0]->id, new \DateTime($data->payments[0]->date))) { $payment->set('id_transaction', $item->id_transaction); } $payment->save(); } } if (isset($data->options)) { foreach ($optionEntities as $option) { self::accountChargeable((int)$item->id_form, $option, Chargeable::OPTION_TYPE, (int)$data->payments[0]->id, new \DateTime($data->payments[0]->date)); } } } } static protected function handleUserRegistration(\stdClass $data, int $id_form, ChargeableInterface $entity, int $chargeable_type) { $chargeable = self::getChargeable($id_form, $entity, $chargeable_type); if (!$chargeable->register_user) { return null; } if (!$identifier = HA::guessUserIdentifier($data->beneficiary)) { throw new SyncException(sprintf( 'Commande n°%s : Impossible d\'inscrire le membre "%s". Aucun %s à lui associer comme identifiant.' . "\n" . 'Informations reçues de HelloAsso :' . "\n" . '%s' . "\n\n" . 'Soit il n\'y a pas de champ pour saisir cette information dans le formulaire HelloAsso, soit l\'utilisateur/trice n\'a pas renseigné cette information, soit l\'option "Champ utilisé pour savoir si un membre existe déjà" est mal réglée.', $data->order_id, $data->beneficiary_label, HA::USER_MATCH_TYPES[HA::getInstance()->plugin()->getConfig()->user_match_type], json_encode($data->beneficiary, JSON_UNESCAPED_UNICODE) )); } if (HA::userAlreadyExists($identifier)) { return true; } $source = [ 'id_parent' => null, self::$_nameField => HA::guessUserName($data->beneficiary), 'date_inscription' => new \DateTime($data->order->date) ]; foreach (self::$_userFieldsMap as $user_field => $api_field) { if (isset($data->beneficiary->$api_field)) $source[$user_field] = $data->beneficiary->$api_field; } $user_match_field = HA::getUserMatchField(); // The user match field may not exist (aka. not filled during the HelloAsso checkout) when the payer is also the beneficiary if (isset($data->beneficiary->{$user_match_field[2]})) { $source[$user_match_field[0]] = $data->beneficiary->{$user_match_field[2]}; } $conflict = false; if ($user_match_field[0] !== DynamicFields::getLoginField()) { $db = DB::getInstance(); $login_field = DynamicFields::getLoginField(); if (array_key_exists($login_field, $source)) { $id_user = EM::getInstance(User::class)->col(sprintf('SELECT id FROM @TABLE WHERE %s = ? COLLATE NOCASE;', $db->quoteIdentifier($login_field)), $source[$login_field]); if ($id_user) { //$conflict = true; $source[$login_field] = sprintf(self::DUPLICATE_MEMBER_PREFIX . $source[$login_field], uniqid()); //unset($source[$login_field]); } } } if (!$conflict) { $user = Users::create(); $user->importForm($source); $user->set('id_category', (int)HA::getInstance()->plugin()->getConfig()->id_category); $user->setNumberIfEmpty(); $user->save(); $id_user = (int)$user->id; } if (!$conflict) { HA::addUserToCache(HA::guessUserIdentifier($data->beneficiary), $id_user); $entity->setUserId($id_user); $entity->save(); $order = EM::findOneById(Order::class, (int)$entity->id_order); $order->set('id_user', (int)$id_user); $order->save(); return $id_user; } return null; } static protected function getChargeable(int $id_form, ChargeableInterface $entity, int $type): Chargeable { $amount = ($type === Chargeable::ONLY_ONE_ITEM_FORM_TYPE ? null : $entity->getAmount()); if ($chargeable = Chargeables::get($id_form, $type, $entity->getLabel(), $amount)) { return $chargeable; } return Chargeables::createChargeable($id_form, $entity, $type); } static protected function accountChargeable(int $id_form, ChargeableInterface $entity, int $type, int $payment_ref, \DateTime $date): bool { $chargeable = self::getChargeable($id_form, $entity, $type); if (null === $chargeable) { $chargeable = Chargeables::createChargeable($id_form, $entity, $type); } elseif ($entity->getAmount() && $chargeable->id_credit_account && $chargeable->id_debit_account) { $transaction = self::createTransaction($entity, [(int)$chargeable->id_credit_account, (int)$chargeable->id_debit_account], $payment_ref, $date); $entity->id_transaction = (int)$transaction->id; $entity->save(); return true; } return false; } static protected function transform(\stdClass $data): \stdClass { $data->id = (int) $data->id; $data->order_id = (int) $data->order->id; $data->payer_name = isset($data->payer) ? Payment::getPersonName($data->payer) : null; $data->payer_infos = isset($data->payer) ? Payment::formatPersonInfos($data->payer) : null; $data->amount = (int) $data->amount; $data->form_slug = $data->order->formSlug; $data->org_slug = $data->order->organizationSlug; $user_data = (!empty($data->user)) ? Payment::formatPersonInfos($data->user) : null; $data->fields = $user_data ?? []; if (!empty($data->customFields)) { foreach ($data->customFields as $field) { $data->fields[$field->name] = $field->answer; } } $data->beneficiary = $data->fields ? (object)array_merge($data->fields, (array)$data->user) : $data->payer; if (!isset($data->beneficiary->email) && ($data->payer->firstName === $data->beneficiary->firstName) && ($data->payer->lastName === $data->beneficiary->lastName) && !empty($data->payer->email)) { $data->beneficiary->email = $data->payer->email; } $data->beneficiary_label = isset($data->user) ? Payment::getPersonName($data->user) : null; return $data; } static protected function transformOption(\stdClass $data): \stdClass { $data->fields = []; if (!empty($data->user)) { $data->fields = Payment::formatPersonInfos($data->user); } if (!empty($data->customFields)) { foreach ($data->customFields as $field) { $data->fields[$field->name] = $field->answer; } } |
︙ | ︙ | |||
323 324 325 326 327 328 329 330 331 332 333 334 335 336 | return Forms::getName($id_form); } } else { return $data->name; } } static public function reset(): void { $sql = sprintf('DELETE FROM %s;', Item::TABLE); DB::getInstance()->exec($sql); } } | > > > > > > > > > > | 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | return Forms::getName($id_form); } } else { return $data->name; } } static protected function catchSyncException(SyncException $e): void { self::$_exceptions[] = $e; } static public function getExceptions(): array { return self::$_exceptions; } static public function reset(): void { $sql = sprintf('DELETE FROM %s;', Item::TABLE); DB::getInstance()->exec($sql); } } |
Modified helloasso/lib/Options.php from [ffcd8420f5] to [f4c97332a5].
1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Plugin\HelloAsso\Entities\Option; use Garradin\DynamicList; class Options { static public function list($for): DynamicList { $columns = [ | > | > > > > > > > > > > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Plugin\HelloAsso\Entities\Option; use Garradin\DynamicList; use Garradin\Entities\Users\User; class Options { static public function list($for): DynamicList { $columns = [ 'id' => [ 'select' => 'o.id' ], 'id_transaction' => [ 'label' => 'Écriture' ], 'amount' => [ 'label' => 'Montant', ], 'label' => [ 'label' => 'Objet', ], 'id_user' => [], 'user_numero' => [ 'select' => 'u.numero' ], 'user_name' => [ 'label' => 'Personne', 'select' => 'u.nom' ], 'custom_fields' => [ 'label' => 'Champs', ] ]; $tables = Option::TABLE . ' o LEFT JOIN ' . User::TABLE . ' u ON (u.id = o.id_user)'; $list = new DynamicList($columns, $tables); $conditions = sprintf('id_order = %d', $for->id); $list->setConditions($conditions); $list->setTitle(sprintf('Commande - %d - Items', $for->id)); |
︙ | ︙ |
Modified helloasso/lib/Orders.php from [f0e66e128b] to [4f13af925d].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Plugin\HelloAsso\Entities\Form; use Garradin\Plugin\HelloAsso\Entities\Order; use Garradin\Plugin\HelloAsso\Entities\Payment; use Garradin\Plugin\HelloAsso\API; use Garradin\DB; use Garradin\DynamicList; use Garradin\Utils; use KD2\DB\EntityManager as EM; class Orders { static public function get(int $id): ?Order { | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php namespace Garradin\Plugin\HelloAsso; use Garradin\Plugin\HelloAsso\Entities\Form; use Garradin\Plugin\HelloAsso\Entities\Order; use Garradin\Plugin\HelloAsso\Entities\Payment; use Garradin\Plugin\HelloAsso\API; use Garradin\Plugin\HelloAsso\HelloAsso as HA; use Garradin\DB; use Garradin\DynamicList; use Garradin\Utils; use Garradin\Entities\Users\User; use KD2\DB\EntityManager as EM; class Orders { static public function get(int $id): ?Order { |
︙ | ︙ | |||
69 70 71 72 73 74 75 | $list->orderBy('date', true); return $list; } static public function sync(string $org_slug): void { $params = [ | | | > > | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | $list->orderBy('date', true); return $list; } static public function sync(string $org_slug): void { $params = [ 'pageSize' => HA::getPageSize(), ]; $page_count = 1; for ($i = 1; $i <= $page_count; $i++) { $params['pageIndex'] = $i; $result = API::getInstance()->listOrganizationOrders($org_slug, $params); $page_count = $result->pagination->totalPages; foreach ($result->data as $order) { self::syncOrder($order); } if (HA::isTrial()) { break; } } } static protected function syncOrder(\stdClass $data): void { $entity = self::get($data->id) ?? new Order; $entity->set('raw_data', json_encode($data)); $data = self::transform($data); if (!$entity->exists()) { $entity->set('id', $data->id); $entity->set('id_form', Forms::getId($data->org_slug, $data->form_slug)); } $entity->set('id_user', HA::getUserId(HA::guessUserIdentifier($data->payer))); // The user may subscribe by himself/herself a long time after his/her order $entity->set('amount', $data->amount); $entity->set('status', $data->status); $entity->set('date', $data->date); $entity->set('person', $data->payer_name); $entity->save(); } static protected function transform(\stdClass $data): \stdClass { $data->id = (int) $data->id; $data->date = new \DateTime($data->date); $data->status = Order::getStatus($data); $data->payer_name = isset($data->payer) ? Payment::getPersonName($data->payer) : null; $data->payer_infos = isset($data->payer) ? Payment::formatPersonInfos($data->payer) : null; $data->amount = (int) ($data->amount->total ?? 0); $data->form_slug = $data->formSlug; $data->org_slug = $data->organizationSlug; return $data; } static public function reset(): void { $sql = sprintf('DELETE FROM %s;', Order::TABLE); DB::getInstance()->exec($sql); } } |
Modified helloasso/lib/Payments.php from [320920d0d4] to [b9dbf88c8c].
︙ | ︙ | |||
207 208 209 210 211 212 213 | $formated = clone $data; $formated->id = (int) $data->id; $formated->id_order = (int) $data->order->id ?: null; $formated->date = new \DateTime($data->date); $formated->status = HA\Payment::STATES[$data->state] ?? '--'; $formated->transferred = isset($data->cashOutState) && $data->cashOutState == HA\Payment::CASH_OUT_OK ? true : false; $formated->transfer_date = isset($data->cashOutDate) ? new \DateTime($data->cashOutDate) : null; | | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | $formated = clone $data; $formated->id = (int) $data->id; $formated->id_order = (int) $data->order->id ?: null; $formated->date = new \DateTime($data->date); $formated->status = HA\Payment::STATES[$data->state] ?? '--'; $formated->transferred = isset($data->cashOutState) && $data->cashOutState == HA\Payment::CASH_OUT_OK ? true : false; $formated->transfer_date = isset($data->cashOutDate) ? new \DateTime($data->cashOutDate) : null; $formated->payer_name = isset($data->payer) ? HA\Payment::getPersonName($data->payer) : null; $formated->payer_infos = isset($data->payer) ? HA\Payment::formatPersonInfos($data->payer) : null; $formated->form_slug = $data->order->formSlug; $formated->org_slug = $data->order->organizationSlug; return $formated; } static public function reset(): void |
︙ | ︙ |
Added helloasso/lib/SyncException.php version [aa6a0e0453].
> > > > > > > > | 1 2 3 4 5 6 7 8 | <?php namespace Garradin\Plugin\HelloAsso; class SyncException extends \RuntimeException { } |
Modified helloasso/schema.sql from [f16757826b] to [36fd2eb4f8].
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | ); CREATE TABLE IF NOT EXISTS plugin_helloasso_item_options ( id INTEGER PRIMARY KEY NOT NULL, id_item INTEGER NOT NULL REFERENCES plugin_helloasso_items(id) ON DELETE CASCADE, -- Redundant but needed by DynamicList since it does not handle JOIN statement id_order INTEGER NOT NULL REFERENCES plugin_helloasso_items(id) ON DELETE CASCADE, id_transaction INTEGER NULL REFERENCES acc_transactions(id) ON DELETE SET NULL, label TEXT NOT NULL, amount INTEGER NOT NULL, raw_data TEXT NOT NULL, custom_fields TEXT NULL ); CREATE TABLE IF NOT EXISTS plugin_helloasso_chargeables ( id INTEGER PRIMARY KEY NOT NULL, id_form INTEGER NOT NULL REFERENCES plugin_helloasso_forms(id) ON DELETE CASCADE, | > | | > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | ); CREATE TABLE IF NOT EXISTS plugin_helloasso_item_options ( id INTEGER PRIMARY KEY NOT NULL, id_item INTEGER NOT NULL REFERENCES plugin_helloasso_items(id) ON DELETE CASCADE, -- Redundant but needed by DynamicList since it does not handle JOIN statement id_order INTEGER NOT NULL REFERENCES plugin_helloasso_items(id) ON DELETE CASCADE, id_user INTEGER NULL REFERENCES users(id) ON DELETE SET NULL, id_transaction INTEGER NULL REFERENCES acc_transactions(id) ON DELETE SET NULL, label TEXT NOT NULL, amount INTEGER NOT NULL, raw_data TEXT NOT NULL, custom_fields TEXT NULL ); CREATE TABLE IF NOT EXISTS plugin_helloasso_chargeables ( id INTEGER PRIMARY KEY NOT NULL, id_form INTEGER NOT NULL REFERENCES plugin_helloasso_forms(id) ON DELETE CASCADE, id_item INTEGER NULL REFERENCES plugin_helloasso_items(id) ON DELETE SET NULL, id_credit_account INTEGER NULL REFERENCES acc_accounts (id) ON DELETE SET NULL, id_debit_account INTEGER NULL REFERENCES acc_accounts (id) ON DELETE SET NULL, type INTEGER NOT NULL, label TEXT NOT NULL, amount INTEGER NULL, register_user UNSIGNED INTEGER NOT NULL ); CREATE UNIQUE INDEX IF NOT EXISTS plugin_helloasso_chargeables_key ON plugin_helloasso_chargeables(id_form, id_item, type, label, amount); CREATE INDEX IF NOT EXISTS plugin_helloasso_chargeables_get ON plugin_helloasso_chargeables(id_form, label, amount); /* CREATE TABLE IF NOT EXISTS plugin_helloasso_options ( id INTEGER PRIMARY KEY NOT NULL, id_order INTEGER NOT NULL REFERENCES plugin_helloasso_orders(id) ON DELETE CASCADE, hash TEXT NOT NULL, label TEXT NOT NULL, |
︙ | ︙ |
Modified helloasso/templates/_chargeables_list.tpl from [5360b872d4] to [b13377d9e6].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | {include file="common/dynamic_list_head.tpl"} {assign var='chargeable_need_config' value=false} {foreach from=$list->iterate() item="row"} <tr {if $plugin.config.accounting && (!$row.id_credit_account || !$row.id_debit_account)}class="awaits_account_configuration"{/if}> <td class="num"><a href="{"chargeable.php?id=%s"|args:$row.id}">{$row.id}</a></td> <td>{$row.type_label}</td> <td>{$row.label}</td> <td class="money">{$row.amount|money_currency|raw}</td> <td class="num"><a href="{$admin_url}acc/accounts/journal.php?id={$row.id_credit_account|intval}">{$row.credit_account}</a></td> <td class="num"><a href="{$admin_url}acc/accounts/journal.php?id={$row.id_debit_account|intval}">{$row.debit_account}</a></td> {* Not yet supported {if property_exists($row, 'custom_fields')} <td> {if $row.custom_fields} | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | {include file="common/dynamic_list_head.tpl"} {assign var='chargeable_need_config' value=false} {foreach from=$list->iterate() item="row"} <tr {if $plugin.config.accounting && (!$row.id_credit_account || !$row.id_debit_account)}class="awaits_account_configuration"{/if}> <td class="num"><a href="{"chargeable.php?id=%s"|args:$row.id}">{$row.id}</a></td> <td>{$row.type_label}</td> <td>{$row.label}</td> <td class="money">{$row.amount|money_currency|raw}</td> <td>{$row.register_user}</td> <td class="num"><a href="{$admin_url}acc/accounts/journal.php?id={$row.id_credit_account|intval}">{$row.credit_account}</a></td> <td class="num"><a href="{$admin_url}acc/accounts/journal.php?id={$row.id_debit_account|intval}">{$row.debit_account}</a></td> {* Not yet supported {if property_exists($row, 'custom_fields')} <td> {if $row.custom_fields} |
︙ | ︙ |
Modified helloasso/templates/_items_list.tpl from [c8cdff8228] to [47e5f8f5bd].
1 2 3 4 5 6 | {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="row"} <tr> | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="row"} <tr> <td class="num"><a href="chargeable.php?id={$row.id_chargeable}">{$row.id_chargeable}</a></td> <td class="num"><a href="{$admin_url}acc/transactions/details.php?id={$row.id_transaction}">{$row.id_transaction}</a></td> <td class="money">{$row.amount|money_currency|raw}</td> <td>{$row.type}</td> <td>{$row.label}</td> <td class="num">{$row.person}</td> <td class="num">{if $row.id_user}{$row.user_name} <a href="{$admin_url}users/details.php?id={$row.id_user}">{$row.numero}</a>{/if}</td> <td>{$row.options|escape|nl2br}</td> {if property_exists($row, 'custom_fields')} <td> {if $row.custom_fields} <table> {foreach from=$row.custom_fields item="value" key="name"} <tr> |
︙ | ︙ | |||
34 35 36 37 38 39 40 | {/foreach} </tbody> </table> | > > > > | 35 36 37 38 39 40 41 42 43 44 45 | {/foreach} </tbody> </table> <p class="help block"> * Est différent de la "personne" si il y a un doute que le/la payeur/euse soit la même personne (ex: courriel différent). </p> |
Modified helloasso/templates/_options_list.tpl from [a3c0446f66] to [757513acdf].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="row"} <tr> <td class="num"><a href="{$admin_url}acc/transactions/details.php?id={$row.id_transaction}">{$row.id_transaction}</a></td> <td class="money">{$row.amount|money_currency|raw}</td> <td>{$row.label}</td> <td>{$row.options|escape|nl2br}</td> {if property_exists($row, 'custom_fields')} <td> {if $row.custom_fields} <table> {foreach from=$row.custom_fields item="value" key="name"} <tr> | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="row"} <tr> <td class="num"><a href="{$admin_url}acc/transactions/details.php?id={$row.id_transaction}">{$row.id_transaction}</a></td> <td class="money">{$row.amount|money_currency|raw}</td> <td>{$row.label}</td> <td class="num">{if $row.id_user}{$row.user_name} <a href="{$admin_url}users/details.php?id={$row.id_user}">{$row.user_numero}</a>{/if}</td> <td>{$row.options|escape|nl2br}</td> {if property_exists($row, 'custom_fields')} <td> {if $row.custom_fields} <table> {foreach from=$row.custom_fields item="value" key="name"} <tr> |
︙ | ︙ |
Modified helloasso/templates/_payments_list.tpl from [d99bdac14c] to [20ff8a2294].
1 2 3 4 5 6 | {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="row"} <tr> <td class="num"><a href="payment.php?id={$row.id}">{$row.reference}</a></td> <td class="num"> | > | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="row"} <tr> <td class="num"><a href="payment.php?id={$row.id}">{$row.reference}</a></td> <td class="num"> {if $row.transactions} {foreach from=$row.transactions item="id_transaction"} {link href="!acc/transactions/details.php?id=%d"|args:$id_transaction label="#%d"|args:$id_transaction} {/foreach} {/if} </td> <td>{$row.label}</td> <td>{$row.date|date}</td> <td class="money">{$row.amount|money_currency|raw}</td> <td> {if $row.id_author && $row.author} <a href="{$admin_url}users/details.php?id={$row.author.id|intval}">{$row.author.nom}</a> |
︙ | ︙ |
Modified helloasso/templates/chargeable.tpl from [17797400d2] to [2ce08d7dec].
︙ | ︙ | |||
35 36 37 38 39 40 41 | {else} En fonctionnement. {/if} </dd> {/if} </dl> | < | > > > > > > > > | | | | | < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | {else} En fonctionnement. {/if} </dd> {/if} </dl> <form method="post" action="{$self_url}"> <fieldset> <legend>Options</legend> <dl> {input type="checkbox" name="register_user" value="1" label="Inscrire comme membre" source=$chargeable help="Inscrira automatiquement la personne comme membre Paheko si cet article est commandé."} </dl> </fieldset> {if $plugin->config->accounting} <fieldset> <legend>Comptabilité</legend> <dl> {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'6':$chart_id name="credit" label="Type de recette" required=true default=$credit_account} {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'1:2:3':$chart_id name="debit" label="Compte d'encaissement" required=true default=$debit_account} </dl> <p class="help block">Cette modification impacte uniquement les <em>futures</em> synchronisations. Elle n'est pas rétro-active.</p> </fieldset> {/if} <p class="submit"> {csrf_field key=$csrf_key} {button type="submit" class="main" name="save" label="Enregistrer" shape="right"} </p> </form> {if $TECH_DETAILS} <dl style="background-color: black; color: limegreen; padding-top: 0.8em;" class="describe"> <dt style="color: limegreen;">item</dt> <dd><pre>{if $chargeable->id_item}{$parent_item|var_dump}{else}NULL{/if}</pre></dd> <dt style="color: limegreen;">item->raw_data</dt> <dd><pre>{if $chargeable->id_item}{$parent_item->raw_data|json_revamp}{else}NULL{/if}</pre></dd> </dl> {/if} {include file="_foot.tpl"} |
Modified helloasso/templates/config.tpl from [f6abb1cd1b] to [2bd85c7123].
︙ | ︙ | |||
11 12 13 14 15 16 17 | {form_errors} <form method="post" action="{$self_url}"> <fieldset> <legend>Correspondance des membres</legend> <dl> | | > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | {form_errors} <form method="post" action="{$self_url}"> <fieldset> <legend>Correspondance des membres</legend> <dl> {input type="select" options=$match_options name="match_email_field" source=$plugin.config required=true label="Champ utilisé pour savoir si un membre existe déjà"} </dl> <dl> {foreach from=$payer_fields key='field' item='label'} {input type="select" name="payer_map[%s]"|args:$field label=$label options=$dynamic_fields required=true} {/foreach} </dl> </fieldset> <p class="submit"> {csrf_field key=$csrf_key} {button type="submit" class="main" name="save" label="Enregistrer" shape="right"} </p> </form> {include file="_foot.tpl"} |
Modified helloasso/templates/config_client.tpl from [9ae9aa18e9] to [5f03186899].
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <p class="help block">Cette option n'est pas définitive et pourra être changée plus tard.</p> <dl> {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'6':$chart_id name="default_credit" label="Type de recette par défaut" required=false default=$default_credit_account help="Sera proposé par défaut pour vous faire gagner du temps lors de vos saisies."} {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'1:2:3':$chart_id name="default_debit" label="Compte d'encaissement par défaut" required=false default=$default_debit_account} </dl> </fieldset> <p class="submit"> {csrf_field key=$csrf_key} {button type="submit" class="main" name="save" label="Enregistrer" shape="right"} </p> </form> {include file="_foot.tpl"} | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | <p class="help block">Cette option n'est pas définitive et pourra être changée plus tard.</p> <dl> {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'6':$chart_id name="default_credit" label="Type de recette par défaut" required=false default=$default_credit_account help="Sera proposé par défaut pour vous faire gagner du temps lors de vos saisies."} {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'1:2:3':$chart_id name="default_debit" label="Compte d'encaissement par défaut" required=false default=$default_debit_account} </dl> </fieldset> <fieldset> <legend>Correspondance des membres</legend> <dl> {input type="select" options=$user_match_fields name="user_match_type" source=$plugin.config required=true label="Champ utilisé pour savoir si un membre existe déjà"} <span class="user_match_field"> {input type="text" name="user_match_field" label='Intitulé du champ HelloAsso correspondant à "%s"'|args:$user_match_fields[1] source=$plugin.config help='Dans la section "Informations relatives à vos tarifs" de la configuration de votre formulaire HelloAsso.'} </span> {input type="select" name="id_category" label="Catégorie" options=$category_options required=true default=$plugin.config.id_category help="Catégorie dans laquelle les membres automatiquement inscrit·e·s seront ajouté·e·s."} {input type="select" name="payer_map[name]" label="Ordre de fusion des champs nom et prénom" options=$merge_names_options required=true default=$plugin.config.payer_map.name} </dl> </fieldset> <fieldset> <legend>Correspondance des payeur/euse.s</legend> <p class="help block"> HelloAsso fournit les informations suivantes sur le/la payeur/euse. Choisissez comment vous souhaitez les lier à Paheko. </p> <dl> {input type="select" name="payer_map[email]" label="Courriel" options=$email_fields required=true default=$plugin.config.payer_map.email} {foreach from=$payer_fields key='field' item='label'} {assign var='source' value=$plugin.config.payer_map} {input type="select" name="payer_map[%s]"|args:$field label=$label options=$dynamic_fields required=true default=$source->$field} {/foreach} </dl> </fieldset> <p class="submit"> {csrf_field key=$csrf_key} {button type="submit" class="main" name="save" label="Enregistrer" shape="right"} </p> </form> <script type="text/javascript"> {literal} (function () { g.toggle('.user_match_field', $('#f_user_match_type').value === '1'); $('#f_user_match_type').onchange = () => { g.toggle('.user_match_field', $('#f_user_match_type').value === '1'); }; })(); {/literal} </script> {include file="_foot.tpl"} |
Modified helloasso/templates/order.tpl from [8e14549a34] to [406a75ad3e].
1 2 3 4 5 6 7 8 | {include file="_head.tpl" title="Commande n°%s — %s"|args:$order.id,$order.person} {include file="./_menu.tpl" current="home"} <h2 class="ruler">Informations de la commande</h2> <dl class="describe"> <dt>Personne</dt> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {include file="_head.tpl" title="Commande n°%s — %s"|args:$order.id,$order.person} {include file="./_menu.tpl" current="home"} <h2 class="ruler">Informations de la commande</h2> <dl class="describe"> <dt>Personne</dt> <dd class="num">{if $order.id_user}{$user->nom} <a href="{$admin_url}users/details.php?id={$user->id|intval}">{$user->numero}</a>{else}{$order.person}{/if}</dd> <dt>Référence</dt> <dd>{$order.id}</dd> <dt>Montant total</dt> <dd>{$order.amount|money_currency|raw}</dd> <dt>Date</dt> <dd>{$order.date|date}</dd> <dt>Statut</dt> |
︙ | ︙ |
Modified helloasso/templates/sync.tpl from [6e9a2cf774] to [f25a627dd7].
1 2 3 4 5 6 7 8 9 10 11 12 | {include file="_head.tpl" title="HelloAsso"} {include file="%s/templates/_menu.tpl"|args:$plugin_root current="sync"} {if $_GET.ok} {if $_GET.ok == 1 && (!$plugin->config->accounting || ($plugin->config->accounting && !$chargeables))} <p class="confirm block">Synchronisation effectuée avec succès.</p> {/if} {/if} {if $plugin->config->accounting} {if $chargeables} | > > > > > > > > > | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | {include file="_head.tpl" title="HelloAsso"} {include file="%s/templates/_menu.tpl"|args:$plugin_root current="sync"} {if $_GET.ok} {if $_GET.ok == 1 && (!$plugin->config->accounting || ($plugin->config->accounting && !$chargeables))} <p class="confirm block">Synchronisation effectuée avec succès.</p> {/if} {/if} {if isset($exceptions)} <p class="alert block"> Les erreurs suivantes sont survenues durant la synchronisation.<br />Les autres entrées ont été synchronisées normalement. </p> {foreach from=$exceptions item='e'} <p class="error block">{$e->getMessage()|escape|nl2br}</p> {/foreach} {/if} {if $plugin->config->accounting} {if $chargeables} <form method="POST" action="{$self_url_no_qs}"> <p class="alert block"> {if !$default_debit_account && !$default_credit_account} Pour pouvoir synchroniser la comptabilité, merci de renseigner les types de recette et comptes d'encaissement pour les articles suivants : {else} Pour pouvoir synchroniser la comptabilité, merci de confirmer les types de recette et comptes d'encaissement pré-remplis pour les articles suivants : {/if} </p> {foreach from=$chargeables key='form_name' item='form'} <fieldset> <legend>{if $form_name === 'Checkout'}Paiements isolés{else}{$form_name}{/if}</legend> {foreach from=$form item='chargeable'} {if $chargeable.type !== Plugin\HelloAsso\Entities\Chargeable::ONLY_ONE_ITEM_FORM_TYPE} <fieldset> <legend> {/if} {if $chargeable.type === Plugin\HelloAsso\Entities\Chargeable::CHECKOUT_TYPE} {$chargeable->label} {elseif $chargeable.type !== Plugin\HelloAsso\Entities\Chargeable::ONLY_ONE_ITEM_FORM_TYPE} {if $chargeable.type === Plugin\HelloAsso\Entities\Chargeable::OPTION_TYPE}"{$chargeable->getItem_name()}" option {/if}"{$chargeable.label}" {$chargeable.amount|escape|money_currency} {/if} </legend> <dl> {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'6':$chart_id name="chargeable_credit[%d]"|args:$chargeable.id label="Type de recette" required=1 default=$default_credit_account} {input type="list" target="!acc/charts/accounts/selector.php?targets=%s&chart=%d"|args:'1:2:3':$chart_id name="chargeable_debit[%d]"|args:$chargeable.id label="Compte d'encaissement" required=1 default=$default_debit_account} {input type="checkbox" name="register_user[%d]"|args:$chargeable.id value="1" label="Inscrire comme membre" source=$chargeable help="Inscrira automatiquement la personne comme membre Paheko si cet article est commandé."} </dl> {if $chargeable.type !== Plugin\HelloAsso\Entities\Chargeable::ONLY_ONE_ITEM_FORM_TYPE} </fieldset> {/if} {/foreach} </fieldset> {/foreach} |
︙ | ︙ |