//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 Utils #define Utils #include "sorting.h" #include "utils.h" #endif // !Utils //fucntions for menu void search_item(void * (*showitem)(void *,int)); void self_help_sale_system(); void print_page(void * ddb, int cur, int end,struct Map* map); struct Map* sortItems(void * ddb, int sort); //main of normal user void normal_menu(){ int choice = 0; do{ char buf[1024]; welcome_message(buf); sprintf(buf+strlen(buf),"Normal User Menu\n"); choice = choices_selecter((char*[]){ "List items", "Search item", "Self help sale system" },3,buf); switch (choice) { case 1:;//List items struct inventory db = read_db_invt(); char * SortItems[] = { "Name", "Price", "Brand", "Category", }; lister(&db,NULL,db.db.row_count,"List of items",SortItems,4,print_page,sortItems,show_item); break; case 2://Search item search_item(show_item); break; case 3://self help sale system self_help_sale_system(); break; default://invalid input ,should not happen,as it is already catch in above function break; } }while(choice != 4); } //search items char* prompt_search(); struct Map* searchItems(struct inventory db, char* searchstr); void search_item(void * (*showitem)(void *,int)){ //search for item //prompt user to select an item //if user selects an item, display the item's details struct inventory db = read_db_invt(); struct Map* map = NULL; do{ //options int breakout = 0; breakout = choices_selecter((char*[]){"Search"},1,welcome_message(NULL)); if(breakout == 2){ break; } char* searchstr = prompt_search(); map = searchItems(db,searchstr); if(map[0].value > 0){ int temp_row = *((int*)map[0].value); char * SortItems[] = { "Name", "Price", "Brand", "Category", }; lister(&db,map+1,temp_row,"List of items",SortItems,4,print_page,sortItems,showitem);//ofset map, as it is use to store the size }else{//empty search printf("No result found\n"); printf("Press any key to continue\n"); fflush_stdin(); getchar(); } }while(true);//break on top } char* prompt_search(){ printf("Enter search string(largest length 100)\n(case insensitive)\nmatches multiple columns\n>"); char* searchstr = malloc(sizeof(char) * 100); fflush_stdin(); scanf("%s", searchstr); printf("searching...\n"); return searchstr; } struct Map* searchItems(struct inventory db, char* searchstr){ struct Map* map = malloc(sizeof(struct Map) * (db.db.row_count+1)); int k = 1; for (int i = 0; i < db.db.row_count; i++){ map[k].key = i; if(strcasestr(db.row[i].product,searchstr) != NULL|| strcasestr(db.row[i].brand,searchstr) != NULL|| strcasestr(db.row[i].category,searchstr) != NULL|| strcasestr(lto_string(db.row[i].barcode),searchstr) != NULL ){ map[k].value = (void*)db.row[i].product; k++; } } int* k_star = malloc(sizeof(int)); *k_star = --k;//decrement and assign to k star;don't use k-- as it will decrement after the assignment map[0].value = (void*)k_star; map[0].key = -1; return map; } //self help struct cart* scan_barcode(struct cart* cart,struct inventory db); struct cart* list_cart(struct cart* cart); void self_help_sale_system(){ //scan barcode struct inventory db = read_db_invt(); struct cart* cart = NULL; int choice = 0; do{ //options int breakout = 0; choice = choices_selecter((char*[]){ "scan barcode", "cart/checkout" },2,welcome_message(NULL)); switch (choice) { case 1: cart = scan_barcode(cart,db); break; case 2: cart = list_cart(cart); break; default: break; } }while(choice!=3); } //support for the linked list struct cart* Cartappend(struct cart* cart,struct inventory_row* row,int quantity){ if(cart == NULL){ cart = malloc(sizeof(struct cart)); cart->row = row; cart->quantity = quantity; cart->next = NULL; }else{ struct cart* temp = cart; while(temp->next != NULL){ temp = temp->next; } temp->next = malloc(sizeof(struct cart)); temp->next->row = row; temp->next->quantity = quantity; temp->next->next = NULL; } return cart; } struct cart* Cartremove(struct cart* cart,int index){ if (cart == NULL){ return cart; }else{ struct cart* temp = cart; if (index == 0){ cart = cart->next; free(temp); return cart; }else{ for (int i = 0; i < index-1; i++){ temp = temp->next; } struct cart* new = temp->next->next; free(temp->next); temp->next = new; return cart; } } } struct cart* Cartupdate(struct cart* cart,int index,int quantity){ if (cart == NULL){ return cart; }else{ struct cart* temp = cart; if (index == 0){ cart->quantity = quantity; return cart; }else{ for (int i = 0; i < index-1; i++){ temp = temp->next; } temp->next->quantity = quantity; return cart; } } } struct inventory_row* Cartget(struct cart* cart,int index){ if (cart == NULL){ return NULL; }else{ struct cart* temp = cart; if (index == 0){ return cart->row; }else{ for (int i = 0; i < index-1; i++){ temp = temp->next; } return temp->next->row; } } } int Cartqty(struct cart* cart,int index){ if (cart == NULL){ return 0; }else{ struct cart* temp = cart; if (index == 0){ return cart->quantity; }else{ for (int i = 0; i < index-1; i++){ temp = temp->next; } return temp->next->quantity; } } } //scan barcode struct inventory_row* find_barcode(struct inventory db,long barcode); long prompt_barcode(); struct cart* scan_barcode(struct cart* cart,struct inventory db){ long barcode = prompt_barcode(); printf("matching...\n"); struct inventory_row* row = find_barcode(db,barcode); if(row != NULL){ int quantity = 0; char choice = 'n'; do{ Cls(); printf("product: %s\n",row->product); printf("price: %.1f\n",row->price); printf("Enter quantity(0 to cancel)\n>");\ fflush_stdin(); scanf("%d", &quantity); fflush_stdin(); if(quantity == 0){ printf("cancelled\n"); printf("press any key to continue\n"); fflush_stdin(); getchar(); return cart; } printf("Are you sure you want to add this item to cart?(y/n)\n>"); fflush_stdin(); scanf("%c", &choice); if(row->stock - quantity < 0 && choice == 'y'){ printf("WARNING:not enough stock\n"); printf("Are you sure the quantity is correct?\n(y to ignore and continue/n)\n>"); fflush_stdin(); scanf("%c", &choice); } }while(choice != 'y'); if(quantity != 0){ cart = Cartappend(cart,row,quantity); printf("added to cart\n"); } }else{//empty search printf("Unable to match or invalid input\n"); } printf("press any key to continue\n"); fflush_stdin(); getchar(); return cart; } long prompt_barcode(){ printf("Please scan the qr code(or input the barcode) "); long barcode; fflush_stdin(); scanf("%ld", &barcode); return barcode; } struct inventory_row* find_barcode(struct inventory db,long barcode){ struct inventory_row row; for (int i = 0; i < db.db.row_count; i++){ if(db.row[i].barcode == barcode){ return &db.row[i]; } } return (struct inventory_row*)NULL; } //list cart struct cart* cart_control(struct cart* cart,int index); struct cart* checkout(struct cart* cart); struct cart* list_cart(struct cart* cart){ int choice = 0; do{ Cls(); welcome_message(stdout); double total_price = 0; int i=1; printf("0 exit\n"); if(cart == NULL){ printf("Cart is empty\n"); }else{ struct cart* temp = cart; while(temp != NULL){//show cart int qty = temp->quantity; double price = temp->row->price * qty; total_price += price; printf("%d product:%s\n",i,temp->row->product); printf(" price(per qty): %.1f\n",temp->row->price);//space to align printf(" price(total): %.1f\n",price); printf(" quantity: %d\n",qty); printf("<------------------------>\n"); temp = temp->next; i++; } printf("\n<------------------------>\n"); printf("Total price: $%.1f\n",total_price); printf("<------------------------>\n"); printf("\n%d CHECKOUT\n",i); printf("%d Clear Cart\n",i+1); } do{ printf("input the corresponding value for more action\n>"); fflush_stdin(); scanf("%d", &choice); if(choice >0 && choice < i){ cart = cart_control(cart,choice); }else if(choice == i && cart != NULL){ cart = checkout(cart); }else if(choice == i+1 && cart != NULL){ cart = NULL; printf("Cart cleared\n"); } }while(choice <0 || choice > i+1); }while(choice != 0); return cart; } struct cart* update_cart(struct cart* cart,int index); struct cart* cart_control(struct cart* cart,int index){ int choice = 0; struct inventory_row* row = Cartget(cart,index-1); int quantity = Cartqty(cart,index-1); do{ char welcome[256]; welcome_message(welcome); sprintf(welcome+strlen(welcome),"product: %s\n",row->product); sprintf(welcome+strlen(welcome),"price: %.1f\n",row->price); sprintf(welcome+strlen(welcome),"quantity: %d\n",quantity); choice = choices_selecter((char*[]){ "remove", "edit quantity" },2,welcome); if(choice == 1){ cart = Cartremove(cart,index-1); printf("Remove successful\n"); printf("press any key to continue\n"); fflush_stdin(); getchar(); }else if(choice == 2){ cart = update_cart(cart,index); printf("Update successful\n"); printf("press any key to continue"); fflush_stdin(); getchar(); } }while(choice != 1 || choice != 2 || choice !=3 ); return cart; } struct cart* update_cart(struct cart* cart,int index){ Cls(); welcome_message(stdout); char choice; do{ int quantity = 0; printf("enter the new quantity: "); fflush_stdin(); scanf("%d", &quantity); printf("Are you sure you want to update this item?(y/n/e to exit)"); fflush_stdin(); scanf("%c", &choice); if(choice == 'y'){ if(quantity != 0){ cart = Cartupdate(cart,index-1,quantity); }else if (quantity == 0){ cart = Cartremove(cart,index-1); } } }while(choice != 'y' && choice != 'e'); return cart; } //Checkout struct cart* checkout(struct cart* cart){ Cls(); welcome_message(stdout); 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 cart; } struct user_row* user = get_user(user_id); if(user == NULL){ printf("Fail to indentify your card or error occurs\n"); printf("press any key to continue\n"); fflush_stdin(); getchar(); return cart; }else{ printf("Welcome %s(%s)\n",user->name,user->role); printf("Are you sure you want to checkout?(y/n)\n>"); char choice; fflush_stdin(); scanf("%c", &choice); if(choice == 'y'){ if(update_stock_N_checkout(cart,user)){//catch err printf("Checkout successful\n"); printf("press any key to continue\n"); fflush_stdin(); getchar(); return NULL; }else{ printf("Checkout failed(files maybe corrputed)\n"); printf("press any key to continue\n"); fflush_stdin(); getchar(); return cart; } }else{ printf("cancelled\n"); printf("press any key to continue\n"); fflush_stdin(); getchar(); return cart; } } return cart; }