diff --git a/admin_user.h b/admin_user.h index 5520a16..890c3e8 100644 --- a/admin_user.h +++ b/admin_user.h @@ -108,6 +108,7 @@ int admin_menu_user_choices(char* name,char* role){ printf("1. Inventory control\n"); printf("2. Transaction control\n"); printf("3. User control\n"); + printf("4. Role control\n"); printf("5. Exit and Logout\n"); printf(">"); scanf("%d", &choice); @@ -802,7 +803,7 @@ struct user list_user(struct user db); void user_control(){ struct user db = read_db_user(); int choice = 0; - while(choice != 9){ + while(choice != 3){ system("cls"); printf("User Control\n"); printf("1. Add User(shortcut)\n"); @@ -977,14 +978,14 @@ struct user list_user(struct user db){ } void print_user(struct user db, int cur, int end,struct Map* map){ - printf("%-5s%-10s%-10s%-10s%-10s\n","No.","Username","ID","Role","IsAdmin"); + printf("%-5s%-20s%-10s%-10s%-10s\n","No.","Username","ID","Role","IsAdmin"); for(int i = cur; i < end; i++){ - if(map[i].value != NULL){ + if(map == NULL){ bool isadmin = is_admin(db.row[i].role); - printf("%-5d%-10s%-10ld%-10s%-10c\n",i+7,db.row[i].name,db.row[i].id,db.row[i].role,isadmin?'Y':'N'); + printf("%-5d%-20s%-10ld%-10s%-10c\n",i+7,db.row[i].name,db.row[i].id,db.row[i].role,isadmin?'Y':'N'); }else{ bool isadmin = is_admin(db.row[map[i].key].role); - printf("%-5s%-10s%-10ld%-10s%-10c\n",i+7,db.row[map[i].key].name,db.row[map[i].key].id,db.row[map[i].key].role,isadmin?'Y':'N'); + printf("%-5s%-20s%-10ld%-10s%-10c\n",i+7,db.row[map[i].key].name,db.row[map[i].key].id,db.row[map[i].key].role,isadmin?'Y':'N'); } } } @@ -1038,8 +1039,8 @@ struct user showUser(struct user db,int index){ system("cls"); welcome_message(); printf("User detail\n"); - printf("%-10s%-10s%-10s\n","Username","ID","Role"); - printf("%-10s%-10ld%-10s\n",db.row[index].name,db.row[index].id,db.row[index].role); + printf("%-20s%-10s%-10s\n","Username","ID","Role"); + printf("%-20s%-10ld%-10s\n",db.row[index].name,db.row[index].id,db.row[index].role); printf("0 exit\n"); printf("1 edit user\n"); printf("2 delete user\n"); @@ -1067,8 +1068,9 @@ struct user showUser(struct user db,int index){ } //role control -void add_role(struct user db); -void edit_role(struct user db); +void add_role(); +void list_role(); + void role_control(){ int choice = -1; struct user db = read_db_user(); @@ -1077,7 +1079,7 @@ void role_control(){ welcome_message(); printf("Role control\n"); printf("0 exit\n"); - printf("1 add role\n"); + printf("1 add admin role\n"); printf("2 list role\n"); printf("Enter choice: "); fflush(stdin); @@ -1086,7 +1088,7 @@ void role_control(){ case 0: break; case 1: - add_role(db); + add_role(); break; case 2: list_role(db); @@ -1099,4 +1101,190 @@ void role_control(){ break; } }while(choice != 0); +} + + +void add_role(){ + char role[100]; + printf("Enter Admin role name: "); + fflush(stdin); + scanf("%s", role); + if(is_admin(role)){//check if role exist in admin file + printf("Admin role already exist\n"); + printf("press any key to continue\n"); + fflush(stdin); + getchar(); + }else{ + add_admin(role); + printf("role added\n"); + printf("press any key to continue\n"); + fflush(stdin); + getchar(); + } + return; +} + +void print_role(struct linkedlist* list,int cur,int end,struct Map* map); +struct Map* sortRole(struct linkedlist* list,int choice); +void showRole(struct linkedlist* list,int index); + +void list_role(){ + struct linkedlist* list = getLinkedList(role_list_db(),0); + int list_size = sizeofLinkedlist(list); + int choice = -1; + int page = 0; + int page_size = PAGE_SIZE; + int total_pages = ceil( (double)list_size / page_size); + struct Map* map = NULL; + //list role + do{ + system("cls"); + welcome_message(); + printf("Role list\n"); + printf("0 exit\n"); + printf("1 sort admin ascending\n"); + printf("2 sort admin descending\n"); + printf("3 sort role ascending\n"); + printf("4 sort role descending\n"); + if(page+1 == total_pages){ + print_role(list,page*page_size,list_size,map); + }else{ + print_role(list,page*page_size,(page+1)*page_size,map); + } + //page control + int current_page_size = page_size+2; + if(page+1 == total_pages){ + current_page_size = list_size - page*page_size + 4; + } + printf("%d next page\n",current_page_size+1); + printf("%d previous page\n",current_page_size+2); + printf("%d set page size\n",current_page_size+3); + printf("%d/%d/%d(page size/page number/total)\n",page_size,page+1,total_pages); + + bool valid = true; + do{ + valid = true; + printf("Please input your choice\n>"); + fflush(stdin); + scanf("%d", &choice); + if(choice <=4 && choice > 0){ + printf("sorting...\n"); + map = sortRole(list,choice); + }else if(choice == current_page_size+1){ + if(page + 1 < total_pages){ + page++; + }else{ + printf("Already at last page\n"); + valid = false; + } + }else if(choice == current_page_size+2){ + if(page > 0){ + page--; + }else{ + printf("Already at first page\n"); + valid = false; + } + }else if(choice == current_page_size+3){ + printf("Enter page size: "); + fflush(stdin); + scanf("%d", &page_size); + total_pages = ceil( (double)list_size / page_size); + page = 0; + + }else if(choice >= 5 && choice <= current_page_size){ + if(map == NULL){ + showRole(list,choice - 5 + page_size*page); + }else{ + showRole(list,map[choice - 5 + page_size*page].key); + } + }else if(choice != 0){ + printf("Invalid choice\n"); + valid = false; + } + }while(!valid); + }while(choice != 0); +} + +void print_role(struct linkedlist* list,int cur,int end,struct Map* map){ + printf("%-10s%-10s%-10s\n","No.","Role","Admin?"); + if(map == NULL){ + for(int i = cur; i < end; i++){ + list = getLinkedList(list,i); + char* name = list->data; + printf("%-10d%-10s%-10s\n",i-cur + 5,name,is_admin(name)?"T":"F"); + } + }else{ + for(int i = cur; i < end; i++){ + list = getLinkedList(list,map[i].key); + char* name = list->data; + printf("%-10d%-10s%-10s\n",i-cur + 5,name,is_admin(name)?"T":"F"); + } + } +} + +void showRole(struct linkedlist* list,int index){ + int choice; + list = getLinkedList(list,index); + do{ + char* name = list->data; + printf("%-10s%-10s\n","Role","Admin?"); + printf("%-10s%-10s\n",name,is_admin(name)?"T":"F"); + printf("1 toogle admin\n"); + printf("2 exit\n"); + bool valid = true; + do{ + valid = true; + printf("Please input your choice\n>"); + fflush(stdin); + scanf("%d", &choice); + if(choice == 1){ + if(is_admin(name)){ + remove_admin(name); + }else{ + add_admin(name); + } + printf("Admin role toggled\n"); + printf("Press any key to continue\n"); + fflush(stdin); + getchar(); + }else if(choice != 2){ + printf("Invalid choice\n"); + valid = false; + } + }while(!valid); + }while(choice != 2); + return; +} + + +struct Map* sortRole(struct linkedlist* list,int choice){ + struct Map* map = malloc(sizeof(struct Map)*sizeofLinkedlist(list)); + list = getLinkedList(list,0); + for(int i = 0; i < sizeofLinkedlist(list); i++){ + switch(choice){ + case 1: + case 2: + map[i].key = i; + bool temp = !is_admin(list->data); + bool* tempstar = malloc(sizeof(bool)); + *tempstar = temp; + map[i].value = tempstar; + break; + case 3: + case 4: + map[i].key = i; + map[i].value = list->data; + break; + } + } + switch(choice){ + case 1: + case 3: + qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_decending); + break; + case 2: + case 4: + qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_ascending); + break; + } } \ No newline at end of file diff --git a/database.h b/database.h index 8ce755e..375b2c4 100644 --- a/database.h +++ b/database.h @@ -13,6 +13,40 @@ #define DNT_H #include "dateNtime.h" #endif // !DNT_H +//linked list +typedef struct linkedlist{ + struct linkedlist* next; + struct linkedlist* prev; + void* data; +}linkedlist; +//linked list functions +int sizeofLinkedlist(struct linkedlist* list){ + linkedlist* start = list; + int size = 0; + while (list != NULL){ + size++; + list = list->next; + } + list = start; + while(list->prev != NULL){ + size++; + list = list->prev; + } + return size; +} +struct linkedlist* getLinkedList(struct linkedlist* list,int pos){ + while(list->prev != NULL){ + list = list->prev; + } + struct linkedlist* start = list; + for(int i=0;inext; + if(list == NULL){ + return start;//return start if pos is out of bounds + } + } + return list; +} typedef struct basic_db{ int row_count; bool init_status;//not really used can be useful @@ -103,7 +137,48 @@ bool is_admin(char* role){ return false; } +void add_admin(char* role){ + FILE* fp = fopen(ADMIN_DB,"a"); + if(fp == NULL){ + printf("Error opening file\n"); + return; + } + fprintf(fp,"%s\n",role); + fclose(fp); + return; +} +void remove_admin(char* role){ + FILE* fp = fopen(ADMIN_DB,"r"); + if(fp == NULL){ + printf("Error opening file\n"); + return; + } + char temp[30] = ADMIN_DB; + strcat(temp,".temp"); + FILE* fp2 = fopen(temp,"w"); + if(fp2 == NULL){ + printf("Error opening file\n"); + return; + } + char line[100]; + while(fgets(line,100,fp) != NULL){ + if(line[0] == '#') { + fprintf(fp2,"%s",line); + continue; + } + if(line[strlen(line)-1] == '\n')//remove newline for compare + line[strlen(line)-1] = '\0'; + if(strcmp(line,role) != 0){ + fprintf(fp2,"%s\n",line); + } + } + fclose(fp); + fclose(fp2); + remove(ADMIN_DB); + rename(temp,ADMIN_DB); + return; +} //list of db func int basic_get_row_count(int end, FILE *fp){ fseek(fp, 0, SEEK_SET);//prevent pointer on wrong position @@ -289,6 +364,81 @@ struct user read_db_user(){ return db; } +struct linkedlist* role_list_db(){ + struct user db = read_db_user(); + struct linkedlist* list = (struct linkedlist*)malloc(sizeof(struct linkedlist)); + //put unqie user role into linked list in acending order + struct linkedlist* current = list; + //initial the first node + current->data = db.row[0].role; + current->next = NULL; + current->prev = NULL; + for(int i=1;idata,role); + if(diff == 0){ + continue; + }else if(diff > 0){ + while(diff > 0){ + if(diff == 0){ + break; + }else if(diff < 0){ + //insert before current + struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist)); + new->data = role; + new->next = current; + new->prev = current->prev; + current->prev->next = new; + current->prev = new; + break; + }else{ + if(current->next == NULL){ + //insert after current + struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist)); + new->data = role; + new->next = NULL; + new->prev = current; + current->next = new; + break; + }else{ + current = current->next; + diff = strcmp(current->data,role); + } + } + } + }else{ + while(diff < 0){ + if(diff == 0){ + break; + }else if(diff > 0){ + //insert after current + struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist)); + new->data = role; + new->next = current; + new->prev = current->prev; + current->prev->next = new; + current->prev = new; + break; + }else{ + if(current->prev == NULL){ + //insert before current + struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist)); + new->data = role; + new->next = current; + new->prev = NULL; + current->prev = new; + break; + }else{ + current = current->prev; + diff = strcmp(current->data,role); + } + } + } + } + } + return list; +} + bool update_db_invt(struct inventory invt){ FILE* fpR = fopen(INVENTORY_DB,"r"); char temp[30] = INVENTORY_DB; diff --git a/normal_user.h b/normal_user.h index 589a09f..e963e57 100644 --- a/normal_user.h +++ b/normal_user.h @@ -110,7 +110,7 @@ void list_page(struct inventory db,struct Map* map,int row,struct inventory (*sh //print items if(page + 1 >= total_pages){ print_page(db, page * page_size, row,map); - }else{//sorted) + }else{ print_page(db, page * page_size, (page + 1) * page_size,map); } @@ -197,12 +197,9 @@ void list_items(){ //for sorting 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++){ + struct Map *map = malloc(sizeof(struct Map) * db.db.row_count-1); + for (int i = 0; i < db.db.row_count-1; i++){ map[i].key = i; - if(db.row[i].barcode == -1024)//catch new item - map[i].value = NULL; - continue; switch(sort){ case 1: @@ -232,15 +229,17 @@ struct Map* sortItems(struct inventory db, int sort){ case 3: case 5: case 7: - qsort(map, db.db.row_count, sizeof(struct Map), compare_decending); + qsort(map, db.db.row_count-1, 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); + qsort(map, db.db.row_count-1, sizeof(struct Map), compare_ascending); break; } + map = realloc(map, sizeof(struct Map) * db.db.row_count); + map[db.db.row_count-1].key = db.db.row_count-1; return map; } diff --git a/sorting.h b/sorting.h index 4467cc7..ba95a30 100644 --- a/sorting.h +++ b/sorting.h @@ -4,7 +4,7 @@ typedef struct Map{ }Map; int compare_decending(const void *a, const void *b){ - if((*(struct Map *)b).value == NULL){//for dont sort new item + if((*(struct Map *)b).value == NULL){//To prevent null pointer cause error return -1; }else if((*(struct Map *)a).value == NULL){ return 1;