diff --git a/VANDAMME32.c b/VANDAMME32.c new file mode 100644 index 0000000..5052e73 --- /dev/null +++ b/VANDAMME32.c @@ -0,0 +1,1149 @@ + +/* + * Fichier client : + *------------------------------------------------------------ + *|UINTL NBClients|Bool Tri| Client 0 | Client 1 | .......ETc| + *------------------------------------------------------------ + *NombreClients est stocké dans mon fichier + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __TVA__ 1.21 +#define __REDUC__ 0.9 +#define __MAXNBRART__ 3 + +#define __STRLEN__ 34 +#define __STRLEN_FILE__ 500 + +#define __TAB_CLIENTDAT_FILE__ 0 +#define __TAB_CLIENTTXT_FILE__ 1 + +typedef enum{FALSE=0,TRUE=1} Bool; +typedef struct ListeArticle_t ListeArticle; + + + + +typedef struct { + char deisgnation[__STRLEN__]; + float prixHTVA; + int quant; +} Article; +typedef struct { + Article * article; + unsigned int nbrArt; +} Panier; + + +typedef struct{ + int jour,moi,annee; +} Date; +typedef struct{ + char rue[__STRLEN__],numero[__STRLEN__],localite[__STRLEN__]; + int codePostal; +} Adresse; +typedef struct{ + char telephone[13],email[__STRLEN__]; +} Contact; +typedef struct{ + char nom[__STRLEN__]; + char prenom[__STRLEN__]; + Adresse adresse; + Contact contact; + Date anniversaire; + int fidelite; + Panier panier; + long ofsetFichierDat; + long ofsetFichierTXT; +} Client; +typedef struct{ + FILE * bin; + FILE * txt; + char emplacementBin[__STRLEN_FILE__]; + char emplacementTXT[__STRLEN_FILE__]; + Bool tri; +} FichierClient; + +struct ListeArticle_t{ + Article article; + ListeArticle * suite; +}; + + +void encoderDate(Date *, char *); //############################################ +Bool dateValide (Date *);//############################################ +void encoderArticle(Article *);//############################################ +void encoderClient(Client *);//############################################ +void afficherClient(Client *, Date *);//############################################ +void encoderFacture(ListeArticle **);//############################################ +void afficherFacture(Date *, Client *, ListeArticle *listeArticle);//############################################ +int pointsFidelite(float);//############################################ +Bool gestionFacture(Client *, Date *);//############################################ +void cleanFgets(char*);//############################################ +Bool clean_keyboard();//############################################ +int ageClient(Client *, Date *);//############################################ +long int rechercheClient(char *, char*, FichierClient *, Client *);//############################################ +Bool gestionClient(Client *, Date *, FichierClient *);//############################################ +int compNP(char *, char *,char *, char *);//############################################ +void localiserFichiersClients(FichierClient *);//############################################ +int sauvegarderClientFile(FichierClient *, Client *); //enregistre le client dans le fichier dat et txt +// /!\ Si nouveau client, sera enregistrer a la fin donc non trier ! +FILE * creerFichierFacture(Date *, Client *);//############################################ +Bool fichierExistant(char *);//############################################ +void sauvergarderFacture(Date *, Client *, ListeArticle *listeArticle);//############################################ +void sauvegarderClientTXT(Client *, FILE *, long,...); /*EcrireDonneesClient +si long = 0, n'affiche pas l'age, enregistre a la position courante += 1, affiche l'age qui est repris sur le 4e arguments (int) (pour une facture par ex), enregistre a la position courante +> 1, ecris sans l'age mais a la position demandé (3e arg, long) +*/ +void clientBinToTXT(FichierClient *);//SauvegarderClientsTxt +void modificationClient(Client *, FichierClient*); +long unsigned int nombreClients(FichierClient*); +void recupererClients(FichierClient*, Client ***); //Mon tableau se terminera par un pointeur null, inutile de mettre ça longueur +void positionCurseurBinaireSurClient(FichierClient*); +void afficherListeClients(Client **); +void qSortClientBinByNP(Client **); +void sauvegarderTabClientFile(FichierClient *, Client **); +void insertClientTabTrier(Client * client, Client *** clientTab); +void setTriFlagFile(FichierClient*); +void unsetTriFlagFile(FichierClient*); + +int afficherListeArticle(ListeArticle *); +Bool listeArticleVide(ListeArticle *); +void nouvelleListeArticle(ListeArticle **); +void detruireListeArticle(ListeArticle **); +void insertListeArticle(ListeArticle **, Article *); +ListeArticle * rechercheElemListe(ListeArticle *); +void suprimerElemListeArticle(ListeArticle **); +void modifierElemListeArticle(ListeArticle *); + + + +int main() +{ + FichierClient fichierClient = {NULL, NULL, "", "", 0}; + Client * client; + Client ** clientTab = NULL; + client = (Client*)calloc(1,sizeof(Client)); + long int ofsetFileCurClient = 0; + unsigned long int nbrClient = 0, idClient = 0; + if(ofsetFileCurClient);//Pour ne pas avoir de warn + char nomClient[__STRLEN__],prenomClient[__STRLEN__]; + int choixMenu; + Date date; + char tmp; + Bool w; + time_t curTimeStamp = time(NULL); + struct tm *locTime = localtime(&curTimeStamp); + locTime->tm_mon += 1; + locTime->tm_year += 1900; + printf("Voulez-vous utilisez la date système %d/%d/%d (Y|n)?\n", locTime->tm_mday,locTime->tm_mon,locTime->tm_year); + scanf("%c", &tmp); + if((tmp|0b00100000) != 'y') + encoderDate(&date, "Date facturation"); + else + { + date.jour = locTime->tm_mday; + date.moi = locTime->tm_mon; + date.annee = locTime->tm_year; + } + localiserFichiersClients(&fichierClient); + nbrClient = nombreClients(&fichierClient); + recupererClients(&fichierClient, &clientTab); + while(w) + { + printf("1. Nouveau client\n"); + printf("2. Client enregistré\n"); + printf("3. Liste des client\n"); + printf("4. Tri des client\n"); + do{ + printf("Choix (1|2|3|4):");clean_keyboard();scanf("%d", &choixMenu); + }while(!(choixMenu<=4 && choixMenu>=1)); + switch (choixMenu) + { + case 1: + + client->ofsetFichierDat = 0; + client->ofsetFichierTXT = 0; + encoderClient(client); + afficherClient(client, &date); + fseek(fichierClient.txt, 0, SEEK_END); + insertClientTabTrier(client, &clientTab); + sauvegarderTabClientFile(&fichierClient, clientTab); + w = gestionClient(client, &date, &fichierClient); + nbrClient++; + break; + case 2: + printf("\nNom du client (sensible a la casse) : "); + clean_keyboard();scanf("%s", nomClient); + printf("\nPrenom du client (sensible a la casse) : "); + clean_keyboard();scanf("%s", prenomClient); + ofsetFileCurClient = rechercheClient(nomClient,prenomClient, &fichierClient, client); + if(ofsetFileCurClient) + w = gestionClient(client, &date, &fichierClient); + else + printf("\nClient non trouvé !\n"); + break; + case 3: + printf("0 : Retour\n"); + afficherListeClients(clientTab); + do { + printf("Entrez l'id du client :"); clean_keyboard();scanf("%lu", &idClient); + } while(idClient > nbrClient); + if(idClient != 0) + { + client = *(clientTab+(idClient-1)); + w = gestionClient(client, &date, &fichierClient); + } + break; + case 4: + printf("Avent\n"); + afficherListeClients(clientTab); + printf("\n\nApres\n"); + qSortClientBinByNP(clientTab); + afficherListeClients(clientTab); + sauvegarderTabClientFile(&fichierClient, clientTab); + break; + } + } + while(*clientTab) + free(*clientTab++); + free(clientTab); + free(client); + fclose(fichierClient.txt); + fclose(fichierClient.bin); + return 0; +} +void encoderDate(Date * date, char *invite) +{ + do { + printf("\n%s\n", invite); + printf("Entrez la date sous cette forme : jj/mm/aaaa\n"); + scanf("%d/%d/%d",&(date->jour),&(date->moi),&(date->annee)); + } while(!dateValide(date)); +} + +Bool dateValide(Date * date) +{ + int m = date->jour; + int d = date->moi; + int y = date->annee; + int daysinmonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if(y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))//Si bis février = 29 + daysinmonth[1]=29; + if (m<13) + { + if( d <= daysinmonth[m-1] ) + return 1; + else + return 0; + } + else + return 0; +} +void encoderArticle(Article * article) +{ + printf("\nVeuillez entrer le nom : "); + clean_keyboard(); + scanf("%34s", article->deisgnation); + printf("\nVeuillez entrer le prix a l'unite hors TVA : "); + clean_keyboard(); + scanf("%f", &article->prixHTVA); + printf("\nVeuillez entrer la quantite desiree : "); + clean_keyboard(); + scanf("%d", &article->quant); +} + +void encoderClient(Client * client) +{ + printf("\nEncoage Client\n"); + client->fidelite = 0; + if(!(printf("Entrez la rue :") && clean_keyboard() && fgets(client->adresse.rue,__STRLEN__,stdin) != NULL && \ + printf("\nEntrez le numero :" ) && clean_keyboard() && fgets(client->adresse.numero,__STRLEN__,stdin) != NULL && \ + printf("\nEntrez la localité :") && clean_keyboard() && fgets(client->adresse.localite,__STRLEN__,stdin) != NULL && \ + printf("\nEntrez le code postal :") && clean_keyboard() && scanf("%d", &(client->adresse.codePostal)) && \ + printf("\nNom client :") && clean_keyboard() && fgets(client->nom,__STRLEN__,stdin) != NULL &&\ + printf("\nPrenom client :") && clean_keyboard() && fgets(client->prenom,__STRLEN__,stdin) != NULL)) + { + printf("\nErreur lors de l'encodage de l'adresse"); + exit(-1); + } + cleanFgets(client->adresse.rue);cleanFgets(client->adresse.numero);cleanFgets(client->adresse.localite); + cleanFgets(client->nom);cleanFgets(client->prenom); + if(!(printf("\n Entrez le numéro de tél. :") && clean_keyboard() &&fgets(client->contact.telephone,13,stdin) && \ + printf("\nEntrez l'adresse email :") && clean_keyboard() &&fgets(client->contact.email,__STRLEN__,stdin))) + { + printf("\nErreur lors de l'encodage des coo de contact"); + exit(-1); + } + cleanFgets(client->contact.telephone);cleanFgets(client->contact.email); + encoderDate(&(client->anniversaire), "\nAnniversaire client:"); +} +void afficherClient(Client *client, Date *date) +{ + printf("\nClient : %s %s (%d)\n", client->nom, client->prenom, ageClient(client, date)); + printf("rue : %s\n",client->adresse.rue); + printf("numero : %s\n",client->adresse.numero); + printf("localité : %s\n",client->adresse.localite); + printf("code postal : %d\n",client->adresse.codePostal); + printf("numéro de tél. : %s\n",client->contact.telephone); + printf("adresse email : %s\n",client->contact.email); + printf("\nPoints de fidelite acquis : %d\n", client->fidelite); +} +void sauvegarderClientTXT(Client *client, FILE * file, long arg, ...) //EcrireDonneesClient +{ + va_list ap; + int age = 0; + va_start(ap, arg); + if(arg>1) + { + fseek(file, arg, SEEK_SET); + fprintf(file, "Client : %s %s", client->nom, client->prenom); + fprintf(file, "\n"); + } + else if(arg == 1) + { + age = va_arg(ap,int); + fprintf(file, "Client : %s %s (%d)\n", client->nom, client->prenom,age); + } + else + fprintf(file, "Client : %s %s \n", client->nom, client->prenom); + fprintf(file, "rue : %s\n",client->adresse.rue); + fprintf(file, "numero : %s\n",client->adresse.numero); + fprintf(file, "localité : %s\n",client->adresse.localite); + fprintf(file, "code postal : %d\n",client->adresse.codePostal); + fprintf(file, "numéro de tél. : %s\n",client->contact.telephone); + fprintf(file, "adresse email : %s\n",client->contact.email); + if(arg == 1) + fprintf(file, "\nPoints de fidelite acquis : %d\n", client->fidelite); + else + fprintf(file, "\n===========================================================================\n"); + va_end(ap); +} +void encoderFacture(ListeArticle ** listeArticle) +{ + Article article; + char continuer = 'y'; + do{ + encoderArticle(&(article)); + printf("Y-a-t-il encore un article ?(Y|n)"); + clean_keyboard(); + scanf("%c", &continuer); + insertListeArticle(listeArticle, &article); + }while((continuer|0b00100000) == 'y'); +} +FILE * creerFichierFacture(Date * date, Client * client) +{ + char fileName[__STRLEN__+16]; + fileName[0] = '\0'; + char dir[__STRLEN__]; + int i; + printf("Dossier d'enregistrement : "); + clean_keyboard(); + scanf("%s", dir); + sprintf(fileName, "%s%d%d%d_", client->nom, date->annee, date->moi, date->jour); + for(i=1; i<= 99; i++) + { + char fileNameTmp[__STRLEN__+16+255]; + sprintf(fileNameTmp,"%s%s%d.txt",dir,fileName,i); + if(!fichierExistant(fileNameTmp)) + { + FILE * f = fopen(fileNameTmp,"w"); + if(f==NULL) + { + printf("Erreur lors de l'ouverture du fichier"); + return creerFichierFacture(date, client); + } + else + return f; + } + } + return NULL; +} +Bool fichierExistant(char * filename) +{ + FILE * f = fopen(filename, "r"); + fclose(f); + if(f==NULL) + return FALSE; + else + return TRUE; +} +void sauvergarderFacture(Date * date, Client * client, ListeArticle * listeArticle) +{ + FILE * file; + file = creerFichierFacture(date, client); + float prixTot = 0; + ListeArticle * debutListeArticle = listeArticle; + fprintf(file,"La Bulle Informatique\nRoute du Condroz 78, 4123 Neupre\n"); + fprintf(file,"\nFacture a payer\n"); + fprintf(file,"Date de facturation :"); + fprintf(file,"%02d/%02d/%02d", date->jour, date->moi, date->annee); + fprintf(file,"\n Info client :"); + afficherClient(client, date); + fprintf(file,"\n|---------------------------------------------------------------------------------------------|\ + \n| Designation | prixHTVA | Quantite | 10%% | prixTVAC |\ + \n|---------------------------------------------------------------------------------------------|"); + + for(;listeArticle;listeArticle=listeArticle->suite) + { + fprintf(file,"\n|%34s|%12.2f Eur |%14d| %c |%12.2f |",\ + listeArticle->article.deisgnation,listeArticle->article.prixHTVA,listeArticle->article.quant\ + ,(listeArticle->article.quant>=20)?'x':' ',\ + (listeArticle->article.quant>=20)?listeArticle->article.prixHTVA*__TVA__*__REDUC__*listeArticle->article.quant:listeArticle->article.prixHTVA*__TVA__*listeArticle->article.quant); + prixTot += (listeArticle->article.quant>=20)?listeArticle->article.prixHTVA*__TVA__*__REDUC__*listeArticle->article.quant:listeArticle->article.prixHTVA*__TVA__*listeArticle->article.quant; + } + fprintf(file,"\n|---------------------------------------------------------------------------------------------|"); + client->fidelite += pointsFidelite(prixTot); + fprintf(file,"\nPrix totale :%f", prixTot); + fprintf(file,"\nPoints de fidelite acquis : %d\n", pointsFidelite(prixTot)); + + listeArticle = debutListeArticle; + fclose(file); +} + +void afficherFacture(Date * date, Client * client, ListeArticle * listeArticle) +{ + float prixTot = 0; + ListeArticle * debutListeArticle = listeArticle; + printf("La Bulle Informatique\nRoute du Condroz 78, 4123 Neupre\n"); + printf("\nFacture a payer\n"); + printf("Date de facturation :"); + printf("%02d/%02d/%02d", date->jour, date->moi, date->annee); + printf("\n Info client :"); + afficherClient(client, date); + printf("\n|---------------------------------------------------------------------------------------------|\ + \n| Designation | prixHTVA | Quantite | 10%% | prixTVAC |\ + \n|---------------------------------------------------------------------------------------------|"); + for(;listeArticle;listeArticle=listeArticle->suite) + { + printf("\n|%34s|%12.2f Eur |%14d| %c |%12.2f |",\ + listeArticle->article.deisgnation,listeArticle->article.prixHTVA,listeArticle->article.quant\ + ,(listeArticle->article.quant>=20)?'x':' ',\ + (listeArticle->article.quant>=20)?listeArticle->article.prixHTVA*__TVA__*__REDUC__*listeArticle->article.quant:listeArticle->article.prixHTVA*__TVA__*listeArticle->article.quant); + prixTot += (listeArticle->article.quant>=20)?listeArticle->article.prixHTVA*__TVA__*__REDUC__*listeArticle->article.quant:listeArticle->article.prixHTVA*__TVA__*listeArticle->article.quant; + } + printf("\n|---------------------------------------------------------------------------------------------|"); + printf("\nPrix totale :%f", prixTot); + printf("\nPoints de fidelite acquis : %d\n", pointsFidelite(prixTot)); + listeArticle = debutListeArticle; +} + +void cleanFgets(char * str) +{ + char *p = strchr(str, '\n'); + if(p!=NULL) + *p = '\0'; + else + { + printf("Une erreur est arrivé lors du nettoygae \\0"); + exit(-1); + } +} + +Bool clean_keyboard() +{ + fflush(stdin); + // char c; + //while ((c = getchar()) != '\n' && c != EOF) { } + /* do { + c = getc(stdin); + printf("%c\n", c); +} while (c != '\n' && c != EOF);*/ +return 1; +} + +int ageClient(Client * client, Date * date) +{ + if((date->moi == client->anniversaire.moi && date->jour >= client->anniversaire.jour) || (date->moi > client->anniversaire.moi))//anniversaire passé + { + return (date->annee - client->anniversaire.annee); + } + else + return (date->annee - client->anniversaire.annee - 1); +} + +int pointsFidelite(float prix) +{ + return (int)(prix/10); +} + + +Bool gestionFacture(Client * client, Date * date) +{ + + ListeArticle * listeArticle = NULL; + int choix; + int ret = 1; + printf("%d/%d/%d\n", date->jour, date->moi, date->annee ); + nouvelleListeArticle(&(listeArticle)); + do{ + do{ + printf("\n1) AJouter un/des article(s)\n"); + printf("2) Liste des articles\n"); + printf("3) Modification article\n"); + printf("4) Suprimer article\n"); + printf("5) Générer facture\n"); + printf("6) Accueil\n"); + printf("7) Quiter\n"); + printf("Votre choix :");clean_keyboard();scanf("%d", &choix); + }while(choix<1 && choix >5); + switch (choix) { + case 1: + encoderFacture(&(listeArticle)); + break; + case 2: + afficherFacture(date, client, listeArticle); + break; + case 3: + modifierElemListeArticle(listeArticle); + break; + case 4: + suprimerElemListeArticle(&listeArticle); + break; + case 5: + if(listeArticle) + { + afficherFacture(date, client, listeArticle); + sauvergarderFacture(date, client, listeArticle); + printf("\n\t\t~~===========================~~" ); + printf("\n\t\t~~=======SAUVEGARDER !=======~~" ); + printf("\n\t\t~~===========================~~\n" ); + } + else + { + printf("\n\t\t~~===========================~~" ); + printf("\n\t\t~~=======AUCUN ARTICLE !=======~~" ); + printf("\n\t\t~~===========================~~\n" ); + } + break; + case 6: + ret = -1; + break; + case 7: + ret=0; + break; + } + }while(ret > 0); + if(listeArticle) + detruireListeArticle(&(listeArticle)); + return ret; +} + +long int rechercheClient(char *nom, char *prenom, FichierClient *fichierClient,Client * client) +{ + long int ofsetFileCurClient; + int t; + fseek(fichierClient->bin, sizeof(unsigned long int)+sizeof(Bool), SEEK_SET); + clearerr(fichierClient->bin); //Clear EOF + do + { + ofsetFileCurClient = ftell(fichierClient->bin); + fread(client, sizeof(Client), 1, fichierClient->bin); + t = compNP(client->nom, client->prenom, nom, prenom); + }while(!feof(fichierClient->bin) && t); + if(feof(fichierClient->bin)) + { + client = NULL; + return 0; + } + else + return ofsetFileCurClient; +} + +Bool gestionClient(Client * client, Date * date, FichierClient *fichierClient) +{ + char choix; + while(1) + { + do + { + printf("A. Donnees client\n"); + printf("B. Modification client\n");//acce au file * + printf("C. Facture\n"); + printf("D. Retour\n"); + printf("E. Quitter"); + clean_keyboard();scanf("%c", &choix); + choix |= 0b00100000; + }while(!(choix == 'a' || choix == 'b' || choix == 'c' || choix == 'd' || choix == 'e')); + switch (choix) { + case 'a': + afficherClient(client, date); + break; + case 'b': + modificationClient(client, fichierClient); + sauvegarderClientFile(fichierClient, client); + break; + case 'c': + if(!gestionFacture(client, date)) + { + sauvegarderClientFile(fichierClient, client); + return 0; + } + break; + case 'd': + sauvegarderClientFile(fichierClient, client); + return 1; + break; + case 'e': + sauvegarderClientFile(fichierClient, client); + return 0; + break; + } + } +} + +void localiserFichiersClients(FichierClient *fichierClient) +{ + + char rep[__STRLEN_FILE__]; + char repTmp[2][__STRLEN_FILE__]; + unsigned long int nbClients = 0; + Bool tri = 0; + printf("Repertoir ou se trouve le fichier client.dat et client.txt"); + clean_keyboard(); + scanf("%s", rep); + sprintf(repTmp[__TAB_CLIENTDAT_FILE__],"%sclients.dat", rep); + sprintf(repTmp[__TAB_CLIENTTXT_FILE__],"%sclients.txt", rep); + fichierClient->txt = fopen(repTmp[__TAB_CLIENTTXT_FILE__], "r"); //A faire Une verification correcte se ferait avec access (voir GNU libc P418) + fichierClient->bin = fopen(repTmp[__TAB_CLIENTDAT_FILE__], "r"); //A faire Une verification correcte se ferait avec access (voir GNU libc P418) + if(fichierClient->bin == NULL || fichierClient->txt == NULL) //Si un des fichier n'existe pas + { + char c; + printf("\nUn fichier n'existe pas. Voulez-vous les creers (C) ou changer de repertoir (R). (C|R)?"); + if(!(fichierClient->bin == NULL && fichierClient->txt == NULL)) + printf("Attention un des deux fichier a été détecter ! Il seront remis a 0 si vous les creers\nChoix (C|R):" ); + clean_keyboard();scanf("%c", &c); + if((c|0b00100000) == 'c') + { + tri = 1; //Il est vide, donc je considère qu'il est trier + fichierClient->tri = 1; + fclose(fichierClient->bin); + fclose(fichierClient->txt); + fichierClient->bin = fopen(repTmp[__TAB_CLIENTDAT_FILE__], "wb"); + fichierClient->txt = fopen(repTmp[__TAB_CLIENTTXT_FILE__], "w"); + fwrite(&nbClients, sizeof(nbClients), 1, fichierClient->bin); + fwrite(&tri, sizeof(tri), 1, fichierClient->bin); + fclose(fichierClient->bin); + fclose(fichierClient->txt); + } + else + localiserFichiersClients(fichierClient); + + } + else + { + fclose(fichierClient->bin); + fclose(fichierClient->txt); + } + clearerr(fichierClient->bin);clearerr(fichierClient->txt); + fichierClient->bin = fopen(repTmp[__TAB_CLIENTDAT_FILE__], "r+b"); + fichierClient->txt = fopen(repTmp[__TAB_CLIENTTXT_FILE__], "r+"); + strcpy(fichierClient->emplacementBin, repTmp[__TAB_CLIENTDAT_FILE__]); + strcpy(fichierClient->emplacementTXT, repTmp[__TAB_CLIENTTXT_FILE__]); + if(fichierClient->bin == NULL || fichierClient->txt == NULL) + { + printf("\nErreur ouverture fichier"); + localiserFichiersClients(fichierClient); + } +} + +int sauvegarderClientFile(FichierClient *fichierClient, Client * client) +{ + /* Si Nouveau client ofsetFichierDat = 0 donc nouveau client sinon on decale de l'ofset */ + if(!client->ofsetFichierDat) + { + unsetTriFlagFile(fichierClient); //On le met a la fin donc non trier + unsigned long int nbrClient; + fseek(fichierClient->bin, 0, SEEK_SET); + + fread(&nbrClient,sizeof(nbrClient),1,fichierClient->bin); + nbrClient++; + fseek(fichierClient->bin, 0, SEEK_SET); + fwrite(&nbrClient,sizeof(nbrClient),1,fichierClient->bin); + + fseek(fichierClient->bin, 0, SEEK_END); + fseek(fichierClient->txt, 0, SEEK_END); + client->ofsetFichierDat = ftell(fichierClient->bin); + client->ofsetFichierTXT = ftell(fichierClient->txt); + sauvegarderClientTXT(client, fichierClient->txt, 0); + fflush(fichierClient->txt); + } + else + fseek(fichierClient->bin, client->ofsetFichierDat, SEEK_SET); + fwrite(client, sizeof(Client), 1, fichierClient->bin); + fflush(fichierClient->bin); + return client->ofsetFichierDat; +} + +int compNP(char *nom1, char *prenom1,char *nom2, char *prenom2) +{ + unsigned int strLen1, strLen2; + char * tmp; + for(strLen1 = 0, tmp = nom1;*tmp++;strLen1++); + for(tmp = prenom1;*tmp++;strLen1++); + for(strLen2 = 0, tmp = nom2;*tmp++;strLen2++); + for(tmp = prenom2;*tmp++;strLen2++); + char * np1 = malloc(strLen1+1); + char * np2 = malloc(strLen2+1); + int renvois=0; + sprintf(np1,"%s%s", nom1, prenom1); + sprintf(np2,"%s%s", nom2, prenom2); + renvois = strcmp(np1,np2); + if(renvois>0) + renvois = 1; + else if(renvois<0) + renvois = -1; + free(np1);free(np2); + return renvois; +} + +void clientBinToTXT(FichierClient *fichierClient) +{ + Client client; + fseek(fichierClient->bin, 0, SEEK_SET);fseek(fichierClient->txt, 0, SEEK_SET); + clearerr(fichierClient->bin);clearerr(fichierClient->txt); + fseek(fichierClient->bin, sizeof(unsigned long int), SEEK_CUR); + fseek(fichierClient->bin, sizeof(Bool), SEEK_CUR); + while(!feof(fichierClient->bin)) + { + if(fread(&client, sizeof(Client), 1,fichierClient->bin)) + sauvegarderClientTXT(&client, fichierClient->txt, 0); + } + fflush(fichierClient->txt); +} + +void modificationClient(Client * client, FichierClient * fichierClient) +{ + char choix = 0; + void * aModifier[] = {(Adresse *)&client->adresse, (char *)&client->contact.telephone, (char *)&client->contact.email}; + char * aAfficher[] = {"Adresse", "Telephne", "E-mail"}; + do + { + do + { + system("cls"); + if(choix) + printf("Erreur choix errone !\n"); + printf("MODIFICATION CLIENT %s %s \n", client->nom, client->prenom); + printf("1. Adresse\n2. Telephne\n3. E-mail\n"); + printf("Votre choix :");clean_keyboard();scanf("%d", (int *)&choix); + }while(!(choix == 1 || choix == 2 || choix == 3)); + printf("Modification %s :", aAfficher[choix-1]); + if(choix == 1) + { + if(!(printf("Entrez la rue :") && clean_keyboard() && fgets(client->adresse.rue,__STRLEN__,stdin) != NULL && \ + printf("\nEntrez le numero :" ) && clean_keyboard() && fgets(client->adresse.numero,__STRLEN__,stdin) != NULL && \ + printf("\nEntrez la localité :") && clean_keyboard() && fgets(client->adresse.localite,__STRLEN__,stdin) != NULL && \ + printf("\nEntrez le code postal :") && clean_keyboard() && scanf("%d", &(client->adresse.codePostal)))) + { + printf("\nErreur lors de l'encodage de l'adresse"); + exit(-1); + } + cleanFgets(client->adresse.rue);cleanFgets(client->adresse.numero);cleanFgets(client->adresse.localite); + } + else + { + clean_keyboard(); + scanf("%s", (char *)aModifier[choix-1]); + } + printf("Y-a-til encore des Modification (y|n) ?"); + clean_keyboard();scanf("%c", &choix); + }while((choix|0b00100000) == 'y'); + sauvegarderClientFile(fichierClient, client); + clientBinToTXT(fichierClient); +} + +long unsigned int nombreClients(FichierClient* fichierClient) +{ + if(!fichierClient->bin) + return 0; + unsigned long int nbrClient; + fseek(fichierClient->bin, 0, SEEK_SET); + + fread(&nbrClient,sizeof(nbrClient),1,fichierClient->bin); + return nbrClient; +} +void recupererClients(FichierClient* fichierClient, Client *** clientTab) +{ + unsigned int i; + unsigned long int nbrClients = nombreClients(fichierClient); + *clientTab = (Client **)calloc(nbrClients+1, sizeof(Client *)); //J'initialise avec des 0 mon tableau de pointeur + *(*clientTab+nbrClients) = NULL; + if(*clientTab == NULL) + { + printf("\nErreur allocation **clientTab!\n"); + } + positionCurseurBinaireSurClient(fichierClient); + for(i=0; ibin); i++) + { + *(*clientTab+i) = (Client*)malloc(sizeof(Client)); + if(*(*clientTab+i) == NULL) + { + for(;i>0;i--) + free(*(*clientTab+i)); + free(*(*clientTab)); + free(*clientTab); + printf("\nErreur allocation *clientTab!\n"); + exit(-1); + } + else + { + fread(*(*clientTab+i), sizeof(Client), 1, fichierClient->bin); + } + } + if(feof(fichierClient->bin)) + { + printf("\nUne erreur c'est produite le nbr de client est incorecte !\n"); + for(--i;i>0;i--) + free(*(*clientTab+i)); + free(*(*clientTab)); + free(*clientTab); + exit(-1); + } +} + +void positionCurseurBinaireSurClient(FichierClient * fichierClient) +{ + if(!fichierClient) + exit(-1); + fseek(fichierClient->bin, 0, SEEK_SET); + fseek(fichierClient->bin, sizeof(unsigned long int), SEEK_CUR); + fseek(fichierClient->bin, sizeof(Bool), SEEK_CUR); +} + +void afficherListeClients(Client ** clientTab) +{ + unsigned long int i; + for(i=0;*(clientTab+i) != NULL;i++) + printf("Client %lu : %s %s\n", i+1, (*(clientTab+i))->nom, (*(clientTab+i))->prenom); +} + +void qSortClientBinByNP(Client ** clientTab) +{ + long i; + Client *clientTmp; + i=0; + while((*(clientTab+i+1))) + { + switch (compNP((*(clientTab+i))->nom,(*(clientTab+i))->prenom,(*(clientTab+i+1))->nom,(*(clientTab+i+1))->prenom)) + { + case -1: + i++; + break; + case 1: + clientTmp = *(clientTab+i); + *(clientTab+i) = *(clientTab+i+1); + *(clientTab+i+1) = clientTmp; + if(i==0) //On est au début du fichier, inutile de comparer l'élem précédent + i++; + else + i--; + break; + case 0: + i++; + break; + } + } +} +void insertClientTabTrier(Client * client, Client *** clientTab) +{ + long i = 0; + long nbrTab; + for(nbrTab=0;*((*clientTab)+nbrTab);nbrTab++); + Bool flagTrouver = FALSE; + Client *clientTmp; + Client **clientTabTmp; + *((*clientTab)+nbrTab) = (Client*)calloc(1,sizeof(Client)); + clientTabTmp = (Client **)realloc(*clientTab, sizeof(Client)*(++nbrTab)); + free(clientTab); + *clientTab = clientTabTmp; + *((*clientTab)+nbrTab) = NULL; + while(*((*clientTab)+i+1)) + { + if(!flagTrouver) + { + switch (compNP((*((*clientTab)+i))->nom,(*((*clientTab)+i))->prenom,client->nom,client->prenom)) + { + case -1: + i++; + break; + case 1: // trouver + flagTrouver = TRUE; + clientTmp = *((*clientTab)+i); + *((*clientTab)+i) = client; + client = clientTmp; + i++; + break; + case 0: + i++; + break; + } + } + else + { + clientTmp = *((*clientTab)+i); + *((*clientTab)+i) = client; + client = clientTmp; + i++; + } + } + clientTmp = *((*clientTab)+i); + *((*clientTab)+i) = client; + client = clientTmp; +} +void sauvegarderTabClientFile(FichierClient *fichierClient, Client ** client) +{ + unsigned long int nbClients = 0; + Bool tri = 1; + fclose(fichierClient->bin); + fclose(fichierClient->txt); + fichierClient->bin = NULL; + fichierClient->txt = NULL; + unlink(fichierClient->emplacementBin); + unlink(fichierClient->emplacementTXT); + + fichierClient->bin = fopen(fichierClient->emplacementBin, "w+b"); + fichierClient->txt = fopen(fichierClient->emplacementTXT, "w+"); + + fwrite(&nbClients, sizeof(unsigned long int), 1, fichierClient->bin); + fwrite(&tri, sizeof(Bool), 1, fichierClient->bin); + + while(*client) + { + (*client)->ofsetFichierDat = ftell(fichierClient->bin); + (*client)->ofsetFichierTXT = ftell(fichierClient->txt); + sauvegarderClientTXT((*client), fichierClient->txt, 0); + fwrite((*client++), sizeof(Client), 1, fichierClient->bin); + nbClients++; + } + + fseek(fichierClient->bin, 0, SEEK_SET); + fwrite(&nbClients, sizeof(unsigned long int), 1, fichierClient->bin); + + fflush(fichierClient->bin); + fflush(fichierClient->txt); +} + +void setTriFlagFile(FichierClient* fichier) +{ + Bool tri = TRUE; + Bool flag = FALSE; + if(fichier->bin == NULL) + { + fichier->bin = fopen(fichier->emplacementBin, "r+b"); + flag = TRUE; + } + fseek(fichier->bin, sizeof(unsigned long int), SEEK_SET); + fwrite(&tri, sizeof(Bool), 1, fichier->bin); + if(flag) + { + fclose(fichier->bin); + fichier->bin = NULL; + } +} +void unsetTriFlagFile(FichierClient* fichier) +{ + Bool tri = FALSE; + Bool flag = FALSE; + if(fichier->bin == NULL) + { + fichier->bin = fopen(fichier->emplacementBin, "r+b"); + flag = TRUE; + } + fseek(fichier->bin, sizeof(unsigned long int), SEEK_SET); + fwrite(&tri, sizeof(Bool), 1, fichier->bin); + if(flag) + { + fclose(fichier->bin); + fichier->bin = NULL; + } +} +Bool getFlagTriFile(FichierClient * fichier) +{ + Bool tri; + Bool flag = FALSE; + if(fichier->bin == NULL) + { + fichier->bin = fopen(fichier->emplacementBin, "r+b"); + flag = TRUE; + } + fseek(fichier->bin, sizeof(unsigned long int), SEEK_SET); + fread(&tri, sizeof(Bool), 1, fichier->bin); + if(flag) + { + fclose(fichier->bin); + fichier->bin = NULL; + } + return tri; +} + + +int afficherListeArticle(ListeArticle * listeArticle) +{ + if(!listeArticle) + return 0; + else + { + int i; + printf("\n|--------------------------------------------------------------------------------------------------|\ + \n| ID | Designation | prixHTVA | Quantite | 10%% | prixTVAC |\ + \n|--------------------------------------------------------------------------------------------------|"); + + for(i=1;listeArticle;listeArticle=listeArticle->suite,i++) + { + printf("\n|%4d|%34s|%12.2f Eur |%14d| %c |%12.2f |",i,\ + listeArticle->article.deisgnation,listeArticle->article.prixHTVA,listeArticle->article.quant\ + ,(listeArticle->article.quant>=20)?'x':' ',\ + (listeArticle->article.quant>=20)?listeArticle->article.prixHTVA*__TVA__*__REDUC__*listeArticle->article.quant:listeArticle->article.prixHTVA*__TVA__*listeArticle->article.quant); + } + printf("\n|---------------------------------------------------------------------------------------------|"); + return 1; + } +} +Bool listeArticleVide(ListeArticle * listeArticle) +{ + return (listeArticle==NULL)?0:1; +} +void nouvelleListeArticle(ListeArticle ** listeArticle) +{ + if((*listeArticle)) + detruireListeArticle(listeArticle); +} +void detruireListeArticle(ListeArticle ** listeArticle) +{ + if(!(*listeArticle)) + { + nouvelleListeArticle(&((*listeArticle)->suite)); + free((*listeArticle)); + *listeArticle = NULL; + } + else + *listeArticle = NULL; +} +void insertListeArticle(ListeArticle ** listeArticle, Article * article) +{ + ListeArticle * debutListeArticle = *listeArticle; + if(!(*listeArticle)) + { + *listeArticle = (ListeArticle *) malloc(sizeof(ListeArticle)); + if(!(*listeArticle)) + { + printf("Erreur aloc ListeArticle"); + exit(-1); + } + memcpy(&((*listeArticle)->article), article, sizeof(Article)); + (*listeArticle)->suite = NULL; + } + else + { + while(((*listeArticle)->suite) && strcmp(((*listeArticle)->suite)->article.deisgnation, article->deisgnation)<0) + (*listeArticle) = (*listeArticle)->suite; + if((*listeArticle)->suite) + { + ListeArticle * tmp = (*listeArticle)->suite; + (*listeArticle)->suite = (ListeArticle *) malloc(sizeof(ListeArticle)); + (*listeArticle)->suite->suite = tmp; + memcpy(&((*listeArticle)->suite->article), article, sizeof(Article)); + } + else if(strcmp((*listeArticle)->article.deisgnation, article->deisgnation)<0) + { + (*listeArticle)->suite = (ListeArticle *) calloc(1, sizeof(ListeArticle)); + memcpy(&((*listeArticle)->suite->article), article, sizeof(Article)); + (*listeArticle)->suite->suite = NULL; + } + else + { + ListeArticle * tmp = (ListeArticle *) malloc(sizeof(ListeArticle)); + tmp->suite = *listeArticle; + *listeArticle = tmp; + memcpy(&((*listeArticle)->article), article, sizeof(Article)); + } + } + if(debutListeArticle) + *listeArticle = debutListeArticle; +} + +void suprimerElemListeArticle(ListeArticle ** listeArticle) +{ + ListeArticle * aSup = rechercheElemListe(*listeArticle); + ListeArticle * tmp = *listeArticle; + if(aSup->suite) + { + ListeArticle * aFree = aSup->suite; + memcpy(aSup, aSup->suite, sizeof(ListeArticle)); + free(aFree); + aFree = NULL; + } + else if(aSup == *listeArticle) + { + free(*listeArticle); + *listeArticle = NULL; + } + else + { + for(;tmp->suite != aSup && tmp;tmp = tmp->suite); + if(tmp){ + free(aSup); + tmp->suite = NULL; + }else{ + printf("\nErreur de supretion\n" ); + } + } +} + +void modifierElemListeArticle(ListeArticle * listeArticle) +{ + int i; + listeArticle = rechercheElemListe(listeArticle); + if(listeArticle) + { + do{ + printf("Modifier\n \ + 1)Prix\n \ + 2)Quantite\nChoix :");clean_keyboard();scanf("%d", &i); + }while(i>=3 && i<0); + switch (i) { + case 1: + printf("\nVeuillez entrer le prix a l'unite hors TVA : "); + clean_keyboard(); + scanf("%f", &(listeArticle->article.prixHTVA)); + break; + case 2: + printf("\nVeuillez entrer la quantite desiree : "); + clean_keyboard(); + scanf("%d", &(listeArticle->article.quant)); + break; + } + } +} + +ListeArticle * rechercheElemListe(ListeArticle * listeArticle) +{ + if(!listeArticle) + return NULL; + int i =0; + ListeArticle * deb = listeArticle; + do{ + if(!listeArticle) + printf("\nChoix Erroné !\n"); + listeArticle = deb; + afficherListeArticle(listeArticle); + printf("\nId :");clean_keyboard();scanf("%d", &i); + for(;listeArticle && i>1;listeArticle = listeArticle->suite,i--); + printf("%s\n", listeArticle->article.deisgnation); + }while (!listeArticle); + return listeArticle; +}