start add selling

This commit is contained in:
Tykayn 2025-02-17 17:51:01 +01:00 committed by tykayn
parent 0d672d5447
commit c1b2c97350
14 changed files with 1798 additions and 92 deletions

View File

@ -5,6 +5,25 @@
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/amp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/byte-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/dns" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/hpack" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/http" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/serialization" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/socket" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/sync" />
<excludeFolder url="file://$MODULE_DIR$/vendor/amphp/windows-registry" />
<excludeFolder url="file://$MODULE_DIR$/vendor/daverandom/libdns" />
<excludeFolder url="file://$MODULE_DIR$/vendor/kelunik/certificate" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/uri" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/uri-interfaces" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/uri-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -214,6 +214,25 @@
<path value="$PROJECT_DIR$/vendor/api-platform/jsonld" />
<path value="$PROJECT_DIR$/vendor/symfonycasts/verify-email-bundle" />
<path value="$PROJECT_DIR$/vendor/symfonycasts/reset-password-bundle" />
<path value="$PROJECT_DIR$/vendor/amphp/sync" />
<path value="$PROJECT_DIR$/vendor/amphp/socket" />
<path value="$PROJECT_DIR$/vendor/amphp/amp" />
<path value="$PROJECT_DIR$/vendor/amphp/dns" />
<path value="$PROJECT_DIR$/vendor/amphp/http-client" />
<path value="$PROJECT_DIR$/vendor/amphp/windows-registry" />
<path value="$PROJECT_DIR$/vendor/amphp/http" />
<path value="$PROJECT_DIR$/vendor/amphp/byte-stream" />
<path value="$PROJECT_DIR$/vendor/amphp/cache" />
<path value="$PROJECT_DIR$/vendor/amphp/hpack" />
<path value="$PROJECT_DIR$/vendor/amphp/process" />
<path value="$PROJECT_DIR$/vendor/amphp/parser" />
<path value="$PROJECT_DIR$/vendor/amphp/serialization" />
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
<path value="$PROJECT_DIR$/vendor/kelunik/certificate" />
<path value="$PROJECT_DIR$/vendor/league/uri" />
<path value="$PROJECT_DIR$/vendor/league/uri-interfaces" />
<path value="$PROJECT_DIR$/vendor/league/uri-parser" />
<path value="$PROJECT_DIR$/vendor/daverandom/libdns" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.4" />

View File

