cs: Fix code style (safe rules only).

This commit is contained in:
Pol Dellaiera
2021-11-23 14:06:38 +01:00
parent 149d7ce991
commit 8f96a1121d
1223 changed files with 65199 additions and 64625 deletions

View File

@@ -1,22 +1,22 @@
<?php
/*
*
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Calculator;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
/**
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
interface CalculatorInterface
{
/**
*
* @param AbstractElement[] $elements
*/
public function calculate(array $elements) : ?CalculatorResult;
public function calculate(array $elements): ?CalculatorResult;
public function getAlias();
}

View File

@@ -1,67 +1,71 @@
<?php
/*
*
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Calculator;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
use OutOfBoundsException;
use function array_key_exists;
use function array_keys;
use function implode;
class CalculatorManager
{
/**
*
* @var CalculatorInterface[]
*/
protected $calculators = [];
protected $defaultCalculator = [];
public function addCalculator(CalculatorInterface $calculator, bool $default)
{
$this->calculators[$calculator::getAlias()] = $calculator;
if ($default) {
$this->defaultCalculator[] = $calculator::getAlias();
}
}
/**
*
* @param string $alias
* @return CalculatorInterface
*/
public function getCalculator($alias)
{
if (FALSE === \array_key_exists($alias, $this->calculators)) {
throw new \OutOfBoundsException("The calculator with alias '$alias' does "
. "not exists. Possible values are ". \implode(", ", \array_keys($this->calculators)));
}
return $this->calculators[$alias];
}
/**
*
* @param AbstractElement[] $elements
*
* @return CalculatorResult[]
*/
public function calculateDefault(array $elements)
{
$results = [];
foreach ($this->defaultCalculator as $alias) {
$calculator = $this->calculators[$alias];
$result = $calculator->calculate($elements);
if ($result !== null) {
if (null !== $result) {
$results[$calculator::getAlias()] = $result;
}
}
return $results;
}
/**
* @param string $alias
*
* @return CalculatorInterface
*/
public function getCalculator($alias)
{
if (false === array_key_exists($alias, $this->calculators)) {
throw new OutOfBoundsException("The calculator with alias '{$alias}' does "
. 'not exists. Possible values are ' . implode(', ', array_keys($this->calculators)));
}
return $this->calculators[$alias];
}
}

View File

@@ -1,23 +1,25 @@
<?php
/*
*
*/
namespace Chill\AMLI\BudgetBundle\Calculator;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Calculator;
class CalculatorResult
{
const TYPE_RATE = 'rate';
const TYPE_CURRENCY = 'currency';
const TYPE_PERCENTAGE = 'percentage';
public $type;
public $result;
public const TYPE_CURRENCY = 'currency';
public const TYPE_PERCENTAGE = 'percentage';
public const TYPE_RATE = 'rate';
public $label;
public $result;
public $type;
}

View File

@@ -1,16 +1,23 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Chill\AMLI\BudgetBundle\DependencyInjection\Compiler\CalculatorCompilerPass;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ChillAMLIBudgetBundle extends Bundle
{
public function build(\Symfony\Component\DependencyInjection\ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CalculatorCompilerPass());
}
}

View File

@@ -1,72 +1,68 @@
<?php
/*
*/
namespace Chill\AMLI\BudgetBundle\Config;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Config;
class ConfigRepository
{
/**
*
* @var array
*/
protected $resources;
/**
*
* @var array
*/
protected $charges;
/**
* @var array
*/
protected $resources;
public function __construct($resources, $charges)
{
$this->resources = $resources;
$this->charges = $charges;
}
/**
*
* @return array where keys are the resource'key and label the ressource label
*/
public function getResourcesLabels()
{
$resources = array();
foreach ($this->resources as $definition) {
$resources[$definition['key']] = $this->normalizeLabel($definition['labels']);
}
return $resources;
}
/**
*
* @return array where keys are the resource'key and label the ressource label
*/
public function getChargesLabels()
{
$charges = array();
$charges = [];
foreach ($this->charges as $definition) {
$charges[$definition['key']] = $this->normalizeLabel($definition['labels']);
}
return $charges;
}
private function normalizeLabel($labels)
/**
* @return array where keys are the resource'key and label the ressource label
*/
public function getResourcesLabels()
{
$normalizedLabels = array();
$resources = [];
foreach ($this->resources as $definition) {
$resources[$definition['key']] = $this->normalizeLabel($definition['labels']);
}
return $resources;
}
private function normalizeLabel($labels)
{
$normalizedLabels = [];
foreach ($labels as $labelDefinition) {
$normalizedLabels[$labelDefinition['lang']] = $labelDefinition['label'];
}
return $normalizedLabels;
}
}

View File

