up routes and schema

This commit is contained in:
Tykayn 2025-02-14 11:00:20 +01:00 committed by tykayn
parent e23013825b
commit 1c700917b3
23 changed files with 1959 additions and 89 deletions

4
.env
View File

@ -40,3 +40,7 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
###> symfony/mailer ###
MAILER_DSN=null://null
###< symfony/mailer ###
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>

View File

@ -1,6 +1,17 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>
<list size="2">
<item index="0" class="java.lang.String" itemvalue="ng-click" />
<item index="1" class="java.lang.String" itemvalue="ng-if" />
</list>
</value>
</option>
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>

View File

@ -22,7 +22,7 @@ A Symfony project created on March 23, 2018.
---
## [Install](docs/installation.md)
Have a look at the [Docs to install](/docs/installation.md) your own Caisse. All documentation is in the "docs" folder.
Have a look at the [Docs to install](docs/installation.md) your own Caisse. All documentation is in the "docs" folder.
Made By Tykayn/CipherBliss under [AGPL Licence](LICENSE).
## News
Ipublish news about this app here:
@ -35,9 +35,7 @@ https://www.cipherbliss.com/feed/
## Where to find help
Join the discussion at the Matrix Channel of CipherBliss:
[#cipherbliss:matrix.org](https://matrix.to/#/!jfoYESqTObXYlKAOVM:matrix.org?via=matrix.org)
Or contact the Author:
Contact the author:
[Contact Choices here](https://www.cipherbliss.com/contact)

View File

@ -0,0 +1,8 @@
form {
button.btn {
padding: 2em;
border-radius: 0.5rem;
background: green !important;
color: white !important;
}
}

View File

@ -7,10 +7,13 @@
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/doctrine-orm": "^4.0",
"api-platform/symfony": "^4.0",
"doctrine/dbal": "^3",
"doctrine/doctrine-bundle": "^2.13",
"doctrine/doctrine-migrations-bundle": "^3.4",
"doctrine/orm": "^3.3",
"nelmio/cors-bundle": "^2.5",
"phpdocumentor/reflection-docblock": "^5.6",
"phpstan/phpdoc-parser": "^2.0",
"symfony/asset": "7.2.*",

1469
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -16,4 +16,6 @@ return [
SymfonyCasts\Bundle\VerifyEmail\SymfonyCastsVerifyEmailBundle::class => ['all' => true],
SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle::class => ['all' => true],
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
];

View File

@ -0,0 +1,7 @@
api_platform:
title: Hello API Platform
version: 1.0.0
defaults:
stateless: true
cache_headers:
vary: ['Content-Type', 'Authorization', 'Origin']

View File

@ -0,0 +1,10 @@
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
expose_headers: ['Link']
max_age: 3600
paths:
'^/': null

View File

@ -0,0 +1,4 @@
api_platform:
resource: .
type: api_platform
prefix: /api

View File

@ -0,0 +1,37 @@
<?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 Version20250214095832 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('CREATE TABLE festvial (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, date_creation DATE DEFAULT NULL, chiffre_affaire DOUBLE PRECISION DEFAULT NULL, clients_count INT DEFAULT NULL, commentaire VARCHAR(500) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE group_of_products_selling (group_of_products_id INT NOT NULL, selling_id INT NOT NULL, INDEX IDX_22D44E55748B7BD1 (group_of_products_id), INDEX IDX_22D44E55155A4545 (selling_id), PRIMARY KEY(group_of_products_id, selling_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE group_of_products_selling ADD CONSTRAINT FK_22D44E55748B7BD1 FOREIGN KEY (group_of_products_id) REFERENCES group_of_products (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE group_of_products_selling ADD CONSTRAINT FK_22D44E55155A4545 FOREIGN KEY (selling_id) REFERENCES selling (id) ON DELETE CASCADE');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE group_of_products_selling DROP FOREIGN KEY FK_22D44E55748B7BD1');
$this->addSql('ALTER TABLE group_of_products_selling DROP FOREIGN KEY FK_22D44E55155A4545');
$this->addSql('DROP TABLE festvial');
$this->addSql('DROP TABLE group_of_products_selling');
}
}

0
src/ApiResource/.gitignore vendored Normal file
View File

View File