@ -169,6 +169,7 @@ angular
$scope.refreshDeduplicateSellings();
}
$scope.removeAll = function () {
console.log('$scope.categories', $scope.categories)
$scope.categories.forEach(category => {
if (category.products && category.products.length) {
@ -193,8 +194,8 @@ angular
$scope.clearSellingComment = function () {
console.log(' $scope.sellingComment', $scope.sellingComment);
// $scope.sellingComment = '';
// document.querySelector('.client-now input').focus();
$scope.sellingComment = '';
document.querySelector('.client-now input').focus();
document.querySelector('.client-now input').select();
};
$scope.clearCurrentSelling = function () {

View File

@ -7,6 +7,7 @@
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"amphp/http-client": "^4.2.1",
"api-platform/doctrine-orm": "^4.0",
"api-platform/symfony": "^4.0",
"doctrine/dbal": "^3",

1390
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,7 @@ security:
- { path: ^/dashboard, roles: ROLE_USER }
- { path: ^/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI
- { path: ^/authentication_token, roles: PUBLIC_ACCESS }
- { path: ^/, roles: PUBLIC_ACCESS }
# - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Autoriser l'accès à la page de connexion
# - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Autoriser l'accès anonyme à toutes les autres pages

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250217160209 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE festival ADD chiffre_affaire DOUBLE PRECISION DEFAULT NULL, ADD clients_count INT DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE festival DROP chiffre_affaire, DROP clients_count');
}
}

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250217165029 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE group_of_products DROP FOREIGN KEY FK_2A99B370A76ED395');
$this->addSql('DROP INDEX IDX_2A99B370A76ED395 ON group_of_products');
$this->addSql('ALTER TABLE group_of_products CHANGE user_id owner_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE group_of_products ADD CONSTRAINT FK_2A99B3707E3C61F9 FOREIGN KEY (owner_id) REFERENCES user (id)');
$this->addSql('CREATE INDEX IDX_2A99B3707E3C61F9 ON group_of_products (owner_id)');
$this->addSql('ALTER TABLE selling DROP date');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE selling ADD date VARCHAR(255) NOT NULL');
$this->addSql('ALTER TABLE group_of_products DROP FOREIGN KEY FK_2A99B3707E3C61F9');
$this->addSql('DROP INDEX IDX_2A99B3707E3C61F9 ON group_of_products');
$this->addSql('ALTER TABLE group_of_products CHANGE owner_id user_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE group_of_products ADD CONSTRAINT FK_2A99B370A76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
$this->addSql('CREATE INDEX IDX_2A99B370A76ED395 ON group_of_products (user_id)');
}
}

View File

@ -2,10 +2,14 @@
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use App\Entity\Festival;
use App\Entity\Selling;
use App\Entity\GroupOfProducts;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
final class DefaultController extends AbstractController
{
@ -16,6 +20,7 @@ final class DefaultController extends AbstractController
'controller_name' => 'DefaultController',
]);
}
#[Route('/accueil', name: 'app_home')]
public function accueil(): Response
{
@ -23,6 +28,7 @@ final class DefaultController extends AbstractController
'controller_name' => 'DefaultController',
]);
}
#[Route('/dashboard', name: 'dashboard')]
public function dashboard(): Response
{
@ -30,7 +36,7 @@ final class DefaultController extends AbstractController
'controller_name' => 'DefaultController',
]);
}
#[Route('/export_all', name: 'export_all')]
public function export_all(): Response
@ -65,34 +71,34 @@ final class DefaultController extends AbstractController
'controller_name' => 'DefaultController',
'chiffreAffaires' => 10000,
'statisticsSoldProducts' => [
[
'name' => 'mock 1',
'count' => 10,
'value' => 10,
],[
'name' => 'mock 2',
'count' => 1,
'value' => 20,
],
[
'name' => 'mock 1',
'count' => 10,
'value' => 10,
], [
'name' => 'mock 2',
'count' => 1,
'value' => 20,
],
],
'activeFestival' => [
'fondDeCaisseAvant' => 10,
'chiffreAffaire' => 10,
'clientsCount' => 10,
'name' => 'demo festival mock dans default controller',
'fondDeCaisseAvant' => 10,
'chiffreAffaire' => 10,
'clientsCount' => 10,
'name' => 'demo festival mock dans default controller',
],
'allSellings' => 12,
'recentSellings' => [],
'recentSells' => [
[
'id' => '1234',
'date' => date_create('now'),
'comment' => 'blah',
'amount' => 52,
'productsSold' => [
'name' => 'un truc de démo aussi làààà'
],
],
[
'id' => '1234',
'date' => date_create('now'),
'comment' => 'blah',
'amount' => 52,
'productsSold' => [
'name' => 'un truc de démo aussi làààà'
],
],
],
'activeSelling' => [],
// 'sellingComment' => [],
@ -105,39 +111,113 @@ final class DefaultController extends AbstractController
#[Route('/logged/get-my-products', name: 'get_my_products')]
public function get_my_products(): JsonResponse
{
// TODO: replace this with actual logic to get products of the logged user
// récupérer les produits de l'user connecté
// TODO: replace this with actual logic to get products of the logged user
// récupérer les produits de l'user connecté
$user = $this->getUser();
$user = $this->getUser();
// $products = $this->getUser()->getProducts();
return $this->json([
'categories' => $user->getGroupOfProducts(),
'products' => $user->getProducts(),
// mock land
'lastFestival' => ['id'=>1,
'name'=>'le festival de mock',
'dateCreation'=>'2025-02-16',
'commentaire'=>'MOCK: hop le commentaire de festival',
'chiffreAffaire'=>'1234',
'fondDeCaisseAvant'=>'100',
'fondDeCaisseAprès'=>'150',
'sold'=>123
'lastFestival' => ['id' => 1,
'name' => 'le festival de mock',
'dateCreation' => '2025-02-16',
'commentaire' => 'MOCK: hop le commentaire de festival',
'chiffreAffaire' => '1234',
'fondDeCaisseAvant' => '100',
'fondDeCaisseAprès' => '150',
'sold' => 123
],
'history' => [],
]);
}
#[Route('/logged/import', name: 'import')]
public function import(): Response
{
// prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST
// prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST
return $this->render('logged/import.html.twig', []);
}
#[Route('/logged/mass_create', name: 'mass_create')]
public function mass_create(): Response
{
// prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST
// prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST
return $this->render('logged/import.html.twig', []);
}
#[Route('/logged/add-selling', name: 'add_selling')]
public function add_selling(): JsonResponse
{
// créer un nouveau Selling et retourner une réponse
//
// $loggedUser = $this->getUser();
// // Prendre les informations en POST et créer une vente avec.
// $request = Request::createFromGlobals();
// $data = json_decode($request->getContent(), true);
//
// $dataOfNewSelling = $data['activeSelling'];
//
// $newSelling = new Selling();
//
// // si l'utilisateur courant n'a pas de festival actuel, en créer un
//
// $currentFestival = $loggedUser->getCurrentFestival();
// if (!$currentFestival) {
//
// $currentFestival = new Festival();
// $currentFestival
// ->setName('festival auto créé')
// ->setClientsCount(1);
// } else {
// $currentFestival->setClientsCount($currentFestival->getClientsCount() + 1);
// }
// $currentFestival->addSelling($newSelling);
//
// // prendre les identifiants des produits en base et les ajouter aux produits de ce Selling
//// $dataOfNewSelling['activeSelling']['id'];
//
//
// // Récupérer l'EntityManager
// $entityManager = $this->getDoctrine()->getManager();
//
// // Récupérer les produits à partir des identifiants
// foreach ($dataOfNewSelling['products']['id'] as $productId) {
//
// $product = $entityManager->getRepository(Product::class)->find($productId);
//
// if ($product) {
// $newSelling->addProduct($product);
// $product->addSelling($newSelling);
// $entityManager->persist($product);
// }
// }
//
//
// $newSelling
// ->setPaidByCustomer($dataOfNewSelling['paidByClient'])
// ->setCustomerInfo($dataOfNewSelling['comment'])
// ->setDate(new \DateTime($data['date']))
// ->setOwner($loggedUser);
//
// $entityManager = $this->getDoctrine()->getManager();
// $entityManager->persist($newSelling);
//
// $entityManager->flush();
// $newSelling = new Selling();
// $newSelling->setOwner($loggedUser);
$response = [
// 'message' => 'yes',
// 'newChiffreAffaire' => $currentFestival->getChiffreAffaire(),
// 'clientsCount' => $currentFestival->getClientsCount(),
// 'activeFestival' => $currentFestival,
];
// prendre en compte l'ajout de nouveaux produits si on a une valeur dans le POST
return $this->json($response);
}
}

