Project 'cooperatic/kohinos-tav' was moved to 'agplv3/kohinos-tav'. Please update any links and bookmarks that may still have the old path.
Commit 7a12ca10 by Yvon Kerdoncuff

Merge branch '6150-et-6159-correction-solde-et-envois-mails' into 'develop'

add fields to fix balance in fiche adherent form for super admin only

See merge request cooperatic/kohinos-tav!84
parents 15b362e3 9639b5c6
......@@ -51,6 +51,7 @@ AUTOMATISATION_RECONVERSION=0
PRESTA_EXTRA_DATA=0
HOUSEHOLD_BASED_ALLOWANCE=0
SSA_FRIENDLY_FLUX_TYPE_NAMES=0
FIX_BALANCE_ADHERENT_PASSWORD=ChangeMe
EMAIL_ERROR=technique@kohinos.net
EMAIL_USER_FROM=noreply@kohinos.fr
......
......@@ -10,6 +10,7 @@ require('../css/admin.css');
require('bootstrap');
require('../css/common.css');
require('../js/geoloc.js');
const $ = require("jquery");
$('#flash-messages').flashNotification('init');
......@@ -130,4 +131,11 @@ $(document).ready(function() {
}
actionOnRecevoirUnRappelChange();
}
if($(".fixBalanceAdherentFormPart").length > 0) {
$(".fixBalanceAdherentFormPart").parent().parent().hide();
$("div[id$='_idmlc']").append(
"<br/><input type='button' id='showFieldsToFixBalance' onclick='$(\".fixBalanceAdherentFormPart\").parent().parent().show();' value='Afficher les champs pour corriger le solde'> </input>"
);
}
});
......@@ -18,6 +18,7 @@ parameters:
presta_extra_data: '%env(PRESTA_EXTRA_DATA)%'
household_based_allowance: '%env(HOUSEHOLD_BASED_ALLOWANCE)%'
ssa_friendly_flux_type_names: '%env(SSA_FRIENDLY_FLUX_TYPE_NAMES)%'
fix_balance_adherent_password: '%env(FIX_BALANCE_ADHERENT_PASSWORD)%'
# PARAMETRES DES IMPORTS POSSIBLE POUR L'APPLICATION DE GESTION DE MONNAIE LOCALE COMPLEMENTAIRE
......
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.
......@@ -12,7 +12,7 @@
"admin": {
"js": [
"/build/runtime.6ad5c9da.js",
"/build/admin.86a2d986.js"
"/build/admin.3edfb527.js"
],
"css": [
"/build/admin.4de55830.css"
......
......@@ -2,7 +2,7 @@
"build/app.css": "/build/app.8a3f698b.css",
"build/app.js": "/build/app.3644f7b2.js",
"build/admin.css": "/build/admin.4de55830.css",
"build/admin.js": "/build/admin.86a2d986.js",
"build/admin.js": "/build/admin.3edfb527.js",
"build/runtime.js": "/build/runtime.6ad5c9da.js",
"build/images/fa-solid-900.svg": "/build/images/fa-solid-900.a838c42a.svg",
"build/images/fa-brands-400.svg": "/build/images/fa-brands-400.05d20183.svg",
......
......@@ -40,6 +40,7 @@ use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormError;
......@@ -359,6 +360,42 @@ class AdherentAdmin extends AbstractAdmin
])
->end()
->end();
//Add form part allowing super admin to fix balance
if($this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance')
&& $this->security->isGranted('ROLE_SUPER_ADMIN')) {
$formMapper
->tab('General')
->with('Informations de cotisation')
->add('fixedBalance', TextType::class, [
'label' => "Corriger le solde suite à une erreur de cotisation",
'mapped' => false,
'required' => false,
'attr' => [
'autocomplete' => 'off',
'class' => 'fixBalanceAdherentFormPart'
]
])
->add('justification', TextType::class, [
'mapped' => false,
'required' => false,
'attr' => [
'autocomplete' => 'off',
'class' => 'fixBalanceAdherentFormPart'
]
])
->add('password', PasswordType::class, [
'label' => 'Mot de passe pour corriger le solde',
'mapped' => false,
'required' => false,
'data' => "",
'attr' => [
'autocomplete' => 'off',
'class' => 'fixBalanceAdherentFormPart'
]
])
->end()
->end();
}
}
}
......@@ -378,8 +415,8 @@ class AdherentAdmin extends AbstractAdmin
}
}
// check cotisation amount
if ($this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance')) {
// check cotisation amount
$adultsCount = $adherent->getHouseholdAdultCount();
$dependentChildrenCount = count($adherent->getDependentChildren());
$minCotisationAmount = 10 + 5 * ( $adultsCount - 1 ) + 5 * $dependentChildrenCount;
......@@ -387,6 +424,26 @@ class AdherentAdmin extends AbstractAdmin
if ($adherent->getCotisationAmount() < $minCotisationAmount) {
$event->getForm()->get('cotisationAmount')->addError(new FormError('Le montant minimum est de ' . $minCotisationAmount . '€ (selon les données du foyer indiquées)'));
}
// try to fix balance if required
if($this->security->isGranted('ROLE_SUPER_ADMIN')
&& $event->getForm()->has('fixedBalance')
&& $event->getForm()->get('fixedBalance')->getData()
&& $event->getForm()->get('fixedBalance')->getData() >= 0) {
$password = $this->getConfigurationPool()->getContainer()->getParameter('fix_balance_adherent_password');
//this password purpose is to be an additional warning for super admin and
//is not intended to be securely stored as only super admin can use this feature
if ($event->getForm()->get('password')->getData() !== $password) {
$event->getForm()->get('password')->addError(new FormError('Mot de passe incorrect.'));
} elseif(!$event->getForm()->get('justification')->getData()) {
$event->getForm()->get('justification')->addError(new FormError('Merci de justifier cette opération sensible.'));
} else {
$this->tavCotisationUtils->fixBalance(
$adherent, $event->getForm()->get('fixedBalance')->getData(), $event->getForm()->get('justification')->getData()
);
$em->flush();
}
}
}
});
parent::configureFormFields($formMapper);
......
......@@ -23,6 +23,9 @@ class CotisationTavApplication extends Flux
{
const TYPE_REVERSEMENT_COTISATION_ADHERENT = 'reversement_cotisation_adherent';
const TYPE_PRELEVEMENT_COTISATION_ADHERENT = 'prelevement_cotisation_adherent';
const TYPE_PRELEVEMENT_COTISATION_ADHERENT_DEPASSEMENT_PLAFOND = 'prelevement_cotisation_adherent_depassement_plafond';
const TYPE_PRELEVEMENT_COTISATION_ADHERENT_CORRECTION_SOLDE = 'prelevement_cotisation_adherent_correction_solde';
const TYPE_REVERSEMENT_COTISATION_ADHERENT_CORRECTION_SOLDE = 'reversement_cotisation_adherent_correction_solde';
/**
* @return string
......
......@@ -12,6 +12,7 @@ use Doctrine\ORM\Mapping as ORM;
* - [Allocation selon foyer] Le montant reçu calculé est inférieur au montant payé
* - [Allocation selon foyer] Un administrateur effectue une opération manuelle de prélèvement de l'adhérent
* pour ramener son solde au niveau de son plafond.
* - [Allocation selon foyer] Un administrateur effectue une opération de correction de solde qui conduit à un prélèvement.
*
* L'adhérent•e reçoit moins d'emlc que ce qu'elle•il paye en €,
* un second flux est créé pour prélever le complément de la cotisation.
......
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Child class used to notify adherents by email.
*
* - [Allocation selon foyer] Un administrateur effectue une opération de correction de solde qui conduit à un prélèvement.
* @ORM\Entity
*/
class CotisationTavPrelevementCorrectionSolde extends CotisationTavPrelevement
{
/**
* @return string
*/
public function getType(): string
{
return parent::TYPE_PRELEVEMENT_COTISATION_ADHERENT_CORRECTION_SOLDE;
}
public function getUsersToNotify()
{
return [
'expediteurs' => [$this->getExpediteur()->getUser()],
];
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Child class used to notify adherents by email.
*
* - [Allocation selon foyer] Un administrateur effectue une opération manuelle de prélèvement de l'adhérent
* pour ramener son solde au niveau de son plafond.
* @ORM\Entity
*/
class CotisationTavPrelevementDepassementPlafond extends CotisationTavPrelevement
{
/**
* @return string
*/
public function getType(): string
{
return parent::TYPE_PRELEVEMENT_COTISATION_ADHERENT_DEPASSEMENT_PLAFOND;
}
public function getUsersToNotify()
{
return [
'expediteurs' => [$this->getExpediteur()->getUser()],
];
}
}
......@@ -10,6 +10,7 @@ use Doctrine\ORM\Mapping as ORM;
* * Dans les cas suivants :
* - [Profil de Cotisation] La taux est supérieur à 1
* - [Allocation selon foyer] Le montant reçu calculé est supérieur au montant payé
* - [Allocation selon foyer] Un administrateur effectue une opération de correction de solde qui conduit à un reversement.
*
* L'adhérent•e reçoit plus d'emlc que ce qu'elle•il paye en €,
* un second flux est créé pour reverser le complément de la cotisation.
......
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Child class used to notify adherents by email.
*
* - [Allocation selon foyer] Un administrateur effectue une opération de correction de solde qui conduit à un reversement.
* @ORM\Entity
*/
class CotisationTavReversementCorrectionSolde extends CotisationTavReversement
{
/**
* @return string
*/
public function getType(): string
{
return parent::TYPE_REVERSEMENT_COTISATION_ADHERENT_CORRECTION_SOLDE;
}
public function getUsersToNotify()
{
return [
'destinataires' => [$this->getDestinataire()->getUser()],
];
}
}
......@@ -57,6 +57,9 @@ use Symfony\Component\Validator\Constraints as Assert;
* "application_cotisation_tav" = "CotisationTavApplication",
* "reversement_cotisation_adherent" = "CotisationTavReversement",
* "prelevement_cotisation_adherent" = "CotisationTavPrelevement",
* "prelevement_cotisation_adherent_depassement_plafond" = "CotisationTavPrelevementDepassementPlafond",
* "prelevement_cotisation_adherent_correction_solde" = "CotisationTavPrelevementCorrectionSolde",
* "reversement_cotisation_adherent_correction_solde" = "CotisationTavReversementCorrectionSolde",
* })
*/
abstract class Flux implements FluxInterface
......@@ -658,13 +661,16 @@ abstract class Flux implements FluxInterface
: $this->type;
}
public static function ssaUsefulFriendlyTypeNames($differentiateAchatsDeMonaPayzenOrComptoir = false)
public static function ssaUsefulFriendlyTypeNames($uniqueValues = false)
{
return [
VenteEmlc::TYPE_VENTE_EMLC_ADHERENT => "Achat de MonA via cotisation" . ($differentiateAchatsDeMonaPayzenOrComptoir ? " (au comptoir)" : ""),
AchatMonnaie::TYPE_ACHAT_ADHERENT => "Achat de MonA via cotisation" . ($differentiateAchatsDeMonaPayzenOrComptoir ? " (via Payzen)" : ""),
VenteEmlc::TYPE_VENTE_EMLC_ADHERENT => "Achat de MonA via cotisation" . ($uniqueValues ? " (au comptoir)" : ""),
AchatMonnaie::TYPE_ACHAT_ADHERENT => "Achat de MonA via cotisation" . ($uniqueValues ? " (via Payzen)" : ""),
CotisationTavApplication::TYPE_REVERSEMENT_COTISATION_ADHERENT => "Allocation complémentaire de la caisse",
CotisationTavApplication::TYPE_REVERSEMENT_COTISATION_ADHERENT_CORRECTION_SOLDE => "Allocation complémentaire de la caisse" . ($uniqueValues ? " (correction solde)" : ""),
CotisationTavApplication::TYPE_PRELEVEMENT_COTISATION_ADHERENT => "Réduction de l'allocation",
CotisationTavApplication::TYPE_PRELEVEMENT_COTISATION_ADHERENT_DEPASSEMENT_PLAFOND => "Réduction de l'allocation" . ($uniqueValues ? " (dépassement plafond)" : ""),
CotisationTavApplication::TYPE_PRELEVEMENT_COTISATION_ADHERENT_CORRECTION_SOLDE => "Réduction de l'allocation" . ($uniqueValues ? " (correction solde)" : ""),
Don::TYPE_DON_ADHERENT => Don::TYPE_DON_ADHERENT,
Don::TYPE_DON_PRESTATAIRE => Don::TYPE_DON_PRESTATAIRE,
Reconversion::TYPE_RECONVERSION_PRESTATAIRE => Reconversion::TYPE_RECONVERSION_PRESTATAIRE,
......
......@@ -3,6 +3,9 @@
namespace App\Utils;
use App\Entity\Adherent;
use App\Entity\CotisationTavPrelevementCorrectionSolde;
use App\Entity\CotisationTavPrelevementDepassementPlafond;
use App\Entity\CotisationTavReversementCorrectionSolde;
use App\Entity\Payment;
use App\Entity\Siege;
use App\Entity\Flux;
......@@ -234,7 +237,7 @@ class TAVCotisationUtils
throw new \Exception("Impossible de prélèver : le solde de l'adhérent est inférieur ou égal au plafond.");
}
$flux = new CotisationTavPrelevement();
$flux = new CotisationTavPrelevementDepassementPlafond();
$flux->setExpediteur($adherent);
$flux->setDestinataire($siege);
$flux->setMontant(-$amountDiff);
......@@ -249,6 +252,41 @@ class TAVCotisationUtils
}
/**
* Method called to create Flux to fix balance (for household based allowance).
*/
public function fixBalance(Adherent $adherent, $fixedBalance, $justification)
{
$balance = $adherent->getEmlcAccount()->getBalance();
$siege = $this->em->getRepository(Siege::class)->getTheOne();
$amountDiff = $fixedBalance - $balance;
if ($amountDiff >= 0) {
//Accroissement du solde
$flux = new CotisationTavReversementCorrectionSolde();
$flux->setExpediteur($siege);
$flux->setDestinataire($adherent);
$flux->setReference(
"Reversement pour corriger le solde de " . $balance . " MonA à " . $fixedBalance . " MonA : " . $justification
);
} else {
//Réduction du solde
$flux = new CotisationTavPrelevementCorrectionSolde();
$flux->setExpediteur($adherent);
$flux->setDestinataire($siege);
$flux->setReference(
"Prélèvement pour corriger le solde de " . $balance . " MonA à " . $fixedBalance . " MonA : " . $justification
);
}
$flux->setMontant(abs($amountDiff));
$flux->setOperateur($this->security->getUser());
$flux->setRole($this->security->getUser()->getGroups()[0]->__toString());
$flux->setMoyen(MoyenEnum::MOYEN_EMLC);
$this->em->persist($flux);
$this->operationUtils->executeOperations($flux);
}
/**
* Get the last cotisation of an adhérent
*
* @param Adherent $adherent
......
......@@ -10,6 +10,12 @@
<h3>
{% if flux.type == 'reconversion' %}
{{ 'Demande de reconversion' }}
{% elseif flux.type == 'prelevement_cotisation_adherent_depassement_plafond' %}
{{ "Réduction de l'allocation après dépassement du plafond" }}
{% elseif flux.type == 'prelevement_cotisation_adherent_correction_solde' %}
{{ "Correction de solde (réduction de l'allocation) suite à une erreur de cotisation" }}
{% elseif flux.type == 'reversement_cotisation_adherent_correction_solde' %}
{{ "Correction de solde (allocation complémentaire de la caisse) suite à une erreur de cotisation" }}
{% else %}
{{ flux.parenttype|capitalize }} : {{ flux.type|replace({'_' : ' => '}) }}
{% endif %}
......
......@@ -130,3 +130,6 @@ des_vente_emlc: 'Achat monnaie numérique'
exp_vente_emlc: 'Vente monnaie numérique'
exp_ticket_print: 'Impression de billets'
exp_ticket_destroy: 'Destruction de billets'
exp_prelevement_cotisation_adherent_depassement_plafond_email_subject: 'Réduction de l''allocation après dépassement du plafond'
exp_prelevement_cotisation_adherent_correction_solde_email_subject: 'Correction de solde (réduction de l''allocation) suite à une erreur de cotisation'
des_reversement_cotisation_adherent_correction_solde_email_subject: 'Correction de solde (allocation complémentaire de la caisse) suite à une erreur de cotisation'
\ No newline at end of file
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