Commit 023d7011 by Damien Moulard

Merge branch 'dev' into master

parents 711202e6 6620571f
...@@ -39,3 +39,12 @@ yarn-error.log ...@@ -39,3 +39,12 @@ yarn-error.log
###> payum ### ###> payum ###
/transactions/ /transactions/
###< payum ### ###< payum ###
###> ui customization ###
/public/images/logo.png
/public/images/favicon/
###< ui customization ###
###>bin ###
/bin/composer
###< bin ###
...@@ -23,4 +23,12 @@ label.required:after { ...@@ -23,4 +23,12 @@ label.required:after {
} }
.leaflet-container { .leaflet-container {
z-index: 4; z-index: 4;
} }
\ No newline at end of file
.kohinos-montant-radio .form-check {
margin: 10px;
}
.kohinos-montant-radio label {
margin-left: 5px;
}
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
* *
* @import "~bootswatch/dist/[theme]/variables"; * @import "~bootswatch/dist/[theme]/variables";
* @import "~bootswatch/dist/[theme]/bootswatch"; * @import "~bootswatch/dist/[theme]/bootswatch";
* *
* Remplacer [theme] par un des thèmes possibles : * Remplacer [theme] par un des thèmes possibles :
* cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux, materia, minty, pulse, sandstone, simplex, sketchy, slate, solar, spacelab, superhero, united, yeti * cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux, materia, minty, pulse, sandstone, simplex, sketchy, slate, solar, spacelab, superhero, united, yeti
*/ */
@import "~bootswatch/dist/lumen/variables"; @import "~bootswatch/dist/lumen/variables";
...@@ -19,4 +19,3 @@ ...@@ -19,4 +19,3 @@
// Modifier les couleurs de l'application : // Modifier les couleurs de l'application :
// $primary: darken(#428bca, 20%); // $primary: darken(#428bca, 20%);
// $secondary: darken(#428bca, 20%); // $secondary: darken(#428bca, 20%);
...@@ -13,6 +13,35 @@ require('../js/geoloc.js'); ...@@ -13,6 +13,35 @@ require('../js/geoloc.js');
$('#flash-messages').flashNotification('init'); $('#flash-messages').flashNotification('init');
$(document).ready(function() { $(document).ready(function() {
/*
* On user edit page, on the rolesgroup checkbox:
* - display 'group' select if "Gestionnaire de groupe" is checked
* - display 'comptoir' select if "Comptoir" is checked
*/
function possiblegroups_display_selects(e) {
var label = $(this).closest('li').find('.control-label__text')[0].textContent.trim().toLowerCase()
var isChecked = $(this).closest('li').find('.checked').length > 0
if (label.includes('comptoir')) {
if (isChecked) {
$('.comptoirsgeres_select').removeClass('hide')
} else {
$('.comptoirsgeres_select').addClass('hide')
}
} else if (label.includes('groupe')) {
if (isChecked) {
$('.groupesgeres_select').removeClass('hide')
} else {
$('.groupesgeres_select').addClass('hide')
}
}
}
$('.possible_group_cblist li .checkbox label').on('click', possiblegroups_display_selects);
$('.possible_group_cblist li .checkbox label ins').on('click', possiblegroups_display_selects);
$('.editableboolean').on('click', function (e) { $('.editableboolean').on('click', function (e) {
e.preventDefault(); e.preventDefault();
var self = $(this); var self = $(this);
...@@ -39,4 +68,4 @@ $(document).ready(function() { ...@@ -39,4 +68,4 @@ $(document).ready(function() {
} }
}); });
}); });
}); });
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// any CSS you require will output into a single css file (app.css in this case) // any CSS you require will output into a single css file (app.css in this case)
// UTILISER LES FONT AWESOME POUR L'ICONOGRAPHIE // UTILISER LES FONT AWESOME POUR L'ICONOGRAPHIE
require('../../public/fontawesome/css/all.min.css'); require('../../public/fontawesome/css/all.min.css');
// CSS DU KOHINOS // CSS DU KOHINOS
require('../css/app.css'); require('../css/app.css');
...@@ -26,6 +26,10 @@ global.$ = global.jQuery = $; ...@@ -26,6 +26,10 @@ global.$ = global.jQuery = $;
// require('popper.js/dist/popper.js'); // require('popper.js/dist/popper.js');
require('bootstrap'); require('bootstrap');
// BOOTSTRAP plugins
require('bootstrap-slider')
require('bootstrap-slider/dist/css/bootstrap-slider.min.css')
// leaftlet : for openstreetmap // leaftlet : for openstreetmap
require('../leaflet/leaflet.js'); require('../leaflet/leaflet.js');
// for flash message notification // for flash message notification
...@@ -64,6 +68,30 @@ function addGroupeForm($collectionHolder, $newLinkLi) { ...@@ -64,6 +68,30 @@ function addGroupeForm($collectionHolder, $newLinkLi) {
$newLinkLi.before($newFormLi); $newLinkLi.before($newFormLi);
} }
function showConfirmTransactionModal(div, form, montant, destinataire = null) {
// Get modal
var modal = $('#confirmTransactionModal')
// Get relevant confirmation message div
var message = modal.find(div)
// Set data in modal
message.find('.montant_transaction').text(montant)
if (destinataire != null) {
message.find('.nom_destinataire').text(destinataire)
}
// Show modal and relevant confirmation message
modal.find(div).show()
modal.modal('show')
// Bind modal validation button with form submition
$('#confirmTransactionModal #confirmTransactionButton').off()
$('#confirmTransactionModal #confirmTransactionButton').on('click', function(e){
form.submit()
});
}
jQuery(document).ready(function() { jQuery(document).ready(function() {
// Get the ul that holds the collection of groupes // Get the ul that holds the collection of groupes
$collectionHolder = $('.groupeprestas'); $collectionHolder = $('.groupeprestas');
...@@ -82,4 +110,78 @@ jQuery(document).ready(function() { ...@@ -82,4 +110,78 @@ jQuery(document).ready(function() {
// BOOTSTRAP TOOLTIPS // BOOTSTRAP TOOLTIPS
$('[data-toggle="tooltip"]').tooltip() $('[data-toggle="tooltip"]').tooltip()
$("input:radio[name='formAchatMonnaieAdherent[montantradio]']").change(function() {
var mySlider = $("input.achatmonnaie-montant-slider").slider();
// Set slider value like radio when radio changes
mySlider.slider('setValue', this.value)
$("span.achat_monnaie_montant_choisi").text(this.value + ' €')
});
$('input.achatmonnaie-montant-slider').slider().on('change', function(event){
var value = event.value.newValue;
$("span.achat_monnaie_montant_choisi").text(value + ' €')
});
$('.transactionSubmit').on('click', function(e){
// Stop form submition
e.preventDefault();
var form = this.closest('form')
if (form.checkValidity()) {
// Get destinataire type : presta or adherent
var destinataire_type = $('#' + form.name + '_destinataireType')[0].value
if (destinataire_type == 'prestataire') {
var div = '.confirmTransactionPrestataire'
} else {
var div = '.confirmTransactionAdherent'
}
// Get destinataire
var destinataire_select = $('#' + form.name + '_destinataire')[0]
var destinataire_name = destinataire_select.options[destinataire_select.selectedIndex].text
// Get montant
var montant_field = $('#' + form.name + '_montant')[0]
var montant_value = montant_field.value
showConfirmTransactionModal(div, form, montant_value, destinataire_name)
} else {
// Use symfony validation
form.submit()
}
});
$('.cotisationMLCSubmit').on('click', function(e){
// Stop form submition
e.preventDefault();
var form = this.closest('form')
// Set form moyen
$('#' + form.name + '_moyen')[0].value = 'mlc'
if (form.checkValidity()) {
var div = '.confirmCotisation'
// Get montant
var montant_field = $('#' + form.name + '_montant')[0]
var montant_value = montant_field.value
showConfirmTransactionModal(div, form, montant_value)
} else {
// Use symfony validation
form.submit()
}
});
$('.cotisationCBSubmit').on('click', function(e){
var form = this.closest('form')
// Set form moyen
$('#' + form.name + '_moyen')[0].value = 'cb'
});
}); });
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
"name": "Julien Jorry", "name": "Julien Jorry",
"email": "julien.jorry@gmail.com", "email": "julien.jorry@gmail.com",
"homepage": "https://www.malt.fr/profile/julienjorry" "homepage": "https://www.malt.fr/profile/julienjorry"
},
{
"name": "Damien Moulard",
"email": "dam.moulard@gmail.com",
"homepage": "https://www.malt.fr/profile/damienmoulard"
} }
], ],
"require": { "require": {
...@@ -74,7 +79,8 @@ ...@@ -74,7 +79,8 @@
"symfony/webpack-encore-bundle": "^1.7", "symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "4.4.*", "symfony/yaml": "4.4.*",
"vich/uploader-bundle": "^1.8", "vich/uploader-bundle": "^1.8",
"willdurand/geocoder-bundle": "^5.0" "willdurand/geocoder-bundle": "^5.0",
"shivas/versioning-bundle": "*"
}, },
"require-dev": { "require-dev": {
"symfony/browser-kit": "4.4.*", "symfony/browser-kit": "4.4.*",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f569a61c588e9ba0313fa37c884eba02", "content-hash": "d4a364a00fe16a9ef06a06f73973f4f4",
"packages": [ "packages": [
{ {
"name": "api-platform/api-pack", "name": "api-platform/api-pack",
...@@ -2083,10 +2083,16 @@ ...@@ -2083,10 +2083,16 @@
{ {
"name": "ekyna/payum-payzen", "name": "ekyna/payum-payzen",
"version": "1.5.x-dev", "version": "1.5.x-dev",
"source": {
"type": "git",
"url": "https://github.com/ekyna/PayumPayzen.git",
"reference": "9854667ee60fdd9ead297eb055e10ba1fdab3afe"
},
"dist": { "dist": {
"type": "path", "type": "zip",
"url": "./lib/ekyna/payum-payzen", "url": "https://api.github.com/repos/ekyna/PayumPayzen/zipball/9854667ee60fdd9ead297eb055e10ba1fdab3afe",
"reference": "17c280ea86308a430cc355578264a1c1f0800edd" "reference": "9854667ee60fdd9ead297eb055e10ba1fdab3afe",
"shasum": ""
}, },
"require": { "require": {
"payum/core": "^1.5", "payum/core": "^1.5",
...@@ -2115,10 +2121,7 @@ ...@@ -2115,10 +2121,7 @@
"keywords": [ "keywords": [
"payum", "payum",
"payzen" "payzen"
], ]
"transport-options": {
"relative": true
}
}, },
{ {
"name": "exsyst/swagger", "name": "exsyst/swagger",
...@@ -5030,6 +5033,59 @@ ...@@ -5030,6 +5033,59 @@
"time": "2019-11-15T08:54:08+00:00" "time": "2019-11-15T08:54:08+00:00"
}, },
{ {
"name": "nikolaposa/version",
"version": "3.2.0",
"source": {
"type": "git",
"url": "https://github.com/nikolaposa/version.git",
"reference": "7ff2bbf2fe6a47efe47832d6198924e99b4a4f5a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikolaposa/version/zipball/7ff2bbf2fe6a47efe47832d6198924e99b4a4f5a",
"reference": "7ff2bbf2fe6a47efe47832d6198924e99b4a4f5a",
"shasum": ""
},
"require": {
"php": "^7.2.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"phpunit/phpunit": "^6.0 || ^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2.x-dev"
}
},
"autoload": {
"psr-4": {
"Version\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nikola Poša",
"email": "posa.nikola@gmail.com",
"homepage": "https://www.nikolaposa.in.rs"
}
],
"description": "Value Object that represents a SemVer-compliant version number.",
"homepage": "https://github.com/nikolaposa/version",
"keywords": [
"semantic",
"semver",
"version",
"versioning"
],
"time": "2019-08-11T08:31:54+00:00"
},
{
"name": "ocramius/package-versions", "name": "ocramius/package-versions",
"version": "1.9.0", "version": "1.9.0",
"source": { "source": {
...@@ -6890,6 +6946,59 @@ ...@@ -6890,6 +6946,59 @@
"time": "2018-12-19T17:14:59+00:00" "time": "2018-12-19T17:14:59+00:00"
}, },
{ {
"name": "shivas/versioning-bundle",
"version": "3.2.3",
"source": {
"type": "git",
"url": "https://github.com/shivas/versioning-bundle.git",
"reference": "44611dbbeeef81376baa32d65ac8c263fe307f62"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/shivas/versioning-bundle/zipball/44611dbbeeef81376baa32d65ac8c263fe307f62",
"reference": "44611dbbeeef81376baa32d65ac8c263fe307f62",
"shasum": ""
},
"require": {
"nikolaposa/version": "^2.2 || ^3",
"php": "^7.0",
"symfony/console": "^3.4 || ^4 || ^5",
"symfony/framework-bundle": "^3.4 || ^4 || ^5",
"symfony/process": "^3.4 || ^4 || ^5"
},
"require-dev": {
"mikey179/vfsstream": "^1.6",
"phpunit/phpunit": "^6.5 || ^7",
"symfony/phpunit-bridge": "^4.3"
},
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Shivas\\VersioningBundle\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Audrius Karabanovas",
"email": "audrius@karabanovas.net",
"role": "Developer"
}
],
"description": "Symfony3|4 application versioning, simple console command to manage version (with providers e.g. git tag) of your application using Semantic Versioning 2.0.0 recommendations",
"homepage": "https://github.com/shivas/versioning-bundle",
"keywords": [
"semantic",
"semver",
"version",
"versioning"
],
"time": "2019-12-08T15:52:26+00:00"
},
{
"name": "sonata-project/admin-bundle", "name": "sonata-project/admin-bundle",
"version": "3.71.0", "version": "3.71.0",
"source": { "source": {
...@@ -7333,6 +7442,7 @@ ...@@ -7333,6 +7442,7 @@
"keywords": [ "keywords": [
"sonata" "sonata"
], ],
"abandoned": true,
"time": "2020-06-04T16:33:00+00:00" "time": "2020-06-04T16:33:00+00:00"
}, },
{ {
...@@ -9908,6 +10018,82 @@ ...@@ -9908,6 +10018,82 @@
"time": "2020-06-12T08:10:13+00:00" "time": "2020-06-12T08:10:13+00:00"
}, },
{ {
"name": "symfony/http-client-contracts",
"version": "v2.3.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client-contracts.git",
"reference": "41db680a15018f9c1d4b23516059633ce280ca33"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41db680a15018f9c1d4b23516059633ce280ca33",
"reference": "41db680a15018f9c1d4b23516059633ce280ca33",
"shasum": ""
},
"require": {
"php": ">=7.2.5"
},
"suggest": {
"symfony/http-client-implementation": ""
},
"type": "library",
"extra": {
"branch-version": "2.3",
"branch-alias": {
"dev-main": "2.3-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\HttpClient\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to HTTP clients",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-14T17:08:19+00:00"
},
{
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v4.4.10", "version": "v4.4.10",
"source": { "source": {
...@@ -9978,16 +10164,16 @@ ...@@ -9978,16 +10164,16 @@
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v4.4.10", "version": "v4.4.15",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "81d42148474e1852a333ed7a732f2a014af75430" "reference": "6544745997b06c7dcecf0d4a70f09e5de1db7ca8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/81d42148474e1852a333ed7a732f2a014af75430", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6544745997b06c7dcecf0d4a70f09e5de1db7ca8",
"reference": "81d42148474e1852a333ed7a732f2a014af75430", "reference": "6544745997b06c7dcecf0d4a70f09e5de1db7ca8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -9995,6 +10181,7 @@ ...@@ -9995,6 +10181,7 @@
"psr/log": "~1.0", "psr/log": "~1.0",
"symfony/error-handler": "^4.4", "symfony/error-handler": "^4.4",
"symfony/event-dispatcher": "^4.4", "symfony/event-dispatcher": "^4.4",
"symfony/http-client-contracts": "^1.1|^2",
"symfony/http-foundation": "^4.4|^5.0", "symfony/http-foundation": "^4.4|^5.0",
"symfony/polyfill-ctype": "^1.8", "symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-php73": "^1.9", "symfony/polyfill-php73": "^1.9",
...@@ -10079,7 +10266,7 @@ ...@@ -10079,7 +10266,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-06-12T11:15:37+00:00" "time": "2020-10-04T07:48:13+00:00"
}, },
{ {
"name": "symfony/inflector", "name": "symfony/inflector",
...@@ -13481,6 +13668,7 @@ ...@@ -13481,6 +13668,7 @@
"i18n", "i18n",
"text" "text"
], ],
"abandoned": true,
"time": "2018-12-05T18:34:18+00:00" "time": "2018-12-05T18:34:18+00:00"
}, },
{ {
......
...@@ -50,4 +50,5 @@ return [ ...@@ -50,4 +50,5 @@ return [
Sonata\ClassificationBundle\SonataClassificationBundle::class => ['all' => true], Sonata\ClassificationBundle\SonataClassificationBundle::class => ['all' => true],
App\Application\Sonata\ClassificationBundle\ApplicationSonataClassificationBundle::class => ['all' => true], App\Application\Sonata\ClassificationBundle\ApplicationSonataClassificationBundle::class => ['all' => true],
Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true], Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true],
Shivas\VersioningBundle\ShivasVersioningBundle::class => ['all' => true],
]; ];
# See https://symfony.com/doc/current/email/dev_environment.html # See https://symfony.com/doc/current/email/dev_environment.html
swiftmailer: swiftmailer:
# send all emails to a specific address # send all emails to a specific address
delivery_addresses: ['julien.jorry@gmail.com'] delivery_addresses: ['dam.moulard@gmail.com']
...@@ -42,6 +42,6 @@ monolog: ...@@ -42,6 +42,6 @@ monolog:
swift_critical: swift_critical:
type: swift_mailer type: swift_mailer
from_email: noreply@kohinos.fr from_email: noreply@kohinos.fr
to_email: [julien.jorry@gmail.com, stephan@gelberger.com] to_email: [dam.moulard@gmail.com]
subject: "MLC : PHP Error !" subject: "MLC : PHP Error !"
level: info level: info
...@@ -480,3 +480,7 @@ services: ...@@ -480,3 +480,7 @@ services:
decorates: 'api_platform.swagger.normalizer.api_gateway' decorates: 'api_platform.swagger.normalizer.api_gateway'
arguments: [ '@App\Swagger\SwaggerDecorator.inner' ] arguments: [ '@App\Swagger\SwaggerDecorator.inner' ]
autoconfigure: false autoconfigure: false
App\Serializer\ApiNormalizer:
decorates: 'api_platform.serializer.normalizer.item'
arguments: [ '@App\Serializer\ApiNormalizer.inner' ]
...@@ -587,6 +587,10 @@ App\Entity\Rubrique: ...@@ -587,6 +587,10 @@ App\Entity\Rubrique:
media: '@media17' media: '@media17'
App\Entity\GlobalParameter: App\Entity\GlobalParameter:
gp15:
name: "APP_TITLE"
value: 'Kohinos'
mandatory: 1
gp11: gp11:
name: "COTISATION_ADHERENT" name: "COTISATION_ADHERENT"
value: '10' value: '10'
...@@ -818,7 +822,7 @@ App\Entity\CotisationPrestataire: ...@@ -818,7 +822,7 @@ App\Entity\CotisationPrestataire:
App\Entity\User: App\Entity\User:
usersuperadmin: usersuperadmin:
username: 'adminuser' username: 'adminuser'
email: 'julien.jorry@gmail.com' email: 'dam.moulard@gmail.com'
plainPassword: 'test' plainPassword: 'test'
enabled: true enabled: true
possiblegroups: ['@usergroup_superadmin', '@usergroup_prestataire'] possiblegroups: ['@usergroup_superadmin', '@usergroup_prestataire']
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
}, },
"dependencies": { "dependencies": {
"bootstrap": "^4.4.1", "bootstrap": "^4.4.1",
"bootstrap-slider": "^11.0.2",
"bootswatch": "^4.3.1", "bootswatch": "^4.3.1",
"ckeditor": "^4.0.0", "ckeditor": "^4.0.0",
"jquery": "^3.3.1", "jquery": "^3.3.1",
......
...@@ -9,4 +9,6 @@ ...@@ -9,4 +9,6 @@
<IfModule mod_alias.c> <IfModule mod_alias.c>
RedirectMatch 302 ^/$ /index.php/ RedirectMatch 302 ^/$ /index.php/
</IfModule> </IfModule>
</IfModule> </IfModule>
\ No newline at end of file SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE "application/atom+xml" "application/javascript" "application/json" "application/ld+json" "application/manifest+json" "application/rdf+xml" "application/rss+xml" "application/schema+json" "application/vnd.geo+json" "application/vnd.ms-fontobject" "application/x-font-ttf" "application/x-javascript" "application/x-web-app-manifest+json" "application/xhtml+xml" "application/xml" "font/eot" "font/opentype" "image/bmp" "image/svg+xml" "image/vnd.microsoft.icon" "image/x-icon" "text/cache-manifest" "text/css" "text/html" "text/javascript" "text/plain" "text/vcard" "text/vnd.rim.location.xloc" "text/vtt" "text/x-component" "text/x-cross-domain-policy" "text/xml"
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /index.php/
</IfModule>
</IfModule>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -3,19 +3,19 @@ ...@@ -3,19 +3,19 @@
"app": { "app": {
"js": [ "js": [
"/build/runtime.420770e4.js", "/build/runtime.420770e4.js",
"/build/app.a6090119.js" "/build/app.a1cf5950.js"
], ],
"css": [ "css": [
"/build/app.b1a10d11.css" "/build/app.0ecb0d81.css"
] ]
}, },
"admin": { "admin": {
"js": [ "js": [
"/build/runtime.420770e4.js", "/build/runtime.420770e4.js",
"/build/admin.da628ab6.js" "/build/admin.3024c297.js"
], ],
"css": [ "css": [
"/build/admin.b8c3eca8.css" "/build/admin.4d653142.css"
] ]
} }
} }
......
{ {
"build/admin.css": "/build/admin.b8c3eca8.css", "build/admin.css": "/build/admin.4d653142.css",
"build/admin.js": "/build/admin.da628ab6.js", "build/admin.js": "/build/admin.3024c297.js",
"build/app.css": "/build/app.b1a10d11.css", "build/app.css": "/build/app.0ecb0d81.css",
"build/app.js": "/build/app.a6090119.js", "build/app.js": "/build/app.a1cf5950.js",
"build/runtime.js": "/build/runtime.420770e4.js", "build/runtime.js": "/build/runtime.420770e4.js",
"build/ckeditor/adapters/jquery.js": "/build/ckeditor/adapters/jquery.js", "build/ckeditor/adapters/jquery.js": "/build/ckeditor/adapters/jquery.js",
"build/ckeditor/ckeditor.js": "/build/ckeditor/ckeditor.js", "build/ckeditor/ckeditor.js": "/build/ckeditor/ckeditor.js",
......
...@@ -150,6 +150,15 @@ class AdherentAdmin extends AbstractAdmin ...@@ -150,6 +150,15 @@ class AdherentAdmin extends AbstractAdmin
'with_latlon' => false 'with_latlon' => false
)) ))
->end() ->end()
->with('Groupe', ['class' => 'col-md-5'])
->add('groupe', ChoiceType::class, array(
'required' => true,
'label' => 'Groupe local :',
'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Groupe::class)->findAll(),
'choice_label' => 'name',
'placeholder' => 'Choisir un groupe',
))
->end()
->end() ->end()
; ;
......
...@@ -5,6 +5,7 @@ namespace App\Admin; ...@@ -5,6 +5,7 @@ namespace App\Admin;
use App\Entity\Adherent; use App\Entity\Adherent;
use App\Entity\GlobalParameter; use App\Entity\GlobalParameter;
use App\Entity\User; use App\Entity\User;
use App\Entity\Flux;
use Sonata\AdminBundle\Datagrid\DatagridMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Form\FormMapper;
......
...@@ -56,7 +56,7 @@ class UserAdmin extends SonataUserAdmin ...@@ -56,7 +56,7 @@ class UserAdmin extends SonataUserAdmin
{ {
parent::configureListFields($listMapper); parent::configureListFields($listMapper);
unset($this->listModes['mosaic']); unset($this->listModes['mosaic']);
if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) { if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
$listMapper $listMapper
->addIdentifier('impersonating', 'string', ['template' => '@SonataUser/Admin/Field/impersonating.html.twig']) ->addIdentifier('impersonating', 'string', ['template' => '@SonataUser/Admin/Field/impersonating.html.twig'])
......
...@@ -31,6 +31,9 @@ use Symfony\Component\Form\Extension\Core\Type\TextType; ...@@ -31,6 +31,9 @@ use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TimezoneType; use Symfony\Component\Form\Extension\Core\Type\TimezoneType;
use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormTypeInterface; use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\Common\Collections\ArrayCollection;
class UserAdmin extends BaseUserAdmin class UserAdmin extends BaseUserAdmin
{ {
...@@ -208,13 +211,13 @@ class UserAdmin extends BaseUserAdmin ...@@ -208,13 +211,13 @@ class UserAdmin extends BaseUserAdmin
->add('enabled', null, ['required' => false]) ->add('enabled', null, ['required' => false])
->end() ->end()
; ;
$hideOrShowGroupe = ['class' => 'hide']; $hideOrShowGroupe = ['class' => 'groupesgeres_select hide'];
$hideOrShowComptoir = ['class' => 'hide']; $hideOrShowComptoir = ['class' => 'comptoirsgeres_select hide'];
if (($subject->isGranted('ROLE_GESTION_GROUPE') || $subject->isGranted('ROLE_CONTACT') || $subject->isGranted('ROLE_TRESORIER'))) { if (($subject->isGranted('ROLE_GESTION_GROUPE') || $subject->isGranted('ROLE_CONTACT') || $subject->isGranted('ROLE_TRESORIER'))) {
$hideOrShowGroupe = []; $hideOrShowGroupe = ['class' => 'groupesgeres_select'];
} }
if ($subject->isGranted('ROLE_COMPTOIR')) { if ($subject->isGranted('ROLE_COMPTOIR')) {
$hideOrShowComptoir = []; $hideOrShowComptoir = ['class' => 'comptoirsgeres_select'];
} }
$formMapper $formMapper
->with('Groups') ->with('Groups')
...@@ -223,6 +226,7 @@ class UserAdmin extends BaseUserAdmin ...@@ -223,6 +226,7 @@ class UserAdmin extends BaseUserAdmin
'required' => false, 'required' => false,
'expanded' => true, 'expanded' => true,
'multiple' => true, 'multiple' => true,
'attr' => ['class' => 'possible_group_cblist']
]) ])
// @TODO : Si on veut voir le groupe choisit par l'utilisateur // @TODO : Si on veut voir le groupe choisit par l'utilisateur
// ->add('groups', null, [ // ->add('groups', null, [
...@@ -292,4 +296,40 @@ class UserAdmin extends BaseUserAdmin ...@@ -292,4 +296,40 @@ class UserAdmin extends BaseUserAdmin
} }
} }
} }
public function postPersist($user): void
{
// On empeche d'enregistrer des comptoirs/groupes gérés si la case correspondante n'est pas cochée dans le choix des possiblegroups
$em = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
$possiblegroups = $user->getPossiblegroups();
$groupesgeres = $user->getGroupesgeres();
$comptoirsgeres = $user->getComptoirsgeres();
$isComptoir = false;
$isGroup = false;
foreach ($possiblegroups as $possiblegroup) {
if ($possiblegroup->getName() == "Comptoir") {
$isComptoir = true;
} else if ($possiblegroup->getName() == "Gestionnaire de Groupe") {
$isGroup = true;
}
}
if (!$isComptoir && !$comptoirsgeres->isEmpty()) {
foreach ($comptoirsgeres as $comptoir) {
$user->removeComptoirsgere($comptoir);
}
}
if (!$isGroup && !$groupesgeres->isEmpty()) {
foreach ($groupesgeres as $group) {
$user->removeGroupesgere($group);
}
}
$em->persist($user);
$em->flush();
}
} }
...@@ -12,6 +12,7 @@ use Symfony\Component\Form\Form; ...@@ -12,6 +12,7 @@ use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
...@@ -19,17 +20,30 @@ use Symfony\Component\Translation\TranslatorInterface; ...@@ -19,17 +20,30 @@ use Symfony\Component\Translation\TranslatorInterface;
use Payum\Core\Payum; use Payum\Core\Payum;
use Payum\Core\Request\GetHumanStatus; use Payum\Core\Request\GetHumanStatus;
use Payum\Core\Request\Notify; use Payum\Core\Request\Notify;
use App\Entity\Flux;
use App\Entity\Payment; use App\Entity\Payment;
use App\Entity\Siege; use App\Entity\Siege;
use App\Entity\User; use App\Entity\User;
use App\Entity\Adherent; use App\Entity\Adherent;
use App\Entity\Prestataire; use App\Entity\Prestataire;
use App\Entity\Geoloc;
use App\Entity\Groupe;
use App\Entity\Usergroup;
use App\Entity\AchatMonnaieAdherent; use App\Entity\AchatMonnaieAdherent;
use App\Entity\AchatMonnaiePrestataire; use App\Entity\AchatMonnaiePrestataire;
use App\Entity\CotisationAdherent; use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire; use App\Entity\CotisationPrestataire;
use App\Entity\GlobalParameter;
use Sonata\Exporter\Handler;
use Sonata\Exporter\Source\DoctrineORMQuerySourceIterator;
use Sonata\Exporter\Writer\CsvWriter;
use Sonata\Exporter\Writer\JsonWriter;
use Sonata\Exporter\Writer\XmlWriter;
use Sonata\Exporter\Writer\XlsWriter;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use FOS\UserBundle\Model\UserManagerInterface;
use App\Security\LoginAuthenticator;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
/** /**
* *
...@@ -59,8 +73,19 @@ class FluxController extends AbstractController ...@@ -59,8 +73,19 @@ class FluxController extends AbstractController
protected $eventDispatcher; protected $eventDispatcher;
protected $session; protected $session;
protected $payum; protected $payum;
protected $authenticator;
public function __construct(Security $security, EntityManagerInterface $em, TranslatorInterface $translator, EventDispatcherInterface $eventDispatcher, SessionInterface $session, Payum $payum) protected $guardHandler;
protected $userManager;
public function __construct(Security $security,
EntityManagerInterface $em,
TranslatorInterface $translator,
EventDispatcherInterface $eventDispatcher,
SessionInterface $session,
LoginAuthenticator $authenticator,
GuardAuthenticatorHandler $guardHandler,
UserManagerInterface $userManager,
Payum $payum)
{ {
$this->security = $security; $this->security = $security;
$this->em = $em; $this->em = $em;
...@@ -68,6 +93,9 @@ class FluxController extends AbstractController ...@@ -68,6 +93,9 @@ class FluxController extends AbstractController
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
$this->session = $session; $this->session = $session;
$this->payum = $payum; $this->payum = $payum;
$this->authenticator = $authenticator;
$this->guardHandler = $guardHandler;
$this->userManager = $userManager;
} }
protected function manageFluxForm(Request $request, Form $form, $compte, $success, $title) protected function manageFluxForm(Request $request, Form $form, $compte, $success, $title)
...@@ -102,16 +130,101 @@ class FluxController extends AbstractController ...@@ -102,16 +130,101 @@ class FluxController extends AbstractController
]); ]);
} }
/* /**
* Crée une instance de Payment et redirige vers la page de paiement * Export all transferts / transactions for a user role
*/ *
public function preparePaymentAction(Form $form, $type) * @param Request $request Request
* @param String $format Format of export ('json', 'xml', 'csv', 'xls')
* @Route("/flux/export/{format}/", name="exportUserFlux", defaults={"format": "csv"})
*/
public function exportFluxAction(Request $request, $format = 'csv')
{ {
$flux_data = $form->getData(); //Prepare query depending on user role
$query = null;
$user = $this->security->getUser();
if ($this->session->get('_prestagere') != null && $this->security->getUser()->isGranted('ROLE_PRESTATAIRE')) {
$query = $this->em->getRepository(Flux::class)->getQueryByPrestataire($this->session->get('_prestagere'));
} elseif ($user->getAdherent() != null && $this->security->getUser()->isGranted('ROLE_ADHERENT')) {
$query = $this->em->getRepository(Flux::class)->getQueryByAdherent($user->getAdherent());
} elseif ($this->session->get('_comptoirgere') != null && $this->security->getUser()->isGranted('ROLE_COMPTOIR')) {
$query = $this->em->getRepository(Flux::class)->getQueryByComptoir($this->session->get('_comptoirgere'));
} elseif ($this->session->get('_groupegere') != null && $this->security->getUser()->isGranted('ROLE_GESTION_GROUPE')) {
$query = $this->em->getRepository(Flux::class)->getQueryByGroupe($this->session->get('_groupegere'));
}
if ($query != null) {
// Prepare the data source
$fields = ['expediteur', 'destinataire', 'type', 'parenttype', 'montant', 'moyen', 'operateur'];
$source = new DoctrineORMQuerySourceIterator($query, $fields);
$filename = sprintf(
'export_flux_%s.%s',
date('Y_m_d_H_i_s', strtotime('now')),
$format
);
return $this->getResponse(
$format,
$filename,
$source
);
} else {
$this->addFlash(
'error',
$this->translator->trans('Export impossible.')
);
return $this->redirectToRoute('index');
}
}
private function getResponse($format, $filename, $source)
{
switch ($format) {
case 'xls':
$writer = new XlsWriter('php://output');
$contentType = 'application/vnd.ms-excel';
break;
case 'xml':
$writer = new XmlWriter('php://output');
$contentType = 'text/xml';
break;
case 'json':
$writer = new JsonWriter('php://output');
$contentType = 'application/json';
break;
case 'csv':
$writer = new CsvWriter('php://output', ',', '"', '\\', true, true);
$contentType = 'text/csv';
break;
default:
throw new \RuntimeException('Invalid format');
}
$callback = static function () use ($source, $writer) {
$handler = Handler::create($source, $writer);
$handler->export();
};
return new StreamedResponse($callback, 200, [
'Content-Type' => $contentType,
'Content-Disposition' => sprintf('attachment; filename="%s"', $filename),
]);
}
/**
* Crée une instance de Payment et redirige vers la page de paiement
*/
public function preparePaymentAction(Form $form, $type, $extra_data = null)
{
// Enregistre les données du Flux en json, pour l'enregistrer une fois le paiement validé // Enregistre les données du Flux en json, pour l'enregistrer une fois le paiement validé
$serializer = $this->container->get('serializer'); $serializer = $this->container->get('serializer');
$data = $serializer->normalize($flux_data, null, $toSerialize = Payment::TYPE_ADHESION == $type ? $form->get('cotisation')->getData() : $form->getData();
$data = $serializer->normalize($toSerialize, null,
[AbstractNormalizer::ATTRIBUTES => ['reference', [AbstractNormalizer::ATTRIBUTES => ['reference',
'moyen', 'moyen',
'montant', 'montant',
...@@ -123,19 +236,39 @@ class FluxController extends AbstractController ...@@ -123,19 +236,39 @@ class FluxController extends AbstractController
$jsondata = $serializer->serialize($data, 'json'); $jsondata = $serializer->serialize($data, 'json');
// Prepare CB Payment // Prepare CB Payment
$gatewayName = 'payzen'; if ($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::USE_PAYZEN) === 'true') {
$gatewayName = 'payzen';
} else {
$this->addFlash(
'error',
$this->translator->trans('Une erreur est survenue due à la configuration du paiement dans l\'application. Il est pour l\'instant impossible de payer par CB, merci de contacter votre monnaie locale.')
);
return $this->redirectToRoute('index');
}
$storage = $this->payum->getStorage('App\Entity\Payment'); $storage = $this->payum->getStorage('App\Entity\Payment');
$payment = $storage->create(); $payment = $storage->create();
$payment->setNumber(uniqid()); $payment->setNumber(uniqid());
$payment->setCurrencyCode('978'); $payment->setCurrencyCode('978');
$payment->setTotalAmount($form->get('montant')->getData()*100); // 1.23 EUR
$payment->setDescription($type); $payment->setDescription($type);
$payment->setClientId($this->getUser()->getId());
$payment->setClientEmail($this->getUser()->getEmail());
$payment->setFluxData($jsondata); $payment->setFluxData($jsondata);
// Data to persist when payment is valid (other than Flux data)
if ($extra_data != null) {
$payment->setExtraData($extra_data);
}
if ($type == Payment::TYPE_ADHESION) {
$payment->setTotalAmount($form->get('cotisation')->get('montant')->getData()*100); // 1.23 EUR
$payment->setClientId('Nouvel adhérent');
$payment->setClientEmail($form->get('user')->get('email')->getData());
} else {
$payment->setTotalAmount($form->get('montant')->getData()*100); // 1.23 EUR
$payment->setClientId($this->getUser()->getId());
$payment->setClientEmail($this->getUser()->getEmail());
}
$storage->update($payment); $storage->update($payment);
$captureToken = $this->payum->getTokenFactory()->createCaptureToken( $captureToken = $this->payum->getTokenFactory()->createCaptureToken(
...@@ -159,7 +292,7 @@ class FluxController extends AbstractController ...@@ -159,7 +292,7 @@ class FluxController extends AbstractController
/** /**
* Fonction de traitement du paiement, à appeler : * Fonction de traitement du paiement, à appeler :
* - automatiquement lorsqu'un événement se produit sur le site de Paiement * - automatiquement lorsqu'un événement se produit sur le site de Paiement (notification)
* - au retour sur le site par l'utilisateur * - au retour sur le site par l'utilisateur
* *
* @Route("/payment/done/", name="payment_done") * @Route("/payment/done/", name="payment_done")
...@@ -169,46 +302,7 @@ class FluxController extends AbstractController ...@@ -169,46 +302,7 @@ class FluxController extends AbstractController
try { try {
$token = $this->payum->getHttpRequestVerifier()->verify($request); $token = $this->payum->getHttpRequestVerifier()->verify($request);
} catch (\Exception $e) { } catch (\Exception $e) {
// Token expiré : retour sur site après paiement // Token expired
// Get last payment
$payment = $this->em->getRepository(Payment::class)->getUserLastPayment($this->getUser()->getId());
if (!is_null($payment)) {
if ($payment->getStatus() == GetHumanStatus::STATUS_CAPTURED || $payment->getStatus() == GetHumanStatus::STATUS_AUTHORIZED) {
$type = $payment->getDescription();
if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type || Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$this->addFlash(
'success',
$this->translator->trans('Achat de monnaie locale bien effectué !')
);
} else {
$this->addFlash(
'success',
$this->translator->trans('Cotisation bien reçue. Merci !')
);
}
// Update payment status
$payment->setStatus($payment->getStatus().';done');
$this->em->persist($payment);
$this->em->flush();
} else if ($payment->getStatus() == GetHumanStatus::STATUS_CANCELED ||
$payment->getStatus() == GetHumanStatus::STATUS_EXPIRED ||
$payment->getStatus() == GetHumanStatus::STATUS_FAILED) {
$this->addFlash(
'error',
$this->translator->trans('La transaction a été annulée.')
);
$payment->setStatus($payment->getStatus().';done');
$this->em->persist($payment);
$this->em->flush();
}
}
return $this->redirectToRoute('index'); return $this->redirectToRoute('index');
} }
...@@ -220,12 +314,65 @@ class FluxController extends AbstractController ...@@ -220,12 +314,65 @@ class FluxController extends AbstractController
// Execute 'done' action according to payment status // Execute 'done' action according to payment status
$gateway->execute($status = new GetHumanStatus($token)); $gateway->execute($status = new GetHumanStatus($token));
// Get payment & update status // Get payment
$payment = $status->getFirstModel(); $payment = $status->getFirstModel();
// Check for actual payment status. If not null or new: payment has already been processed.
if ($payment->getStatus() == GetHumanStatus::STATUS_CAPTURED || $payment->getStatus() == GetHumanStatus::STATUS_AUTHORIZED) {
// Invalidate token
$this->payum->getHttpRequestVerifier()->invalidate($token);
$type = $payment->getDescription();
if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type || Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$this->addFlash(
'success',
$this->translator->trans('Achat de monnaie locale bien effectué !')
);
} else if (Payment::TYPE_COTISATION_ADHERENT == $type || Payment::TYPE_COTISATION_PRESTA == $type) {
$this->addFlash(
'success',
$this->translator->trans('Cotisation bien reçue. Merci !')
);
} else if (Payment::TYPE_ADHESION == $type) {
$this->addFlash(
'success',
$this->translator->trans('Votre adhésion a bien été prise en compte, bienvenue !')
);
// Connect new user
return $this->guardHandler
->authenticateUserAndHandleSuccess(
$this->em->getRepository(User::class)->findOneBy(array('id' => $payment->getClientId())),
$request,
$this->authenticator,
'main'
);
}
return $this->redirectToRoute('index');
} else if ($payment->getStatus() == GetHumanStatus::STATUS_CANCELED ||
$payment->getStatus() == GetHumanStatus::STATUS_EXPIRED ||
$payment->getStatus() == GetHumanStatus::STATUS_FAILED) {
// Invalidate token
$this->payum->getHttpRequestVerifier()->invalidate($token);
$this->addFlash(
'error',
$this->translator->trans('La transaction a été annulée.')
);
return $this->redirectToRoute('index');
}
// We got here, payment hasn't been processed, we're in the notification process. Update payment status and go on.
$payment->setStatus($status->getValue()); $payment->setStatus($status->getValue());
$this->em->persist($payment); $this->em->persist($payment);
$this->em->flush(); $this->em->flush();
$type = '';
// If payment succesful, persist serialized 'Flux' stored in payment // If payment succesful, persist serialized 'Flux' stored in payment
if ($status->getValue() == GetHumanStatus::STATUS_CAPTURED || $status->getValue() == GetHumanStatus::STATUS_AUTHORIZED) { if ($status->getValue() == GetHumanStatus::STATUS_CAPTURED || $status->getValue() == GetHumanStatus::STATUS_AUTHORIZED) {
...@@ -246,6 +393,9 @@ class FluxController extends AbstractController ...@@ -246,6 +393,9 @@ class FluxController extends AbstractController
$dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']); $dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest); $flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
} else if (Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) { } else if (Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$flux = $serializer->deserialize( $flux = $serializer->deserialize(
$payment->getFluxData(), $payment->getFluxData(),
...@@ -259,6 +409,9 @@ class FluxController extends AbstractController ...@@ -259,6 +409,9 @@ class FluxController extends AbstractController
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']); $dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest); $flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
} else if (Payment::TYPE_COTISATION_ADHERENT == $type) { } else if (Payment::TYPE_COTISATION_ADHERENT == $type) {
$flux = $serializer->deserialize( $flux = $serializer->deserialize(
$payment->getFluxData(), $payment->getFluxData(),
...@@ -273,6 +426,9 @@ class FluxController extends AbstractController ...@@ -273,6 +426,9 @@ class FluxController extends AbstractController
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']); $dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest); $flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setRecu(true); $flux->setRecu(true);
} else if (Payment::TYPE_COTISATION_PRESTA == $type) { } else if (Payment::TYPE_COTISATION_PRESTA == $type) {
$flux = $serializer->deserialize( $flux = $serializer->deserialize(
...@@ -288,14 +444,65 @@ class FluxController extends AbstractController ...@@ -288,14 +444,65 @@ class FluxController extends AbstractController
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']); $dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest); $flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setRecu(true); $flux->setRecu(true);
} else if (Payment::TYPE_ADHESION == $type) {
$new_adherent_data = json_decode($payment->getExtraData());
$adherent = new Adherent();
$user = $this->userManager->createUser();
$usergroup = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$group = $this->em->getRepository(Groupe::class)->findOneBy(array('id' => $new_adherent_data->groupe->id));
$user->setEmail($new_adherent_data->user->email);
$user->setUsername($new_adherent_data->user->username);
$user->setFirstname($new_adherent_data->user->firstname);
$user->setLastname($new_adherent_data->user->lastname);
$user->setPlainPassword($new_adherent_data->user->plainPassword);
$user->setEnabled(true);
$user->addPossiblegroup($usergroup);
$user->addGroup($usergroup);
$user->addRole('ROLE_ADHERENT');
$user->setAdherent($adherent);
$adherent->setEcompte('0');
$adherent->setUser($user);
$adherent->setGroupe($group);
if ($adherent->getGeoloc() == null) {
$geoloc = new Geoloc();
$geoloc->setAdresse($new_adherent_data->geoloc->adresse);
$geoloc->setCpostal($new_adherent_data->geoloc->cpostal);
$geoloc->setVille($new_adherent_data->geoloc->ville);
$adherent->setGeoloc($geoloc);
}
$this->em->persist($adherent);
$this->em->flush();
// Create first cotisation
$flux = $serializer->deserialize(
$payment->getFluxData(),
CotisationAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$flux->setOperateur($user);
$flux->setExpediteur($adherent);
$flux->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(array('mlc' => true)));
$flux->setRole('Adherent');
$flux->setRecu(true);
// Update payment with new user id, remove user data
$payment->setClientId($user->getId());
$payment->setExtraData('');
$this->em->persist($payment);
} else { } else {
return new Response('', Response::HTTP_BAD_REQUEST); return new Response('', Response::HTTP_BAD_REQUEST);
} }
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$this->em->persist($flux); $this->em->persist($flux);
$this->em->flush(); $this->em->flush();
...@@ -303,26 +510,15 @@ class FluxController extends AbstractController ...@@ -303,26 +510,15 @@ class FluxController extends AbstractController
MLCEvents::FLUX, MLCEvents::FLUX,
new FluxEvent($flux) new FluxEvent($flux)
); );
} else if ($payment->getStatus() == GetHumanStatus::STATUS_CANCELED ||
// Add Flash message here in case Gataway doesn't notify $payment->getStatus() == GetHumanStatus::STATUS_EXPIRED ||
$this->addFlash( $payment->getStatus() == GetHumanStatus::STATUS_FAILED) {
'success',
$this->translator->trans('Achat de monnaie locale bien effectué !')
);
// Invalidate token
$this->payum->getHttpRequestVerifier()->invalidate($token);
} else if ($status->getValue() == GetHumanStatus::STATUS_CANCELED ||
$status->getValue() == GetHumanStatus::STATUS_EXPIRED ||
$status->getValue() == GetHumanStatus::STATUS_FAILED) {
$this->addFlash( $this->addFlash(
'error', 'error',
$this->translator->trans('La transaction a été annulée.') $this->translator->trans('La transaction a été annulée.')
); );
$this->payum->getHttpRequestVerifier()->invalidate($token);
} }
return $this->redirectToRoute('index'); return $this->redirectToRoute('index');
......
...@@ -17,6 +17,8 @@ use App\Entity\Rubrique; ...@@ -17,6 +17,8 @@ use App\Entity\Rubrique;
use App\Entity\Siege; use App\Entity\Siege;
use App\Entity\User; use App\Entity\User;
use App\Entity\Usergroup; use App\Entity\Usergroup;
use App\Entity\Flux;
use App\Entity\TypePrestataire;
use App\Enum\ImportEnum; use App\Enum\ImportEnum;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Events\MLCEvents; use App\Events\MLCEvents;
...@@ -37,6 +39,7 @@ use Symfony\Component\HttpFoundation\Response; ...@@ -37,6 +39,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class ImportController extends CRUDController class ImportController extends CRUDController
{ {
...@@ -54,8 +57,14 @@ class ImportController extends CRUDController ...@@ -54,8 +57,14 @@ class ImportController extends CRUDController
protected $userManager; protected $userManager;
protected $translator; protected $translator;
protected $tokenGenerator; protected $tokenGenerator;
protected $eventDispatcher;
public function __construct(EntityManagerInterface $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator, TokenGeneratorInterface $tokenGenerator)
public function __construct(EntityManagerInterface $em,
Security $security,
UserManagerInterface $userManager,
TranslatorInterface $translator,
TokenGeneratorInterface $tokenGenerator,
EventDispatcherInterface $eventDispatcher)
{ {
$this->header = null; $this->header = null;
$this->warnings = array(); $this->warnings = array();
...@@ -68,6 +77,7 @@ class ImportController extends CRUDController ...@@ -68,6 +77,7 @@ class ImportController extends CRUDController
$this->userManager = $userManager; $this->userManager = $userManager;
$this->translator = $translator; $this->translator = $translator;
$this->tokenGenerator = $tokenGenerator; $this->tokenGenerator = $tokenGenerator;
$this->eventDispatcher = $eventDispatcher;
$this->siege = null; $this->siege = null;
$this->sendemail = false; $this->sendemail = false;
} }
...@@ -91,32 +101,45 @@ class ImportController extends CRUDController ...@@ -91,32 +101,45 @@ class ImportController extends CRUDController
$this->em->flush(); $this->em->flush();
$idimport = $import->getId(); $idimport = $import->getId();
$this->importFromCSV($type, $media); try {
$this->importFromCSV($type, $media);
$import = $this->em->getRepository(Import::class)->findOneById($idimport); $import = $this->em->getRepository(Import::class)->findOneById($idimport);
$import->setEnabled(true); $import->setEnabled(true);
$import->setSuccess(json_encode($this->success)); $import->setSuccess(json_encode($this->success));
$import->setWarnings(json_encode($this->warnings)); $import->setWarnings(json_encode($this->warnings));
$import->setErrors(json_encode($this->errors)); $import->setErrors(json_encode($this->errors));
$import->setNbentityadded($this->nbsuccess); $import->setNbentityadded($this->nbsuccess);
$import->setNbentityerror($this->nberrors); $import->setNbentityerror($this->nberrors);
$this->em->persist($import); $this->em->persist($import);
$this->em->flush(); $this->em->flush();
if (empty($this->errors)) { if (empty($this->errors)) {
$this->addFlash( $this->addFlash(
'success', 'success',
'Import effectué avec succès !' 'Import effectué avec succès !'
); );
} else { } else {
$this->addFlash( $this->addFlash(
'error', 'error',
"Il y a eu des erreurs lors de l'import !" "Il y a eu des erreurs lors de l'import !"
); );
}
return $this->redirect($this->admin->generateUrl('show', array('id' => $import->getId())));
} catch (\Exception $e) {
if ('prod' === $this->container->get('kernel')->getEnvironment()) {
return $this->renderWithExtraParams('admin/import_error.html.twig', [
'action' => 'list',
'error' => $e->getMessage(),
]);
}
throw $e;
} }
return $this->redirect($this->admin->generateUrl('show', array('id' => $import->getId())));
} }
return $this->renderWithExtraParams('admin/import.html.twig', array( return $this->renderWithExtraParams('admin/import.html.twig', array(
'action' => 'list', 'action' => 'list',
'form' => $form->createView(), 'form' => $form->createView(),
...@@ -333,191 +356,182 @@ class ImportController extends CRUDController ...@@ -333,191 +356,182 @@ class ImportController extends CRUDController
private function importPrestataire($csvRows) private function importPrestataire($csvRows)
{ {
// Iterate over the reader and write each row to the database $operateur = $this->getUser();
// groupe;adresse;cpostal;ville;raison;ecompte;metier;statut;responsable;iban;siret;web;horaires;description;rubriques;tags;tauxreconversion;cotisations;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2 $operateur_id = $operateur->getId();
$line = 1; $line = 0;
/**
* Iterate over the reader and write each row to the database.
* Each row has at least 6 required columns.
*
* Row format: groupe;adresse;cpostal;ville;raison;ecompte;metier;statut;responsable;iban;siret;web;horaires;...
* description;rubriques;tags;tauxreconversion;cotisations;...
* gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;...
* contact1;phone1;email1;contact2;phone2;email2
*/
$requiredColumns = [
'groupe', 'raison', 'siret', 'adresse', 'cpostal', 'ville',
];
$warningColumns = [
'metier', 'statut', 'responsable', 'iban', 'web', 'horaires', 'description', 'ecompte',
];
$columns = array_fill_keys(
array_merge($requiredColumns, $warningColumns, ['rubriques', 'tags', 'tauxreconversion', 'cotisations']),
null
);
foreach ($csvRows as $row) { foreach ($csvRows as $row) {
$hasError = false; $hasError = false;
if ($line == 1) { $line++;
$line++;
continue; // The header is ignored
} if ($line === 1) {
if (!array_key_exists("groupe", $row)) {
$this->addError($row, $line, 'groupe', $this->translator->trans("La colonne 'groupe' est obligatoire !"));
}
if (!array_key_exists("adresse", $row)) {
$this->addError($row, $line, 'adresse', $this->translator->trans("La colonne 'adresse' est obligatoire !"));
}
if (!array_key_exists("cpostal", $row)) {
$this->addError($row, $line, 'cpostal', $this->translator->trans("La colonne 'cpostal' est obligatoire !"));
}
if (!array_key_exists("ville", $row)) {
$this->addError($row, $line, 'ville', $this->translator->trans("La colonne 'ville' est obligatoire !"));
}
if (!array_key_exists("raison", $row)) {
$this->addError($row, $line, 'raison', $this->translator->trans("La colonne 'raison' est obligatoire !"));
}
if (!(array_key_exists("groupe", $row) && array_key_exists("adresse", $row) && array_key_exists("cpostal", $row) && array_key_exists("ville", $row) && array_key_exists("raison", $row))) {
$line++;
$this->nberrors++;
continue; continue;
} }
$groupe = array_key_exists("groupe", $row) ? $row['groupe'] : '';
$adresse = array_key_exists("adresse", $row) ? $row['adresse'] : ''; // Add the missing columns to the current row (with a null value).
$cpostal = array_key_exists("cpostal", $row) ? $row['cpostal'] : ''; $row += $columns;
$ville = array_key_exists("ville", $row) ? $row['ville'] : '';
$raison = array_key_exists("raison", $row) ? $row['raison'] : ''; /**
if (empty($groupe)) { * Check the required columns.
$this->addError($row, $line, 'groupe', $this->translator->trans("Le 'groupe' est obligatoire !")); * If one is not present or empty => add an error and go to the next line.
} */
if (empty($adresse)) { foreach ($requiredColumns as $column) {
$this->addError($row, $line, 'adresse', $this->translator->trans("Le 'adresse' est obligatoire !")); if (! $row[$column]) {
} $this->addError($row, $line, $column,
if (empty($cpostal)) { $this->translator->trans('prestataire.column_required', [$column], 'import')
$this->addError($row, $line, 'cpostal', $this->translator->trans("Le 'cpostal' est obligatoire !")); );
} $hasError = true;
if (empty($ville)) { }
$this->addError($row, $line, 'ville', $this->translator->trans("Le 'ville' est obligatoire !"));
}
if (empty($raison)) {
$this->addError($row, $line, 'raison', $this->translator->trans("Le 'raison' est obligatoire !"));
} }
if (empty($groupe) || empty($adresse) || empty($cpostal) || empty($ville) || empty($raison)) {
if ($hasError) {
$this->nberrors++; $this->nberrors++;
$line++;
continue; continue;
} }
$ecompte = array_key_exists("ecompte", $row) ? $row['ecompte'] : '';
$metier = array_key_exists("metier", $row) ? $row['metier'] : '';
$statut = array_key_exists("statut", $row) ? $row['statut'] : '';
$responsable = array_key_exists("responsable", $row) ? $row['responsable'] : '';
$iban = array_key_exists("iban", $row) ? $row['iban'] : '';
$siret = array_key_exists("siret", $row) ? $row['siret'] : '';
$web = array_key_exists("web", $row) ? $row['web'] : '';
$horaires = array_key_exists("horaires", $row) ? $row['horaires'] : '';
$description = array_key_exists("description", $row) ? $row['description'] : '';
$rubriques = array_key_exists("rubriques", $row) ? $row['rubriques'] : '';
$tags = array_key_exists("tags", $row) ? $row['tags'] : '';
$tauxreconversion = array_key_exists("tauxreconversion", $row) ? $row['tauxreconversion'] : '';
$cotisations = array_key_exists("cotisations", $row) ? $row['cotisations'] : '';
$prestataire = $this->em->getRepository(Prestataire::class)->findOneBy(array('slug' => $this->slugify($raison))); /**
if (empty($prestataire)) { * If it doesn't exist yet, create and fill a Prestataire.
* Otherwise => error!
*/
$prestataire = $this->em->getRepository(Prestataire::class)->findOneBy([
'slug' => $this->slugify($row['raison'])
]);
if (!$prestataire) {
$prestataire = new Prestataire(); $prestataire = new Prestataire();
if (!empty($raison)) { // Actually, each new Prestataire will have the 'prestataire' as TypePrestataire
$prestataire->setRaison($raison); // @TODO: add a column 'type' in the CSV file (to choose a TypePrestataire)?
} else { $prestataire->setTypePrestataire($this->em->getRepository(TypePrestataire::class)->findOneBy([
$this->addWarning($row, $line, 'raison', 'empty'); 'slug' => 'prestataire'
} ]));
if (!empty($metier)) {
$prestataire->setMetier($metier); foreach ($requiredColumns as $column) {
} else { // Special processings for these fields => so we skip them
$this->addWarning($row, $line, 'metier', 'empty'); if (in_array($column, ['groupe', 'adresse', 'cpostal', 'ville'])) continue;
}
if (!empty($statut)) { $prestataire->{'set'.ucfirst($column)}($row[$column]);
$prestataire->setStatut($statut);
} else {
$this->addWarning($row, $line, 'statut', 'empty');
}
if (!empty($responsable)) {
$prestataire->setResponsable($responsable);
} else {
$this->addWarning($row, $line, 'responsable', 'empty');
}
if (!empty($iban)) {
$prestataire->setIban($iban);
} else {
$this->addWarning($row, $line, 'iban', 'empty');
}
if (!empty($siret)) {
$prestataire->setSiret($siret);
} else {
$this->addWarning($row, $line, 'siret', 'empty');
} }
if (!empty($web)) {
$prestataire->setWeb($web); // Special processing for the 'ecompte' field
} else { if ($e =& $row['ecompte']) {
$this->addWarning($row, $line, 'web', 'empty'); $e = $this->tofloat($e);
} }
if (!empty($horaires)) {
$prestataire->setHoraires($horaires); foreach ($warningColumns as $column) {
} else { if ($row[$column]) {
$this->addWarning($row, $line, 'horaires', 'empty'); $prestataire->{'set'.ucfirst($column)}($row[$column]);
} else {
$this->addWarning($row, $line, $column, 'empty');
}
} }
if (!empty($description)) {
$prestataire->setDescription($description); /**
} else { * If one or many Contacts are present, we create them for the Prestataire.
$this->addWarning($row, $line, 'description', 'empty'); * If a phone or an email is defined, the associated 'contact' field must be defined too!
*/
for ($i = 1; $i < 10; $i++) {
$name = $row["contact$i"] ?? null;
$phone = $row["phone$i"] ?? null;
$email = $row["email$i"] ?? null;
if ($name) {
$contact = new ContactPrestataire();
$contact->setPrestataire($prestataire);
$contact->setEnabled(true);
$contact->setName($name);
$contact->setTel($row["phone$i"] ?? '');
$contact->setEmail($row["email$i"] ?? '');
$this->em->persist($contact);
} elseif ($phone || $email) {
$this->addError($row, $line, "contact$i",
$this->translator->trans('prestataire.column_required', ["contact$i"], 'import')
);
$hasError = true;
}
} }
$cptContact = 1; if ($hasError) {
while (array_key_exists("contact".$cptContact, $row) && $cptContact < 10) { $this->nberrors++;
$contact = array_key_exists('contact'.$cptContact, $row) ? $row['contact'.$cptContact] : ''; continue;
$phone = array_key_exists('phone'.$cptContact, $row) ? $row['phone'.$cptContact] : '';
$email = array_key_exists('email'.$cptContact, $row) ? $row['email'.$cptContact] : '';
$contactC = new ContactPrestataire();
$contactC->setPrestataire($prestataire);
$contactC->setEnabled(true);
$contactC->setName($contact);
$contactC->setTel($phone);
$contactC->setEmail($email);
$this->em->persist($contactC);
++$cptContact;
} }
// Importer les gestionnaires du prestataire s'ils existent // Importer les gestionnaires du prestataire s'ils existent
$groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire'); $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire');
$gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire); $gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire);
$prestataire->setUsers($gestionnaires); $prestataire->setUsers($gestionnaires);
if (!empty($ecompte)) { /**
$prestataire->setEcompte($this->tofloat($ecompte)); * If no Groupe object exists for the 'groupe' field, we create one.
} else { * Note: at this point, the 'groupe' field is necessarily not empty (because it was required above).
$this->addWarning($row, $line, 'ecompte', 'empty'); */
$groupe = $row['groupe'];
$groupeObj = $this->em->getRepository(Groupe::class)->findOneBy(['name' => $groupe]);
if (! $groupeObj) {
$groupeObj = new Groupe();
$groupeObj->setName($groupe);
$groupeObj->setSiege($this->siege);
$this->em->persist($groupeObj);
$this->addSuccess($row, $line, 'groupe',
$this->translator->trans('prestataire.groupe_notfound_created', [$groupe], 'import')
);
} }
if (!empty($groupe)) { $prestataire->setGroupe($groupeObj);
$groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $groupe));
if (empty($groupeFound)) { if ($cotisations = $row['cotisations']) {
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
$this->em->persist($groupeFound);
$this->addWarning($row, $line, 'groupe', $this->translator->trans('Groupe introuvable, création du groupe : ').$groupe);
}
$prestataire->setGroupe($groupeFound);
} else {
$this->addWarning($row, $line, 'groupe', 'empty');
}
if (!empty($cotisations)) {
$cotisationArray = explode(',', $cotisations); $cotisationArray = explode(',', $cotisations);
if (count($cotisationArray) > 0) { foreach ($cotisationArray as $cotisationDetails) {
foreach ($cotisationArray as $cotisationDetails) { $cotisation = new CotisationPrestataire();
$cotisation = new CotisationPrestataire(); $now = new DateTime();
$now = new DateTime(); $cotisation->setReference('Import du '.$now->format('d/m/Y H:i'));
$cotisation->setReference('Import du '.$now->format('d/m/Y H:i')); $cotisation->setOperateur($operateur);
$cotisation->setOperateur($this->getUser()); $cotisation->setRole('ROLE_SUPER_ADMIN');
$cotisation->setRole('ROLE_SUPER_ADMIN'); $cotisation->setExpediteur($prestataire);
$cotisation->setExpediteur($prestataire); $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
$cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE); $cotisationDetailsArray = explode(':', $cotisationDetails);
$cotisationDetailsArray = explode(':', $cotisationDetails); if (count($cotisationDetailsArray) == 1) {
if (count($cotisationDetailsArray) == 1) { $cotisation->setMontant(intval($cotisationDetails[0]));
$cotisation->setMontant(intval($cotisationDetails)); $cotisation->getCotisationInfos()->setDebut($now);
$cotisation->getCotisationInfos()->setDebut($now); $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year'));
$cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year')); } else {
} else { $cotisation->setMontant(intval($cotisationDetailsArray[0]));
$cotisation->setMontant(intval($cotisationDetailsArray[0])); $cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1]));
$cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1])); $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101'));
$cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101')); $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231'));
$cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231'));
}
$this->em->persist($cotisation);
$this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajouté : ').$groupe);
} }
$this->em->persist($cotisation);
$this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajouté : ').$groupe);
} }
} else { } else {
$this->addWarning($row, $line, 'cotisations', 'empty'); $this->addWarning($row, $line, 'cotisations', 'empty');
} }
if (!empty($rubriques)) {
if ($rubriques = $row['rubriques']) {
$rubriquesArray = explode(',', $rubriques); $rubriquesArray = explode(',', $rubriques);
foreach ($rubriquesArray as $rubrique) { foreach ($rubriquesArray as $rubrique) {
$rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('slug' => $this->slugify($rubrique))); $rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('slug' => $this->slugify($rubrique)));
...@@ -527,11 +541,13 @@ class ImportController extends CRUDController ...@@ -527,11 +541,13 @@ class ImportController extends CRUDController
$this->em->persist($rubriquesFound); $this->em->persist($rubriquesFound);
$this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ').$rubrique); $this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ').$rubrique);
} }
$prestataire->addRubrique($rubriquesFound);
} }
} else { } else {
$this->addWarning($row, $line, 'rubriques', 'empty'); $this->addWarning($row, $line, 'rubriques', 'empty');
} }
if (!empty($tags)) {
if ($tags = $row['tags']) {
$tagsArray = explode(',', $tags); $tagsArray = explode(',', $tags);
foreach ($tagsArray as $tag) { foreach ($tagsArray as $tag) {
$tagsFound = $this->em->getRepository(EtatPrestataire::class)->findOneBy(array('slug' => $this->slugify($tag))); $tagsFound = $this->em->getRepository(EtatPrestataire::class)->findOneBy(array('slug' => $this->slugify($tag)));
...@@ -545,40 +561,58 @@ class ImportController extends CRUDController ...@@ -545,40 +561,58 @@ class ImportController extends CRUDController
} else { } else {
$this->addWarning($row, $line, 'tags', 'empty'); $this->addWarning($row, $line, 'tags', 'empty');
} }
if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
$geolocP = new GeolocPrestataire(); /**
$geolocP->setName('Adresse'); * Add a Geoloc for this Prestataire.
$geolocP->setPrestataire($prestataire); * At this point, 'adresse', 'cpostal' and 'ville' fields exist and are not empty.
$geolocFound = new Geoloc(); */
$geolocFound->setEnabled(true); $geoloc = new Geoloc();
$geolocFound->setAdresse($adresse); $geoloc->setEnabled(true);
$geolocFound->setCpostal(intval($cpostal)); $geoloc->setAdresse($row['adresse']);
$geolocFound->setVille($ville); $geoloc->setCpostal($row['cpostal']);
$geolocP->setGeoloc($geolocFound); $geoloc->setVille($row['ville']);
$prestataire->setGeolocs([$geolocP]);
$this->em->persist($geolocP); $geolocP = new GeolocPrestataire();
} $geolocP->setName('Adresse');
$geolocP->setPrestataire($prestataire);
$geolocP->setGeoloc($geoloc);
$this->em->persist($geolocP);
$prestataire->setGeolocs([$geolocP]);
} else { } else {
$this->addError($row, $line, 'name', $this->translator->trans("Le prestataire avec cette raison '".$raison."' existe déjà !")); $this->addError($row, $line, 'raison',
$this->translator->trans('prestataire.already_exists', [$row['raison']], 'import')
);
$this->nberrors++; $this->nberrors++;
$hasError = true; $hasError = true;
} }
if (!$hasError) { if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire bien ajouté : ').$prestataire->__toString());
$this->nbsuccess++;
$this->em->persist($prestataire); $this->em->persist($prestataire);
$this->em->flush(); $this->em->flush();
$this->em->clear(); $this->em->clear();
}
$line++; // em is fully cleared: we need to refetch entities we get from em during process
$operateur = $this->em->getRepository(User::class)->findOneById($operateur_id);
$this->siege = $this->em->getRepository(Siege::class)->findOneById(1);
$this->addSuccess($row, $line, 'user',
$this->translator->trans('prestataire.added', [(string) $prestataire], 'import')
);
$this->nbsuccess++;
}
} }
ksort($this->errors); ksort($this->errors);
ksort($this->warnings); ksort($this->warnings);
} }
private function importAdherent($csvRows) private function importAdherent($csvRows)
{ {
// Batch operations with doctrine require some workaround
$operateur = $this->getUser();
$operateur_id = $operateur->getId();
// Iterate over the reader and write each row to the database // Iterate over the reader and write each row to the database
// groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte // groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte
$line = 1; $line = 1;
...@@ -678,23 +712,43 @@ class ImportController extends CRUDController ...@@ -678,23 +712,43 @@ class ImportController extends CRUDController
$cotisation = new CotisationAdherent(); $cotisation = new CotisationAdherent();
$now = new DateTime(); $now = new DateTime();
$cotisation->setReference('Import du '.$now->format('d/m/Y H:i')); $cotisation->setReference('Import du '.$now->format('d/m/Y H:i'));
$cotisation->setOperateur($this->getUser()); $cotisation->setOperateur($operateur);
$cotisation->setRole('ROLE_ADHERENT'); $cotisation->setRole('ROLE_ADHERENT');
$cotisation->setExpediteur($adherent); $cotisation->setExpediteur($adherent);
$cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE); $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
$cotisationDetailsArray = explode(':', $cotisationDetails); $cotisationDetailsArray = explode(':', $cotisationDetails);
if (count($cotisationDetailsArray) == 1) { if (count($cotisationDetailsArray) == 1) {
// fix #201: A 'cotisation' can't be zero! (because of the Flux error management)
if (0 === intval($cotisationDetails)) {
$this->addError($row, $line, 'cotisations',
$this->translator->trans('adherent.cotisations.isZero', [], 'import')
);
$this->nberrors++;
$line++;
continue;
}
$cotisation->setMontant(intval($cotisationDetails)); $cotisation->setMontant(intval($cotisationDetails));
$cotisation->getCotisationInfos()->setDebut($now); $cotisation->getCotisationInfos()->setDebut($now);
$cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year')); $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year'));
} else { } else {
// fix #201: A 'cotisation' can't be zero! (because of the Flux error management)
if (0 === intval($cotisationDetailsArray[0])) {
$this->addError($row, $line, 'cotisations',
$this->translator->trans('adherent.cotisations.isZero', [], 'import')
);
$this->nberrors++;
$line++;
continue;
}
$cotisation->setMontant(intval($cotisationDetailsArray[0])); $cotisation->setMontant(intval($cotisationDetailsArray[0]));
$cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1])); $cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1]));
$cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101')); $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101'));
$cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231')); $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231'));
} }
$this->em->persist($cotisation); $this->em->persist($cotisation);
$this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajouté : ').$groupe); $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajoutée : ').$groupe);
} }
} }
} else { } else {
...@@ -717,6 +771,8 @@ class ImportController extends CRUDController ...@@ -717,6 +771,8 @@ class ImportController extends CRUDController
} }
$this->em->flush(); $this->em->flush();
$this->em->clear(); $this->em->clear();
// em is fully cleared: we need to refetch entities we get from em during process
$operateur = $this->em->getRepository(User::class)->findOneBy(array('id' => $operateur_id));
} }
$line++; $line++;
......
...@@ -14,6 +14,7 @@ use App\Entity\Prestataire; ...@@ -14,6 +14,7 @@ use App\Entity\Prestataire;
use App\Entity\Siege; use App\Entity\Siege;
use App\Entity\User; use App\Entity\User;
use App\Entity\Usergroup; use App\Entity\Usergroup;
use App\Entity\Payment;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Form\Type\AdhererFormType; use App\Form\Type\AdhererFormType;
use App\Form\Type\ContactFormType; use App\Form\Type\ContactFormType;
...@@ -49,6 +50,7 @@ use Symfony\Component\Security\Core\Security as Secur; ...@@ -49,6 +50,7 @@ use Symfony\Component\Security\Core\Security as Secur;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Templating\EngineInterface; use Symfony\Component\Templating\EngineInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class IndexController extends AbstractController class IndexController extends AbstractController
{ {
...@@ -147,7 +149,7 @@ class IndexController extends AbstractController ...@@ -147,7 +149,7 @@ class IndexController extends AbstractController
$configs = $form['config']->getData(); $configs = $form['config']->getData();
$groupe->setSiege($siege); $groupe->setSiege($siege);
$comptoir->setGroupe($groupe); $comptoir->setGroupe($groupe);
//Création du prestataire recevant les cotisations //Création du prestataire recevant les cotisations
$presta = new Prestataire(); $presta = new Prestataire();
$presta->setMlc(true); $presta->setMlc(true);
...@@ -178,7 +180,7 @@ class IndexController extends AbstractController ...@@ -178,7 +180,7 @@ class IndexController extends AbstractController
$userAPI->setEmail('userapi@kohinos.fr'); $userAPI->setEmail('userapi@kohinos.fr');
$userAPI->addRole('ROLE_API'); $userAPI->addRole('ROLE_API');
$this->userManager->updateUser($userAPI); $this->userManager->updateUser($userAPI);
$this->em->flush(); $this->em->flush();
$this->addFlash( $this->addFlash(
'success', 'success',
...@@ -202,47 +204,29 @@ class IndexController extends AbstractController ...@@ -202,47 +204,29 @@ class IndexController extends AbstractController
*/ */
public function adhererAction(Request $request) public function adhererAction(Request $request)
{ {
// @TODO : formulaire d'adhésion sans cotisation ? à valider après ?
$adherent = new Adherent(); $adherent = new Adherent();
$user = $this->userManager->createUser();
$groupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$user->setEnabled(false);
$user->addPossiblegroup($groupe);
$user->addGroup($groupe);
$user->addRole('ROLE_ADHERENT');
$adherent->setEcompte('0');
$user->setAdherent($adherent);
$adherent->setUser($user);
// @TODO : ajouter le moyen de payer sa cotisation en CB directement
// if (count($adherent->getUser()->getCotisations()) <= 0) {
// $cotisation = new Cotisation();
// $cotisation->setMontant(floatval($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::COTISATION_ADHERENT)));
// $cotisation->setOperateur($adherent->getUser());
// $cotisation->setExpediteur($adherent);
// $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
// $cotisation->setDebut(new \DateTime());
// $cotisation->setFin(new \DateTime('+ 1 year'));
// $adherent->getUser()->addCotisation($cotisation);
// }
if ($adherent->getGeoloc() == null) {
$adherent->setGeoloc(new Geoloc());
}
$form = $this->createForm(AdhererFormType::class, $adherent); $form = $this->createForm(AdhererFormType::class, $adherent);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted()) { if ($form->isSubmitted()) {
if ($form->isValid()) { if ($form->isValid()) {
$adherentNew = $form->getData(); $adherentNew = $form->getData();
// @TODO : redirect to paiement page
// Serialize form data in json to store with payment object and persist when payment is valid
// $this->em->persist($adherentNew); $serializer = $this->container->get('serializer');
// $this->em->flush(); $data = $serializer->normalize($adherentNew, null,
// $this->addFlash( [AbstractNormalizer::ATTRIBUTES => ['user' => ['username', 'email', 'firstname', 'lastname', 'plainPassword'],
// 'success', 'groupe' => ['id'],
// 'Adhésion bien pris en compte, vous recevrez un email très bientôt !' 'geoloc' => ['adresse', 'cpostal', 'ville']]]);
// ); $jsondata = $serializer->serialize($data, 'json');
return $this->redirectToRoute('index');
// Redirect to payment page
return $this->forward('App\Controller\FluxController::preparePaymentAction', [
'form' => $form,
'type' => Payment::TYPE_ADHESION,
'extra_data' => $jsondata
]);
} else { } else {
$this->addFlash( $this->addFlash(
'error', 'error',
...@@ -334,7 +318,7 @@ class IndexController extends AbstractController ...@@ -334,7 +318,7 @@ class IndexController extends AbstractController
$this->authenticator, $this->authenticator,
'main' 'main'
); );
return $this->redirectToRoute('sonata_admin_dashboard'); return $this->redirectToRoute('sonata_admin_dashboard');
} }
......
...@@ -40,7 +40,7 @@ class UserAdherentController extends FluxController ...@@ -40,7 +40,7 @@ class UserAdherentController extends FluxController
$this->em->flush(); $this->em->flush();
$this->addFlash( $this->addFlash(
'success', 'success',
$this->translator->trans('Infos du prestataire modifiée !') $this->translator->trans('Infos de l\'adhérent modifiées !')
); );
$referer = $request->headers->get('referer'); $referer = $request->headers->get('referer');
if ($referer && !$request->isXmlHttpRequest()) { if ($referer && !$request->isXmlHttpRequest()) {
......
...@@ -52,13 +52,8 @@ class UserController extends AbstractController ...@@ -52,13 +52,8 @@ class UserController extends AbstractController
if ($form->isSubmitted()) { if ($form->isSubmitted()) {
$cotisation = $form->getData(); $cotisation = $form->getData();
if ($form->get('payMLC')->isClicked()) {
$cotisation->setMoyen(MoyenEnum::MOYEN_MLC);
} else {
$cotisation->setMoyen(MoyenEnum::MOYEN_CB);
}
if ($form->isValid()) { if ($form->isValid()) {
if ($form->get('payMLC')->isClicked()) { if ($cotisation->getMoyen() == MoyenEnum::MOYEN_MLC) {
$cotisation->setRecu(true); $cotisation->setRecu(true);
$this->em->persist($cotisation); $this->em->persist($cotisation);
$this->em->flush(); $this->em->flush();
...@@ -78,7 +73,7 @@ class UserController extends AbstractController ...@@ -78,7 +73,7 @@ class UserController extends AbstractController
} else { } else {
$this->addFlash( $this->addFlash(
'error', 'error',
$this->translator->trans('Problème avec la cotisation !') $this->translator->trans('Problème avec la cotisation !') . ' ' . $form->getErrors()
); );
} }
} }
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Flux;
use App\Entity\Prestataire; use App\Entity\Prestataire;
use App\Entity\Rubrique; use App\Entity\Rubrique;
use App\Entity\TransactionPrestataireAdherent; use App\Entity\TransactionPrestataireAdherent;
...@@ -17,9 +16,6 @@ use App\Form\Type\TransfertPrestataireSiegeFormType; ...@@ -17,9 +16,6 @@ use App\Form\Type\TransfertPrestataireSiegeFormType;
use App\Form\Type\AchatMonnaiePrestataireFormType; use App\Form\Type\AchatMonnaiePrestataireFormType;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sonata\Exporter\Handler;
use Sonata\Exporter\Source\DoctrineORMQuerySourceIterator;
use Sonata\Exporter\Writer\CsvWriter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
...@@ -41,7 +37,7 @@ class UserPrestataireController extends FluxController ...@@ -41,7 +37,7 @@ class UserPrestataireController extends FluxController
$this->em->flush(); $this->em->flush();
$this->addFlash( $this->addFlash(
'success', 'success',
$this->translator->trans('Infos du prestataire modifiée !') $this->translator->trans('Infos du prestataire modifiées !')
); );
$referer = $request->headers->get('referer'); $referer = $request->headers->get('referer');
if ($referer && !$request->isXmlHttpRequest()) { if ($referer && !$request->isXmlHttpRequest()) {
...@@ -60,7 +56,12 @@ class UserPrestataireController extends FluxController ...@@ -60,7 +56,12 @@ class UserPrestataireController extends FluxController
*/ */
public function groupePrestataireInscriptionAction(Request $request) public function groupePrestataireInscriptionAction(Request $request)
{ {
$form = $this->createForm(GroupePrestataireInscriptionFormType::class, $this->session->get('_prestagere')); //#180: at this point, the Prestataire entity is detached from the EntityManager (because we get it from the session)
$presta = $this->session->get('_prestagere');
//#180: $presta now refers to the fully managed copy returned by the merge operation.
$presta = $this->em->merge($presta);
$form = $this->createForm(GroupePrestataireInscriptionFormType::class, $presta);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
...@@ -101,7 +102,7 @@ class UserPrestataireController extends FluxController ...@@ -101,7 +102,7 @@ class UserPrestataireController extends FluxController
return $this->manageFluxForm( return $this->manageFluxForm(
$request, $request,
$form, $form,
$this->session->get('_prestagere')->getCompte(), $this->session->get('_prestagere')->getEcompte(),
$this->translator->trans('Transaction bien effectuée !'), $this->translator->trans('Transaction bien effectuée !'),
$this->translator->trans('Transaction à un ').$type $this->translator->trans('Transaction à un ').$type
); );
...@@ -121,7 +122,7 @@ class UserPrestataireController extends FluxController ...@@ -121,7 +122,7 @@ class UserPrestataireController extends FluxController
return $this->manageFluxForm( return $this->manageFluxForm(
$request, $request,
$form, $form,
$this->session->get('_prestagere')->getCompte(), $this->session->get('_prestagere')->getEcompte(),
$this->translator->trans('Reconversion envoyée, elle sera validée lorsque le virement sera effectué !'), $this->translator->trans('Reconversion envoyée, elle sera validée lorsque le virement sera effectué !'),
$this->translator->trans('Reconversion de monnaie au siège') $this->translator->trans('Reconversion de monnaie au siège')
); );
...@@ -154,69 +155,4 @@ class UserPrestataireController extends FluxController ...@@ -154,69 +155,4 @@ class UserPrestataireController extends FluxController
]); ]);
} }
/**
* Export all transferts / transactions for prestataire
*
* @param Request $request Request
* @param String $format Format of export ('json', 'xml', 'csv', 'xls')
* @Route("/prestataire/export/{format}/", name="exportPrestaFlux", defaults={"format": "csv"})
* @IsGranted("ROLE_PRESTATAIRE")
*/
public function exportFluxAction(Request $request, $format = 'csv')
{
// Prepare the data source
$query = $this->em->getRepository(Flux::class)->getQueryByPrestataire($this->session->get('_prestagere'));
$fields = ['expediteur', 'destinataire', 'type', 'parenttype', 'montant', 'moyen', 'operateur'];
$source = new DoctrineORMQuerySourceIterator($query, $fields);
$filename = sprintf(
'export_flux_%s.%s',
date('Y_m_d_H_i_s', strtotime('now')),
$format
);
return $this->getResponse(
$format,
$filename,
$source
);
}
private function getResponse($format, $filename, SourceIteratorInterface $source)
{
switch ($format) {
case 'xls':
$writer = new XlsWriter('php://output');
$contentType = 'application/vnd.ms-excel';
break;
case 'xml':
$writer = new XmlWriter('php://output');
$contentType = 'text/xml';
break;
case 'json':
$writer = new JsonWriter('php://output');
$contentType = 'application/json';
break;
case 'csv':
$writer = new CsvWriter('php://output', ',', '"', '\\', true, true);
$contentType = 'text/csv';
break;
default:
throw new \RuntimeException('Invalid format');
}
$callback = static function () use ($source, $writer) {
$handler = Handler::create($source, $writer);
$handler->export();
};
return new StreamedResponse($callback, 200, [
'Content-Type' => $contentType,
'Content-Disposition' => sprintf('attachment; filename="%s"', $filename),
]);
}
} }
...@@ -122,11 +122,13 @@ class Adherent ...@@ -122,11 +122,13 @@ class Adherent
public function __toString(): string public function __toString(): string
{ {
if (!empty($this->getUser()->getLastname().$this->getUser()->getFirstname())) { if (!empty($this->getUser())) {
if (!empty($this->getUser()->getLastname().$this->getUser()->getFirstname())) {
return $this->getUser()->getLastname().' '.$this->getUser()->getFirstname(); return $this->getUser()->getLastname().' '.$this->getUser()->getFirstname();
} }
if (!empty($this->getUser()->getUsername())) { if (!empty($this->getUser()->getUsername())) {
return $this->getUser()->getUsername(); return $this->getUser()->getUsername();
}
} }
return 'Adhérent ['.$this->getId().']'; return 'Adhérent ['.$this->getId().']';
} }
......
...@@ -11,7 +11,7 @@ trait ContactEmailTelTrait ...@@ -11,7 +11,7 @@ trait ContactEmailTelTrait
/** /**
* @var null|string * @var null|string
* *
* @ORM\Column(name="tel", type="string", length=20, nullable=true) * @ORM\Column(name="tel", type="string", length=100, nullable=true)
* @Groups({"read", "write"}) * @Groups({"read", "write"})
*/ */
protected $tel; protected $tel;
......
...@@ -28,6 +28,7 @@ class GlobalParameter ...@@ -28,6 +28,7 @@ class GlobalParameter
const MAP_CENTER = 'MAP_CENTER'; const MAP_CENTER = 'MAP_CENTER';
const MAP_ZOOM = 'MAP_ZOOM'; const MAP_ZOOM = 'MAP_ZOOM';
const USE_PAYZEN = 'USE_PAYZEN'; const USE_PAYZEN = 'USE_PAYZEN';
const APP_TITLE = 'APP_TITLE';
/** /**
* @ORM\Id() * @ORM\Id()
......
...@@ -11,9 +11,10 @@ use Payum\Core\Model\Payment as BasePayment; ...@@ -11,9 +11,10 @@ use Payum\Core\Model\Payment as BasePayment;
class Payment extends BasePayment class Payment extends BasePayment
{ {
const TYPE_ACHAT_MONNAIE_ADHERENT = 'achat_monnaie_adherent'; const TYPE_ACHAT_MONNAIE_ADHERENT = 'achat_monnaie_adherent';
const TYPE_ACHAT_MONNAIE_PRESTA = 'achat_monnaie_presta'; const TYPE_ACHAT_MONNAIE_PRESTA = 'achat_monnaie_presta';
const TYPE_COTISATION_ADHERENT = 'cotisation_adherent'; const TYPE_COTISATION_ADHERENT = 'cotisation_adherent';
const TYPE_COTISATION_PRESTA = 'cotisation_presta'; const TYPE_COTISATION_PRESTA = 'cotisation_presta';
const TYPE_ADHESION = 'adhesion';
/** /**
...@@ -40,6 +41,14 @@ class Payment extends BasePayment ...@@ -40,6 +41,14 @@ class Payment extends BasePayment
*/ */
protected $flux_data; protected $flux_data;
/**
* @var string|null
* Extra data to persist if payment valid
*
* @ORM\Column(type="text", nullable=true)
*/
protected $extra_data;
/** /**
* @return string * @return string
*/ */
...@@ -75,4 +84,22 @@ class Payment extends BasePayment ...@@ -75,4 +84,22 @@ class Payment extends BasePayment
$this->flux_data = $flux_data; $this->flux_data = $flux_data;
return $this; return $this;
} }
/**
* @return string
*/
public function getExtraData(): ?string
{
return $this->extra_data;
}
/**
* @param string $extra_data
* @return Payment
*/
public function setExtraData(string $extra_data): self
{
$this->extra_data = $extra_data;
return $this;
}
} }
...@@ -39,6 +39,7 @@ class Rubrique ...@@ -39,6 +39,7 @@ class Rubrique
* @ORM\Id * @ORM\Id
* @ORM\Column(name="id", type="integer") * @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue * @ORM\GeneratedValue
* @Groups("read")
*/ */
protected $id; protected $id;
......
...@@ -134,7 +134,13 @@ class FormFactory ...@@ -134,7 +134,13 @@ class FormFactory
if (empty($user) || empty($this->session->get('_prestagere'))) { if (empty($user) || empty($this->session->get('_prestagere'))) {
throw new \Exception("[FORM 6] Opération impossible !"); throw new \Exception("[FORM 6] Opération impossible !");
} }
$form = $this->ff->create(GroupePrestataireInscriptionFormType::class, $this->session->get('_prestagere'), array('action' => $this->router->generate('groupeprestataire_inscription')));
//#180: at this point, the Prestataire entity is detached from the EntityManager (because we get it from the session)
$presta = $this->session->get('_prestagere');
//#180: $presta now refers to the fully managed copy returned by the merge operation.
$presta = $this->em->merge($presta);
$form = $this->ff->create(GroupePrestataireInscriptionFormType::class, $presta, array('action' => $this->router->generate('groupeprestataire_inscription')));
return $form->createView(); return $form->createView();
} }
......
...@@ -5,11 +5,17 @@ namespace App\Form\Type; ...@@ -5,11 +5,17 @@ namespace App\Form\Type;
use App\Entity\Siege; use App\Entity\Siege;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Form\Type\FluxFormType; use App\Form\Type\FluxFormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\RangeType;
class AchatMonnaieFormType extends FluxFormType class AchatMonnaieFormType extends FluxFormType
{ {
private $defaultMontantSlider = 30;
private $maxMontantSlider = 250;
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder $builder
...@@ -22,6 +28,38 @@ class AchatMonnaieFormType extends FluxFormType ...@@ -22,6 +28,38 @@ class AchatMonnaieFormType extends FluxFormType
'entity_class' => Siege::class, 'entity_class' => Siege::class,
'em' => $this->em 'em' => $this->em
)) ))
->add('montantradio', ChoiceType::class, array(
'choices' => [
'30 €' => 30,
'50 €' => 50,
'100 €' => 100,
],
'required' => false,
'placeholder' => false,
'data' => $this->defaultMontantSlider,
'expanded' => true,
'multiple' => false,
'label' => 'Sélectionnez un montant :',
'mapped' => false
))
->add('montant', RangeType::class, [
'attr' => [
"min" => 0,
"max" => $this->maxMontantSlider,
"data-provide" => "slider",
"data-slider-ticks" => "[0, 50, 100, 150, 200, 250]",
"data-slider-ticks-labels" => '[0, 50, 100, 150, 200, 250]',
"data-slider-ticks-positions" => '[0, 20, 40, 60, 80, 100]',
"data-slider-min" => "0",
"data-slider-max" => $this->maxMontantSlider,
"data-slider-step" => "5",
"data-slider-value" => $this->defaultMontantSlider,
"style" => "width:100%;",
"class" => "achatmonnaie-montant-slider"
],
'label' => 'Ou choisissez librement le montant : ',
'required' => false
])
; ;
} }
......
...@@ -3,18 +3,17 @@ ...@@ -3,18 +3,17 @@
namespace App\Form\Type; namespace App\Form\Type;
use App\Entity\Cotisation; use App\Entity\Cotisation;
use App\Entity\GlobalParameter;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Form\Type\CotisationInfosFormType; use App\Form\Type\CotisationInfosFormType;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\Constraints\NotBlank;
class AddCotisationFormType extends AbstractType class AddCotisationFormType extends AbstractType
{ {
...@@ -30,28 +29,21 @@ class AddCotisationFormType extends AbstractType ...@@ -30,28 +29,21 @@ class AddCotisationFormType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$now = new \DateTime(); $now = new \DateTime();
$flux = $options['data'];
if (empty($this->security) || empty($this->security->getUser())) {
throw new \Exception("Opération impossible ! Utilisateur non connecté !");
}
$builder $builder
->add('operateur', HiddenType::class, array(
'entity_class' => User::class,
'em' => $this->em,
'data_class' => null,
'data' => $this->security->getUser()
))
->add('reference', HiddenType::class, array( ->add('reference', HiddenType::class, array(
'label' => 'Reference :', 'label' => 'Reference :',
'required' => true, 'required' => true,
'data' => 'Cotisation '.$now->format('Y') 'data' => 'Adhésion '.$now->format('d/m/Y')
)) ))
->add('montant', HiddenType::class, array( ->add('montant', IntegerType::class, array(
'data' => intval($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::COTISATION_ADHERENT)),
'constraints' => [
new NotBlank()
],
)) ))
->add('moyen', HiddenType::class, array( ->add('moyen', HiddenType::class, array(
'data' => MoyenEnum::MOYEN_AUTRE, 'data' => MoyenEnum::MOYEN_CB,
)) ))
;
; ;
} }
......
...@@ -8,7 +8,6 @@ use App\Entity\Prestataire; ...@@ -8,7 +8,6 @@ use App\Entity\Prestataire;
use App\Entity\User; use App\Entity\User;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Form\Type\GeolocFormType; use App\Form\Type\GeolocFormType;
use App\Form\Type\RegistrationFormType;
use App\Form\Type\UserInfosFormType; use App\Form\Type\UserInfosFormType;
use Doctrine\DBAL\Types\FloatType; use Doctrine\DBAL\Types\FloatType;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
......
...@@ -4,26 +4,16 @@ namespace App\Form\Type; ...@@ -4,26 +4,16 @@ namespace App\Form\Type;
use App\Entity\Adherent; use App\Entity\Adherent;
use App\Entity\Groupe; use App\Entity\Groupe;
use App\Entity\Prestataire;
use App\Entity\User;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Form\Type\GeolocFormType; use App\Form\Type\GeolocFormType;
use App\Form\Type\RegistrationFormType; use App\Form\Type\RegistrationFormType;
use Doctrine\DBAL\Types\FloatType;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
...@@ -46,28 +36,27 @@ class AdhererFormType extends AbstractType ...@@ -46,28 +36,27 @@ class AdhererFormType extends AbstractType
$builder $builder
->add('user', RegistrationFormType::class, array( ->add('user', RegistrationFormType::class, array(
'label' => false, 'label' => false,
'required' => false 'required' => true
))
->add('groupe', ChoiceType::class, array(
'required' => true,
'label' => 'Groupe local',
'choices' => $this->container->get('doctrine')->getRepository(Groupe::class)->findAll(),
'choice_label' => 'name',
'placeholder' => 'Choisir un groupe',
)) ))
// ->add('groupe', ChoiceType::class, array(
// 'required' => true,
// 'label' => 'GROUPE LOCAL',
// 'choices' => $this->container->get('doctrine')->getRepository(Groupe::class)->findAll(),
// 'choice_label' => 'name',
// 'placeholder' => 'Choisir un groupe',
// ))
->add('geoloc', GeolocFormType::class, array( ->add('geoloc', GeolocFormType::class, array(
'label' => false, 'label' => false,
'required' => true, 'required' => true,
'with_geoloc' => false, 'with_geoloc' => false,
'with_latlon' => false 'with_latlon' => false
)) ))
// ->add('cotisation', AddCotisationFormType::class, array( ->add('cotisation', AddCotisationFormType::class, array(
// 'label' => false, 'label' => false,
// 'required' => false, 'required' => true,
// 'mapped' => false, 'mapped' => false,
// 'data' => $adherent->getUser()->getCotisations()->last() 'data_class' => null
// )) ))
// ->add('save', SubmitType::class, ['label' => "Valider l'adhésion"])
->add('save', SubmitType::class, ['label' => "Payer en CB"]); ->add('save', SubmitType::class, ['label' => "Payer en CB"]);
; ;
} }
......
...@@ -88,16 +88,21 @@ class CotiserFormType extends AbstractType ...@@ -88,16 +88,21 @@ class CotiserFormType extends AbstractType
'data' => MoyenEnum::MOYEN_MLC, 'data' => MoyenEnum::MOYEN_MLC,
)) ))
; ;
// ->add('moyen', ChoiceType::class, array(
// 'required' => true,
// 'label' => 'Moyen de paiement :',
// 'choices' => $canPayWithMlc ? [MoyenEnum::getTypeName(MoyenEnum::MOYEN_MLC) => MoyenEnum::MOYEN_MLC, MoyenEnum::getTypeName(MoyenEnum::MOYEN_CB) => MoyenEnum::MOYEN_CB] : [MoyenEnum::getTypeName(MoyenEnum::MOYEN_CB) => MoyenEnum::MOYEN_CB]
// ))
if ($canPayWithMlc) { if ($canPayWithMlc) {
$builder->add('payMLC', SubmitType::class, ['label' => "Payer en eMLC"]); $builder->add('payMLC', SubmitType::class, array(
'label' => "Payer en eMLC",
'attr' => [
'class' => 'btn-primary btn cotisationMLCSubmit'
]
));
} }
if ($canPayWithCB) { if ($canPayWithCB) {
$builder->add('payCB', SubmitType::class, ['label' => "Payer en CB"]); $builder->add('payCB', SubmitType::class, array(
'label' => "Payer en CB",
'attr' => [
'class' => 'btn-primary btn cotisationCBSubmit'
]
));
} }
if ($this->security->getUser()->isGranted('ROLE_ADHERENT')) { if ($this->security->getUser()->isGranted('ROLE_ADHERENT')) {
......
...@@ -13,6 +13,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType; ...@@ -13,6 +13,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormError;
...@@ -30,7 +31,10 @@ class FluxFormType extends AbstractType ...@@ -30,7 +31,10 @@ class FluxFormType extends AbstractType
protected $container; protected $container;
protected $session; protected $session;
public function __construct(EntityManagerInterface $em, Security $security, ContainerInterface $container, SessionInterface $session) public function __construct(EntityManagerInterface $em,
Security $security,
ContainerInterface $container,
SessionInterface $session)
{ {
$this->em = $em; $this->em = $em;
$this->security = $security; $this->security = $security;
...@@ -96,9 +100,11 @@ class FluxFormType extends AbstractType ...@@ -96,9 +100,11 @@ class FluxFormType extends AbstractType
$builder $builder
->add('reference', TextType::class, array( ->add('reference', TextType::class, array(
'label' => 'Reference :', 'label' => 'Reference :',
'required' => false 'required' => true
))
->add('save', SubmitType::class, array(
'label' => "Valider"
)) ))
->add('save', SubmitType::class, ['label' => "Valider"])
->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($builder) { ->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($builder) {
$flux = $event->getData(); $flux = $event->getData();
if ($event->getForm()->isValid() && (!$flux || null === $flux->getId()) && $flux->getParenttype() == Flux::TYPE_COTISATION && $flux->getMoyen() == MoyenEnum::MOYEN_MLC) { if ($event->getForm()->isValid() && (!$flux || null === $flux->getId()) && $flux->getParenttype() == Flux::TYPE_COTISATION && $flux->getMoyen() == MoyenEnum::MOYEN_MLC) {
......
...@@ -24,6 +24,12 @@ class GlobalConfigurationFormType extends AbstractType ...@@ -24,6 +24,12 @@ class GlobalConfigurationFormType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder $builder
->add('apptitle', GlobalParameterType::class, array(
'label' => "Tittre de l'application :",
'name_param' => GlobalParameter::APP_TITLE,
'_placeholder' => 'Kohinos',
'required' => true,
))
->add('mlcname', GlobalParameterType::class, array( ->add('mlcname', GlobalParameterType::class, array(
'label' => 'Nom de la Monnaie (long) :', 'label' => 'Nom de la Monnaie (long) :',
'name_param' => GlobalParameter::MLC_NAME, 'name_param' => GlobalParameter::MLC_NAME,
......
...@@ -39,11 +39,11 @@ class RegistrationFormType extends AbstractType ...@@ -39,11 +39,11 @@ class RegistrationFormType extends AbstractType
)) ))
->add('firstname', TextType::class, array( ->add('firstname', TextType::class, array(
'label' => 'Prénom', 'label' => 'Prénom',
'required' => false, 'required' => true,
)) ))
->add('lastname', TextType::class, array( ->add('lastname', TextType::class, array(
'label' => 'Nom', 'label' => 'Nom',
'required' => false, 'required' => true,
)) ))
->add('plainPassword', RepeatedType::class, array( ->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class, 'type' => PasswordType::class,
......
...@@ -28,6 +28,10 @@ class TransactionAdherentAdherentFormType extends TransactionFormType ...@@ -28,6 +28,10 @@ class TransactionAdherentAdherentFormType extends TransactionFormType
'required' => true, 'required' => true,
'label' => 'Adherent :', 'label' => 'Adherent :',
)) ))
->add('destinataireType', HiddenType::class, array(
'data' => 'adherent',
'mapped' => false
))
; ;
} }
......
...@@ -26,7 +26,11 @@ class TransactionAdherentPrestataireFormType extends TransactionFormType ...@@ -26,7 +26,11 @@ class TransactionAdherentPrestataireFormType extends TransactionFormType
'choices' => $this->em->getRepository(Prestataire::class)->findBy(array('enabled' => true, 'mlc' => false), array('raison'=> 'ASC')), 'choices' => $this->em->getRepository(Prestataire::class)->findBy(array('enabled' => true, 'mlc' => false), array('raison'=> 'ASC')),
'placeholder' => 'Prestataire', 'placeholder' => 'Prestataire',
'required' => true, 'required' => true,
'label' => 'Prestataire :', 'label' => 'Prestataire :'
))
->add('destinataireType', HiddenType::class, array(
'data' => 'prestataire',
'mapped' => false
)) ))
; ;
} }
......
...@@ -5,6 +5,7 @@ namespace App\Form\Type; ...@@ -5,6 +5,7 @@ namespace App\Form\Type;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Form\Type\FluxFormType; use App\Form\Type\FluxFormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
class TransactionFormType extends FluxFormType class TransactionFormType extends FluxFormType
...@@ -15,6 +16,12 @@ class TransactionFormType extends FluxFormType ...@@ -15,6 +16,12 @@ class TransactionFormType extends FluxFormType
->add('moyen', HiddenType::class, array( ->add('moyen', HiddenType::class, array(
'data' => MoyenEnum::MOYEN_VIREMENT 'data' => MoyenEnum::MOYEN_VIREMENT
)) ))
->add('save', SubmitType::class, array(
'label' => "Valider",
'attr' => [
'class' => 'btn-primary btn transactionSubmit'
]
))
; ;
} }
......
...@@ -28,6 +28,10 @@ class TransactionPrestataireAdherentFormType extends TransactionFormType ...@@ -28,6 +28,10 @@ class TransactionPrestataireAdherentFormType extends TransactionFormType
'required' => true, 'required' => true,
'label' => 'Adherent :', 'label' => 'Adherent :',
)) ))
->add('destinataireType', HiddenType::class, array(
'data' => 'adherent',
'mapped' => false
))
; ;
} }
......
...@@ -28,6 +28,10 @@ class TransactionPrestatairePrestataireFormType extends TransactionFormType ...@@ -28,6 +28,10 @@ class TransactionPrestatairePrestataireFormType extends TransactionFormType
'required' => true, 'required' => true,
'label' => 'Prestataire :', 'label' => 'Prestataire :',
)) ))
->add('destinataireType', HiddenType::class, array(
'data' => 'prestataire',
'mapped' => false
))
; ;
} }
......
...@@ -38,11 +38,11 @@ class UserFormType extends AbstractType ...@@ -38,11 +38,11 @@ class UserFormType extends AbstractType
)) ))
->add('firstname', TextType::class, array( ->add('firstname', TextType::class, array(
'label' => 'Prénom', 'label' => 'Prénom',
'required' => false, 'required' => true,
)) ))
->add('lastname', TextType::class, array( ->add('lastname', TextType::class, array(
'label' => 'Nom', 'label' => 'Nom',
'required' => false, 'required' => true,
)) ))
->add('phone', TextType::class, array( ->add('phone', TextType::class, array(
'label' => 'Téléphone fixe :', 'label' => 'Téléphone fixe :',
......
<?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 Version20200909121737 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('ALTER TABLE payment ADD extra_data LONGTEXT DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE payment DROP extra_data');
}
}
<?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 Version20200925152216 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('ALTER TABLE contact_comptoir CHANGE tel tel VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE contact_prestataire CHANGE tel tel VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE groupeprestaire CHANGE tel tel VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE siege 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('ALTER TABLE contact_comptoir CHANGE tel tel VARCHAR(20) CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE contact_prestataire CHANGE tel tel VARCHAR(20) CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE groupeprestaire CHANGE tel tel VARCHAR(20) CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE siege CHANGE ecompte ecompte NUMERIC(12, 2) NOT NULL');
}
}
<?php
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Sonata\MediaBundle\Provider\Pool;
use App\Entity\Prestataire;
/**
* This class allows to expose the media of a Prestataire in ApiPlatform
* (because it's not possible with a Media from SonataMediaBundle)
*/
final class ApiNormalizer implements NormalizerInterface, SerializerAwareInterface
{
private $decorated;
private $pool;
public function __construct(NormalizerInterface $decorated, Pool $pool)
{
$this->decorated = $decorated;
$this->pool = $pool;
}
public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}
public function normalize($object, $format = null, array $context = [])
{
$data = $this->decorated->normalize($object, $format, $context);
// In the case of normalizing a Prestataire...
if (! $object instanceof Prestataire) {
return $data;
}
// ... we retrieve its associated Sonata Media (from the Sonata Media's provider, from the providers pool)
if (is_array($data) && $media = $object->getMedia()) {
if ($provider = $this->pool->getProvider($media->getProviderName())) {
$data['media'] = $provider->getHelperProperties($media, 'reference');
}
}
return $data;
}
public function setSerializer(SerializerInterface $serializer)
{
if($this->decorated instanceof SerializerAwareInterface) {
$this->decorated->setSerializer($serializer);
}
}
}
...@@ -338,6 +338,9 @@ ...@@ -338,6 +338,9 @@
"nikic/php-parser": { "nikic/php-parser": {
"version": "v4.1.0" "version": "v4.1.0"
}, },
"nikolaposa/version": {
"version": "3.2.0"
},
"ocramius/package-versions": { "ocramius/package-versions": {
"version": "1.3.0" "version": "1.3.0"
}, },
...@@ -455,6 +458,9 @@ ...@@ -455,6 +458,9 @@
"ref": "421933bf8f0e75546ac8e00cb3eb12904fa2ac1a" "ref": "421933bf8f0e75546ac8e00cb3eb12904fa2ac1a"
} }
}, },
"shivas/versioning-bundle": {
"version": "3.2.3"
},
"sonata-project/admin-bundle": { "sonata-project/admin-bundle": {
"version": "3.31", "version": "3.31",
"recipe": { "recipe": {
...@@ -657,6 +663,9 @@ ...@@ -657,6 +663,9 @@
"ref": "2230e9f42b10616b91a28d15ed3a2d984e0b6c10" "ref": "2230e9f42b10616b91a28d15ed3a2d984e0b6c10"
} }
}, },
"symfony/http-client-contracts": {
"version": "v2.3.1"
},
"symfony/http-foundation": { "symfony/http-foundation": {
"version": "v4.1.7" "version": "v4.1.7"
}, },
......
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
{% block content %} {% block content %}
<div class='container' style='max-width:800px;'> <div class='container' style='max-width:800px;'>
<h4 class='mt-3'>{{'Adhérer'|trans }} :</h4> <div class='text-center mb-5 mt-2'>
<h4 class='mt-3'><b>{{'Adhérer'|trans }}</b></h4>
</div>
<p> <p>
{% if isPayzenEnabled() %}
{{form_start(form)}} {{form_start(form)}}
{{ form_row(form.user) }} {{ form_row(form.user) }}
{% if form.groupe is defined %} {% if form.groupe is defined %}
...@@ -11,10 +14,18 @@ ...@@ -11,10 +14,18 @@
{% endif %} {% endif %}
{{ form_row(form.geoloc) }} {{ form_row(form.geoloc) }}
<div class='text-center mb-5 mt-2'> <div class='text-center mb-5 mt-2'>
<h5>{{ 'Montant de la cotisation'|trans }} : <b>{{ KOH_COTISATION_ADHERENT|default('') }}</b></h5> <h5><b>{{ 'Cotisation'|trans }}</b></h5>
</div>
{{ form_row(form.cotisation) }}
<div class='text-center mb-5 mt-2'>
{{ form_row(form.save) }} {{ form_row(form.save) }}
</div> </div>
{{form_end(form)}} {{form_end(form)}}
{% else %}
<div class='text-center mb-5 mt-2'>
<p><i>Vous ne pouvez malheureusement pas adhérer ici, le paiement n'est pas configuré sur cette application.</i></p>
</div>
{% endif %}
</p> </p>
</div> </div>
{% endblock %} {% endblock %}
...@@ -5,5 +5,15 @@ ...@@ -5,5 +5,15 @@
{% endblock blocktitle %} {% endblock blocktitle %}
{% block blockcontent %} {% block blockcontent %}
{% set form = getAchatMonnaieAdherentForm(app.user) %} {% set form = getAchatMonnaieAdherentForm(app.user) %}
{{form(form)}}
{{form_start(form)}}
{{ form_errors(form) }}
{{ form_row(form.montantradio, {attr: {class: 'custom-control custom-radio custom-control-inline kohinos-montant-radio'} }) }}
{{ form_row(form.montant) }}
<p>Montant choisi : <span class="achat_monnaie_montant_choisi">{{ form.montantradio.vars.value }}</span></p>
{{ form_row(form.save)}}
{{form_end(form)}}
{% endblock blockcontent %} {% endblock blockcontent %}
{% extends base_template %}
{% import _self as macros %}
{%- block tab_menu -%}
{{ knp_menu_render(admin.sidemenu(action), {
'currentClass': 'active',
'template': get_global_template('tab_menu_template')
}, 'twig') }}
{%- endblock -%}
{% block title %}
{{ 'Import de données : erreur !'|trans }}
{% endblock %}
{% block navbar_title %}
{{ block('title') }}
{% endblock %}
{% block content %}
<div class="px-3">
<h3>Erreur lors de l'importation !</h3>
<p><strong>Message à transmettre à l'équipe technique :</strong> {{ error }}</p>
</div>
{% endblock %}
...@@ -26,4 +26,4 @@ ...@@ -26,4 +26,4 @@
{{ form_row(form.save) }} {{ form_row(form.save) }}
{% endif %} {% endif %}
{{ form_end(form) }} {{ form_end(form) }}
{% endblock blockcontent %} {% endblock blockcontent %}
\ No newline at end of file
...@@ -45,19 +45,19 @@ ...@@ -45,19 +45,19 @@
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<a class="dropdown-item" href="{{ path('exportPrestaFlux', {'format' : 'json'}) }}"> <a class="dropdown-item" href="{{ path('exportUserFlux', {'format' : 'json'}) }}">
<i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i> <i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i>
JSON JSON
</a> </a>
<a class="dropdown-item" href="{{ path('exportPrestaFlux', {'format' : 'xml'}) }}"> <a class="dropdown-item" href="{{ path('exportUserFlux', {'format' : 'xml'}) }}">
<i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i> <i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i>
XML XML
</a> </a>
<a class="dropdown-item" href="{{ path('exportPrestaFlux', {'format' : 'csv'}) }}"> <a class="dropdown-item" href="{{ path('exportUserFlux', {'format' : 'csv'}) }}">
<i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i> <i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i>
CSV CSV
</a> </a>
<a class="dropdown-item" href="{{ path('exportPrestaFlux', {'format' : 'xls'}) }}"> <a class="dropdown-item" href="{{ path('exportUserFlux', {'format' : 'xls'}) }}">
<i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i> <i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i>
XLS XLS
</a> </a>
......
...@@ -65,10 +65,13 @@ ...@@ -65,10 +65,13 @@
{% set siege = getSiege() %} {% set siege = getSiege() %}
{% set compte = siege.getCompte() %} {% set compte = siege.getCompte() %}
{% set soldelabel = 'Solde du siège'|trans %} {% set compteNanti = siege.getCompteNantie() %}
{% set ecompteNanti = siege.getECompte() %}
{% set soldelabel = 'Billets au siège'|trans %}
{% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %} {% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %}
{% include 'block/solde.html.twig' with {'compte': siege.getECompte(), 'soldelabel': 'Solde de monnaie numérique distribuée'} %} {% include 'block/solde.html.twig' with {'compte': compteNanti, 'soldelabel': 'Billets nantis'} %}
{% include 'block/solde.html.twig' with {'compte': siege.getCompteNantie(), 'soldelabel': 'Monnaie nantie'} %} {% include 'block/solde.html.twig' with {'compte': ecompteNanti, 'soldelabel': 'Monnaie numérique distribuée'} %}
{% include 'block/solde.html.twig' with {'compte': compteNanti + ecompteNanti, 'soldelabel': 'Monnaie nantie'} %}
{% include 'block/userinfos.html.twig' %} {% include 'block/userinfos.html.twig' %}
{% include 'block/userpassword.html.twig' %} {% include 'block/userpassword.html.twig' %}
{% include 'siege/block/solde_edit.html.twig' %} {% include 'siege/block/solde_edit.html.twig' %}
...@@ -84,14 +87,28 @@ ...@@ -84,14 +87,28 @@
{% set siege = getSiege() %} {% set siege = getSiege() %}
{% set compte = siege.getCompte() %} {% set compte = siege.getCompte() %}
{% set soldelabel = 'Solde du siège'|trans %} {% set compteNanti = siege.getCompteNantie() %}
{% set ecompteNanti = siege.getECompte() %}
{% set soldelabel = 'Billets au siège'|trans %}
{% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %} {% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %}
{% include 'block/solde.html.twig' with {'compte': compteNanti, 'soldelabel': 'Billets nantis'} %}
{% include 'block/solde.html.twig' with {'compte': ecompteNanti, 'soldelabel': 'Monnaie numérique distribuée'} %}
{% include 'block/solde.html.twig' with {'compte': compteNanti + ecompteNanti, 'soldelabel': 'Monnaie nantie'} %}
{% include 'block/userinfos.html.twig' %} {% include 'block/userinfos.html.twig' %}
{% include 'block/userpassword.html.twig' %} {% include 'block/userpassword.html.twig' %}
{# {% include 'block/soldegroupes.html.twig' %} #} {# {% include 'block/soldegroupes.html.twig' %} #}
{% elseif app.user and is_granted('ROLE_CONTROLEUR') %} {% elseif app.user and is_granted('ROLE_CONTROLEUR') %}
{% set siege = getSiege() %}
{% set compte = siege.getCompte() %}
{% set compteNanti = siege.getCompteNantie() %}
{% set ecompteNanti = siege.getECompte() %}
{% set soldelabel = 'Billets au siège'|trans %}
{% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %}
{% include 'block/solde.html.twig' with {'compte': compteNanti, 'soldelabel': 'Billets nantis'} %}
{% include 'block/solde.html.twig' with {'compte': ecompteNanti, 'soldelabel': 'Monnaie numérique distribuée'} %}
{% include 'block/solde.html.twig' with {'compte': compteNanti + ecompteNanti, 'soldelabel': 'Monnaie nantie'} %}
{% include 'block/userinfos.html.twig' %} {% include 'block/userinfos.html.twig' %}
{% elseif app.user and is_granted('ROLE_GESTION_GROUPE') %} {% elseif app.user and is_granted('ROLE_GESTION_GROUPE') %}
...@@ -135,9 +152,13 @@ ...@@ -135,9 +152,13 @@
{% set siege = getSiege() %} {% set siege = getSiege() %}
{% set compte = siege.getCompte() %} {% set compte = siege.getCompte() %}
{% set soldelabel = 'Solde du siège'|trans %} {% set compteNanti = siege.getCompteNantie() %}
{% set ecompteNanti = siege.getECompte() %}
{% set soldelabel = 'Billets au siège'|trans %}
{% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %} {% include 'block/solde.html.twig' with {'compte': compte, 'soldelabel': soldelabel} %}
{% include 'block/solde.html.twig' with {'compte': siege.getCompteNantie(), 'soldelabel': 'Monnaie nantie'} %} {% include 'block/solde.html.twig' with {'compte': compteNanti, 'soldelabel': 'Billets nantis'} %}
{% include 'block/solde.html.twig' with {'compte': ecompteNanti, 'soldelabel': 'Monnaie numérique distribuée'} %}
{% include 'block/solde.html.twig' with {'compte': compteNanti + ecompteNanti, 'soldelabel': 'Monnaie nantie'} %}
{% include 'block/userinfos.html.twig' %} {% include 'block/userinfos.html.twig' %}
{% include 'block/userpassword.html.twig' %} {% include 'block/userpassword.html.twig' %}
...@@ -168,15 +189,15 @@ ...@@ -168,15 +189,15 @@
{% set esoldelabel = 'Solde e-mlc'|trans %} {% set esoldelabel = 'Solde e-mlc'|trans %}
{% include 'block/solde.html.twig' with {'compte': app.user.adherent.ecompte, 'soldelabel': esoldelabel} %} {% include 'block/solde.html.twig' with {'compte': app.user.adherent.ecompte, 'soldelabel': esoldelabel} %}
{% include 'adherent/block/infos.html.twig' %}
{% include 'block/userpassword.html.twig' %}
{% include 'block/cotisations.html.twig' %}
{% include 'block/transactions.html.twig' %}
{% if isPayzenEnabled() %} {% if isPayzenEnabled() %}
{% include 'adherent/block/achat_monnaie.html.twig' %} {% include 'adherent/block/achat_monnaie.html.twig' %}
{% endif %} {% endif %}
{% include 'adherent/block/transaction_presta.html.twig' %} {% include 'adherent/block/transaction_presta.html.twig' %}
{% include 'adherent/block/transaction_adherent.html.twig' %} {% include 'adherent/block/transaction_adherent.html.twig' %}
{% include 'block/transactions.html.twig' %}
{% include 'block/cotisations.html.twig' %}
{% include 'adherent/block/infos.html.twig' %}
{% include 'block/userpassword.html.twig' %}
{% else %} {% else %}
{% if KOH_USE_WORDPRESS is defined and KOH_USE_WORDPRESS == 'false' %} {% if KOH_USE_WORDPRESS is defined and KOH_USE_WORDPRESS == 'false' %}
......
...@@ -22,7 +22,7 @@ Modified for MLC from Sonata package. ...@@ -22,7 +22,7 @@ Modified for MLC from Sonata package.
<!DOCTYPE html> <!DOCTYPE html>
<html {% block html_attributes %}class="no-js"{% endblock %}> <html {% block html_attributes %}class="no-js"{% endblock %}>
<head> <head>
<title>{{title|default('Kohinos') }}</title> <title>{{ title ?? KOH_APP_TITLE ?? 'Kohinos' }}</title>
<meta name="description" content="{{ description|default('Kohinos : Outil de gestion de monnaie locale complémentaire') }}" /> <meta name="description" content="{{ description|default('Kohinos : Outil de gestion de monnaie locale complémentaire') }}" />
<meta name="keywords" content="{{ keywords|default('Kohinos, mlc, mlcc, monnaie locale, monnaies locales') }}" /> <meta name="keywords" content="{{ keywords|default('Kohinos, mlc, mlcc, monnaie locale, monnaies locales') }}" />
......
<footer class="container clearfix footer"> <footer class="container clearfix footer">
{# TODO : ajouter crédit et lien vers la solution de gestion de la monnaie locale complémentaire libre de droits #} {# TODO : ajouter crédit et lien vers la solution de gestion de la monnaie locale complémentaire libre de droits #}
<a href='http://www.kohinos.com' target='_blank'>© Kohinos 2020</a> <a href='http://www.kohinos.com' target='_blank'>© Kohinos 2020</a> - V{{ shivas_app_version }}
<div class='float-right'> <div class='float-right'>
<a href="{{ path('contact') }}">Nous contacter</a> <a href="{{ path('contact') }}">Nous contacter</a>
</div> </div>
</footer> </footer>
\ No newline at end of file
...@@ -8,4 +8,4 @@ ...@@ -8,4 +8,4 @@
{% include 'common/menu.html.twig' %} {% include 'common/menu.html.twig' %}
{% endblock menu %} {% endblock menu %}
</nav> </nav>
</header> </header>
\ No newline at end of file
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
<html class="no-js" lang="fr-FR"> <html class="no-js" lang="fr-FR">
<!--<![endif]--> <!--<![endif]-->
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{title|default('Kohinos') }}</title> <title>{{ title ?? KOH_APP_TITLE ?? 'Kohinos' }}</title>
<meta name="description" content="{{ description|default('Kohinos : Outil de gestion de monnaie locale complémentaire') }}" /> <meta name="description" content="{{ description|default('Kohinos : Outil de gestion de monnaie locale complémentaire') }}" />
<meta name="keywords" content="{{ keywords|default('Kohinos, mlc, mlcc, monnaie locale, monnaies locales') }}" /> <meta name="keywords" content="{{ keywords|default('Kohinos, mlc, mlcc, monnaie locale, monnaies locales') }}" />
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
...@@ -38,7 +38,8 @@ ...@@ -38,7 +38,8 @@
<input type="hidden" name="koh_map_center" id="koh_map_center" value='{{KOH_MAP_CENTER|default('')}}' /> <input type="hidden" name="koh_map_center" id="koh_map_center" value='{{KOH_MAP_CENTER|default('')}}' />
<input type="hidden" name="koh_map_zoom" id="koh_map_zoom" value='{{KOH_MAP_ZOOM|default('')}}' /> <input type="hidden" name="koh_map_zoom" id="koh_map_zoom" value='{{KOH_MAP_ZOOM|default('')}}' />
{% include 'common/modale_choix_groupe.html.twig' %} {% include 'common/modale_choix_groupe.html.twig' %}
{% include 'common/modale_confirmation_transaction.html.twig' %}
<!-- HEADER --> <!-- HEADER -->
{% block header %} {% block header %}
......
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
;
{% if menuItems is not defined %} {% if menuItems is not defined %}
{% set menuItems = getMenuItemsFromAlias('main') %} {% set menuItems = getMenuItemsFromAlias('main') %}
{% endif %} {% endif %}
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
{% if app.user is null %} {% if app.user is null and isPayzenEnabled() %}
<li class="nav-item dropdownmenu-item has-child dropdown" role="menu-item"> <li class="nav-item dropdownmenu-item has-child dropdown" role="menu-item">
<a href="#" id="navbarDropdown1" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link parent dropdown-toggle ">{{ 'Adhérer'|trans }}</a> <a href="#" id="navbarDropdown1" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link parent dropdown-toggle ">{{ 'Adhérer'|trans }}</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown1"> <div class="dropdown-menu" aria-labelledby="navbarDropdown1">
......
<!-- Modal -->
<div class="modal fade" id="confirmTransactionModal" tabindex="-1" role="dialog" aria-labelledby="confirmTransactionModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmTransactionModalTitle">{{ 'Vous allez effectuer une transaction'|trans }}</h5>
</div>
<div class="modal-body">
<div class="confirmTransactionPrestataire" style="display:none;">
<p>{{ 'Vous vous apprêtez à effectuer une transaction au prestataire'|trans }} <b><span class="nom_destinataire"></span></b> {{ 'd\'une valeur de'|trans }} <b><span class="montant_transaction"></span> {{ 'eMLC'|trans }}</b>.</p>
</div>
<div class="confirmTransactionAdherent" style="display:none;">
<p>{{ 'Vous vous apprêtez à effectuer une transaction à l\'adhérent'|trans }} <b><span class="nom_destinataire"></span></b> {{ 'd\'une valeur de'|trans }} <b><span class="montant_transaction"></span> {{ 'eMLC'|trans }}</b>.</p>
</div>
<div class="confirmCotisation" style="display:none;">
<p>{{ 'Vous vous apprêtez à cotiser.'|trans }} {{ 'Montant de votre cotisation :'|trans }} <b><span class="montant_transaction"></span> {{ 'eMLC'|trans }}</b></p>
</div>
<p>{{ 'Voulez-vous continuer ?'|trans }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ 'Annuler'|trans }}</button>
<button type="button" class="btn btn-primary" id="confirmTransactionButton">{{ 'Confirmer'|trans }}</button>
</div>
</div>
</div>
</div>
...@@ -5,5 +5,15 @@ ...@@ -5,5 +5,15 @@
{% endblock blocktitle %} {% endblock blocktitle %}
{% block blockcontent %} {% block blockcontent %}
{% set form = getAchatMonnaiePrestataireForm(app.user) %} {% set form = getAchatMonnaiePrestataireForm(app.user) %}
{{form(form)}}
{{form_start(form)}}
{{ form_errors(form) }}
{{ form_row(form.montantradio, {attr: {class: 'custom-control custom-radio custom-control-inline kohinos-montant-radio'} }) }}
{{ form_row(form.montant) }}
<p>Montant choisi : <span class="achat_monnaie_montant_choisi">{{ form.montantradio.vars.value }}</span></p>
{{ form_row(form.save)}}
{{form_end(form)}}
{% endblock blockcontent %} {% endblock blockcontent %}
adherent:
cotisations.isZero: Une cotisation adhérent ne peut pas être égale à zéro.
prestataire:
already_exists: 'Le prestataire avec la raison "0" existe déjà !'
column_required: 'La colonne "0" ne doit pas être vide'
groupe_notfound_created: 'Création du groupe "0" car introuvable'
added: 'Prestaitaire bien ajouté : 0'
adherent:
cotisations.isZero: Une cotisation adhérent ne peut pas être égale à zéro.
prestataire:
already_exists: 'Le prestataire avec la raison "0" existe déjà !'
column_required: 'La colonne "0" ne doit pas être vide'
groupe_notfound_created: 'Création du groupe "0" car introuvable'
added: 'Prestaitaire bien ajouté : 0'
...@@ -861,6 +861,46 @@ ...@@ -861,6 +861,46 @@
<source>Créer votre mot de passe</source> <source>Créer votre mot de passe</source>
<target>Créer votre mot de passe</target> <target>Créer votre mot de passe</target>
</trans-unit> </trans-unit>
<trans-unit id="8yTsV8G" resname="Cotiser">
<source>Cotiser</source>
<target>Cotiser</target>
</trans-unit>
<trans-unit id="STMXKMO" resname="Achat de monnaie locale bien effectué !">
<source>Achat de monnaie locale bien effectué !</source>
<target>Achat de monnaie locale bien effectué !</target>
</trans-unit>
<trans-unit id="dfPWdav" resname="La transaction a été annulée.">
<source>La transaction a été annulée.</source>
<target>La transaction a été annulée.</target>
</trans-unit>
<trans-unit id="NXrqKKn" resname="Export impossible.">
<source>Export impossible.</source>
<target>Export impossible.</target>
</trans-unit>
<trans-unit id="zF0OMr1" resname="Cotisation ajoutée : ">
<source>Cotisation ajoutée : </source>
<target>Cotisation ajoutée : </target>
</trans-unit>
<trans-unit id="pNAxMG8" resname="Infos de l'adhérent modifiées !">
<source>Infos de l'adhérent modifiées !</source>
<target>Infos de l'adhérent modifiées !</target>
</trans-unit>
<trans-unit id="qedWcct" resname="Infos du prestataire modifiées !">
<source>Infos du prestataire modifiées !</source>
<target>Infos du prestataire modifiées !</target>
</trans-unit>
<trans-unit id="JkNHITX" resname="Une erreur est survenue due à la configuration du paiement dans l'application. Il est pour l'instant impossible de payer par CB, merci de contacter votre monnaie locale.">
<source>Une erreur est survenue due à la configuration du paiement dans l'application. Il est pour l'instant impossible de payer par CB, merci de contacter votre monnaie locale.</source>
<target>Une erreur est survenue due à la configuration du paiement dans l'application. Il est pour l'instant impossible de payer par CB, merci de contacter votre monnaie locale.</target>
</trans-unit>
<trans-unit id="FXJP8R7" resname="Cotisation">
<source>Cotisation</source>
<target>Cotisation</target>
</trans-unit>
<trans-unit id="QZ19VOy" resname="Votre adhésion a bien été prise en compte, bienvenue !">
<source>Votre adhésion a bien été prise en compte, bienvenue !</source>
<target>Votre adhésion a bien été prise en compte, bienvenue !</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>
...@@ -877,6 +877,46 @@ ...@@ -877,6 +877,46 @@
<source>Créer votre mot de passe</source> <source>Créer votre mot de passe</source>
<target>Créer votre mot de passe</target> <target>Créer votre mot de passe</target>
</trans-unit> </trans-unit>
<trans-unit id="8yTsV8G" resname="Cotiser">
<source>Cotiser</source>
<target>Cotiser</target>
</trans-unit>
<trans-unit id="STMXKMO" resname="Achat de monnaie locale bien effectué !">
<source>Achat de monnaie locale bien effectué !</source>
<target>Achat de monnaie locale bien effectué !</target>
</trans-unit>
<trans-unit id="dfPWdav" resname="La transaction a été annulée.">
<source>La transaction a été annulée.</source>
<target>La transaction a été annulée.</target>
</trans-unit>
<trans-unit id="NXrqKKn" resname="Export impossible.">
<source>Export impossible.</source>
<target>Export impossible.</target>
</trans-unit>
<trans-unit id="zF0OMr1" resname="Cotisation ajoutée : ">
<source>Cotisation ajoutée : </source>
<target>Cotisation ajoutée : </target>
</trans-unit>
<trans-unit id="pNAxMG8" resname="Infos de l'adhérent modifiées !">
<source>Infos de l'adhérent modifiées !</source>
<target>Infos de l'adhérent modifiées !</target>
</trans-unit>
<trans-unit id="qedWcct" resname="Infos du prestataire modifiées !">
<source>Infos du prestataire modifiées !</source>
<target>Infos du prestataire modifiées !</target>
</trans-unit>
<trans-unit id="JkNHITX" resname="Une erreur est survenue due à la configuration du paiement dans l'application. Il est pour l'instant impossible de payer par CB, merci de contacter votre monnaie locale.">
<source>Une erreur est survenue due à la configuration du paiement dans l'application. Il est pour l'instant impossible de payer par CB, merci de contacter votre monnaie locale.</source>
<target>Une erreur est survenue due à la configuration du paiement dans l'application. Il est pour l'instant impossible de payer par CB, merci de contacter votre monnaie locale.</target>
</trans-unit>
<trans-unit id="FXJP8R7" resname="Cotisation">
<source>Cotisation</source>
<target>Cotisation</target>
</trans-unit>
<trans-unit id="QZ19VOy" resname="Votre adhésion a bien été prise en compte, bienvenue !">
<source>Votre adhésion a bien été prise en compte, bienvenue !</source>
<target>Votre adhésion a bien été prise en compte, bienvenue !</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>
...@@ -1469,6 +1469,11 @@ boolbase@^1.0.0, boolbase@~1.0.0: ...@@ -1469,6 +1469,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bootstrap-slider@^11.0.2:
version "11.0.2"
resolved "https://registry.yarnpkg.com/bootstrap-slider/-/bootstrap-slider-11.0.2.tgz#4b167c165f322339cc66f0c7166b5a39e289e251"
integrity sha512-CdwS+Z6X79OkLes9RfDgPB9UIY/+81wTkm6ktdSB6hdyiRbjJLFQIjZdnEr55tDyXZfgC7U6yeSXkNN9ZdGqjA==
bootstrap@^4.4.1: bootstrap@^4.4.1:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.0.tgz#97d9dbcb5a8972f8722c9962483543b907d9b9ec" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.0.tgz#97d9dbcb5a8972f8722c9962483543b907d9b9ec"
......
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