Commit 7dbd77e8 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

Administration des flux en cours (reste la gestion du champ public)

parent 1f9464ea
Loading
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -23,13 +23,25 @@ class ActivityDateFlowController extends AbstractOscarController

    public function adminAction(){
        if( $this->isAjax() || $this->params()->fromQuery('f') === 'json' ){

            $creatorId = $this->getOscarUserContextService()->getAuthentification()->getId();

            switch ($this->getHttpXMethod()) {
                case Request::METHOD_PUT:
                    $datas = $this->getJsonREST();
                    throw new OscarException(json_encode($datas));
                    $this->getActivityDateFlowService()->putJsonDateFlow($datas, $creatorId);
                    return $this->getResponseOk();
                case Request::METHOD_POST:
                    $datas = $this->getJsonPosted();
                    $this->getActivityDateFlowService()->postJsonDateFlow($datas, $creatorId);
                    return $this->getResponseOk();
                case Request::METHOD_DELETE:
                    $dateflowId = $this->getRequest()->getQuery('id');
                    $this->getActivityDateFlowService()->deleteById($dateflowId, $creatorId);
                    return $this->getResponseOk();
                case Request::METHOD_GET:
                    $data = [
                        'activitydateflows' => $this->getActivityDateFlowService()->getDateFlows(),
                        'activitydateflows' => $this->getActivityDateFlowService()->getDateFlows($creatorId),
                        'datetypes' => $this->getActivityDateFlowService()->getDateTypes()
                    ];
                    return $this->jsonOutput($data);
+66 −8
Original line number Diff line number Diff line
@@ -25,21 +25,39 @@ class ActivityDateFlow
     */
    private string $label;

    /**
     * @var int
     * @ORM\Column(type="integer", nullable=true)
     */
    private ?int $createdBy = 0;

    /**
     * @var string
     * @ORM\Column(type="string", nullable=true)
     */
    private string $description;

    /**
     * @var boolean
     * @ORM\Column(type="boolean", options={"default": "true"})
     */
    private string $public;


    /**
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\ManyToMany(targetEntity="ActivityDateFlowElement")
     * @ORM\OneToMany(
     *     targetEntity="ActivityDateFlowElement",
     *     mappedBy="activityDateFlow",
     *     cascade={"persist", "remove"},
     *     orphanRemoval=true
     * )
     */
    private Collection $dateTypes;
    private Collection $elements;

    public function __construct()
    {
        $this->dateTypes = new ArrayCollection();
        $this->elements = new ArrayCollection();
    }

    /**
@@ -70,23 +88,63 @@ class ActivityDateFlow
        $this->description = $description;
    }

    public function getElements(): Collection
    {
        return $this->elements;
    }

    public function addElement(ActivityDateFlowElement $element): self
    {
        if (!$this->elements->contains($element)) {
            $this->elements[] = $element;
            $element->setActivityDateFlow($this);
        }
        return $this;
    }

    public function removeElement(ActivityDateFlowElement $element): self
    {
        if ($this->elements->removeElement($element)) {
            // Si nécessaire, on casse la relation inverse
            if ($element->getActivityDateFlow() === $this) {
                $element->setActivityDateFlow(null);
            }
        }
        return $this;
    }

    public function getDateTypes(): \Doctrine\Common\Collections\Collection
    {
        return $this->dateTypes;
        return $this->elements;
    }

    public function addDateType(ActivityDateFlowElement $dateType): void
    {
        $this->dateTypes->add($dateType);
        $this->addElement($dateType);
    }

    public function removeDateType(ActivityDateFlowElement $dateType): void
    {
        $this->dateTypes->removeElement($dateType);
        $this->removeElement($dateType);
    }

    public function getCreatedBy(): ?int
    {
        return $this->createdBy;
    }

    public function setCreatedBy(?int $createdBy): void
    {
        $this->createdBy = $createdBy;
    }

    public function getPublic(): bool
    {
        return $this->public;
    }

    public function setDateTypes(\Doctrine\Common\Collections\Collection $dateTypes): void
    public function setPublic(bool $public): void
    {
        $this->dateTypes = $dateTypes;
        $this->public = $public;
    }
}
 No newline at end of file
+40 −0
Original line number Diff line number Diff line
@@ -30,6 +30,20 @@ class ActivityDateFlowElement
     */
    private int $daysInterval;

    /**
     * @ORM\ManyToOne(targetEntity=ActivityDateFlow::class, inversedBy="elements")
     * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
     */
    private $activityDateFlow;

    /**
     * @var int
     * @ORM\Column(type="integer")
     */
    private int $ordering;



    /**
     * @return mixed
     */
@@ -38,6 +52,16 @@ class ActivityDateFlowElement
        return $this->id;
    }

    public function getOrder(): int
    {
        return $this->ordering;
    }

    public function setOrder(int $ordering): void
    {
        $this->ordering = $ordering;
    }

    public function getDateType(): DateType
    {
        return $this->dateType;
@@ -57,4 +81,20 @@ class ActivityDateFlowElement
    {
        $this->daysInterval = $daysInterval;
    }

    /**
     * @return mixed
     */
    public function getActivityDateFlow()
    {
        return $this->activityDateFlow;
    }

    /**
     * @param mixed $activityDateFlow
     */
    public function setActivityDateFlow($activityDateFlow): void
    {
        $this->activityDateFlow = $activityDateFlow;
    }
}
 No newline at end of file
+154 −3
Original line number Diff line number Diff line
@@ -5,9 +5,13 @@ namespace Oscar\Service;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Exception\NotSupported;
use Oscar\Entity\ActivityDateFlow;
use Oscar\Entity\ActivityDateFlowElement;
use Oscar\Entity\Authentification;
use Oscar\Entity\AuthentificationRepository;
use Oscar\Entity\DateType;
use Oscar\Entity\DateTypeRepository;
use Oscar\Entity\Repository\ActivityDateFlowRepository;
use Oscar\Exception\OscarException;

class ActivityDateFlowService
{
@@ -32,10 +36,157 @@ class ActivityDateFlowService
        return $dateTypeRepository->allArray();
    }

    /**
     * Retourne les modèles de jalons disponibles.
     * @return array
     */
    public function getDateFlows()
    {
        /** @var ActivityDateFlowRepository $activityDateFlowRepository */
        $activityDateFlowRepository = $this->entityManager->getRepository(ActivityDateFlow::class);
        return $activityDateFlowRepository->getAllArray();
        $dateflows = $this->getActivityDateFlowRepository()->findAll();
        /** @var AuthentificationRepository $authentificationRepository */
        $authentificationRepository = $this->entityManager->getRepository(Authentification::class);
        $out = [];
        /** @var ActivityDateFlow $dateflow */
        foreach ($dateflows as $dateflow) {
            $createdBy = $dateflow->getCreatedBy() ? $authentificationRepository->find($dateflow->getCreatedBy()) : null;
            $creator = $createdBy? $createdBy->getUsername() : "Anonymous";

            $elements = [];
            /** @var ActivityDateFlowElement $dateFlowElement */
            foreach ($dateflow->getDateTypes() as $dateFlowElement) {
                $elements[] = [
                    'id' => $dateFlowElement->getId(),
                    'interval' => $dateFlowElement->getDaysInterval(),
                    'order' => $dateFlowElement->getOrder(),
                    'datetype' => [
                        'id' => $dateFlowElement->getDateType()->getId(),
                        'label' => $dateFlowElement->getDateType()->getLabel(),
                    ]
                ];
            }
            usort($elements, function ($a, $b) {
                return $a['order'] <=> $b['order']; // tri ascendant
            });
            $out[] = [
                'id' => $dateflow->getId(),
                'label' => $dateflow->getLabel(),
                'description' => $dateflow->getDescription(),
                'createdBy' => $creator,
                'datetypes' => $elements,
                'public' => $dateflow->getPublic(),
            ];

        }
        return $out;
    }


    /**
     * Enregistrement d'un modèle de jalon (POST - Mise à jour)
     * @param mixed $jsonDatas
     * @return void
     */
    public function postJsonDateFlow(mixed $jsonDatas, ?int $creatorId) :void
    {
        $this->saveJson($jsonDatas, $creatorId);
    }

    /**
     * Enregistrement d'un modèle de jalon (PUT - Nouveau)
     * @param mixed $jsonDatas
     * @return void
     */
    public function putJsonDateFlow(mixed $jsonDatas, ?int $creatorId) :void
    {
        $this->saveJson($jsonDatas, $creatorId);
    }

    /**
     * Suppression d'un modèle de jalon
     * @param mixed $dateflowId
     * @return void
     * @throws OscarException
     */
    public function deleteById(mixed $dateflowId)
    {
        try {
            $dateflow = $this->getActivityDateFlowRepository()->find($dateflowId);
            $this->entityManager->remove($dateflow);
            $this->entityManager->flush();
        } catch (\Exception $exception) {
            $this->loggerService->throw($exception, "Can't delete ActivityDateFlow($dateflowId) : " . $e->getMessage());
        }
    }

    /**
     * Enregistrement d'un modèle de jalon
     * @param mixed $jsonDatas
     * @return void
     * @throws OscarException
     * @throws \Doctrine\ORM\Exception\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    private function saveJson(mixed $jsonDatas, ?int $creatorId) :void
    {
        $dateflowId = $jsonDatas['id'];
        if( $dateflowId ) {
            try {
                /** @var ActivityDateFlow $dateflow */
                $dateflow = $this->getActivityDateFlowRepository()->find($dateflowId);
                $dateflowelements_exist = array_map(function($element) { return $element->getId(); }, $dateflow->getElements()->toArray());
                $dateflowelements_input = array_map(function($element) { return $element['id']; }, $jsonDatas['datetypes']);
                $dateflowelements_deleted = array_diff($dateflowelements_exist, $dateflowelements_input);
                foreach ($dateflowelements_deleted as $dateflowelementId) {
                    $dateflowelement = $this->entityManager->getRepository(ActivityDateFlowElement::class)->find($dateflowelementId);
                    $this->entityManager->remove($dateflowelement);
                }
            } catch (\Exception $e){
                $this->loggerService->throw($e, "Can't get ActivityDateFlow($dateflowId) : " . $e->getMessage());
                return;
            }
        } else {
            $dateflow = new ActivityDateFlow();
            $this->entityManager->persist($dateflow);
        }

        $dateflow->setLabel($jsonDatas['label']);
        $dateflow->setDescription($jsonDatas['description']);
        $dateflow->setCreatedBy($creatorId);
        $dateflow->setPublic(boolval($jsonDatas['public']));

        // Trier les données par ORDER*
        usort($jsonDatas['datetypes'], function ($a, $b) {
            return $a['order'] <=> $b['order']; // tri ascendant
        });

        $order = 1;
        foreach ($jsonDatas['datetypes'] as $datetypeDatas) {
            try {
                $id = $datetypeDatas['id'];
                $datetypeId = $datetypeDatas['datetype']['id'];
                $this->loggerService->info("datetype_id: $datetypeId");
                $this->loggerService->info("datetype_id: $datetypeId");
                $datatype = $this->entityManager->getRepository(DateType::class)->find($datetypeId);
                if( $id ){
                    $dateFlowElement = $this->entityManager->getRepository(ActivityDateFlowElement::class)->find($id);
                } else {
                    $dateFlowElement = new ActivityDateFlowElement();
                    $this->entityManager->persist($dateFlowElement);
                }
                $dateFlowElement->setDateType($datatype);
                $dateFlowElement->setOrder($order++);
                $dateFlowElement->setDaysInterval($datetypeDatas['interval']);
                $dateflow->addDateType($dateFlowElement);
            } catch (\Exception $exception) {
                $this->loggerService->throw($exception, "Can't save ActivityDateFlowElement");
            }
        }
        $this->entityManager->flush();
    }

    ////////////////////////////////////////////////////////////////////////
    protected function getActivityDateFlowRepository():ActivityDateFlowRepository
    {
        return $this->entityManager->getRepository(ActivityDateFlow::class);
    }
}
 No newline at end of file