@@ -1,38 +1,42 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\TranslatorInterface;
abstract class AbstractElementController extends Controller
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var LoggerInterface
*/
protected $chillMainLogger;
/**
* @var EntityManagerInterface
*/
protected $em;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
@@ -44,94 +48,14 @@ abstract class AbstractElementController extends Controller
}
/**
* @return AbstractElement the newly created element
*/
abstract protected function createNewElement();
abstract protected function getType();
/**
*
*/
protected function _new(Person $person, Request $request, $template, $flashMessageOnSuccess)
{
/* @var $element \Chill\AMLI\BudgetBundle\Entity\AbstractElement */
$element = $this->createNewElement()
->setPerson($person)
;
$this->denyAccessUnlessGranted(BudgetElementVoter::CREATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($element);
$em->flush();
$this->addFlash('success', $this->translator->trans($flashMessageOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $person->getId()
]);
} elseif ($form->isSubmitted()) {
$this->addFlash('error', $this->translator->trans('This form contains errors'));
}
return $this->render($template, array(
'form' => $form->createView(),
'person' => $person,
'element' => $element
));
}
/**
*
* @param AbstractElement $element
* @param Request $request
* @param string $template
* @param string $flashOnSuccess
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function _edit(AbstractElement $element, Request $request, $template, $flashOnSuccess)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::UPDATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
$this->addFlash('success', $this->translator->trans($flashOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $element->getPerson()->getId()
]);
}
return $this->render($template, array(
'element' => $element,
'form' => $form->createView(),
'person' => $element->getPerson()
));
}
/**
*
* Route(
* "{_locale}/family-members/family-members/{id}/delete",
* name="chill_family_members_family_members_delete"
* )
*
* @param AbstractElement $element
* @param Request $request
* ).
*
* @param mixed $template
* @param mixed $flashMessage
*
* @return \Symfony\Component\BrowserKit\Response
*/
protected function _delete(AbstractElement $element, Request $request, $template, $flashMessage)
@@ -145,63 +69,140 @@ abstract class AbstractElementController extends Controller
$form->handleRequest($request);
if ($form->isValid()) {
$this->chillMainLogger->notice("A budget element has been removed", array(
'family_element' => get_class($element),
'by_user' => $this->getUser()->getUsername(),
'family_member_id' => $element->getId(),
'amount' => $element->getAmount(),
'type' => $element->getType()
));
$this->chillMainLogger->notice('A budget element has been removed', [
'family_element' => get_class($element),
'by_user' => $this->getUser()->getUsername(),
'family_member_id' => $element->getId(),
'amount' => $element->getAmount(),
'type' => $element->getType(),
]);
$em = $this->getDoctrine()->getManager();
$em->remove($element);
$em->flush();
$this->addFlash('success', $this->translator
->trans($flashMessage));
->trans($flashMessage));
return $this->redirectToRoute('chill_budget_elements_index', array(
'id' => $element->getPerson()->getId()
));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $element->getPerson()->getId(),
]);
}
}
return $this->render($template, array(
'element' => $element,
'delete_form' => $form->createView()
));
return $this->render($template, [
'element' => $element,
'delete_form' => $form->createView(),
]);
}
/**
* @param string $template
* @param string $flashOnSuccess
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function _edit(AbstractElement $element, Request $request, $template, $flashOnSuccess)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::UPDATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
$this->addFlash('success', $this->translator->trans($flashOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $element->getPerson()->getId(),
]);
}
return $this->render($template, [
'element' => $element,
'form' => $form->createView(),
'person' => $element->getPerson(),
]);
}
/**
* @param mixed $template
* @param mixed $flashMessageOnSuccess
*/
protected function _new(Person $person, Request $request, $template, $flashMessageOnSuccess)
{
/* @var $element \Chill\AMLI\BudgetBundle\Entity\AbstractElement */
$element = $this->createNewElement()
->setPerson($person);
$this->denyAccessUnlessGranted(BudgetElementVoter::CREATE, $element);
$form = $this->createForm($this->getType(), $element);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() and $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($element);
$em->flush();
$this->addFlash('success', $this->translator->trans($flashMessageOnSuccess));
return $this->redirectToRoute('chill_budget_elements_index', [
'id' => $person->getId(),
]);
}
if ($form->isSubmitted()) {
$this->addFlash('error', $this->translator->trans('This form contains errors'));
}
return $this->render($template, [
'form' => $form->createView(),
'person' => $person,
'element' => $element,
]);
}
/**
* Route(
* "{_locale}/family-members/family-members/{id}/view",
* name="chill_family_members_family_members_view"
* )
* ).
*
* @param mixed $template
*/
protected function _view(AbstractElement $element, $template)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::SHOW, $element);
return $this->render($template, array(
'element' => $element
));
return $this->render($template, [
'element' => $element,
]);
}
/**
* @return AbstractElement the newly created element
*/
abstract protected function createNewElement();
abstract protected function getType();
/**
* Creates a form to delete a help request entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm()
{
return $this->createFormBuilder()
->setMethod(Request::METHOD_DELETE)
->add('submit', SubmitType::class, array('label' => 'Delete'))
->getForm()
;
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
}

View File

@@ -1,102 +1,96 @@
<?php
/*
*
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\AMLI\BudgetBundle\Controller\AbstractElementController;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Chill\AMLI\BudgetBundle\Form\ChargeType;
use Chill\PersonBundle\Entity\Person;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ChargeController extends AbstractElementController
{
protected function getType()
{
return ChargeType::class;
}
protected function createNewElement()
{
return new Charge();
}
/**
*
* @Route(
* "{_locale}/budget/charge/{id}/view",
* name="chill_budget_charge_view"
* "{_locale}/budget/charge/{id}/delete",
* name="chill_budget_charge_delete"
* )
* @param Charge $charge
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Charge $charge)
{
return $this->_delete(
$charge,
$request,
'@ChillAMLIBudget/Charge/confirm_delete.html.twig',
'Charge deleted'
);
}
/**
* @Route(
* "{_locale}/budget/charge/{id}/edit",
* name="chill_budget_charge_edit"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Charge $charge)
{
return $this->_edit(
$charge,
$request,
'@ChillAMLIBudget/Charge/edit.html.twig',
'Charge updated'
);
}
/**
* @Route(
* "{_locale}/budget/charge/by-person/{id}/new",
* name="chill_budget_charge_new"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Charge/new.html.twig',
'Charge created'
);
}
/**
* @Route(
* "{_locale}/budget/charge/{id}/view",
* name="chill_budget_charge_view"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function viewAction(Charge $charge)
{
return $this->_view($charge, '@ChillAMLIBudget/Charge/view.html.twig');
}
/**
* @Route(
* "{_locale}/budget/charge/by-person/{id}/new",
* name="chill_budget_charge_new"
* )
*
* @param Request $request
* @param Person $person
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
protected function createNewElement()
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Charge/new.html.twig',
'Charge created');
return new Charge();
}
/**
* @Route(
* "{_locale}/budget/charge/{id}/edit",
* name="chill_budget_charge_edit"
* )
*
* @param Request $request
* @param Charge $charge
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Charge $charge)
protected function getType()
{
return $this->_edit(
$charge,
$request,
'@ChillAMLIBudget/Charge/edit.html.twig',
'Charge updated');
}
/**
*
* @Route(
* "{_locale}/budget/charge/{id}/delete",
* name="chill_budget_charge_delete"
* )
*
* @param Request $request
* @param Charge $charge
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Charge $charge)
{
return $this->_delete(
$charge,
$request,
'@ChillAMLIBudget/Charge/confirm_delete.html.twig',
'Charge deleted');
return ChargeType::class;
}
}

View File

@@ -1,46 +1,49 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Translation\TranslatorInterface;
use Psr\Log\LoggerInterface;
use Chill\AMLI\BudgetBundle\Calculator\CalculatorManager;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Chill\AMLI\BudgetBundle\Calculator\CalculatorManager;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Translation\TranslatorInterface;
use function array_merge;
class ElementController extends Controller
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var LoggerInterface
*/
protected $chillMainLogger;
/**
*
* @var CalculatorManager
*/
protected $calculator;
/**
* @var LoggerInterface
*/
protected $chillMainLogger;
/**
* @var EntityManagerInterface
*/
protected $em;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
EntityManagerInterface $em,
TranslatorInterface $translator,
@@ -52,45 +55,44 @@ class ElementController extends Controller
$this->chillMainLogger = $chillMainLogger;
$this->calculator = $calculator;
}
/**
* @Route(
* "{_locale}/budget/elements/by-person/{id}",
* name="chill_budget_elements_index"
* "{_locale}/budget/elements/by-person/{id}",
* name="chill_budget_elements_index"
* )
*/
public function indexAction(Person $person)
{
$this->denyAccessUnlessGranted(BudgetElementVoter::SHOW, $person);
$charges = $this->em
->getRepository(Charge::class)
->findByPerson($person);
$ressources = $this->em
->getRepository(Resource::class)
->findByPerson($person);
$now = new \DateTime('now');
$now = new DateTime('now');
$actualCharges = $this->em
->getRepository(Charge::class)
->findByPersonAndDate($person, $now);
$actualResources = $this->em
->getRepository(Resource::class)
->findByPersonAndDate($person, $now);
$elements = \array_merge($actualCharges, $actualResources);
$elements = array_merge($actualCharges, $actualResources);
if (count($elements) > 0) {
$results = $this->calculator->calculateDefault($elements);
}
return $this->render('ChillAMLIBudgetBundle:Element:index.html.twig', array(
return $this->render('ChillAMLIBudgetBundle:Element:index.html.twig', [
'person' => $person,
'charges' => $charges,
'resources' => $ressources,
'results' => $results ?? []
));
'results' => $results ?? [],
]);
}
}

