sba/normal_user.h
2023-11-07 01:07:45 +08:00

494 lines
14 KiB
C

//include std lib if they havent been included
#ifndef STD_LIB_H
#define STD_LIB_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#include<time.h>
#include<ctype.h>
#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;
}