diff --git a/admin_user.h b/admin_user.h index 8c45f21..43f0963 100644 --- a/admin_user.h +++ b/admin_user.h @@ -120,89 +120,80 @@ int admin_menu_user_choices(char* name,char* role){ //invetory control void add_item(); -void remove_item(); -void update_item(); -void view_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(struct inventory db,int index); -void inv_control(){ +int prompt_inv_control(){ + int choice = 0; + do{ system("cls"); - struct inventory db = read_db_invt(); - admin_list_pages(db,NULL,db.row); + 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 item_control(struct inventory db,int index); -void admin_list_pages(struct inventory db,struct Map* map,int row){//user for showing list result and search result - int choice = -1; - int page = 0; - int page_size = PAGE_SIZE; - int total_pages = ceil((double)row / page_size); - do{ - - //options - system("cls"); - printf("0 exit\n"); - printf("1 sort name decending\n"); - printf("2 sort name ascending\n"); - printf("3 sort price decending\n"); - printf("4 sort price ascending\n"); - printf("5 sort brand decending\n"); - printf("6 sort brand ascending\n"); - printf("7 sort category decending\n"); - printf("8 sort category ascending\n"); - printf("List of items:\n"); - - //print items - if(page + 1 >= total_pages){ - print_page(db, page * page_size, row,map); - }else{//sorted) - print_page(db, page * page_size, (page + 1) * page_size,map); - } - printf("%d new item",page_size+4); - //page control - printf("%d next page\n", page_size+5); - printf("%d previous page\n", page_size+6); - printf("%d set page size\n", page_size+7); - printf("%d/%d/%d(page size/page number/total)\n",page_size, page+1,total_pages); - - //prompt user to select an item - bool valid = true; - do{ - valid = true; - printf("Enter your choice: "); - fflush(stdin); - scanf("%d", &choice); - if(choice <=8 && choice > 0){ - printf("sorting...\n"); - map = sortItems(db,choice); - }else if(choice == page_size+3){ - add_item(); - }else if(choice == page_size+4 && page + 1 < total_pages){ - page++; - }else if(choice == page_size+5 && page > 0){ - page--; - }else if(choice == page_size+6){ - printf("Enter page size: "); - fflush(stdin); - scanf("%d", &page_size); - total_pages = ceil(row / page_size); - }else if(choice >= 9 && choice < row+9){ - item_control(db,choice - 9 + page_size*page); - }else if(choice != 0){ - printf("Invalid choice\n"); - valid = false; +void inv_control(){ + struct inventory db = read_db_invt(); + 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 + 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(!valid); + }while(choice != 3); +} - }while(choice != 0); +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; } void item_control(struct inventory db,int index){ int choice = 0; + if(db.row[index].barcode == -1024){//new item + add_item(); + return; + } do { system("cls"); - show_item(db,index); + show_item_admin(db,index); + printf("Operations\n"); printf("0 exit\n"); printf("1 update item\n"); printf("2 remove item\n"); @@ -223,26 +214,65 @@ void item_control(struct inventory db,int index){ } while (choice != 0); } +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"); + fflush(stdin); + char c = getchar(); + if(c == 'n'){ + return NULL; + } + } + }while(strcmp(item,"") == 0); + return item; +} + void add_item(){ + char* temp; system("cls"); printf("Add new item\n"); - printf("Please input the item name\n>"); - struct inventory_row *item; - fflush(stdin); - scanf("%[^\n]", item->product); - printf("Please input the item brand\n>"); - fflush(stdin); - scanf("%[^\n]", item->brand); - printf("Please input the item price\n>"); - scanf("%lf", &item->price); - printf("Please input the item stock\n>"); - scanf("%d", &item->stock); - printf("Please input the item category\n>"); - fflush(stdin); - scanf("%[^\n]", item->category); - printf("Please input the item barcode\n>"); - fflush(stdin); - scanf("%[^\n]", item->barcode); + 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{ @@ -254,24 +284,52 @@ void add_item(){ } void update_item(struct inventory db,int index){ - system("cls"); - printf("Update item\n"); - printf("Please input the item name\n>"); + 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]", db.row[index].product); - printf("Please input the item brand\n>"); + 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]", db.row[index].brand); - printf("Please input the item price\n>"); - scanf("%lf", &db.row[index].price); - printf("Please input the item stock\n>"); - scanf("%d", &db.row[index].stock); - printf("Please input the item category\n>"); + 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]", db.row[index].category); - printf("Please input the item barcode\n>"); + 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]", db.row[index].barcode); + 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"); }else{ @@ -283,7 +341,6 @@ void update_item(struct inventory db,int index){ } void remove_item(struct inventory db,int index){ - system("cls"); printf("Remove item\n"); printf("Are you sure you want to remove this item? (y/n)\n"); char choice; diff --git a/data_file_admin.txt b/data_file_admin.txt index 2f31a47..1b3a9ee 100644 --- a/data_file_admin.txt +++ b/data_file_admin.txt @@ -1,4 +1,4 @@ #name of role that are consider as admin -Teacher +teacher Staff Admin \ No newline at end of file diff --git a/database.h b/database.h index b2bb15b..f49d02f 100644 --- a/database.h +++ b/database.h @@ -15,7 +15,7 @@ #endif // !DNT_H typedef struct basic_db{ int row_count; - bool init_status; + bool init_status;//not really used can be useful //array of struct of row }basic_db; @@ -298,6 +298,8 @@ bool update_db_invt(struct inventory invt){ return false; } for(int i=0;icategory); + fprintf(fp,"%s\n",row->brand); + fprintf(fp,"%s\n",row->product); + fprintf(fp,"%.1f\n",row->price); + fprintf(fp,"%d\n",row->stock); + fprintf(fp,"%ld\n",row->barcode); fclose(fp); return true; } @@ -484,29 +469,12 @@ bool append_transaction_db(struct transaction_row* row){ printf("Error in opening file\n"); return false; } - for(TRANSACTION i=date;i<=ENDOFTRANSACTION;i++){ - switch(i){ - case date: - fprintf(fp,"%d-%02d-%02d",row.date.year,row.date.month,row.date.day); - break; - case TIME: - fprintf(fp,"%02d:%02d:%02d",row.time.hour,row.time.minute,row.time.second); - break; - case id_tran: - fprintf(fp,"%ld",row.id); - break; - case price_tran: - fprintf(fp,"%.1f",row.price); - break; - case quantity: - fprintf(fp,"%d",row.quantity); - break; - case barcode_tran: - fprintf(fp,"%ld",row.barcode); - break; - } - fprintf(fp,"\n"); - } + fprintf(fp,"%d-%02d-%02d\n",row->date.year,row->date.month,row->date.day); + fprintf(fp,"%02d:%02d:%02d\n",row->time.hour,row->time.minute,row->time.second); + fprintf(fp,"%ld\n",row->id); + fprintf(fp,"%.1f\n",row->price); + fprintf(fp,"%d\n",row->quantity); + fprintf(fp,"%ld\n",row->barcode); fclose(fp); return true; } @@ -517,20 +485,9 @@ bool append_user(struct user_row* row){ printf("Error in opening file\n"); return false; } - for(USER i=name;i<=ENDOFUSER;i++){ - switch(i){ - case name: - fprintf(fp,"%s",row.name); - break; - case role: - fprintf(fp,"%s",row.role); - break; - case id_user: - fprintf(fp,"%ld",row.id); - break; - } - fprintf(fp,"\n"); - } + fprintf(fp,"%s\n",row->name); + fprintf(fp,"%s\n",row->role); + fprintf(fp,"%ld\n",row->id); fclose(fp); return true; } diff --git a/normal_user.h b/normal_user.h index f9af3fc..b6b1035 100644 --- a/normal_user.h +++ b/normal_user.h @@ -85,7 +85,9 @@ int normal_menu_user_choices(){ scanf("%d", &choice); return choice; } -void list_page(struct inventory db,struct Map* map,int row){//user for showing list result and search result + +//user for showing list result and search result +void list_page(struct inventory db,struct Map* map,int row,void (*showitem)(struct inventory,int)){//showitem is a function pointer for showing item,allow customization for better flexibilty int choice = -1; int page = 0; int page_size = PAGE_SIZE; @@ -138,7 +140,7 @@ void list_page(struct inventory db,struct Map* map,int row){//user for showing l scanf("%d", &page_size); total_pages = ceil(row / page_size); }else if(choice >= 9 && choice < row+9){ - show_item(db,choice - 9 + page_size*page); + (*showitem)(db,choice - 9 + page_size*page); }else if(choice != 0){ printf("Invalid choice\n"); valid = false; @@ -172,7 +174,7 @@ void list_items(){ struct inventory db = read_db_invt(); struct Map* map = NULL; - list_page(db,map,db.db.row_count); + list_page(db,map,db.db.row_count,show_item); } //for sorting @@ -180,6 +182,9 @@ struct Map* sortItems(struct inventory db, int sort){ struct Map *map = malloc(sizeof(struct Map) * db.db.row_count); for (int i = 0; i < db.db.row_count; i++){ map[i].key = i; + if(db.row[i].barcode == -1024)//catch new item + map[i].value = NULL; + switch(sort){ case 1: case 2: @@ -259,7 +264,7 @@ void search_item(){ printf("searching...\n"); map = searchItems(db,searchstr); if(map[0].value > 0){ - list_page(db,map+1,(int)map[0].value);//ofset map, as it is use to store the size + list_page(db,map+1,(int)map[0].value,show_item);//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"); @@ -479,7 +484,7 @@ struct cart* scan_barcode(struct cart* cart,struct inventory db){ do{ system("cls"); printf("product: %s\n",row->product); - printf("price: %.2f\n",row->price); + printf("price: %.1f\n",row->price); printf("Enter quantity(0 to cancel)\n>");\ fflush(stdin); scanf("%d", &quantity); @@ -556,15 +561,15 @@ struct cart* list_cart(struct cart* cart){ double price = temp->row->price * qty; total_price += price; printf("%d product:%s\n",i,temp->row->product); - printf(" price(per qty): %.2f\n",temp->row->price);//space to align - printf(" price(total): %.2f\n",price); + 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: $%.2f\n",total_price); + printf("Total price: $%.1f\n",total_price); printf("<------------------------>\n"); printf("\n%d CHECKOUT\n",i); @@ -595,7 +600,7 @@ struct cart* cart_control(struct cart* cart,int index){ printf("1 remove\n"); printf("2 edit quantity\n"); printf("product: %s\n",row->product); - printf("price: %.2f\n",row->price); + printf("price: %.1f\n",row->price); printf("quantity: %d\n",quantity); bool check; do{ diff --git a/sorting.h b/sorting.h index 638b127..4467cc7 100644 --- a/sorting.h +++ b/sorting.h @@ -4,9 +4,21 @@ typedef struct Map{ }Map; int compare_decending(const void *a, const void *b){ + if((*(struct Map *)b).value == NULL){//for dont sort new item + return -1; + }else if((*(struct Map *)a).value == NULL){ + return 1; + + } return (*(struct Map *)b).value - (*(struct Map *)a).value; } int compare_ascending(const void *a, const void *b){ + if((*(struct Map *)b).value == NULL){ + return -1; + }else if((*(struct Map *)a).value == NULL){ + return 1; + + } return (*(struct Map *)a).value - (*(struct Map *)b).value; }