View File

@ -7,6 +7,7 @@ use App\Form\Selling1Type;
use App\Repository\SellingRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@ -78,4 +79,6 @@ final class SellingController extends AbstractController
return $this->redirectToRoute('app_selling_index', [], Response::HTTP_SEE_OTHER);
}
}

View File

@ -55,6 +55,12 @@ class Festival
#[ORM\ManyToOne(inversedBy: 'festivals')]
private ?SerieFestival $serieFestival = null;
#[ORM\Column(nullable: true)]
private ?float $chiffreAffaire = null;
#[ORM\Column(nullable: true)]
private ?int $clientsCount = null;
public function __construct()
{
$this->users = new ArrayCollection();
@ -233,4 +239,28 @@ class Festival
return $this;
}
public function getChiffreAffaire(): ?float
{
return $this->chiffreAffaire;
}
public function setChiffreAffaire(?float $chiffreAffaire): static
{
$this->chiffreAffaire = $chiffreAffaire;
return $this;
}
public function getClientsCount(): ?int
{
return $this->clientsCount;
}
public function setClientsCount(?int $clientsCount): static
{
$this->clientsCount = $clientsCount;
return $this;
}
}

View File

@ -2,12 +2,14 @@
namespace App\Entity;
use App\Repository\GroupOfProductsRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\ApiResource;
use \App\Entity\GroupOfProducts;
use \App\Entity\Product;
use \App\Entity\Selling;
#[ApiResource(paginationEnabled: false)]
#[ORM\Entity(repositoryClass: GroupOfProductsRepository::class)]
@ -24,7 +26,6 @@ class GroupOfProducts
/**
* @var Collection<int, Product>
*/
// TODO apiresource return properties
#[ORM\ManyToMany(targetEntity: Product::class, inversedBy: 'groupOfProducts')]
private Collection $products;
@ -35,7 +36,8 @@ class GroupOfProducts
private ?Collection $sellings = null;
#[ORM\ManyToOne(inversedBy: 'groupOfProducts')]
private ?User $user = null;
private ?User $owner = null;
public function __construct()
{
@ -72,10 +74,11 @@ class GroupOfProducts
}
return $productsDTO;
}
public function getProducts(): ?object
{
return $this->products;
}
public function getProducts(): ?object
{
return $this->products;
}
public function setProducts(object $products): static
{
@ -124,14 +127,14 @@ class GroupOfProducts
return $this;
}
public function getUser(): ?User
public function getOwner(): ?User
{
return $this->user;
return $this->owner;
}
public function setUser(?User $user): static
public function setOwner(?User $owner): static
{
$this->user = $user;
$this->owner = $owner;
return $this;
}

View File

