diff options
-rw-r--r-- | data/latex/devis.tex | 79 | ||||
-rw-r--r-- | data/latex/enveloppe_recto.tex | 21 | ||||
-rw-r--r-- | data/latex/enveloppe_verso.tex | 13 | ||||
-rw-r--r-- | data/latex/facture.tex | 80 | ||||
-rw-r--r-- | data/latex/location.tex | 44 | ||||
-rw-r--r-- | data/latex/ordipolo.png | bin | 0 -> 46751 bytes | |||
-rw-r--r-- | src/Dates.php | 105 | ||||
-rw-r--r-- | src/Latex.php | 84 | ||||
-rw-r--r-- | src/dependances.php | 100 | ||||
-rw-r--r-- | src/functions.php | 51 | ||||
-rw-r--r-- | src/latex_templates/devis.php | 84 | ||||
-rw-r--r-- | src/latex_templates/enveloppe_recto.php | 26 | ||||
-rw-r--r-- | src/latex_templates/enveloppe_verso.php | 18 | ||||
-rw-r--r-- | src/latex_templates/facture.php | 85 | ||||
-rw-r--r-- | src/latex_templates/location.php | 49 | ||||
-rwxr-xr-x | src/main.php | 239 | ||||
-rw-r--r-- | src/model/CESU.php | 46 | ||||
-rw-r--r-- | src/model/Clients.php | 50 | ||||
-rw-r--r-- | src/model/DB.php | 48 | ||||
-rw-r--r-- | src/model/DevisFactures.php | 98 | ||||
-rw-r--r-- | src/model/Locations.php | 74 | ||||
-rw-r--r-- | src/model/Model.php | 162 | ||||
-rw-r--r-- | src/model/Prestations.php | 62 | ||||
-rw-r--r-- | src/model/StructTablesDB.php | 35 | ||||
-rw-r--r-- | src/view/Zenity.php | 110 | ||||
-rw-r--r-- | src/view/zenity_setup.php | 37 |
26 files changed, 1800 insertions, 0 deletions
diff --git a/data/latex/devis.tex b/data/latex/devis.tex new file mode 100644 index 0000000..debcdc5 --- /dev/null +++ b/data/latex/devis.tex | |||
@@ -0,0 +1,79 @@ | |||
1 | \documentclass{report} | ||
2 | |||
3 | \usepackage[french]{babel} | ||
4 | \usepackage{lmodern} % police latin modern | ||
5 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
6 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
7 | \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} % marges | ||
8 | \usepackage{graphicx} % insertions d'images | ||
9 | \usepackage{textcomp} % pour N° | ||
10 | \usepackage{xcolor} % texte en couleur | ||
11 | \usepackage{tabularx} % dimensions des tableaux automatique | ||
12 | \usepackage{tikz} % le rectangle | ||
13 | |||
14 | \begin{document} | ||
15 | \setlength{\parindent}{0cm} % supprimer les alinéas | ||
16 | \large{} | ||
17 | \pagestyle{empty} % en-tête et pied de page vides | ||
18 | \definecolor{vert}{rgb}{0.07, 0.46, 0.13} % saisie en vert | ||
19 | |||
20 | \begin{center} | ||
21 | \includegraphics{ordipolo.png}\\ | ||
22 | \Large\textbf{Dépannage informatique - Assistance à domicile} | ||
23 | \end{center} | ||
24 | |||
25 | 2 A rue de l'île de Man, 29000 Quimper | ||
26 | |||
27 | SIRET : 814 320 610 00011 | ||
28 | |||
29 | \begin{tabularx}{0.67\linewidth}{@{}X@{}@{}X@{}} | ||
30 | Tel : 06.63.85.48.82 & Courriel : ordipolo@gmx.fr | ||
31 | \end{tabularx} | ||
32 | |||
33 | Plus d'infos sur le site web: https\string://ordipolo.fr\\ | ||
34 | % \string supprime l'espace devant les : | ||
35 | |||
36 | \begin{center} | ||
37 | \large\textbf{DEVIS} | ||
38 | \end{center} | ||
39 | |||
40 | CLIENT\\ | ||
41 | |||
42 | \begin{tabularx}{\linewidth}{@{}X@{}@{}X@{}} | ||
43 | Mme, M : \textcolor{vert}{} & | ||
44 | Date du devis : \textcolor{vert}{}\\ | ||
45 | Adresse : \textcolor{vert}{} & | ||
46 | Delai de livraison : \textcolor{vert}{}\\ | ||
47 | \end{tabularx}\\\\ | ||
48 | |||
49 | PRESTATION\\ | ||
50 | |||
51 | \textcolor{vert}{} | ||
52 | |||
53 | Total main d'oeuvre : \textcolor{vert}{}\\ | ||
54 | |||
55 | PIÈCES\\ | ||
56 | |||
57 | \textcolor{vert}{} | ||
58 | |||
59 | Total pièces : \textcolor{vert}{}\\ | ||
60 | |||
61 | TOTAL\\ | ||
62 | |||
63 | Déplacement : \textcolor{vert}{} | ||
64 | |||
65 | Total HT : \textcolor{vert}{} | ||
66 | |||
67 | \textit{(TVA non applicable, article 293B du code général des impôts)} | ||
68 | |||
69 | Référence du devis : \textcolor{vert}{}\\ | ||
70 | |||
71 | Devis reçu avant l'exécution des travaux, signature du client :\\ | ||
72 | \begin{tikzpicture} | ||
73 | \draw (0,0) rectangle (4,2); | ||
74 | \end{tikzpicture}\\ | ||
75 | |||
76 | \small{}NOTA BENE\\ | ||
77 | |||
78 | Si le délai de livraison n’est pas précisé, c’est naturellement le délai légal de 30 jours qui est appliqué. Lorsqu'Ordi Polo garde (ou prête) un ordinateur le temps nécessaire à la réparation, le prêt peut être formalisé par un document signé par les deux parties. Le dépannage inclut principalement l'intervention sur les logiciels et si nécessaire le démontage et remontage de la machine nécessaires au nettoyage de la poussière ou au remplacement d'une pièce. Ordi Polo ne répare pas les composants électroniques défectueux et n'est pas responsable des dysfonctionnements de l'ordinateur dont l'origine est matérielle. Ordi Polo ne vend pas de matériel mais peut conseiller ou réaliser les démarches d’un achat. | ||
79 | \end{document} \ No newline at end of file | ||
diff --git a/data/latex/enveloppe_recto.tex b/data/latex/enveloppe_recto.tex new file mode 100644 index 0000000..d1f3f43 --- /dev/null +++ b/data/latex/enveloppe_recto.tex | |||
@@ -0,0 +1,21 @@ | |||
1 | \documentclass[]{report} | ||
2 | |||
3 | \usepackage[french]{babel} | ||
4 | \usepackage{lmodern} % police latin modern | ||
5 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
6 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
7 | \usepackage{graphicx} % insertions d'images | ||
8 | \usepackage[papersize={22cm, 11cm}, top=1cm, left=1cm, bottom=1cm]{geometry} | ||
9 | \pagestyle{empty} | ||
10 | |||
11 | \begin{document} | ||
12 | \setlength{\parindent}{0cm} | ||
13 | \includegraphics{ordipolo.png}\\ | ||
14 | \large\textbf{Dépannage informatique - Assistance à domicile} | ||
15 | |||
16 | \setlength{\parindent}{7,9cm} | ||
17 | \begin{minipage}[b][5,8cm]{12cm} | ||
18 | \LARGE{M. Truc\\3, rue Machin\\\\\\} | ||
19 | \LARGE{2 \ 9 \ 0 \ 0 \ 0 \ \ \ \ QUIMPER} | ||
20 | \end{minipage} | ||
21 | \end{document} \ No newline at end of file | ||
diff --git a/data/latex/enveloppe_verso.tex b/data/latex/enveloppe_verso.tex new file mode 100644 index 0000000..24baa8a --- /dev/null +++ b/data/latex/enveloppe_verso.tex | |||
@@ -0,0 +1,13 @@ | |||
1 | \documentclass[]{report} | ||
2 | |||
3 | \usepackage[french]{babel} | ||
4 | \usepackage{lmodern} % police latin modern | ||
5 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
6 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
7 | \usepackage[papersize={22cm, 11cm}, top=0.6cm, left=4.5cm]{geometry} | ||
8 | \pagestyle{empty} | ||
9 | |||
10 | \begin{document} | ||
11 | \setlength{\parindent}{0cm} | ||
12 | \Large{Paul Jusot\\2A, rue de l'île de Man\\29000 QUIMPER} | ||
13 | \end{document} \ No newline at end of file | ||
diff --git a/data/latex/facture.tex b/data/latex/facture.tex new file mode 100644 index 0000000..babb2ab --- /dev/null +++ b/data/latex/facture.tex | |||
@@ -0,0 +1,80 @@ | |||
1 | \documentclass{report} | ||
2 | |||
3 | \usepackage[french]{babel} | ||
4 | \usepackage{lmodern} % police latin modern | ||
5 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
6 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
7 | \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} % marges | ||
8 | \usepackage{graphicx} % insertions d'images | ||
9 | \usepackage{textcomp} % pour N° | ||
10 | \usepackage{xcolor} % texte en couleur | ||
11 | \usepackage{tabularx} % dimensions des tableaux automatique | ||
12 | |||
13 | \begin{document} | ||
14 | \setlength{\parindent}{0cm} % supprimer les alinéas | ||
15 | \large{} | ||
16 | \pagestyle{empty} % en-tête et pied de page vides | ||
17 | \definecolor{vert}{rgb}{0.07, 0.46, 0.13} % saisie en vert | ||
18 | |||
19 | \begin{center} | ||
20 | \includegraphics{ordipolo.png}\\ | ||
21 | \Large\textbf{Dépannage informatique - Assistance à domicile} | ||
22 | \end{center} | ||
23 | |||
24 | 2 A rue de l'île de Man, 29000 Quimper | ||
25 | |||
26 | SIRET : 814 320 610 00011 | ||
27 | |||
28 | \begin{tabularx}{0.67\linewidth}{@{}X@{}@{}X@{}} | ||
29 | Tel : 06.63.85.48.82 & Courriel : ordipolo@gmx.fr | ||
30 | \end{tabularx} | ||
31 | |||
32 | Plus d'infos sur le site web: https\string://ordipolo.fr\\ | ||
33 | % \string supprime l'espace devant les : | ||
34 | |||
35 | \begin{center} | ||
36 | \large\textbf{FACTURE} | ||
37 | \end{center} | ||
38 | |||
39 | CLIENT\\ | ||
40 | |||
41 | \begin{tabularx}{\linewidth}{@{}X@{}@{}X@{}} | ||
42 | Mme, M : \textcolor{vert}{} & | ||
43 | Date : \textcolor{vert}{}\\ | ||
44 | \end{tabularx}\\ | ||
45 | Adresse : \textcolor{vert}{}\\ | ||
46 | |||
47 | PRESTATION\\ | ||
48 | |||
49 | \textcolor{vert}{} | ||
50 | |||
51 | Modèle de l'ordinateur : \textcolor{vert}{} | ||
52 | |||
53 | Système d'exploitation : \textcolor{vert}{} | ||
54 | |||
55 | Données à conserver : \textcolor{vert}{} | ||
56 | |||
57 | Clé d'activation : \textcolor{vert}{}\\ | ||
58 | |||
59 | Total main d'oeuvre : \textcolor{vert}{}\\ | ||
60 | |||
61 | PIÈCES\\ | ||
62 | |||
63 | \textcolor{vert}{} | ||
64 | |||
65 | Total pièces : \textcolor{vert}{}\\ | ||
66 | |||
67 | TOTAL\\ | ||
68 | |||
69 | Déplacement : \textcolor{vert}{} | ||
70 | |||
71 | Total HT : \textcolor{vert}{} | ||
72 | |||
73 | \textit{(TVA non applicable, article 293B du code général des impôts)} | ||
74 | |||
75 | Référence de la facture : \textcolor{vert}{}\\ | ||
76 | |||
77 | \small{}NOTA BENE\\ | ||
78 | |||
79 | Lorsqu'Ordi Polo garde (ou prête) un ordinateur le temps nécessaire à la réparation, le prêt peut être formalisé par un document signé par les deux parties. Le dépannage inclut principalement l'intervention sur les logiciels et si nécessaire le démontage et remontage de la machine nécessaires au nettoyage de la poussière ou au remplacement d'une pièce. Ordi Polo ne répare pas les composants électroniques défectueux et n'est pas responsable des dysfonctionnements de l'ordinateur dont l'origine est matérielle. Ordi Polo ne vend pas de matériel mais peut conseiller ou réaliser les démarches d’un achat. | ||
80 | \end{document} \ No newline at end of file | ||
diff --git a/data/latex/location.tex b/data/latex/location.tex new file mode 100644 index 0000000..bcfb1e5 --- /dev/null +++ b/data/latex/location.tex | |||
@@ -0,0 +1,44 @@ | |||
1 | \documentclass{report} | ||
2 | |||
3 | \usepackage[french]{babel} | ||
4 | \usepackage{lmodern} % police latin modern | ||
5 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
6 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
7 | \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} % marges | ||
8 | \usepackage{graphicx} % insertions d'images | ||
9 | \usepackage{textcomp} % pour N° | ||
10 | \usepackage{xcolor} % texte en couleur | ||
11 | %\usepackage{wrapfig} % placer texte et image côte-à-côte | ||
12 | \usepackage{tabularx} % dimensions des tableaux automatique | ||
13 | |||
14 | \begin{document} | ||
15 | \setlength{\parindent}{0cm} % supprimer les alinéas | ||
16 | \large{} | ||
17 | \pagestyle{empty} % en-tête et pied de page vides | ||
18 | \definecolor{vert}{rgb}{0.07, 0.46, 0.13} % saisie en vert | ||
19 | |||
20 | \begin{center} | ||
21 | \includegraphics{ordipolo.png}\\ | ||
22 | \Large\textbf{Dépannage informatique - Assistance à domicile} | ||
23 | \end{center} | ||
24 | |||
25 | 2 A rue de l'île de Man, 29000 Quimper | ||
26 | |||
27 | SIRET : 814 320 610 00011 | ||
28 | |||
29 | \begin{tabularx}{0.67\linewidth}{@{}X@{}@{}X@{}} | ||
30 | Tel : 06.63.85.48.82 & Courriel : ordipolo@gmx.fr | ||
31 | \end{tabularx} | ||
32 | |||
33 | Plus d'infos sur le site web: https\string://ordipolo.fr\\ | ||
34 | % \string supprime l'espace devant les : | ||
35 | |||
36 | CLIENT\\ | ||
37 | |||
38 | \begin{tabularx}{\linewidth}{@{}X@{}@{}X@{}} | ||
39 | Mme, M : \textcolor{vert}{} & | ||
40 | Date : \textcolor{vert}{}\\ | ||
41 | \end{tabularx}\\ | ||
42 | Adresse : \textcolor{vert}{}\\ | ||
43 | |||
44 | \end{document} \ No newline at end of file | ||
diff --git a/data/latex/ordipolo.png b/data/latex/ordipolo.png new file mode 100644 index 0000000..2acd67d --- /dev/null +++ b/data/latex/ordipolo.png | |||
Binary files differ | |||
diff --git a/src/Dates.php b/src/Dates.php new file mode 100644 index 0000000..de71b08 --- /dev/null +++ b/src/Dates.php | |||
@@ -0,0 +1,105 @@ | |||
1 | <?php | ||
2 | // php/DateTimestamp.php | ||
3 | |||
4 | class Dates | ||
5 | { | ||
6 | private $date; | ||
7 | private $timestamp; // valeurs négatives autorisées => dates avant 1970 | ||
8 | static public $date_format = 'EU'; // dates européennes jj-mm-aaaa (EU) ou américaines mm/dd/yyyy (US) | ||
9 | |||
10 | |||
11 | public function __construct($entry = NULL) | ||
12 | { | ||
13 | if(gettype($entry) === 'string') // une date est attendue | ||
14 | { | ||
15 | $this->setDate($entry); | ||
16 | } | ||
17 | elseif(gettype($entry) === 'integer') | ||
18 | { | ||
19 | $this->setTimestamp($entry); | ||
20 | } | ||
21 | } | ||
22 | |||
23 | |||
24 | public function setDate(string $entry) | ||
25 | { | ||
26 | $entry = $this->dashOrSlash($entry); // pour strtotime() | ||
27 | |||
28 | $splitedDate = preg_split('#\D#', $entry); // \D = tout sauf chiffre | ||
29 | |||
30 | if(self::$date_format === 'EU') | ||
31 | { | ||
32 | $tmp = $splitedDate[0]; | ||
33 | $splitedDate[0] = $splitedDate[1]; | ||
34 | $splitedDate[1] = $tmp; | ||
35 | } | ||
36 | |||
37 | if(checkdate($splitedDate[0], $splitedDate[1], $splitedDate[2])) | ||
38 | { | ||
39 | $this->date = $entry; | ||
40 | $this->timestamp = strtotime($entry); // date (string) -> timestamp (int) | ||
41 | // strtotime() devine le format en analysant la chaîne en entrée, on l'aide un peu | ||
42 | // avec des /, php considère que la date est américaine | ||
43 | // avec des - ou des ., php considère que la date est européenne | ||
44 | } | ||
45 | else | ||
46 | { | ||
47 | echo("Date incorrecte, le format de la date dans le fichier config.php est " . self::$date_format . ".\nLes choix possibles sont EU pour Europe et US pour États-Unis."); | ||
48 | die(); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | public function setTimestamp(int $entry) | ||
53 | { | ||
54 | $this->timestamp = $entry; | ||
55 | $this->date = $this->timestamp_to_date($entry); // timestamp (int) -> date (string) | ||
56 | } | ||
57 | |||
58 | |||
59 | public function getDate(): string | ||
60 | { | ||
61 | return($this->date); | ||
62 | } | ||
63 | |||
64 | public function getTimestamp(): int | ||
65 | { | ||
66 | return($this->timestamp); | ||
67 | } | ||
68 | |||
69 | |||
70 | private function dashOrSlash(string $date): string | ||
71 | { | ||
72 | if(self::$date_format === 'EU') | ||
73 | { | ||
74 | // change jj/mm/aaaa en jj-mm-aaaa | ||
75 | return(preg_replace('#\D#', '-', $date)); // \D = tout sauf chiffre | ||
76 | } | ||
77 | elseif(self::$date_format === 'US') | ||
78 | { | ||
79 | // change mm-dd.yyyy en mm/dd/yyyy | ||
80 | return(preg_replace('#\D#', '/', $date)); | ||
81 | } | ||
82 | else | ||
83 | { | ||
84 | echo('Le fichier config.php comporte une erreur. La variable $date_format doit avoir pour valeur "EU" ou "US"'); | ||
85 | die(); // brutal | ||
86 | } | ||
87 | } | ||
88 | |||
89 | private function timestamp_to_date(int $timestamp): string | ||
90 | { | ||
91 | if(self::$date_format === 'EU') | ||
92 | { | ||
93 | return(date("j-m-Y", $timestamp)); | ||
94 | } | ||
95 | elseif(self::$date_format === 'US') | ||
96 | { | ||
97 | return(date("m/d/Y", $timestamp)); | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | echo('Le fichier config.php comporte une erreur. La variable $date_format doit avoir pour valeur "EU" ou "US"'); | ||
102 | die(); // brutal | ||
103 | } | ||
104 | } | ||
105 | } | ||
diff --git a/src/Latex.php b/src/Latex.php new file mode 100644 index 0000000..c3d56af --- /dev/null +++ b/src/Latex.php | |||
@@ -0,0 +1,84 @@ | |||
1 | <?php | ||
2 | // php/Latex.php | ||
3 | // | ||
4 | // génération du code LaTeX | ||
5 | |||
6 | abstract class Latex | ||
7 | { | ||
8 | protected $fileName = ''; | ||
9 | protected $latexPath = ''; | ||
10 | protected $pdfPath = ''; | ||
11 | |||
12 | protected function createFile(string $latex, string $fileName, string $latexPath) | ||
13 | { | ||
14 | // nom du fichier créé = nom.tex | ||
15 | // pour les devis, factures et enveloppes, le nom est le code la prestation | ||
16 | // pour les livre de recettes et registres des achats mensuels: | ||
17 | // le nom du fichier suit cet exemple: "Recettes-2022-06-Juin.tex" | ||
18 | // pour le livre de recette ou le registre des achats annuel, même principe: "Achats-2022.tex" | ||
19 | // pour le bilan comptable annuel, ça donne: "Bilan-2022.tex" | ||
20 | $fichier = fopen($latexPath . $fileName, "w+"); | ||
21 | fputs($fichier, $latex); | ||
22 | fclose($fichier); | ||
23 | } | ||
24 | } | ||
25 | |||
26 | |||
27 | abstract class PrestaLatex extends Latex | ||
28 | { | ||
29 | public function __construct(string $quoi, string $codePresta) | ||
30 | { | ||
31 | nameTheFile($quoi, $codePresta); | ||
32 | } | ||
33 | |||
34 | // forme = code-presta.tex | ||
35 | protected function nameTheFile(string $quoi, string $codePresta) | ||
36 | { | ||
37 | $this->fileName = $quoi . '-' . $codePresta . '.tex'; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | class DevisLatex extends PrestaLatex | ||
42 | {} | ||
43 | |||
44 | class FactureLatex extends PrestaLatex | ||
45 | {} | ||
46 | |||
47 | class LocationLatex extends PrestaLatex | ||
48 | {} | ||
49 | |||
50 | class EnveloppeRectoLatex extends PrestaLatex | ||
51 | {} | ||
52 | class EnveloppeVersoLatex extends PrestaLatex | ||
53 | {} | ||
54 | |||
55 | |||
56 | abstract class ComptaLatex extends Latex | ||
57 | { | ||
58 | public function __construct(string $quoi, string $annee, int $numeroMois = 0) | ||
59 | { | ||
60 | nameTheFile($quoi, $annee, $numeroMois); | ||
61 | } | ||
62 | |||
63 | // forme = Recettes-2022-06-Juin.tex ou Recettes-2022.tex | ||
64 | // type de 'annee'? | ||
65 | protected function nameTheFile(string $quoi, string $annee, int $numeroMois = 0) | ||
66 | { | ||
67 | $this->fileName = $quoi . '-' . $annee; | ||
68 | $mois = ['', 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']; | ||
69 | if($numeroMois > 0 && $numeroMois <= 12) | ||
70 | { | ||
71 | $this->fileName .= '-' . $numeroMois . '-' . $mois[$numeroMois]; | ||
72 | } | ||
73 | $this->fileName .= '.tex'; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | class LivreRecettesLatex extends ComptaLatex | ||
78 | {} | ||
79 | |||
80 | class RegistreAchatsLatex extends ComptaLatex | ||
81 | {} | ||
82 | |||
83 | class BilanLatex extends ComptaLatex | ||
84 | {} | ||
diff --git a/src/dependances.php b/src/dependances.php new file mode 100644 index 0000000..66ce414 --- /dev/null +++ b/src/dependances.php | |||
@@ -0,0 +1,100 @@ | |||
1 | <?php | ||
2 | // php/dependances.php | ||
3 | // Vérification des dépendances nécessaires au fonctionnement de ce programmes. | ||
4 | |||
5 | // Environnement dans lequel ce programmes a été créé: | ||
6 | // - système archlinux avec l'interpréteur bash | ||
7 | // - PHP 8.1 + paquet php-sqlite | ||
8 | // - module pdo_sqlite activé dans le fichier php.ini | ||
9 | // - sqlitebrowser (interface graphique pour sqlite) | ||
10 | // - distribution LaTeX texlive | ||
11 | // - zenity | ||
12 | |||
13 | // zenity disponible | ||
14 | if(exec("zenity --version 2> /dev/null") === '') // commande qui n'ouvre pas de fenêtre, erreur si la chaine est vide parce que la sortie d'erreur va dans /dev/null | ||
15 | { | ||
16 | printf("Impossible de lancer zenity. Veuillez installer le paquet zenity\n"); | ||
17 | exit(); | ||
18 | } | ||
19 | |||
20 | // compilateur pdflatex disponible | ||
21 | if(exec("pdflatex -version 2> /dev/null") === '') // erreur si la chaine est vide parce que la sortie d'erreur va dans /dev/null | ||
22 | { | ||
23 | printf("Impossible de lancer pdflatex. Veuillez installer une distribution LaTeX.\n"); | ||
24 | exit(); | ||
25 | } | ||
26 | |||
27 | // test de la présence du paquet php-sqlite | ||
28 | // compliqué? dépend de l'OS? | ||
29 | // note: l'erreur se produit dès le démarrage de PHP si le php.ini est bon mais qu'il manque le paquet | ||
30 | |||
31 | // module pdo_sqlite de PHP activé? | ||
32 | if(!extension_loaded("pdo_sqlite")) | ||
33 | { | ||
34 | printf("Impossible d'utiliser la base de données. Veuillez installer le paquet php-sqlite ET activer l'extension pdo_sqlite dans le fichier php.ini.\n"); | ||
35 | exit(); | ||
36 | } | ||
37 | |||
38 | |||
39 | // client sqlite | ||
40 | if($exec_mode === 'gui') | ||
41 | { | ||
42 | // sqlitebrowser disponible | ||
43 | if(exec("which sqlitebrowser 2> /dev/null") !== '') // which parcourt les dossiers du PATH et affiche les chemins trouvés, erreur si la chaine est vide parce que la sortie d'erreur va dans /dev/null | ||
44 | { | ||
45 | $sqlitebrowser_enable = true; | ||
46 | } | ||
47 | // terminal en mode graphique disponible, permettra d'y utiliser sqlite dans la console | ||
48 | else | ||
49 | { | ||
50 | printf("Sqlitebrowser n'est pas disponible. J'espère que vous maîtrisez le SQL.\n"); | ||
51 | |||
52 | if(exec("which xterm 2> /dev/null") !== '' && exec("xterm -v 2> /dev/null") !== '') | ||
53 | { | ||
54 | $x_term_ccommand = 'xterm -e'; | ||
55 | } | ||
56 | elseif(exec("which urxvt 2> /dev/null") !== '') | ||
57 | { | ||
58 | $x_term_ccommand = 'urxvt -e'; | ||
59 | } | ||
60 | elseif(exec("which lxterminal 2> /dev/null") !== '' && exec("lxterminal -v 2> /dev/null") !== '') | ||
61 | { | ||
62 | $x_term_ccommand = 'lxterminal -e'; | ||
63 | } | ||
64 | elseif(exec("which xfce4-terminal 2> /dev/null") !== '' && exec("xfce4-terminal -V 2> /dev/null") !== '') | ||
65 | { | ||
66 | $x_term_ccommand = 'xfce4-terminal -x'; | ||
67 | } | ||
68 | elseif(exec("which gnome-terminal 2> /dev/null") !== '') | ||
69 | { | ||
70 | $x_term_ccommand = 'gnome-terminal --'; | ||
71 | } | ||
72 | elseif(exec("which konsole 2> /dev/null") !== '' && exec("konsole -v 2> /dev/null") !== '') | ||
73 | { | ||
74 | $x_term_ccommand = 'konsole -e'; | ||
75 | } | ||
76 | // pour MAC - NON TESTÉ !! (possibilité de détecter le système avec uname?) | ||
77 | //~ elseif(exec("which Terminal 2> /dev/null") !== '') | ||
78 | //~ { | ||
79 | //~ $x_term_ccommand = 'open -a Terminal -e'; // ne marche probablement pas | ||
80 | //~ } | ||
81 | else | ||
82 | { | ||
83 | printf("Impossible d'ouvrir un terminal pour y lancer sqlite. Veuillez installer un terminal en mode graphique (par exemple xterm).\n"); | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | // sqlite CLI disponible | ||
89 | if(exec("which sqlite 2> /dev/null") !== '' && exec("sqlite --version 2> /dev/null") !== '') | ||
90 | { | ||
91 | $sqlite_cli = 'sqlite'; | ||
92 | } | ||
93 | elseif(exec("which sqlite3 2> /dev/null") !== '' && exec("sqlite3 --version 2> /dev/null") !== '') | ||
94 | { | ||
95 | $sqlite_cli = 'sqlite3'; | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | printf("Impossible de lancer sqlite dans le terminal en utilisant la commande ' . $sqlite_cli . '\n"); | ||
100 | } | ||
diff --git a/src/functions.php b/src/functions.php new file mode 100644 index 0000000..d67a05e --- /dev/null +++ b/src/functions.php | |||
@@ -0,0 +1,51 @@ | |||
1 | <?php | ||
2 | // php/functions.php | ||
3 | // | ||
4 | // gros fourre-tout, il faudra le ranger plus tard | ||
5 | |||
6 | |||
7 | // commande pour lancer une application graphique en ouvrant un fichier | ||
8 | function window_app_command(string $app, string $path = ''): string | ||
9 | { | ||
10 | // attention, la syntaxe utilisée est la plus simple: "app fichier" | ||
11 | // ça fonctionne avec les logiciels choisis: gimp, scribus | ||
12 | // mais ça pourrait ne pas convenir | ||
13 | |||
14 | $command = 'nohup ' . $app; // détache l'appli du script PHP | ||
15 | if($path !== '') | ||
16 | { | ||
17 | $command .= ' ' . $path; | ||
18 | } | ||
19 | $command .= ' > /dev/null 2>&1 &'; | ||
20 | // stdout > /dev/null et & permettent de rendre la main à PHP | ||
21 | // stderr > stdout pour cacher un message inutile | ||
22 | return $command; | ||
23 | } | ||
24 | |||
25 | function recherche_client(string $saisie): array | ||
26 | { | ||
27 | $resultats = []; | ||
28 | |||
29 | // recherche dans la BDD | ||
30 | |||
31 | |||
32 | return($resultats); | ||
33 | } | ||
34 | |||
35 | // compilation à partir d'un fichier .tex | ||
36 | function latexToPdf(string $fileName, string $latexPath, string $pdfPath) | ||
37 | { | ||
38 | $outputDir = ''; | ||
39 | if($pdfPath !== '') | ||
40 | { | ||
41 | $outputDir = '-output-directory=' . $pdfPath . ' '; | ||
42 | } | ||
43 | |||
44 | // compilation | ||
45 | exec('pdflatex ' . $outputDir . $latexPath . $fileName); | ||
46 | |||
47 | // nettoyage | ||
48 | $basename = basename($fileName, '.tex'); | ||
49 | unlink($pdfPath . $basename . '.aux'); | ||
50 | unlink($pdfPath . $basename . '.log'); | ||
51 | } | ||
diff --git a/src/latex_templates/devis.php b/src/latex_templates/devis.php new file mode 100644 index 0000000..7df98e8 --- /dev/null +++ b/src/latex_templates/devis.php | |||
@@ -0,0 +1,84 @@ | |||
1 | <?php | ||
2 | ob_start(); | ||
3 | ?> | ||
4 | \documentclass{report} | ||
5 | |||
6 | \usepackage[french]{babel} | ||
7 | \usepackage{lmodern} % police latin modern | ||
8 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
9 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
10 | \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} % marges | ||
11 | \usepackage{graphicx} % insertions d'images | ||
12 | \usepackage{textcomp} % pour N° | ||
13 | \usepackage{xcolor} % texte en couleur | ||
14 | \usepackage{tabularx} % dimensions des tableaux automatique | ||
15 | \usepackage{tikz} % le rectangle | ||
16 | |||
17 | \begin{document} | ||
18 | \setlength{\parindent}{0cm} % supprimer les alinéas | ||
19 | \large{} | ||
20 | \pagestyle{empty} % en-tête et pied de page vides | ||
21 | \definecolor{vert}{rgb}{0.07, 0.46, 0.13} % saisie en vert | ||
22 | |||
23 | \begin{center} | ||
24 | \includegraphics{ordipolo.png}\\ | ||
25 | \Large\textbf{Dépannage informatique - Assistance à domicile} | ||
26 | \end{center} | ||
27 | |||
28 | 2 A rue de l'île de Man, 29000 Quimper | ||
29 | |||
30 | SIRET : 814 320 610 00011 | ||
31 | |||
32 | \begin{tabularx}{0.67\linewidth}{@{}X@{}@{}X@{}} | ||
33 | Tel : 06.63.85.48.82 & Courriel : ordipolo@gmx.fr | ||
34 | \end{tabularx} | ||
35 | |||
36 | Plus d'infos sur le site web: https\string://ordipolo.fr\\ | ||
37 | % \string supprime l'espace devant les : | ||
38 | |||
39 | \begin{center} | ||
40 | \large\textbf{DEVIS} | ||
41 | \end{center} | ||
42 | |||
43 | CLIENT\\ | ||
44 | |||
45 | \begin{tabularx}{\linewidth}{@{}X@{}@{}X@{}} | ||
46 | Mme, M : \textcolor{vert}{} & | ||
47 | Date du devis : \textcolor{vert}{}\\ | ||
48 | Adresse : \textcolor{vert}{} & | ||
49 | Delai de livraison : \textcolor{vert}{}\\ | ||
50 | \end{tabularx}\\\\ | ||
51 | |||
52 | PRESTATION\\ | ||
53 | |||
54 | \textcolor{vert}{} | ||
55 | |||
56 | Total main d'oeuvre : \textcolor{vert}{}\\ | ||
57 | |||
58 | PIÈCES\\ | ||
59 | |||
60 | \textcolor{vert}{} | ||
61 | |||
62 | Total pièces : \textcolor{vert}{}\\ | ||
63 | |||
64 | TOTAL\\ | ||
65 | |||
66 | Déplacement : \textcolor{vert}{} | ||
67 | |||
68 | Total HT : \textcolor{vert}{} | ||
69 | |||
70 | \textit{(TVA non applicable, article 293B du code général des impôts)} | ||
71 | |||
72 | Référence du devis : \textcolor{vert}{}\\ | ||
73 | |||
74 | Devis reçu avant l'exécution des travaux, signature du client :\\ | ||
75 | \begin{tikzpicture} | ||
76 | \draw (0,0) rectangle (4,2); | ||
77 | \end{tikzpicture}\\ | ||
78 | |||
79 | \small{}NOTA BENE\\ | ||
80 | |||
81 | Si le délai de livraison n’est pas précisé, c’est naturellement le délai légal de 30 jours qui est appliqué. Lorsqu'Ordi Polo garde (ou prête) un ordinateur le temps nécessaire à la réparation, le prêt peut être formalisé par un document signé par les deux parties. Le dépannage inclut principalement l'intervention sur les logiciels et si nécessaire le démontage et remontage de la machine nécessaires au nettoyage de la poussière ou au remplacement d'une pièce. Ordi Polo ne répare pas les composants électroniques défectueux et n'est pas responsable des dysfonctionnements de l'ordinateur dont l'origine est matérielle. Ordi Polo ne vend pas de matériel mais peut conseiller ou réaliser les démarches d’un achat. | ||
82 | \end{document} | ||
83 | <?php | ||
84 | $devisLatex = ob_get_clean(); | ||
diff --git a/src/latex_templates/enveloppe_recto.php b/src/latex_templates/enveloppe_recto.php new file mode 100644 index 0000000..38003a1 --- /dev/null +++ b/src/latex_templates/enveloppe_recto.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | ob_start(); | ||
3 | ?> | ||
4 | \documentclass[]{report} | ||
5 | |||
6 | \usepackage[french]{babel} | ||
7 | \usepackage{lmodern} % police latin modern | ||
8 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
9 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
10 | \usepackage{graphicx} % insertions d'images | ||
11 | \usepackage[papersize={22cm, 11cm}, top=1cm, left=1cm, bottom=1cm]{geometry} | ||
12 | \pagestyle{empty} | ||
13 | |||
14 | \begin{document} | ||
15 | \setlength{\parindent}{0cm} | ||
16 | \includegraphics{ordipolo.png}\\ | ||
17 | \large\textbf{Dépannage informatique - Assistance à domicile} | ||
18 | |||
19 | \setlength{\parindent}{7,9cm} | ||
20 | \begin{minipage}[b][5,8cm]{12cm} | ||
21 | \LARGE{M. Truc\\3, rue Machin\\\\\\} | ||
22 | \LARGE{2 \ 9 \ 0 \ 0 \ 0 \ \ \ \ QUIMPER} | ||
23 | \end{minipage} | ||
24 | \end{document} | ||
25 | <?php | ||
26 | $enveloppeRectoLatex = ob_get_clean(); | ||
diff --git a/src/latex_templates/enveloppe_verso.php b/src/latex_templates/enveloppe_verso.php new file mode 100644 index 0000000..51f5f4d --- /dev/null +++ b/src/latex_templates/enveloppe_verso.php | |||
@@ -0,0 +1,18 @@ | |||
1 | <?php | ||
2 | ob_start(); | ||
3 | ?> | ||
4 | \documentclass[]{report} | ||
5 | |||
6 | \usepackage[french]{babel} | ||
7 | \usepackage{lmodern} % police latin modern | ||
8 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
9 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
10 | \usepackage[papersize={22cm, 11cm}, top=0.6cm, left=4.5cm]{geometry} | ||
11 | \pagestyle{empty} | ||
12 | |||
13 | \begin{document} | ||
14 | \setlength{\parindent}{0cm} | ||
15 | \Large{Paul Jusot\\2A, rue de l'île de Man\\29000 QUIMPER} | ||
16 | \end{document} | ||
17 | <?php | ||
18 | $enveloppeVersoLatex = ob_get_clean(); | ||
diff --git a/src/latex_templates/facture.php b/src/latex_templates/facture.php new file mode 100644 index 0000000..409dd9a --- /dev/null +++ b/src/latex_templates/facture.php | |||
@@ -0,0 +1,85 @@ | |||
1 | <?php | ||
2 | ob_start(); | ||
3 | ?> | ||
4 | \documentclass{report} | ||
5 | |||
6 | \usepackage[french]{babel} | ||
7 | \usepackage{lmodern} % police latin modern | ||
8 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
9 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
10 | \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} % marges | ||
11 | \usepackage{graphicx} % insertions d'images | ||
12 | \usepackage{textcomp} % pour N° | ||
13 | \usepackage{xcolor} % texte en couleur | ||
14 | \usepackage{tabularx} % dimensions des tableaux automatique | ||
15 | |||
16 | \begin{document} | ||
17 | \setlength{\parindent}{0cm} % supprimer les alinéas | ||
18 | \large{} | ||
19 | \pagestyle{empty} % en-tête et pied de page vides | ||
20 | \definecolor{vert}{rgb}{0.07, 0.46, 0.13} % saisie en vert | ||
21 | |||
22 | \begin{center} | ||
23 | \includegraphics{ordipolo.png}\\ | ||
24 | \Large\textbf{Dépannage informatique - Assistance à domicile} | ||
25 | \end{center} | ||
26 | |||
27 | 2 A rue de l'île de Man, 29000 Quimper | ||
28 | |||
29 | SIRET : 814 320 610 00011 | ||
30 | |||
31 | \begin{tabularx}{0.67\linewidth}{@{}X@{}@{}X@{}} | ||
32 | Tel : 06.63.85.48.82 & Courriel : ordipolo@gmx.fr | ||
33 | \end{tabularx} | ||
34 | |||
35 | Plus d'infos sur le site web: https\string://ordipolo.fr\\ | ||
36 | % \string supprime l'espace devant les : | ||
37 | |||
38 | \begin{center} | ||
39 | \large\textbf{FACTURE} | ||
40 | \end{center} | ||
41 | |||
42 | CLIENT\\ | ||
43 | |||
44 | \begin{tabularx}{\linewidth}{@{}X@{}@{}X@{}} | ||
45 | Mme, M : \textcolor{vert}{} & | ||
46 | Date : \textcolor{vert}{}\\ | ||
47 | \end{tabularx}\\ | ||
48 | Adresse : \textcolor{vert}{}\\ | ||
49 | |||
50 | PRESTATION\\ | ||
51 | |||
52 | \textcolor{vert}{} | ||
53 | |||
54 | Modèle de l'ordinateur : \textcolor{vert}{} | ||
55 | |||
56 | Système d'exploitation : \textcolor{vert}{} | ||
57 | |||
58 | Données à conserver : \textcolor{vert}{} | ||
59 | |||
60 | Clé d'activation : \textcolor{vert}{}\\ | ||
61 | |||
62 | Total main d'oeuvre : \textcolor{vert}{}\\ | ||
63 | |||
64 | PIÈCES\\ | ||
65 | |||
66 | \textcolor{vert}{} | ||
67 | |||
68 | Total pièces : \textcolor{vert}{}\\ | ||
69 | |||
70 | TOTAL\\ | ||
71 | |||
72 | Déplacement : \textcolor{vert}{} | ||
73 | |||
74 | Total HT : \textcolor{vert}{} | ||
75 | |||
76 | \textit{(TVA non applicable, article 293B du code général des impôts)} | ||
77 | |||
78 | Référence de la facture : \textcolor{vert}{}\\ | ||
79 | |||
80 | \small{}NOTA BENE\\ | ||
81 | |||
82 | Lorsqu'Ordi Polo garde (ou prête) un ordinateur le temps nécessaire à la réparation, le prêt peut être formalisé par un document signé par les deux parties. Le dépannage inclut principalement l'intervention sur les logiciels et si nécessaire le démontage et remontage de la machine nécessaires au nettoyage de la poussière ou au remplacement d'une pièce. Ordi Polo ne répare pas les composants électroniques défectueux et n'est pas responsable des dysfonctionnements de l'ordinateur dont l'origine est matérielle. Ordi Polo ne vend pas de matériel mais peut conseiller ou réaliser les démarches d’un achat. | ||
83 | \end{document} | ||
84 | <?php | ||
85 | $factureLatex = ob_get_clean(); | ||
diff --git a/src/latex_templates/location.php b/src/latex_templates/location.php new file mode 100644 index 0000000..dc4ea3e --- /dev/null +++ b/src/latex_templates/location.php | |||
@@ -0,0 +1,49 @@ | |||
1 | <?php | ||
2 | ob_start(); | ||
3 | ?> | ||
4 | \documentclass{report} | ||
5 | |||
6 | \usepackage[french]{babel} | ||
7 | \usepackage{lmodern} % police latin modern | ||
8 | \usepackage[utf8]{inputenc} % encodage d'entrée (document) | ||
9 | \usepackage[T1]{fontenc} % encodage de sortie (rendu) | ||
10 | \usepackage[top=2cm, bottom=2cm, left=2cm, right=2cm]{geometry} % marges | ||
11 | \usepackage{graphicx} % insertions d'images | ||
12 | \usepackage{textcomp} % pour N° | ||
13 | \usepackage{xcolor} % texte en couleur | ||
14 | %\usepackage{wrapfig} % placer texte et image côte-à-côte | ||
15 | \usepackage{tabularx} % dimensions des tableaux automatique | ||
16 | |||
17 | \begin{document} | ||
18 | \setlength{\parindent}{0cm} % supprimer les alinéas | ||
19 | \large{} | ||
20 | \pagestyle{empty} % en-tête et pied de page vides | ||
21 | \definecolor{vert}{rgb}{0.07, 0.46, 0.13} % saisie en vert | ||
22 | |||
23 | \begin{center} | ||
24 | \includegraphics{ordipolo.png}\\ | ||
25 | \Large\textbf{Dépannage informatique - Assistance à domicile} | ||
26 | \end{center} | ||
27 | |||
28 | 2 A rue de l'île de Man, 29000 Quimper | ||
29 | |||
30 | SIRET : 814 320 610 00011 | ||
31 | |||
32 | \begin{tabularx}{0.67\linewidth}{@{}X@{}@{}X@{}} | ||
33 | Tel : 06.63.85.48.82 & Courriel : ordipolo@gmx.fr | ||
34 | \end{tabularx} | ||
35 | |||
36 | Plus d'infos sur le site web: https\string://ordipolo.fr\\ | ||
37 | % \string supprime l'espace devant les : | ||
38 | |||
39 | CLIENT\\ | ||
40 | |||
41 | \begin{tabularx}{\linewidth}{@{}X@{}@{}X@{}} | ||
42 | Mme, M : \textcolor{vert}{} & | ||
43 | Date : \textcolor{vert}{}\\ | ||
44 | \end{tabularx}\\ | ||
45 | Adresse : \textcolor{vert}{}\\ | ||
46 | |||
47 | \end{document} | ||
48 | <?php | ||
49 | $locationLatex = ob_get_clean(); | ||
diff --git a/src/main.php b/src/main.php new file mode 100755 index 0000000..e890744 --- /dev/null +++ b/src/main.php | |||
@@ -0,0 +1,239 @@ | |||
1 | #!/bin/php | ||
2 | <?php | ||
3 | // php/main.php | ||
4 | |||
5 | // configuration du programme par l'utilisateur | ||
6 | require('../config.php'); // fichier de l'utilisateur: à déplacer peut-être dans un dossier config | ||
7 | //require('config_window.php'); // configuration user-friendly et assistée avec des messages d'erreur et des indications | ||
8 | //require('config_check.php'); // contrôle de config.php | ||
9 | |||
10 | // variables diverses, certaines utilisent les variables de config.php | ||
11 | $exec_mode = 'gui'; // les versions pure console (CLI) et serveur web (CGI) de ce programme ne sont pas prévues pour l'instant | ||
12 | $file_explorer = 'xdg-open'; // ouvre l'explorateur de fichiers par défaut quand suivi d'un chemin en paramètre | ||
13 | $flyer = $pub . $flyer; | ||
14 | $business_card = $pub . $business_card; | ||
15 | $db_place .= $db_name . '.sqlite'; | ||
16 | $sqlitebrowser_enable = false; | ||
17 | $sqlite_cli = ''; // commande sqlite ou sqlite3 | ||
18 | $x_term_command = ''; // commande terminal en mode graphique | ||
19 | |||
20 | require('dependances.php'); // vérification des dépendances | ||
21 | require('functions.php'); | ||
22 | require('Dates.php'); // gère dates et timestamps | ||
23 | Dates::$date_format = $date_format; // dates européennes ou américaines | ||
24 | |||
25 | require('model/DB.php'); // connexion en héritant de PDO | ||
26 | DB::$dsn = 'sqlite:' . $db_place; // Data Source Name = 1er paramètre du constructeur de PDO: $bdd = new PDO($dsn); | ||
27 | |||
28 | require('model/Model.php'); // class Model extends DB, requêtes SQL | ||
29 | require('model/StructTablesDB.php'); | ||
30 | Model::createTables(); | ||
31 | |||
32 | require('model/Clients.php'); | ||
33 | require('model/Prestations.php'); | ||
34 | require('model/DevisFactures.php'); | ||
35 | require('model/CESU.php'); | ||
36 | require('model/Locations.php'); | ||
37 | |||
38 | // instancier et supprimer à chaque fois quand nécessaire | ||
39 | $Client = new Clients(); | ||
40 | $Client->setPrenom_nom('Jean Némar')->setAdresse('10, rue des douves')->setCode_client('464653476')->setCommentaires('un peu chiant'); | ||
41 | $Client->create(); | ||
42 | |||
43 | // même chose avec un tableau en entrée au lieu d'écrire toutes les méthodes | ||
44 | $input = ['prenom_nom' => 'Eva Casquer', 'adresse' => "2, place d'Écosse", 'code_client' => '958465875', 'commentaires' => 'bonne vache à lait']; | ||
45 | $Client->hydrate($input); | ||
46 | $Client->create(); | ||
47 | |||
48 | $input = ['prenom_nom' => 'Eva Paparla', 'commentaires' => 'grosse nunuche']; | ||
49 | $Client->hydrate($input); | ||
50 | $Client->update(2); | ||
51 | |||
52 | $Client->delete(3); | ||
53 | |||
54 | //$Date = new Dates; | ||
55 | |||
56 | |||
57 | require('view/Zenity.php'); // commande système zenity | ||
58 | require('view/zenity_setup.php'); // texte dans les fenêtres ET instanciation (un objet = une commande) | ||
59 | require('Latex.php'); // générer le code LaTeX | ||
60 | |||
61 | // injection de variables dans le document | ||
62 | // problème à régler: et si je veux faire une deuxième facture? | ||
63 | //~ include('latex_templates/devis.php'); | ||
64 | //~ include('latex_templates/facture.php'); | ||
65 | //~ include('latex_templates/enveloppe_recto.php'); | ||
66 | //~ include('latex_templates/enveloppe_verso.php'); | ||
67 | //~ include('latex_templates/location.php'); | ||
68 | |||
69 | |||
70 | // boucle principale | ||
71 | $boucle = true; | ||
72 | while($boucle) | ||
73 | { | ||
74 | // menu principal | ||
75 | $choix_niv1 = exec($MenuPrincipal->get()); | ||
76 | |||
77 | // enregistrement | ||
78 | if($choix_niv1 === $menu_principal_entrees[0]) // = Nouvelle prestation | ||
79 | { | ||
80 | // est ce que le client est déjà dans la base? | ||
81 | if(exec($QuestionNouveauClient->get()) === 0) // $? = 0 signifie oui | ||
82 | { | ||
83 | // saisie du nom du client et recherche | ||
84 | $client_saisie = exec($RechercheClient->get()); | ||
85 | |||
86 | // sélection parmi les résultats | ||
87 | $ResultatsRechercheClient->setEntries(recherche_client($client_saisie)); | ||
88 | $choix_niv2 = exec($ResultatsRechercheClient->get()); | ||
89 | if($choix_niv2 !== '') | ||
90 | { | ||
91 | echo "client trouvé\n"; | ||
92 | } | ||
93 | else // chaîne vide | ||
94 | { | ||
95 | echo "client pas trouvé\n"; | ||
96 | exec($NouveauClient->get()); | ||
97 | |||
98 | // enregistrement dans la BDD | ||
99 | |||
100 | } | ||
101 | |||
102 | // récupération des infos dans la BDD | ||
103 | |||
104 | } | ||
105 | else | ||
106 | { | ||
107 | echo "nouveau client\n"; | ||
108 | exec($NouveauClient->get()); | ||
109 | |||
110 | // enregistrement dans la BDD | ||
111 | |||
112 | } | ||
113 | |||
114 | // choix type comptable: devis, facture, cesu | ||
115 | $choix_niv2 = exec($MenuEnregistrement->get()); | ||
116 | $continuer = true; | ||
117 | if($choix_niv2 === $menu_enregistrement_entrees[0]) | ||
118 | { | ||
119 | // | ||
120 | } | ||
121 | elseif($choix_niv2 === $menu_enregistrement_entrees[1]) | ||
122 | { | ||
123 | // | ||
124 | } | ||
125 | elseif($choix_niv2 === $menu_enregistrement_entrees[2]) | ||
126 | { | ||
127 | // | ||
128 | } | ||
129 | elseif($choix_niv2 === $menu_enregistrement_entrees[3]) | ||
130 | { | ||
131 | // | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | $continuer = false; // retour menu principal | ||
136 | } | ||
137 | |||
138 | // détail de la prestation | ||
139 | if($continuer) | ||
140 | { | ||
141 | exec($Calendrier->get()); | ||
142 | exec($FormulairePrestation->get()); | ||
143 | // enregistrement date et prestation en BDD | ||
144 | exec($CommentairePrestation->get()); | ||
145 | // enregistrement commentaire en BDD | ||
146 | // vérification? | ||
147 | |||
148 | // tableau récaptilatif et demande de confirmation des informations | ||
149 | // création fichiers LaTeX et PDF | ||
150 | |||
151 | // imprimer? | ||
152 | //~ $imprimer_facture = exec('zenity --question --width=250 --title="Base de données mise à jour" --text="Imprimer la facture?"'); | ||
153 | //~ $imprimer_enveloppe = exec('zenity --question --width=250 --title="Base de données mise à jour" --text="Imprimer l\'adresse sur une enveloppe? (insérer une enveloppe DL sans fenêtre dans l\'imprimante"'); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | elseif($choix_niv1 === $menu_principal_entrees[1]) // = Modifier un enregistrement | ||
158 | {} | ||
159 | |||
160 | elseif($choix_niv1 === $menu_principal_entrees[2]) // = Fichier clients | ||
161 | { | ||
162 | // quel affichage? un grand tableau avec zenity? une page web? un document LaTeX? | ||
163 | } | ||
164 | |||
165 | // documents à imprimer | ||
166 | elseif($choix_niv1 === $menu_principal_entrees[3]) // = Créer/imprimer un document | ||
167 | { | ||
168 | $choix_niv2 = exec($MenuDocuments->get()); | ||
169 | if($choix_niv2 === $menu_documents_entrees[0]) | ||
170 | { | ||
171 | |||
172 | } | ||
173 | elseif($choix_niv2 === $menu_documents_entrees[1]) // = Facture | ||
174 | { | ||
175 | |||
176 | } | ||
177 | elseif($choix_niv2 === $menu_documents_entrees[2]) // = Lettre avec adresse | ||
178 | { | ||
179 | |||
180 | } | ||
181 | elseif($choix_niv2 === $menu_documents_entrees[3]) // = Livre des recettes | ||
182 | { | ||
183 | |||
184 | } | ||
185 | elseif($choix_niv2 === $menu_documents_entrees[4]) // = Registre des achats | ||
186 | { | ||
187 | |||
188 | } | ||
189 | elseif($choix_niv2 === $menu_documents_entrees[5]) // = Bilan annuel | ||
190 | { | ||
191 | |||
192 | } | ||
193 | else | ||
194 | { | ||
195 | // retour menu principal | ||
196 | } | ||
197 | } | ||
198 | |||
199 | // Supports de communication | ||
200 | elseif($choix_niv1 === $menu_principal_entrees[4]) // = Communication | ||
201 | { | ||
202 | $choix_niv2 = exec($MenuCommunication->get()); | ||
203 | if($choix_niv2 === $menu_communication_entrees[0]) // = Flyer (nécessite gimp) | ||
204 | { | ||
205 | exec(window_app_command($image_editor, $flyer)); | ||
206 | } | ||
207 | elseif($choix_niv2 === $menu_communication_entrees[1]) // = Carte de visite (nécessite scribus) | ||
208 | { | ||
209 | exec(window_app_command($publishing, $business_card)); | ||
210 | } | ||
211 | elseif($choix_niv2 === $menu_communication_entrees[2]) // = Explorateur de fichiers | ||
212 | { | ||
213 | exec(window_app_command($file_explorer, $pub)); | ||
214 | } | ||
215 | else | ||
216 | { | ||
217 | // retour menu principal | ||
218 | } | ||
219 | } | ||
220 | |||
221 | // BDD | ||
222 | elseif($choix_niv1 === $menu_principal_entrees[5]) // = Base de données | ||
223 | { | ||
224 | if($sqlitebrowser_enable) | ||
225 | { | ||
226 | exec(window_app_command($sqlite_gui, $db_place)); | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | exec($x_term_command . ' ' . $sqlite_cli . ' ' . $db_place); // correpond à priori à: xterm -e sqlite3 ~/ORDIPOLO/Appli_PHP/ordipolo.sqlite | ||
231 | } | ||
232 | } | ||
233 | |||
234 | // arrêt | ||
235 | else | ||
236 | { | ||
237 | $boucle = false; | ||
238 | } | ||
239 | } | ||
diff --git a/src/model/CESU.php b/src/model/CESU.php new file mode 100644 index 0000000..4679da2 --- /dev/null +++ b/src/model/CESU.php | |||
@@ -0,0 +1,46 @@ | |||
1 | <?php | ||
2 | // model/CESU.php | ||
3 | |||
4 | class CESU extends Model | ||
5 | { | ||
6 | const TABLE = 'cesu'; | ||
7 | |||
8 | // lecture des données ou hydratation | ||
9 | private $ID; | ||
10 | private $ID_presta; | ||
11 | private $taches; | ||
12 | private $duree_travail; | ||
13 | private $salaire; | ||
14 | |||
15 | public function __construct() | ||
16 | { | ||
17 | $this->table = self::TABLE; // => Model::$table | ||
18 | } | ||
19 | |||
20 | // setters | ||
21 | public function setID(int $value) | ||
22 | { | ||
23 | $this->ID = $value; | ||
24 | return($this); | ||
25 | } | ||
26 | public function setIDPresta(int $value) | ||
27 | { | ||
28 | $this->ID_presta = $value; | ||
29 | return($this); | ||
30 | } | ||
31 | public function setTaches(string $value) | ||
32 | { | ||
33 | $this->taches = $value; | ||
34 | return($this); | ||
35 | } | ||
36 | public function setDureeTravail(string $value) | ||
37 | { | ||
38 | $this->duree_travail = $value; | ||
39 | return($this); | ||
40 | } | ||
41 | public function setSalaire(float $value) | ||
42 | { | ||
43 | $this->salaire = $value; | ||
44 | return($this); | ||
45 | } | ||
46 | } | ||
diff --git a/src/model/Clients.php b/src/model/Clients.php new file mode 100644 index 0000000..1256458 --- /dev/null +++ b/src/model/Clients.php | |||
@@ -0,0 +1,50 @@ | |||
1 | <?php | ||
2 | // model/Clients.php | ||
3 | |||
4 | class Clients extends Model | ||
5 | { | ||
6 | // lecture des données ou hydratation | ||
7 | public $ID; | ||
8 | public $prenom_nom; | ||
9 | public $adresse; | ||
10 | public $code_client; | ||
11 | public $commentaires; | ||
12 | |||
13 | public function __construct() | ||
14 | { | ||
15 | $this->table = strtolower(__CLASS__); // simple parce que la classe a le nom de la table | ||
16 | } | ||
17 | |||
18 | //~ public function set(string $variable, $value) | ||
19 | //~ { | ||
20 | //~ $this->$variable = $value; | ||
21 | //~ return($this); | ||
22 | //~ } | ||
23 | |||
24 | // setters | ||
25 | public function setID(int $value) // inutile? il s'autoincrémente | ||
26 | { | ||
27 | $this->ID = $value; | ||
28 | return($this); | ||
29 | } | ||
30 | public function setPrenom_nom(string $value) | ||
31 | { | ||
32 | $this->prenom_nom = $value; | ||
33 | return($this); | ||
34 | } | ||
35 | public function setAdresse(string $value) | ||
36 | { | ||
37 | $this->adresse = $value; | ||
38 | return($this); | ||
39 | } | ||
40 | public function setCode_client(string $value) | ||
41 | { | ||
42 | $this->code_client = $value; | ||
43 | return($this); | ||
44 | } | ||
45 | public function setCommentaires(string $value) | ||
46 | { | ||
47 | $this->commentaires = $value; | ||
48 | return($this); | ||
49 | } | ||
50 | } | ||
diff --git a/src/model/DB.php b/src/model/DB.php new file mode 100644 index 0000000..381623b --- /dev/null +++ b/src/model/DB.php | |||
@@ -0,0 +1,48 @@ | |||
1 | <?php | ||
2 | // php/DB.php | ||
3 | |||
4 | // cette classe suit le pattern "singleton" | ||
5 | // but: ne permettre qu'une seule instance de la classe (laquelle sera éventuellement globale) | ||
6 | |||
7 | // comment? | ||
8 | // - Un attribut privé et statique contiendra l'instance unique de la classe | ||
9 | // - Un constructeur privé afin d'empêcher l'instanciation depuis l'extérieur de la classe | ||
10 | // - Une méthode statique qui permet soit d'instancier la classe soit de retourner l'unique instance créée. | ||
11 | |||
12 | class DB extends PDO | ||
13 | { | ||
14 | // paramètres du constructeur de PDO (avec sqlite seul le premier est nécessaire) | ||
15 | public static $dsn = ''; // Data Source Name = 1er paramètre | ||
16 | //~ public static $dbms = 'sqlite'; | ||
17 | //~ public static $user = ''; | ||
18 | //~ public static $password = ''; | ||
19 | //~ public static $options = ''; | ||
20 | private static $Instance; | ||
21 | |||
22 | private function __construct() // exécuté une seul fois à cause du "if" dans getInstance() | ||
23 | { | ||
24 | try | ||
25 | { | ||
26 | parent::__construct(self::$dsn); // => PDO::$dsn | ||
27 | //$this->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8'); // pour mysql/mariadb | ||
28 | $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // $this pour la méthode du parent PDO | ||
29 | $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // pour PDO:fetch() et PDO::fetchAll() | ||
30 | // avec PDO::FETCH_ASSOC on obtient un tableau associatif, marche très bien puisqu'on utilise déjà des ID avec incrémentation automatique | ||
31 | // avec PDO::FETCH_BOTH (par défaut) on récupère les données en double (identifiants partant de 0 + tableau associatif) | ||
32 | } | ||
33 | catch(PDOException $e) | ||
34 | { | ||
35 | die("Impossible de se connecter à la base de données.\n" . $e->getMessage()); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | // créer son objet avec: $Bdd = parent::getInstance(); | ||
40 | public static function getInstance(): self | ||
41 | { | ||
42 | if(self::$Instance === null) | ||
43 | { | ||
44 | self::$Instance = new self(); | ||
45 | } | ||
46 | return self::$Instance; | ||
47 | } | ||
48 | } | ||
diff --git a/src/model/DevisFactures.php b/src/model/DevisFactures.php new file mode 100644 index 0000000..be733dd --- /dev/null +++ b/src/model/DevisFactures.php | |||
@@ -0,0 +1,98 @@ | |||
1 | <?php | ||
2 | // model/DevisFactures.php | ||
3 | |||
4 | class DevisFactures extends Model | ||
5 | { | ||
6 | // lecture des données ou hydratation | ||
7 | private $ID; | ||
8 | private $ID_presta; | ||
9 | private $validite_devis; | ||
10 | private $signature_devis; | ||
11 | private $taches; | ||
12 | private $machine; | ||
13 | private $OS; | ||
14 | private $donnees; | ||
15 | private $cles_licences; | ||
16 | private $total_main_d_oeuvre; | ||
17 | private $pieces; | ||
18 | private $total_pieces; | ||
19 | private $deplacement; | ||
20 | private $total_HT; | ||
21 | |||
22 | public function __construct() | ||
23 | { | ||
24 | $this->table = strtolower(__CLASS__); | ||
25 | } | ||
26 | |||
27 | // setters | ||
28 | public function setID(int $value) | ||
29 | { | ||
30 | $this->ID = $value; | ||
31 | return($this); | ||
32 | } | ||
33 | public function setIDPresta(int $value) | ||
34 | { | ||
35 | $this->ID_presta = $value; | ||
36 | return($this); | ||
37 | } | ||
38 | public function setValiditeDdevis(string $value) | ||
39 | { | ||
40 | $this->validite_devis = $value; | ||
41 | return($this); | ||
42 | } | ||
43 | public function setSignatureDevis(string $value) | ||
44 | { | ||
45 | $this->signature_devis = $value; | ||
46 | return($this); | ||
47 | } | ||
48 | public function setTaches(string $value) | ||
49 | { | ||
50 | $this->taches = $value; | ||
51 | return($this); | ||
52 | } | ||
53 | public function setMachine(string $value) | ||
54 | { | ||
55 | $this->machine = $value; | ||
56 | return($this); | ||
57 | } | ||
58 | public function setOS(string $value) | ||
59 | { | ||
60 | $this->OS = $value; | ||
61 | return($this); | ||
62 | } | ||
63 | public function setDonnees(string $value) | ||
64 | { | ||
65 | $this->donnees = $value; | ||
66 | return($this); | ||
67 | } | ||
68 | public function setClesLicences(string $value) | ||
69 | { | ||
70 | $this->cles_licences = $value; | ||
71 | return($this); | ||
72 | } | ||
73 | public function setTotalMainDOeuvre(float $value) | ||
74 | { | ||
75 | $this->total_main_d_oeuvre = $value; | ||
76 | return($this); | ||
77 | } | ||
78 | public function setPieces(string $value) | ||
79 | { | ||
80 | $this->pieces = $value; | ||
81 | return($this); | ||
82 | } | ||
83 | public function setTotalPieces(float $value) | ||
84 | { | ||
85 | $this->total_pieces = $value; | ||
86 | return($this); | ||
87 | } | ||
88 | public function setDeplacement(float $value) | ||
89 | { | ||
90 | $this->deplacement = $value; | ||
91 | return($this); | ||
92 | } | ||
93 | public function setTotalHT(float $value) | ||
94 | { | ||
95 | $this->total_HT = $value; | ||
96 | return($this); | ||
97 | } | ||
98 | } | ||
diff --git a/src/model/Locations.php b/src/model/Locations.php new file mode 100644 index 0000000..2aa175a --- /dev/null +++ b/src/model/Locations.php | |||
@@ -0,0 +1,74 @@ | |||
1 | <?php | ||
2 | // model/Locations.php | ||
3 | |||
4 | class Locations extends Model | ||
5 | { | ||
6 | // lecture des données ou hydratation | ||
7 | private $ID; | ||
8 | private $ID_presta; | ||
9 | private $nature_bien; | ||
10 | private $modele; | ||
11 | private $valeur; | ||
12 | private $etat_des_lieux_debut; | ||
13 | private $etat_des_lieux_fin; | ||
14 | private $duree_location; | ||
15 | private $loyer_mensuel; | ||
16 | private $total_HT; | ||
17 | |||
18 | public function __construct() | ||
19 | { | ||
20 | $this->table = strtolower(__CLASS__); | ||
21 | } | ||
22 | |||
23 | // setters | ||
24 | public function setID(int $value) | ||
25 | { | ||
26 | $this->ID = $value; | ||
27 | return($this); | ||
28 | } | ||
29 | public function setIDPresta(int $value) | ||
30 | { | ||
31 | $this->ID_presta = $value; | ||
32 | return($this); | ||
33 | } | ||
34 | public function setNatureBien(string $value) | ||
35 | { | ||
36 | $this->nature_bien = $value; | ||
37 | return($this); | ||
38 | } | ||
39 | public function setModele(string $value) | ||
40 | { | ||
41 | $this->modele = $value; | ||
42 | return($this); | ||
43 | } | ||
44 | public function setValeur(float $value) | ||
45 | { | ||
46 | $this->valeur = $value; | ||
47 | return($this); | ||
48 | } | ||
49 | public function setEtatDesLieuxDebut(string $value) | ||
50 | { | ||
51 | $this->etat_des_lieux_debut = $value; | ||
52 | return($this); | ||
53 | } | ||
54 | public function setEtatDesLieuxFin(string $value) | ||
55 | { | ||
56 | $this->etat_des_lieux_fin = $value; | ||
57 | return($this); | ||
58 | } | ||
59 | public function setDureeLocation(string $value) | ||
60 | { | ||
61 | $this->duree_location = $value; | ||
62 | return($this); | ||
63 | } | ||
64 | public function setlLyerMensuel(float $value) | ||
65 | { | ||
66 | $this->loyer_mensuel = $value; | ||
67 | return($this); | ||
68 | } | ||
69 | public function setTotalHT(float $value) | ||
70 | { | ||
71 | $this->total_HT = $value; | ||
72 | return($this); | ||
73 | } | ||
74 | } | ||
diff --git a/src/model/Model.php b/src/model/Model.php new file mode 100644 index 0000000..ad9e6c7 --- /dev/null +++ b/src/model/Model.php | |||
@@ -0,0 +1,162 @@ | |||
1 | <?php | ||
2 | // php/Model.php | ||
3 | |||
4 | class Model extends DB | ||
5 | { | ||
6 | private $db; // instance de PDO | ||
7 | protected $table; // <= enfant | ||
8 | //static protected $tableStructure; | ||
9 | |||
10 | public function __construct() | ||
11 | { | ||
12 | $this->db = parent::getInstance(); // connexion | ||
13 | } | ||
14 | |||
15 | |||
16 | // setters (plusieurs en même temps) | ||
17 | public function hydrate(array $data) // $data = tableau associatif en entrée: nom_du_champ => valeur | ||
18 | { | ||
19 | foreach($data as $key => $value) | ||
20 | { | ||
21 | // nom d'un setter, forme "setMachin()" | ||
22 | $setterName = 'set' . ucfirst($key); // ucfirst met la première lettre en majuscule | ||
23 | // détection | ||
24 | if(method_exists($this, $setterName)) // on trouve aussi la méthode is_callable() | ||
25 | { | ||
26 | // on renseigne les propriétés des l'instance | ||
27 | $this->$setterName($value); // nom d'une méthode dans une variable | ||
28 | } | ||
29 | } | ||
30 | return($this); | ||
31 | } | ||
32 | |||
33 | |||
34 | // exécuter le SQL | ||
35 | // les attributs correspondent aux ? dans les requêtes préparées | ||
36 | // ne pas surcharger la méthode PDO::query() qui n'est pas compatible | ||
37 | protected function execQuery(string $sql, array $attributes = null) | ||
38 | { | ||
39 | $this->db = parent::getInstance(); // connexion | ||
40 | |||
41 | if($attributes !== null) // requête préparée | ||
42 | { | ||
43 | $query = $this->db->prepare($sql); | ||
44 | $query->execute($attributes); | ||
45 | return $query; | ||
46 | } | ||
47 | else // requête simple | ||
48 | { | ||
49 | return $this->db->query($sql); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | |||
54 | // méthodes CRUD qui marchent (les spécifiques sont dans les classes enfant) | ||
55 | |||
56 | // create INSERT | ||
57 | public function create() // = write | ||
58 | { | ||
59 | $fields = []; | ||
60 | $question_marks = []; // ? | ||
61 | $values = []; | ||
62 | foreach($this as $field => $value) | ||
63 | { | ||
64 | // champs non renseignées et variables de l'objet qui ne sont pas des champs | ||
65 | // note: avec le !== (au lieu de !=) une valeur 0 passe le filtre | ||
66 | if($value !== null && $field != 'db' && $field != 'table') | ||
67 | { | ||
68 | $fields[] = $field; // push | ||
69 | $question_marks[] = '?'; | ||
70 | $values[] = $value; | ||
71 | } | ||
72 | } | ||
73 | $field_list = implode(', ', $fields); | ||
74 | $question_mark_list = implode(', ', $question_marks); | ||
75 | |||
76 | // INSERT INTO annonces (titre, description, actif) VALUES (?, ?, ?) | ||
77 | return($this->execQuery('INSERT INTO ' . $this->table . ' (' . $field_list . ') VALUES (' . $question_mark_list . ')', $values)); | ||
78 | } | ||
79 | |||
80 | |||
81 | // read SELECT | ||
82 | public function readAll() | ||
83 | { | ||
84 | $query = $this->execQuery('SELECT * FROM ' . $this->table . ';'); // fonctionne aussi sans le point virgule dans le SQL!! | ||
85 | return($query->fetchAll()); | ||
86 | } | ||
87 | public function findById(int $id) | ||
88 | { | ||
89 | return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id = ' . $id)->fetch()); | ||
90 | } | ||
91 | |||
92 | public function find(array $criteria) | ||
93 | { | ||
94 | $fields = []; | ||
95 | $values = []; | ||
96 | |||
97 | // change "'ID' => 2" en "'ID' = ?" et "2" | ||
98 | foreach($criteria as $field => $value) | ||
99 | { | ||
100 | $fields[] = "$field = ?"; // même chose que: $field . " = ?" | ||
101 | $values[] = $value; | ||
102 | } | ||
103 | $field_list = implode(' AND ', $fields); // créer une chaîne reliant les morceaux avec le morceau AND en paramètre: 'adresse = ? AND ID = ?' | ||
104 | |||
105 | // SELECT * FROM annonces WHERE actif = 1; | ||
106 | return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE ' . $field_list, $values)->fetchAll()); | ||
107 | } | ||
108 | |||
109 | |||
110 | // update UPDATE | ||
111 | public function update(int $id) | ||
112 | { | ||
113 | $fields = []; | ||
114 | $values = []; | ||
115 | foreach($this as $field => $value) | ||
116 | { | ||
117 | if($value !== null && $field != 'db' && $field != 'table') // champs non renseignées et variables de l'objet qui ne sont pas des champs | ||
118 | { | ||
119 | $fields[] = $field . ' = ?'; | ||
120 | $values[] = $value; | ||
121 | } | ||
122 | } | ||
123 | $values[] = $id; | ||
124 | $field_list = implode(', ', $fields); | ||
125 | |||
126 | // UPDATE annonces SET titre = ?, description = ?, actif = ? WHERE id= ? | ||
127 | return($this->execQuery('UPDATE ' . $this->table . ' SET ' . $field_list . ' WHERE id = ?', $values)); | ||
128 | } | ||
129 | |||
130 | |||
131 | // delete DELETE | ||
132 | public function delete(int $id) | ||
133 | { | ||
134 | return($this->execQuery("DELETE FROM {$this->table} WHERE id = ?", [$id])); // double quotes "" pour insertion de variable, paramètre [$id] parce qu'on veut un tableau | ||
135 | } | ||
136 | |||
137 | |||
138 | // fonction appelée une seule fois pour chaque table | ||
139 | // le tableau nécessaire n'est pas copié en mémoire à l'instanciation (pas de fuite de mémoire), mais uniquement à l'appel de cette fonction statique, à la fin de la fonction la mémoire est libérée | ||
140 | // DBStructure::${self::$tableStructure} permet de nommer une variable statique de classe | ||
141 | static public function createTables() | ||
142 | { | ||
143 | //~ var_dump(StructTablesDB::$structureOfTables); | ||
144 | foreach(StructTablesDB::$structureOfTables as $tableName => $oneTable) | ||
145 | { | ||
146 | //var_dump(StructTablesDB::${self::$tableStructure}); => propriété statique de classe dans une variable | ||
147 | $fields_and_types = []; | ||
148 | $query = 'CREATE TABLE IF NOT EXISTS ' . $tableName . ' ('; | ||
149 | foreach($oneTable as $key => $value) | ||
150 | { | ||
151 | $fields_and_types[] = $key . ' ' . $value; | ||
152 | } | ||
153 | $query .= implode(', ', $fields_and_types); // implode() convertit un tableau en une chaîne avec un séparateur entre chaque élément | ||
154 | $query .= ', PRIMARY KEY(ID AUTOINCREMENT));'; | ||
155 | //echo($query . "\n\n"); | ||
156 | |||
157 | parent::getInstance()->exec($query); // merci singleton! | ||
158 | } | ||
159 | |||
160 | |||
161 | } | ||
162 | } | ||
diff --git a/src/model/Prestations.php b/src/model/Prestations.php new file mode 100644 index 0000000..4f58d70 --- /dev/null +++ b/src/model/Prestations.php | |||
@@ -0,0 +1,62 @@ | |||
1 | <?php | ||
2 | // model/Prestations.php | ||
3 | |||
4 | class Prestations extends Model | ||
5 | { | ||
6 | // lecture des données ou hydratation | ||
7 | private $ID; | ||
8 | private $IDClient; | ||
9 | private $combientieme_fois; | ||
10 | private $code_presta; | ||
11 | private $date; | ||
12 | private $type; | ||
13 | private $mode_paiement; | ||
14 | private $commentaires; | ||
15 | |||
16 | public function __construct() | ||
17 | { | ||
18 | $this->table = strtolower(__CLASS__); | ||
19 | } | ||
20 | |||
21 | // setters | ||
22 | public function setID(int $value) | ||
23 | { | ||
24 | $this->ID = $value; | ||
25 | return($this); | ||
26 | } | ||
27 | public function setIDClient(int $value) | ||
28 | { | ||
29 | $this->ID_client = $value; | ||
30 | return($this); | ||
31 | } | ||
32 | public function setCombientiemeFois(int $value) | ||
33 | { | ||
34 | $this->combientieme_fois = $value; | ||
35 | return($this); | ||
36 | } | ||
37 | public function setCodePresta(string $value) | ||
38 | { | ||
39 | $this->code_presta = $value; | ||
40 | return($this); | ||
41 | } | ||
42 | public function setDate(int $value) | ||
43 | { | ||
44 | $this->date = $value; | ||
45 | return($this); | ||
46 | } | ||
47 | public function setType(string $value) | ||
48 | { | ||
49 | $this->type = $value; | ||
50 | return($this); | ||
51 | } | ||
52 | public function setModePaiement(string $value) | ||
53 | { | ||
54 | $this->mode_paiement = $value; | ||
55 | return($this); | ||
56 | } | ||
57 | public function setCommentaires(string $value) | ||
58 | { | ||
59 | $this->commentaires = $value; | ||
60 | return($this); | ||
61 | } | ||
62 | } | ||
diff --git a/src/model/StructTablesDB.php b/src/model/StructTablesDB.php new file mode 100644 index 0000000..cf6de5d --- /dev/null +++ b/src/model/StructTablesDB.php | |||
@@ -0,0 +1,35 @@ | |||
1 | <?php | ||
2 | // model/StructTablesDB.php | ||
3 | |||
4 | // structure de données façon C | ||
5 | // créer les requêtes avec implode(', ', $DbStructure) | ||
6 | class StructTablesDB | ||
7 | { | ||
8 | // possibilité de lire un fichier JSON | ||
9 | static public $structureOfTables = [ | ||
10 | // la table prestations est liée à la table clients | ||
11 | // les tables devis_factures, cesu et locations sont liées à la table prestations | ||
12 | 'clients' => ['ID' => 'INTEGER', 'prenom_nom' => 'TEXT', 'adresse' => 'TEXT', 'code_client' => 'TEXT', 'commentaires' => 'TEXT'], | ||
13 | 'prestations' => ['ID' => 'INTEGER', 'ID_client' => 'INTEGER', 'combientieme_fois' => 'INTEGER', 'code_presta' => 'TEXT', 'date' => 'INTEGER', 'type' => 'TEXT', 'mode_paiement' => 'TEXT', 'commentaires' => 'TEXT'], | ||
14 | 'devisfactures' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'validite_devis' => 'TEXT', 'signature_devis' => 'TEXT', 'taches' => 'TEXT', 'machine' => 'TEXT', 'OS' => 'TEXT', 'donnees' => 'TEXT', 'cles_licences' => 'TEXT', 'total_main_d_oeuvre' => 'REAL', 'pieces' => 'TEXT', 'total_pieces' => 'REAL', 'deplacement' => 'REAL', 'total_HT' => 'REAL'], | ||
15 | 'cesu' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'taches' => 'TEXT', 'duree_travail' => 'TEXT', 'salaire' => 'REAL'], | ||
16 | 'locations' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'nature_bien' => 'TEXT', 'modele' => 'TEXT', 'valeur' => 'REAL', 'etat_des_lieux_debut' => 'TEXT', 'etat_des_lieux_fin' => 'TEXT', 'duree_location' => 'TEXT', 'loyer_mensuel' => 'REAL', 'total_HT' => 'REAL'] | ||
17 | ]; | ||
18 | |||
19 | // les types de variables de sqlite sont peu nombreux et autorisent un typage automatique | ||
20 | // le "type indiqué" est indiqué dans l'instruction CREATE TABLE | ||
21 | // https://www.leppf.com/site/spip.php?article89 | ||
22 | |||
23 | // || type indiqué || type choisi automatiquement || autre types possibles || | ||
24 | // --------------------------------------------------------------------------- | ||
25 | // || TEXT || TEXT || BLOB, NULL || | ||
26 | // || INTEGER || INTEGER (de 1 à 8 octets) || REAL, TEXT, BLOB, NULL || | ||
27 | // || REAL || REAL (flottant sur 9 octets) || TEXT, BLOB, NULL || | ||
28 | // || NUMERIC || INTEGER ou REAL || TEXT, BLOB, NULL || | ||
29 | // || NONE || indéfini || dépend des données || | ||
30 | |||
31 | // du code SQL écrit pour d'autres SGBD devrait fonctionner, | ||
32 | // sqlite fera des conversions dans ses propres types avec les problèmes qu'on peut imaginer | ||
33 | |||
34 | // pour les dates, on stockera à priori le timestamp | ||
35 | } | ||
diff --git a/src/view/Zenity.php b/src/view/Zenity.php new file mode 100644 index 0000000..a04b794 --- /dev/null +++ b/src/view/Zenity.php | |||
@@ -0,0 +1,110 @@ | |||
1 | <?php | ||
2 | // php/Zenity.php | ||
3 | // | ||
4 | // commande système zenity | ||
5 | |||
6 | abstract class ZenityCmd | ||
7 | { | ||
8 | protected $command = 'zenity'; | ||
9 | protected $command_type = ''; | ||
10 | protected $rows = []; | ||
11 | private $title = 'ORDIPOLO'; | ||
12 | private $text = ''; | ||
13 | protected $width = 300; | ||
14 | protected $height = 200; // recalculée en fonction du contenu, vaut au minimum 150 | ||
15 | |||
16 | protected function __construct($text, array $rows = []) // $rows est optionnel | ||
17 | { | ||
18 | $this->text = $text; | ||
19 | $this->rows= $rows; | ||
20 | $this->command .= $this->command_type; | ||
21 | $this->command .= ' --title="' . $this->title . '"'; | ||
22 | $this->command .= ' --text="' . $this->text . '"'; | ||
23 | } | ||
24 | |||
25 | public function get() | ||
26 | { | ||
27 | return($this->command); | ||
28 | } | ||
29 | } | ||
30 | |||
31 | |||
32 | class ZenityList extends ZenityCmd | ||
33 | { | ||
34 | public function __construct($text, array $rows) | ||
35 | { | ||
36 | $this->command_type = ' --list'; | ||
37 | parent::__construct($text, $rows); | ||
38 | $this->height = 80 + count($this->rows) * 25; | ||
39 | $this->command .= ' --width=' . $this->width; | ||
40 | $this->command .= ' --height=' . $this->height; | ||
41 | $this->command .= ' --hide-header'; // ligne inutile, il y a déjà le --text | ||
42 | self::one_column_zenity_list($this->rows); | ||
43 | } | ||
44 | |||
45 | public function set_entries($rows_set) // variable renseignée après la construction | ||
46 | { | ||
47 | $this->rows = $rows_set; | ||
48 | } | ||
49 | |||
50 | private function one_column_zenity_list($rows) | ||
51 | { | ||
52 | $output = ' --column=""'; | ||
53 | foreach($rows as $entry) | ||
54 | { | ||
55 | $output .= ' "' . $entry . '"'; // forme: ' "choix 1" "choix 2"' | ||
56 | } | ||
57 | $this->command .= $output; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | class ZenityQuestion extends ZenityCmd | ||
62 | { | ||
63 | public function __construct($text) | ||
64 | { | ||
65 | $this->command_type = ' --question'; | ||
66 | parent::__construct($text); | ||
67 | $this->command .= ' && echo $?'; | ||
68 | // la sortie de "zenity --question" est le statut de sortie "$?" | ||
69 | // $? vaut 0 pour oui, 1 pour non, à ceci près que pour non zenity ne renvoie rien | ||
70 | } | ||
71 | } | ||
72 | |||
73 | class ZenityForms extends ZenityCmd | ||
74 | { | ||
75 | public function __construct($text, array $rows) | ||
76 | { | ||
77 | $this->command_type = ' --forms'; | ||
78 | parent::__construct($text, $rows); | ||
79 | //$this->height = 80 + count($this->rows) * 25; // à tester, mais devrait produire le rendu attendu | ||
80 | self::entries_zenity_forms($this->rows); | ||
81 | } | ||
82 | |||
83 | private function entries_zenity_forms($entries) | ||
84 | { | ||
85 | $output = ''; | ||
86 | foreach($entries as $one_entry) | ||
87 | { | ||
88 | $output .= ' --add-entry="' . $one_entry . '"'; // forme: ' "choix 1" "choix 2"' | ||
89 | } | ||
90 | $this->command .= $output; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | class ZenityCalendar extends ZenityCmd | ||
95 | { | ||
96 | public function __construct($text) | ||
97 | { | ||
98 | $this->command_type = ' --calendar'; | ||
99 | parent::__construct($text); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | class ZenityEntry extends ZenityCmd | ||
104 | { | ||
105 | public function __construct($text) | ||
106 | { | ||
107 | $this->command_type = ' --entry'; | ||
108 | parent::__construct($text); | ||
109 | } | ||
110 | } | ||
diff --git a/src/view/zenity_setup.php b/src/view/zenity_setup.php new file mode 100644 index 0000000..2f55cf2 --- /dev/null +++ b/src/view/zenity_setup.php | |||
@@ -0,0 +1,37 @@ | |||
1 | <?php | ||
2 | // php/zenity_setup.php | ||
3 | |||
4 | |||
5 | // contenu des fenêtres zenity | ||
6 | $menu_principal_text = "Gestion d'une micro-entreprise"; | ||
7 | $menu_principal_entrees = ["Nouvelle prestation", "Modifier enregistrement", "Fichier clients", "Créer/imprimer un document", "Communication", "Base de données"]; | ||
8 | $question_nouveau_client_text = "Ce client figure t\'il déjà dans le fichier clients?"; | ||
9 | $menu_enregistrement_text = "Type d\'enregistrement?"; | ||
10 | $menu_enregistrement_entrees = ["Devis", "Facture", "CESU", "Pas de prestation"]; | ||
11 | $menu_documents_text = "Création de documents LaTeX"; | ||
12 | $menu_documents_entrees = ["Devis", "Facture", "Lettre avec adresse", "Livre des recettes", "Registre des achats", "Bilan annuel"]; | ||
13 | $menu_communication_text = "Imprimer un support de communication"; | ||
14 | $menu_communication_entrees = ["Flyer (nécessite gimp)", "Carte de visite (nécessite scribus)", "Explorateur de fichiers"]; | ||
15 | $recherche_client_text = "Recherche d'un client avec son nom ou son code client"; | ||
16 | $resultats_recherche_client_text = "Résultats de la recherche, sélectionner un client"; | ||
17 | $nouveau_client_text = "Nouveau client"; | ||
18 | $nouveau_client_entrees = ["Prénom Nom:", "Adresse:", "Code client, type: J.P.Duchmol"]; | ||
19 | $calendar_text = 'Nouvelle prestation étape 1/3 - Choisir une date'; | ||
20 | $formulaire_text = 'Nouvelle prestation 2/3 - Détail des travaux'; | ||
21 | $formulaire_entrees = ["Tâches effectuées:", "Modèle du PC:", "OS:", "Données sauvegardées:", "Clés d\'activation:", "Temps main d\'oeuvre (heures):", "Total main d\'oeuvre (euros):", "Total pièces (euros):", "Déplacement (euros)", "Total HT (euros):",]; | ||
22 | $commentaire_prestation_text = 'Nouvelle prestation 3/3 - Commentaires'; | ||
23 | |||
24 | |||
25 | // commandes système qui ouvrent les fenêtres zenity, un objet = une commande | ||
26 | // s'utilisent comme ceci: exec($Objet->get()); | ||
27 | $MenuPrincipal = new ZenityList($menu_principal_text, $menu_principal_entrees); | ||
28 | $QuestionNouveauClient = new ZenityQuestion($question_nouveau_client_text); | ||
29 | $MenuEnregistrement = new ZenityList($menu_enregistrement_text, $menu_enregistrement_entrees); | ||
30 | $MenuDocuments = new ZenityList($menu_documents_text, $menu_documents_entrees); | ||
31 | $MenuCommunication = new ZenityList($menu_communication_text, $menu_communication_entrees); | ||
32 | $RechercheClient = new zenityEntry($recherche_client_text); | ||
33 | $ResultatsRechercheClient = new zenityList($resultats_recherche_client_text, []); | ||
34 | $NouveauClient = new ZenityForms($nouveau_client_text, $nouveau_client_entrees); | ||
35 | $Calendrier = new ZenityCalendar($calendar_text); | ||
36 | $FormulairePrestation = new ZenityForms($formulaire_text, $formulaire_entrees); | ||
37 | $CommentairePrestation = new ZenityEntry($commentaire_prestation_text); | ||