Files
crm_ecosplay/src/Entity/DevisLine.php
Serreau Jovann 8b35e2b6d2 feat: comptabilite + prestataires + rapport financier + stats dynamiques
Comptabilite (Super Admin) :
- ComptabiliteController avec 7 exports CSV/JSON compatibles SAGE
  (journal ventes, grand livre, FEC, balance agee, reglements,
  commissions Stripe 1.5%+0.25E, couts services)
- Export PDF via ComptaPdf (FPDF) avec bloc legal pre-rempli,
  tableau pagine, champ signature DocuSeal
- Signature electronique DocuSeal + callback + envoi email signe
  avec template dedie (compta_export_signed.html.twig)
- Rapport financier public (RapportFinancierPdf) : recettes par
  service, depenses (Stripe, infra, prestataires), bilan excedent/deficit
- Codes comptables clients EC-XXXX (plus de 411xxx)

Prestataires (Super Admin) :
- Entite Prestataire (raisonSociale, siret, email, phone, adresse)
- Entite FacturePrestataire (numFacture, montantHt, montantTtc,
  year, month, isPaid, PDF via Vich)
- CRUD complet avec recherche SIRET via proxy API data.gouv.fr
- Commande cron app:reminder:factures-prestataire (5 du mois)
- Factures prestataires integrees dans export couts services
- Sidebar Super Admin : entree Prestataires + Comptabilite

Stats (/admin/stats) :
- Cout prestataire dynamique depuis FacturePrestataire
- Fusion Infra + Prestataire en "Cout de fonctionnement"
- Commission Stripe corrigee (1.5% + 0.25E par transaction)

Divers :
- DocuSealService::sendComptaForSignature() + getApi()
- Customer::generateCodeComptable() format EC-XXXX-XXXXX
- Protection double prefixe EC- a la creation client
- Bouton regenerer PDF cache quand advert state=accepted
- Modals sans script inline (data-modal-open/close dans app.js)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:39:31 +02:00

127 lines
2.4 KiB
PHP

<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class DevisLine
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(targetEntity: Devis::class, inversedBy: 'lines')]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private Devis $devis;
#[ORM\Column]
private int $pos = 0;
#[ORM\Column(length: 255)]
private string $title;
#[ORM\Column(type: 'text', nullable: true)]
private ?string $description = null;
#[ORM\Column(type: 'decimal', precision: 10, scale: 2, options: ['default' => '0.00'])]
private string $priceHt = '0.00';
#[ORM\Column(length: 30, nullable: true)]
private ?string $type = null;
#[ORM\Column(nullable: true)]
private ?int $serviceId = null;
public function __construct(Devis $devis, string $title, string $priceHt = '0.00', int $pos = 0)
{
$this->devis = $devis;
$this->title = $title;
$this->priceHt = $priceHt;
$this->pos = $pos;
}
public function getId(): ?int
{
return $this->id;
}
public function getDevis(): Devis
{
return $this->devis;
}
public function getPos(): int
{
return $this->pos;
}
public function setPos(int $pos): static
{
$this->pos = $pos;
return $this;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
public function getPriceHt(): string
{
return $this->priceHt;
}
public function setPriceHt(string $priceHt): static
{
$this->priceHt = $priceHt;
return $this;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(?string $type): static
{
$this->type = $type;
return $this;
}
public function getServiceId(): ?int
{
return $this->serviceId;
}
public function setServiceId(?int $serviceId): static
{
$this->serviceId = $serviceId;
return $this;
}
}