feat(customer): Ajoute l'entité CustomerWallet et la vue porte-monnaie.
♻️ refactor(template): Renomme external.twig en wallet.twig.
 feat(website): Ajoute une option pour afficher les options du site.
🐛 fix(serverCard): Affiche correctement le statut en temps réel via MQTT.
🌐 i18n: Corrige une faute de frappe dans la traduction de "Newsletter".
```
This commit is contained in:
Serreau Jovann
2025-11-06 15:31:08 +01:00
parent a34589721f
commit 5c0500dc19
13 changed files with 380 additions and 23 deletions

View File

@@ -21,6 +21,7 @@ export class ServerCard extends HTMLDivElement{
mqttClient.on("message", (topic, message) => {
if(topic == "server/"+this.getAttribute('id')+"/online") {
console.log(topic,message.toString());
let json = JSON.parse(message.toString());
if(json.status) {
this.s.classList = "s font-semibold bg-RUNNING";
@@ -70,21 +71,5 @@ export class ServerCard extends HTMLDivElement{
}
}
});
/*fetch("/api-interne/server/"+this.getAttribute('id')).then(e=>e.json()).then((rslt)=>{
this.s.classList = "s font-semibold bg-"+rslt.status;
this.s.innerText = rslt.status;
this.cpu.querySelector('.p').innerText = rslt.cpu+"%";
this.cpu.querySelector('.gauge >div').style.width = rslt.cpu+"%";
this.cpu.querySelector('.gauge >div').classList = "bg-"+rslt.cpu_color+"-500 h-2 rounded-l-full";
this.ram.querySelector('.p').innerText = rslt.ram+"%";
this.ram.querySelector('.gauge >div').style.width = rslt.ram+"%";
this.ram.querySelector('.gauge >div').classList = "bg-"+rslt.ram_color+"-500 h-2 rounded-l-full";
this.hdd.querySelector('.p').innerText = rslt.hdd+"%";
this.hdd.querySelector('.gauge >div').style.width = rslt.hdd+"%";
this.hdd.querySelector('.gauge >div').classList = "bg-"+rslt.hdd_color+"-500 h-2 rounded-l-full";
})*/
}
}

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 Version20251106072345 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 customer_wallet (id SERIAL NOT NULL, customer_id INT DEFAULT NULL, ammount DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE UNIQUE INDEX UNIQ_CDAD4E4E9395C3F3 ON customer_wallet (customer_id)');
$this->addSql('CREATE TABLE customer_wallet_history (id SERIAL NOT NULL, wallet_id INT DEFAULT NULL, entry_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, operation VARCHAR(255) NOT NULL, ammount DOUBLE PRECISION NOT NULL, author VARCHAR(255) NOT NULL, descrition VARCHAR(255) NOT NULL, paiment_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_CFD66197712520F3 ON customer_wallet_history (wallet_id)');
$this->addSql('COMMENT ON COLUMN customer_wallet_history.entry_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE customer_wallet ADD CONSTRAINT FK_CDAD4E4E9395C3F3 FOREIGN KEY (customer_id) REFERENCES customer (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE customer_wallet_history ADD CONSTRAINT FK_CFD66197712520F3 FOREIGN KEY (wallet_id) REFERENCES customer_wallet (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE customer_wallet DROP CONSTRAINT FK_CDAD4E4E9395C3F3');
$this->addSql('ALTER TABLE customer_wallet_history DROP CONSTRAINT FK_CFD66197712520F3');
$this->addSql('DROP TABLE customer_wallet');
$this->addSql('DROP TABLE customer_wallet_history');
}
}

View File

@@ -123,6 +123,9 @@ class Customer
#[ORM\OneToMany(targetEntity: CustomerSepa::class, mappedBy: 'customer')]
private Collection $customerSepas;
#[ORM\OneToOne(mappedBy: 'customer', cascade: ['persist', 'remove'])]
private ?CustomerWallet $customerWallet = null;
public function __clone(): void
{
@@ -633,4 +636,26 @@ class Customer
return $this;
}
public function getCustomerWallet(): ?CustomerWallet
{
return $this->customerWallet;
}
public function setCustomerWallet(?CustomerWallet $customerWallet): static
{
// unset the owning side of the relation if necessary
if ($customerWallet === null && $this->customerWallet !== null) {
$this->customerWallet->setCustomer(null);
}
// set the owning side of the relation if necessary
if ($customerWallet !== null && $customerWallet->getCustomer() !== $this) {
$customerWallet->setCustomer($this);
}
$this->customerWallet = $customerWallet;
return $this;
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace App\Entity;
use App\Repository\CustomerWalletRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: CustomerWalletRepository::class)]
class CustomerWallet
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\OneToOne(inversedBy: 'customerWallet', cascade: ['persist', 'remove'])]
private ?Customer $customer = null;
#[ORM\Column]
private ?float $ammount = null;
/**
* @var Collection<int, CustomerWalletHistory>
*/
#[ORM\OneToMany(targetEntity: CustomerWalletHistory::class, mappedBy: 'wallet')]
private Collection $customerWalletHistories;
public function __construct()
{
$this->customerWalletHistories = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getCustomer(): ?Customer
{
return $this->customer;
}
public function setCustomer(?Customer $customer): static
{
$this->customer = $customer;
return $this;
}
public function getAmmount(): ?float
{
return $this->ammount;
}
public function setAmmount(float $ammount): static
{
$this->ammount = $ammount;
return $this;
}
/**
* @return Collection<int, CustomerWalletHistory>
*/
public function getCustomerWalletHistories(): Collection
{
return $this->customerWalletHistories;
}
public function addCustomerWalletHistory(CustomerWalletHistory $customerWalletHistory): static
{
if (!$this->customerWalletHistories->contains($customerWalletHistory)) {
$this->customerWalletHistories->add($customerWalletHistory);
$customerWalletHistory->setWallet($this);
}
return $this;
}
public function removeCustomerWalletHistory(CustomerWalletHistory $customerWalletHistory): static
{
if ($this->customerWalletHistories->removeElement($customerWalletHistory)) {
// set the owning side to null (unless already changed)
if ($customerWalletHistory->getWallet() === $this) {
$customerWalletHistory->setWallet(null);
}
}
return $this;
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace App\Entity;
use App\Repository\CustomerWalletHistoryRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: CustomerWalletHistoryRepository::class)]
class CustomerWalletHistory
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'customerWalletHistories')]
private ?CustomerWallet $wallet = null;
#[ORM\Column]
private ?\DateTimeImmutable $entryAt = null;
#[ORM\Column(length: 255)]
private ?string $operation = null;
#[ORM\Column]
private ?float $ammount = null;
#[ORM\Column(length: 255)]
private ?string $author = null;
#[ORM\Column(length: 255)]
private ?string $descrition = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $paimentId = null;
public function getId(): ?int
{
return $this->id;
}
public function getWallet(): ?CustomerWallet
{
return $this->wallet;
}
public function setWallet(?CustomerWallet $wallet): static
{
$this->wallet = $wallet;
return $this;
}
public function getEntryAt(): ?\DateTimeImmutable
{
return $this->entryAt;
}
public function setEntryAt(\DateTimeImmutable $entryAt): static
{
$this->entryAt = $entryAt;
return $this;
}
public function getOperation(): ?string
{
return $this->operation;
}
public function setOperation(string $operation): static
{
$this->operation = $operation;
return $this;
}
public function getAmmount(): ?float
{
return $this->ammount;
}
public function setAmmount(float $ammount): static
{
$this->ammount = $ammount;
return $this;
}
public function getAuthor(): ?string
{
return $this->author;
}
public function setAuthor(string $author): static
{
$this->author = $author;
return $this;
}
public function getDescrition(): ?string
{
return $this->descrition;
}
public function setDescrition(string $descrition): static
{
$this->descrition = $descrition;
return $this;
}
public function getPaimentId(): ?string
{
return $this->paimentId;
}
public function setPaimentId(?string $paimentId): static
{
$this->paimentId = $paimentId;
return $this;
}
}

View File

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

View File

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

View File

@@ -20,6 +20,10 @@
<i class="fad fa-home"></i>
Nom de domaine
</a>
<a href="{{ path('artemis_esyweb_view',{id:website.id,current:'options'}) }}" class="px-4 py-2 font-semibold {% if current == "ndd" %}{{ active }}{% else %}{{ desactive }}{% endif %}">
<i class="fad fa-home"></i>
Options du site
</a>
</div>
{% include 'artemis/esyweb/website/'~current~".twig" %}

View File

@@ -71,9 +71,6 @@
</div>
</div>
<div class="mt-6 flex justify-end">
<a class="px-4 py-2 bg-indigo-600 text-white text-sm font-medium rounded-xl hover:bg-indigo-700">Détails</a>
</div>
</div>
{% endfor %}

View File

@@ -24,9 +24,9 @@
<i class="fad fa-browser"></i>
Site internet
</a>
<a href="{{ path('artemis_intranet_customer_view',{id:customer.id,current:'external'}) }}" class="px-4 py-2 font-semibold {% if current == "external" %}{{ active }}{% else %}{{ desactive }}{% endif %}">
<i class="fad fa-link"></i>
Service externe
<a href="{{ path('artemis_intranet_customer_view',{id:customer.id,current:'wallet'}) }}" class="px-4 py-2 font-semibold {% if current == "wallet" %}{{ active }}{% else %}{{ desactive }}{% endif %}">
<i class="fad fa-wallet"></i>
Porte monnaie
</a>
</div>

View File

@@ -0,0 +1 @@
wallet

View File

@@ -45,7 +45,7 @@ modules_pushForward: Mise en avant
modules_bouton: Bouton
modules_title: Titre
modules_event: Evénement
modules_news: Newsletter
modules_news: Actualité
modules_partenair: Partenaire
modules_faq: Question et Response
modules_form: Formulaire