From fcbd309c69a895c6200bc5854c3ae4a2068ee78f Mon Sep 17 00:00:00 2001 From: smarttommyau Date: Sat, 27 Aug 2022 17:33:07 +0800 Subject: [PATCH] list_item_first_bui;d test --- .gitignore | 1 + admin_user.h | 16 +- data_file_inventory.txt | 2 +- database.h | 393 +++++++++++++++++++++++++++++++++++----- dateNtime.h | 1 + filecontrol.h | 1 + main.c | 1 + menu.h | 1 + normal_user.h | 192 +++++++++++++++++++- sorting.h | 11 ++ 10 files changed, 568 insertions(+), 51 deletions(-) create mode 100644 .gitignore create mode 100644 sorting.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f4ebb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +main.exe diff --git a/admin_user.h b/admin_user.h index 95e5890..3d27ee6 100644 --- a/admin_user.h +++ b/admin_user.h @@ -5,4 +5,18 @@ #include #include #include -#endif \ No newline at end of file +#include +#endif + +#ifndef MENU_H +#define MENU_H +#include "menu.h" +#endif //MENU_H + +bool admin_menu(){ + system("cls"); + welcome_message(); + + + return true; +} \ No newline at end of file diff --git a/data_file_inventory.txt b/data_file_inventory.txt index 6c26fe7..b219055 100644 --- a/data_file_inventory.txt +++ b/data_file_inventory.txt @@ -1,4 +1,4 @@ -#category, brand, product, price, cost, stock, barcode +#category, brand, product, price, stock, barcode Test Testing Co Ltd Testing Product diff --git a/database.h b/database.h index 94bb8bb..3deade3 100644 --- a/database.h +++ b/database.h @@ -5,18 +5,20 @@ #include #include #include +#include #endif #ifndef DNT_H #define DNT_H #include "dateNtime.h" #endif // !DNT_H typedef struct basic_db{ - FILE *fp; int row_count; + bool init_status; //array of struct of row }; //inventory +#define INVENTORY_DB "data_file_inventory.txt" typedef struct inventory{ struct basic_db db; struct inventory_row* row; @@ -27,15 +29,16 @@ typedef struct inventory_row{ char band[100]; char product[100]; double price; - double cost; int stock; long barcode; + bool isdeleted;//common for all rows,default is false }; -typedef enum INVENTORY { - category = 1, brand = 2, product = 3, price = 4, cost = 5, stock = 6 , barcode = 7 - }; - +typedef enum { + category = 1, brand = 2, product = 3, price_inv = 4, stock = 5, barcode_inv = 6 + }INVENTORY; +#define ENDOFINVENTORY 6 //transaction +#define TRANSACTION_DB "data_file_transaction.txt" typedef struct transaction{ struct basic_db db; struct transaction_row* row; @@ -48,12 +51,14 @@ typedef struct transaction_row{ double price; int quantity; long barcode; + bool isdeleted;//common for all rows,default is false }; -typedef enum TRANSACTION { - date = 1, time = 2, id = 3, price = 5, quantity = 4, barcode = 7 - }; - +typedef enum { + date = 1, time = 2, id_tran = 3, price_tran = 5, quantity = 4, barcode_tran = 7 + }TRANSACTION; +#define ENDOFTRANSACTION 7 //user +#define USER_DB "data_file_user.txt" typedef struct user{ struct basic_db db; struct user_row* row; @@ -63,50 +68,344 @@ typedef struct user_row{ char role[100]; long id; bool isAdmin; + bool isdeleted;//common for all rows,default is false }; -typedef enum USER { - name = 1, role = 2,id = 3 - }; - - +typedef enum { + name = 1, role = 2, id_user = 3 + }USER; +#define ENDOFUSER 3 +//TODOLwrite function for these functions //list of db func -bool read_db_invt(FILE* fp,enum INVENTORY inventory){ +int basic_get_row_count(int end, FILE *fp){ + fseek(fp, 0, SEEK_SET);//prevent pointer on wrong position + //get row count + int row_count = 0; + int colmun_count = 0; + while(!feof(fp)&&!ferror(fp)){ + char buffer[100]; + fgets(buffer, sizeof(buffer),fp); + if(buffer[0] == '#'){//catch comment line and ignore + continue; + } + colmun_count++; + if(colmun_count == end){ + row_count++; + colmun_count = 0; + } + } +} + +struct inventory read_db_invt(){//please open file in read mode + FILE* fp = fopen(INVENTORY_DB, "r"); + struct inventory db; + + //gets the number of rows in the file + int row_count = basic_get_row_count(ENDOFINVENTORY,fp); + db.row = (struct inventory_row*)malloc(row_count * sizeof(struct inventory_row)); + db.db.row_count = row_count; + + fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file + + //read data + for(int i=0;idb.row_count;i++){ + if(invt->row[i].isdeleted == true){ + continue; + } + for(INVENTORY j=category;jrow[i].category); + break; + case brand: + fprintf(fpW,"%s",invt->row[i].band); + break; + case product: + fprintf(fpW,"%s",invt->row[i].product); + break; + case price_inv: + fprintf(fpW,"%f",invt->row[i].price); + break; + case stock: + fprintf(fpW,"%d",invt->row[i].stock); + break; + case barcode_inv: + fprintf(fpW,"%ld",invt->row[i].barcode); + break; + } + fprintf(fpW,"\n"); + } + } + //close file and replace old file with new file + fclose(fpR); + fclose(fpW); + remove(INVENTORY_DB); + rename(temp,INVENTORY_DB); + return true; + +} + +bool update_db_tran(struct transaction* tran){ + FILE* fpR = fopen(TRANSACTION_DB,"r"); + char temp[30] = TRANSACTION_DB; + strcat(temp,".temp"); + FILE* fpW = fopen(temp,"w"); + if(fpR == NULL || fpW == NULL){ + printf("Error in opening file\n"); + return false; + } + for(int i=0;idb.row_count;i++){ + if(tran->row[i].isdeleted == true){ + continue; + } + for(TRANSACTION j=date;jrow[i].date.day,tran->row[i].date.month,tran->row[i].date.year); + break; + case time: + fprintf(fpW,"%d:%d:%d",tran->row[i].time.hour,tran->row[i].time.minute,tran->row[i].time.second); + break; + case id_tran: + fprintf(fpW,"%ld",tran->row[i].id); + break; + case price_tran: + fprintf(fpW,"%f",tran->row[i].price); + break; + case quantity: + fprintf(fpW,"%d",tran->row[i].quantity); + break; + case barcode_tran: + fprintf(fpW,"%ld",tran->row[i].barcode); + break; + } + fprintf(fpW,"\n"); + } + } + //close file and replace old file with new file + fclose(fpR); + fclose(fpW); + remove(TRANSACTION_DB); + rename(temp,TRANSACTION_DB); return true; } -bool read_db_tran(FILE* fp,enum TRANSACTION transaction){ - return true; -} -bool read_db_user(FILE* fp,enum USER user){ - return true; -} -bool new_db_invt(FILE* fp,enum INVENTORY inventory){ - return true; -} -bool new_db_tran(FILE* fp,enum TRANSACTION transaction){ - return true; -} -bool new_db_user(FILE* fp,enum USER user){ - return true; -} -bool edit_db_invt(FILE* fp,enum INVENTORY inventory){ - return true; -} -bool edit_db_tran(FILE* fp,enum TRANSACTION transaction){ - return true; -} -bool edit_db_user(FILE* fp,enum USER user){ - return true; -} -bool rm_db_invt(FILE* fp,enum INVENTORY inventory){ - return true; -} -bool rm_db_tran(FILE* fp,enum TRANSACTION transaction){ - return true; -} -bool rm_db_user(FILE* fp,enum USER user){ + +bool update_db_user(struct user* user){ + FILE* fpR = fopen(USER_DB,"r"); + char temp[30] = USER_DB; + strcat(temp,".temp"); + FILE* fpW = fopen(temp,"w"); + if(fpR == NULL || fpW == NULL){ + printf("Error in opening file\n"); + return false; + } + for(int i=0;idb.row_count;i++){ + if(user->row[i].isdeleted == true){ + continue; + } + for(USER j=name;jrow[i].name); + break; + case role: + fprintf(fpW,"%s",user->row[i].role); + break; + case id_user: + fprintf(fpW,"%ld",user->row[i].id); + break; + } + fprintf(fpW,"\n"); + } + } + //close file and replace old file with new file + fclose(fpR); + fclose(fpW); + remove(USER_DB); + rename(temp,USER_DB); return true; } \ No newline at end of file diff --git a/dateNtime.h b/dateNtime.h index cb2a10c..a97a04c 100644 --- a/dateNtime.h +++ b/dateNtime.h @@ -5,6 +5,7 @@ #include #include #include +#include #endif //DATE typedef struct date{ diff --git a/filecontrol.h b/filecontrol.h index 53b4675..d6f5644 100644 --- a/filecontrol.h +++ b/filecontrol.h @@ -5,4 +5,5 @@ #include #include #include +#include #endif diff --git a/main.c b/main.c index 1ab985b..268ea13 100644 --- a/main.c +++ b/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #endif #ifndef CUSTOM_H #define CUSTOM_H diff --git a/menu.h b/menu.h index 1cb33e1..27cf4f3 100644 --- a/menu.h +++ b/menu.h @@ -5,6 +5,7 @@ #include #include #include +#include #endif diff --git a/normal_user.h b/normal_user.h index fe2826d..0771344 100644 --- a/normal_user.h +++ b/normal_user.h @@ -5,6 +5,7 @@ #include #include #include +#include #endif #ifndef MENU_H @@ -12,9 +13,196 @@ #include "menu.h" #endif //MENU_H +#ifndef SORT_H +#define SORT_H +#include "sorting.h" +#endif // !SORT_H +#define PAGE_SIZE 20 + +//for sort list +void list_items(); +int normal_menu_user_choices(); bool normal_menu(){ + system("cls"); + welcome_message(); + //the selection menu + int choice = normal_menu_user_choices(); + + switch (choice) + { + case 1://List items + list_items(); + break; + case 2://Search item + // search_item(); + break; + case 3://scan barcode + // scan_barcode(); + break; + case 4://Exit + return false; + break; + default://invalid input + printf("Invalid choice\n"); + return false; + break; + } + + return true; +} + + +int normal_menu_user_choices(){ + int choice; + printf("You can buy items inside the 2 option below\n"); + printf("1. List items\n"); + printf("2. Search item\n"); + printf("3. Scan Barcodes\n"); + printf("4. Exit\n"); + printf("Enter your choice: "); + scanf("%d", &choice); + return choice; +} + +//list items +void show_item(struct inventory db,int index); +void print_page(struct inventory db, int cur, int end,struct Map* map); +struct Map* sortItems(struct inventory db, int sort); +void list_items(){ + system("cls"); + welcome_message(); + //get the list of items from the database + //print the list of items + //prompt user to select an item + //if user selects an item, display the item's details + int choice = -1; + int page = 0; + int page_size = PAGE_SIZE; + struct inventory db = read_db_invt(); + int total_pages = ceil(db.db.row_count / page_size); + struct Map* map = NULL; + + + do{ + + //ooptions + system("cls"); + printf("0 exit\n"); + printf("1 sort name decending\n"); + printf("2 sort name ascending\n"); + printf("3 sort price decending\n"); + printf("4 sort price ascending\n"); + printf("5 sort band decending\n"); + printf("6 sort band ascending\n"); + printf("7 sort category decending\n"); + printf("8 sort category ascending\n"); + printf("List of items:\n"); + + //print items + if(map == NULL){ + print_page(db, page * page_size, (page + 1== total_pages)?db.db.row_count:(page+1) * page_size,(struct Map*)NULL); + }else{//sorted) + print_page(db, page * page_size, (page + 1== total_pages)?db.db.row_count:(page+1) * page_size,map); + } + + //page control + printf("%d next page\n", page_size+3); + printf("%d previous page\n", page_size+4); + printf("%d set page size\n", page_size+5); + printf("%D/%d/%d(page size/page number/total)\n",page_size, page+1,total_pages); + + //prompt user to select an item + bool valid = true; + do{ + printf("Enter your choice: "); + scanf("%d", &choice); + if(choice <=8 && choice > 0){ + printf("sorting...\n"); + map = sortItems(db,choice); + }else if(choice == page_size+3){ + page++; + }else if(choice == page_size+4 && page > 0){ + page--; + }else if(choice == page_size+5){ + printf("Enter page size: "); + scanf("%d", &page_size); + total_pages = ceil(db.db.row_count / page_size); + }else if(choice >= 0 && choice < db.db.row_count){ + show_item(db,choice-9 + page_size*page); + }else{ + printf("Invalid choice\n"); + valid = false; + } + }while(!valid); + + }while(choice != 0); +} +struct Map* sortItems(struct inventory db, int sort){ + struct Map *map = malloc(sizeof(struct Map) * db.db.row_count); + for (int i = 0; i < db.db.row_count; i++){ + map[i].key = i; + switch(sort){ + case 1: + case 2: + map[i].value = (int)db.row[i].product; + break; + + case 3: + case 4: + map[i].value = (int)db.row[i].price*100;//presume there is no price contain 0.001 + break; + case 5: + case 6: + map[i].value = (int)db.row[i].band; + break; + case 7: + case 8: + map[i].value = (int)db.row[i].category; + break; + } + } + switch (sort){ + case 1: + case 3: + case 5: + case 7: + qsort(map, db.db.row_count, sizeof(struct Map), compare_decending); + break; + case 2: + case 4: + case 6: + case 8: + qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending); + break; + } + return map; +} + +void print_page(struct inventory db, int cur, int end,struct Map* map){ + for (int i = cur; i < end; i++) + { + if(map != NULL){ + printf("%d. %s\n", i + 1, db.row[map[i].key].product); + } + else{ + printf("item%d. %s\n", i + 3, db.row[i].product); + } + } +} + +void show_item(struct inventory db,int index){ + system("cls"); + printf("Product: %s\n", db.row[index].product); + printf("Catergory: %s\n", db.row[index].category); + printf("Band: %d\n", db.row[index].band); + printf("Price: $%lf\n", db.row[index].price); + printf("Stock: %d\n", db.row[index].stock); + printf("Barcode: %ld\n",db.row[index].barcode); + + return; +} - retrurn true -} \ No newline at end of file +// + diff --git a/sorting.h b/sorting.h new file mode 100644 index 0000000..7a2234d --- /dev/null +++ b/sorting.h @@ -0,0 +1,11 @@ +typedef struct Map{ + int key; + int value; +}; + +int compare_decending(const void *a, const void *b){ + return (*(struct Map *)b).value - (*(struct Map *)a).value; +} +int compare_ascending(const void *a, const void *b){ + return (*(struct Map *)a).value - (*(struct Map *)b).value; +} \ No newline at end of file