From 1894fc377e6b938ea34df9980567a1634ec6ef48 Mon Sep 17 00:00:00 2001 From: polo Date: Wed, 28 Dec 2022 05:19:55 +0100 Subject: =?UTF-8?q?r=C3=A9organisation=20+=20bient=C3=B4t=20finie=20la=20s?= =?UTF-8?q?ection=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.php | 8 +- data/ordipolo.sqlite | Bin 0 -> 32768 bytes src/Dates.php | 78 ++++++++----- src/functions.php | 18 +-- src/main.php | 160 ++++++--------------------- src/model/CESU.php | 23 ++-- src/model/Clients.php | 56 ++++++++-- src/model/DevisFactures.php | 32 +++++- src/model/Locations.php | 21 ++-- src/model/Model.php | 12 +- src/model/Prestations.php | 81 +++++++++++--- src/model/StructTablesDB.php | 6 +- src/model/traits.php | 18 +-- src/sections/1_new_service.php | 241 +++++++++++++++++++++++++++++++++++++++++ src/view/Zenity.php | 29 ++--- src/view/ZenitySetup.php | 30 +++++ src/view/zenity_setup.php | 37 ------- 17 files changed, 572 insertions(+), 278 deletions(-) create mode 100644 data/ordipolo.sqlite create mode 100644 src/sections/1_new_service.php create mode 100644 src/view/ZenitySetup.php delete mode 100644 src/view/zenity_setup.php diff --git a/config.php b/config.php index 2fec5ad..c51e793 100644 --- a/config.php +++ b/config.php @@ -55,15 +55,15 @@ $publishing = 'scribus'; // $sqliteGUI = 'sqlitebrowser'; $sqlite_gui = 'sqlitebrowser'; -// format des dates: EU exemple européenne 28-11-2022, US exemple américaine 11/28/2022 -// $date_format = 'EU'; -$date_format = 'EU'; +// format des dates: 'euro' exemple 28-11-2022, 'usa' exemple 11/28/2022 +// $date_format = 'euro'; +$date_format = 'euro'; // $x_terminal = 'xterm'; // -- état actuel du programme -- // les terminaux gérés sont: xterm, urxvt, lxterminal, xfce4-terminal, gnome-terminal, konsole, Terminal (MAC, désactivé tant que non testé) -// ajouter à l'accaz: i3-sensible-terminal (pour i3), lxterminal-qt (pour LXQT, et donc lubuntu) +// ajouter à l'accaz: i3-sensible-terminal (pour i3), lxterminal-qt (pour lubuntu) // le choix est automatique en prenant le 1er terminal disponible, ceux-ci sont testés un par un dans l'ordre de la liste ci-dessus diff --git a/data/ordipolo.sqlite b/data/ordipolo.sqlite new file mode 100644 index 0000000..2c76848 Binary files /dev/null and b/data/ordipolo.sqlite differ diff --git a/src/Dates.php b/src/Dates.php index de71b08..36b19a8 100644 --- a/src/Dates.php +++ b/src/Dates.php @@ -3,56 +3,66 @@ class Dates { - private $date; - private $timestamp; // valeurs négatives autorisées => dates avant 1970 - static public $date_format = 'EU'; // dates européennes jj-mm-aaaa (EU) ou américaines mm/dd/yyyy (US) + private $date = ''; + static public $date_format = 'euro'; // dates européennes jj-mm-aaaa (EU) ou américaines mm/dd/yyyy (US) + private $day = ''; + private $month = ''; + private $year = ''; - public function __construct($entry = NULL) + private $timestamp = 0; // valeurs négatives autorisées => dates avant 1970 + + public function __construct($input = NULL) { - if(gettype($entry) === 'string') // une date est attendue + if(gettype($input) === 'string' && $input !== '') // une date est attendue { - $this->setDate($entry); + $this->setDate($input); } - elseif(gettype($entry) === 'integer') + elseif(gettype($input) === 'integer' && $input !== 0) { - $this->setTimestamp($entry); + $this->setTimestamp($input); } } - public function setDate(string $entry) + public function setDate(string $input) { - $entry = $this->dashOrSlash($entry); // pour strtotime() + $input = $this->dashOrSlash($input); // pour strtotime() - $splitedDate = preg_split('#\D#', $entry); // \D = tout sauf chiffre + $splitedDate = preg_split('#\D#', $input); // \D = tout sauf chiffre + $this->year = $splitedDate[2]; - if(self::$date_format === 'EU') + if(self::$date_format === 'euro') { - $tmp = $splitedDate[0]; - $splitedDate[0] = $splitedDate[1]; - $splitedDate[1] = $tmp; + $this->day = $splitedDate[1]; + $this->month = $splitedDate[0]; + } + else + { + $this->day = $splitedDate[0]; + $this->month = $splitedDate[1]; } - if(checkdate($splitedDate[0], $splitedDate[1], $splitedDate[2])) + //~ if(checkdate($splitedDate[0], $splitedDate[1], $splitedDate[2])) + if(checkdate($this->day, $this->month, $this->year)) { - $this->date = $entry; - $this->timestamp = strtotime($entry); // date (string) -> timestamp (int) + $this->date = $input; + $this->timestamp = strtotime($input); // date (string) -> timestamp (int) // strtotime() devine le format en analysant la chaîne en entrée, on l'aide un peu // avec des /, php considère que la date est américaine // avec des - ou des ., php considère que la date est européenne } else { - 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."); + echo("Date incorrecte, le format de la date dans le fichier config.php est " . self::$date_format . ".\nLes choix possibles sont 'euro' pour Europe et 'usa' pour États-Unis."); die(); } } - public function setTimestamp(int $entry) + public function setTimestamp(int $input) { - $this->timestamp = $entry; - $this->date = $this->timestamp_to_date($entry); // timestamp (int) -> date (string) + $this->timestamp = $input; + $this->date = $this->timestamp_to_date($input); // timestamp (int) -> date (string) } @@ -60,6 +70,18 @@ class Dates { return($this->date); } + public function getDay(): string + { + return($this->day); + } + public function getMonth(): string + { + return($this->month); + } + public function getYear(): string + { + return($this->year); + } public function getTimestamp(): int { @@ -69,36 +91,36 @@ class Dates private function dashOrSlash(string $date): string { - if(self::$date_format === 'EU') + if(self::$date_format === 'euro') { // change jj/mm/aaaa en jj-mm-aaaa return(preg_replace('#\D#', '-', $date)); // \D = tout sauf chiffre } - elseif(self::$date_format === 'US') + elseif(self::$date_format === 'usa') { // change mm-dd.yyyy en mm/dd/yyyy return(preg_replace('#\D#', '/', $date)); } else { - echo('Le fichier config.php comporte une erreur. La variable $date_format doit avoir pour valeur "EU" ou "US"'); + echo("Le fichier config.php comporte une erreur. La variable $date_format doit avoir pour valeur 'euro' ou 'usa'"); die(); // brutal } } private function timestamp_to_date(int $timestamp): string { - if(self::$date_format === 'EU') + if(self::$date_format === 'euro') { return(date("j-m-Y", $timestamp)); } - elseif(self::$date_format === 'US') + elseif(self::$date_format === 'usa') { return(date("m/d/Y", $timestamp)); } else { - echo('Le fichier config.php comporte une erreur. La variable $date_format doit avoir pour valeur "EU" ou "US"'); + echo("Le fichier config.php comporte une erreur. La variable $date_format doit avoir pour valeur 'euro' ou 'usa'"); die(); // brutal } } diff --git a/src/functions.php b/src/functions.php index 82263bb..bdcd594 100644 --- a/src/functions.php +++ b/src/functions.php @@ -30,24 +30,26 @@ function rechercheClient(string $input, Clients $Client): array return($result); } -// NOTE 1: les objets sont passés aux fonctions par référence par défaut, toutefois ce n'est pas entièrement vrai +// NOTE 1: en PHP les objets sont passés aux fonctions par référence par défaut, toutefois ce n'est pas entièrement vrai // NOTE 2: PHP n'a pas de pointeur mais des références, une référence est un alias qui ne contient pas l'objet lui-même // NOTE 3: la variable créée lors d'un "new" est elle-même une référence contenant un identifiant (= le pointeur?) // NOTE 4: l'objet est détruit lorsque la dernière référence est supprimée -function enregistrementNouveauClient(string $name, Clients $Client): bool +function controlFormInput(array $data): bool { - if($name !== '') + $tableSize = count(StructTablesDB::$structureOfTables[$table]); // int + if($data !== '') { - $tableau = explode('|', $name); - if(count($tableau) === 4) + $dataArray = explode('|', $data); + + if(count($dataArray) === $tableSize - 1) // nombre de champs sauf ID qui est auto-incrémenté automatiquement { - $Client->newRow($tableau); // écriture dans la BDD - return true; + + } else { - echo "debug: mauvais tableau, il doit avoir 4 cases\n"; + echo "debug: mauvais tableau, il doit avoir " . $tableSize - 1 . " cases\n"; return false; } } diff --git a/src/main.php b/src/main.php index 3c9c4aa..12715f3 100755 --- a/src/main.php +++ b/src/main.php @@ -39,162 +39,67 @@ require('model/CESU.php'); require('model/Locations.php'); require('view/Zenity.php'); // commande système zenity -require('view/zenity_setup.php'); // texte dans les fenêtres ET instanciation (un objet = une commande) +require('view/ZenitySetup.php'); // texte dans les fenêtres ET instanciation (un objet = une commande) require('Latex.php'); // générer le code LaTeX +require('sections/1_new_service.php'); + // boucle principale $boucle = true; while($boucle) { // niveau 1: menu principal + $MenuPrincipal = new ZenityList(ZenitySetup::$menu_principal_text, ZenitySetup::$menu_principal_entrees); $choix_niv1 = exec($MenuPrincipal->get()); - // Nouvelle prestation - if($choix_niv1 === $menu_principal_entrees[0]) + // -- SECTION 1: Nouvelle prestation -- + if($choix_niv1 === ZenitySetup::$menu_principal_entrees[0]) { - $Client = new Clients; - $id_client_connu = false; - - // niveau 2: est ce que le client est déjà dans la base? - if(exec($QuestionNouveauClient->get()) == '0') // $? = 0 signifie oui, double égal == pour le transtypage - { - echo "debug: recherche souhaitée\n"; - - // niveau 3: saisie du nom du client - $nom_client = exec($RechercheClient->get()); - if($nom_client !== '') - { - echo "debug: recherche effectuée\n"; - $ResultatsRechercheClient->setListRows(rechercheClient($nom_client, $Client), $Client->getTable()); // recherche silencieuse - //~ var_dump($ResultatsRechercheClient->get()); die(); - unset($nom_client); - - // niveau 4: sélection parmi les résultats - $choix_niv4 = exec($ResultatsRechercheClient->get()); - $ResultatsRechercheClient->cleanCommand(); - - if($choix_niv4 !== '') - { - echo "debug: client sélectionné\n"; - $id_client_connu = true; - } - else - { - echo "debug: client pas trouvé ou pas sélectionné\n"; - } - } - else - { - echo "debug: recherche annulée ou saisie vide\n"; - } - } - else - { - echo "debug: nouveau client\n"; - } - - // niveau 2: on n'a pas cherché OU on n'a pas trouvé - if(!$id_client_connu) - { - $id_client_connu = enregistrementNouveauClient(exec($NouveauClient->get()), $Client); // fenêtre + écriture BDD - } - - // niveau 2: type comptable d'enregistrement: devis, facture, cesu ou pas de prestation - if($id_client_connu) - { - $choix_niv2 = exec($MenuEnregistrement->get()); - $continuer = true; - if($choix_niv2 === $menu_enregistrement_entrees[0]) - { - // - } - elseif($choix_niv2 === $menu_enregistrement_entrees[1]) - { - // - } - elseif($choix_niv2 === $menu_enregistrement_entrees[2]) - { - // - } - elseif($choix_niv2 === $menu_enregistrement_entrees[3]) - { - // - } - else - { - $continuer = false; // retour menu principal - } - - if($continuer) - { - //niveau 3: détail de la prestation - $Date = new Dates(exec($Calendrier->get())); - $Objet->setDate($Date->getTimestamp()); // enregistrement du timestamp en BDD - - exec($FormulairePrestation->get()); - // enregistrement date et prestation en BDD - - exec($CommentairePrestation->get()); - // enregistrement commentaire en BDD - // vérification? - - // tableau récaptilatif et demande de confirmation des informations - - // création fichiers LaTeX et PDF - //~ $latex_path = '../data/latex/'; // noms de variables dans le config.php - //~ $file_name = 'devis.tex'; - //~ $template = 'devis'; // vaut 'devis' ou 'enveloppe_recto' ou 'enveloppe_verso' ou 'facture' ou 'location' - //~ $latex = getLatexFromTemplate($template); - //~ file_put_contents($latex_path . $file_name, $latex); // injection des variables & écriture du fichier - //~ $pdf_path = '../data/pdf/'; - //~ latexToPdf($latex_path, $file_name, $pdf_path); - - // imprimer? - //~ $imprimer_facture = exec('zenity --question --width=250 --title="Base de données mise à jour" --text="Imprimer la facture?"'); - //~ $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"'); - } - } - unset($Client); // suppression de la dernière référence (normallement) + echo("choix: $choix_niv1\n"); + newService(); } - // Modifier un enregistrement - elseif($choix_niv1 === $menu_principal_entrees[1]) + // -- SECTION 2: Modifier un enregistrement -- + elseif($choix_niv1 === ZenitySetup::$menu_principal_entrees[1]) { - // niveau 2: + echo("choix: $choix_niv1\n"); } - // Fichier clients - elseif($choix_niv1 === $menu_principal_entrees[2]) + // -- SECTION 3: Fichier clients -- + elseif($choix_niv1 === ZenitySetup::$menu_principal_entrees[2]) { + echo("choix: $choix_niv1\n"); // quel affichage? un grand tableau avec zenity? une page web? un document LaTeX? } - // documents à imprimer - elseif($choix_niv1 === $menu_principal_entrees[3]) // = Créer/imprimer un document + // -- SECTION 4: documents à imprimer -- + elseif($choix_niv1 === ZenitySetup::$menu_principal_entrees[3]) // = Créer/imprimer un document { + echo("choix: $choix_niv1\n"); + $MenuDocuments = new ZenityList(ZenitySetup::$menu_documents_text, ZenitySetup::$menu_documents_entrees); $choix_niv2 = exec($MenuDocuments->get()); - if($choix_niv2 === $menu_documents_entrees[0]) + if($choix_niv2 === ZenitySetup::$menu_documents_entrees[0]) { } - elseif($choix_niv2 === $menu_documents_entrees[1]) // = Facture + elseif($choix_niv2 === ZenitySetup::$menu_documents_entrees[1]) // = Facture { } - elseif($choix_niv2 === $menu_documents_entrees[2]) // = Lettre avec adresse + elseif($choix_niv2 === ZenitySetup::$menu_documents_entrees[2]) // = Lettre avec adresse { } - elseif($choix_niv2 === $menu_documents_entrees[3]) // = Livre des recettes + elseif($choix_niv2 === ZenitySetup::$menu_documents_entrees[3]) // = Livre des recettes { } - elseif($choix_niv2 === $menu_documents_entrees[4]) // = Registre des achats + elseif($choix_niv2 === ZenitySetup::$menu_documents_entrees[4]) // = Registre des achats { } - elseif($choix_niv2 === $menu_documents_entrees[5]) // = Bilan annuel + elseif($choix_niv2 === ZenitySetup::$menu_documents_entrees[5]) // = Bilan annuel { } @@ -204,19 +109,21 @@ while($boucle) } } - // Supports de communication - elseif($choix_niv1 === $menu_principal_entrees[4]) // = Communication + // -- SECTION 5: Supports de communication -- + elseif($choix_niv1 === ZenitySetup::$menu_principal_entrees[4]) // = Communication { + echo("choix: $choix_niv1\n"); + $MenuCommunication = new ZenityList(ZenitySetup::$menu_communication_text, ZenitySetup::$menu_communication_entrees); $choix_niv2 = exec($MenuCommunication->get()); - if($choix_niv2 === $menu_communication_entrees[0]) // = Flyer (nécessite gimp) + if($choix_niv2 === ZenitySetup::$menu_communication_entrees[0]) // = Flyer (nécessite gimp) { exec(windowAppCommand($image_editor, $flyer)); } - elseif($choix_niv2 === $menu_communication_entrees[1]) // = Carte de visite (nécessite scribus) + elseif($choix_niv2 === ZenitySetup::$menu_communication_entrees[1]) // = Carte de visite (nécessite scribus) { exec(windowAppCommand($publishing, $business_card)); } - elseif($choix_niv2 === $menu_communication_entrees[2]) // = Explorateur de fichiers + elseif($choix_niv2 === ZenitySetup::$menu_communication_entrees[2]) // = Explorateur de fichiers { exec(windowAppCommand($file_explorer, $pub)); } @@ -226,9 +133,10 @@ while($boucle) } } - // BDD - elseif($choix_niv1 === $menu_principal_entrees[5]) // = Base de données + // -- SECTION 6: BDD -- + elseif($choix_niv1 === ZenitySetup::$menu_principal_entrees[5]) // = Base de données { + echo("choix: $choix_niv1\n"); if($sqlitebrowser_enable) { exec(windowAppCommand($sqlite_gui, $db_place)); diff --git a/src/model/CESU.php b/src/model/CESU.php index 28a54a8..2be89c0 100644 --- a/src/model/CESU.php +++ b/src/model/CESU.php @@ -3,28 +3,33 @@ class CESU extends Model { - const TABLE = 'cesu'; + //~ const TABLE = 'cesu'; // lecture des données ou hydratation - private $ID; - private $ID_presta; + private $ID_cesu; private $taches; private $duree_travail; private $salaire; use ModelChildren; - // setters - public function setID(int $value) + public function __construct(int $client_ID) { - $this->ID = $value; - return($this); + parent::__construct($client_ID); + $this->type == 'cesu'; } - public function setIDPresta(int $value) + + // setters + public function setIDCesu(int $value) { - $this->ID_presta = $value; + $this->ID_cesu = $value; return($this); } + //~ public function setIDPresta(int $value) + //~ { + //~ $this->ID_presta = $value; + //~ return($this); + //~ } public function setTaches(string $value) { $this->taches = $value; diff --git a/src/model/Clients.php b/src/model/Clients.php index 92a4b31..aeb39c1 100644 --- a/src/model/Clients.php +++ b/src/model/Clients.php @@ -4,20 +4,37 @@ class Clients extends Model { // lecture des données ou hydratation - public $ID; - public $prenom_nom; - public $adresse; - public $code_client; - public $commentaires; + protected $ID; // auto-incrémentée + protected $prenom_nom = ''; + protected $code_client = ''; + protected $adresse = ''; + protected $telephone = ''; + protected $courriel = ''; + protected $commentaires = ''; use ModelChildren; // renseigne parent::table + public function __construct() + { + $this->table = 'clients'; + } + //~ public function set(string $variable, $value) //~ { //~ $this->$variable = $value; //~ return($this); //~ } + // getters + public function getID(): int + { + return $this->ID; + } + public function getCodeClient(): string + { + return $this->code_client; + } + // setters public function setID(int $value) // inutile? il s'autoincrémente { @@ -29,14 +46,27 @@ class Clients extends Model $this->prenom_nom = $value; return($this); } + public function setCode_client(string $value) + { + $this->code_client = $value; + return($this); + } public function setAdresse(string $value) { $this->adresse = $value; return($this); } - public function setCode_client(string $value) + public function setTelephone(string $value) // chaine parce que zenity renvoie une chaine et parce qu'on garde le 0 au début { - $this->code_client = $value; + if(is_numeric($value)) + { + $this->telephone = $value; + } + return($this); + } + public function setCourriel(string $value) + { + $this->courriel = $value; return($this); } public function setCommentaires(string $value) @@ -48,12 +78,18 @@ class Clients extends Model public function newRow(array $input) { - $this->hydrate(['prenom_nom' => $input[0], 'adresse' => $input[1], 'code_client' => $input[2], 'commentaires' => $input[3]]); + $this->hydrate(['prenom_nom' => $input[0], 'code_client' => $input[1], 'adresse' => $input[2], 'telephone' => $input[3], 'courriel' => $input[4], 'commentaires' => $input[5]]); $this->create(); - $this->setIdFromLastInsertID(); // dans ModelChildren, n'utilise pas Model::execQuery() + // ID obtenu par auto-incrémentation + $this->ID = $this->db->lastInsertId(); // méthode de PDO } + //~ public function setIdFromLastInsertID() // à faire juste après l'écriture d'une nouvelle entrée + //~ { + //~ $this->db = parent::getInstance(); // $db est créée dans Model::execQuery() + //~ $this->ID = $this->db->lastInsertId(); // méthode de PDO + //~ } - public function findByKeywords(array $keywords, string $field): array + public function findByKeywords(array $keywords, string $field): array // n'hydrate pas les variables, on doit choisir un client et hydrater ensuite { $result = []; for($i = 0; $i < count($keywords); $i++) diff --git a/src/model/DevisFactures.php b/src/model/DevisFactures.php index 218ebfe..1ed3a5c 100644 --- a/src/model/DevisFactures.php +++ b/src/model/DevisFactures.php @@ -4,8 +4,8 @@ class DevisFactures extends Model { // lecture des données ou hydratation - private $ID; - private $ID_presta; + private $ID_devis_facture; // auto-incrémentée + private $ID_presta = 0; private $validite_devis; private $signature_devis; private $taches; @@ -19,12 +19,25 @@ class DevisFactures extends Model private $deplacement; private $total_HT; - use ModelChildren; + //~ use ModelChildren; + + public function __construct(int $ID_presta) + { + $this->table = 'devisfactures'; + $this->ID_presta = $ID_presta; + } // setters - public function setID(int $value) + public function setIDDevisFacture(int $value = 0) { - $this->ID = $value; + if($value === 0) + { + $this->ID_devis_facture = $this->db->lastInsertId(); // méthode de PDO + } + else + { + $this->ID_devis_facture = $value; + } return($this); } public function setIDPresta(int $value) @@ -92,4 +105,13 @@ class DevisFactures extends Model $this->total_HT = $value; return($this); } + + public function newRow(array $input, array $quotations_input = []) + { + if(!empty($quotations_input)) // cas d'un devis + { + $this->hydrate(['validite_devis' => $quotations_input[0], 'signature_devis' => $quotations_input[1]]); + } + $this->hydrate([]); + } } diff --git a/src/model/Locations.php b/src/model/Locations.php index b788d43..21e9b09 100644 --- a/src/model/Locations.php +++ b/src/model/Locations.php @@ -4,8 +4,7 @@ class Locations extends Model { // lecture des données ou hydratation - private $ID; - private $ID_presta; + private $ID_location; private $nature_bien; private $modele; private $valeur; @@ -17,17 +16,23 @@ class Locations extends Model use ModelChildren; - // setters - public function setID(int $value) + public function __construct(int $client_ID) { - $this->ID = $value; - return($this); + parent::__construct($client_ID); + $this->type == 'location'; } - public function setIDPresta(int $value) + + // setters + public function setIDLocation(int $value) { - $this->ID_presta = $value; + $this->ID_location = $value; return($this); } + //~ public function setIDPresta(int $value) + //~ { + //~ $this->ID_presta = $value; + //~ return($this); + //~ } public function setNatureBien(string $value) { $this->nature_bien = $value; diff --git a/src/model/Model.php b/src/model/Model.php index 8cbf056..938e3dd 100644 --- a/src/model/Model.php +++ b/src/model/Model.php @@ -9,7 +9,8 @@ class Model extends DB public function __construct() { - $this->db = parent::getInstance(); // connexion + //~ $this->db = parent::getInstance(); // connexion + //~ $this->table = strtolower(__CLASS__); } // getters @@ -26,8 +27,9 @@ class Model extends DB // nom d'un setter, forme "setMachin()" $setterName = 'set' . ucfirst($key); // ucfirst met la première lettre en majuscule // détection - if(method_exists($this, $setterName)) // on trouve aussi la méthode is_callable() + if(method_exists($this, $setterName) && $value != NULL) // on trouve aussi la méthode is_callable() { + //~ var_dump($value); // on renseigne les propriétés des l'instance $this->$setterName($value); // nom d'une méthode dans une variable } @@ -84,7 +86,7 @@ class Model extends DB // read SELECT - public function readAll(): array // obtenir une table + protected function readAll(): array // obtenir une table { return($this->execQuery('SELECT * FROM ' . $this->table)->fetchAll()); // fonctionne aussi sans le point virgule dans le SQL!! } @@ -94,7 +96,7 @@ class Model extends DB return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id = ' . $id)->fetch()); } - public function find(array $criteria): array // obtenir une entrée avec un tableau associatif 'champ' => 'valeur' + protected function find(array $criteria): array // obtenir une entrée avec un tableau associatif 'champ' => 'valeur' { $fields = []; $values = []; @@ -134,7 +136,7 @@ class Model extends DB // delete DELETE - public function delete(int $id) + protected function delete(int $id) { 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 } diff --git a/src/model/Prestations.php b/src/model/Prestations.php index 32f9768..cbe8e6c 100644 --- a/src/model/Prestations.php +++ b/src/model/Prestations.php @@ -4,23 +4,56 @@ class Prestations extends Model { // lecture des données ou hydratation - private $ID; - private $IDClient; - private $combientieme_fois; - private $code_presta; - private $date; - private $type; - private $mode_paiement; - private $commentaires; + protected $ID_presta; // auto-incrémentée + protected $ID_client = 0; + protected $combientieme_fois = 0; + protected $code_presta = ''; + protected $date = 0; // timestamp unix + protected $type_presta = ''; + protected $mode_paiement = ''; + protected $commentaires = ''; - use ModelChildren; + //~ use ModelChildren; + + public function __construct(int $ID_client) + { + $this->table = 'prestations'; + $this->ID_client = $ID_client; + $this->combientiemeFois(); + } + + // getters + public function getIDPresta(): int + { + return $this->ID_presta; + } + public function getIDClient(): int + { + return $this->ID_client; + } + public function getCombientiemeFois(): int + { + return $this->combientieme_fois; + } + public function getDate(): int + { + return $this->date; + } // setters - public function setID(int $value) + public function setIDPresta(int $value = 0) { - $this->ID = $value; + if($value === 0) + { + $this->ID_presta = $this->db->lastInsertId(); // méthode de PDO + } + else + { + $this->ID_presta = $value; + } return($this); } + public function setIDClient(int $value) { $this->ID_client = $value; @@ -41,9 +74,9 @@ class Prestations extends Model $this->date = $value; return($this); } - public function setType(string $value) + public function setTypePresta(string $value) { - $this->type = $value; + $this->type_presta = $value; return($this); } public function setModePaiement(string $value) @@ -56,4 +89,26 @@ class Prestations extends Model $this->commentaires = $value; return($this); } + + protected function combientiemeFois() + { + // on récupère un tableau contenant toutes les prestations d'un client tous types confondus (devis, facture, cesu, location, enregistrement sans vente) + $array = $this->find(['ID_client' => $this->ID_client]); + $this->combientieme_fois = count($array) + 1; + } + + // code client = année-mois-jour-codeclient-combientièmefois + public function makeCodePresta(Dates $Date, string $code_client) + { + $array_code = [$Date->getYear(), $Date->getMonth(), $Date->getDay(), $code_client, $this->combientieme_fois]; + $this->code_presta = implode('-', $array_code); + } + + //~ public function newRow(array $input) + //~ { + //~ $this->hydrate(['ID_client' => $input[0], 'code_presta' => $input[1], 'date' => $input[2], 'type_presta' => $input[3], 'mode_paiement' => $input[4], 'commentaires' => $input[5]]); + //~ $this->create(); + //~ // ID obtenu par auto-incrémentation + //~ $this->ID_presta = $this->db->lastInsertId(); // méthode de PDO + //~ } } diff --git a/src/model/StructTablesDB.php b/src/model/StructTablesDB.php index ee4baf1..0f13b80 100644 --- a/src/model/StructTablesDB.php +++ b/src/model/StructTablesDB.php @@ -9,11 +9,11 @@ class StructTablesDB static public $structureOfTables = [ // la table prestations est liée à la table clients // les tables devis_factures, cesu et locations sont liées à la table prestations - 'clients' => ['ID' => 'INTEGER', 'prenom_nom' => 'TEXT', 'adresse' => 'TEXT', 'code_client' => 'TEXT', 'commentaires' => 'TEXT'], - 'prestations' => ['ID' => 'INTEGER', 'ID_client' => 'INTEGER', 'combientieme_fois' => 'INTEGER', 'code_presta' => 'TEXT', 'date' => 'INTEGER', 'type_presta' => 'TEXT', 'mode_paiement' => 'TEXT', 'commentaires' => 'TEXT'], + 'clients' => ['ID' => 'INTEGER', 'prenom_nom' => 'TEXT', 'code_client' => 'TEXT', 'adresse' => 'TEXT', 'telephone' => 'TEXT', 'courriel' => 'TEXT', 'commentaires' => 'TEXT'], + 'prestations' => ['ID' => 'INTEGER', 'ID_client' => 'INTEGER', 'code_presta' => 'TEXT', 'date' => 'INTEGER', 'type_presta' => 'TEXT', 'mode_paiement' => 'TEXT', 'commentaires' => 'TEXT'], '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'], 'cesu' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'taches' => 'TEXT', 'duree_travail' => 'TEXT', 'salaire' => 'REAL'], - 'locations' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'designation' => 'TEXT', 'modele_description' => 'TEXT', 'valeur' => 'REAL', 'etat_des_lieux_debut' => 'TEXT', 'etat_des_lieux_fin' => 'TEXT', 'duree_location' => 'INTEGER', 'loyer_mensuel' => 'REAL', 'loyers_encaisse' => 'INTEGER', 'caution' => 'INTEGER'] + 'locations' => ['ID' => 'INTEGER', 'ID_presta' => 'INTEGER', 'designation' => 'TEXT', 'modele_description' => 'TEXT', 'valeur' => 'REAL', 'etat_des_lieux_debut' => 'TEXT', 'etat_des_lieux_fin' => 'TEXT', 'duree_location' => 'INTEGER', 'loyer_mensuel' => 'REAL', 'loyers_payes' => 'INTEGER', 'caution' => 'INTEGER'] ]; // les types de variables de sqlite sont peu nombreux et autorisent un typage automatique diff --git a/src/model/traits.php b/src/model/traits.php index 43d9b7f..3d446c1 100644 --- a/src/model/traits.php +++ b/src/model/traits.php @@ -3,14 +3,14 @@ trait ModelChildren // pour ne pas toucher au constructeur de la classe Model { - public function __construct() - { - $this->table = strtolower(__CLASS__); - } + //~ public function __construct() + //~ { + //~ $this->table = strtolower(__CLASS__); + //~ } - public function setIdFromLastInsertID() // à faire juste après l'écriture d'une nouvelle entrée - { - $this->db = parent::getInstance(); - $this->ID = $this->db->lastInsertId(); // méthode de PDO - } + //~ public function setIdFromLastInsertID() // à faire juste après l'écriture d'une nouvelle entrée + //~ { + //~ $this->db = parent::getInstance(); + //~ $this->ID = $this->db->lastInsertId(); // méthode de PDO + //~ } } diff --git a/src/sections/1_new_service.php b/src/sections/1_new_service.php new file mode 100644 index 0000000..172402a --- /dev/null +++ b/src/sections/1_new_service.php @@ -0,0 +1,241 @@ +get()) == '0') // $? = 0 signifie oui, double égal == pour le transtypage + { + echo "debug: recherche souhaitée\n"; + + // niveau 3: saisie du nom du client + $nom_client = exec($RechercheClient->get()); + if($nom_client !== '') + { + echo "debug: recherche effectuée\n"; + $ResultatsRechercheClient->setListRows(rechercheClient($nom_client, $Client), $Client->getTable()); // recherche silencieuse + unset($nom_client); + + // niveau 4: sélection parmi les résultats + $choix_niv4 = exec($ResultatsRechercheClient->get()); // renvoie l'ID de la table 'clients' + $ResultatsRechercheClient->cleanCommand(); + + if($choix_niv4 !== '') + { + echo "debug: client sélectionné\n"; + $Client->hydrate($Client->findById($choix_niv4)); + $continuer = true; + } + else + { + echo "debug: client pas trouvé ou pas sélectionné\n"; + } + } + else + { + echo "debug: recherche annulée ou saisie vide\n"; + } + } + else + { + echo "debug: nouveau client\n"; + } + + // niveau 2: on n'a pas cherché OU on n'a pas trouvé + if(!$continuer) + { + $data_string = exec($NouveauClient->get()); + //~ $data_array = explode('|', $data_string); + //~ if(controlFormInput($data_array)) + //~ { + //~ $Client->newRow($data_array); // écriture dans la BDD + //~ $continuer = true; + //~ } + + if($data_string !== '') + { + $data_array = explode('|', $data_string); + $data_string = ''; // nettoyage + + if(count($data_array) === count(StructTablesDB::$structureOfTables[$Client->getTable()]) - 1) + { + if($data_array[0] != "") // le champ "prenom_nom" ne doit pas être vide + { + $Client->newRow($data_array); // écriture dans la BDD + $continuer = true; + } + else + { + echo "debug: données insuffisantes, le nom du client doit au minimum être renseigné\n"; + $continuer = false; + } + } + else + { + echo "debug: le nombre d'informations à enregistrer du nombre de champs à renseigner dans la table\n"; + $continuer = false; + } + } + else + { + echo "debug: annulation lors du formulaire\n"; + $continuer = false; + } + } + + // niveau 2: type comptable d'enregistrement: devis, facture, cesu, location ou pas de prestation + if($continuer) + { + $choix_niv2 = exec($MenuEnregistrement->get()); + $continuer = false; + $Presta = new Prestations($Client->getID()); + + switch($choix_niv2) + { + case ZenitySetup::$menu_enregistrement_entrees[0]: // "Devis" + $DetailsPresta = new DevisFactures($Client->getID()); + $Presta->setTypePresta('devis'); + $continuer = true; + break; + case ZenitySetup::$menu_enregistrement_entrees[1]: // "Facture" + $DetailsPresta = new DevisFactures($Client->getID()); + $Presta->setTypePresta('facture'); + $continuer = true; + break; + case ZenitySetup::$menu_enregistrement_entrees[2]: // "CESU" + $DetailsPresta = new CESU($Client->getID()); + $Presta->setTypePresta('cesu'); + $continuer = true; + break; + case ZenitySetup::$menu_enregistrement_entrees[3]: // "Location" + $DetailsPresta = new Locations($Client->getID()); + $Presta->setTypePresta('location'); + $continuer = true; + break; + case ZenitySetup::$menu_enregistrement_entrees[4]: // "non_vendue" + // objet $Presta uniquement + $Presta->setTypePresta('non_vendue'); + $continuer = true; + break; + default: + $continuer = false; // annulation, retour menu principal + } + + if($continuer) + { + // niveau 3: détail de la prestation + // noter que exec() renvoie toujours une chaîne, sauf en cas d'erreur où il renvoie un "false" + $Date = new Dates(exec($Calendrier->get())); + if($Date->getDate() !== '') // on n'a pas cliqué sur "annuler" + { + $Presta->setDate($Date->getTimestamp()); // un entier pour la BDD + $Presta->makeCodePresta($Date, $Client->getCodeClient()); // d'un objet à l'autre + + // on continue si le formulaire précédent a été rempli + switch($choix_niv2) + { + case $Presta->getType = 'devis'; + $data_string = exec($FormulaireDevis->get()); + break; + case $Presta->getType = 'facture'; + $data_string = exec($FormulaireFacture->get()); // tester si c'est vide ou clic sur 'Annuler' + break; + case $Presta->getType = 'cesu'; + $data_string = exec($FormulaireCesu->get()); + break; + case $Presta->getType = 'location'; + $data_string = exec($FormulaireLocation->get()); + break; + case $data_string->getType = 'non_vendue'; + // ne rien faire + break; + default: + $continuer = false; // annulation, retour menu principal + } + + if($continuer) + { + // dans $Presta + $comment = exec($CommentairePrestation->get()); + if(!empty($comment)) + { + $Presta->setCommentaires($comment); + } + else + { + $continuer = false; // annulation, retour menu principal + } + } + } + $Presta->create(); + $Presta->setIDPresta(); // sans paramètre pour récupérer le dernier ID inséré + + if($data_string !== '') + { + $data_array = explode('|', $data_string); + + if(count($data_array) === count(StructTablesDB::$structureOfTables[$DetailsPresta->getTable()]) - 1) + { + if($data_array[0] != "") // le champ "prenom_nom" ne doit pas être vide + { + $DetailsPresta->newRow($data_array); // INSUFFISANT + $continuer = true; + } + else + { + echo "debug: données insuffisantes, le nom du client doit au minimum être renseigné\n"; + $continuer = false; + } + } + else + { + echo "debug: le nombre d'informations à enregistrer du nombre de champs à renseigner dans la table\n"; + $continuer = false; + } + } + else + { + echo "debug: annulation lors du formulaire\n"; + $continuer = false; + } + $DetailsPresta->setIDPresta($Presta->getIDPresta()); // d'un objet à l'autre + $DetailsPresta->create(); + + + // tableau récaptilatif, possibilité de modification + //ZenityList + + + // création fichiers LaTeX et PDF + //~ $latex_path = '../data/latex/'; // noms de variables dans le config.php + //~ $file_name = 'devis.tex'; + //~ $template = 'devis'; // vaut 'devis' ou 'enveloppe_recto' ou 'enveloppe_verso' ou 'facture' ou 'location' + //~ $latex = getLatexFromTemplate($template); + //~ file_put_contents($latex_path . $file_name, $latex); // injection des variables & écriture du fichier + //~ $pdf_path = '../data/pdf/'; + //~ latexToPdf($latex_path, $file_name, $pdf_path); + + // imprimer? + //~ $imprimer_facture = exec('zenity --question --width=250 --title="Base de données mise à jour" --text="Imprimer la facture?"'); + //~ $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"'); + } + } +} diff --git a/src/view/Zenity.php b/src/view/Zenity.php index 1299d1c..72d5eed 100644 --- a/src/view/Zenity.php +++ b/src/view/Zenity.php @@ -1,7 +1,8 @@ get()); abstract class ZenityCmd { @@ -33,17 +34,17 @@ class ZenityList extends ZenityCmd { private $columns = 1; // tableau simple ou multidimensionnel? - public function __construct(string $text, array $rows = [], int $columns = 1) + public function __construct(string $text, array $rows = []) { $this->command_type = ' --list'; parent::__construct($text, $rows); - $this->columns = $columns; - $this->height = 80 + count($this->rows) * 25; - $this->command .= ' --height=' . $this->height; + $this->columns = 1; $this->command .= ' --hide-header'; // ligne inutile, il y a déjà le --text if($this->rows !== []) { $this->command .= ' --width=' . $this->width; + $this->height = 80 + count($this->rows) * 25; + $this->command .= ' --height=' . $this->height; $this->fillZenityList(); } } @@ -54,8 +55,10 @@ class ZenityList extends ZenityCmd { $this->rows = $rows; $this->columns = count(StructTablesDB::$structureOfTables[$table]); - $this->width = 600; + $this->width = 800; $this->command .= ' --width=' . $this->width; + $this->height = 80 + count($this->rows) * 25; + $this->command .= ' --height=' . $this->height; $this->fillZenityList(); } @@ -100,7 +103,7 @@ class ZenityList extends ZenityCmd class ZenityQuestion extends ZenityCmd { - public function __construct($text) + public function __construct(string $text) { $this->command_type = ' --question'; parent::__construct($text); @@ -114,7 +117,7 @@ class ZenityQuestion extends ZenityCmd // si on clique sur 'Annuler', renvoie une chaine vide class ZenityForms extends ZenityCmd { - public function __construct($text, array $rows) + public function __construct(string $text, array $rows) { $this->command_type = ' --forms'; parent::__construct($text, $rows); @@ -122,12 +125,12 @@ class ZenityForms extends ZenityCmd self::entriesZenityForms($this->rows); } - private function entriesZenityForms($entries) + private function entriesZenityForms(array $input) { $output = ''; - foreach($entries as $one_entry) + foreach($input as $one_question) { - $output .= ' --add-entry="' . $one_entry . '"'; // forme: ' "choix 1" "choix 2"' + $output .= ' --add-entry="' . $one_question . '"'; // forme: ' "choix 1" "choix 2"' } $this->command .= $output; } @@ -135,7 +138,7 @@ class ZenityForms extends ZenityCmd class ZenityCalendar extends ZenityCmd { - public function __construct($text) + public function __construct(string $text) { $this->command_type = ' --calendar'; parent::__construct($text); @@ -144,7 +147,7 @@ class ZenityCalendar extends ZenityCmd class ZenityEntry extends ZenityCmd { - public function __construct($text) + public function __construct(string $text) { $this->command_type = ' --entry'; parent::__construct($text); diff --git a/src/view/ZenitySetup.php b/src/view/ZenitySetup.php new file mode 100644 index 0000000..e8a3ddb --- /dev/null +++ b/src/view/ZenitySetup.php @@ -0,0 +1,30 @@ +get()); -$MenuPrincipal = new ZenityList($menu_principal_text, $menu_principal_entrees); -$QuestionNouveauClient = new ZenityQuestion($question_nouveau_client_text); -$MenuEnregistrement = new ZenityList($menu_enregistrement_text, $menu_enregistrement_entrees); -$MenuDocuments = new ZenityList($menu_documents_text, $menu_documents_entrees); -$MenuCommunication = new ZenityList($menu_communication_text, $menu_communication_entrees); -$RechercheClient = new zenityEntry($recherche_client_text); -$ResultatsRechercheClient = new ZenityList($resultats_recherche_client_text, [], 2); -$NouveauClient = new ZenityForms($nouveau_client_text, $nouveau_client_entrees); -$Calendrier = new ZenityCalendar($calendar_text); -$FormulairePrestation = new ZenityForms($formulaire_text, $formulaire_entrees); -$CommentairePrestation = new ZenityEntry($commentaire_prestation_text); -- cgit v1.2.3