@ -2,12 +2,10 @@
namespace App\Entity;
use App\Repository\SellingRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\ApiResource;
#[ApiResource(paginationEnabled: false)]
#[ORM\Entity(repositoryClass: SellingRepository::class)]
@ -42,6 +40,16 @@ class Selling
#[ORM\ManyToOne(inversedBy: 'sellings')]
private ?Festival $festival = null;
#[ORM\Column(length: 255)]
private ?string $customer_info = null;
#[ORM\Column]
private ?float $paidByCustomer = null;
#[ORM\ManyToOne(inversedBy: 'sellings')]
private ?User $owner = null;
public function __construct()
{
$this->groupOfProducts = new ArrayCollection();
@ -155,4 +163,42 @@ class Selling
return $this;
}
public function getCustomerInfo(): ?string
{
return $this->customer_info;
}
public function setCustomerInfo(string $customer_info): static
{
$this->customer_info = $customer_info;
return $this;
}
public function getPaidByCustomer(): ?float
{
return $this->paidByCustomer;
}
public function setPaidByCustomer(float $paidByCustomer): static
{
$this->paidByCustomer = $paidByCustomer;
return $this;
}
public function getOwner(): ?User
{
return $this->owner;
}
public function setOwner(?User $owner): static
{
$this->owner = $owner;
return $this;
}
}

View File

@ -11,6 +11,9 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use ApiPlatform\Metadata\ApiResource;
use \App\Entity\GroupOfProducts;
use \App\Entity\Product;
use \App\Entity\Selling;
#[ApiResource(paginationEnabled: false)]
#[ORM\Entity(repositoryClass: UserRepository::class)]
@ -65,11 +68,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\OneToMany(targetEntity: Product::class, mappedBy: 'user')]
private Collection $products;
/**
* @var Collection<int, GroupOfProducts>
*/
#[ORM\OneToMany(targetEntity: GroupOfProducts::class, mappedBy: 'user')]
private Collection $groupOfProducts;
/**
* @var Collection<int, Festival>
@ -86,14 +84,27 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\OneToOne(cascade: ['persist', 'remove'])]
private ?Festival $activeFestival = null;
/**
* @var Collection<int, GroupOfProducts>
*/
#[ORM\OneToMany(targetEntity: GroupOfProducts::class, mappedBy: 'owner')]
private Collection $groupOfProducts;
/**
* @var Collection<int, Selling>
*/
#[ORM\OneToMany(targetEntity: Selling::class, mappedBy: 'owner')]
private Collection $sellings;
public function __construct()
{
$this->expenses = new ArrayCollection();
$this->products = new ArrayCollection();
$this->groupOfProducts = new ArrayCollection();
$this->festivals = new ArrayCollection();
$this->seriesFestival = new ArrayCollection();
$this->groupOfProducts = new ArrayCollection();
$this->sellings = new ArrayCollection();
}
public function getId(): ?int
@ -259,36 +270,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
/**
* @return Collection<int, GroupOfProducts>
*/
public function getGroupOfProducts(): Collection
{
return $this->groupOfProducts;
}
public function addGroupOfProduct(GroupOfProducts $groupOfProduct): static
{
if (!$this->groupOfProducts->contains($groupOfProduct)) {
$this->groupOfProducts->add($groupOfProduct);
$groupOfProduct->setUser($this);
}
return $this;
}
public function removeGroupOfProduct(GroupOfProducts $groupOfProduct): static
{
if ($this->groupOfProducts->removeElement($groupOfProduct)) {
// set the owning side to null (unless already changed)
if ($groupOfProduct->getUser() === $this) {
$groupOfProduct->setUser(null);
}
}
return $this;
}
/**
* @return Collection<int, Festival>
*/
@ -387,4 +368,66 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
/**
* @return Collection<int, GroupOfProducts>
*/
public function getGroupOfProducts(): Collection
{
return $this->groupOfProducts;
}
public function addGroupOfProduct(GroupOfProducts $groupOfProduct): static
{
if (!$this->groupOfProducts->contains($groupOfProduct)) {
$this->groupOfProducts->add($groupOfProduct);
$groupOfProduct->setOwner($this);
}
return $this;
}
public function removeGroupOfProduct(GroupOfProducts $groupOfProduct): static
{
if ($this->groupOfProducts->removeElement($groupOfProduct)) {
// set the owning side to null (unless already changed)
if ($groupOfProduct->getOwner() === $this) {
$groupOfProduct->setOwner(null);
}
}
return $this;
}
/**
* @return Collection<int, Selling>
*/
public function getSellings(): Collection
{
return $this->sellings;
}
public function addSelling(Selling $selling): static
{
if (!$this->sellings->contains($selling)) {
$this->sellings->add($selling);
$selling->setOwner($this);
}
return $this;
}
public function removeSelling(Selling $selling): static
{
if ($this->sellings->removeElement($selling)) {
// set the owning side to null (unless already changed)
if ($selling->getOwner() === $this) {
$selling->setOwner(null);
}
}
return $this;
}
}