View File

@@ -1,103 +1,96 @@
<?php
/*
*
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Chill\AMLI\BudgetBundle\Controller\AbstractElementController;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Chill\AMLI\BudgetBundle\Form\ResourceType;
use Chill\PersonBundle\Entity\Person;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ResourceController extends AbstractElementController
{
protected function getType()
{
return ResourceType::class;
}
protected function createNewElement()
{
return new Resource();
}
/**
*
* @Route(
* "{_locale}/budget/resource/{id}/view",
* name="chill_budget_resource_view"
* "{_locale}/budget/resource/{id}/delete",
* name="chill_budget_resource_delete"
* )
* @param Request $request
* @param Resource $resource
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Resource $resource)
{
return $this->_delete(
$resource,
$request,
'@ChillAMLIBudget/Resource/confirm_delete.html.twig',
'Resource deleted'
);
}
/**
* @Route(
* "{_locale}/budget/resource/{id}/edit",
* name="chill_budget_resource_edit"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Resource $resource)
{
return $this->_edit(
$resource,
$request,
'@ChillAMLIBudget/Resource/edit.html.twig',
'Resource updated'
);
}
/**
* @Route(
* "{_locale}/budget/resource/by-person/{id}/new",
* name="chill_budget_resource_new"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Resource/new.html.twig',
'Resource created'
);
}
/**
* @Route(
* "{_locale}/budget/resource/{id}/view",
* name="chill_budget_resource_view"
* )
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function viewAction(Resource $resource)
{
return $this->_view($resource, '@ChillAMLIBudget/Resource/view.html.twig');
}
/**
* @Route(
* "{_locale}/budget/resource/by-person/{id}/new",
* name="chill_budget_resource_new"
* )
*
* @param Request $request
* @param Person $person
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, Person $person)
protected function createNewElement()
{
return $this->_new(
$person,
$request,
'@ChillAMLIBudget/Resource/new.html.twig',
'Resource created');
return new Resource();
}
/**
* @Route(
* "{_locale}/budget/resource/{id}/edit",
* name="chill_budget_resource_edit"
* )
*
* @param Request $request
* @param Resource $resource
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, Resource $resource)
protected function getType()
{
return $this->_edit(
$resource,
$request,
'@ChillAMLIBudget/Resource/edit.html.twig',
'Resource updated');
}
/**
*
* @Route(
* "{_locale}/budget/resource/{id}/delete",
* name="chill_budget_resource_delete"
* )
*
* @param Request $request
* @param Resource $resource
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteAction(Request $request, Resource $resource)
{
return $this->_delete($resource,
$request,
'@ChillAMLIBudget/Resource/confirm_delete.html.twig',
'Resource deleted');
return ResourceType::class;
}
}

View File

@@ -1,30 +1,34 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
* @see http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class ChillAMLIBudgetExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
$loader->load('services/config.yaml');
$loader->load('services/form.yaml');
$loader->load('services/security.yaml');
@@ -32,7 +36,7 @@ class ChillAMLIBudgetExtension extends Extension implements PrependExtensionInte
$loader->load('services/templating.yaml');
$loader->load('services/menu.yaml');
$loader->load('services/calculator.yaml');
$this->storeConfig('resources', $config, $container);
$this->storeConfig('charges', $config, $container);
}
@@ -42,36 +46,35 @@ class ChillAMLIBudgetExtension extends Extension implements PrependExtensionInte
$this->prependAuthorization($container);
$this->prependRoutes($container);
}
protected function storeConfig($position, array $config, ContainerBuilder $container)
/* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/
public function prependRoutes(ContainerBuilder $container)
{
$container
->setParameter(sprintf('chill_budget.%s', $position), $config[$position])
;
//add routes for custom bundle
$container->prependExtensionConfig('chill_main', [
'routing' => [
'resources' => [
'@ChillAMLIBudgetBundle/config/routing.yaml',
],
],
]);
}
protected function prependAuthorization(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
BudgetElementVoter::UPDATE => [ BudgetElementVoter::SHOW ],
BudgetElementVoter::CREATE => [ BudgetElementVoter::SHOW ]
)
));
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
BudgetElementVoter::UPDATE => [BudgetElementVoter::SHOW],
BudgetElementVoter::CREATE => [BudgetElementVoter::SHOW],
],
]);
}
/* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/
public function prependRoutes(ContainerBuilder $container)
protected function storeConfig($position, array $config, ContainerBuilder $container)
{
//add routes for custom bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillAMLIBudgetBundle/config/routing.yaml'
)
)
));
$container
->setParameter(sprintf('chill_budget.%s', $position), $config[$position]);
}
}

View File

@@ -1,29 +1,29 @@
<?php
/*
*
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CalculatorCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$manager = $container->getDefinition('Chill\AMLI\BudgetBundle\Calculator\CalculatorManager');
foreach ($container->findTaggedServiceIds('chill_budget.calculator') as $id => $tags) {
foreach($tags as $tag) {
foreach ($tags as $tag) {
$reference = new Reference($id);
$manager->addMethodCall('addCalculator', [ $reference, $tag['default'] ?? false ]);
$manager->addMethodCall('addCalculator', [$reference, $tag['default'] ?? false]);
}
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@@ -12,66 +19,61 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('chill_amli_budget');
$rootNode = $treeBuilder->getRootNode('chill_amli_budget');
$rootNode
->children()
// ressources
->arrayNode('resources')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('charges')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('resources')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
;
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('charges')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('salary')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Salaire')
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
}

View File

@@ -1,46 +1,38 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* AbstractElement
* AbstractElement.
*
* @ORM\MappedSuperclass()
* @ORM\MappedSuperclass
*/
abstract class AbstractElement
{
/**
*
* @var Person
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Person"
* )
*/
private $person;
/**
* @var string
*
* @ORM\Column(name="type", type="string", length=255)
*/
private $type;
/**
* @var decimal
*
* @ORM\Column(name="amount", type="decimal", precision=10, scale=2)
* @Assert\GreaterThan(
* value=0
* value=0
* )
* @Assert\NotNull(
* message="The amount cannot be empty"
* message="The amount cannot be empty"
* )
*
*/
private $amount;
@@ -52,52 +44,82 @@ abstract class AbstractElement
private $comment;
/**
* @var \DateTimeImmutable
* @var DateTimeImmutable|null
*
* @ORM\Column(name="endDate", type="datetime_immutable", nullable=true)
* @Assert\GreaterThan(
* propertyPath="startDate",
* message="The budget element's end date must be after the start date"
* )
*/
private $endDate;
/**
* @var Person
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Person"
* )
*/
private $person;
/**
* @var DateTimeImmutable
*
* @ORM\Column(name="startDate", type="datetime_immutable")
* @Assert\Date()
* @Assert\Date
*/
private $startDate;
/**
* @var \DateTimeImmutable|null
* @var string
*
* @ORM\Column(name="endDate", type="datetime_immutable", nullable=true)
* @Assert\GreaterThan(
* propertyPath="startDate",
* message="The budget element's end date must be after the start date"
* )
* @ORM\Column(name="type", type="string", length=255)
*/
private $endDate;
abstract public function isCharge(): bool;
abstract public function isResource(): bool;
private $type;
/**
* Get amount.
*
* @return float
*/
public function getAmount()
{
return (float) $this->amount;
}
/**
* Get comment.
*
* @return string|null
*/
public function getComment()
{
return $this->comment;
}
/**
* Get endDate.
*
* @return DateTimeImmutable|null
*/
public function getEndDate()
{
return $this->endDate;
}
public function getPerson(): Person
{
return $this->person;
}
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
/**
* Set type.
* Get startDate.
*
* @param string $type
*
* @return AbstractElement
* @return DateTimeImmutable
*/
public function setType($type)
public function getStartDate()
{
$this->type = $type;
return $this;
return $this->startDate;
}
/**
@@ -110,6 +132,15 @@ abstract class AbstractElement
return $this->type;
}
abstract public function isCharge(): bool;
public function isEmpty()
{
return 0 == $this->amount;
}
abstract public function isResource(): bool;
/**
* Set amount.
*
@@ -124,16 +155,6 @@ abstract class AbstractElement
return $this;
}
/**
* Get amount.
*
* @return double
*/
public function getAmount()
{
return (double) $this->amount;
}
/**
* Set comment.
*
@@ -149,27 +170,40 @@ abstract class AbstractElement
}
/**
* Get comment.
* Set endDate.
*
* @return string|null
* @return AbstractElement
*/
public function getComment()
public function setEndDate(?DateTimeInterface $endDate = null)
{
return $this->comment;
if ($endDate instanceof DateTime) {
$this->endDate = DateTimeImmutable::createFromMutable($endDate);
} elseif (null === $endDate) {
$this->endDate = null;
} else {
$this->endDate = $endDate;
}
return $this;
}
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
/**
* Set startDate.
*
* @param \DateTimeInterface $startDate
*
* @return AbstractElement
*/
public function setStartDate(\DateTimeInterface $startDate)
public function setStartDate(DateTimeInterface $startDate)
{
if ($startDate instanceof \DateTime) {
$this->startDate = \DateTimeImmutable::createFromMutable($startDate);
} elseif (NULL === $startDate) {
if ($startDate instanceof DateTime) {
$this->startDate = DateTimeImmutable::createFromMutable($startDate);
} elseif (null === $startDate) {
$this->startDate = null;
} else {
$this->startDate = $startDate;
@@ -179,47 +213,16 @@ abstract class AbstractElement
}
/**
* Get startDate.
* Set type.
*
* @return \DateTimeImmutable
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate.
*
* @param \DateTimeInterface|null $endDate
* @param string $type
*
* @return AbstractElement
*/
public function setEndDate(\DateTimeInterface $endDate = null)
public function setType($type)
{
if ($endDate instanceof \DateTime) {
$this->endDate = \DateTimeImmutable::createFromMutable($endDate);
} elseif (NULL === $endDate) {
$this->endDate = null;
} else {
$this->endDate = $endDate;
}
$this->type = $type;
return $this;
}
/**
* Get endDate.
*
* @return \DateTimeImmutable|null
*/
public function getEndDate()
{
return $this->endDate;
}
public function isEmpty()
{
return $this->amount == 0;
}
}

View File

@@ -1,18 +1,47 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\HasCenterInterface;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
/**
* Charge
* Charge.
*
* @ORM\Table(name="chill_budget.charge")
* @ORM\Entity(repositoryClass="Chill\AMLI\BudgetBundle\Repository\ChargeRepository")
*/
class Charge extends AbstractElement implements HasCenterInterface
{
public const HELP_ASKED = 'running';
public const HELP_NO = 'no';
public const HELP_NOT_RELEVANT = 'not-relevant';
public const HELP_YES = 'yes';
public const HELPS = [
self::HELP_ASKED,
self::HELP_NO,
self::HELP_YES,
self::HELP_NOT_RELEVANT,
];
/**
* @var string
* @ORM\Column(name="help", type="string", nullable=true)
*/
private $help = self::HELP_NOT_RELEVANT;
/**
* @var int
*
@@ -21,30 +50,20 @@ class Charge extends AbstractElement implements HasCenterInterface
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @var string
* @ORM\Column(name="help", type="string", nullable=true)
*/
private $help = self::HELP_NOT_RELEVANT;
const HELP_ASKED = 'running';
const HELP_NO = 'no';
const HELP_YES = 'yes';
const HELP_NOT_RELEVANT = 'not-relevant';
const HELPS = [
self::HELP_ASKED,
self::HELP_NO,
self::HELP_YES,
self::HELP_NOT_RELEVANT
];
public function __construct()
{
$this->setStartDate(new \DateTimeImmutable('today'));
$this->setStartDate(new DateTimeImmutable('today'));
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
public function getHelp()
{
return $this->help;
}
/**
@@ -56,23 +75,6 @@ class Charge extends AbstractElement implements HasCenterInterface
{
return $this->id;
}
public function getHelp()
{
return $this->help;
}
public function setHelp($help)
{
$this->help = $help;
return $this;
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
public function isCharge(): bool
{
@@ -83,4 +85,11 @@ class Charge extends AbstractElement implements HasCenterInterface
{
return false;
}
public function setHelp($help)
{
$this->help = $help;
return $this;
}
}

View File

@@ -1,12 +1,20 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\HasCenterInterface;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
/**
* Resource
* Resource.
*
* @ORM\Table(name="chill_budget.resource")
* @ORM\Entity(repositoryClass="Chill\AMLI\BudgetBundle\Repository\ResourceRepository")
@@ -21,13 +29,17 @@ class Resource extends AbstractElement implements HasCenterInterface
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
public function __construct()
{
$this->setStartDate(new \DateTimeImmutable('today'));
$this->setStartDate(new DateTimeImmutable('today'));
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
/**
* Get id.
*
@@ -38,11 +50,6 @@ class Resource extends AbstractElement implements HasCenterInterface
return $this->id;
}
public function getCenter(): \Chill\MainBundle\Entity\Center
{
return $this->getPerson()->getCenter();
}
public function isCharge(): bool
{
return false;

View File

@@ -1,19 +1,28 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\AMLI\BudgetBundle\Form;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\AMLI\BudgetBundle\Entity\Charge;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use function array_flip;
use function asort;
class ChargeType extends AbstractType
{
@@ -34,23 +43,23 @@ class ChargeType extends AbstractType
$builder
->add('type', ChoiceType::class, [
'choices' => $this->getTypes(),
'placeholder' => 'Choose a charge type'
'placeholder' => 'Choose a charge type',
])
->add('amount', MoneyType::class)
->add('comment', TextareaType::class, [
'required' => false
'required' => false,
]);
if ($options['show_start_date']) {
$builder->add('startDate', ChillDateType::class, [
'label' => 'Start of validity period'
'label' => 'Start of validity period',
]);
}
if ($options['show_end_date']) {
$builder->add('endDate', ChillDateType::class, [
'required' => false,
'label' => 'End of validity period'
'label' => 'End of validity period',
]);
}
@@ -60,15 +69,35 @@ class ChargeType extends AbstractType
'charge.help.running' => Charge::HELP_ASKED,
'charge.help.no' => Charge::HELP_NO,
'charge.help.yes' => Charge::HELP_YES,
'charge.help.not-concerned' => Charge::HELP_NOT_RELEVANT
'charge.help.not-concerned' => Charge::HELP_NOT_RELEVANT,
],
'placeholder' => 'Choose a status',
'required' => false,
'label' => 'Help to pay charges'
'label' => 'Help to pay charges',
]);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Charge::class,
'show_start_date' => true,
'show_end_date' => true,
'show_help' => true,
]);
$resolver
->setAllowedTypes('show_start_date', 'boolean')
->setAllowedTypes('show_end_date', 'boolean')
->setAllowedTypes('show_help', 'boolean');
}
public function getBlockPrefix()
{
return 'chill_amli_budgetbundle_charge';
}
private function getTypes()
{
$charges = $this->configRepository
@@ -79,28 +108,8 @@ class ChargeType extends AbstractType
$charges[$key] = $this->translatableStringHelper->localize($labels);
}
\asort($charges);
asort($charges);
return \array_flip($charges);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Charge::class,
'show_start_date' => true,
'show_end_date' => true,
'show_help' => true
));
$resolver
->setAllowedTypes('show_start_date', 'boolean')
->setAllowedTypes('show_end_date', 'boolean')
->setAllowedTypes('show_help', 'boolean');
}
public function getBlockPrefix()
{
return 'chill_amli_budgetbundle_charge';
return array_flip($charges);
}
}

View File

@@ -1,19 +1,27 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\AMLI\BudgetBundle\Form;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\AMLI\BudgetBundle\Entity\Resource;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use function array_flip;
class ResourceType extends AbstractType
{
@@ -35,34 +43,34 @@ class ResourceType extends AbstractType
->add('type', ChoiceType::class, [
'choices' => $this->getTypes(),
'placeholder' => 'Choose a resource type',
'label' => 'Resource element type'
'label' => 'Resource element type',
])
->add('amount', MoneyType::class)
->add('comment', TextareaType::class, [
'required' => false
'required' => false,
]);
if ($options['show_start_date']) {
$builder->add('startDate', ChillDateType::class, [
'label' => 'Start of validity period'
'label' => 'Start of validity period',
]);
}
if ($options['show_end_date']) {
$builder->add('endDate', ChillDateType::class, [
'required' => false,
'label' => 'End of validity period'
'label' => 'End of validity period',
]);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
$resolver->setDefaults([
'data_class' => Resource::class,
'show_start_date' => true,
'show_end_date' => true
));
'show_end_date' => true,
]);
$resolver
->setAllowedTypes('show_start_date', 'boolean')
@@ -86,6 +94,6 @@ class ResourceType extends AbstractType
asort($resources);
return \array_flip($resources);
return array_flip($resources);
}
}

View File

@@ -1,60 +1,59 @@
<?php
/*
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Menu;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Chill\AMLI\BudgetBundle\Security\Authorization\BudgetElementVoter;
use Symfony\Component\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class UserMenuBuilder implements LocalMenuBuilderInterface
{
/**
*
* @var AuthorizationCheckerInterface
*/
protected $authorizationChecker;
/**
*
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
AuthorizationCheckerInterface $authorizationChecker,
AuthorizationCheckerInterface $authorizationChecker,
TranslatorInterface $translator
) {
$this->authorizationChecker = $authorizationChecker;
$this->translator = $translator;
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
/* @var $person \Chill\PersonBundle\Entity\Person */
$person = $parameters['person'];
if ($this->authorizationChecker->isGranted(BudgetElementVoter::SHOW, $person)) {
$menu->addChild(
$this->translator->trans('Budget'), [
$this->translator->trans('Budget'),
[
'route' => 'chill_budget_elements_index',
'routeParameters' => [ 'id' => $person->getId() ],
])
->setExtra('order', 460)
;
'routeParameters' => ['id' => $person->getId()],
]
)
->setExtra('order', 460);
}
}
public static function getMenuIds(): array
{
return [ 'person' ];
return ['person'];
}
}

View File

@@ -1,35 +1,42 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Repository;
use Chill\PersonBundle\Entity\Person;
use DateTime;
/**
* ChargeRepository
* ChargeRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ChargeRepository extends \Doctrine\ORM\EntityRepository
{
public function findByPersonAndDate(Person $person, \DateTime $date, $sort = null)
public function findByPersonAndDate(Person $person, DateTime $date, $sort = null)
{
$qb = $this->createQueryBuilder('c');
$qb->where('c.person = :person')
->andWhere('c.startDate < :date')
->andWhere('c.startDate < :date OR c.startDate IS NULL')
;
if ($sort !== null) {
->andWhere('c.startDate < :date OR c.startDate IS NULL');
if (null !== $sort) {
$qb->orderBy($sort);
}
$qb->setParameters([
'person' => $person,
'date' => $date
'date' => $date,
]);
return $qb->getQuery()->getResult();
}
}

View File

@@ -1,35 +1,42 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Repository;
use Chill\PersonBundle\Entity\Person;
use DateTime;
/**
* ResourceRepository
* ResourceRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ResourceRepository extends \Doctrine\ORM\EntityRepository
{
public function findByPersonAndDate(Person $person, \DateTime $date, $sort = null)
public function findByPersonAndDate(Person $person, DateTime $date, $sort = null)
{
$qb = $this->createQueryBuilder('c');
$qb->where('c.person = :person')
->andWhere('c.startDate < :date')
->andWhere('c.startDate < :date OR c.startDate IS NULL')
;
if ($sort !== null) {
->andWhere('c.startDate < :date OR c.startDate IS NULL');
if (null !== $sort) {
$qb->orderBy($sort);
}
$qb->setParameters([
'person' => $person,
'date' => $date
'date' => $date,
]);
return $qb->getQuery()->getResult();
}
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Application\Migrations;
@@ -6,10 +15,17 @@ use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* create schema for chill budget
* create schema for chill budget.
*/
final class Version20180522080432 extends AbstractMigration
{
public function down(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SCHEMA chill_budget CASCADE');
}
public function up(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
@@ -28,14 +44,5 @@ final class Version20180522080432 extends AbstractMigration
$this->addSql('COMMENT ON COLUMN chill_budget.charge.endDate IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE chill_budget.resource ADD CONSTRAINT FK_5E0A5E97217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_budget.charge ADD CONSTRAINT FK_5C99D2C3217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SCHEMA chill_budget CASCADE');
}
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Application\Migrations;
@@ -6,21 +15,21 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* autorise les valeurs nulles dans "HELP"
* autorise les valeurs nulles dans "HELP".
*/
final class Version20181219145631 extends AbstractMigration
{
public function up(Schema $schema) : void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_budget.charge ALTER help DROP NOT NULL');
}
public function down(Schema $schema) : void
public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_budget.charge ALTER help SET NOT NULL');
}
public function up(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_budget.charge ALTER help DROP NOT NULL');
}
}