+60 −12
Original line number Diff line number Diff line
@@ -35,13 +35,25 @@ export default {
      this.form = {
        id: null,
        label: "",
        public: false,
        description: "",
        datetypes: [
          {id: null, order: 1, datetype: {id: 4, label: "Test"}}
        ]
        datetypes: []
      };
    },

    handlerEdit(dateflow){
      this.form = JSON.parse(JSON.stringify(dateflow));
    },

    handlerDuplicate(dateflow){
      let duplicated = JSON.parse(JSON.stringify(dateflow));
      duplicated.id = null;
      duplicated.datetypes.forEach( datetype => {
        datetype.id = null;
      });
      this.form = duplicated;
    },

    handlerDown(datetype){
      console.log("BAS");
      let currentIndex = this.form.datetypes.indexOf(datetype);
@@ -59,7 +71,6 @@ export default {
    },

    handlerUp(datetype){
      console.log("HAUT");
      let currentIndex = this.form.datetypes.indexOf(datetype);
      let currentItem = this.form.datetypes[currentIndex];
      let currentOrder = currentItem.order;
@@ -90,15 +101,12 @@ export default {
            interval: 0,
            order: order,
            datetype: {
              id: null,
              datetype_id: selectedDateType,
              id: selectedDateType,
              label: this.datetypes.find(i => i.id == selectedDateType).label
            }
          }
      )
      event.target.value = null;
      console.log("Datetypes(après) > ", this.form.datetypes.map( item => item.order));
//      console.log(this.datetypes.find(i => i.id = selectedDateType));
    },

    handlerSave(){
@@ -110,7 +118,14 @@ export default {
        res = AxiosOscar.put(this.url, json);
      }
      res.then((response) => {
        console.log(response)
        this.fetch();
        this.form = null;
      })
    },

    handlerDelete(dateflow){
      let res = AxiosOscar.delete(this.url + "?id=" + dateflow.id).then((response) => {
        this.fetch();
      })
    }
  },
