Compare commits

...

45 Commits

Author SHA1 Message Date
796bea7d41 Merge branch 'production-dv-thanato' into production 2025-08-18 14:50:40 +03:00
ece8666881 fix add gitignore 2025-08-18 14:49:36 +03:00
9a1c8bca86 feat add is_tva client 2025-08-18 14:49:35 +03:00
narindraezway
d10dce3880 Refactor email signature handling to include user name in footer content 2025-08-18 14:49:34 +03:00
narindraezway
63ff1428d8 Update admin app ID 2025-08-18 14:49:34 +03:00
narindraezway
1983f506c8 Fix signature image dimensions email 2025-08-18 14:49:34 +03:00
Tiavina
458ad6588a log production dv thanato 2025-08-18 14:49:33 +03:00
Tiavina
7dd75e4076 Merge branch 'staging' into production 2025-08-01 13:40:43 +03:00
narindraezway
5a880677c4 Merge branch 'staging' into production 2025-07-09 13:50:01 +03:00
Tiavina
f2f737d6f8 Merge branch 'staging' into production 2025-06-10 17:01:09 +03:00
Tiavina
024df6bcd8 Merge branch 'staging' into production 2025-06-10 15:30:32 +03:00
narindraezway
2b867f27ea Merge branch 'staging' into production 2025-06-05 10:56:58 +03:00
Tiavina
416f4b030a Merge branch 'staging' into production 2025-06-02 15:08:10 +03:00
Tiavina
2d3196ffe4 Merge branch 'staging' into production 2025-05-20 10:21:57 +03:00
narindraezway
fc37e8583d Merge branch 'staging' into production 2025-05-07 15:04:42 +03:00
Tiavina
db6839451b Merge branch 'staging' into production 2025-05-06 16:21:58 +03:00
narindraezway
625e81ac30 Merge branch 'staging' into production 2025-05-05 13:45:31 +03:00
Tiavina
fbce8789c1 Merge branch 'staging' into production 2025-04-30 18:10:30 +03:00
Tiavina
5396c6ad1b Merge branch 'staging' into production 2025-04-30 18:05:52 +03:00
Tiavina
01f9176d32 Merge branch 'staging' into production 2025-04-30 17:51:15 +03:00
Tiavina
f5d1426d12 Merge remote-tracking branch 'origin/staging' into production 2025-04-25 17:30:53 +03:00
Tiavina
8f13e48206 Merge branch 'staging' into production 2025-04-25 15:06:17 +03:00
Tiavina Handrianina
459fda7106 Merge branch 'staging' into 'production'
HOTFIXESdevis list group facturation redirect

See merge request sottye/hytha35!6
2025-04-15 12:27:05 +00:00
Tiavina Handrianina
45f0f81c03 Merge branch 'staging' into 'production'
HOTFIXES OVERRIDE TEMPLATE TYPE CODE

See merge request sottye/hytha35!5
2025-04-15 11:16:07 +00:00
Tiavina Handrianina
1c4a972222 Merge branch 'staging' into 'production'
Deploying facturation at any date for HYTHA 35

See merge request sottye/hytha35!4
2025-04-15 10:16:44 +00:00
Tiavina Handrianina
d065671291 Merge branch 'staging' into 'production'
Deploying compte comptable into production

See merge request sottye/hytha35!3
2025-04-14 13:07:56 +00:00
Tiavina Handrianina
5512c23004 Merge branch 'staging' into 'production'
Merge staging into production

See merge request sottye/hytha35!2
2025-04-10 15:23:52 +00:00
Tiavina
3ea9d4ed52 Merge remote-tracking branch 'origin/staging' into releases/release-hytha-prod 2025-04-07 16:53:43 +03:00
Tiavina
602466d9a9 Merge branch 'staging' into releases/release-hytha-prod 2025-04-04 19:43:40 +03:00
Tiavina
b1fabe9804 Merge branch 'staging' into releases/release-hytha-prod 2025-03-27 08:51:59 +03:00
Tiavina
2bbfe390eb Merge branch 'staging' into releases/release-hytha-prod 2025-03-26 19:55:15 +03:00
Tiavina
12a751c1c3 Merge branch 'staging' into releases/release-hytha-prod 2025-03-26 19:43:51 +03:00
Tiavina
0276655040 Merge branch 'features/feature-devis-group' into releases/release-hytha-prod 2025-03-26 13:06:50 +03:00
Tiavina
5ab91d4be7 Merge branch 'staging' into releases/release-hytha-prod 2025-03-25 13:34:15 +03:00
Tiavina
91c67452c2 Merge branch 'staging' into releases/release-hytha-prod 2025-03-21 09:29:13 +03:00
Tiavina
31633b04d9 Merge branch 'hotfixes/hotfix-update-client' into releases/release-hytha-prod 2025-03-19 11:38:00 +03:00
Tiavina
dc3da8d425 Merge branch 'hotfixes/hotfix-update-client' into releases/release-hytha-prod 2025-03-19 10:50:02 +03:00
Tiavina
ea119f5c73 Merge branch 'hotfixes/hotfix-update-client' into releases/release-hytha-prod 2025-03-19 10:43:24 +03:00
Tiavina
4bd86ae762 Merge branch 'hotfixes/hotfix-update-client' into releases/release-hytha-prod 2025-03-19 10:30:55 +03:00
Tiavina
2c1e771472 Merge branch 'hotfixes/hotfix-update-client' into releases/release-hytha-prod 2025-03-19 10:13:45 +03:00
Tiavina
c07c4aaf88 Merge branch 'staging' into releases/release-hytha-prod 2025-03-18 10:19:21 +03:00
Tiavina
95be6e4827 Merge branch 'staging' into releases/release-hytha-prod 2025-03-17 16:16:16 +03:00
Tiavina
e7c51a4d73 Merge branch 'fixes/fix-rapport-bijoux-text' into releases/release-hytha-prod 2025-03-13 12:06:47 +03:00
Tiavina
f509f5e988 Merge branch 'staging' into releases/release-hytha-prod 2025-03-13 10:53:37 +03:00
Tiavina
f8ff4c6b3e Merge branch 'hotfixes/hotfixe-show-facture-case-and-order-number' into releases/release-hytha-prod 2025-03-07 13:17:00 +03:00
43 changed files with 16874 additions and 4962 deletions

22
.gitignore vendored
View File