View File

@@ -1,37 +1,41 @@
<?php
/*
*/
namespace Chill\AMLI\BudgetBundle\Security\Authorization;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Security\Core\Role\Role;
/**
* Chill is a software for social workers
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Security\Authorization;
use Chill\AMLI\BudgetBundle\Entity\AbstractElement;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Security\Core\Role\Role;
use function in_array;
class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
const CREATE = 'CHILL_BUDGET_ELEMENT_CREATE';
const DELETE = 'CHILL_BUDGET_ELEMENT_DELETE';
const UPDATE = 'CHILL_BUDGET_ELEMENT_UPDATE';
const SHOW = 'CHILL_BUDGET_ELEMENT_SHOW';
public const CREATE = 'CHILL_BUDGET_ELEMENT_CREATE';
const ROLES = [
public const DELETE = 'CHILL_BUDGET_ELEMENT_DELETE';
public const ROLES = [
self::CREATE,
self::DELETE,
self::SHOW,
self::UPDATE
self::UPDATE,
];
public const SHOW = 'CHILL_BUDGET_ELEMENT_SHOW';
public const UPDATE = 'CHILL_BUDGET_ELEMENT_UPDATE';
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
@@ -41,26 +45,6 @@ class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierar
$this->authorizationHelper = $authorizationHelper;
}
protected function supports($attribute, $subject)
{
return (\in_array($attribute, self::ROLES) && $subject instanceof AbstractElement)
or
($subject instanceof Person && \in_array($attribute, [ self::SHOW, self::CREATE ]));
}
protected function voteOnAttribute($attribute, $subject, \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token)
{
$user = $token->getUser();
if (FALSE === $user instanceof User) {
return false;
}
return $this->authorizationHelper
->userHasAccess($user, $subject, new Role($attribute));
}
public function getRoles(): array
{
return self::ROLES;
@@ -76,4 +60,21 @@ class BudgetElementVoter extends AbstractChillVoter implements ProvideRoleHierar
return self::ROLES;
}
protected function supports($attribute, $subject)
{
return (in_array($attribute, self::ROLES) && $subject instanceof AbstractElement)
or ($subject instanceof Person && in_array($attribute, [self::SHOW, self::CREATE]));
}
protected function voteOnAttribute($attribute, $subject, \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token)
{
$user = $token->getUser();
if (false === $user instanceof User) {
return false;
}
return $this->authorizationHelper
->userHasAccess($user, $subject, new Role($attribute));
}
}

View File

@@ -1,65 +1,63 @@
<?php
/*
*
*/
namespace Chill\AMLI\BudgetBundle\Templating;
use Twig\Extension\AbstractExtension;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Twig\TwigFilter;
/**
*
* Chill is a software for social workers
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Templating;
use Chill\AMLI\BudgetBundle\Config\ConfigRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use UnexpectedValueException;
class Twig extends AbstractExtension
{
/**
*
* @var ConfigRepository
*/
protected $configRepository;
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(
ConfigRepository $configRepository,
ConfigRepository $configRepository,
TranslatableStringHelper $translatableStringHelper
) {
$this->configRepository = $configRepository;
$this->translatableStringHelper = $translatableStringHelper;
}
public function getFilters()
{
return [
new TwigFilter('budget_element_type_display', [ $this, 'displayLink' ], [ 'is_safe' => [ 'html' ]])
];
}
public function displayLink($link, $family)
{
switch($family) {
switch ($family) {
case 'resource':
return $this->translatableStringHelper->localize(
$this->configRepository->getResourcesLabels()[$link]
);
);
case 'charge':
return $this->translatableStringHelper->localize(
$this->configRepository->getChargesLabels()[$link]
);
);
default:
throw new \UnexpectedValueException("This family of element: $family is not "
throw new UnexpectedValueException("This family of element: {$family} is not "
. "supported. Supported families are 'resource', 'charge'");
}
}
public function getFilters()
{
return [
new TwigFilter('budget_element_type_display', [$this, 'displayLink'], ['is_safe' => ['html']]),
];
}
}

View File

@@ -1,18 +1,22 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\AMLI\BudgetBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class ElementControllerTest extends WebTestCase
{
public function testList()
{
$client = static::createClient();
$crawler = $client->request('GET', '/list');
}
public function testIndex()
{
$client = static::createClient();
@@ -20,4 +24,10 @@ class ElementControllerTest extends WebTestCase
$crawler = $client->request('GET', '/index');
}
public function testList()
{
$client = static::createClient();
$crawler = $client->request('GET', '/list');
}
}