diff --git a/VANDAMME28.c b/VANDAMME28.c new file mode 100644 index 0000000..7a1f5ab --- /dev/null +++ b/VANDAMME28.c @@ -0,0 +1,653 @@ +#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 + +typedef enum{FALSE,TRUE} Bool; +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; +} Client; + + + + +void encoderDate(Date *, char *); +Bool dateValide (Date *); +void encoderArticle(Article *); +void encoderClient(Client *); +void sauvegarderClient(Client *, FILE *, Date*); +void afficherClient(Client *, Date *); +void encoderFacture(Panier *); +FILE * creerFichier(Date *, Client *); +Bool fichierExistant(char *); +void sauvergarderFacture(FILE *, Date *, Client *); +void afficherFacture(Date *, Client *); +void cleanFgets(char*); +int itoaY(int i, char*); +int itoaDM(int i, char*); +Bool clean_keyboard(); +int ageClient(Client *, Date *); +int pointsFidelite(float); +void gestionFacture(Client *, Date *); +Client * rechercheClient(char *, char *, FILE *, Date *); +Bool gestionClient(Client *, Date *); +FILE * localiserFichierClients(char *); +int ajouterClientBin(FILE *, Client *); +int compNP(char *, char *,char *, char *); +void qSortClientBinByNP(FILE *); + +int main() +{ + FILE * clientF; + 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; + } + + Client * client; + char nomClient[__STRLEN__]; + char prenomClient[__STRLEN__]; + char fichierClient[__STRLEN_FILE__]; + int choixMenu; + clientF = localiserFichierClients(fichierClient); + while(w) + { + printf("1. Nouveau client\n"); + printf("2. Client enregistré\n"); + do{ + printf("Choix (1|2):");clean_keyboard();scanf("%d", &choixMenu); + }while(!(choixMenu<=2 && choixMenu>=1)); + switch (choixMenu) + { + case 1: + client = malloc(sizeof(Client)); + encoderClient(client); + afficherClient(client, &date); + ajouterClientBin(clientF, client); + w = gestionClient(client, &date); + break; + case 2: + printf("Nom du client (sensible a la casse) : "); + clean_keyboard();scanf("%s", nomClient); + printf("\nPrenom du client (sensible a la casse) : "); + clean_keyboard();scanf("%s", prenomClient); + client = rechercheClient(nomClient, prenomClient clientF, &date); + if(client != NULL) + { + w = gestionClient(client, &date); + } + else + { + printf("Client non trouvé !\n"); + printf("%d",(int)sizeof(Client)); + } + break; + } + } + fclose(clientF); + return 0; +} +void encoderDate(Date * date, char invite[__STRLEN__]) +{ + do { + printf("%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 j = date->jour; + int m = date->moi; + int a = 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("Encodage 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("Client : %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 aqui : %d\n", client->fidelite); +} +void sauvegarderClient(Client *client, FILE * file, Date *date) +{ + fprintf(file, "Client : %s %s (%d)\n", client->nom, client->prenom, ageClient(client, date)); + 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); + fprintf(file, "\nPoints de fidelite aqui : %d\n", client->fidelite); +} +void encoderFacture(Panier * panier) +{ + char continuer = 'y'; + do{ + if(panier->nbrArt <= __MAXNBRART__) + { + encoderArticle(&(panier->article[panier->nbrArt-1])); + printf("Y-a-t-il encore un article ?(Y|n)"); + clean_keyboard(); + scanf("%c", &continuer); + if(panier->nbrArt < __MAXNBRART__ && (continuer|0b00100000) == 'y') + { + panier->nbrArt++; + Article * tempArticle; + tempArticle = (Article*)realloc(panier->article, sizeof(Article)*(panier->nbrArt)); + if(panier->article == NULL) + { + printf("ERREUR ALLOCATION !"); + free(tempArticle); + free(panier->article); + exit(-1); + } + else + { + panier->article = tempArticle; + } + } + else if((continuer|0b00100000) == 'y') + { + system("cls"); + printf("Vous avez ateint le nombre d'article maximum !\n\n"); + break; + } + } + }while((continuer|0b00100000) == 'y' && panier->nbrArt <= __MAXNBRART__); +} +FILE * creerFichier(Date * date, Client * client) +{ + char fileName[__STRLEN__+16]; + fileName[0] = '\0'; + char dir[__STRLEN__]; + int i; + char buf[5]; + printf("Dossier d'enregistrement : "); + clean_keyboard(); + scanf("%s", dir); + //Toute cette partie aurais pus être remplacé par un sprintf + strcat(fileName,client->nom); + itoaY(date->annee, buf); + strcat(fileName,buf); + itoaDM(date->moi, buf); + strcat(fileName, buf); + itoaDM(date->jour, buf); + strcat(fileName, buf); + strcat(fileName,"_"); + + + 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 creerFichier(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(FILE * file, Date * date, Client * client) +{ + int i; + float prixTot = 0; + 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 :"); + sauvegarderClient(client, file, date); + fprintf(file,"\n|---------------------------------------------------------------------------------------------|\ + \n| Designation | prixHTVA | Quantite | 10%% | prixTVAC |\ + \n|---------------------------------------------------------------------------------------------|"); + + for(i=0;client->panier.nbrArt>i;i++) + { + fprintf(file,"\n|%34s|%12.2f Eur |%14d| %c |%12.2f |",\ + client->panier.article[i].deisgnation,client->panier.article[i].prixHTVA,client->panier.article[i].quant\ + ,(client->panier.article[i].quant>=20)?'x':' ',\ + (client->panier.article[i].quant>=20)?client->panier.article[i].prixHTVA*__TVA__*__REDUC__*client->panier.article[i].quant:client->panier.article[i].prixHTVA*__TVA__*client->panier.article[i].quant); + prixTot += (client->panier.article[i].quant>=20)?client->panier.article[i].prixHTVA*__TVA__*__REDUC__*client->panier.article[i].quant:client->panier.article[i].prixHTVA*__TVA__*client->panier.article[i].quant; + } + fprintf(file,"\n|---------------------------------------------------------------------------------------------|"); + fprintf(file,"\nPrix totale :%f", prixTot); + fprintf(file, "\nPoints de fidelite aqui : %d\n", client->fidelite); +} + +void afficherFacture(Date * date, Client * client) +{ + int i; + float prixTot = 0; + 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(i=0;client->panier.nbrArt>i;i++) + { + printf("\n|%34s|%12.2f Eur |%14d| %c |%12.2f |",\ + client->panier.article[i].deisgnation,client->panier.article[i].prixHTVA,client->panier.article[i].quant\ + ,(client->panier.article[i].quant>=20)?'x':' ',\ + (client->panier.article[i].quant>=20)?client->panier.article[i].prixHTVA*__TVA__*__REDUC__*client->panier.article[i].quant:client->panier.article[i].prixHTVA*__TVA__*client->panier.article[i].quant); + prixTot += (client->panier.article[i].quant>=20)?client->panier.article[i].prixHTVA*__TVA__*__REDUC__*client->panier.article[i].quant:client->panier.article[i].prixHTVA*__TVA__*client->panier.article[i].quant; + } + printf("\n|---------------------------------------------------------------------------------------------|"); + client->fidelite = pointsFidelite(prixTot); + printf("\nPrix totale :%f", prixTot); + printf("\nPoints de fidelite aqui : %d\n", client->fidelite); + +} + + +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); + } +} +int itoaY(int i, char * buf) +{ + buf [0] = '0'; + buf [1] = '0'; + buf [2] = '0'; + buf [3] = '0'; + buf [4] = '\0'; + int j; + if(!i) + return 1; + buf [3] = '1'; + for(j=1; j<=i && j<=9999 ; j++) + { + if(!(j%1000)) + { + buf[0]++; + buf[1]='0'; + buf[2]='0'; + buf[3]='0'; + } + else if(!(j%100)) + { + buf[1]++; + buf[2]='0'; + buf[3]='0'; + } + else if(!(j%10)) + { + buf[2]++; + buf[3]='0'; + } + else + { + buf[3]++; + } + } + if(j>9999) + return 0; + else + return 1; +} +int itoaDM(int i, char * buf) +{ + buf[0] = '0'; + buf[1] = '0'; + buf[2] = '\0'; + int j; + if(!i) + return 1; + buf[1]++; + for(j=1; j<=i && j<=99 ; j++) + { + if(!(j%10)) + { + (buf[0])++; + (buf[1])='0'; + } + else + { + (buf[1])++; + } + } + if(j>99) + return 0; + else + return 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); +} + + +void gestionFacture(Client * client, Date * date) +{ + FILE * file; + + + printf("%d/%d/%d\n", date->jour, date->moi, date->annee ); + file = creerFichier(date, client); + + client->panier.article = (Article *)malloc(sizeof(Article)); + client->panier.nbrArt = 1; + if(client->panier.article == NULL) + { + printf("ERREUR ALLOCATION ARTICLE!"); + free(client->panier.article); + exit(-1); + } + + encoderFacture(&client->panier); + afficherFacture(date, client); + sauvergarderFacture(file, date, client); + // getch(); + fclose(file); + free(client->panier.article); +} + +Client * rechercheClient(char nom[__STRLEN__], char prenom[__STRLEN__], FILE * clientF, Date * date) +{ + Client * client = NULL; + client = malloc(sizeof(Client)); + fseek(clientF, sizeof(unsigned long int)+sizeof(Bool), SEEK_SET); //On se possitionne apprès le nbr de client + clearerr(clientF); //Clear EOF + do + { + fread(client, sizeof(Client), 1, clientF); + }while(!feof(clientF) && compNP(client->nom, client->prenom, nom, prenom)); + if(feof(clientF)) + return NULL; + else + return client; +} + +Bool gestionClient(Client * client, Date * date) +{ + char choix; + while(1) + { + do + { + printf("A. Donnees client\n"); + printf("B. Facture\n"); + printf("C. Retour\n"); + printf("D. Quitter"); + clean_keyboard();scanf("%c", &choix); + choix |= 0b00100000; + }while(!(choix == 'a' || choix == 'b' || choix == 'c' || choix == 'd')); + switch (choix) { + case 'a': + afficherClient(client, date); + break; + case 'b': + gestionFacture(client, date); + break; + case 'c': + return 1; + break; + case 'd': + return 0; + break; + } + } +} + +FILE * localiserFichierClients(char fichierClient[__STRLEN_FILE__]) +{ + FILE * clientF; + char rep[__STRLEN_FILE__]; + char repTmp[__STRLEN_FILE__]; + printf("Repertoir ou se trouve le fichier client.dat"); + clean_keyboard(); + scanf("%s", rep); + sprintf(repTmp,"%sclients.dat", rep); + clientF = fopen(repTmp, "r"); + if(clientF == NULL) + { + char c; + fclose(clientF); + printf("\nLe fichier n'existe pas. Voulez-vous le creer (C) ou changer de repertoir (R) (C|R)?"); + clean_keyboard();scanf("%c", &c); + if(c&0b00100000 == 'c') + { + clientF = fopen(repTmp, "wb"); + fwrite(0, sizeof(Bool), 1, clientF); //Les 1e bits stockent si fichier trier et le nbr de client + fwrite(0, sizeof(unsigned long int), 1, clientF); + fclose(clientF); + } + else + return localiserFichierClients(fichierClient); + } + else + fclose(clientF); + clientF = fopen(repTmp, "r+b"); + if(clientF == NULL) + { + printf("\nErreur ouverture fichier"); + return localiserFichierClients(fichierClient); + } + strcpy(fichierClient, repTmp); + return clientF; +} + +int ajouterClientBin(FILE * clientF, Client * client) +{ + int posi; + unsigned long int nbClient; + fseek(clientF,0,SEEK_SET); + fread(&nbClient,sizeof(unsigned long int),1,clientF); + fseek(clientF,0,SEEK_SET); + nbClient++; + fwrite(nbClient, sizeof(unsigned long int),1,clientF); + + fseek(clientF, 0, SEEK_END); + posi = ftell(clientF); + fwrite(client, sizeof(Client), 1, clientF); + fseek(clientF, 0, SEEK_END); + fflush(clientF); + return posi; +} +int compNP(char nom1[__STRLEN__], char prenom1[__STRLEN__],char nom2[__STRLEN__], char prenom2[__STRLEN__]) +{ + char np1[__STRLEN__*2]; + char np2[__STRLEN__*2]; + sprinf(np1,"%s%s", nom1, prenom1); + sprinf(np2,"%s%s", nom2, prenom2); + return strcmp(np1,np2); +} +void qSortClientBinByNP(FILE * clientF) +{ + Client client1, client2; + size_t sizeClient = sizeof(Client); + Bool trier; + fseek(clientF, 0, SEEK_SET); + clearerr(clientF); + unsigned long int nbrClients = 0; + fread(&nbrClients,sizeof(nbrClients),1, clientF); + fread(&trier, sizeof(Bool),1,clientF); + if(!trier) + { + const unsigned int start = ftell(clientF); + while(!feof(clientF)) + { + fread(&client1, sizeClient, 1, clientF); + if(feof(clientF)) //On est a la fin du fichier inutile d'aller plus loin + break; + fread(&client2, sizeClient, 1, clientF); + switch (compNP(client1.nom,client1.prenom,client2.nom,client2.prenom)) + { + case -1: + fseek(clientF,-sizeClient); + break; + case 1: + fseek(clientF,-(2*sizeClient)); + fwrite(client2,sizeClient,1,clientF); + fwrite(client1,sizeClient,1,clientF); + if((ftell(clientF)-(2*sizeClient))>start) //On est au début du fichier, inutile de comparer l'élem précédent + fseek(clientF,-sizeClient); + else + fseek(clientF,-(3*sizeClient); + clearerr(clientF); + break; + case 0: + fseek(clientF,-sizeClient); + break; + } + fflush(clientF); + } + } +}