@ -1,11 +1,25 @@
# Ignore tout par défaut
*
*.sql
# Exceptions : fichiers et dossiers à inclure
!.gitignore
!calendar/
!gestion/
!Jenkinsfile
# Dossiers à inclure
!calendar/
!gestion/
# Inclure tout le contenu de ces dossiers
!calendar/**
!gestion/**
# Ignorer spécifiquement (même dans les dossiers inclus)
*.sql
node_modules/
**/node_modules/
**/package-lock.json
**/composer.lock
**/.env
**/.env.*
**/dist/
**/build/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ abstract class BddConstant
const DEFAULT_TABLE_PREFIX = "*PREFIX*";
const DEFAULT_CLIENT_GROUP_NAME = "Nom du groupe";
const DEFAULT_ADMIN_ID_NEXTCLOUD = 'admin';
const DEFAULT_ADMIN_APP_ID_NEXTCLOUD = "Johann";
const DEFAULT_ADMIN_APP_ID_NEXTCLOUD = "Vanessa";
const ISLEAVEPROPERTYONVCALENDAR = "ISLEAVE";

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
namespace OCA\Gestion\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use OCP\IDBConnection;
/**
* Migration pour ajouter le champ is_tva à la table oc_gestion_client
*/
class Version20001Date20250812120000 extends SimpleMigrationStep
{
private IDbConnection $db;
public function __construct(IDbConnection $db)
{
$this->db = $db;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper
{
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$tableprefix = "gestion_";
// Vérifier si la table existe
if ($schema->hasTable($tableprefix.'client')) {
$table = $schema->getTable($tableprefix.'client');
// Ajouter le champ is_tva s'il n'existe pas déjà
if (!$table->hasColumn('is_tva')) {
$table->addColumn('is_tva', 'smallint', [
'notnull' => true,
'default' => 1,
'comment' => 'Indique si le client est assujetti à la TVA (1=oui, 0=non)',
'unsigned' => true,
'length' => 1
]);
$output->info('Champ is_tva ajouté à la table gestion_client');
return $schema;
}
}
return null;
}
}

View File

@ -42,7 +42,7 @@ class CareCertificatePdfHandler extends FPDF {
function Header()
{
if($this->logo != "nothing"){
$this->Image($this->imagePath."logo.png", 10, 10, 75, 25);
$this->Image($this->imagePath."logo.png", 4, 2, 50, 35);
}
else{
$this->Cell(55,30,'');

View File

@ -32,7 +32,8 @@ use OCA\Gestion\Helpers\DateHelpers;
use OCA\Gestion\Helpers\FileExportHelpers;
use OCA\Gestion\Helpers\PriceHelpers;
class PacemakerCertificatePdfHandler extends FPDF {
class PacemakerCertificatePdfHandler extends FPDF
{
private $devisOfDefunt = [];
private $logo = null;
@ -41,11 +42,10 @@ class PacemakerCertificatePdfHandler extends FPDF {
function Header()
{
if($this->logo != "nothing"){
$this->Image($this->imagePath."logo.png", 10, 10, 75, 25);
}
else{
$this->Cell(55,30,'');
if ($this->logo != "nothing") {
$this->Image($this->imagePath . "logo.png", 4, 2, 50, 35);
} else {
$this->Cell(55, 30, '');
}
}
function Footer()
@ -53,108 +53,120 @@ class PacemakerCertificatePdfHandler extends FPDF {
$this->SetY(-18);
$this->SetFont('ComicSans', '', 10);
$this->MultiCell(0, 5, utf8_decode(html_entity_decode($this->devisOfDefunt['configuration']->legal_one)), 0, 'C');
$this->MultiCell(0, 5, utf8_decode(html_entity_decode($this->devisOfDefunt['configuration']->adresse)), 0,'C');
$this->MultiCell(0, 5, utf8_decode(html_entity_decode($this->devisOfDefunt['configuration']->adresse)), 0, 'C');
}
public function SetPacemakerCertificateData(array $devisOfDefunt,$logo = null,$signatureImageExist = false){
public function SetPacemakerCertificateData(array $devisOfDefunt, $logo = null, $signatureImageExist = false)
{
$this->devisOfDefunt = $devisOfDefunt;
$this->logo = $logo;
$this->signatureImageExist = $signatureImageExist;
}
public function SetPacemakerCertificate(){
public function SetPacemakerCertificate()
{
$this->AddPage();
$this->SetMargins(left:20,top:0,right:20);
$this->SetMargins(left: 20, top: 0, right: 20);
$this->SetPacemakerCertificateTitle();
$this->SetPacemakerCertificateContent();
$this->SetSigning();
}
private function SetSigning(){
$this->SetXY(140,$this->GetY() + 15);
$this->Cell(0,10,'Cachet et signature');
private function SetSigning()
{
$this->SetXY(140, $this->GetY() + 15);
$this->Cell(0, 10, 'Cachet et signature');
if($this->signatureImageExist){
$this->Image($this->imagePath."sign.png", 135, $this->GetY() + 12, 60, 40);
if ($this->signatureImageExist) {
$this->Image($this->imagePath . "sign.png", 135, $this->GetY() + 12, 60, 40);
}
}
private function SetPacemakerCertificateContent(){
private function SetPacemakerCertificateContent()
{
$this->SetFont('ComicSans', '', 14);
$this->MultiCell(0,7,FileExportHelpers::FormatTextForExport('La Société '. $this->devisOfDefunt['configuration']->entreprise. ' habilitée sous le numéro ' . $this->devisOfDefunt['thanato_reference'] . ', certifie par la présente que : '));
$this->MultiCell(0, 7, FileExportHelpers::FormatTextForExport('La Société ' . $this->devisOfDefunt['configuration']->entreprise . ' habilitée sous le numéro ' . $this->devisOfDefunt['thanato_reference'] . ', certifie par la présente que : '));
$this->SetFont('ComicSans', 'B', 14);
$this->Cell(0,12, 'Mr/Mme ' . FileExportHelpers::FormatTextForExport($this->devisOfDefunt['thanato_nom'] . ' ' . $this->devisOfDefunt['thanato_prenom']),0,1);
$this->Cell(0, 12, 'Mr/Mme ' . FileExportHelpers::FormatTextForExport($this->devisOfDefunt['thanato_nom'] . ' ' . $this->devisOfDefunt['thanato_prenom']), 0, 1);
$this->SetFont('ComicSans', '', 14);
$this->MultiCell(0,7, FileExportHelpers::FormatTextForExport('Employé(e) au sein de notre société et titulaire du diplôme national de Thanatopracteur, a retiré ce jour, la prothèse fonctionnant à pile implantée sur le corps du défunt :'));
$this->MultiCell(0, 7, FileExportHelpers::FormatTextForExport('Employé(e) au sein de notre société et titulaire du diplôme national de Thanatopracteur, a retiré ce jour, la prothèse fonctionnant à pile implantée sur le corps du défunt :'));
$this->SetFont('ComicSans', 'B', 14);
$this->Cell(0,12, FileExportHelpers::FormatTextForExport($this->devisOfDefunt['defunt_nom']),0,1);
$this->Cell(0, 12, FileExportHelpers::FormatTextForExport($this->devisOfDefunt['defunt_nom']), 0, 1);
$this->SetFont('ComicSans', '', 14);
$this->Cell(0,12, FileExportHelpers::FormatTextForExport("Qui reposait à l'adresse suivante") . ' : ',0,1);
$this->Cell(0, 12, FileExportHelpers::FormatTextForExport("Qui reposait à l'adresse suivante") . ' : ', 0, 1);
$this->SetFont('ComicSans', 'B', 14);
$this->MultiCell(0,6, FileExportHelpers::FormatTextForExport($this->devisOfDefunt['location_of_devis']));
$this->MultiCell(0, 6, FileExportHelpers::FormatTextForExport($this->devisOfDefunt['location_of_devis']));
$this->Ln(6);
$this->SetFont('ComicSans', '', 14);
$this->Cell(0,6,
FileExportHelpers::FormatTextForExport("Numéro de série : ").
FileExportHelpers::FormatTextForExport($this->devisOfDefunt['defunt_reference_pacemaker']),0,1);
$this->Cell(0,6,
FileExportHelpers::FormatTextForExport("Marque du produit : ").
FileExportHelpers::FormatTextForExport($this->devisOfDefunt['defunt_product_brand']),0,1);
$this->Cell(0,12, FileExportHelpers::FormatTextForExport("La présente attestation est établie pour faire valoir ce que de droit."),0,5);
$this->Cell(
0,
6,
FileExportHelpers::FormatTextForExport("Numéro de série : ") .
FileExportHelpers::FormatTextForExport($this->devisOfDefunt['defunt_reference_pacemaker']),
0,
1
);
$this->Cell(
0,
6,
FileExportHelpers::FormatTextForExport("Marque du produit : ") .
FileExportHelpers::FormatTextForExport($this->devisOfDefunt['defunt_product_brand']),
0,
1
);
$this->Cell(0, 12, FileExportHelpers::FormatTextForExport("La présente attestation est établie pour faire valoir ce que de droit."), 0, 5);
$this->Ln(5);
$this->MultiAlignCell(120,7,FileExportHelpers::FormatTextForExport('Fait à '). FileExportHelpers::FormatTextForExport($this->devisOfDefunt['configuration']->adresse),0);
$this->MultiAlignCell(120, 7, FileExportHelpers::FormatTextForExport('Fait à ') . FileExportHelpers::FormatTextForExport($this->devisOfDefunt['configuration']->adresse), 0);
$this->SetX(140);
$this->Cell(0,7,'le '. $this->devisOfDefunt['devis_date']->format('d/m/Y'),0);
$this->Cell(0, 7, 'le ' . $this->devisOfDefunt['devis_date']->format('d/m/Y'), 0);
}
private function SetPacemakerCertificateTitle(){
private function SetPacemakerCertificateTitle()
{
$this->SetY(y: 50);
$this->SetFont('ComicSans', 'B', 20);
$this->Cell(0,10,'ATTESTATION DE RETRAIT DE LA',0,1,'C');
$this->Cell(0,10,'PROTHESE FONCTIONNANT A PILE',0,1,'C');
$this->Ln(20);
$this->Cell(0, 10, 'ATTESTATION DE RETRAIT DE LA', 0, 1, 'C');
$this->Cell(0, 10, 'PROTHESE FONCTIONNANT A PILE', 0, 1, 'C');
$this->Ln(20);
}
function MultiAlignCell($w,$h,$text,$border=0,$ln=0,$align='L',$fill=false)
{
// Store reset values for (x,y) positions
$x = $this->GetX() + $w;
$y = $this->GetY();
function MultiAlignCell($w, $h, $text, $border = 0, $ln = 0, $align = 'L', $fill = false)
{
// Store reset values for (x,y) positions
$x = $this->GetX() + $w;
$y = $this->GetY();
// Make a call to FPDF's MultiCell
$this->MultiCell($w,$h,$text,$border,$align,$fill);
// Make a call to FPDF's MultiCell
$this->MultiCell($w, $h, $text, $border, $align, $fill);
// Reset the line position to the right, like in Cell
if( $ln==0 )
{
$this->SetXY($x,$y);
}
}
// Reset the line position to the right, like in Cell
if ($ln == 0) {
$this->SetXY($x, $y);
}
}
function NbLines($w, $txt)
function NbLines($w, $txt)
{
// Compute the number of lines a MultiCell of width w will take
if(!isset($this->CurrentFont))
if (!isset($this->CurrentFont))
$this->Error('No font has been set');
$cw = $this->CurrentFont['cw'];
if($w==0)
$w = $this->w-$this->rMargin-$this->x;
$wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
$s = str_replace("\r",'',(string)$txt);
if ($w == 0)
$w = $this->w - $this->rMargin - $this->x;
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
$s = str_replace("\r", '', (string) $txt);
$nb = strlen($s);
if($nb>0 && $s[$nb-1]=="\n")
if ($nb > 0 && $s[$nb - 1] == "\n")
$nb--;
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$nl = 1;
while($i<$nb)
{
while ($i < $nb) {
$c = $s[$i];
if($c=="\n")
{
if ($c == "\n") {
$i++;
$sep = -1;
$j = $i;
@ -162,24 +174,20 @@ class PacemakerCertificatePdfHandler extends FPDF {
$nl++;
continue;
}
if($c==' ')
if ($c == ' ')
$sep = $i;
$l += $cw[$c];
if($l>$wmax)
{
if($sep==-1)
{
if($i==$j)
if ($l > $wmax) {
if ($sep == -1) {
if ($i == $j)
$i++;
}
else
$i = $sep+1;
} else
$i = $sep + 1;
$sep = -1;
$j = $i;
$l = 0;
$nl++;
}
else
} else
$i++;
}
return $nl;

View File

@ -27,65 +27,69 @@ declare(strict_types=1);
namespace OCA\Gestion\Service\Devis\Pdf;
use DateTime;
use \FPDF;
use FPDF;
use OCA\Gestion\Helpers\FileExportHelpers;
use OCA\Gestion\Helpers\PriceHelpers;
class DevisPdfHandler extends FPDF {
class DevisPdfHandler extends FPDF
{
private $multipleDevisData = [];
private $devisData = [];
private $logo = null;
private $logoPath = "/var/www/html/data/admin/files/.gestion/";
function Header()
public function Header()
{
if($this->logo != "nothing"){
$this->Image($this->logoPath."logo.png", 2, 2, 50,35);
}
else{
$this->Cell(55,30,'');
if ($this->logo != "nothing") {
$this->Image($this->logoPath . "logo.png", 4, 2, 50, 35);
} else {
$this->Cell(55, 30, '');
}
}
function Footer()
public function Footer()
{
$this->SetY(-40);
$this->SetFont('ComicSans', '', 7);
$this->MultiCell(0,5,utf8_decode(html_entity_decode('Tout retard de paiement entraînera de plein droit une pénalité de retard de 3 fois le taux légal ( Loi 2008-776 du 4 août 2008) et une indemnité forfaitaire de 40 EUR pour frais de recouvrement sera appliquée.')));
$this->MultiCell(0, 5, utf8_decode(html_entity_decode('Tout retard de paiement entraînera de plein droit une pénalité de retard de 3 fois le taux légal ( Loi 2008-776 du 4 août 2008) et une indemnité forfaitaire de 40 EUR pour frais de recouvrement sera appliquée.')));
$this->Ln(1);
$this->MultiCell(0,5,utf8_decode(html_entity_decode('Si les frais de recouvrement sont supérieurs à ce montant forfaitaire, une indemnisation complémentaire sera due sur présentation de justificatifs ( articles L.441-3 et L.441-6 du code de commerce ).
')));
$this->MultiCell(0, 5, utf8_decode(html_entity_decode('Si les frais de recouvrement sont supérieurs à ce montant forfaitaire, une indemnisation complémentaire sera due sur présentation de justificatifs ( articles L.441-3 et L.441-6 du code de commerce ).
')));
$this->SetY(-15);
$this->SetFont('ComicSans', 'B', 8);
$this->Cell(0, 10, utf8_decode(html_entity_decode($this->devisData['configuration']->legal_one)), 0, 0, 'C');
}
public function SetDevisPdfData(array $devisData,$logo = null){
public function SetDevisPdfData(array $devisData, $logo = null)
{
$this->devisData = $devisData;
$this->logo = $logo;
}
public function SetMultipleDevisPdfData(array $multipleDevisData,$logo = null){
public function SetMultipleDevisPdfData(array $multipleDevisData, $logo = null)
{
$this->multipleDevisData = $multipleDevisData;
$this->logo = $logo;
}
private function DrawDevisCompanyAndClientInfo(){
private function DrawDevisCompanyAndClientInfo()
{
$this->SetY(40);
$this->SetFont('ComicSans', '', 12);
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration']->entreprise), 0, 0);
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['client_nom']), 0, 1,'R');
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['client_nom']), 0, 1, 'R');
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration_adresse']), 0, 0);
$this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->devisData['client_real_adress'])), 0, 1,'R');
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration_adresse_city']), 0, 0);border:
$this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->devisData['client_adress_city'])), 0, 1,'R');
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport('Tél : ') . FileExportHelpers::FormatTextForExport($this->devisData['configuration']->telephone),0,0);
$this->Cell(0, 7, 'Siret: ' . $this->devisData['siret'], 0, 1,'R');
$this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->devisData['client_real_adress'])), 0, 1, 'R');
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration_adresse_city']), 0, 0);
border:
$this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->devisData['client_adress_city'])), 0, 1, 'R');
$this->Cell(0, 7, FileExportHelpers::FormatTextForExport('Tél : ') . FileExportHelpers::FormatTextForExport($this->devisData['configuration']->telephone), 0, 0);
$this->Cell(0, 7, 'Siret: ' . $this->devisData['siret'], 0, 1, 'R');
$this->Cell(0, 7, 'Mail : ' . $this->devisData['configuration']->mail, 0, 1);
$this->Ln(3);
}
private function DrawDevisInfoTable(){
private function DrawDevisInfoTable()
{
$this->SetFont('ComicSans', 'B', 11);
$this->Cell(30, 7, 'DATE', 1, 0, 'C');
$this->Cell(80, 7, 'CLIENT', 1, 0, 'C');
@ -99,91 +103,110 @@ class DevisPdfHandler extends FPDF {
$this->Ln(8);
}
private function DrawArticlesTable(){
$this->SetLineWidth(0.1);
private function DrawArticlesTable()
{
$this->SetLineWidth(0.1);
$this->Rect(10, 105, 190, 100, "D");
// cadre titre des colonnes
$this->Line(10, 115, 200,115);
$this->Line(10, 115, 200, 115);
// les traits verticaux colonnes
$this->Line(35, 105, 35, 205);
$this->Line(135, 105, 135, 205);
$this->Line(155, 105, 155, 205);
$this->Line(135, 105, 135, 205);
$this->Line(155, 105, 155, 205);
$this->Line(175, 105, 175, 205);
}
private function DrawArticlesTableHeader(){
$tvaValue = $this->devisData["configuration"]->tva_default;
$this->SetFont('ComicSans','',10);
$this->SetXY( 10,106 );
$this->Cell( 20, 8, "Date", 0, 0, 'C');
private function DrawArticlesTableHeader()
{
$tvaDefault = $this->devisData["configuration"]->tva_default;
$clientTvaStatus = isset($this->devisData["tva"]) ? (int)$this->devisData["tva"] : 1;
$this->SetXY( 35,106 );
$this->Cell( 100, 8, "Description", 0, 0, 'C');
$this->SetXY( 135,106 );
$this->Cell( 20, 8, "Prix Uni. HT", 0, 0, 'C');
$this->SetXY( 155,106 );
$this->Cell( 20, 8, 'TVA ' . $tvaValue . '%', 0, 0, 'C');
$this->SetXY( 175,106 );
$this->Cell( 25, 8, "Prix Uni. TTC", 0, 0, 'C');
// Déterminer le libellé TVA selon le statut du client
$tvaLabel = ($clientTvaStatus === 0) ? "TVA 0%" : "TVA " . $tvaDefault . "%";
$this->SetFont('ComicSans', '', 10);
$this->SetXY(10, 106);
$this->Cell(20, 8, "Date", 0, 0, 'C');
$this->SetXY(35, 106);
$this->Cell(100, 8, "Description", 0, 0, 'C');
$this->SetXY(135, 106);
$this->Cell(20, 8, "Prix Uni. HT", 0, 0, 'C');
$this->SetXY(155, 106);
$this->Cell(20, 8, $tvaLabel, 0, 0, 'C');
$this->SetXY(175, 106);
$this->Cell(25, 8, "Prix Uni. TTC", 0, 0, 'C');
}
public function DrawArticlesTableValueAndReturnTotalPrice(){
$this->SetFont('ComicSans','',10);
$tvaValue = $this->devisData["configuration"]->tva_default;
public function DrawArticlesTableValueAndReturnTotalPrice()
{
$this->SetFont('ComicSans', '', 10);
$tvaDefault = $this->devisData["configuration"]->tva_default;
$clientTvaStatus = isset($this->devisData["tva"]) ? (int)$this->devisData["tva"] : 1;
// Déterminer le taux de TVA à appliquer selon le statut du client
$tvaValue = ($clientTvaStatus === 0) ? 0 : $tvaDefault;
$tvaLabel = ($clientTvaStatus === 0) ? "0%" : $tvaDefault . "%";
$totalHt = 0;
$totalTtc = 0;
$totalTva = 0;
$products = $this->devisData["products"];
$yValue = 116;
foreach($products as $product){
foreach ($products as $product) {
$valueHt = $product['produit_price'] * $product['quantite'];
$valueTtc = PriceHelpers::calculPriceWithVatValue($valueHt,$tvaValue);
$totalHt+=$valueHt;
$totalTtc+=$valueTtc;
// Calculer la TVA selon le statut du client
if ($clientTvaStatus === 0) {
// Client exonéré - pas de TVA
$valueTtc = $valueHt;
$tvaAmount = 0;
} else {
// Client soumis à la TVA - utiliser le calcul normal
$valueTtc = PriceHelpers::calculPriceWithVatValue($valueHt, $tvaValue);
$tvaAmount = $valueTtc - $valueHt;
}
$totalHt += $valueHt;
$totalTtc += $valueTtc;
$totalTva += $tvaAmount;
$productDescription = $product["produit_description"];
$dateValue = "";
if($product === end($products)){
if ($product === end($products)) {
$dateValue = $this->devisData['devis_date'];
$productDescription .= " de " . FileExportHelpers::GetSexeLabel($this->devisData['defunt_sexe']) . ' '. $this->devisData["defunt_nom"];
$productDescription .= " de " . FileExportHelpers::GetSexeLabel($this->devisData['defunt_sexe']) . ' ' . $this->devisData["defunt_nom"];
}
$tvaAmount = $valueTtc - $valueHt;
$this->SetXY( 10,$yValue );
$this->Cell(20, 6, $dateValue, 0,0);
$this->SetXY( 35,$yValue );
$this->MultiAlignCell(100, 6, utf8_decode(html_entity_decode($productDescription)),0,'0',);
$this->SetXY( 135,$yValue );
$this->Cell(20, 6, number_format($valueHt,2,'.','').chr(128), 0, 0, 'C');
$this->SetXY( 155,$yValue );
$this->Cell(20, 6, number_format($tvaAmount,2,'.','').chr(128), 0, 0, 'C');
$this->SetXY( 175,$yValue );
$this->Cell(25, 6, number_format($valueTtc,2,'.','').chr(128), 0, 1, 'C');
$this->SetXY(10, $yValue);
$this->Cell(20, 6, $dateValue, 0, 0);
$this->SetXY(35, $yValue);
$this->MultiAlignCell(100, 6, utf8_decode(html_entity_decode($productDescription)), 0, '0', );
$this->SetXY(135, $yValue);
$this->Cell(20, 6, number_format($valueHt, 2, '.', '') . chr(128), 0, 0, 'C');
$this->SetXY(155, $yValue);
$this->Cell(20, 6, number_format($tvaAmount, 2, '.', '') . chr(128), 0, 0, 'C');
$this->SetXY(175, $yValue);
$this->Cell(25, 6, number_format($valueTtc, 2, '.', '') . chr(128), 0, 1, 'C');
$yValue += 12;
$totalTva += $tvaAmount;
}
return [
"TOTAL HT" => $totalHt,
"TVA ".$tvaValue. "%" => $totalTva,
"TVA " . $tvaLabel => $totalTva,
"TOTAL TTC" => $totalTtc
];
}
private function DrawBankAndTotalPriceInfo($totalPriceArray){
private function DrawBankAndTotalPriceInfo($totalPriceArray)
{
$this->SetY(210);
$this->SetFont('ComicSans', '', 9);
$this->MultiCell(0,5,utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de ". $this->devisData['configuration']->entreprise)));
$this->MultiCell(0,5,utf8_decode(html_entity_decode("en indiquant le numéro de facture, ou par virement :")));
$this->MultiCell(0, 5, utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de " . $this->devisData['configuration']->entreprise)));
$this->MultiCell(0, 5, utf8_decode(html_entity_decode("en indiquant le numéro de facture, ou par virement :")));
$this->Ln(1);
//Table IBAN
$this->SetFont('ComicSans', '', 11);
$ibanWidth = 90;
@ -193,28 +216,30 @@ class DevisPdfHandler extends FPDF {
$this->Cell($ibanWidth, 7, 'Code SWIFT : AGRI FR PP 836', 1, 1, 'C');
//TABLE HT
$ibanLastPositionX = $ibanCursorX+$ibanWidth + 20;
$ibanLastPositionX = $ibanCursorX + $ibanWidth + 20;
$startOfArrayX = $ibanLastPositionX;
$startOfArrayY = $ibanCursorY;
foreach($totalPriceArray as $label => $price){
$this->SetXY($startOfArrayX,$startOfArrayY);
foreach ($totalPriceArray as $label => $price) {
$this->SetXY($startOfArrayX, $startOfArrayY);
$this->Cell(40, 7, $label, 1, 1, 'C');
$this->SetXY($startOfArrayX + 40,$startOfArrayY);
$this->Cell(40, 7, number_format($price,2,'.','').chr(128), 1, 1, 'C');
$this->SetXY($startOfArrayX + 40, $startOfArrayY);
$this->Cell(40, 7, number_format($price, 2, '.', '') . chr(128), 1, 1, 'C');
$startOfArrayY += 7;
}
}
public function SetMultipleDevisContent(){
foreach($this->multipleDevisData as $devisData){
public function SetMultipleDevisContent()
{
foreach ($this->multipleDevisData as $devisData) {
$this->devisData = $devisData;
$this->SetDevisContent();
}
}
public function SetDevisContent(){
public function SetDevisContent()
{
$this->AddPage();
$this->SetMargins(10,0,10);
$this->SetMargins(10, 0, 10);
$this->DrawDevisCompanyAndClientInfo();
$this->DrawDevisInfoTable();
$this->DrawArticlesTable();
@ -223,45 +248,45 @@ class DevisPdfHandler extends FPDF {
$this->DrawBankAndTotalPriceInfo($totalPriceValue);
}
function MultiAlignCell($w,$h,$text,$border=0,$ln=0,$align='L',$fill=false)
{
// Store reset values for (x,y) positions
$x = $this->GetX() + $w;
$y = $this->GetY();
public function MultiAlignCell($w, $h, $text, $border = 0, $ln = 0, $align = 'L', $fill = false)
{
// Store reset values for (x,y) positions
$x = $this->GetX() + $w;
$y = $this->GetY();
// Make a call to FPDF's MultiCell
$this->MultiCell($w,$h,$text,$border,$align,$fill);
// Make a call to FPDF's MultiCell
$this->MultiCell($w, $h, $text, $border, $align, $fill);
// Reset the line position to the right, like in Cell
if( $ln==0 )
{
$this->SetXY($x,$y);
}
}
// Reset the line position to the right, like in Cell
if ($ln == 0) {
$this->SetXY($x, $y);
}
}
function NbLines($w, $txt)
public function NbLines($w, $txt)
{
// Compute the number of lines a MultiCell of width w will take
if(!isset($this->CurrentFont))
if (!isset($this->CurrentFont)) {
$this->Error('No font has been set');
}
$cw = $this->CurrentFont['cw'];
if($w==0)
$w = $this->w-$this->rMargin-$this->x;
$wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
$s = str_replace("\r",'',(string)$txt);
if ($w == 0) {
$w = $this->w - $this->rMargin - $this->x;
}
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
$s = str_replace("\r", '', (string) $txt);
$nb = strlen($s);
if($nb>0 && $s[$nb-1]=="\n")
if ($nb > 0 && $s[$nb - 1] == "\n") {
$nb--;
}
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$nl = 1;
while($i<$nb)
{
while ($i < $nb) {
$c = $s[$i];
if($c=="\n")
{
if ($c == "\n") {
$i++;
$sep = -1;
$j = $i;
@ -269,25 +294,25 @@ class DevisPdfHandler extends FPDF {
$nl++;
continue;
}
if($c==' ')
if ($c == ' ') {
$sep = $i;
}
$l += $cw[$c];
if($l>$wmax)
{
if($sep==-1)
{
if($i==$j)
if ($l > $wmax) {
if ($sep == -1) {
if ($i == $j) {
$i++;
}
} else {
$i = $sep + 1;
}
else
$i = $sep+1;
$sep = -1;
$j = $i;
$l = 0;
$nl++;
}
else
} else {
$i++;
}
}
return $nl;
}

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
*/
namespace OCA\Gestion\Service\Devis\Pdf;
require_once __DIR__ . '/../../../../vendor/autoload.php';
use DateTime;
@ -90,6 +91,7 @@ class DevisPdfService
private function formatDevisDataToPdfDataFormat($devis, $configuration)
{
$devisDate = $devis['devis_date'];
$tva = isset($devis["tva"]) ? $devis["tva"] : 1;
$devisDate = DateTime::createFromFormat('Y-m-d', $devisDate);
$devisDate = $devisDate->format('d-m-Y');
$devis['devis_date'] = $devisDate;
@ -99,6 +101,7 @@ class DevisPdfService
$firstClient = $this->gestionBdd->getFirstClient();
$devis["siret"] = $firstClient != null ? $firstClient['legal_one'] : '';
$devis["products"] = $products;
$devis["tva"] = $tva;
$clientAdresses = FileExportHelpers::GetAddressAndCityFromAddress($devis["client_adresse"]);
$devis["client_real_adress"] = $clientAdresses["address"];
$devis["client_adress_city"] = $clientAdresses["city"];

View File

@ -57,7 +57,7 @@ class InvoiceGroupPdfHandler extends FPDF
function Header()
{
if ($this->logo != "nothing") {
$this->Image($this->logoPath . "logo.png", 2, 10, 75, 25);
$this->Image($this->logoPath . "logo.png", 4, 2, 50, 35);
$this->AddWatermark();
} else {
$this->Cell(55, 30, '');

View File

@ -27,7 +27,7 @@ declare(strict_types=1);
namespace OCA\Gestion\Service;
use DateTime;
use \FPDF;
use FPDF;
use OCA\Gestion\Constants\MultipleFactureTypeConstant;
use OCA\Gestion\Helpers\DateHelpers;
use OCA\Gestion\Helpers\FileExportHelpers;
@ -35,7 +35,6 @@ use OCA\Gestion\Helpers\PriceHelpers;
class InvoicePdfHandler extends FPDF
{
private $multipleFactureData = [];
private $factureData = [];
private $logo = null;
@ -48,61 +47,61 @@ class InvoicePdfHandler extends FPDF
private $articleTablesHeight = 130;
public $interLigneHeader = 5;
function Header()
public $interLigneHeader = 5;
public function Header()
{
if ($this->logo != "nothing") {
$this->Image($this->logoPath . "logo.png", 2, 10, 75, 25);
$this->Image($this->logoPath . "logo.png", 4, 2, 50, 35);
$this->AddWatermark();
} else {
$this->Cell(55, 30, '');
}
}
function AddWatermark()
public function AddWatermark()
{
$this->SetAlpha(0.2);
$imagePath = $this->logoPath . "filigrane_pdf.png";
list($originalWidth, $originalHeight) = getimagesize($imagePath);
// Convertir les dimensions de pixels à mm (1 pixel = 0.264583 mm)
// Convertir les dimensions de pixels à mm (1 pixel = 0.264583 mm)
$originalWidth = $originalWidth * 0.264583;
$originalHeight = $originalHeight * 0.264583;
// Convertir les dimensions de pixels à mm (1 pixel = 0.264583 mm)
// Convertir les dimensions de pixels à mm (1 pixel = 0.264583 mm)
$originalWidth = $originalWidth * 0.264583;
$originalHeight = $originalHeight * 0.264583;
// Augmenter l'échelle, par exemple, 1.5 pour 150% de la taille d'origine
$scale = 1.7;
$width = $originalWidth * $scale;
$height = $originalHeight * $scale;
// Calculer la position pour centrer l'image
$x = (210 - $width) / 2 + 15; // Décalage à droite de 15 mm
$y = ((297 - $height) / 2 ) + 21; // 297 mm est la hauteur d'une page A4
// Augmenter l'échelle, par exemple, 1.5 pour 150% de la taille d'origine
$scale = 1.7;
$width = $originalWidth * $scale;
$height = $originalHeight * $scale;
// Calculer la position pour centrer l'image
$x = (210 - $width) / 2 + 15; // Décalage à droite de 15 mm
$y = ((297 - $height) / 2) + 21; // 297 mm est la hauteur d'une page A4
// Ajouter l'image en filigrane
$this->Image($imagePath, $x, $y, $width, $height); // Chemin, position x, position y, largeur, hauteur
$this->SetAlpha(0.1); // Définir l'opacité
// Ajouter l'image en filigrane
$this->Image($imagePath, $x, $y, $width, $height); // Chemin, position x, position y, largeur, hauteur
$this->SetAlpha(0.1); // Définir l'opacité
}
function SetAlpha($alpha)
public function SetAlpha($alpha)
{
// Appliquer la transparence au document
$this->SetFillColor(255, 255, 255, $alpha * 255);
$this->SetTextColor(0, 0, 0, $alpha * 255);
$this->SetTextColor(0, 0, 0, $alpha * 255);
$this->SetDrawColor(0, 0, 0, $alpha * 255);
}
function Footer()
public function Footer()
{
$this->SetY(-34);
$this->SetFont('ComicSans', '', 7);
$this->SetFont('ComicSans', '', 7);
$this->MultiCell(0,4,utf8_decode(html_entity_decode('Tout retard de paiement entraînera de plein droit une pénalité de retard de 3 fois le taux légal ')));
$this->MultiCell(0,4,utf8_decode(html_entity_decode('(Loi 2008-776 du 4 août 2008) et une indemnité forfaitaire de 40 EUR pour frais de recouvrement sera appliquée.')));
$this->MultiCell(0, 4, utf8_decode(html_entity_decode('Tout retard de paiement entraînera de plein droit une pénalité de retard de 3 fois le taux légal ')));
$this->MultiCell(0, 4, utf8_decode(html_entity_decode('(Loi 2008-776 du 4 août 2008) et une indemnité forfaitaire de 40 EUR pour frais de recouvrement sera appliquée.')));
$this->Ln(1);
$this->MultiCell(0,4,utf8_decode(html_entity_decode('Si les frais de recouvrement sont supérieurs à ce montant forfaitaire, une indemnisation complémentaire')));
$this->MultiCell(0,4,utf8_decode(html_entity_decode('sera due sur présentation de justificatifs (articles L.441-3 et L.441-6 du code de commerce).')));
$this->MultiCell(0, 4, utf8_decode(html_entity_decode('Si les frais de recouvrement sont supérieurs à ce montant forfaitaire, une indemnisation complémentaire')));
$this->MultiCell(0, 4, utf8_decode(html_entity_decode('sera due sur présentation de justificatifs (articles L.441-3 et L.441-6 du code de commerce).')));
$this->SetY(-10);
$this->SetFont('ComicSans', '', 7);
@ -172,13 +171,13 @@ class InvoicePdfHandler extends FPDF
$addressWidth = $this->GetStringWidth($address);
$addressWidthGreaterThanMaxWidth = $addressWidth > $availableWidhtForClientInfo;
$addressIsMoreThanTwoLines = ($addressWidth / $availableWidhtForClientInfo) > 2;
$clientInfoYAxis = $addressIsMoreThanTwoLines ? 35 : 35;// the old is ? 35 : 39 but not working
$this->SetXY($clientInfoXAxis, $clientInfoYAxis);
$this->Cell(0, $this->interLigneHeader, FileExportHelpers::FormatTextForExport($clientName));
$clientInfoYAxis += $this->interLigneHeader;
$clientAddresses = explode(",", $clientAddress);
foreach ($clientAddresses as $address) {
foreach ($clientAddresses as $address) {
$address = FileExportHelpers::FormatTextForExport(trim($address));
$addressWidth = $this->GetStringWidth($address);
$addressWidthGreaterThanMaxWidth = $addressWidth > $availableWidhtForClientInfo;
@ -204,7 +203,7 @@ class InvoicePdfHandler extends FPDF
$this->Cell(0, $this->interLigneHeader, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_adress_city'])));
$clientInfoYAxis += $this->interLigneHeader;
$this->SetXY($clientInfoXAxis, $clientInfoYAxis);
$this->Cell(0, $this->interLigneHeader,'Siret: ' . $this->factureData['siret']);
$this->Cell(0, $this->interLigneHeader, 'Siret: ' . $this->factureData['siret']);
$clientInfoYAxis += $this->interLigneHeader;
$this->SetXY($clientInfoXAxis, $clientInfoYAxis);
$this->Cell(0, $this->interLigneHeader, FileExportHelpers::FormatTextForExport('Mail : ') . $this->factureData['client_mail']);
@ -234,7 +233,7 @@ class InvoicePdfHandler extends FPDF
$this->Cell(39, 7, 'FACTURE', 1, 0, 'C');
$this->Cell(36, 7, 'ECHEANCE', 1, 1, 'C');
$this->SetFont('ComicSans', '', 10);
$this->Cell(25, 7, $factureDatePaiement, 1, 0, 'C');
$this->Cell(104, 7, utf8_decode(html_entity_decode($this->factureData['client_nom'])), 1, 0, 'C');
@ -268,36 +267,37 @@ class InvoicePdfHandler extends FPDF
$this->SetLineWidth(0.2);
$gapBetweenStartingOfArticlesTableAndColumnName = 8;
$tableHeight = $this->thereIsOrderOrCaseNumber ? $this->articleTablesHeight : $this->articleTablesHeight + 9;
$this->Rect(3, $this->startingYOfArticlesTable , 204, $tableHeight, "D");
$this->Rect(3, $this->startingYOfArticlesTable, 204, $tableHeight, "D");
// cadre titre des colonnes
$this->Line(3, $this->startingYOfArticlesTable + $gapBetweenStartingOfArticlesTableAndColumnName, 207, $this->startingYOfArticlesTable + $gapBetweenStartingOfArticlesTableAndColumnName);
// les traits verticaux colonnes
$additionalMargRight = 1;
$endingLine = $this->thereIsOrderOrCaseNumber ? 231 : 230; // mois +1 pour le groupe
$this->Line(27 + $additionalMargRight, $this->startingYOfArticlesTable, 27+ $additionalMargRight , $endingLine);
$this->Line(142 + $additionalMargRight, $this->startingYOfArticlesTable, 142+ $additionalMargRight , $endingLine);
$this->Line(164 + $additionalMargRight, $this->startingYOfArticlesTable, 164+ $additionalMargRight , $endingLine);
$this->Line(182 + $additionalMargRight, $this->startingYOfArticlesTable, 182+ $additionalMargRight , $endingLine);
$endingLine = $this->thereIsOrderOrCaseNumber ? 231 : 230; // mois +1 pour le groupe
$this->Line(27 + $additionalMargRight, $this->startingYOfArticlesTable, 27 + $additionalMargRight, $endingLine);
$this->Line(142 + $additionalMargRight, $this->startingYOfArticlesTable, 142 + $additionalMargRight, $endingLine);
$this->Line(164 + $additionalMargRight, $this->startingYOfArticlesTable, 164 + $additionalMargRight, $endingLine);
$this->Line(182 + $additionalMargRight, $this->startingYOfArticlesTable, 182 + $additionalMargRight, $endingLine);
}
private function DrawArticlesTableHeader()
{
$additionalMargRight = 1;
$tvaValue = $this->factureData["configuration"]->tva_default;
$tvaDefault = $this->factureData["configuration"]->tva_default;
$clientTvaStatus = isset($this->factureData["tva"]) ? (int)$this->factureData["tva"] : 1;
// Déterminer le libellé TVA selon le statut du client
$tvaLabel = ($clientTvaStatus === 0) ? "TVA 0%" : "TVA " . $tvaDefault . "%";
$columnNameY = $this->startingYOfArticlesTable - 1;
$this->SetFont('ComicSans', '', 10);
$this->SetXY(12 + $additionalMargRight, $columnNameY);
$this->Cell(7, 10, "Date", 0, 0, 'C');
$this->SetXY(30 + $additionalMargRight, $columnNameY);
$this->Cell(100, 10, "Description", 0, 0, 'C');
$this->SetXY(143 + $additionalMargRight, $columnNameY);
$this->Cell(20, 10, "Prix Uni. HT", 0, 0, 'C');
$this->SetXY(163 + $additionalMargRight, $columnNameY);
$this->Cell(20, 10, 'TVA ' . $tvaValue . '%', 0, 0, 'C');
$this->Cell(20, 10, $tvaLabel, 0, 0, 'C');
$this->SetXY(185, $columnNameY);
$this->Cell(20, 10, "Prix Uni. TTC", 0, 0, 'C');
}
@ -308,49 +308,62 @@ class InvoicePdfHandler extends FPDF
$devisDate = $this->factureData['devis_date'];
$devisDate = DateTime::createFromFormat('Y-m-d', $devisDate);
$devisDate = $devisDate->format('d-m-Y');
$tvaValue = $this->factureData["configuration"]->tva_default;
$tvaDefault = $this->factureData["configuration"]->tva_default;
$clientTvaStatus = isset($this->factureData["tva"]) ? (int)$this->factureData["tva"] : 1;
// Déterminer le taux de TVA à appliquer selon le statut du client
$tvaValue = ($clientTvaStatus === 0) ? 0 : $tvaDefault;
$tvaLabel = ($clientTvaStatus === 0) ? "0%" : $tvaDefault . "%";
$totalHt = 0;
$totalTtc = 0;
$totalTva = 0;
$products = $this->factureData["products"];
$yValue = $this->startingYOfArticlesTable + 13;
$maxDescriptionWidth = 102;
foreach ($products as $product) {
foreach ($products as $product) {
$valueHt = $product['produit_price'] * $product['quantite'];
$valueTtc = PriceHelpers::calculPriceWithVatValue($valueHt, $tvaValue);
// Calculer la TVA selon le statut du client
if ($clientTvaStatus === 0) {
// Client exonéré - pas de TVA
$valueTtc = $valueHt;
$tvaAmount = 0;
} else {
// Client soumis à la TVA - utiliser le calcul normal
$valueTtc = PriceHelpers::calculPriceWithVatValue($valueHt, $tvaValue);
$tvaAmount = $valueTtc - $valueHt;
}
$totalHt += $valueHt;
$totalTtc += $valueTtc;
$totalTva += $tvaAmount;
$productDescription = $product["produit_description"];
$dateValue = "";
if ($product === end($products)) {
$dateValue = $devisDate;
$productDescription .= " de " . FileExportHelpers::GetSexeLabel($this->factureData['defunt_sexe']) . ' ' . $this->factureData["defunt_nom"];
}
$tvaAmount = $valueTtc - $valueHt;
$this->SetXY(5, $yValue);
$this->Cell(5, 6, $dateValue, 0, 0);
$this->SetXY(30, $yValue);
$this->MultiAlignCell($maxDescriptionWidth , 6, utf8_decode(html_entity_decode($productDescription)), 0, '0',);
$this->MultiAlignCell($maxDescriptionWidth, 6, utf8_decode(html_entity_decode($productDescription)), 0, '0', );
$this->SetXY(144, $yValue);
$this->Cell(20, 6, number_format($valueHt, 2, '.', '') . chr(128), 0, 0, 'C');
$this->SetXY(165, $yValue);
$this->Cell(20, 6, number_format($tvaAmount, 2, '.', '') . chr(128), 0, 0, 'C');
$this->SetXY(182, $yValue);
$this->Cell(25, 6, number_format($valueTtc, 2, '.', '') . chr(128), 0, 1, 'C');
$yValue += 12;
$totalTva += $tvaAmount;
}
return [
"TOTAL HT" => $totalHt,
"TVA " . $tvaValue . "%" => $totalTva,
"TVA " . $tvaLabel => $totalTva,
"TOTAL TTC" => $totalTtc
];
}
@ -358,13 +371,13 @@ class InvoicePdfHandler extends FPDF
private function DrawBankAndTotalPriceInfo($totalPriceArray)
{
$startOfYAfterMainTable = 236;
$this->SetY( $startOfYAfterMainTable);
$this->SetY($startOfYAfterMainTable);
$this->SetFont('ComicSans', '', 8);
$this->MultiCell(0,4,utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de ". $this->factureData['configuration']->entreprise)));
$this->MultiCell(0,4,utf8_decode(html_entity_decode("en indiquant le numéro de facture, ou par virement :")));
$this->MultiCell(0, 4, utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de " . $this->factureData['configuration']->entreprise)));
$this->MultiCell(0, 4, utf8_decode(html_entity_decode("en indiquant le numéro de facture, ou par virement :")));
$this->Ln(1);
$startOftable = 3 ;
$startOftable = 3;
$this->SetX($startOftable);
// Table IBAN
$this->SetFont('ComicSans', '', 8);
@ -372,7 +385,7 @@ class InvoicePdfHandler extends FPDF
$this->Cell($ibanWidth, 6.5, 'IBAN : FR76 1360 6000 1436 5418 1800 038', 1, 1, 'C');
$this->SetX($startOftable);
$this->Cell($ibanWidth, 6.5, 'Code SWIFT : AGRI FR PP 836', 1, 1, 'C');
//TABLE HT
$tableWidth = 48; // Largeur totale de la 2e table (20+20)
$marginRight = 3; // Marge par rapport au bord droit
@ -380,15 +393,15 @@ class InvoicePdfHandler extends FPDF
// Position correcte de la 2e table
$startOfArrayX = $pageWidth - $tableWidth - $marginRight;
$startOfArrayY = $startOfYAfterMainTable + 0.5;
$startOfArrayY = $startOfYAfterMainTable + 0.5;
$this->SetFont('ComicSans', '', 10);
foreach($totalPriceArray as $label => $price){
$this->SetXY($startOfArrayX,$startOfArrayY);
foreach ($totalPriceArray as $label => $price) {
$this->SetXY($startOfArrayX, $startOfArrayY);
$this->Cell(24, 6.5, $label, 1, 1, 'C');
$this->SetXY($startOfArrayX + 24,$startOfArrayY);
$this->Cell(24, 6.5, number_format($price,2,'.','').chr(128), 1, 1, 'C');
$this->SetXY($startOfArrayX + 24, $startOfArrayY);
$this->Cell(24, 6.5, number_format($price, 2, '.', '') . chr(128), 1, 1, 'C');
$startOfArrayY += 6.5;
}
}
@ -413,7 +426,7 @@ class InvoicePdfHandler extends FPDF
$this->DrawBankAndTotalPriceInfo($totalPriceValue);
}
function MultiAlignCell($w, $h, $text, $border = 0, $ln = 0, $align = 'L', $fill = false)
public function MultiAlignCell($w, $h, $text, $border = 0, $ln = 0, $align = 'L', $fill = false)
{
// Store reset values for (x,y) positions
$x = $this->GetX() + $w;
@ -428,19 +441,22 @@ class InvoicePdfHandler extends FPDF
}
}
function NbLines($w, $txt)
public function NbLines($w, $txt)
{
// Compute the number of lines a MultiCell of width w will take
if (!isset($this->CurrentFont))
if (!isset($this->CurrentFont)) {
$this->Error('No font has been set');
}
$cw = $this->CurrentFont['cw'];
if ($w == 0)
if ($w == 0) {
$w = $this->w - $this->rMargin - $this->x;
}
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
$s = str_replace("\r", '', (string)$txt);
$s = str_replace("\r", '', (string) $txt);
$nb = strlen($s);
if ($nb > 0 && $s[$nb - 1] == "\n")
if ($nb > 0 && $s[$nb - 1] == "\n") {
$nb--;
}
$sep = -1;
$i = 0;
$j = 0;
@ -456,21 +472,25 @@ class InvoicePdfHandler extends FPDF
$nl++;
continue;
}
if ($c == ' ')
if ($c == ' ') {
$sep = $i;
}
$l += $cw[$c];
if ($l > $wmax) {
if ($sep == -1) {
if ($i == $j)
if ($i == $j) {
$i++;
} else
}
} else {
$i = $sep + 1;
}
$sep = -1;
$j = $i;
$l = 0;
$nl++;
} else
} else {
$i++;
}
}
return $nl;
}

View File

@ -41,77 +41,79 @@ use OCA\Gestion\Service\InvoiceRecap\InvoiceRecapService;
use OCP\DB\Exception;
use OCP\Files\IRootFolder;
class InvoicePdfService {
/** @var Bdd */
private $gestionBdd;
class InvoicePdfService
{
/** @var Bdd */
private $gestionBdd;
/** @var IRootFolder */
private $rootFolder;
private $rootFolder;
/** @var InvoiceRecapService */
private $invoiceRecapService;
private $invoiceRecapService;
private const DEFAULT_NEXTCLOUD_ADMIN = "admin";
public function __construct(
Bdd $gestionBdd,
public function __construct(
Bdd $gestionBdd,
IRootFolder $rootFolder,
InvoiceRecapService $invoiceRecapService) {
InvoiceRecapService $invoiceRecapService
) {
$this->gestionBdd = $gestionBdd;
$this->rootFolder = $rootFolder;
$this->invoiceRecapService = $invoiceRecapService;
}
}
private function getLogo(){
private function getLogo()
{
$storage = $this->rootFolder->getUserFolder(self::DEFAULT_NEXTCLOUD_ADMIN);
try{
try {
if(isset($storage)){
$file = $storage->get('/.gestion/logo.png');
}else{
return "nothing";
}
} catch(\OCP\Files\NotFoundException $e) {
$file = $storage->get('/.gestion/logo.jpeg');
}
}
catch(\OCP\Files\NotFoundException $e) {
return "nothing";
}
try {
try {
if(isset($storage)) {
$file = $storage->get('/.gestion/logo.png');
} else {
return "nothing";
}
} catch(\OCP\Files\NotFoundException $e) {
$file = $storage->get('/.gestion/logo.jpeg');
}
} catch(\OCP\Files\NotFoundException $e) {
return "nothing";
}
return base64_encode($file->getContent());
}
return base64_encode($file->getContent());
}
private function generateFactureSinglePdfByFactureId($factureId,$idNextCloud){
private function generateFactureSinglePdfByFactureId($factureId, $idNextCloud)
{
$storage = $this->rootFolder->getUserFolder($idNextCloud);
$configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN));
$currentConfig = $configs[0];
$logo = $this->getLogo();
$invoicePdfData = $this->gestionBdd->getInvoicePdfData($factureId,$currentConfig);
if($invoicePdfData == null){
return null;
}
$currentConfig = $configs[0];
$logo = $this->getLogo();
$invoicePdfData = $this->gestionBdd->getInvoicePdfData($factureId, $currentConfig);
if($invoicePdfData == null) {
return null;
}
$clean_folder = html_entity_decode(string: $currentConfig->path).'/';
$factureFolders = $this->getFacturesFolder($invoicePdfData,$clean_folder);
$factureFolders = $this->getFacturesFolder($invoicePdfData, $clean_folder);
$pdf = new InvoicePdfHandler();
$pdf->AddFont('ComicSans','','Comic Sans MS.php');
$pdf->AddFont('ComicSans','B','comic-sans-bold.php');
$pdf->InvoicePdfFactory($invoicePdfData,$logo);
$pdf->AddFont('ComicSans', '', 'Comic Sans MS.php');
$pdf->AddFont('ComicSans', 'B', 'comic-sans-bold.php');
$pdf->InvoicePdfFactory($invoicePdfData, $logo);
$pdf->SetFactureContent();
$pdfContent = $pdf->Output('','S');
$pdfContent = $pdf->Output('', 'S');
$pdfFilename = $pdf->GetInvoiceFilename();
$prefixPdf = "FACTURE";
if($invoicePdfData['is_negative']){
if($invoicePdfData['is_negative']) {
$prefixPdf = "AVOIR";
}
$pdfFilename = $prefixPdf."_".$pdfFilename;
$filenames = [];
foreach($factureFolders as $folder){
foreach($factureFolders as $folder) {
try {
$storage->newFolder($folder);
}
catch(\OCP\Files\NotPermittedException $e) {
} catch(\OCP\Files\NotPermittedException $e) {
}
$ff_pdf = $folder.$pdfFilename.'.pdf';
$ff_pdf = $folder.$pdfFilename.'.pdf';
$storage->newFile($ff_pdf);
$file_pdf = $storage->get($ff_pdf);
$file_pdf->putContent($pdfContent);
@ -124,18 +126,19 @@ class InvoicePdfService {
];
}
public function generateFacturePdfByFactureId($factureId,$idNextCloud){
public function generateFacturePdfByFactureId($factureId, $idNextCloud)
{
$factureType = $this->gestionBdd->getFactureTypeByFactureId($factureId);
if($factureType == FactureTypeConstant::TYPE_SINGLE){
return $this->generateFactureSinglePdfByFactureId($factureId,$idNextCloud);
}
else{
return $this->generateFactureGroupPdfByFactureId($factureId,$idNextCloud);
if($factureType == FactureTypeConstant::TYPE_SINGLE) {
return $this->generateFactureSinglePdfByFactureId($factureId, $idNextCloud);
} else {
return $this->generateFactureGroupPdfByFactureId($factureId, $idNextCloud);
}
}
private function getGroupFactureFolder(array $factureData,$racinePath){
$clientRacineFolder = $racinePath.'CLIENTS/'.mb_strtoupper($factureData["group_name"],'UTF-8').'/';
private function getGroupFactureFolder(array $factureData, $racinePath)
{
$clientRacineFolder = $racinePath.'CLIENTS/'.mb_strtoupper($factureData["group_name"], 'UTF-8').'/';
$factureDate = $factureData['date_paiement'];
$factureDatetime = new DateTime($factureDate);
$factureDateYear = $factureDatetime->format('Y');
@ -145,10 +148,11 @@ class InvoicePdfService {
$factureByYearFolder
];
}
private function getFacturesFolder(array $factureData,$racinePath){
$clientRacineFolder = $racinePath.'CLIENTS/'.mb_strtoupper($factureData["client_nom"],'UTF-8').'/';
$defuntsFolder = $clientRacineFolder.'DEFUNTS/'.mb_strtoupper($factureData['defunt_nom'],'UTF-8').'/'.'FACTURES'.'/';
private function getFacturesFolder(array $factureData, $racinePath)
{
$clientRacineFolder = $racinePath.'CLIENTS/'.mb_strtoupper($factureData["client_nom"], 'UTF-8').'/';
$defuntsFolder = $clientRacineFolder.'DEFUNTS/'.mb_strtoupper($factureData['defunt_nom'], 'UTF-8').'/'.'FACTURES'.'/';
$devisDate = $factureData['devis_date'];
$devisDatetime = new DateTime($devisDate);
$devisDateYear = $devisDatetime->format('Y');
@ -160,48 +164,48 @@ class InvoicePdfService {
];
}
private function generateFactureGroupPdfByFactureId($factureId,$idNextCloud){
private function generateFactureGroupPdfByFactureId($factureId, $idNextCloud)
{
$storage = $this->rootFolder->getUserFolder($idNextCloud);
$configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN));
$currentConfig = $configs[0];
$logo = $this->getLogo();
$invoicePdfData = $this->gestionBdd->getInvoiceGroupPdfData($factureId,$currentConfig);
if($invoicePdfData == null){
return "";
}
$currentConfig = $configs[0];
$logo = $this->getLogo();
$invoicePdfData = $this->gestionBdd->getInvoiceGroupPdfData($factureId, $currentConfig);
if($invoicePdfData == null) {
return "";
}
$templateType = $invoicePdfData['template_type_key'];
$clean_folder = html_entity_decode(string: $currentConfig->path).'/';
$factureFolders = $this->getGroupFactureFolder($invoicePdfData,$clean_folder);
//For testing
$factureFolders = $this->getGroupFactureFolder($invoicePdfData, $clean_folder);
//For testing
// $templateType = ClientTemplateTypeConstant::OGF;
switch ($templateType) {
case ClientTemplateTypeConstant::FUNECAP:
$pdf = new InvoiceFunecapPdfHandler();
break;
case ClientTemplateTypeConstant::OGF:
$pdf = new InvoiceOgfPdfHandler();
break;
default:
$pdf = new InvoiceGroupPdfHandler();
break;
}
$pdf->AddFont('ComicSans','','Comic Sans MS.php');
$pdf->AddFont('ComicSans','B','comic-sans-bold.php');
$pdf->InvoicePdfFactory($invoicePdfData,$logo);
$pdf->AddFont('ComicSans', '', 'Comic Sans MS.php');
$pdf->AddFont('ComicSans', 'B', 'comic-sans-bold.php');
$pdf->InvoicePdfFactory($invoicePdfData, $logo);
$pdf->SetFactureContent();
$pdfContent = $pdf->Output('','S');
$pdfContent = $pdf->Output('', 'S');
$pdfFilename = $pdf->GetInvoiceFilename();
$filenames = [];
foreach($factureFolders as $folder){
foreach($factureFolders as $folder) {
try {
$storage->newFolder($folder);
}
catch(\OCP\Files\NotPermittedException $e) {
} catch(\OCP\Files\NotPermittedException $e) {
}
$ff_pdf = $folder.$pdfFilename.'.pdf';
$ff_pdf = $folder.$pdfFilename.'.pdf';
$storage->newFile($ff_pdf);
$file_pdf = $storage->get($ff_pdf);
$file_pdf->putContent($pdfContent);
@ -214,58 +218,61 @@ class InvoicePdfService {
];
}
public function generateFacturePdfByFactureIds(array $factureIds,$idNextCloud){
foreach( $factureIds as $factureId ){
$this->generateFacturePdfByFactureId($factureId,$idNextCloud);
public function generateFacturePdfByFactureIds(array $factureIds, $idNextCloud)
{
foreach($factureIds as $factureId) {
$this->generateFacturePdfByFactureId($factureId, $idNextCloud);
}
}
public function generateMultipleInvoicePdfByClientAndMonthYear($filter,$month,$year,$idNextCloud,$filterType){
public function generateMultipleInvoicePdfByClientAndMonthYear($filter, $month, $year, $idNextCloud, $filterType)
{
$storage = $this->rootFolder->getUserFolder($idNextCloud);
$configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN));
$currentConfig = $configs[0];
$currentConfig = $configs[0];
$logo = $this->getLogo();
$invoiceData = $this->gestionBdd->getInvoicePdfDataByClientAndMonthYear($filter,$month,$year,$currentConfig,$filterType);
if(empty($invoiceData)){
return null;
}
$invoiceData = $this->gestionBdd->getInvoicePdfDataByClientAndMonthYear($filter, $month, $year, $currentConfig, $filterType);
if(empty($invoiceData)) {
return null;
}
$pdf = new InvoicePdfHandler();
$pdf->AddFont('ComicSans','','Comic Sans MS.php');
$pdf->AddFont('ComicSans','B','comic-sans-bold.php');
$pdf->MutlipleInvoicePdfFactory($invoiceData,$logo);
$pdf->AddFont('ComicSans', '', 'Comic Sans MS.php');
$pdf->AddFont('ComicSans', 'B', 'comic-sans-bold.php');
$pdf->MutlipleInvoicePdfFactory($invoiceData, $logo);
$pdf->SetMultipleFactureContent();
$racinePath = html_entity_decode(string: $currentConfig->path).'/';
$clientNameInFolder = $invoiceData[0]["client_nom"];
if($invoiceData[0]['facture_type'] == MultipleFactureTypeConstant::GROUP_FILTER_TYPE){
if($invoiceData[0]["group_name"] != null && $invoiceData[0]["group_name"] != ""){
if($invoiceData[0]['facture_type'] == MultipleFactureTypeConstant::GROUP_FILTER_TYPE) {
if($invoiceData[0]["group_name"] != null && $invoiceData[0]["group_name"] != "") {
$clientNameInFolder = $invoiceData[0]["group_name"];
}
}
$clientRacineFolder = $racinePath.'CLIENTS/'.mb_strtoupper($clientNameInFolder,'UTF-8').'/';
$filename = "FACTURE".'_'.$pdf->GetMultipleInvoiceFilename($month,$year);
$clientRacineFolder = $racinePath.'CLIENTS/'.mb_strtoupper($clientNameInFolder, 'UTF-8').'/';
$filename = "FACTURE".'_'.$pdf->GetMultipleInvoiceFilename($month, $year);
$filenamePath = $clientRacineFolder.$filename.'.pdf';
$pdfContent = $pdf->Output('','S');
$pdfContent = $pdf->Output('', 'S');
try {
$storage->newFolder($clientRacineFolder);
}
catch(\OCP\Files\NotPermittedException $e) {
}
} catch(\OCP\Files\NotPermittedException $e) {
}
$storage->newFile($filenamePath);
$file_pdf = $storage->get($filenamePath);
$file_pdf->putContent($pdfContent);
return $filenamePath;
}
public function generateInvoiceRecap($filter,$filterType,$date,$idNextCloud){
$this->invoiceRecapService->generateInvoiceRecap($filter,$filterType,$date,$idNextCloud);
public function generateInvoiceRecap($filter, $filterType, $date, $idNextCloud)
{
$this->invoiceRecapService->generateInvoiceRecap($filter, $filterType, $date, $idNextCloud);
}
public function exportGroupOfDevisIntoFacture($clientId,$clientType,$month,$year,$facturationDate,$idNextcloud = BddConstant::DEFAULT_ADMIN_ID_NEXTCLOUD){
try{
public function exportGroupOfDevisIntoFacture($clientId, $clientType, $month, $year, $facturationDate, $idNextcloud = BddConstant::DEFAULT_ADMIN_ID_NEXTCLOUD)
{
try {
$datetime = new Datetime();
$month = $month ?? $datetime->format('m');
$year = $year ?? $datetime->format('Y');
$factureId = null;
$fkClientId = null;
$fkClientGroupFacturationId = null;
@ -274,22 +281,22 @@ class InvoicePdfService {
DevisMentionConstant::MENTION
];
// Recuperer les devis non facturés du client avant la date de facturation du mois
//Si il a devis qui n est pas encore facturés
//Si il a devis qui n est pas encore facturés
//Cree un facture, atttaché l ID du facture au devis et generer le pdf
if($clientType == MultipleFactureTypeConstant::CLIENT_FILTER_TYPE){
$devisIds = $this->gestionBdd->getDevisIdsByClientIdAndDate($clientId,$facturationDate,$devisMentionFiltersToBeInvoiced);
if($clientType == MultipleFactureTypeConstant::CLIENT_FILTER_TYPE) {
$devisIds = $this->gestionBdd->getDevisIdsByClientIdAndDate($clientId, $facturationDate, $devisMentionFiltersToBeInvoiced);
$fkClientId = $clientId;
$factureId = $this->gestionBdd->getFactureIdByClientIdAndDate($clientId,$facturationDate);
$factureId = $this->gestionBdd->getFactureIdByClientIdAndDate($clientId, $facturationDate);
}else{
$devisIds = $this->gestionBdd->getDevisIdsByClientGroupFacturationIdAnDate($clientId , $facturationDate , $devisMentionFiltersToBeInvoiced );
} else {
$devisIds = $this->gestionBdd->getDevisIdsByClientGroupFacturationIdAnDate($clientId, $facturationDate, $devisMentionFiltersToBeInvoiced);
$fkClientGroupFacturationId = $clientId;
$factureId = $this->gestionBdd->getFactureIdByClientGroupFacturationIdAndDate($clientId,$facturationDate);
$factureId = $this->gestionBdd->getFactureIdByClientGroupFacturationIdAndDate($clientId, $facturationDate);
}
// if($clientType == MultipleFactureTypeConstant::CLIENT_FILTER_TYPE){
// $devisIds = $this->gestionBdd->getDevisIdsByClientIdAndMonthYear($clientId,$month,$year,$devisMentionFiltersToBeInvoiced);
// $devisIds = $this->gestionBdd->getDevisIdsByClientIdAndMonthYear($clientId,$month,$year,$devisMentionFiltersToBeInvoiced);
// $fkClientId = $clientId;
// }
// else{
@ -307,11 +314,11 @@ class InvoicePdfService {
// $fkClientId,
// $fkClientGroupFacturationId);
// }
if (!empty($devisIds)) {
//Get facture by date and client
$clientIsAlreadyFacturedForThisDate = $factureId != null && $factureId != 0;
if (!$clientIsAlreadyFacturedForThisDate) {
$clientIsAlreadyFacturedForThisDate = $factureId != null && $factureId != 0;
if (!$clientIsAlreadyFacturedForThisDate) {
$factureId = $this->gestionBdd->createFactureAndReturnFactureId(
$facturationDate,
FactureTypeConstant::TYPE_GROUP,
@ -320,16 +327,15 @@ class InvoicePdfService {
$fkClientId,
$fkClientGroupFacturationId
);
}
$this->gestionBdd->invoiceListOfDevisIds($devisIds , $factureId);
$factureGeneratedResponse = $this->generateFactureGroupPdfByFactureId($factureId,$idNextcloud);
}
$this->gestionBdd->invoiceListOfDevisIds($devisIds, $factureId);
$factureGeneratedResponse = $this->generateFactureGroupPdfByFactureId($factureId, $idNextcloud);
return $factureGeneratedResponse["filenames"];
}
return null;
}
catch(Exception){
} catch(Exception) {
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,7 @@ class MailerService {
if (!$signatureImage) {
return "";
}
return "<img style= 'width: 250px;height: 150px;' src='data:image/jpeg;base64,".base64_encode($signatureImage)."'>" ;
return "<img width='170' height='80' style= 'width: 170;height: 80px;display:block;' src='data:image/jpeg;base64,".base64_encode($signatureImage)."'>" ;
}
private function getSignatureContent(){

View File

@ -215,13 +215,45 @@ export function getGlobal(id_devis) {
})
}).done((function (res) {
var myresp = JSON.parse(response)[0];
var total = JSON.parse(res).total;
var tva = parseFloat(myresp.tva_default);
var devisData = JSON.parse(res);
var total = devisData.total;
var clientTvaStatus = devisData.client_tva_status;
// S'assurer que total est un nombre
total = parseFloat(total);
clientTvaStatus = parseInt(clientTvaStatus);
var tvaDefault = parseFloat(myresp.tva_default);
$('#totaldevis tbody').empty();
$('#totaldevis tbody').append('<tr><td>' + cur.format(total) + '</td><td id="tva">' + tva + ' %</td><td id="totaltva">' + cur.format(Math.round((total * tva)) / 100) + '</td><td>' + cur.format(Math.round((total * (tva + 100))) / 100) + '</td></tr>');
if (clientTvaStatus === 0) {
// Client exonéré de TVA - TVA = 0%
$('#totaldevis tbody').append(
'<tr>' +
'<td>' + cur.format(total) + '</td>' +
'<td id="tva">0 %</td>' +
'<td id="totaltva">' + cur.format(0) + '</td>' +
'<td>' + cur.format(total) + '</td>' +
'</tr>'
);
} else {
// Client soumis à la TVA - utiliser le taux par défaut
var montantTva = Math.round((total * tvaDefault)) / 100;
var totalTTC = Math.round((total * (tvaDefault + 100))) / 100;
$('#totaldevis tbody').append(
'<tr>' +
'<td>' + cur.format(total) + '</td>' +
'<td id="tva">' + tvaDefault + ' %</td>' +
'<td id="totaltva">' + cur.format(montantTva) + '</td>' +
'<td>' + cur.format(totalTTC) + '</td>' +
'</tr>'
);
}
$('#mentions_default').html(myresp.mentions_default);
}));
})
});
}
export function getGlobalPromise() {

View File

@ -10,15 +10,18 @@ export class Client {
*/
constructor(myresp) {
this.id = myresp.id;
this.entreprise = ((myresp.entreprise.length === 0) ? '-' : myresp.entreprise);
this.prenom = ((myresp.prenom.length === 0) ? '-' : myresp.prenom);
this.nom = ((myresp.nom.length === 0) ? '-' : myresp.nom);
this.legal_one = ((myresp.legal_one.length === 0) ? '-' : myresp.legal_one);
this.telephone = ((myresp.telephone.length === 0) ? '-' : myresp.telephone);
this.mail = ((myresp.mail.length === 0) ? '-' : myresp.mail);
this.adresse = ((myresp.adresse.length === 0) ? '-' : myresp.adresse);
this.clientGroupName = ((myresp.client_group_name.length === 0) ? '-' : myresp.client_group_name);
this.clientGroupFacturationName = ((myresp.client_group_facturation_name.length === 0) ? '-' : myresp.client_group_facturation_name);
this.code_comptable = ((myresp.code_comptable && myresp.code_comptable.length > 0) ? myresp.code_comptable : '-'); // AJOUTÉ
this.agence = ((myresp.agence && myresp.agence.length > 0) ? myresp.agence : '-'); // AJOUTÉ
this.entreprise = ((myresp.entreprise && myresp.entreprise.length > 0) ? myresp.entreprise : '-');
this.prenom = ((myresp.prenom && myresp.prenom.length > 0) ? myresp.prenom : '-');
this.nom = ((myresp.nom && myresp.nom.length > 0) ? myresp.nom : '-');
this.legal_one = ((myresp.legal_one && myresp.legal_one.length > 0) ? myresp.legal_one : '-');
this.telephone = ((myresp.telephone && myresp.telephone.length > 0) ? myresp.telephone : '-');
this.mail = ((myresp.mail && myresp.mail.length > 0) ? myresp.mail : '-');
this.adresse = ((myresp.adresse && myresp.adresse.length > 0) ? myresp.adresse : '-');
this.is_tva = myresp.is_tva !== undefined && myresp.is_tva !== null ? myresp.is_tva : 0;
this.clientGroupName = ((myresp.client_group_name && myresp.client_group_name.length > 0) ? myresp.client_group_name : '-');
this.clientGroupFacturationName = ((myresp.client_group_facturation_name && myresp.client_group_facturation_name.length > 0) ? myresp.client_group_facturation_name : '-');
let clientGroupId = 0;
if(myresp.fk_client_group_id != null && myresp.fk_client_group_id.length > 0){
@ -40,17 +43,21 @@ export class Client {
let myrow = [
'<input class="clientToExport" data-id= '+ this.id + ' type="checkbox" name="clientToExport" value="' + this.id + '"/>',
'<div>' + this.id + '</div>',
'<div class="editable" data-table="client" data-column="entreprise" data-id="' + this.id + '">' + this.entreprise + '</div>',
'<div class="editable" data-table="client" data-column="code_comptable" data-id="' + this.id + '">' + this.code_comptable + '</div>',
'<div class="editable" data-table="client" data-column="agence" data-id="' + this.id + '">' + this.agence + '</div>',
'<div class="editable" data-table="client" data-column="prenom" data-id="' + this.id + '">' + this.prenom + '</div>',
'<div class="editable" data-table="client" data-column="nom" data-id="' + this.id + '">' + this.nom + '</div>',
'<div class="editable" data-table="client" data-column="entreprise" data-id="' + this.id + '">' + this.entreprise + '</div>',
'<div class="editable" data-table="client" data-column="legal_one" data-id="' + this.id + '">' + this.legal_one + '</div>',
'<div class="editable" data-table="client" data-column="telephone" data-id="' + this.id + '">' + this.telephone + '</div>',
'<div class="editable" data-table="client" data-column="mail" data-id="' + this.id + '">' + this.mail + '</div>',
'<div class="editable" data-table="client" data-column="adresse" data-id="' + this.id + '">' + this.adresse + '</div>',
'<div><input type="checkbox" class="gestion-checkbox" data-table="client" data-column="is_tva" data-id="' + this.id + '" ' + (this.is_tva == 1 || this.is_tva == true ? 'checked' : '') + ' /></div>',
'<div class="selectClientGroupList" data-table="client" data-column="fk_client_group_id" data-id="' + this.id + '" data-current="' + this.clientGroupId + '">' + this.clientGroupName + '</div>',
'<div class="selectClientGroupFacturationList" data-table="client" data-column="fk_client_group_facturation_id" data-id="' + this.id + '" data-current="' + this.clientGroupFacturationId + '">' + this.clientGroupFacturationName + '</div>',
'<center><div data-modifier="client" data-id=' + this.id + ' data-table="client" style="display:inline-block;margin-right:0px;" class="deleteItem icon-delete"></div></center>'
'<div><center><div data-modifier="client" data-id=' + this.id + ' data-table="client" style="display:inline-block;margin-right:0px;" class="deleteItem icon-delete"></div></center></div>' // MODIFIÉ
];
return myrow;
}
@ -82,7 +89,8 @@ export class Client {
oReq.setRequestHeader("Content-Type", "application/json");
oReq.onload = function(e){
if (this.status == 200) {
LoadDT(clientDT, JSON.parse(this.response), Client);
const data = JSON.parse(this.response);
LoadDT(clientDT, data, Client);
}else{
showError(this.response);
}
@ -100,13 +108,14 @@ export class Client {
oReq.setRequestHeader("Content-Type", "application/json");
oReq.onload = function(e){
if (this.status == 200) {
callback(JSON.parse(this.response));
const data = JSON.parse(this.response);
callback(data);
}else{
showError(this.response);
}
};
oReq.send();
}
}
/**
*
@ -196,4 +205,4 @@ export class Client {
});
}
}
}

View File

@ -17,8 +17,9 @@
?>
</select>&nbsp;&nbsp;
<select name="annee" id="yearselector">
<option value="-1" <?php if ((int) $_GET['annee'] == -1)
echo 'selected' ?>>Toutes les années</option>
<option value="-1" <?php if ((int) $_GET['annee'] == -1) {
echo 'selected';
} ?>>Toutes les années</option>
<?php
$currentYear = date('Y');
for ($year = $currentYear; $year >= $currentYear - 10; $year--) {
@ -27,73 +28,86 @@
?>
</select>&nbsp;&nbsp;
<select name="mois" id="monthselector">
<option value="0" <?php if ((int) $_GET['mois'] == 0)
echo 'selected' ?>>Tous les mois</option>
<option value="1" <?php if ((int) $_GET['mois'] == 1)
echo 'selected' ?>>Janvier</option>
<option value="2" <?php if ((int) $_GET['mois'] == 2)
echo 'selected' ?>>Fevrier</option>
<option value="3" <?php if ((int) $_GET['mois'] == 3)
echo 'selected' ?>>Mars</option>
<option value="4" <?php if ((int) $_GET['mois'] == 4)
echo 'selected' ?>>Avril</option>
<option value="5" <?php if ((int) $_GET['mois'] == 5)
echo 'selected' ?>>Mai</option>
<option value="6" <?php if ((int) $_GET['mois'] == 6)
echo 'selected' ?>>Juin</option>
<option value="7" <?php if ((int) $_GET['mois'] == 7)
echo 'selected' ?>>Juillet</option>
<option value="8" <?php if ((int) $_GET['mois'] == 8)
echo 'selected' ?>>Août</option>
<option value="9" <?php if ((int) $_GET['mois'] == 9)
echo 'selected' ?>>Septembre</option>
<option value="10" <?php if ((int) $_GET['mois'] == 10)
echo 'selected' ?>>Octobre</option>
<option value="11" <?php if ((int) $_GET['mois'] == 11)
echo 'selected' ?>>Novembre</option>
<option value="12" <?php if ((int) $_GET['mois'] == 12)
echo 'selected' ?>>Decembre</option>
<option value="0" <?php if ((int) $_GET['mois'] == 0) {
echo 'selected';
} ?>>Tous les mois</option>
<option value="1" <?php if ((int) $_GET['mois'] == 1) {
echo 'selected';
} ?>>Janvier</option>
<option value="2" <?php if ((int) $_GET['mois'] == 2) {
echo 'selected';
} ?>>Fevrier</option>
<option value="3" <?php if ((int) $_GET['mois'] == 3) {
echo 'selected';
} ?>>Mars</option>
<option value="4" <?php if ((int) $_GET['mois'] == 4) {
echo 'selected';
} ?>>Avril</option>
<option value="5" <?php if ((int) $_GET['mois'] == 5) {
echo 'selected';
} ?>>Mai</option>
<option value="6" <?php if ((int) $_GET['mois'] == 6) {
echo 'selected';
} ?>>Juin</option>
<option value="7" <?php if ((int) $_GET['mois'] == 7) {
echo 'selected';
} ?>>Juillet</option>
<option value="8" <?php if ((int) $_GET['mois'] == 8) {
echo 'selected';
} ?>>Août</option>
<option value="9" <?php if ((int) $_GET['mois'] == 9) {
echo 'selected';
} ?>>Septembre</option>
<option value="10" <?php if ((int) $_GET['mois'] == 10) {
echo 'selected';
} ?>>Octobre</option>
<option value="11" <?php if ((int) $_GET['mois'] == 11) {
echo 'selected';
} ?>>Novembre</option>
<option value="12" <?php if ((int) $_GET['mois'] == 12) {
echo 'selected';
} ?>>Decembre</option>
</select>&nbsp;&nbsp;
<input type="hidden" name="filterType" id="filterType"
value="<?php echo ($_GET['filterType'] ?? 'group'); ?>">
value="<?php echo($_GET['filterType'] ?? 'group'); ?>">
<input type="submit" value="Filtrer" />
</form>
<div class="d-flex flex-row">
<?php
$clients = $_['clients'];
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$devis = array_filter($_['devis'], function ($currentDevis) {
if ($currentDevis->cid) {
$datesplit = explode("-", $currentDevis->date);
$year = (int) $datesplit[0];
$month = (int) $datesplit[1];
$checkClient = false;
$filterType = "group";
if (array_key_exists('filterType', $_GET) && $_GET['filterType'] == 'client') {
$filterType = "client";
}
$clientIsNotSelected = strcmp($_GET['cli'], '') == 0;
if ($clientIsNotSelected) {
if ($filterType == "group") {
$checkClient = $_['clients'][0]->fk_client_group_facturation_id == $currentDevis->cid;
} else {
$checkClient = $_['clients'][0]->id == $currentDevis->cid;
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$devis = array_filter($_['devis'], function ($currentDevis) {
if ($currentDevis->cid) {
$datesplit = explode("-", $currentDevis->date);
$year = (int) $datesplit[0];
$month = (int) $datesplit[1];
$checkClient = false;
$filterType = "group";
if (array_key_exists('filterType', $_GET) && $_GET['filterType'] == 'client') {
$filterType = "client";
}
} else {
if ($filterType == "group") {
$checkClient = $currentDevis->fk_client_group_facturation_id == $_GET['cli'];
$clientIsNotSelected = strcmp($_GET['cli'], '') == 0;
if ($clientIsNotSelected) {
if ($filterType == "group") {
$checkClient = $_['clients'][0]->fk_client_group_facturation_id == $currentDevis->cid;
} else {
$checkClient = $_['clients'][0]->id == $currentDevis->cid;
}
} else {
$checkClient = $currentDevis->cid == $_GET['cli'];
if ($filterType == "group") {
$checkClient = $currentDevis->fk_client_group_facturation_id == $_GET['cli'];
} else {
$checkClient = $currentDevis->cid == $_GET['cli'];
}
}
$checkYear = ((int) ($_GET['annee']) == -1) ? (true) : ($year == ((int) $_GET['annee']));
$checkMounth = (((int) $_GET['mois']) == 0) ? (true) : ($month == ((int) $_GET['mois']));
return $checkClient && $checkYear && $checkMounth;
}
$checkYear = ((int) ($_GET['annee']) == -1) ? (true) : ($year == ((int) $_GET['annee']));
$checkMounth = (((int) $_GET['mois']) == 0) ? (true) : ($month == ((int) $_GET['mois']));
return $checkClient && $checkYear && $checkMounth;
}
return false;
});
if (strcmp($_GET['cli'], '') != 0 && sizeof($devis) > 0) {
?>
return false;
});
if (strcmp($_GET['cli'], '') != 0 && sizeof($devis) > 0) {
?>
<button class="btn btn-secondary" type="button"
id="exportMultipleDevisToPdf"><?php p($l->t('Save in Nextcloud')); ?></button>
<button class="btn btn-secondary" type="button" id="showGroupDevisFacturationModal" data-toggle="modal"
@ -101,22 +115,23 @@
Facturer
</button>
<?php
}
}
}
?>
?>
</div>
</div>
<hr>
<div id="gestion-canvas" class="canvas_div_pdf">
<?php
if ($_SERVER['REQUEST_METHOD'] == 'GET' && strcmp($_GET['cli'], '') != 0) {
if (sizeof($devis) == 0)
if (sizeof($devis) == 0) {
echo "Aucun devis trouvé.";
}
}
;
;
foreach ($devis as $key => $currentDevis) {
?>
foreach ($devis as $key => $currentDevis) {
?>
<div class="bootstrap-iso d-flex flex-column justify-content-between">
<div class="d-flex flex-column w-100">
<h2 class="mt-3 mb-3 text-center"> <?php p($l->t('Quote')); ?>
@ -143,12 +158,12 @@
</div>
<div class="col-2 h-100 m-0" style="min-height:250px;">
<?php
if (isset($_['logo']) && $_['logo'] !== "nothing") {
echo "<center><a><img alt='" . $l->t('Company logo') . "' class=\"img-fluid\" src=\"data:image/png;base64, " . $_['logo'] . "\"/></a></center>";
} else {
echo "<span style='font-size:12px' id='Company-logo' data-html2canvas-ignore><b><center>" . $l->t('You can add your company logo here.') . "</center></b><br/><i>" . $l->t('To add a logo, drop the logo.png file in ".gestion" folder at the root of your Nextcloud Files app. Remember to set "Show hidden files".') . "</i><br/><br/><center>" . $l->t('This message will not appear on generated PDF.') . "</center></span>";
}
?>
if (isset($_['logo']) && $_['logo'] !== "nothing") {
echo "<center><a><img alt='" . $l->t('Company logo') . "' class=\"img-fluid\" src=\"data:image/png;base64, " . $_['logo'] . "\"/></a></center>";
} else {
echo "<span style='font-size:12px' id='Company-logo' data-html2canvas-ignore><b><center>" . $l->t('You can add your company logo here.') . "</center></b><br/><i>" . $l->t('To add a logo, drop the logo.png file in ".gestion" folder at the root of your Nextcloud Files app. Remember to set "Show hidden files".') . "</i><br/><br/><center>" . $l->t('This message will not appear on generated PDF.') . "</center></span>";
}
?>
</div>
<div class="col-5 h-100 m-0" style="min-height:250px;">
<h5 class="p-3 m-0 text-dark text-center border border-2 border-dark"><?php p($l->t('TO')); ?>
@ -197,7 +212,7 @@
style="display:inline"
data-table="devis" data-column="order_number"
data-id="<?php echo $currentDevis->id;?>">
<?php echo ($currentDevis->order_number == "" ) ? "-" : $currentDevis->order_number ; ?>
<?php echo ($currentDevis->order_number == "") ? "-" : $currentDevis->order_number ; ?>
</div>
</div>
<hr />
@ -209,7 +224,7 @@
style="display:inline"
data-table="devis" data-column="case_number"
data-id="<?php echo $currentDevis->id;?>">
<?php echo ($currentDevis->case_number == "" ) ? "-" : $currentDevis->case_number ; ?>
<?php echo ($currentDevis->case_number == "") ? "-" : $currentDevis->case_number ; ?>
</div>
</div>
<hr />
@ -253,16 +268,28 @@
</thead>
<tbody>
<?php
$totalhtc = 0;
$tva = json_decode($_['configuration'])[0]->tva_default;
$totalttc = 0;
$totalprice = 0;
foreach ($currentDevis->dproduits as $key => $produit) {
$totalhtc = $totalhtc + ($produit->quantite * $produit->prix_unitaire);
}
$totalttc = ($totalhtc * $tva) / 100;
$totalprice = $totalhtc + $totalttc;
?>
$totalhtc = 0;
$tva = json_decode($_['configuration'])[0]->tva_default;
$clientTvaStatus = isset($currentDevis->tva) ? (int)$currentDevis->tva : 1;
$totalttc = 0;
$totalprice = 0;
foreach ($currentDevis->dproduits as $key => $produit) {
$totalhtc = $totalhtc + ($produit->quantite * $produit->prix_unitaire);
}
// Calculer la TVA selon le statut du client
if ($clientTvaStatus === 0) {
// Client exonéré de TVA
$tva = 0;
$totalttc = 0;
$totalprice = $totalhtc;
} else {
// Client soumis à la TVA
$totalttc = ($totalhtc * $tva) / 100;
$totalprice = $totalhtc + $totalttc;
}
?>
<tr>
<td>&euro;<?php echo number_format($totalhtc, 2) ?></td>
<td><?php echo $tva ?> &percnt;</td>
@ -288,8 +315,8 @@
<hr data-html2canvas-ignore>
<hr data-html2canvas-ignore>
<?php
}
?>
}
?>
</div>
<div class="modal" id="groupDevisFacturationModal" tabindex="-1">
<div class="modal-dialog">

View File

@ -1,16 +1,17 @@
<div class="d-flex flex-column w-100 p-4">
<?php $factures = []; $showRecapButton=false;?>
<?php $factures = [];
$showRecapButton = false;?>
<div class="d-flex justify-content-between">
<form method="get" class="d-flex flex-row align-items-center">
<select name="cli" id="clientselector">
<?php
foreach ($_['clients'] as $key => $client) {
?>
?>
<option
<?php
if($_GET['cli'] == $client->id && $_GET['filterType'] == $client->client_type){
echo 'selected';
}
<?php
if($_GET['cli'] == $client->id && $_GET['filterType'] == $client->client_type) {
echo 'selected';
}
?>
value='<?php echo $client->id ?>'
data-type='<?php echo $client->client_type ?>'
@ -19,78 +20,109 @@
</option>
<?php
}
?>
?>
</select>&nbsp;&nbsp;
<select name="annee" id="yearselector">
<option value="-1" <?php if((int) $_GET['annee'] == -1) echo 'selected' ?>>Toutes les années</option>
<option value="-1" <?php if((int) $_GET['annee'] == -1) {
echo 'selected';
} ?>>Toutes les années</option>
<?php
$currentYear = date('Y');
for ($year = $currentYear; $year >= $currentYear - 10; $year--) {
echo '<option value="' . $year . '" ' . ((int)$_GET['annee'] == $year ? 'selected' : '') . '>' . $year . '</option>';
}
?>
for ($year = $currentYear; $year >= $currentYear - 10; $year--) {
echo '<option value="' . $year . '" ' . ((int)$_GET['annee'] == $year ? 'selected' : '') . '>' . $year . '</option>';
}
?>
</select>&nbsp;&nbsp;
<select name="mois" id="monthselector">
<option value="0" <?php if((int) $_GET['mois'] == 0) echo 'selected' ?>>Tous les mois</option>
<option value="1" <?php if((int) $_GET['mois'] == 1) echo 'selected' ?>>Janvier</option>
<option value="2" <?php if((int) $_GET['mois'] == 2) echo 'selected' ?>>Fevrier</option>
<option value="3" <?php if((int) $_GET['mois'] == 3) echo 'selected' ?>>Mars</option>
<option value="4" <?php if((int) $_GET['mois'] == 4) echo 'selected' ?>>Avril</option>
<option value="5" <?php if((int) $_GET['mois'] == 5) echo 'selected' ?>>Mai</option>
<option value="6" <?php if((int) $_GET['mois'] == 6) echo 'selected' ?>>Juin</option>
<option value="7" <?php if((int) $_GET['mois'] == 7) echo 'selected' ?>>Juillet</option>
<option value="8" <?php if((int) $_GET['mois'] == 8) echo 'selected' ?>>Août</option>
<option value="9" <?php if((int) $_GET['mois'] == 9) echo 'selected' ?>>Septembre</option>
<option value="10" <?php if((int) $_GET['mois'] == 10) echo 'selected' ?>>Octobre</option>
<option value="11" <?php if((int) $_GET['mois'] == 11) echo 'selected' ?>>Novembre</option>
<option value="12" <?php if((int) $_GET['mois'] == 12) echo 'selected' ?>>Decembre</option>
<option value="0" <?php if((int) $_GET['mois'] == 0) {
echo 'selected';
} ?>>Tous les mois</option>
<option value="1" <?php if((int) $_GET['mois'] == 1) {
echo 'selected';
} ?>>Janvier</option>
<option value="2" <?php if((int) $_GET['mois'] == 2) {
echo 'selected';
} ?>>Fevrier</option>
<option value="3" <?php if((int) $_GET['mois'] == 3) {
echo 'selected';
} ?>>Mars</option>
<option value="4" <?php if((int) $_GET['mois'] == 4) {
echo 'selected';
} ?>>Avril</option>
<option value="5" <?php if((int) $_GET['mois'] == 5) {
echo 'selected';
} ?>>Mai</option>
<option value="6" <?php if((int) $_GET['mois'] == 6) {
echo 'selected';
} ?>>Juin</option>
<option value="7" <?php if((int) $_GET['mois'] == 7) {
echo 'selected';
} ?>>Juillet</option>
<option value="8" <?php if((int) $_GET['mois'] == 8) {
echo 'selected';
} ?>>Août</option>
<option value="9" <?php if((int) $_GET['mois'] == 9) {
echo 'selected';
} ?>>Septembre</option>
<option value="10" <?php if((int) $_GET['mois'] == 10) {
echo 'selected';
} ?>>Octobre</option>
<option value="11" <?php if((int) $_GET['mois'] == 11) {
echo 'selected';
} ?>>Novembre</option>
<option value="12" <?php if((int) $_GET['mois'] == 12) {
echo 'selected';
} ?>>Decembre</option>
</select>&nbsp;&nbsp;
<input type="hidden" name="filterType" id="filterType" value="<?php echo ($_GET['filterType'] ?? 'client'); ?>">
<input type="hidden" name="filterType" id="filterType" value="<?php echo($_GET['filterType'] ?? 'client'); ?>">
<input type="submit" value="Filtrer"/>
</form>
<div class="d-flex flex-row">
<?php
if($_SERVER['REQUEST_METHOD'] == 'GET') {
if(intval($_GET['mois'])!=0 && intval($_GET['annee'])!=0) $showRecapButton = true;
$factures = array_filter($_['factures'], function($f) {
if(intval($_GET['mois']) != 0 && intval($_GET['annee']) != 0) {
$showRecapButton = true;
}
$factures = array_filter($_['factures'], function ($f) {
$datesplit = explode("-", $f->date_paiement);
$year = (int) $datesplit[0];
$month = (int) $datesplit[1];
$checkClient = false;
$filterType = "client";
if(array_key_exists('filterType',$_GET) && $_GET['filterType'] == 'group'){
if(array_key_exists('filterType', $_GET) && $_GET['filterType'] == 'group') {
$filterType = "group";
}
if($_GET['cli'] != null && $_GET['cli'] != '') {
if($filterType == "group"){
if($filterType == "group") {
$checkClient = $f->fk_client_group_facturation_id == $_GET['cli'];
}
else{
} else {
$checkClient = $f->id_cli == $_GET['cli'];
}
}
$checkYear = ((int) ($_GET['annee']) == -1)?(true):($year==((int) $_GET['annee']));
$checkMounth = (((int) $_GET['mois']) == 0)? (true): ($month==((int) $_GET['mois']));
$checkYear = ((int) ($_GET['annee']) == -1) ? (true) : ($year == ((int) $_GET['annee']));
$checkMounth = (((int) $_GET['mois']) == 0) ? (true) : ($month == ((int) $_GET['mois']));
return $checkClient && $checkYear && $checkMounth;
});
if(sizeof($factures)>0) {
?>
if(sizeof($factures) > 0) {
?>
<?php if($showRecapButton) {?><button class="btn btn-secondary" type="button" id="documentrecap">Generer le document recapitulatif</button><?php }?>
<button class="btn btn-secondary ml-2" type="button" id="exportMultipleFactureToPdf"><?php p($l->t('Save in Nextcloud'));?></button>
<?php
}
}
?>
?>
</div>
</div>
<hr>
<div class="canvas_div_pdf">
<?php
if($_SERVER['REQUEST_METHOD'] == 'GET') {
if(sizeof($factures)==0) echo "Aucune facture trouvée.";
};
foreach ($factures as $key => $facture) {
if($_SERVER['REQUEST_METHOD'] == 'GET') {
if(sizeof($factures) == 0) {
echo "Aucune facture trouvée.";
}
};
foreach ($factures as $key => $facture) {
?>
<div class="bootstrap-iso d-flex flex-column justify-content-between">
<div class="d-flex flex-column w-100">
@ -112,12 +144,12 @@
</div>
<div class="col-2 h-100 m-0" style="min-height:250px;">
<?php
if(isset($_['logo']) && $_['logo'] !== "nothing"){
if(isset($_['logo']) && $_['logo'] !== "nothing") {
echo "<center><a><img alt='".$l->t('Company logo')."' class=\"img-fluid\" src=\"data:image/png;base64, ".$_['logo']."\"/></a></center>";
}else{
} else {
echo "<span style='font-size:12px' id='Company-logo' data-html2canvas-ignore><b><center>".$l->t('You can add your company logo here.')."</center></b><br/><i>".$l->t('To add a logo, drop the logo.png file in ".gestion" folder at the root of your Nextcloud Files app. Remember to set "Show hidden files".')."</i><br/><br/><center>".$l->t('This message will not appear on generated PDF.')."</center></span>";
}
?>
?>
</div>
<div class="col-5 h-100 m-0" style="min-height:250px;">
<h5 class="p-3 m-0 text-dark text-center border border-2 border-dark"><?php p($l->t('TO'));?> <span id="entreprise"><?php echo $facture->nom ?></span></h6>
@ -148,7 +180,7 @@
<div class="row">
<div class="col col-md">
<hr />
<div class="col col-xl mb-3 text-center" style="display:inline" ><?php echo ($facture->dcomment == "" ) ? "-" : $facture->dcomment ; ?></div>
<div class="col col-xl mb-3 text-center" style="display:inline" ><?php echo ($facture->dcomment == "") ? "-" : $facture->dcomment ; ?></div>
<hr />
</div>
</div>
@ -172,7 +204,7 @@
<td><?php echo $produit->comment ?></td>
<td><?php echo $produit->quantite ?></td>
<td>&euro;<?php echo number_format($produit->prix_unitaire, 2) ?></td>
<td>&euro;<?php echo number_format($produit->prix_unitaire*$produit->quantite, 2) ?></td>
<td>&euro;<?php echo number_format($produit->prix_unitaire * $produit->quantite, 2) ?></td>
</tr>
<?php } ?>
</tbody>
@ -189,17 +221,30 @@
</tr>
</thead>
<tbody>
<?php
$totalhtc = 0;
$tva = json_decode($_['configuration'])[0]->tva_default;
$totalttc = 0;
$totalprice = 0;
foreach ($facture->dproduits as $key => $produit) {
$totalhtc = $totalhtc + ($produit->quantite*$produit->prix_unitaire);
}
$totalttc = ($totalhtc * $tva)/100;
$totalprice = $totalhtc + $totalttc;
?>
<?php
$totalhtc = 0;
$tva = json_decode($_['configuration'])[0]->tva_default;
$clientTvaStatus = isset($facture->tva_cli) ? (int)$facture->tva_cli : 1;
$totalttc = 0;
$totalprice = 0;
foreach ($facture->dproduits as $key => $produit) {
$totalhtc = $totalhtc + ($produit->quantite * $produit->prix_unitaire);
}
// Calculer la TVA selon le statut du client
if ($clientTvaStatus === 0) {
// Client exonéré de TVA
$tva = 0;
$totalttc = 0;
$totalprice = $totalhtc;
} else {
// Client soumis à la TVA
$totalttc = ($totalhtc * $tva) / 100;
$totalprice = $totalhtc + $totalttc;
}
?>
<tr>
<td>&euro;<?php echo number_format($totalhtc, 2) ?></td>
<td><?php echo $tva ?> &percnt;</td>
@ -224,7 +269,7 @@
<hr data-html2canvas-ignore>
<hr data-html2canvas-ignore>
<?php
}
?>
}
?>
</div>
</div>

View File

@ -27,11 +27,14 @@
<th><?php p($l->t('ID'));?></th>
<th><?php p($l->t('Code comptable'));?></th>
<th><?php p($l->t('Agence'));?></th>
<th><?php p($l->t('Prénom'));?></th> <!-- AJOUTÉ -->
<th><?php p($l->t('Nom'));?></th> <!-- AJOUTÉ -->
<th><?php p($l->t('Company'));?></th>
<th><?php p($l->t('Legal information'));?></th>
<th><?php p($l->t('Phone number'));?></th>
<th><?php p($l->t('Email'));?></th>
<th><?php p($l->t('Address'));?></th>
<th><?php p($l->t('TVA'));?></th>
<th><?php p($l->t('Groupes tarifaires'));?></th>
<th><?php p($l->t('Groupes facturations'));?></th>
<th><?php p($l->t('Actions'));?></th>