@ -25,8 +25,83 @@ final class DefaultController extends AbstractController
#[Route('/dashboard', name: 'dashboard')]
public function dashboard(): Response
{
return $this->render('default/main-screen.html.twig', [
return $this->render('logged/dashboard.html.twig', [
'controller_name' => 'DefaultController',
]);
}
#[Route('/export_all', name: 'export_all')]
public function export_all(): Response
{
return $this->render('logged/export_all.html.twig', [
'controller_name' => 'DefaultController',
]);
}
// export_all_json
#[Route('/export_all_json', name: 'export_all_json')]
public function export_all_json(): Response
{
return $this->render('logged/export_all_json.html.twig', [
'controller_name' => 'DefaultController',
]);
}
#[Route('/history', name: 'history')]
public function history(): Response
{
return $this->render('logged/history.html.twig', [
'controller_name' => 'DefaultController',
'chiffreAffaires' => 10000,
'statisticsSoldProducts' => [
[
'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',
],
'allSellings' => 12,
'recentSellings' => [],
'recentSells' => [
[
'id' => '1234',
'date' => date_create('now'),
'comment' => 'blah',
'amount' => 52,
'productsSold' => [
'name' => 'un truc de démo aussi làààà'
],
],
],
'activeSelling' => [],
// 'sellingComment' => [],
'statisticsFestivals' => 'todo',
'recentSells' => ''
]);
}
#[Route('/logged/get-my-products', name: 'get_my_products')]
public function get_my_products(): Response
{
// TODO: replace this with actual logic to get products of the logged user
// récupérer les produits de l'user connecté
return $this->json([
'mock_response' => 'TODO',
]);
}
}

96
src/Entity/Festvial.php Normal file
View File

@ -0,0 +1,96 @@
<?php
namespace App\Entity;
use App\Repository\FestvialRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: FestvialRepository::class)]
class Festvial
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
#[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
private ?\DateTimeInterface $dateCreation = null;
#[ORM\Column(nullable: true)]
private ?float $chiffreAffaire = null;
#[ORM\Column(nullable: true)]
private ?int $clientsCount = null;
#[ORM\Column(length: 500, nullable: true)]
private ?string $commentaire = null;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
public function getDateCreation(): ?\DateTimeInterface
{
return $this->dateCreation;
}
public function setDateCreation(?\DateTimeInterface $dateCreation): static
{
$this->dateCreation = $dateCreation;
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;
}
public function getCommentaire(): ?string
{
return $this->commentaire;
}
public function setCommentaire(?string $commentaire): static
{
$this->commentaire = $commentaire;
return $this;
}
}

View File

@ -25,9 +25,16 @@ class GroupOfProducts
#[ORM\ManyToMany(targetEntity: Product::class, inversedBy: 'groupOfProducts')]
private Collection $products;
/**
* @var Collection<int, Selling>
*/
#[ORM\ManyToMany(targetEntity: Selling::class, inversedBy: 'groupOfProducts')]
private Collection $sellings;
public function __construct()
{
$this->products = new ArrayCollection();
$this->sellings = new ArrayCollection();
}
@ -75,4 +82,28 @@ class GroupOfProducts
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);
}
return $this;
}
public function removeSelling(Selling $selling): static
{
$this->sellings->removeElement($selling);
return $this;
}
}

View File

