//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 search_item(void * (*showitem)(void *,int)); void inv_control(){ int choice = 0; do{ char buf[1024]; welcome_message(buf); sprintf(buf+strlen(buf),"Inventory control\n"); choice = choices_selecter((char*[]){ "List(allow all operation include add)", "Add item(shortcut to add item)", "Search item" },3,buf); 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: search_item(item_control); break; case 4://exit break; default://should not happen printf("Invalid choice\n"); break; } }while(choice != 4); } 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); printf("%-5s%-15s%-15s%-10s%-10s%-10s%-10s\n","No.","Product","Brand","Category","Price","Stock","Barcode"); for (int i = cur; i < end; i++) { if(map != NULL){ int index = map[i].key; printf("%-5d%-15s%-15s%-10s%-10.2lf%-10d%-10ld\n",i+9,StringCompression(db.row[index].product,13),StringCompression(db.row[index].brand,13),StringCompression(db.row[index].category,8),db.row[index].price,db.row[index].stock,db.row[index].barcode); } else{ printf("%-5d%-15s%-15s%-10s%-10.2lf%-10d%-10ld\n",i+9,StringCompression(db.row[i].product,13),StringCompression(db.row[i].brand,13),StringCompression(db.row[i].category,8),db.row[i].price,db.row[i].stock,db.row[i].barcode); } } } 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 { choice = choices_selecter((char*[]){ "update item", "remove item" },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; }