Commit 5dc0e526 by Damien Moulard

Paiement par CB: achat de monnaie & cotisations

parent 6c790f14
......@@ -33,3 +33,11 @@ CORS_ALLOW_ORIGIN=^https?://localhost(:[0-9]+)?$
#JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
#JWT_PASSPHRASE=2162f52d0600275e618fccd274c080f2
###< lexik/jwt-authentication-bundle ###
## PAYUM GATEWAYS CONFIGURATION ##
###> payum-payzen ###
PAZEN_SITE_ID=ChangeMeWithYourPayzenCredentials
PAYZEN_CERTIFICATE=ChangeMeWithYourPayzenCredentials
PAYZEN_CTX_MODE=PRODUCTION
PAYZEN_DEBUG=false
###< payum-payzen ###
......@@ -35,3 +35,7 @@ yarn-error.log
/mlc.test-access.log
/mlc.test-error.log
###< symfony/webpack-encore-bundle ###
###> payum ###
/transactions/
###< payum ###
......@@ -14,29 +14,35 @@
"php": "^7.4",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-intl" : "*",
"ext-intl": "*",
"api-platform/api-pack": "^1.2",
"beberlei/doctrineextensions": "^1.2",
"doctrine/annotations": "^1.8",
"doctrine/migrations": "^3.0",
"doctrine/doctrine-fixtures-bundle": "^3.0",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/migrations": "^3.0",
"ekyna/payum-payzen": "@dev",
"friendsofsymfony/user-bundle": "^2.1",
"geocoder-php/cache-provider": "^4.1",
"geocoder-php/google-maps-provider": "^4.3",
"geocoder-php/nominatim-provider": "^5.0",
"hautelook/alice-bundle": "^2.3",
"knplabs/knp-paginator-bundle": "^2.8",
"lexik/translation-bundle": "~4.0",
"liip/imagine-bundle": "^2.1",
"nelmio/api-doc-bundle": "^3.3",
"payum/offline": "^1.6",
"payum/payum-bundle": "^2.4",
"php-http/guzzle6-adapter": "^2.0",
"php-http/message": "^1.7",
"pixassociates/sortable-behavior-bundle": "^1.5",
"prodigious/sonata-menu-bundle": "^3.0",
"sensio/framework-extra-bundle": "^5.1",
"sensiolabs/security-checker": "^5.0",
"sonata-project/admin-bundle": "^3.65",
"sonata-project/block-bundle": "^3.18",
"sonata-project/core-bundle": "^3.18",
"sonata-project/classification-bundle": "^3.11",
"sonata-project/core-bundle": "^3.18",
"sonata-project/doctrine-orm-admin-bundle": "^3.6",
"sonata-project/easy-extends-bundle": "^2.5",
"sonata-project/formatter-bundle": "^4.1",
......@@ -49,6 +55,7 @@
"symfony/asset": "4.4.*",
"symfony/cache": "4.4.*",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/expression-language": "4.4.*",
"symfony/flex": "^1.1",
"symfony/form": "4.4.*",
......@@ -67,11 +74,7 @@
"symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "4.4.*",
"vich/uploader-bundle": "^1.8",
"willdurand/geocoder-bundle": "^5.0",
"doctrine/doctrine-fixtures-bundle": "^3.0",
"symfony/dotenv": "4.4.*",
"sensiolabs/security-checker": "^5.0",
"hautelook/alice-bundle": "^2.3"
"willdurand/geocoder-bundle": "^5.0"
},
"require-dev": {
"symfony/browser-kit": "4.4.*",
......@@ -126,8 +129,14 @@
},
"extra": {
"symfony": {
"allow-contrib": false,
"allow-contrib": true,
"require": "4.4.*"
}
},
"repositories": [
{
"type": "vcs",
"url": "https://damienmoulard:7748456c803670933eaa313cff6837eeb84273a2@github.com/damienmoulard/PayumPayzen"
}
]
}
......@@ -49,4 +49,5 @@ return [
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Sonata\ClassificationBundle\SonataClassificationBundle::class => ['all' => true],
App\Application\Sonata\ClassificationBundle\ApplicationSonataClassificationBundle::class => ['all' => true],
Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true],
];
payum:
storages:
App\Entity\Payment: { doctrine: orm }
security:
token_storage:
App\Entity\PaymentToken: { doctrine: orm }
gateways:
offline:
factory: offline
payzen:
factory: payzen
site_id: '%env(PAZEN_SITE_ID)%'
certificate: '%env(PAYZEN_CERTIFICATE)%' # Clé de TEST ou PRODUCTION
ctx_mode: '%env(PAYZEN_CTX_MODE)%' # TEST ou PRODUCTION
directory: '%kernel.project_dir%/transactions'
debug: '%env(bool:PAYZEN_DEBUG)%'
......@@ -236,6 +236,7 @@ sonata_admin:
items:
- admin.flux.gerer
- admin.all.cotisations
- admin.all.achats_monnaie
- admin.transfert.gerer
- admin.transaction.gerer
- admin.reconversion.gerer
......
......@@ -30,3 +30,6 @@ app.swagger_ui:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
payum_all:
resource: "@PayumBundle/Resources/config/routing/all.xml"
......@@ -167,6 +167,14 @@ services:
calls:
- [setManager, ['@doctrine.orm.entity_manager']]
app.payzen_gateway_factory:
class: Payum\Core\Bridge\Symfony\Builder\GatewayFactoryBuilder
arguments: [Ekyna\Component\Payum\Payzen\PayzenGatewayFactory]
tags:
- { name: payum.gateway_factory_builder, factory: payzen }
###### Configuration de l'admin ######
admin.block.dashboard:
class: App\Block\DashboardKohinosBlock
arguments:
......@@ -174,8 +182,6 @@ services:
tags:
- { name: sonata.block }
###### Configuration de l'admin ######
admin.adherent.gerer:
class: App\Admin\AdherentAdmin
# arguments: [~, App\Entity\OBJECT, 'PixSortableBehaviorBundle:SortableAdmin']
......@@ -206,6 +212,18 @@ services:
calls:
- [ setSecurity, ['@security.helper']]
admin.all.achats_monnaie:
class: App\Admin\AchatMonnaieAdmin
arguments: [~, App\Entity\AchatMonnaie, ~]
tags:
- name: sonata.admin
manager_type: orm
group: "Flux"
label: "Achats de monnaie"
public: true
calls:
- [ setSecurity, ['@security.helper']]
admin.adherent.cotisations:
class: App\Admin\CotisationAdherentAdmin
arguments: [~, App\Entity\CotisationAdherent, ~]
......@@ -364,7 +382,7 @@ services:
pager_type: "simple"
public: true
calls:
- [ setSubClasses, [{transaction: 'App\Entity\Transaction', transfert: 'App\Entity\Transfert', cotisation: 'App\Entity\Cotisation'}]]
- [ setSubClasses, [{transaction: 'App\Entity\Transaction', transfert: 'App\Entity\Transfert', cotisation: 'App\Entity\Cotisation', achat_monnaie: 'App\Entity\AchatMonnaie'}]]
- [ setSecurity, ['@security.helper']]
admin.transfert.gerer:
......
<?php
namespace App\Admin;
use App\Entity\User;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Security\Core\Security;
/**
* Administration des flux 'Achat de monnaie'
*
* KOHINOS : Outil de gestion de Monnaie Locale Complémentaire
* @author Damien Moulard <dam.moulard@gmail.com>
*/
class AchatMonnaieAdmin extends AbstractAdmin
{
protected $baseRouteName = 'achat_monnaie';
protected $baseRoutePattern = 'achat_monnaie';
protected $security;
protected $translator;
protected $datagridValues = [
'_sort_order' => 'DESC',
'_sort_by' => 'createdAt',
];
public function setSecurity(Security $security)
{
$this->security = $security;
}
/**
* {@inheritdoc}
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{
$datagridMapper->add('type', null, array(
'advanced_filter' => false,
'show_filter' => true,
'field_type' => ChoiceType::class,
'field_options' => array(
'choices' => array('Adhérent' => 'achat_monnaie_adherent', 'Prestataire' => 'achat_monnaie_prestataire'),
'placeholder' => 'Indifférent',
'expanded' => true,
'multiple' => false
)
));
}
/**
* {@inheritdoc}
*/
protected function configureFormFields(FormMapper $formMapper)
{
}
protected function configureRoutes(RouteCollection $collection)
{
$collection->remove('delete');
if ($this->security->getUser() != null && !($this->security->getUser()->isGranted('ROLE_TRESORIER') || $this->security->getUser()->isGranted('ROLE_SUPER_ADMIN') || $this->security->getUser()->isGranted('ROLE_COMPTOIR'))) {
$collection->clearExcept(array('list', 'export'));
}
}
/**
* {@inheritdoc}
*/
protected function configureListFields(ListMapper $listMapper)
{
unset($this->listModes['mosaic']);
$listMapper
->add('createdAt', 'datetime', array('label' => 'Date'))
->add('montant', null, array('label' => 'Montant'))
->add('destinataire', null, array('label' => 'Destinataire'))
->add('operateur', null, array('label' => 'Operateur'))
->add('reference', null, array('label' => 'Reference'))
;
}
}
......@@ -81,7 +81,7 @@ class FluxAdmin extends AbstractAdmin
'show_filter' => true,
'field_type' => SChoiceType::class,
'field_options' => array(
'choices' => array('Transactions' => 'transaction', 'Transferts' => 'transfert', 'Cotisations' => 'cotisation'),
'choices' => array('Transactions' => 'transaction', 'Transferts' => 'transfert', 'Cotisations' => 'cotisation', 'Achat de monnaie' => 'achat'),
'placeholder' => 'Indifférent',
'expanded' => true,
'multiple' => false
......
......@@ -8,6 +8,7 @@ use App\Entity\Geoloc;
use App\Entity\TransactionAdherentAdherent;
use App\Entity\TransactionAdherentPrestataire;
use App\Entity\AchatMonnaieAdherent;
use App\Entity\Payment;
use App\Entity\Usergroup;
use App\Form\Type\AdherentInfosFormType;
use App\Form\Type\AdhererFormType;
......@@ -104,18 +105,19 @@ class UserAdherentController extends FluxController
}
$entity = new AchatMonnaieAdherent();
$entity->setReference("Achat Monnaie en CB");
$form = $this->createForm(AchatMonnaieAdherentFormType::class, $entity);
$form->handleRequest($request);
//TODO custom form handling -> redirect to payzen or other mean of payment
return $this->redirectToRoute('index');
return $this->manageFluxForm(
$request,
if ($form->isSubmitted() && $form->isValid()) {
return $this->preparePaymentAction(
$form,
$this->getUser()->getAdherent()->getCompte(),
$this->translator->trans('Achat de monnaie locale bien effectuée !'),
$this->translator->trans('Achat de monnaie locale')
Payment::TYPE_ACHAT_MONNAIE_ADHERENT
);
}
return $this->render('flux/transaction.html.twig', [
'form' => $form->createView(),
'title' => $this->translator->trans('Achat de monnaie locale')
]);
}
}
......@@ -5,6 +5,7 @@ namespace App\Controller;
use App\Entity\User;
use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\Payment;
use App\Enum\MoyenEnum;
use App\Form\Type\CotiserFormType;
use App\Form\Type\UserInfosFormType;
......@@ -37,10 +38,13 @@ class UserController extends AbstractController
public function cotiserAction(Request $request)
{
$options = [];
$payment_type = '';
if ($this->security->getUser()->isGranted('ROLE_ADHERENT')) {
$options['data_class'] = CotisationAdherent::class;
$payment_type = Payment::TYPE_COTISATION_ADHERENT;
} elseif ($this->security->getUser()->isGranted('ROLE_PRESTATAIRE')) {
$options['data_class'] = CotisationPrestataire::class;
$payment_type = Payment::TYPE_COTISATION_PRESTA;
}
$form = $this->createForm(CotiserFormType::class, null, $options);
......@@ -65,7 +69,11 @@ class UserController extends AbstractController
);
return $this->redirectToRoute('index');
} else {
//@TODO : redirect to payment page
// Redirect to payment page
return $this->forward('App\Controller\FluxController::preparePaymentAction', [
'form' => $form,
'type' => $payment_type
]);
}
} else {
$this->addFlash(
......
......@@ -9,6 +9,7 @@ use App\Entity\TransactionPrestataireAdherent;
use App\Entity\TransfertPrestataireSiege;
use App\Entity\TypePrestataire;
use App\Entity\AchatMonnaiePrestataire;
use App\Entity\Payment;
use App\Form\Type\GroupePrestataireInscriptionFormType;
use App\Form\Type\PrestataireInfosFormType;
use App\Form\Type\TransactionPrestataireAdherentFormType;
......@@ -135,21 +136,24 @@ class UserPrestataireController extends FluxController
if (empty($this->getUser()) || empty($this->session->get('_prestagere'))) {
return $this->redirectToRoute('index');
}
$entity = new AchatMonnaiePrestataire();
$form = $this->createForm(AchatMonnaiePrestataireFormType::class, $entity);
$form->handleRequest($request);
///TODO custom form handling -> redirect to payzen or other mean of payment
return $this->redirectToRoute('index');
return $this->manageFluxForm(
$request,
if ($form->isSubmitted() && $form->isValid()) {
return $this->preparePaymentAction(
$form,
$this->session->get('_prestagere'),
$this->translator->trans('Achat de monnaie locale bien effectuée !'),
$this->translator->trans('Achat de monnaie locale')
Payment::TYPE_ACHAT_MONNAIE_PRESTA
);
}
return $this->render('flux/transaction.html.twig', [
'form' => $form->createView(),
'title' => $this->translator->trans('Achat de monnaie locale')
]);
}
/**
* Export all transferts / transactions for prestataire
*
......
......@@ -44,8 +44,8 @@ class Cotisation extends Flux
// throw new \Exception("[FLUX] Opération impossible ! Prestataire recevant la monnaie locale non configuré !");
// }
// $destinataire = $destinataires[0];
$compteExp = $this->getExpediteur()->getEcompte() - $this->getMontant();
if ($this->getMoyen() == MoyenEnum::MOYEN_MLC) {
$compteExp = $this->getExpediteur()->getEcompte() - $this->getMontant();
if ($compteExp < 0) {
throw new \Exception("[FLUX] Opération impossible ! Montant supérieur au solde de monnaie éléctronique !");
} else {
......@@ -55,6 +55,7 @@ class Cotisation extends Flux
return [$this->getExpediteur(), $this->getDestinataire()];
}
}
// Pas d'opération si la cotisation se fait par CB
return [];
}
......
......@@ -13,7 +13,7 @@ trait HasEcompteEntity
* Compte de MLC numérique
* @var int
*
* @ORM\Column(name="ecompte", type="decimal", precision=12, scale=2)
* @ORM\Column(name="ecompte", type="decimal", precision=12, scale=2, options={"default" : 0})
* @Groups({"read"})
*/
private $ecompte = 0;
......
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Payment as BasePayment;
/**
* @ORM\Entity(repositoryClass="App\Repository\PaymentRepository")
* @ORM\Table(name="payment")
*/
class Payment extends BasePayment
{
const TYPE_ACHAT_MONNAIE_ADHERENT = 'achat_monnaie_adherent';
const TYPE_ACHAT_MONNAIE_PRESTA = 'achat_monnaie_presta';
const TYPE_COTISATION_ADHERENT = 'cotisation_adherent';
const TYPE_COTISATION_PRESTA = 'cotisation_presta';
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*
* @var integer $id
*/
protected $id;
/**
* @var string|null
*
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $status;
/**
* @var string|null
* JSON array of 'Flux' to persist if payment valid
*
* @ORM\Column(type="text", nullable=true)
*/
protected $flux_data;
/**
* @return string
*/
public function getStatus(): ?string
{
return $this->status;
}
/**
* @param string $status
* @return Payment
*/
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
/**
* @return string
*/
public function getFluxData(): ?string
{
return $this->flux_data;
}
/**
* @param string $flux_data
* @return Payment
*/
public function setFluxData(string $flux_data): self
{
$this->flux_data = $flux_data;
return $this;
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Token;
/**
* @ORM\Entity
* @ORM\Table(name="payment_token")
*/
class PaymentToken extends Token
{
}
......@@ -10,7 +10,7 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Entity(repositoryClass="App\Repository\SiegeRepository")
* @ORM\Table(name="siege")
*/
class Siege
......
......@@ -23,7 +23,7 @@ class AchatMonnaieAdherentFormType extends AchatMonnaieFormType
'em' => $this->em
))
->add('reference', HiddenType::class, array(
'data' => 'Achat monnaie en CB'
'data' => 'Achat monnaie en CB Adhérent'
))
->add('save', SubmitType::class, ['label' => "Payer en CB"])
;
......
......@@ -4,6 +4,7 @@ namespace App\Form\Type;
use App\Entity\Prestataire;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
......@@ -22,8 +23,9 @@ class AchatMonnaiePrestataireFormType extends AchatMonnaieFormType
'em' => $this->em
))
->add('reference', HiddenType::class, array(
'data' => 'Achat monnaie en CB'
'data' => 'Achat monnaie en CB Prestataire'
))
->add('save', SubmitType::class, ['label' => "Payer en CB"])
;
}
......
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20200626122137 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE payment (id INT AUTO_INCREMENT NOT NULL, number VARCHAR(255) DEFAULT NULL, description VARCHAR(255) DEFAULT NULL, client_email VARCHAR(255) DEFAULT NULL, client_id VARCHAR(255) DEFAULT NULL, total_amount INT DEFAULT NULL, currency_code VARCHAR(255) DEFAULT NULL, details LONGTEXT NOT NULL COMMENT \'(DC2Type:json_array)\', status VARCHAR(50) DEFAULT NULL, flux_data LONGTEXT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_general_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE payment_token (hash VARCHAR(255) NOT NULL, details LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:object)\', after_url LONGTEXT DEFAULT NULL, target_url LONGTEXT NOT NULL, gateway_name VARCHAR(255) NOT NULL, PRIMARY KEY(hash)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_general_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE adherent CHANGE ecompte ecompte NUMERIC(12, 2) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE prestataire CHANGE ecompte ecompte NUMERIC(12, 2) DEFAULT \'0\' NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE payment');
$this->addSql('DROP TABLE payment_token');
$this->addSql('ALTER TABLE adherent CHANGE ecompte ecompte NUMERIC(12, 2) NOT NULL');
$this->addSql('ALTER TABLE prestataire CHANGE ecompte ecompte NUMERIC(12, 2) NOT NULL');
}
}
<?php
namespace App\Repository;
use App\Entity\Payment;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
/**
* @method Siege|null find($id, $lockMode = null, $lockVersion = null)
* @method Siege|null findOneBy(array $criteria, array $orderBy = null)
* @method Siege[] findAll()
* @method Siege[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PaymentRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Payment::class);
}
/**
* @param int $id User id
*
* @return Payment|null Returns user's last payment
*/
public function getUserLastPayment($id) {
$results = $this->findBy(
array('clientId' => $id),
array('id'=>'DESC'),
1,
0
);
if (empty($results)) {
return null;
} else {
return $results[0];
}
}
}
<?php
namespace App\Repository;
use App\Entity\Siege;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
/**
* @method Siege|null find($id, $lockMode = null, $lockVersion = null)
* @method Siege|null findOneBy(array $criteria, array $orderBy = null)
* @method Siege[] findAll()
* @method Siege[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class SiegeRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Siege::class);
}
}
......@@ -107,6 +107,9 @@
"egulias/email-validator": {
"version": "2.1.6"
},
"ekyna/payum-payzen": {
"version": "1.5.x-dev"
},
"exsyst/swagger": {
"version": "v0.4.1"
},
......@@ -248,6 +251,27 @@
"lcobucci/jwt": {
"version": "3.3.1"
},
"league/uri": {
"version": "5.3.0"
},
"league/uri-components": {
"version": "1.8.2"
},
"league/uri-hostname-parser": {
"version": "1.1.1"
},
"league/uri-interfaces": {
"version": "1.1.1"
},
"league/uri-manipulations": {
"version": "1.5.0"
},
"league/uri-parser": {
"version": "1.4.1"
},
"league/uri-schemes": {
"version": "1.2.1"
},
"lexik/jwt-authentication-bundle": {
"version": "2.5",
"recipe": {
......@@ -320,6 +344,27 @@
"ocramius/proxy-manager": {
"version": "2.1.1"
},
"payum/core": {
"version": "1.6.0"
},
"payum/iso4217": {
"version": "1.0.1"
},
"payum/offline": {
"version": "1.6.0"
},
"payum/payum-bundle": {
"version": "2.4",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "master",
"version": "2.4",
"ref": "72ad834a0f4a99175beddb5e2d049136f4a50a67"
},
"files": [
"config/packages/payum.yaml"
]
},
"php": {
"version": "7.4"
},
......
......@@ -24,7 +24,7 @@
{% if ((app.user and is_granted('ROLE_ADHERENT') and app.user.adherent) or (app.user and is_granted('ROLE_PRESTATAIRE') and app.session.has('_prestagere'))) %}
<a class='btn btn-xs btn-primary' href='{{ path('cotiser') }}'>
{{ 'Cotiser en MLC'|trans }}
{{ 'Cotiser'|trans }}
</a>
{% endif %}
{% endblock blockcontent %}
......
......@@ -27,7 +27,7 @@
{% if flux.type == 'reconversion' %}
<td>Demande de reconversion</td>
{% else %}
<td>{{flux.parenttype|capitalize}} de {{ flux.type|capitalize|replace({'_' : ' à '}) }}</td>
<td>{{ flux.type|capitalize|replace({'_' : ' '}) }}</td>
{% endif %}
<td>{{flux.expediteur}}</td>
<td>{{flux.destinataire}}</td>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment