mass import ok, liens entre série et festival CRUD ok

This commit is contained in:
Tykayn 2025-02-26 17:14:37 +01:00 committed by tykayn
parent e973573fd7
commit b79fc2ac9f
8 changed files with 152 additions and 79 deletions

View File

@ -21,7 +21,7 @@ catégorie: dessin à la demande
// use example in mass import // use example in mass import
$('#use_example').on('click', function () { $('#use_example').on('click', function () {
$('#produits').val(massimportExample); $('#produits').val(massimportExample);
// $('#filling_zone input').click(); $('#filling_zone input').click();
}); });
// intro js // intro js
$('#introjs_start').on('click', function () { $('#introjs_start').on('click', function () {

View File

@ -85,31 +85,15 @@ final class DefaultController extends AbstractController
'value' => 20, 'value' => 20,
], ],
], ],
'activeFestival' => [ 'activeFestival' => $user->getActiveFestival(),
'fondDeCaisseAvant' => 10,
'chiffreAffaire' => 10,
'clientsCount' => 10,
'name' => 'demo festival mock dans default controller',
],
'allSellings' => 12, 'allSellings' => 12,
'recentSellings' => [], 'recentSellings' => [],
'recentSells' => 'recentSells' =>
$user->getSellings(), $user->getSellings(),
// [
// [
// 'id' => '1234',
// 'date' => date_create('now'),
// 'comment' => 'blah',
// 'amount' => 52,
// 'productsSold' => [
// 'name' => 'un truc de démo aussi làààà'
// ],
// ],
// ],
'activeSelling' => [], 'activeSelling' => [],
// 'sellingComment' => [], 'sellingComment' => [],
'statisticsFestivals' => 'todo', 'statisticsFestivals' => 'todo',
'recentSells' => '' 'recentSells' => $user->getSellings(),
]); ]);
} }
@ -144,6 +128,7 @@ final class DefaultController extends AbstractController
{ {
// TODO prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST // TODO prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST
// $request = Request::createFromGlobals(); // $request = Request::createFromGlobals();
$data = json_decode($request->getContent(), true); $data = json_decode($request->getContent(), true);
$loggedUser = $this->getUser(); $loggedUser = $this->getUser();
@ -156,64 +141,111 @@ final class DefaultController extends AbstractController
// super bannière A2;10€ // super bannière A2;10€
// Sébastien Chabal sexy;10€ // Sébastien Chabal sexy;10€
$detected = "";
// Vérifiez si une requête POST a été faite // Vérifiez si une requête POST a été faite
if ($request->isMethod('POST')) { if ($request->isMethod('POST')) {
$data = $request->getContent(); $data = $request->getContent();
return new Response(var_dump($data)); var_dump($data);
// Remplacer temporairement les retours à la ligne par un marqueur
$data = str_replace(["\r\n", "\r", "\n"], "RETOUR_A_LA_LIGNE", $data);
// Décoder les caractères URL
$data = urldecode($data);
// Restaurer les vrais retours à la ligne
$data = str_replace("RETOUR_A_LA_LIGNE", "\n", $data);
// Décode les caractères URL encodés
$data = urldecode($data);
var_dump($data);
// die();
// Extrait la partie après "produits="
if (strpos($data, 'produits=') === 0) {
$data = substr($data, 9);
}
// Normalise les retours à la ligne
$data = str_replace(["\r\n", "\r"], "\n", $data);
var_dump($data);
// $detected += "data: ".$data."\n -------------- \n";
$lines = explode("\n", $data);
$lines = explode("\n", $data); // Séparez les lignes
$currentCategory = null; $currentCategory = null;
$categoriesCount = 0;
$productsCount = 0;
foreach ($lines as $line) { foreach ($lines as $line) {
$line = trim($line); $line = trim($line);
if (empty($line)) { if (empty($line)) {
continue; // Ignorez les lignes vides
}
// Vérifiez si la ligne commence par un nom de catégorie
if (preg_match('/^(.*):$/', $line, $matches)) {
$currentCategory = new GroupOfProducts();
$currentCategory->setName(trim($matches[1]));
$currentCategory->setOwner($loggedUser);
$entityManager->persist($currentCategory);
continue; continue;
} }
// Vérifiez si la ligne contient un produit // Modifié pour matcher "catégorie: dessin à la demande"
if ($currentCategory && preg_match('/^(.*); ([0-9]+(?:\.[0-9]+)?)$/', $line, $matches)) { if (preg_match('/^catégorie:(.*)$/', $line, $matches)) {
$detected .= "\n category ".trim($matches[1]);
$currentCategory = new GroupOfProducts();
$currentCategory->setName(trim($matches[1]));
$currentCategory->setUser($loggedUser);
$loggedUser->addGroupOfProduct($currentCategory);
$entityManager->persist($currentCategory);
$categoriesCount++;
continue;
}
// Modifié pour matcher "nom_produit;XXX€"
if ($currentCategory && preg_match('/(.*?);.*(\d+)€\s*$/', $line, $matches)) {
$productName = trim($matches[1]); $productName = trim($matches[1]);
$productPrice = (float)trim($matches[2]); $productPrice = (float)trim($matches[2]);
// Créez un nouvel objet Product
$product = new Product(); $product = new Product();
$product->setUser($loggedUser); $product->setUser($loggedUser);
$loggedUser->addProduct($product);
$product->setName($productName); $product->setName($productName);
$detected .= "\n product ".$productName;
$product->setPrice($productPrice); $product->setPrice($productPrice);
$product->setStock(1);
$product->setImage('default.jpg');
// Ajoutez le produit à la catégorie
$currentCategory->addProduct($product); $currentCategory->addProduct($product);
$entityManager->persist($product); $entityManager->persist($product);
$productsCount++;
} }
} }
// Enregistrez tous les changements dans la base de données $entityManager->persist($loggedUser);
$entityManager->flush(); $entityManager->flush();
$this->addFlash(
'success',
sprintf(
'Import réussi ! %d catégorie(s) et %d produit(s) ont été créés.',
$categoriesCount,
$productsCount
)
);
// return $this->redirectToRoute('app_product_index'); if ($categoriesCount === 0 && $productsCount === 0) {
return new Response('Produits importés avec succès.', Response::HTTP_CREATED); $this->addFlash(
'warning',
'Aucune donnée n\'a été importée. Vérifiez le format de vos données.'
);
} }
$this->addFlash(
'success',
'détecté: '.$detected
);
return $this->redirectToRoute('app_product_index');
}
return new Response('Méthode non autorisée', Response::HTTP_METHOD_NOT_ALLOWED);
} }
@ -279,7 +311,7 @@ final class DefaultController extends AbstractController
->setPaidByCustomer($dataOfNewSelling['paidByClient']) ->setPaidByCustomer($dataOfNewSelling['paidByClient'])
->setCustomerInfo($dataOfNewSelling['sellingComment']) ->setCustomerInfo($dataOfNewSelling['sellingComment'])
->setDate(new \DateTime()) ->setDate(new \DateTime())
->setOwner($loggedUser); ->setUser($loggedUser);
$currentFestival->updateChiffreAffaire(); $currentFestival->updateChiffreAffaire();
@ -287,7 +319,7 @@ final class DefaultController extends AbstractController
$entityManager->persist($newSelling); $entityManager->persist($newSelling);
$entityManager->persist($currentFestival); $entityManager->persist($currentFestival);
$newSelling->setOwner($loggedUser); $newSelling->setUser($loggedUser);
$entityManager->persist($loggedUser); $entityManager->persist($loggedUser);
$entityManager->flush(); $entityManager->flush();

