Time Tracking

This commit is contained in:
2020-07-01 15:54:52 +02:00
parent 0ba2f94521
commit 8f5f136607
9 changed files with 1894 additions and 2 deletions

View File

@@ -0,0 +1,176 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Timer as Entity;
use App\Form\TimerType as Form;
class TimerController extends AbstractController
{
private $data = "timer";
private $route = "app_timer";
private $render = "Timer/";
private $entity = "App:Timer";
public function list(Request $request)
{
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
$tasks = $em->getRepository("App:Task")->findAll();
$timers = $em->getRepository("App:Timer")->findBy(["user"=>$iduser]);
return $this->render($this->render.'list.html.twig',[
"useheader" => true,
"usesidebar" => true,
"user" => $user,
"tasks" => $tasks,
"timers" => $timers,
]);
}
public function create(Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
$taskid = $request->request->get('taskid');
$description = $request->request->get('description');
$task = $em->getRepository("App:Task")->find($taskid);
$start = \DateTime::createFromFormat('D M d Y H:i:s e+',$request->request->get('start'));
$end = \DateTime::createFromFormat('D M d Y H:i:s e+',$request->request->get('end'));
$duration = new \DateTime(date("H:i:s", ($request->request->get('duration')/1000)));
$duration->sub(new \DateInterval('PT1H'));
$timer = new Entity();
$timer->setUser($user);
$timer->setTask($task);
$timer->setStart($start);
$timer->setEnd($end);
$timer->setDuration($duration);
$timer->setDescription($description);
$em->persist($timer);
$em->flush();
$output=["return"=>"OK"];
return new Response(json_encode($output));
}
public function submit(Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data = new Entity();
// Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"submit"));
// Récupération des data du formulaire
$form->handleRequest($request);
// Sur erreur
$this->getErrorForm(null,$form,$request,$data,"submit");
// Sur validation
if ($form->get('submit')->isClicked() && $form->isValid()) {
$data = $form->getData();
$em->persist($data);
$em->flush();
// Retour à la liste
return $this->redirectToRoute($this->route);
}
// Affichage du formulaire
return $this->render($this->render.'edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
$this->data => $data,
'mode' => 'submit',
'form' => $form->createView()
]);
}
public function update($id,Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data=$em->getRepository($this->entity)->find($id);
// Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"update"));
// Récupération des data du formulaire
$form->handleRequest($request);
// Sur erreur
$this->getErrorForm(null,$form,$request,$data,"update");
// Sur validation
if ($form->get('submit')->isClicked() && $form->isValid()) {
$data = $form->getData();
$em->persist($data);
$em->flush();
// Retour à la liste
return $this->redirectToRoute($this->route);
}
return $this->render($this->render.'edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
$this->data => $data,
'mode' => 'update',
'form' => $form->createView()
]);
}
public function delete($id, Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data=$em->getRepository($this->entity)->find($id);
// Controle avant suppression
$error=false;
if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else {
try {
$em->remove($data);
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste
return $this->redirectToRoute($this->route);
}
}
protected function getErrorForm($id,$form,$request,$data,$mode) {
if ($form->get('submit')->isClicked()&&$mode=="delete") {
}
if ($form->get('submit')->isClicked() && $mode=="submit") {
}
if ($form->get('submit')->isClicked() && !$form->isValid()) {
$this->get('session')->getFlashBag()->clear();
$errors = $form->getErrors();
foreach( $errors as $error ) {
$request->getSession()->getFlashBag()->add("error", $error->getMessage());
}
}
}
}

View File

@@ -61,12 +61,17 @@ class Task
*/
private $events;
/**
* @ORM\OneToMany(targetEntity="Timer", mappedBy="task", cascade={"persist"}, orphanRemoval=false)
*/
private $timers;
/**
* @ORM\OneToMany(targetEntity="Penalty", mappedBy="task", cascade={"persist"}, orphanRemoval=false)
*/
private $penaltys;
/**
/**
* Calculate Displayname
*/
public function getDisplayname(): ?string
@@ -74,7 +79,7 @@ class Task
return $this->project->getCustomer()->getName()."-".$this->project->getName()."-".$this->name;
}
/**
/**
* Calculate Duration
*/
public function getDuration($end): ?string
@@ -90,6 +95,7 @@ class Task
public function __construct()
{
$this->events = new ArrayCollection();
$this->timers = new ArrayCollection();
$this->penaltys = new ArrayCollection();
}
@@ -191,6 +197,24 @@ class Task
return $this;
}
/**
* @return Collection|Timer[]
*/
public function getTimers(): Collection
{
return $this->tasks;
}
public function addTimer(Timer $timer): self
{
if (!$this->timers->contains($timer)) {
$this->timers[] = $timer;
$timer->setTask($this);
}
return $this;
}
public function removeEvent(Event $event): self
{
if ($this->events->contains($event)) {
@@ -235,4 +259,17 @@ class Task
return $this;
}
public function removeTimer(Timer $timer): self
{
if ($this->timers->contains($timer)) {
$this->timers->removeElement($timer);
// set the owning side to null (unless already changed)
if ($timer->getTask() === $this) {
$timer->setTask(null);
}
}
return $this;
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Timer
*
* @ORM\Table(name="timer")
* @ORM\Entity(repositoryClass="App\Repository\TimerRepository")
*/
class Timer
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="start", type="datetime")
*
*/
private $start;
/**
* @ORM\Column(name="end", type="datetime")
*
*/
private $end;
/**
* @ORM\Column(name="duration", type="datetime")
*
*/
private $duration;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $description;
/**
* @ORM\ManyToOne(targetEntity="User")
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity="Task", inversedBy="timers"))
*/
private $task;
public function __construct()
{
$this->start = new \DateTime();
$this->end = new \DateTime();
$this->duration = new \DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function getStart(): ?\DateTimeInterface
{
return $this->start;
}
public function setStart(\DateTimeInterface $start): self
{
$this->start = $start;
return $this;
}
public function getEnd(): ?\DateTimeInterface
{
return $this->end;
}
public function setEnd(\DateTimeInterface $end): self
{
$this->end = $end;
return $this;
}
public function getDuration(): ?\DateTimeInterface
{
return $this->duration;
}
public function setDuration(\DateTimeInterface $duration): self
{
$this->duration = $duration;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getTask(): ?Task
{
return $this->task;
}
public function setTask(?Task $task): self
{
$this->task = $task;
return $this;
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\ChoiceList\ChoiceList;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class TimerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Valider",
"attr" => ["class" => "btn btn-success no-print"],
]
);
$builder->add('task',
EntityType::class, [
"label" => "Tâche",
"class" => "App:Task",
"choice_label" => function ($task) {
return $task->getDisplayname();},
"disabled" => false,
"required" => true,
"multiple" => false,
"placeholder" => "Selectionner une Tâche",
]
);
$builder->add('description',
TextType::class, [
"label" => "Description"
]
);
$builder->add('start',
DateTimeType::class, [
"label" =>"Début",
"date_widget" => "single_text",
"time_widget" => "single_text",
"format" => "yyyy-MM-dd HH:mm",
]
);
$builder->add('end',
DateTimeType::class, [
"label" =>"Fin",
"date_widget" => "single_text",
"time_widget" => "single_text",
"format" => "yyyy-MM-dd HH:mm",
]
);
$builder->addEventListener(
);
$builder->add('duration',
TimeType::class, [
"label" =>"Durée",
"widget" => "single_text",
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Timer',
'mode' => 'string',
));
}
}