@ -3,6 +3,8 @@
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;
@ -26,6 +28,17 @@ class Selling
#[ORM\Column(nullable: true)]
private ?float $reduction = null;
/**
* @var Collection<int, GroupOfProducts>
*/
#[ORM\ManyToMany(targetEntity: GroupOfProducts::class, mappedBy: 'sellings')]
private Collection $groupOfProducts;
public function __construct()
{
$this->groupOfProducts = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
@ -78,4 +91,31 @@ class Selling
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->addSelling($this);
}
return $this;
}
public function removeGroupOfProduct(GroupOfProducts $groupOfProduct): static
{
if ($this->groupOfProducts->removeElement($groupOfProduct)) {
$groupOfProduct->removeSelling($this);
}
return $this;
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\Festvial;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Festvial>
*/
class FestvialRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Festvial::class);
}
// /**
// * @return Festvial[] Returns an array of Festvial objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('f')
// ->andWhere('f.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('f.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Festvial
// {
// return $this->createQueryBuilder('f')
// ->andWhere('f.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -1,4 +1,18 @@
{
"api-platform/symfony": {
"version": "4.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "4.0",
"ref": "e9952e9f393c2d048f10a78f272cd35e807d972b"
},
"files": [
"config/packages/api_platform.yaml",
"config/routes/api_platform.yaml",
"src/ApiResource/.gitignore"
]
},
"doctrine/doctrine-bundle": {
"version": "2.13",
"recipe": {
@ -26,6 +40,18 @@
"migrations/.gitignore"
]
},
"nelmio/cors-bundle": {
"version": "2.5",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.5",
"ref": "6bea22e6c564fba3a1391615cada1437d0bde39c"
},
"files": [
"config/packages/nelmio_cors.yaml"
]
},
"phpunit/phpunit": {
"version": "9.6",
"recipe": {
@ -262,6 +288,15 @@
"templates/base.html.twig"
]
},
"symfony/uid": {
"version": "7.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.0",
"ref": "0df5844274d871b37fc3816c57a768ffc60a43a5"
}
},
"symfony/ux-turbo": {
"version": "2.22",
"recipe": {

View File

@ -10,12 +10,12 @@
<!-- ligne d'informations-->
{% endverbatim %}
{# {% include 'logged/listing-options.html.twig' %}#}
{# {% include 'logged/festival-infos.html.twig' %}#}
{% include 'logged/listing-options.html.twig' %}
{% include 'logged/festival-infos.html.twig' %}
</div>
<div class="col-xs-12">
{# {% include 'logged/customer.html.twig' %}#}
{% include 'logged/customer.html.twig' %}
{% verbatim %}
</div>

View File

@ -1,5 +1,5 @@
<div id="festival-current_info">
<a class="btn " href=" {{ path('festival_index') }}">
<a class="btn " href=" {{ path('app_festival_index') }}">
<i class="fa fa-th-large"></i>
Festival:

View File

@ -1,75 +1 @@
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script>
var dataPoints = [
{% for pair in statisticsSoldProducts %}
{
label: "{{ pair.name }}",
x: {{ pair.count }},
y: {{ pair.count }}
},
{% endfor %}
];
var dataPointsChiffreAffaire = [
{% for pair in statisticsSoldProducts %}
{
label: "{{ pair.name }}",
x: {{ pair.value }},
y: {{ pair.value }}
},
{% endfor %}
];
var dataPointsFestivals = [
{% for pair in statisticsFestivals %}
{
label: "{{ pair.name }} {{ pair.date|date('Y-m-d') }} , {{ pair.chiffreAffaire }} €",
y: {{ pair.chiffreAffaire }} ,
countClients : "{{ pair.clients_count }} clients"
},
{% endfor %}
];
console.log(dataPointsFestivals);
var chartFestival = new CanvasJS.Chart("chartContainerstatisticsFestivals", {
title:{
text: "Chiffre d'affaire par festival"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "column",
dataPoints: dataPointsFestivals
}
]
});
console.log('dataPointsFestivals', dataPointsFestivals);
chartFestival.render();
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "Volume de produits vendus"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: dataPoints
}
]
});
chart.render();
var chartContainerChiffreAffaire = new CanvasJS.Chart("chartContainerChiffreAffaire", {
title:{
text: "Valeur en euros des produits vendus"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: dataPointsChiffreAffaire
}
]
});
chartContainerChiffreAffaire.render();
</script>

View File

@ -105,10 +105,7 @@
</tr>
</thead>
<tbody>
{% for vente in recentSells %}
{% for vente in recentSells %}
<tr>
<td> {{ vente.id }}</td>
@ -149,8 +146,81 @@
</div>
{% include ':logged:history-script.html.twig' %}
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script>
var dataPoints = [
{% for pair in statisticsSoldProducts %}
{
label: "{{ pair.name }}",
x: {{ pair.count }},
y: {{ pair.count }}
},
{% endfor %}
];
var dataPointsChiffreAffaire = [
{% for pair in statisticsSoldProducts %}
{
label: "{{ pair.name }}",
x: {{ pair.value }},
y: {{ pair.value }}
},
{% endfor %}
];
var dataPointsFestivals = [
{% for pair in statisticsFestivals %}
{
label: "{{ pair.name }} {{ pair.date|date('Y-m-d') }} , {{ pair.chiffreAffaire }} €",
y: {{ pair.chiffreAffaire }} ,
countClients : "{{ pair.clients_count }} clients"
},
{% endfor %}
];
console.log(dataPointsFestivals);
var chartFestival = new CanvasJS.Chart("chartContainerstatisticsFestivals", {
title:{
text: "Chiffre d'affaire par festival"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "column",
dataPoints: dataPointsFestivals
}
]
});
console.log('dataPointsFestivals', dataPointsFestivals);
chartFestival.render();
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "Volume de produits vendus"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: dataPoints
}
]
});
chart.render();
var chartContainerChiffreAffaire = new CanvasJS.Chart("chartContainerChiffreAffaire", {
title:{
text: "Valeur en euros des produits vendus"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: dataPointsChiffreAffaire
}
]
});
chartContainerChiffreAffaire.render();
</script>
</div>
{% endblock %}