@@ -123,9 +138,32 @@ export default {

<template>
  <h1><i class="icon-calendar" />Flux de jalon</h1>
  <div>url : <code>{{ url }}</code></div>
  <nav class="buttons-bar">
    <button @click="handlerNew" class="btn btn-default">Nouveau flux</button>
    <button @click="fetch">fetch</button>
  <button @click="handlerNew">Nouveau</button>
  </nav>
  <hr>
  <section class="activitydateflows">
    <article class="card" v-for="adf in activitydateflows">
      <h3>
        <code>[{{ adf.id }}]</code>
        <strong>
        {{ adf.label }}
        </strong>
        <sup><small>(<em>par</em> <strong>{{ adf.createdBy }}</strong>)</small></sup>
        <i class="icon-globe-1" v-show="adf.public"></i>
      </h3>
      <p>{{ adf.description }}</p>
      <section class="activitydateflow-element" v-for="adfe in adf.datetypes">
        <h4>{{ adfe.datetype.label }} <em>{{ adfe.interval }} jours</em></h4>
      </section>
      <nav class="buttons-bar">
        <button class="btn btn-danger" @click.prevent="handlerDelete(adf)">Supprimer</button>
        <button class="btn btn-default" @click.prevent="handlerEdit(adf)">Modifier</button>
        <button class="btn btn-default" @click.prevent="handlerDuplicate(adf)">Dupliquer</button>
      </nav>
    </article>
  </section>
  <hr>
  <div v-if="form" class="overlay">
    <div class="overlay-content">
@@ -133,19 +171,29 @@ export default {
        <strong v-if="form.id">Modification du flux</strong>
        <em v-else>Nouveau flux de jalon</em>
      </h1>
      <div class="row">
        <div class="col-md-6">
          <div class="div">
            <label for="label">
              Intitulé
              <input type="text" class="form-control" v-model="form.label" />
            </label>
          </div>

          <div class="div">
            <label for="">
              Description
              <textarea class="form-control textarea" v-model="form.description" />
            </label>
          </div>
          <div class="div">
            <label for="">
              Publique {{ form }}
              <input type="checkbox" class="form-control" v-model="form.public" />
            </label>
          </div>
        </div>
      </div>


      <select name="" id="" @change="handlerSelectDateStype">
        <option value=""></option>