diff --git a/admin_user.h b/admin_user.h index 5b5735d..7672002 100644 --- a/admin_user.h +++ b/admin_user.h @@ -18,10 +18,10 @@ //TODO: split all controller functions into their own files //TODO: reformat all output to be formatted and unifed //TODO: create a list base function to unified all variants of list functions -void inv_control(); -void tran_control(); -void user_control(); -void role_control(); +#include "inv_control.h" +#include "tran_control.h" +#include "user_control.h" +#include "role_control.h" struct user_row *prompt_user(); int admin_menu_user_choices(char* name,char* role); @@ -105,901 +105,3 @@ struct user_row *prompt_user(){ } return user; } - - -//invetory control -void add_item(); -void remove_item(struct inventory db,int index); -void update_item(struct inventory db,int index); -void admin_list_pages(struct inventory db); -void * item_control(void * ddb,int index); - - -void inv_control(){ - int choice = 0; - do{ - char * items[] = { - "List(allow all operation include add)", - "Add item(shortcut to add item)" - }; - choice = choices_selecter(items,2,NULL); - switch (choice){ - case 1:;//list - //add a new element with product name new item - //for item control - struct inventory db = read_db_invt(); - db.row = (struct inventory_row *)realloc(db.row, sizeof(struct inventory_row) * (db.db.row_count + 1)); - db.db.row_count += 1; - strcpy(db.row[db.db.row_count - 1].product,"CREATE NEW ITEM"); - db.row[db.db.row_count - 1].barcode = -1024;//IMPORTANT: -1024 is reserved for new item - char * SortItems[] = { - "Name", - "Price", - "Brand", - "Category", - }; - lister(&db,NULL,db.db.row_count,"Inventory",SortItems,4,print_page,sortItems,item_control); - break; - case 2://add item - add_item(); - break; - case 3://exit - break; - default://should not happen - printf("Invalid choice\n"); - break; - } - }while(choice != 3); -} - -char * show_item_admin(struct inventory db,int index){ - char * output = (char*)malloc(sizeof(char) * 2048); - sprintf(output,"Product: %s\n", db.row[index].product); - sprintf(output+strlen(output),"Catergory: %s\n", db.row[index].category);// strlen to add offset - sprintf(output+strlen(output),"Brand: %s\n", db.row[index].brand); - sprintf(output+strlen(output),"Price: $%lf\n", db.row[index].price); - sprintf(output+strlen(output),"Stock: %d\n", db.row[index].stock); - sprintf(output+strlen(output),"Barcode: %ld\n",db.row[index].barcode); - return output; -} -void * item_control(void * ddb,int index){ - struct inventory db = *((struct inventory*)ddb); - int choice = 0; - if(db.row[index].barcode == -1024){//new item - add_item(); - struct inventory temp = read_db_invt();//reappend new item at back - temp.row = (struct inventory_row *)realloc(temp.row, sizeof(struct inventory_row) * (temp.db.row_count + 1)); - temp.db.row_count += 1; - strcpy(temp.row[temp.db.row_count - 1].product,"CREATE NEW ITEM"); - temp.row[temp.db.row_count - 1].barcode = -1024;//IMPORTANT: -1024 is reserved for new item - void * re = malloc(sizeof(temp)); - memcpy(re,&temp,sizeof(temp)); - return re; - } - char * item = show_item_admin(db,index); - char welcome[4096]; - strcpy(welcome,item); - strcat(welcome,"Operations\n"); - do - { - char * items[] = { - "update item", - "remove item" - }; - choice = choices_selecter(items,2,welcome); - switch (choice) - { - case 1: - update_item(db,index); - break; - case 2: - remove_item(db,index); - break; - default: - break; - } - } while (choice != 3&&choice != 2); - struct inventory temp = read_db_invt(); - temp.row = (struct inventory_row *)realloc(temp.row, sizeof(struct inventory_row) * (temp.db.row_count + 1)); - temp.db.row_count += 1; - strcpy(temp.row[temp.db.row_count - 1].product,"CREATE NEW ITEM"); - temp.row[temp.db.row_count - 1].barcode = -1024;//IMPORTANT: -1024 is reserved for new item - void * re = malloc(sizeof(temp)); - memcpy(re,&temp,sizeof(temp)); - return re; -} - -void add_item(){ - Cls(); - printf("Add new item\n"); - struct inventory_row *item = (struct inventory_row *)malloc(sizeof(struct inventory_row)); - if(!item_inputer("name",STRING,&item->product,false) || - !item_inputer("brand",STRING,&item->brand,false) || - !item_inputer("category",STRING,&item->category,false) || - !item_inputer("price",DOUBLE,&item->price,false) || - !item_inputer("stock",INT,&item->stock,false) || - !item_inputer("barcode",LONG,&item->barcode,false) - ){ - free(item); - return; - } - if(item == NULL || !append_inventory(item)){ - printf("Failed to add item\n"); - }else{ - printf("Item added\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); -} - -void update_item(struct inventory db,int index){ - char temp[100]; - printf("Update item(empty value to not change the value)\n"); - printf("Name: %s\n", db.row[index].product); - printf("Brand: %s\n", db.row[index].brand); - printf("Catergory: %s\n", db.row[index].category); - printf("Price: $%lf\n", db.row[index].price); - printf("Stock: %d\n", db.row[index].stock); - printf("Barcode: %ld\n",db.row[index].barcode); - item_inputer("name",STRING,&db.row[index].product,true); - item_inputer("brand",STRING,&db.row[index].brand,true); - item_inputer("category",STRING,&db.row[index].category,true); - item_inputer("stock",DOUBLE,&db.row[index].price,true); - item_inputer("barcode",LONG,&db.row[index].barcode,true); - if(!update_db_invt(db)){ - printf("Failed to update item\n"); - exit(1); - }else{ - printf("Item updated\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); -} - -void remove_item(struct inventory db,int index){ - printf("Remove item\n"); - printf("Are you sure you want to remove this item? (y/n)\n"); - char choice; - fflush_stdin(); - scanf("%c", &choice); - db.row[index].isdeleted = true; - if(choice == 'y'){ - if(!update_db_invt(db)){ - printf("Failed to remove item\n"); - }else{ - printf("Item removed\n"); - } - }else{ - printf("Item not removed\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); -} - -//tran control -void add_tran(); -void print_tran(void * ddb, int cur, int end,struct Map* map); -void * showTran(void * ddb,int index); -struct Map* sortTrans(void * ddb,int choice); - -void tran_control(){ - struct transaction tran = read_db_tran(); - int choice; - do{ - char * items[] = { - "List transaction", - "new transaction" - }; - choice = choices_selecter(items,2,"><\nTransaction control"); - switch(choice){ - case 1: - char * SortItems[] = { - "Date&Time", - "product(barcode)", - "quantity", - "total", - }; - lister(&tran,NULL,tran.db.row_count,"Transaction",SortItems,4,print_tran,sortTrans,showTran); - break; - case 2: - add_tran(tran); - break; - default: - break; - } - }while(choice != 3); -} - -void print_tran(void * ddb, int cur, int end,struct Map* map){ - struct transaction db = *((struct transaction*)ddb); - printf("%-5s%-15s%-10s%-10s%-10s%-10s%-10s%-10s\n","No.","Date","Time","Barcode","ID","Price","Quantity","Total"); - for (int i = cur; i < end; i++) - { - if(map != NULL){ - int index = map[i].key; - double total = db.row[index].price * db.row[index].quantity; - //reconstuct date and time and print all transaction info out - char date[11]; - char time[9]; - sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year); - sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second); - printf("%-5d%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",i+9,date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity,total); - }else{ - double total = db.row[i].price * db.row[i].quantity; - //reconstuct date and time and print all transaction info out - char date[11]; - char time[9]; - sprintf(date,"%02d-%02d-%04d",db.row[i].date.day,db.row[i].date.month,db.row[i].date.year); - sprintf(time,"%02d:%02d:%02d",db.row[i].time.hour,db.row[i].time.minute,db.row[i].time.second); - printf("%-5d%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",i+9,date,time,db.row[i].barcode,db.row[i].id,db.row[i].price,db.row[i].quantity,total); - } - } -} -//show trans - -struct transaction update_tran(struct transaction db,int index); -struct transaction remove_tran(struct transaction db,int index); - -void * showTran(void * ddb,int index){ - struct transaction db = *((struct transaction*)ddb); - int choice; - do{ - printf("Transaction detail\n"); - double total = db.row[index].price * db.row[index].quantity; - //reconstuct date and time and print all transaction info out - char date[11]; - char time[9]; - sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year); - sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second); - printf("%-15s%-10s%-10s%-10s%-10s%-10s%-10s\n","Date","Time","Barcode","ID","Price","Quantity","Total"); - printf("%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity,total); - printf("1 edit transaction\n"); - printf("2 delete transaction\n"); - printf("3 exit\n"); - bool valid = true; - do{ - printf("Please input your choice: "); - fflush_stdin(); - scanf("%d",&choice); - switch(choice){ - case 1: - valid = true; - db = update_tran(db,index); - break; - case 2: - valid = true; - db = remove_tran(db,index); - break; - case 3: - valid = true; - break; - default: - printf("Invalid input, try again\n"); - valid = false; - break; - } - }while(!valid); - }while(choice != 3); - void * re = malloc(sizeof(db)); - memcpy(re,&db,sizeof(db)); - return re; -} - -//tran controls -void add_tran(){ - char* temp; - struct transaction_row* row = (struct transaction_row*)malloc(sizeof(struct transaction_row)); - char check; - printf("Use current date time? (y/n): "); - fflush_stdin(); - scanf("%c",&check); - if(check == 'y'){ - row->date = get_date(); - row->time = get_time(); - }else{ - if( !item_inputer("date:day",INT,&row->date.day,false) || - !item_inputer("date:month",INT,&row->date.month,false) || - !item_inputer("date:year",INT,&row->date.year,false) || - !item_inputer("time:hour",INT,&row->time.hour,false) || - !item_inputer("time:minute",INT,&row->time.minute,false) || - !item_inputer("time:second",INT,&row->time.second,false) - ){ - free(row); - return; - } - } - if ( - !item_inputer("price",DOUBLE,&row->price,false) || - !item_inputer("quantity",INT,&row->quantity,false) || - !item_inputer("ID",LONG,&row->id,false) || - !item_inputer("barcode",LONG,&row->barcode,false) - ){ - free(row); - return; - } - if(row == NULL || !append_transaction_db(row)){ - printf("Failed to add item\n"); - }else{ - printf("Item added\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - - -} - -struct transaction update_tran(struct transaction db,int index){ - char temp[100]; - printf("Update transaction(empty value to not change the value)\n"); - char date[11],time[9]; - sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year); - sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second); - printf("%-15s%-10s%-10s%-10s%-10s%-10s\n","Date","Time","Barcode","ID","Price","Quantity"); - printf("%-15s%-10s%-10d%-10d%-10.2lf%-10d\n",date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity); - - item_inputer("Date:day",INT,&db.row[index].date.day,true); - item_inputer("Date:month",INT,&db.row[index].date.month,true); - item_inputer("Date:year",INT,&db.row[index].date.year,true); - item_inputer("Time:hour",INT,&db.row[index].time.hour,true); - item_inputer("Time:minute",INT,&db.row[index].time.minute,true); - item_inputer("Time:second",INT,&db.row[index].time.second,true); - item_inputer("Price",DOUBLE,&db.row[index].price,true); - item_inputer("Quantity",INT,&db.row[index].quantity,true); - item_inputer("ID",LONG,&db.row[index].id,true); - item_inputer("Barcode",LONG,&db.row[index].barcode,true); - - if(!update_db_tran(db)){ - printf("Failed to update transaction\n"); - exit(1);//exit program to prevent errors - }else{ - printf("Transaction updated\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - - return db; -} - -struct transaction remove_tran(struct transaction db,int index){ - db.row[index].isdeleted = true; - if(!update_db_tran(db)){ - printf("Failed to delete transaction\n"); - exit(1);//exit program to prevent errors - }else{ - printf("Transaction deleted\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - - return read_db_tran(); -} - -//sort transaction - -struct Map* sortTrans(void * ddb,int choice){ - struct transaction db = *((struct transaction*)ddb); - struct Map *map = malloc(sizeof(struct Map) * db.db.row_count); - printf("l"); - for (int i = 0; i < db.db.row_count; i++){ - map[i].key = i; - switch(choice){ - case 1: - case 2:; - long long temp = (long long)db.row[i].time.second+ db.row[i].time.minute*60 + db.row[i].time.hour*3600 + db.row[i].date.day*86400 + db.row[i].date.month*2592000 + db.row[i].date.year*31104000; - long long* tempstar = malloc(sizeof(long long)); - *tempstar = temp; - map[i].value = (void*)tempstar; - break; - - case 3: - case 4:; - long* tempstar2 = malloc(sizeof(long)); - *tempstar2 = db.row[i].barcode; - map[i].value = (void*)tempstar2; - break; - case 5: - case 6:; - int* tempstar3 = malloc(sizeof(int)); - *tempstar3 = db.row[i].quantity; - map[i].value = (void*)tempstar3; - break; - case 7: - case 8:; - long temp4 = lround(db.row[i].price * db.row[i].quantity * 10000);//clear all decimal places - long* tempstar4 = malloc(sizeof(long)); - *tempstar4 = temp4; - map[i].value = (void*)tempstar4; - break; - } - } - switch (choice){ - 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; -} - -//user control -struct user add_user(struct user db); -void * showUser(void * ddb,int index); -struct Map* SortUser(void * ddb,int choice); -void print_user(void * ddb, int cur, int end,struct Map* map); -void user_control(){ - struct user db = read_db_user(); - int choice = 0; - while(choice != 3){ - Cls(); - printf("User Control\n"); - printf("1. Add User(shortcut)\n"); - printf("2. List User\n"); - printf("3. Exit\n"); - printf("Please input your choice\n>"); - fflush_stdin(); - scanf("%d",&choice); - switch(choice){ - case 1: - db = add_user(db); - break; - case 2: - char * SortItems[] = { - "Name", - "ID", - "Role", - }; - lister(&db,NULL,db.db.row_count,"User",SortItems,3,print_user,SortUser,showUser); - db = read_db_user(); - break; - case 3: - break; - default: - printf("Invalid choice\n"); - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - break; - } - } -} - -struct user add_user(struct user db){ - char* temp; - int index = db.db.row_count; - struct user_row *temprow = realloc(db.row, sizeof(struct user_row)); - if ( - !item_inputer("name",STRING,&temprow->name,false) || - !item_inputer("id",LONG,&temprow->id,false) || - !item_inputer("role",STRING,&temprow->role,false) - ){ - free(temprow); - return db; - } - - if(!append_user(temprow)){ - printf("Failed to add user\n"); - exit(1);//exit program to prevent errors - }else{ - printf("User added\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - - return read_db_user(); -} -struct user edit_user(struct user db,int index){ - char temp[100]; - printf("Update transaction(empty value to not change the value)\n"); - 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); - item_inputer("username",STRING,&db.row[index].name,true); - item_inputer("id",LONG,&db.row[index].id,true); - item_inputer("role",STRING,&db.row[index].role,true); - - if(!update_db_user(db)){ - printf("Failed to update user\n"); - exit(1);//exit program to prevent errors - }else{ - printf("User updated\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - - return db; -} -struct user delete_user(struct user db,int index){ - db.row[index].isdeleted = true; - if(!update_db_user(db)){ - printf("Failed to delete user\n"); - exit(1);//exit program to prevent errors - }else{ - printf("User deleted\n"); - } - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - - return read_db_user(); -} -struct Map* sortUser(struct user db,int choice); - -void print_user(void * ddb, int cur, int end,struct Map* map){ - struct user db = *((struct user*)ddb); - printf("%-5s%-20s%-10s%-10s%-10s\n","No.","Username","ID","Role","IsAdmin"); - for(int i = cur; i < end; i++){ - if(map == NULL){ - bool isadmin = is_admin(db.row[i].role); - // printf("isadmin%s\n",db.row[i].id); - 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{ - int index = map[i].key; - bool isadmin = is_admin(db.row[index].role); - printf("%-5d%-20s%-10ld%-10s%-10c\n",i+7,db.row[index].name,db.row[index].id,db.row[index].role,isadmin?'Y':'N'); - } - } -} - -struct Map* sortUser(struct user db,int choice){ - 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(choice){ - case 1: - case 2:; - char* temp = malloc(sizeof(char) * 100); - strcpy(temp,db.row[i].name); - map[i].value = (void*)temp; - break; - - case 3: - case 4:; - char* temp2 = malloc(sizeof(char) * 100); - strcpy(temp2,db.row[i].role); - map[i].value = (void*)temp2; - break; - case 5: - case 6:; - long* tempstar3 = malloc(sizeof(long)); - *tempstar3 = db.row[i].id; - map[i].value = (void*)tempstar3; - break; - - } - } - switch (choice){ - case 1: - case 3: - qsort(map, db.db.row_count, sizeof(struct Map), compare_decending_str); - break; - case 2: - case 4: - qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending_str); - break; - case 5: - qsort(map, db.db.row_count, sizeof(struct Map), compare_decending); - break; - case 6: - qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending); - break; - - } - return map; -} - -struct Map* SortUser(void * ddb,int choice){ - struct user db = *((struct user*)ddb); - 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(choice){ - case 1: - case 2:; - char* temp = malloc(sizeof(char) * 100); - strcpy(temp,db.row[i].name); - map[i].value = (void*)temp; - break; - - case 3: - case 4:; - char* temp2 = malloc(sizeof(char) * 100); - strcpy(temp2,db.row[i].role); - map[i].value = (void*)temp2; - break; - case 5: - case 6:; - long* tempstar3 = malloc(sizeof(long)); - *tempstar3 = db.row[i].id; - map[i].value = (void*)tempstar3; - break; - - } - } - switch (choice){ - case 1: - case 3: - qsort(map, db.db.row_count, sizeof(struct Map), compare_decending_str); - break; - case 2: - case 4: - qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending_str); - break; - case 5: - qsort(map, db.db.row_count, sizeof(struct Map), compare_decending); - break; - case 6: - qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending); - break; - - } - return map; -} - - -void * showUser(void * ddb,int index){ - struct user db = *((struct user*)ddb); - int choice = -1; - do{ - Cls(); - welcome_message(); - printf("User detail\n"); - 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"); - printf("Enter choice: "); - fflush_stdin(); - scanf("%d", &choice); - switch (choice){ - case 0: - break; - case 1: - db = edit_user(db,index); - break; - case 2: - db = delete_user(db,index); - break; - default: - printf("Invalid choice\n"); - printf("press any key to continue\n"); - fflush_stdin(); - getchar(); - break; - } - }while(choice != 0&&choice!=2); - void * re = malloc(sizeof(db)); - memcpy(re,&db,sizeof(db)); - return re; -} - -//role control -void add_role(); -void list_role(); - -void role_control(){ - int choice = -1; - struct user db = read_db_user(); - do{ - char * items[] = { - "add admin role", - "list role" - }; - choice = choices_selecter(items,2,"><\nRole control"); - switch (choice){ - case 0: - break; - case 1: - add_role(); - break; - case 2: - list_role(db); - break; - default: - 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{ - 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)); - struct linkedlist* cur = 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(cur->data); - bool* tempstar = malloc(sizeof(bool)); - *tempstar = temp; - map[i].value = tempstar; - break; - case 3: - case 4: - map[i].key = i; - map[i].value = cur->data; - break; - } - cur = cur->next; - } - switch(choice){ - case 1: - case 3: - qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_decending_str); - break; - case 2: - case 4: - qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_ascending_str); - break; - } - return map; -} diff --git a/inv_control.h b/inv_control.h new file mode 100644 index 0000000..cb4ee30 --- /dev/null +++ b/inv_control.h @@ -0,0 +1,254 @@ +//invetory control +void add_item(); +void remove_item(struct inventory db,int index); +void update_item(struct inventory db,int index); +void * item_control(void * ddb,int index); +char * show_item_admin(struct inventory db,int index); +void * show_item(void * ddb,int index); +void print_page(void * ddb, int cur, int end,struct Map* map); +struct Map* sortItems(void * ddb, int sort); + +void inv_control(){ + int choice = 0; + do{ + char * items[] = { + "List(allow all operation include add)", + "Add item(shortcut to add item)" + }; + choice = choices_selecter(items,2,NULL); + switch (choice){ + case 1:;//list + //add a new element with product name new item + //for item control + struct inventory db = read_db_invt(); + db.row = (struct inventory_row *)realloc(db.row, sizeof(struct inventory_row) * (db.db.row_count + 1)); + db.db.row_count += 1; + strcpy(db.row[db.db.row_count - 1].product,"CREATE NEW ITEM"); + db.row[db.db.row_count - 1].barcode = -1024;//IMPORTANT: -1024 is reserved for new item + char * SortItems[] = { + "Name", + "Price", + "Brand", + "Category", + }; + lister(&db,NULL,db.db.row_count,"Inventory",SortItems,4,print_page,sortItems,item_control); + break; + case 2://add item + add_item(); + break; + case 3://exit + break; + default://should not happen + printf("Invalid choice\n"); + break; + } + }while(choice != 3); +} + +char * show_item_admin(struct inventory db,int index){ + char * output = (char*)malloc(sizeof(char) * 2048); + sprintf(output,"Product: %s\n", db.row[index].product); + sprintf(output+strlen(output),"Catergory: %s\n", db.row[index].category);// strlen to add offset + sprintf(output+strlen(output),"Brand: %s\n", db.row[index].brand); + sprintf(output+strlen(output),"Price: $%lf\n", db.row[index].price); + sprintf(output+strlen(output),"Stock: %d\n", db.row[index].stock); + sprintf(output+strlen(output),"Barcode: %ld\n",db.row[index].barcode); + return output; +} +//for normal user +void * show_item(void * ddb,int index){ + struct inventory db = *((struct inventory*)ddb); + Cls(); + printf("Product: %s\n", db.row[index].product); + printf("Catergory: %s\n", db.row[index].category); + printf("Brand: %s\n", db.row[index].brand); + printf("Price: $%lf\n", db.row[index].price); + printf("Stock: %d\n", db.row[index].stock); + printf("Barcode: %ld\n",db.row[index].barcode); + printf("Press any key to return to the list\n"); + fflush_stdin(); + getchar(); + return ddb; +} + +void print_page(void * ddb, int cur, int end,struct Map* map){ + struct inventory db = *((struct inventory*)ddb); + for (int i = cur; i < end; i++) + { + if(map != NULL){ + printf("%d item %d: %s\n", i + 9,i, db.row[map[i].key].product); + } + else{ + printf("%d item %d: %s\n", i + 9,i, db.row[i].product); + } + } +} + +void * item_control(void * ddb,int index){ + struct inventory db = *((struct inventory*)ddb); + int choice = 0; + if(db.row[index].barcode == -1024){//new item + add_item(); + struct inventory temp = read_db_invt();//reappend new item at back + temp.row = (struct inventory_row *)realloc(temp.row, sizeof(struct inventory_row) * (temp.db.row_count + 1)); + temp.db.row_count += 1; + strcpy(temp.row[temp.db.row_count - 1].product,"CREATE NEW ITEM"); + temp.row[temp.db.row_count - 1].barcode = -1024;//IMPORTANT: -1024 is reserved for new item + void * re = malloc(sizeof(temp)); + memcpy(re,&temp,sizeof(temp)); + return re; + } + char * item = show_item_admin(db,index); + char welcome[4096]; + strcpy(welcome,item); + strcat(welcome,"Operations\n"); + do + { + char * items[] = { + "update item", + "remove item" + }; + choice = choices_selecter(items,2,welcome); + switch (choice) + { + case 1: + update_item(db,index); + break; + case 2: + remove_item(db,index); + break; + default: + break; + } + } while (choice != 3&&choice != 2); + struct inventory temp = read_db_invt(); + temp.row = (struct inventory_row *)realloc(temp.row, sizeof(struct inventory_row) * (temp.db.row_count + 1)); + temp.db.row_count += 1; + strcpy(temp.row[temp.db.row_count - 1].product,"CREATE NEW ITEM"); + temp.row[temp.db.row_count - 1].barcode = -1024;//IMPORTANT: -1024 is reserved for new item + void * re = malloc(sizeof(temp)); + memcpy(re,&temp,sizeof(temp)); + return re; +} + +void add_item(){ + Cls(); + printf("Add new item\n"); + struct inventory_row *item = (struct inventory_row *)malloc(sizeof(struct inventory_row)); + if(!item_inputer("name",STRING,&item->product,false) || + !item_inputer("brand",STRING,&item->brand,false) || + !item_inputer("category",STRING,&item->category,false) || + !item_inputer("price",DOUBLE,&item->price,false) || + !item_inputer("stock",INT,&item->stock,false) || + !item_inputer("barcode",LONG,&item->barcode,false) + ){ + free(item); + return; + } + if(item == NULL || !append_inventory(item)){ + printf("Failed to add item\n"); + }else{ + printf("Item added\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); +} + +void update_item(struct inventory db,int index){ + char temp[100]; + printf("Update item(empty value to not change the value)\n"); + printf("Name: %s\n", db.row[index].product); + printf("Brand: %s\n", db.row[index].brand); + printf("Catergory: %s\n", db.row[index].category); + printf("Price: $%lf\n", db.row[index].price); + printf("Stock: %d\n", db.row[index].stock); + printf("Barcode: %ld\n",db.row[index].barcode); + item_inputer("name",STRING,&db.row[index].product,true); + item_inputer("brand",STRING,&db.row[index].brand,true); + item_inputer("category",STRING,&db.row[index].category,true); + item_inputer("stock",DOUBLE,&db.row[index].price,true); + item_inputer("barcode",LONG,&db.row[index].barcode,true); + if(!update_db_invt(db)){ + printf("Failed to update item\n"); + exit(1); + }else{ + printf("Item updated\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); +} + +void remove_item(struct inventory db,int index){ + printf("Remove item\n"); + printf("Are you sure you want to remove this item? (y/n)\n"); + char choice; + fflush_stdin(); + scanf("%c", &choice); + db.row[index].isdeleted = true; + if(choice == 'y'){ + if(!update_db_invt(db)){ + printf("Failed to remove item\n"); + }else{ + printf("Item removed\n"); + } + }else{ + printf("Item not removed\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); +} + +struct Map* sortItems(void * ddb, int sort){ + struct inventory db = *((struct inventory*)ddb); + 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; + + switch(sort){ + case 1: + case 2: + map[i].value = (void*)db.row[i].product; + break; + + case 3: + case 4:; + double price = db.row[i].price * 100; + double * price_star = malloc(sizeof(long)); + *price_star = price; + map[i].value = (void*)price_star;//presume there is no price contain 0.001 + break; + case 5: + case 6: + map[i].value = (void*)db.row[i].brand; + break; + case 7: + case 8: + map[i].value = (void*)db.row[i].category; + break; + } + } + switch (sort){ + case 1: + case 5: + case 7: + qsort(map, db.db.row_count-1, sizeof(struct Map), compare_decending_str); + break; + case 2: + case 6: + case 8: + qsort(map, db.db.row_count-1, sizeof(struct Map), compare_ascending_str); + break; + case 3: + qsort(map, db.db.row_count-1, sizeof(struct Map), compare_decending); + break; + case 4: + 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; +} \ No newline at end of file diff --git a/main.c b/main.c index 7bd1131..c58526b 100644 --- a/main.c +++ b/main.c @@ -15,8 +15,8 @@ #include "database.h" #endif // !CUSTOM_H -#include "normal_user.h" #include "admin_user.h" +#include "normal_user.h" #ifndef Utils #define Utils #include "utils.h" diff --git a/normal_user.h b/normal_user.h index 501b6cc..d94e319 100644 --- a/normal_user.h +++ b/normal_user.h @@ -16,7 +16,6 @@ #define SORT_H #include "sorting.h" #endif // !SORT_H -#define PAGE_SIZE 20 #ifndef Utils #define Utils #include "utils.h" @@ -55,36 +54,7 @@ void normal_menu(){ }while(choice != 4); } -//universal functions for normal user -void * show_item(void * ddb,int index){ - struct inventory db = *((struct inventory*)ddb); - Cls(); - printf("Product: %s\n", db.row[index].product); - printf("Catergory: %s\n", db.row[index].category); - printf("Brand: %s\n", db.row[index].brand); - printf("Price: $%lf\n", db.row[index].price); - printf("Stock: %d\n", db.row[index].stock); - printf("Barcode: %ld\n",db.row[index].barcode); - printf("Press any key to return to the list\n"); - fflush_stdin(); - getchar(); - return ddb; -} -void print_page(void * ddb, int cur, int end,struct Map* map){ - struct inventory db = *((struct inventory*)ddb); - for (int i = cur; i < end; i++) - { - if(map != NULL){ - printf("%d item %d: %s\n", i + 9,i, db.row[map[i].key].product); - } - else{ - printf("%d item %d: %s\n", i + 9,i, db.row[i].product); - } - } -} //list items - - void list_items(){ Cls(); welcome_message(); @@ -104,61 +74,6 @@ void list_items(){ lister(&db,map,db.db.row_count,"List of items",SortItems,4,print_page,sortItems,show_item); } -//for sorting - -struct Map* sortItems(void * ddb, int sort){ - struct inventory db = *((struct inventory*)ddb); - 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; - - switch(sort){ - case 1: - case 2: - map[i].value = (void*)db.row[i].product; - break; - - case 3: - case 4:; - double price = db.row[i].price * 100; - double * price_star = malloc(sizeof(long)); - *price_star = price; - map[i].value = (void*)price_star;//presume there is no price contain 0.001 - break; - case 5: - case 6: - map[i].value = (void*)db.row[i].brand; - break; - case 7: - case 8: - map[i].value = (void*)db.row[i].category; - break; - } - } - switch (sort){ - case 1: - case 5: - case 7: - qsort(map, db.db.row_count-1, sizeof(struct Map), compare_decending_str); - break; - case 2: - case 6: - case 8: - qsort(map, db.db.row_count-1, sizeof(struct Map), compare_ascending_str); - break; - case 3: - qsort(map, db.db.row_count-1, sizeof(struct Map), compare_decending); - break; - case 4: - 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; -} - - //search items char* prompt_search(); struct Map* searchItems(struct inventory db, char* searchstr); diff --git a/role_control.h b/role_control.h new file mode 100644 index 0000000..7fa9c0b --- /dev/null +++ b/role_control.h @@ -0,0 +1,223 @@ + +//role control +void add_role(); +void list_role(); +void print_role(struct linkedlist* list,int cur,int end,struct Map* map); +void showRole(struct linkedlist* list,int index); +struct Map* sortRole(struct linkedlist* list,int choice); + +void role_control(){ + int choice = -1; + struct user db = read_db_user(); + do{ + char * items[] = { + "add admin role", + "list role" + }; + choice = choices_selecter(items,2,"><\nRole control"); + switch (choice){ + case 0: + break; + case 1: + add_role(); + break; + case 2: + char * SortItems[] = { + "admin", + "role", + }; + void * list = getLinkedList(role_list_db(),0); + lister(list,NULL,sizeofLinkedlist(list),"Role",SortItems,2,print_role,sortRole,showRole); + list_role(); + break; + default: + 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 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{ + 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)); + struct linkedlist* cur = 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(cur->data); + bool* tempstar = malloc(sizeof(bool)); + *tempstar = temp; + map[i].value = tempstar; + break; + case 3: + case 4: + map[i].key = i; + map[i].value = cur->data; + break; + } + cur = cur->next; + } + switch(choice){ + case 1: + case 3: + qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_decending_str); + break; + case 2: + case 4: + qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_ascending_str); + break; + } + return map; +} diff --git a/tran_control.h b/tran_control.h new file mode 100644 index 0000000..f7ca6ae --- /dev/null +++ b/tran_control.h @@ -0,0 +1,255 @@ +//tran control +void add_tran(); +void print_tran(void * ddb, int cur, int end,struct Map* map); +void * showTran(void * ddb,int index); +struct Map* sortTrans(void * ddb,int choice); + +void tran_control(){ + struct transaction tran = read_db_tran(); + int choice; + do{ + char * items[] = { + "List transaction", + "new transaction" + }; + choice = choices_selecter(items,2,"><\nTransaction control"); + switch(choice){ + case 1: + char * SortItems[] = { + "Date&Time", + "product(barcode)", + "quantity", + "total", + }; + lister(&tran,NULL,tran.db.row_count,"Transaction",SortItems,4,print_tran,sortTrans,showTran); + break; + case 2: + add_tran(tran); + break; + default: + break; + } + }while(choice != 3); +} + +void print_tran(void * ddb, int cur, int end,struct Map* map){ + struct transaction db = *((struct transaction*)ddb); + printf("%-5s%-15s%-10s%-10s%-10s%-10s%-10s%-10s\n","No.","Date","Time","Barcode","ID","Price","Quantity","Total"); + for (int i = cur; i < end; i++) + { + if(map != NULL){ + int index = map[i].key; + double total = db.row[index].price * db.row[index].quantity; + //reconstuct date and time and print all transaction info out + char date[11]; + char time[9]; + sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year); + sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second); + printf("%-5d%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",i+9,date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity,total); + }else{ + double total = db.row[i].price * db.row[i].quantity; + //reconstuct date and time and print all transaction info out + char date[11]; + char time[9]; + sprintf(date,"%02d-%02d-%04d",db.row[i].date.day,db.row[i].date.month,db.row[i].date.year); + sprintf(time,"%02d:%02d:%02d",db.row[i].time.hour,db.row[i].time.minute,db.row[i].time.second); + printf("%-5d%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",i+9,date,time,db.row[i].barcode,db.row[i].id,db.row[i].price,db.row[i].quantity,total); + } + } +} +//show trans + +struct transaction update_tran(struct transaction db,int index); +struct transaction remove_tran(struct transaction db,int index); + +void * showTran(void * ddb,int index){ + struct transaction db = *((struct transaction*)ddb); + int choice; + do{ + printf("Transaction detail\n"); + double total = db.row[index].price * db.row[index].quantity; + //reconstuct date and time and print all transaction info out + char date[11]; + char time[9]; + sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year); + sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second); + printf("%-15s%-10s%-10s%-10s%-10s%-10s%-10s\n","Date","Time","Barcode","ID","Price","Quantity","Total"); + printf("%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity,total); + printf("1 edit transaction\n"); + printf("2 delete transaction\n"); + printf("3 exit\n"); + bool valid = true; + do{ + printf("Please input your choice: "); + fflush_stdin(); + scanf("%d",&choice); + switch(choice){ + case 1: + valid = true; + db = update_tran(db,index); + break; + case 2: + valid = true; + db = remove_tran(db,index); + break; + case 3: + valid = true; + break; + default: + printf("Invalid input, try again\n"); + valid = false; + break; + } + }while(!valid); + }while(choice != 3); + void * re = malloc(sizeof(db)); + memcpy(re,&db,sizeof(db)); + return re; +} + +//tran controls +void add_tran(){ + char* temp; + struct transaction_row* row = (struct transaction_row*)malloc(sizeof(struct transaction_row)); + char check; + printf("Use current date time? (y/n): "); + fflush_stdin(); + scanf("%c",&check); + if(check == 'y'){ + row->date = get_date(); + row->time = get_time(); + }else{ + if( !item_inputer("date:day",INT,&row->date.day,false) || + !item_inputer("date:month",INT,&row->date.month,false) || + !item_inputer("date:year",INT,&row->date.year,false) || + !item_inputer("time:hour",INT,&row->time.hour,false) || + !item_inputer("time:minute",INT,&row->time.minute,false) || + !item_inputer("time:second",INT,&row->time.second,false) + ){ + free(row); + return; + } + } + if ( + !item_inputer("price",DOUBLE,&row->price,false) || + !item_inputer("quantity",INT,&row->quantity,false) || + !item_inputer("ID",LONG,&row->id,false) || + !item_inputer("barcode",LONG,&row->barcode,false) + ){ + free(row); + return; + } + if(row == NULL || !append_transaction_db(row)){ + printf("Failed to add item\n"); + }else{ + printf("Item added\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + + +} + +struct transaction update_tran(struct transaction db,int index){ + char temp[100]; + printf("Update transaction(empty value to not change the value)\n"); + char date[11],time[9]; + sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year); + sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second); + printf("%-15s%-10s%-10s%-10s%-10s%-10s\n","Date","Time","Barcode","ID","Price","Quantity"); + printf("%-15s%-10s%-10d%-10d%-10.2lf%-10d\n",date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity); + + item_inputer("Date:day",INT,&db.row[index].date.day,true); + item_inputer("Date:month",INT,&db.row[index].date.month,true); + item_inputer("Date:year",INT,&db.row[index].date.year,true); + item_inputer("Time:hour",INT,&db.row[index].time.hour,true); + item_inputer("Time:minute",INT,&db.row[index].time.minute,true); + item_inputer("Time:second",INT,&db.row[index].time.second,true); + item_inputer("Price",DOUBLE,&db.row[index].price,true); + item_inputer("Quantity",INT,&db.row[index].quantity,true); + item_inputer("ID",LONG,&db.row[index].id,true); + item_inputer("Barcode",LONG,&db.row[index].barcode,true); + + if(!update_db_tran(db)){ + printf("Failed to update transaction\n"); + exit(1);//exit program to prevent errors + }else{ + printf("Transaction updated\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + + return db; +} + +struct transaction remove_tran(struct transaction db,int index){ + db.row[index].isdeleted = true; + if(!update_db_tran(db)){ + printf("Failed to delete transaction\n"); + exit(1);//exit program to prevent errors + }else{ + printf("Transaction deleted\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + + return read_db_tran(); +} + +//sort transaction + +struct Map* sortTrans(void * ddb,int choice){ + struct transaction db = *((struct transaction*)ddb); + struct Map *map = malloc(sizeof(struct Map) * db.db.row_count); + printf("l"); + for (int i = 0; i < db.db.row_count; i++){ + map[i].key = i; + switch(choice){ + case 1: + case 2:; + long long temp = (long long)db.row[i].time.second+ db.row[i].time.minute*60 + db.row[i].time.hour*3600 + db.row[i].date.day*86400 + db.row[i].date.month*2592000 + db.row[i].date.year*31104000; + long long* tempstar = malloc(sizeof(long long)); + *tempstar = temp; + map[i].value = (void*)tempstar; + break; + + case 3: + case 4:; + long* tempstar2 = malloc(sizeof(long)); + *tempstar2 = db.row[i].barcode; + map[i].value = (void*)tempstar2; + break; + case 5: + case 6:; + int* tempstar3 = malloc(sizeof(int)); + *tempstar3 = db.row[i].quantity; + map[i].value = (void*)tempstar3; + break; + case 7: + case 8:; + long temp4 = lround(db.row[i].price * db.row[i].quantity * 10000);//clear all decimal places + long* tempstar4 = malloc(sizeof(long)); + *tempstar4 = temp4; + map[i].value = (void*)tempstar4; + break; + } + } + switch (choice){ + 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; +} \ No newline at end of file diff --git a/user_control.h b/user_control.h new file mode 100644 index 0000000..c522ea9 --- /dev/null +++ b/user_control.h @@ -0,0 +1,254 @@ +//user control +struct user add_user(struct user db); +void * showUser(void * ddb,int index); +struct Map* SortUser(void * ddb,int choice); +void print_user(void * ddb, int cur, int end,struct Map* map); +void user_control(){ + struct user db = read_db_user(); + int choice = 0; + while(choice != 3){ + Cls(); + printf("User Control\n"); + printf("1. Add User(shortcut)\n"); + printf("2. List User\n"); + printf("3. Exit\n"); + printf("Please input your choice\n>"); + fflush_stdin(); + scanf("%d",&choice); + switch(choice){ + case 1: + db = add_user(db); + break; + case 2: + char * SortItems[] = { + "Name", + "ID", + "Role", + }; + lister(&db,NULL,db.db.row_count,"User",SortItems,3,print_user,SortUser,showUser); + db = read_db_user(); + break; + case 3: + break; + default: + printf("Invalid choice\n"); + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + break; + } + } +} + +void * showUser(void * ddb,int index){ + struct user db = *((struct user*)ddb); + int choice = -1; + do{ + Cls(); + welcome_message(); + printf("User detail\n"); + 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"); + printf("Enter choice: "); + fflush_stdin(); + scanf("%d", &choice); + switch (choice){ + case 0: + break; + case 1: + db = edit_user(db,index); + break; + case 2: + db = delete_user(db,index); + break; + default: + printf("Invalid choice\n"); + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + break; + } + }while(choice != 0&&choice!=2); + void * re = malloc(sizeof(db)); + memcpy(re,&db,sizeof(db)); + return re; +} + + +struct user add_user(struct user db){ + char* temp; + int index = db.db.row_count; + struct user_row *temprow = realloc(db.row, sizeof(struct user_row)); + if ( + !item_inputer("name",STRING,&temprow->name,false) || + !item_inputer("id",LONG,&temprow->id,false) || + !item_inputer("role",STRING,&temprow->role,false) + ){ + free(temprow); + return db; + } + + if(!append_user(temprow)){ + printf("Failed to add user\n"); + exit(1);//exit program to prevent errors + }else{ + printf("User added\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + + return read_db_user(); +} +struct user edit_user(struct user db,int index){ + char temp[100]; + printf("Update transaction(empty value to not change the value)\n"); + 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); + item_inputer("username",STRING,&db.row[index].name,true); + item_inputer("id",LONG,&db.row[index].id,true); + item_inputer("role",STRING,&db.row[index].role,true); + + if(!update_db_user(db)){ + printf("Failed to update user\n"); + exit(1);//exit program to prevent errors + }else{ + printf("User updated\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + + return db; +} +struct user delete_user(struct user db,int index){ + db.row[index].isdeleted = true; + if(!update_db_user(db)){ + printf("Failed to delete user\n"); + exit(1);//exit program to prevent errors + }else{ + printf("User deleted\n"); + } + printf("press any key to continue\n"); + fflush_stdin(); + getchar(); + + return read_db_user(); +} +struct Map* sortUser(struct user db,int choice); + +void print_user(void * ddb, int cur, int end,struct Map* map){ + struct user db = *((struct user*)ddb); + printf("%-5s%-20s%-10s%-10s%-10s\n","No.","Username","ID","Role","IsAdmin"); + for(int i = cur; i < end; i++){ + if(map == NULL){ + bool isadmin = is_admin(db.row[i].role); + // printf("isadmin%s\n",db.row[i].id); + 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{ + int index = map[i].key; + bool isadmin = is_admin(db.row[index].role); + printf("%-5d%-20s%-10ld%-10s%-10c\n",i+7,db.row[index].name,db.row[index].id,db.row[index].role,isadmin?'Y':'N'); + } + } +} + +struct Map* sortUser(struct user db,int choice){ + 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(choice){ + case 1: + case 2:; + char* temp = malloc(sizeof(char) * 100); + strcpy(temp,db.row[i].name); + map[i].value = (void*)temp; + break; + + case 3: + case 4:; + char* temp2 = malloc(sizeof(char) * 100); + strcpy(temp2,db.row[i].role); + map[i].value = (void*)temp2; + break; + case 5: + case 6:; + long* tempstar3 = malloc(sizeof(long)); + *tempstar3 = db.row[i].id; + map[i].value = (void*)tempstar3; + break; + + } + } + switch (choice){ + case 1: + case 3: + qsort(map, db.db.row_count, sizeof(struct Map), compare_decending_str); + break; + case 2: + case 4: + qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending_str); + break; + case 5: + qsort(map, db.db.row_count, sizeof(struct Map), compare_decending); + break; + case 6: + qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending); + break; + + } + return map; +} + +struct Map* SortUser(void * ddb,int choice){ + struct user db = *((struct user*)ddb); + 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(choice){ + case 1: + case 2:; + char* temp = malloc(sizeof(char) * 100); + strcpy(temp,db.row[i].name); + map[i].value = (void*)temp; + break; + + case 3: + case 4:; + char* temp2 = malloc(sizeof(char) * 100); + strcpy(temp2,db.row[i].role); + map[i].value = (void*)temp2; + break; + case 5: + case 6:; + long* tempstar3 = malloc(sizeof(long)); + *tempstar3 = db.row[i].id; + map[i].value = (void*)tempstar3; + break; + + } + } + switch (choice){ + case 1: + case 3: + qsort(map, db.db.row_count, sizeof(struct Map), compare_decending_str); + break; + case 2: + case 4: + qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending_str); + break; + case 5: + qsort(map, db.db.row_count, sizeof(struct Map), compare_decending); + break; + case 6: + qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending); + break; + + } + return map; +} + + diff --git a/utils.h b/utils.h index fbe99d3..fa8c073 100644 --- a/utils.h +++ b/utils.h @@ -11,8 +11,11 @@ #endif #ifdef _WIN32 #else +//for fflush_stdin #include #endif +#define PAGE_SIZE 20 + void Cls(){ #ifdef _WIN32 system("cls");