Commit 5a776250 by Yvon Kerdoncuff

Merge branch '7916-add-params-to-household-allowance-calculation' into 'develop'

add params to household allowance calculation & add allowance cap at calculation with param

See merge request !140
parents 3b0eeba8 f6a0440b
...@@ -205,6 +205,8 @@ class AdherentAdmin extends AbstractAdmin ...@@ -205,6 +205,8 @@ class AdherentAdmin extends AbstractAdmin
; ;
if ($tav_env) { if ($tav_env) {
$mlc = $em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_SYMBOL);
if ($this->getConfigurationPool()->getContainer()->getParameter('ccas_mode')) { if ($this->getConfigurationPool()->getContainer()->getParameter('ccas_mode')) {
$formMapper $formMapper
->tab('General') ->tab('General')
...@@ -325,6 +327,14 @@ class AdherentAdmin extends AbstractAdmin ...@@ -325,6 +327,14 @@ class AdherentAdmin extends AbstractAdmin
$cotisSectionInfo .= " " . $adherent->getProfilDeCotisation() . "."; $cotisSectionInfo .= " " . $adherent->getProfilDeCotisation() . ".";
} }
$maxAllocationAmount = $em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_MAX_ALLOCATION_AMOUNT);
$allowanceCalculationLimitationMsg = (null !== $maxAllocationAmount) ? " dans la limite de {$maxAllocationAmount} {$mlc}" : '';
$minCotisationAmount = $em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_COTISATION_MINIMUM);
$minCotisationMsg = (null !== $minCotisationAmount) ? "Montant minimum : {$minCotisationAmount}€ par foyer." : '';
// Add cotisation info // Add cotisation info
$formMapper $formMapper
->tab('General') ->tab('General')
...@@ -334,14 +344,14 @@ class AdherentAdmin extends AbstractAdmin ...@@ -334,14 +344,14 @@ class AdherentAdmin extends AbstractAdmin
]) ])
->add('cotisationAmount', NumberType::class, [ ->add('cotisationAmount', NumberType::class, [
'label' => 'Montant de la cotisation (en €)', 'label' => 'Montant de la cotisation (en €)',
'help' => $simplified_household_based_allowance ? '' : 'Montant minimum : 10€ par foyer + 5€/personne supplémentaire du foyer', 'help' => $minCotisationMsg,
'disabled' => $disableHouseholdAllowanceFields, 'disabled' => $disableHouseholdAllowanceFields,
]) ])
->add('allocationAmount', NumberType::class, [ ->add('allocationAmount', NumberType::class, [
'label' => 'Montant d\'allocation prévu en fonction du foyer (en MonA)', 'label' => 'Montant d\'allocation prévu en fonction du foyer (en MonA)',
'disabled' => true, 'disabled' => true,
'required' => false, 'required' => false,
'help' => 'Le montant de l\'allocation sera calculé automatiquement en fonction des informations du foyer une fois les informations sauvegardées.' 'help' => "Le montant de l'allocation sera calculé automatiquement en fonction des informations du foyer une fois les informations sauvegardées{$allowanceCalculationLimitationMsg}."
]) ])
->end() ->end()
->end(); ->end();
...@@ -453,7 +463,6 @@ class AdherentAdmin extends AbstractAdmin ...@@ -453,7 +463,6 @@ class AdherentAdmin extends AbstractAdmin
if (!empty($adherent) && !empty($adherent->getEmlcAccount()) ) { if (!empty($adherent) && !empty($adherent->getEmlcAccount()) ) {
$balance = $adherent->getEmlcAccount()->getBalance(); $balance = $adherent->getEmlcAccount()->getBalance();
$mlc = $em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_SYMBOL);
$formMapper $formMapper
->tab('General') ->tab('General')
->with('Informations de cotisation') ->with('Informations de cotisation')
...@@ -550,15 +559,12 @@ class AdherentAdmin extends AbstractAdmin ...@@ -550,15 +559,12 @@ class AdherentAdmin extends AbstractAdmin
} }
if ($this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance')) { if ($this->getConfigurationPool()->getContainer()->getParameter('household_based_allowance')) {
if (!$this->getConfigurationPool()->getContainer()->getParameter('simplified_household_based_allowance')) { // check cotisation amount above minimum if activated
// check cotisation amount $minCotisationAmount = $em->getRepository(GlobalParameter::class)
$adultsCount = $adherent->getHouseholdAdultCount(); ->val(GlobalParameter::SSA_HOUSEHOLD_COTISATION_MINIMUM);
$dependentChildrenCount = count($adherent->getDependentChildren());
$minCotisationAmount = 10 + 5 * ( $adultsCount - 1 ) + 5 * $dependentChildrenCount; if (null !== $minCotisationAmount && $adherent->getCotisationAmount() < (int) $minCotisationAmount) {
$event->getForm()->get('cotisationAmount')->addError(new FormError('Champ invalide'));
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 // try to fix balance if required
......
...@@ -29,7 +29,7 @@ class DependentChild ...@@ -29,7 +29,7 @@ class DependentChild
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean")
*/ */
private $olderThanFourteen; private $olderThanLimitAge;
/** /**
* @var float * @var float
...@@ -57,14 +57,14 @@ class DependentChild ...@@ -57,14 +57,14 @@ class DependentChild
return $this; return $this;
} }
public function getOlderThanFourteen() public function getOlderThanLimitAge()
{ {
return $this->olderThanFourteen; return $this->olderThanLimitAge;
} }
public function setOlderThanFourteen($olderThanFourteen) public function setOlderThanLimitAge($olderThanLimitAge)
{ {
$this->olderThanFourteen = $olderThanFourteen; $this->olderThanLimitAge = $olderThanLimitAge;
return $this; return $this;
} }
......
...@@ -61,6 +61,13 @@ class GlobalParameter ...@@ -61,6 +61,13 @@ class GlobalParameter
const SSA_SIMPL_HOUSEHOLD_ADMIN_TEXT_INFO_ADHERENT_FALLBACKS_TO_PROFILECOTIS = 'SSA_SIMPL_HOUSEHOLD_ADMIN_TEXT_INFO_ADHERENT_FALLBACKS_TO_PROFILECOTIS'; const SSA_SIMPL_HOUSEHOLD_ADMIN_TEXT_INFO_ADHERENT_FALLBACKS_TO_PROFILECOTIS = 'SSA_SIMPL_HOUSEHOLD_ADMIN_TEXT_INFO_ADHERENT_FALLBACKS_TO_PROFILECOTIS';
const SSA_DISABLE_COTISATION = 'SSA_DISABLE_COTISATION'; const SSA_DISABLE_COTISATION = 'SSA_DISABLE_COTISATION';
const SSA_FORCE_ALLOCATION_AMOUNT = 'SSA_FORCE_ALLOCATION_AMOUNT'; const SSA_FORCE_ALLOCATION_AMOUNT = 'SSA_FORCE_ALLOCATION_AMOUNT';
const SSA_HOUSEHOLD_BASE_AMOUNT = 'SSA_HOUSEHOLD_BASE_AMOUNT';
const SSA_HOUSEHOLD_SECONDARY_AMOUNT = 'SSA_HOUSEHOLD_SECONDARY_AMOUNT';
const SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE = 'SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE';
const SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT = 'SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT';
const SSA_HOUSEHOLD_USE_SHARED_CUSTODY = 'SSA_HOUSEHOLD_USE_SHARED_CUSTODY';
const SSA_HOUSEHOLD_MAX_ALLOCATION_AMOUNT = 'SSA_HOUSEHOLD_MAX_ALLOCATION_AMOUNT';
const SSA_HOUSEHOLD_COTISATION_MINIMUM = 'SSA_HOUSEHOLD_COTISATION_MINIMUM';
/** /**
* @var \Ramsey\Uuid\UuidInterface * @var \Ramsey\Uuid\UuidInterface
* *
...@@ -130,7 +137,7 @@ class GlobalParameter ...@@ -130,7 +137,7 @@ class GlobalParameter
return $this->value; return $this->value;
} }
public function setValue(string $value): self public function setValue(?string $value): self
{ {
$this->value = $value; $this->value = $value;
......
...@@ -7,35 +7,50 @@ use Symfony\Component\Form\AbstractType; ...@@ -7,35 +7,50 @@ 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\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\GlobalParameter;
class DependentChildFormType extends AbstractType class DependentChildFormType extends AbstractType
{ {
protected $em;
public function __construct(EntityManagerInterface $em) {
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$dependantChildAge = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE);
$builder $builder
->add('olderThanFourteen', ChoiceType::class, array( ->add('olderThanLimitAge', ChoiceType::class, array(
'choices' => [ 'choices' => [
'oui' => true, 'oui' => true,
'non' => false 'non' => false
], ],
'label' => "A-t-il plus de 14 ans ?", 'label' => "A-t-il plus de {$dependantChildAge} ans ?",
'required' => true, 'required' => true,
'expanded' => true 'expanded' => true
)) ))
->add('sharedCustodyPercentage', ChoiceType::class, [
'label' => "Est-il en garde partagée ?",
'required' => true,
'choices' => [
'non' => null,
'oui : je le garde 25 % du temps' => '0.25',//using strings as values (and not floats) seems required
'oui : je le garde 50 % du temps' => '0.50',//to make display work fine
'oui : je le garde 75 % du temps' => '0.75',
],
'required' => false,
'attr' => ['autocomplete' => 'off'] //avoid non-saved value to be displayed
])
; ;
if ('true' === $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::SSA_HOUSEHOLD_USE_SHARED_CUSTODY)) {
$builder
->add('sharedCustodyPercentage', ChoiceType::class, [
'label' => "Est-il en garde partagée ?",
'required' => true,
'choices' => [
'non' => null,
'oui : je le garde 25 % du temps' => '0.25',
'oui : je le garde 50 % du temps' => '0.50',
'oui : je le garde 75 % du temps' => '0.75',
],
'required' => false,
'attr' => ['autocomplete' => 'off'] //avoid non-saved value to be displayed
])
;
}
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
......
<?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 Version20250411113705 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("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_BASE_AMOUNT', 'Valeur de la part de base dans l\allocation par foyer', '150', '1')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_SECONDARY_AMOUNT', 'Valeur des autres parts dans l\allocation par foyer (e.g. à partir du deuxième adulte, enfants à charge, etc...)', '75', '1')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE', 'Age limite des enfants à charge', '14', '1')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT', 'Si défini, valeur des parts pour les enfants à charge sous la limite d\'age. Si non défini, utilise SSA_HOUSEHOLD_SECONDARY_AMOUNT pour tous les enfants à charge.', null, '0')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_USE_SHARED_CUSTODY', 'Si la valeur est à true, active et prend en compte la garde partagé pour les enfants à charge dans le calcul de l\'allocation', 'true', '0')");
$this->addSql("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_MAX_ALLOCATION_AMOUNT', 'Si une valeur est renseignée, applique la valeur comme plafond de montant d\'allocation dans le calcul', null, '0')");
$this->addSql('ALTER TABLE dependent_child CHANGE older_than_fourteen older_than_limit_age TINYINT(1) NOT NULL');
}
public function down(Schema $schema) : void
{
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_BASE_AMOUNT'");
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_SECONDARY_AMOUNT'");
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE'");
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT'");
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_USE_SHARED_CUSTODY'");
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_MAX_ALLOCATION_AMOUNT'");
$this->addSql('ALTER TABLE dependent_child CHANGE older_than_limit_age older_than_fourteen TINYINT(1) NOT NULL');
// this down() migration is auto-generated, please modify it to your needs
}
}
<?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 Version20250411142610 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("INSERT INTO global_parameter (id, name, description, value, mandatory) VALUES (UUID(), 'SSA_HOUSEHOLD_COTISATION_MINIMUM', 'Si défini, valeur minimum de cotisation', '10', '0')");
}
public function down(Schema $schema) : void
{
$this->addSql("DELETE FROM global_parameter WHERE name='SSA_HOUSEHOLD_COTISATION_MINIMUM'");
// this down() migration is auto-generated, please modify it to your needs
}
}
...@@ -175,13 +175,15 @@ class TAVCotisationUtils ...@@ -175,13 +175,15 @@ class TAVCotisationUtils
* allowance based on user's household. * allowance based on user's household.
* *
* Rules are as follow: * Rules are as follow:
* - 150 emlc for the first person in user's household * - [SSA_HOUSEHOLD_BASE_AMOUNT] emlc for the first person in user's household
* - 75 emlc for each other adult * - [SSA_HOUSEHOLD_SECONDARY_AMOUNT] emlc for each other adult
* - 75 emlc amount for each dependant child, with a percentage applied if the child is in shared custody: * - [SSA_HOUSEHOLD_SECONDARY_AMOUNT] emlc for each dependant child above [SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE]
* 25%, 50% or 75% depending on the shared custody arrangement * - if SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT is defined:
* * [SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT] emlc for each dependant child under [SSA_HOUSEHOLD_DEPENDANT_CHILD_LIMIT_AGE]
* Once the full amount is calculated, cap user's balance. * else
* User account balance is capped at twice the amount previously calculated. * [SSA_HOUSEHOLD_SECONDARY_AMOUNT] for all dependant child
* - if SSA_HOUSEHOLD_USE_SHARED_CUSTODY is true:
* apply a percentage if the child is in shared custody: 25%, 50% or 75% depending on the shared custody arrangement
* *
* @param Adherent $adherent (by ref) * @param Adherent $adherent (by ref)
*/ */
...@@ -195,30 +197,56 @@ class TAVCotisationUtils ...@@ -195,30 +197,56 @@ class TAVCotisationUtils
return; return;
} }
// base allowance, for one adult
$mlcAllowanceAmount = 150;
$adultsCount = $adherent->getHouseholdAdultCount(); $adultsCount = $adherent->getHouseholdAdultCount();
if ($adultsCount == null) { if ($adultsCount == null) {
return; return;
} }
// base allowance, for the first adult
$mlcAllowanceAmount = (int) $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_BASE_AMOUNT);
// Get amount for the other houshold members
$mclSecondaryAmount = (int) $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_SECONDARY_AMOUNT);
// increment for each other adult in the household // increment for each other adult in the household
$mlcAllowanceAmount += 75 * ($adultsCount - 1); $mlcAllowanceAmount += $mclSecondaryAmount * ($adultsCount - 1);
// increment allowance for each dependant child, depending on the shared custody arrangement // increment allowance for each dependant child, depending on the shared custody arrangement
$useSharedCustody = $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_USE_SHARED_CUSTODY);
$childUnderLimitAmount = (int) $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_DEPENDANT_CHILD_UNDER_LIMIT_AMOUNT);
$dependentChildren = $adherent->getDependentChildren(); $dependentChildren = $adherent->getDependentChildren();
foreach ($dependentChildren as $child) { foreach ($dependentChildren as $child) {
$childAllowanceAmount = 75; $childAllowanceAmount = $mclSecondaryAmount;
// Different value for children under limit age, if activated
if (false === $child->getOlderThanLimitAge() && null !== $childUnderLimitAmount) {
$childAllowanceAmount = (int) $childUnderLimitAmount;
}
$sharedCustodyPercentage = $child->getSharedCustodyPercentage(); // Apply shared custody percentage if activated and set
if ($sharedCustodyPercentage != null) { if ('true' === $useSharedCustody) {
$childAllowanceAmount = $childAllowanceAmount * $sharedCustodyPercentage; $sharedCustodyPercentage = $child->getSharedCustodyPercentage();
} if ($sharedCustodyPercentage != null) {
$childAllowanceAmount = $childAllowanceAmount * $sharedCustodyPercentage;
}
}
$mlcAllowanceAmount += $childAllowanceAmount; $mlcAllowanceAmount += $childAllowanceAmount;
} }
$maxAllocationAmount = $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::SSA_HOUSEHOLD_MAX_ALLOCATION_AMOUNT);
// Apply cap if activated in configuration
if (null !== $maxAllocationAmount && 0 !== intval($maxAllocationAmount) && $mlcAllowanceAmount > intval($maxAllocationAmount)) {
$mlcAllowanceAmount = intval($maxAllocationAmount);
}
$adherent->setAllocationAmount($mlcAllowanceAmount); $adherent->setAllocationAmount($mlcAllowanceAmount);
} }
......
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