View File

@ -68,6 +68,7 @@ final class FestivalController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'Le festival a été modifié avec succès.');
return $this->redirectToRoute('app_festival_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_festival_index', [], Response::HTTP_SEE_OTHER);
} }

View File

@ -25,14 +25,20 @@ final class SerieFestivalController extends AbstractController
#[Route('/new', name: 'app_serie_festival_new', methods: ['GET', 'POST'])] #[Route('/new', name: 'app_serie_festival_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response public function new(Request $request, EntityManagerInterface $entityManager): Response
{ {
$userFound = $this->getUser();
$serieFestival = new SerieFestival(); $serieFestival = new SerieFestival();
$serieFestival->setUser($userFound);
$serieFestival->setDateCreation(new \DateTime());
$userFound->addSeriesFestival($serieFestival);
$form = $this->createForm(SerieFestivalType::class, $serieFestival); $form = $this->createForm(SerieFestivalType::class, $serieFestival);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($serieFestival); $entityManager->persist($serieFestival);
$entityManager->persist($userFound);
$entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'La série de festivals "'.$serieFestival->getName().'" a été créée avec succès.');
return $this->redirectToRoute('app_serie_festival_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_serie_festival_index', [], Response::HTTP_SEE_OTHER);
} }
@ -45,6 +51,10 @@ final class SerieFestivalController extends AbstractController
#[Route('/{id}', name: 'app_serie_festival_show', methods: ['GET'])] #[Route('/{id}', name: 'app_serie_festival_show', methods: ['GET'])]
public function show(SerieFestival $serieFestival): Response public function show(SerieFestival $serieFestival): Response
{ {
$userFound = $this->getUser();
if (!$userFound || $serieFestival->getUser() !== $userFound) {
throw $this->createAccessDeniedException('Vous n\'êtes pas autorisé à consulter cette série de festivals.');
}
return $this->render('serie_festival/show.html.twig', [ return $this->render('serie_festival/show.html.twig', [
'serie_festival' => $serieFestival, 'serie_festival' => $serieFestival,
@ -54,12 +64,17 @@ final class SerieFestivalController extends AbstractController
#[Route('/{id}/edit', name: 'app_serie_festival_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_serie_festival_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, SerieFestival $serieFestival, EntityManagerInterface $entityManager): Response public function edit(Request $request, SerieFestival $serieFestival, EntityManagerInterface $entityManager): Response
{ {
$userFound = $this->getUser();
// if (!$userFound || $serieFestival->getUser() !== $userFound) {
// throw $this->createAccessDeniedException('Vous n\'êtes pas autorisé à modifier cette série de festivals.');
// }
$form = $this->createForm(SerieFestivalType::class, $serieFestival); $form = $this->createForm(SerieFestivalType::class, $serieFestival);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'La série de festivals a été modifiée avec succès.');
return $this->redirectToRoute('app_serie_festival_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_serie_festival_index', [], Response::HTTP_SEE_OTHER);
} }
@ -72,9 +87,15 @@ final class SerieFestivalController extends AbstractController
#[Route('/{id}', name: 'app_serie_festival_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_serie_festival_delete', methods: ['POST'])]
public function delete(Request $request, SerieFestival $serieFestival, EntityManagerInterface $entityManager): Response public function delete(Request $request, SerieFestival $serieFestival, EntityManagerInterface $entityManager): Response
{ {
$userFound = $this->getUser();
if (!$userFound || $serieFestival->getUser() !== $userFound) {
throw $this->createAccessDeniedException('Vous n\'êtes pas autorisé à supprimer cette série de festivals.');
}
if ($this->isCsrfTokenValid('delete'.$serieFestival->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$serieFestival->getId(), $request->getPayload()->getString('_token'))) {
$entityManager->remove($serieFestival); $entityManager->remove($serieFestival);
$entityManager->flush(); $entityManager->flush();
$this->addFlash('success', 'La série de festivals a été supprimée avec succès.');
} }
return $this->redirectToRoute('app_serie_festival_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_serie_festival_index', [], Response::HTTP_SEE_OTHER);

View File

@ -4,6 +4,7 @@ namespace App\Form;
use App\Entity\SerieFestival; use App\Entity\SerieFestival;
use App\Entity\User; use App\Entity\User;
use App\Entity\Festival;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
@ -18,10 +19,18 @@ class SerieFestivalType extends AbstractType
->add('dateCreation', null, [ ->add('dateCreation', null, [
'widget' => 'single_text', 'widget' => 'single_text',
]) ])
->add('user', EntityType::class, [ ->add('festivals', EntityType::class, [
'class' => User::class, 'class' => Festival::class,
'choice_label' => 'id', 'choice_label' => function($festival) {
return $festival->getName() . ' : ' . $festival->getDateStart()->format('Y-m-d') . ' - ' . $festival->getDateEnd()->format('Y-m-d');
},
'multiple' => true,
'expanded' => true
]) ])
// ->add('user', EntityType::class, [
// 'class' => User::class,
// 'choice_label' => 'id',
// ])
; ;
} }

View File

@ -110,26 +110,29 @@
<tr> <tr>
<td> {{ vente.id }}</td> <td> {{ vente.id }}</td>
<td> {{ vente.date |date('Y-m-d H:i:s') }}</td> <td> {{ vente.date |date('Y-m-d H:i:s') }}</td>
<td>{{ vente.comment }}</td> <td>
{# {{ vente.comment }} #}
</td>
<td class="text-right"> <td class="text-right">
{% if vente.productsSold |length >1 %} {% if vente.products |length >1 %}
<strong> <strong>
{{ vente.productsSold |length }} {{ vente.products |length }}
</strong> produits </strong> produits
{% else %} {% else %}
{% if vente.productsSold and vente.productsSold.0 is defined %} {% if vente.products and vente.products.0 is defined %}
{{ vente.productsSold.0.name }} {{ vente.products.0.name }}
{% endif %} {% endif %}
{% endif %} {% endif %}
</td> </td>
<td class="text-right"> <td class="text-right">
{{ vente.amount }} {{ vente.sum }}
</td> </td>
<td> <td>
<a href="{{ path('sellrecord_delete',{id: vente.id }) }}" <a href="{{ path('app_selling_delete',{id: vente.id }) }}"
class="btn btn-warning pull-right"> class="btn btn-warning pull-right">
<i class="fa fa-trash"></i> <i class="fa fa-trash"></i>
</a> </a>

View File

@ -1,5 +1,5 @@
<div id="mass-register"> <div id="mass-register">
<form action="{{ path('mass_create') }}" method="post"> <form action="{{ path('mass_create') }}" method="POST">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-6"> <div class="col-xs-12 col-sm-6">
@ -35,9 +35,14 @@ catégorie: dessin à la demande
nom de catégorie existe déjà, le produit sera associé avec celle-ci. nom de catégorie existe déjà, le produit sera associé avec celle-ci.
</label> </label>
<textarea style="width: 100%;" name="produits" id="produits" cols="30" rows="10" <textarea style="width: 100%;" name="produits" id="produits" cols="30" rows="10"
value="catégorie: livre
les moutaines;5€
la laine des moutons;6€
star wars spécial noël;7€
catégorie: poster
super bannière A2;10€"
placeholder="catégorie et produits"> placeholder="catégorie et produits">
catégorie: livre
mon livre ; 5€
</textarea> </textarea>
<input class="btn btn-primary btn-block" type="submit" value="créer en masse"> <input class="btn btn-primary btn-block" type="submit" value="créer en masse">
</div> </div>

View File

@ -11,6 +11,7 @@
<th>Id</th> <th>Id</th>
<th>Name</th> <th>Name</th>
<th>DateCreation</th> <th>DateCreation</th>
<th>Nombre de festivals</th>
<th>actions</th> <th>actions</th>
</tr> </tr>
</thead> </thead>
@ -20,6 +21,7 @@
<td>{{ serie_festival.id }}</td> <td>{{ serie_festival.id }}</td>
<td>{{ serie_festival.name }}</td> <td>{{ serie_festival.name }}</td>
<td>{{ serie_festival.dateCreation ? serie_festival.dateCreation|date('Y-m-d') : '' }}</td> <td>{{ serie_festival.dateCreation ? serie_festival.dateCreation|date('Y-m-d') : '' }}</td>
<td>{{ serie_festival.festivals|length }}</td>
<td> <td>
<a href="{{ path('app_serie_festival_show', {'id': serie_festival.id}) }}">show</a> <a href="{{ path('app_serie_festival_show', {'id': serie_festival.id}) }}">show</a>
<a href="{{ path('app_serie_festival_edit', {'id': serie_festival.id}) }}">edit</a> <a href="{{ path('app_serie_festival_edit', {'id': serie_festival.id}) }}">edit</a>
@ -27,7 +29,7 @@
</tr> </tr>
{% else %} {% else %}
<tr> <tr>
<td colspan="4">no records found</td> <td colspan="5">Aucun enregistrement trouvé</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>