//include std lib if they havent been included #ifndef STD_LIB_H #define STD_LIB_H #include #include #include #include #include #include #include #endif #ifndef MENU_H #define MENU_H #include "menu.h" #endif //MENU_H //list of functions void inv_control(); void tran_control(); void user_control(); void admin_control(); struct user_row *prompt_user(); int admin_menu_user_choices(char* name,char* role); void admin_menu(){ system("cls"); welcome_message(); //the selection menu // if(login valid) struct user_row *user = prompt_user(); if(user == NULL){//invalid user return; } int choice = 0; do { choice = admin_menu_user_choices(user->name,user->role); switch (choice) { case 1://action with inventory inv_control(); break; case 2://action with transction tran_control(); break; case 3://action with user // user_control(); break; case 4://action with admin user register // admin_control(); break; case 5://Exit break; default://invalid input ,should not happen,as it is already catch in above function printf("Invalid choice\n"); break; } }while(choice != 5); return; } //func for main for admin struct user_row *prompt_user(){ long user_id = 0; printf("Please tap your card(student card, staff card,etc)(or input the id)(0 to cancel)\n>"); scanf("%ld", &user_id); if(user_id == 0){ printf("cancelled\n"); printf("press any key to continue\n"); fflush(stdin); getchar(); return NULL; } struct user_row *user = get_user(user_id); if(user == NULL){ printf("User not found\n"); printf("press any key to continue\n"); fflush(stdin); getchar(); return NULL; }else if(!is_admin(user->role)){ printf("You aren't an admin\n"); printf("press any key to continue\n"); fflush(stdin); getchar(); return NULL; }else{ printf("Welcome %s(%s)\n", user->name,user->role); printf("press any key to continue\n"); fflush(stdin); getchar(); } return user; } int admin_menu_user_choices(char* name,char* role){ int choice = 0; do{ system("cls"); printf("Welcome %s(%s)\n", name,role); printf("Please select an option:\n"); printf("1. Inventory control\n"); printf("2. Transaction control\n"); printf("3. User control\n"); printf("4. Admin user register\n"); printf("5. Exit and Logout\n"); printf(">"); scanf("%d", &choice); if(choice < 1 || choice > 5){ printf("Invalid choice...press any key to retry....\n"); fflush(stdin); getchar(); } }while(choice < 1 || choice > 5); return choice; } //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); struct inventory item_control(struct inventory db,int index); int prompt_inv_control(){ int choice = 0; do{ system("cls"); printf("Please select an option:\n"); printf("1. List(allow all operation include add)\n"); printf("2. Add item(shortcut to add item)\n"); printf("3. Exit\n"); printf(">"); scanf("%d", &choice); if(choice < 1 || choice > 3){ printf("Invalid choice...press any key to retry....\n"); fflush(stdin); getchar(); } }while(choice < 1 || choice > 3); return choice; } void inv_control(){ int choice = 0; do{ choice = prompt_inv_control(); 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 list_page(db,NULL,db.db.row_count,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); } void show_item_admin(struct inventory db,int index){ system("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); getchar(); return; } struct inventory item_control(struct inventory db,int index){ 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 return temp; } do { system("cls"); show_item_admin(db,index); printf("Operations\n"); printf("0 exit\n"); printf("1 update item\n"); printf("2 remove item\n"); printf("Enter your choice: "); fflush(stdin); scanf("%d", &choice); switch (choice) { case 1: update_item(db,index); break; case 2: remove_item(db,index); break; default: break; } } while (choice != 0); 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 return temp; } char* prompt_item(char* prompt){ char* item = malloc(sizeof(char) * 100); do{ printf("%s",prompt); fflush(stdin); scanf("%[^\n]",item); if(strcmp(item,"") == 0){ printf("Invalid input, try again?(y/n)\n"); char temp[100]; fflush(stdin); scanf("%[^\n]",temp); if(strcmp(temp,"n") == 0){ return NULL; } } }while(strcmp(item,"") == 0); return item; } void add_item(){ char* temp; system("cls"); printf("Add new item\n"); struct inventory_row *item = (struct inventory_row *)malloc(sizeof(struct inventory_row)); temp = prompt_item("Please input the name: \n>"); if(temp == NULL){ free(item); return; } strcpy(item->product,temp); temp = prompt_item("Please input the brand: \n>"); if(temp == NULL){ free(item); return; } strcpy(item->brand,temp); temp = prompt_item("Please input the category: \n>"); if(temp == NULL){ free(item); return; } strcpy(item->category,temp); temp = prompt_item("Please input the price: \n>"); if(temp == NULL){ free(item); return; } item->price = atof(temp); temp = prompt_item("Please input the stock: \n>"); if(temp == NULL){ free(item); return; } item->stock = atoi(temp); temp = prompt_item("Please input the barcode: \n>"); if(temp == NULL){ free(item); return; } item->barcode = atol(temp); 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("Please input the name(original:%s)\n>",db.row[index].product); fflush(stdin); scanf("%[^\n]", temp);//input until /n if(strcmp(temp,"") != 0){//check if temp is not empty strcpy(db.row[index].product,temp);//if yes, copy temp to product }//else preserve the original value printf("Please input the brand(orginal:%s)\n>",db.row[index].brand); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ strcpy(db.row[index].brand,temp); } printf("Please input the category(orginal:%s)\n>",db.row[index].category); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ strcpy(db.row[index].category,temp); } printf("Please input the price(orginal:$%.1lf)\n>",db.row[index].price); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].price = atof(temp); } printf("Please input the stock(orginal:%d)\n>",db.row[index].stock); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].stock = atoi(temp); } printf("Please input the barcode(original:%ld)\n>",db.row[index].barcode); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].barcode = atol(temp); } 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 list_tran(struct transaction db); void add_tran(); void tran_control(){ struct transaction tran = read_db_tran(); int choice; do{ system("cls"); welcome_message(); printf("Transaction control\n"); printf("1. List transaction\n"); printf("2. new transaction\n"); printf("3. Exit\n"); printf("Please input your choice: "); fflush(stdin); scanf("%d",&choice); switch(choice){ case 1: list_tran(tran); break; case 2: add_tran(tran); break; case 3: break; default: printf("Invalid input, try again\n"); printf("press any key to continue\n"); fflush(stdin); getchar(); break; } }while(choice != 5); } void print_tran(struct transaction db, int cur, int end,struct Map* map); struct transaction showTran(struct transaction db,int index); void list_tran(struct transaction db){ int choice = -1; int page = 0; int page_size = PAGE_SIZE; int total_pages = ceil((double)db.db.row_count / page_size); int row = db.db.row_count; struct Map* map = NULL; do{ system("cls"); welcome_message(); printf("Transaction list\n"); printf("0 exit\n"); printf("1 sort Date&Time decending\n"); printf("2 sort Date&Time ascending\n"); printf("3 sort price decending\n"); printf("4 sort price ascending\n"); printf("5 sort quantity decending\n"); printf("6 sort quantity ascending\n"); printf("7 sort total decending\n"); printf("8 sort total ascending\n"); printf("No. Date Time Price Quantity Total\n"); if(page+1 == total_pages){ print_tran(db,page*page_size,row,map); }else{ print_tran(db,page*page_size,(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); bool valid = true; do{ valid = true; printf("Please input your choice: "); fflush(stdin); scanf("%d",&choice); if(choice <=8 && choice > 0){ printf("sorting...\n"); map = sortTrans(db,choice); }else if(choice == page_size+3 && page + 1 < total_pages){ page++; }else if(choice == page_size+4 && page > 0){ page--; }else if(choice == page_size+5){ printf("Enter page size: "); fflush(stdin); scanf("%d", &page_size); total_pages = ceil(row / page_size); }else if(choice >= 9 && choice < row+9){ if(map == NULL){ db = showTran(db,choice - 9 + page_size*page); }else{ db = showTran(db,map[choice - 9 + page_size*page].key); } }else if(choice != 0){ printf("Invalid choice\n"); valid = false; } }while(!valid); }while(choice != 0); return; } void print_tran(struct transaction db, int cur, int end,struct Map* map){ for (int i = cur; i < end; i++) { if(map != NULL){ double total = db.row[map[i].key].price * db.row[map[i].key].quantity; printf("%-4d%-12s%-12s$%-12.1lf%-12d$%-12.1lf\n",i+1,db.row[map[i].key].date,db.row[map[i].key].time,db.row[map[i].key].price,db.row[map[i].key].quantity,total); }else{ double total = db.row[i].price * db.row[i].quantity; printf("%-4d%-12s%-12s$%-12.1lf%-12d$%-12.1lf\n",i+1,db.row[i].date,db.row[i].time,db.row[i].price,db.row[i].quantity,total); } } } struct transaction update_tran(struct transaction db,int index); struct transaction remove_tran(struct transaction db,int index); struct transaction showTran(struct transaction db,int index){ printf("Transaction detail\n"); printf("Date:day %s\n",db.row[index].date.day); printf("Date:month %s\n",db.row[index].date.month); printf("Date:year %s\n",db.row[index].date.year); printf("Time:hour %s\n",db.row[index].time.hour); printf("Time:minute %s\n",db.row[index].time.minute); printf("Time:second %s\n",db.row[index].time.second); printf("Price: $%.1lf\n",db.row[index].price); printf("Quantity: %d\n",db.row[index].quantity); printf("ID: %d\n",db.row[index].id); printf("Barcode: %s\n",db.row[index].barcode); printf("Total: $%.1lf\n",db.row[index].price * db.row[index].quantity); printf("1 edit transaction\n"); printf("2 delete transaction\n"); printf("3 exit\n"); int choice; do{ printf("Please input your choice: "); fflush(stdin); scanf("%d",&choice); switch(choice){ case 1: db = update_tran(db,index); break; case 2: db = remove_tran(db,index); break; case 3: break; default: printf("Invalid input, try again\n"); break; } }while(choice != 3); } //tran controls void add_tran(){ char* temp; struct transaction_row* row = (struct transaction_row*)malloc(sizeof(struct transaction_row)); temp = prompt_item("Please input date:day \n>"); if(temp == NULL){ free(row); return; } strcpy(row->date.day,temp); temp = prompt_item("Please input date:month \n>"); if(temp == NULL){ free(row); return; } strcpy(row->date.month,temp); temp = prompt_item("Please input date:year \n>"); if(temp == NULL){ free(row); return; } strcpy(row->date.year,temp); temp = prompt_item("Please input time:hour \n>"); if(temp == NULL){ free(row); return; } strcpy(row->time.hour,temp); temp = prompt_item("Please input time:minute \n>"); if(temp == NULL){ free(row); return; } strcpy(row->time.minute,temp); temp = prompt_item("Please input price \n>"); if(temp == NULL){ free(row); return; } row->price = atof(temp); temp = prompt_item("Please input quantity \n>"); if(temp == NULL){ free(row); return; } row->quantity = atoi(temp); temp = prompt_item("Please input ID \n>"); if(temp == NULL){ free(row); return; } row->id = atol(temp); temp = prompt_item("Please input barcode \n>"); if(temp == NULL){ free(row); return; } row->barcode = atol(temp); if(row == NULL || !append_tran(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"); printf("Please input the Date:day(original:%s)\n>",db.row[index].date.day); fflush(stdin); scanf("%[^\n]", temp);//input until /n if(strcmp(temp,"") != 0){//check if temp is not empty db.row[index].date.day = atoi(temp); }//else preserve the original value printf("Please input the Date:month(original:%s)\n>",db.row[index].date.month); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].date.month = atoi(temp); } printf("Please input the Date:year(original:%s)\n>",db.row[index].date.year); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].date.year = atoi(temp); } printf("Please input the Time:hour(original:%s)\n>",db.row[index].time.hour); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].time.hour = atoi(temp); } printf("Please input the Time:minute(original:%s)\n>",db.row[index].time.minute); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].time.minute = atoi(temp); } printf("Please input the Time:second(original:%s)\n>",db.row[index].time.second); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].time.second = atoi(temp); } printf("Please input the Price(original:%.1lf)\n>",db.row[index].price); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].price = atof(temp); } printf("Please input the Quantity(original:%d)\n>",db.row[index].quantity); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].quantity = atoi(temp); } printf("Please input the ID(original:%d)\n>",db.row[index].id); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].id = atol(temp); } printf("Please input the Barcode(original:%d)\n>",db.row[index].barcode); fflush(stdin); scanf("%[^\n]", temp); if(strcmp(temp,"") != 0){ db.row[index].barcode = atol(temp); } 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 delete_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(); }