sba/admin_user.h
2022-11-03 18:23:44 +08:00

1297 lines
39 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 MENU_H
#define MENU_H
#include "menu.h"
#endif //MENU_H
//list of functions
//TODO: split all controller functions into their own files
//TODO: reformat all output to be formatted and unifed
//TODO: create a list base function to unified all variants of list functions
void inv_control();
void tran_control();
void user_control();
void role_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://role management
role_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. Role control\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&&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
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 != 3);
}
void print_tran(struct transaction db, int cur, int end,struct Map* map);
struct Map* sortTrans(struct transaction db,int choice);
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 product(barcode) decending\n");
printf("4 sort product(barcode) 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");
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
int current_page_size = page_size+8;
if(page+1 == total_pages){
current_page_size = row - page*page_size+8;
}
printf("%d next page\n", current_page_size+1);
printf("%d previous page\n", current_page_size+2);
printf("%d set page size\n", current_page_size+3);
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\n>");
fflush(stdin);
scanf("%d",&choice);
if(choice <=8 && choice > 0){
printf("sorting...\n");
map = sortTrans(db,choice);
}else if(choice == current_page_size+1 ){
if(page + 1 < total_pages){
page++;
}else{
printf("Already at last page\n");
valid = false;
}
}else if(choice == current_page_size+2){
if(page > 0){
page--;
}else{
printf("Already at first page\n");
valid = false;
}
}else if(choice == current_page_size+3){
printf("Enter page size: ");
fflush(stdin);
scanf("%d", &page_size);
total_pages = ceil(row / page_size);
}else if(choice >= 9 && choice <= current_page_size){
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){
printf("%-5s%-15s%-10s%-10s%-10s%-10s%-10s%-10s\n","No.","Date","Time","Barcode","ID","Price","Quantity","Total");
for (int i = cur; i < end; i++)
{
if(map != NULL){
double total = db.row[map[i].key].price * db.row[map[i].key].quantity;
//reconstuct date and time and print all transaction info out
char date[11];
char time[9];
sprintf(date,"%02d-%02d-%04d",db.row[map[i].key].date.day,db.row[map[i].key].date.month,db.row[map[i].key].date.year);
sprintf(time,"%02d:%02d:%02d",db.row[map[i].key].time.hour,db.row[map[i].key].time.minute,db.row[map[i].key].time.second);
printf("%-5d%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",i+9,date,time,db.row[map[i].key].barcode,db.row[map[i].key].id,db.row[map[i].key].price,db.row[map[i].key].quantity,total);
}else{
double total = db.row[i].price * db.row[i].quantity;
//reconstuct date and time and print all transaction info out
char date[11];
char time[9];
sprintf(date,"%02d-%02d-%04d",db.row[i].date.day,db.row[i].date.month,db.row[i].date.year);
sprintf(time,"%02d:%02d:%02d",db.row[i].time.hour,db.row[i].time.minute,db.row[i].time.second);
printf("%-5d%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",i+9,date,time,db.row[i].barcode,db.row[i].id,db.row[i].price,db.row[i].quantity,total);
}
}
}
//show trans
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){
int choice;
do{
printf("Transaction detail\n");
double total = db.row[index].price * db.row[index].quantity;
//reconstuct date and time and print all transaction info out
char date[11];
char time[9];
sprintf(date,"%02d-%02d-%04d",db.row[index].date.day,db.row[index].date.month,db.row[index].date.year);
sprintf(time,"%02d:%02d:%02d",db.row[index].time.hour,db.row[index].time.minute,db.row[index].time.second);
printf("%-15s%-10s%-10s%-10s%-10s%-10s%-10s\n","Date","Time","Barcode","ID","Price","Quantity","Total");
printf("%-15s%-10s%-10d%-10d%-10.2lf%-10d%-10.2lf\n",date,time,db.row[index].barcode,db.row[index].id,db.row[index].price,db.row[index].quantity,total);
printf("1 edit transaction\n");
printf("2 delete transaction\n");
printf("3 exit\n");
bool valid = true;
do{
printf("Please input your choice: ");
fflush(stdin);
scanf("%d",&choice);
switch(choice){
case 1:
valid = true;
db = update_tran(db,index);
break;
case 2:
valid = true;
db = remove_tran(db,index);
break;
case 3:
valid = true;
break;
default:
printf("Invalid input, try again\n");
valid = false;
break;
}
}while(!valid);
}while(choice != 3);
return db;
}
//tran controls
void add_tran(){
char* temp;
struct transaction_row* row = (struct transaction_row*)malloc(sizeof(struct transaction_row));
char check;
printf("Use current date time? (y/n): ");
fflush(stdin);
scanf("%c",&check);
if(check == 'y'){
row->date = get_date();
row->time = get_time();
}else{
temp = prompt_item("Please input date:day \n>");
if(temp == NULL){
free(row);
return;
}
row->date.day = atoi(temp);
temp = prompt_item("Please input date:month \n>");
if(temp == NULL){
free(row);
return;
}
row->date.month = atoi(temp);
temp = prompt_item("Please input date:year \n>");
if(temp == NULL){
free(row);
return;
}
row->date.year = atoi(temp);
temp = prompt_item("Please input time:hour \n>");
if(temp == NULL){
free(row);
return;
}
row->time.hour = atoi(temp);
temp = prompt_item("Please input time:minute \n>");
if(temp == NULL){
free(row);
return;
}
row->time.minute = atoi(temp);
temp = prompt_item("Please input time:second \n>");
if(temp == NULL){
free(row);
return;
}
}
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_transaction_db(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:%d)\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:%d)\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:%d)\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:%d)\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:%d)\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:%d)\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 remove_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();
}
//sort transaction
struct Map* sortTrans(struct transaction db,int choice){
struct Map *map = malloc(sizeof(struct Map) * db.db.row_count);
for (int i = 0; i < db.db.row_count; i++){
switch(choice){
case 1:
case 2:
long long temp = (long long)db.row[i].time.second+ db.row[i].time.minute*60 + db.row[i].time.hour*3600 + db.row[i].date.day*86400 + db.row[i].date.month*2592000 + db.row[i].date.year*31104000;
long long* tempstar = malloc(sizeof(long long));
*tempstar = temp;
map[i].value = (void*)tempstar;
break;
case 3:
case 4:
long* tempstar2 = malloc(sizeof(long));
*tempstar2 = db.row[i].barcode;
map[i].value = (void*)tempstar2;
break;
case 5:
case 6:
int* tempstar3 = malloc(sizeof(int));
*tempstar3 = db.row[i].quantity;
map[i].value = (void*)tempstar3;
break;
case 7:
case 8:
long temp4 = lround(db.row[i].price * db.row[i].quantity * 10000);//clear all decimal places
long* tempstar4 = malloc(sizeof(long));
*tempstar4 = temp4;
map[i].value = (void*)tempstar4;
break;
}
}
switch (choice){
case 1:
case 3:
case 5:
case 7:
qsort(map, db.db.row_count, sizeof(struct Map), compare_decending);
break;
case 2:
case 4:
case 6:
case 8:
qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending);
break;
}
return map;
}
//user control
struct user add_user(struct user db);
struct user list_user(struct user db);
void user_control(){
struct user db = read_db_user();
int choice = 0;
while(choice != 3){
system("cls");
printf("User Control\n");
printf("1. Add User(shortcut)\n");
printf("2. List User\n");
printf("3. Exit\n");
printf("Please input your choice\n>");
fflush(stdin);
scanf("%d",&choice);
switch(choice){
case 1:
db = add_user(db);
break;
case 2:
db = list_user(db);
break;
case 3:
break;
default:
printf("Invalid choice\n");
printf("press any key to continue\n");
fflush(stdin);
getchar();
break;
}
}
}
struct user add_user(struct user db){
char* temp;
int index = db.db.row_count;
struct user_row *temprow = realloc(db.row, sizeof(struct user_row));
temp = prompt_item("Please input the username\n>");
strcpy(temprow->name,temp);
temp = prompt_item("Please input the id\n>");
temprow->id = atol(temp);
temp = prompt_item("Please input the role\n>");
strcpy(temprow->role,temp);
if(!append_user(temprow)){
printf("Failed to add user\n");
exit(1);//exit program to prevent errors
}else{
printf("User added\n");
}
printf("press any key to continue\n");
fflush(stdin);
getchar();
return read_db_user();
}
struct user edit_user(struct user db,int index){
char temp[100];
printf("Please input the username(original:%s)\n>",db.row[index].name);
fflush(stdin);
scanf("%[^\n]", temp);
if(strcmp(temp,"") != 0){
strcpy(db.row[index].name,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 role(original:%s)\n>",db.row[index].role);
fflush(stdin);
scanf("%[^\n]", temp);
if(strcmp(temp,"") != 0){
strcpy(db.row[index].role,temp);
}
if(!update_db_user(db)){
printf("Failed to update user\n");
exit(1);//exit program to prevent errors
}else{
printf("User updated\n");
}
printf("press any key to continue\n");
fflush(stdin);
getchar();
return db;
}
struct user delete_user(struct user db,int index){
db.row[index].isdeleted = true;
if(!update_db_user(db)){
printf("Failed to delete user\n");
exit(1);//exit program to prevent errors
}else{
printf("User deleted\n");
}
printf("press any key to continue\n");
fflush(stdin);
getchar();
return read_db_user();
}
void print_user(struct user db, int cur, int end,struct Map* map);
struct Map* sortUser(struct user db,int choice);
struct user showUser(struct user db,int index);
struct user list_user(struct user 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("User list\n");
printf("0 exit\n");
printf("1 sort User decending\n");
printf("2 sort User ascending\n");
printf("3 sort Role decending\n");
printf("4 sort Role ascending\n");
printf("5 sort ID decending\n");
printf("6 sort ID ascending\n");
if(page+1==total_pages){
print_user(db,page*page_size,db.db.row_count,map);
}else{
print_user(db,page*page_size,(page+1)*page_size,map);
}
//page control
int current_page_size = page_size+8;
if(page+1 == total_pages){
current_page_size = row - page*page_size+6;
}
printf("%d next page\n",current_page_size+1);
printf("%d previous page\n",current_page_size+2);
printf("%d set page size\n",current_page_size+3);
bool valid;
do{
valid = true;
printf("Please input your choice\n>");
fflush(stdin);
scanf("%d",&choice);
if(choice <=6 && choice > 0){
printf("sorting...\n");
map = sortUser(db,choice);
}else if(choice == current_page_size+1 ){
if(page + 1 < total_pages){
page++;
}else{
printf("Already at last page\n");
valid = false;
}
}else if(choice == current_page_size+2){
if(page > 0){
page--;
}else{
printf("Already at first page\n");
valid = false;
}
}else if(choice == current_page_size+3){
printf("Enter page size: ");
fflush(stdin);
scanf("%d", &page_size);
total_pages = ceil(row / page_size);
}else if(choice >= 7 && choice <= current_page_size){
if(map == NULL){
db = showUser(db,choice - 7 + page_size*page);
}else{
db = showUser(db,map[choice - 7 + page_size*page].key);
}
}else if(choice != 0){
printf("Invalid choice\n");
valid = false;
}
}while(!valid);
}while(choice != 0);
return db;
}
void print_user(struct user db, int cur, int end,struct Map* map){
printf("%-5s%-20s%-10s%-10s%-10s\n","No.","Username","ID","Role","IsAdmin");
for(int i = cur; i < end; i++){
if(map == NULL){
bool isadmin = is_admin(db.row[i].role);
printf("%-5d%-20s%-10ld%-10s%-10c\n",i+7,db.row[i].name,db.row[i].id,db.row[i].role,isadmin?'Y':'N');
}else{
int index = map[i].key;
bool isadmin = is_admin(db.row[index].role);
printf("%-5d%-20s%-10ld%-10s%-10c\n",i+7,db.row[index].name,db.row[index].id,db.row[index].role,isadmin?'Y':'N');
}
}
}
struct Map* sortUser(struct user db,int choice){
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;
switch(choice){
case 1:
case 2:
char* temp = malloc(sizeof(char) * 100);
strcpy(temp,db.row[i].name);
map[i].value = (void*)temp;
break;
case 3:
case 4:
char* temp2 = malloc(sizeof(char) * 100);
strcpy(temp2,db.row[i].role);
map[i].value = (void*)temp2;
break;
case 5:
case 6:
long* tempstar3 = malloc(sizeof(long));
*tempstar3 = db.row[i].id;
map[i].value = (void*)tempstar3;
break;
}
}
switch (choice){
case 1:
case 3:
qsort(map, db.db.row_count, sizeof(struct Map), compare_decending_str);
break;
case 2:
case 4:
qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending_str);
break;
case 5:
qsort(map, db.db.row_count, sizeof(struct Map), compare_decending);
break;
case 6:
qsort(map, db.db.row_count, sizeof(struct Map), compare_ascending);
break;
}
return map;
}
struct user showUser(struct user db,int index){
int choice = -1;
do{
system("cls");
welcome_message();
printf("User detail\n");
printf("%-20s%-10s%-10s\n","Username","ID","Role");
printf("%-20s%-10ld%-10s\n",db.row[index].name,db.row[index].id,db.row[index].role);
printf("0 exit\n");
printf("1 edit user\n");
printf("2 delete user\n");
printf("Enter choice: ");
fflush(stdin);
scanf("%d", &choice);
switch (choice){
case 0:
break;
case 1:
db = edit_user(db,index);
break;
case 2:
db = delete_user(db,index);
break;
default:
printf("Invalid choice\n");
printf("press any key to continue\n");
fflush(stdin);
getchar();
break;
}
}while(choice != 0);
return db;
}
//role control
void add_role();
void list_role();
void role_control(){
int choice = -1;
struct user db = read_db_user();
do{
system("cls");
welcome_message();
printf("Role control\n");
printf("0 exit\n");
printf("1 add admin role\n");
printf("2 list role\n");
printf("Enter choice: ");
fflush(stdin);
scanf("%d", &choice);
switch (choice){
case 0:
break;
case 1:
add_role();
break;
case 2:
list_role(db);
break;
default:
printf("Invalid choice\n");
printf("press any key to continue\n");
fflush(stdin);
getchar();
break;
}
}while(choice != 0);
}
void add_role(){
char role[100];
printf("Enter Admin role name: ");
fflush(stdin);
scanf("%s", role);
if(is_admin(role)){//check if role exist in admin file
printf("Admin role already exist\n");
printf("press any key to continue\n");
fflush(stdin);
getchar();
}else{
add_admin(role);
printf("role added\n");
printf("press any key to continue\n");
fflush(stdin);
getchar();
}
return;
}
void print_role(struct linkedlist* list,int cur,int end,struct Map* map);
struct Map* sortRole(struct linkedlist* list,int choice);
void showRole(struct linkedlist* list,int index);
void list_role(){
struct linkedlist* list = getLinkedList(role_list_db(),0);
int list_size = sizeofLinkedlist(list);
int choice = -1;
int page = 0;
int page_size = PAGE_SIZE;
int total_pages = ceil( (double)list_size / page_size);
struct Map* map = NULL;
//list role
do{
system("cls");
welcome_message();
printf("Role list\n");
printf("0 exit\n");
printf("1 sort admin ascending\n");
printf("2 sort admin descending\n");
printf("3 sort role ascending\n");
printf("4 sort role descending\n");
if(page+1 == total_pages){
print_role(list,page*page_size,list_size,map);
}else{
print_role(list,page*page_size,(page+1)*page_size,map);
}
//page control
int current_page_size = page_size+2;
if(page+1 == total_pages){
current_page_size = list_size - page*page_size + 4;
}
printf("%d next page\n",current_page_size+1);
printf("%d previous page\n",current_page_size+2);
printf("%d set page size\n",current_page_size+3);
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\n>");
fflush(stdin);
scanf("%d", &choice);
if(choice <=4 && choice > 0){
printf("sorting...\n");
map = sortRole(list,choice);
}else if(choice == current_page_size+1){
if(page + 1 < total_pages){
page++;
}else{
printf("Already at last page\n");
valid = false;
}
}else if(choice == current_page_size+2){
if(page > 0){
page--;
}else{
printf("Already at first page\n");
valid = false;
}
}else if(choice == current_page_size+3){
printf("Enter page size: ");
fflush(stdin);
scanf("%d", &page_size);
total_pages = ceil( (double)list_size / page_size);
page = 0;
}else if(choice >= 5 && choice <= current_page_size){
if(map == NULL){
showRole(list,choice - 5 + page_size*page);
}else{
showRole(list,map[choice - 5 + page_size*page].key);
}
}else if(choice != 0){
printf("Invalid choice\n");
valid = false;
}
}while(!valid);
}while(choice != 0);
}
void print_role(struct linkedlist* list,int cur,int end,struct Map* map){
printf("%-10s%-10s%-10s\n","No.","Role","Admin?");
if(map == NULL){
for(int i = cur; i < end; i++){
list = getLinkedList(list,i);
char* name = list->data;
printf("%-10d%-10s%-10s\n",i-cur + 5,name,is_admin(name)?"T":"F");
}
}else{
for(int i = cur; i < end; i++){
list = getLinkedList(list,map[i].key);
char* name = list->data;
printf("%-10d%-10s%-10s\n",i-cur + 5,name,is_admin(name)?"T":"F");
}
}
}
void showRole(struct linkedlist* list,int index){
int choice;
list = getLinkedList(list,index);
do{
char* name = list->data;
printf("%-10s%-10s\n","Role","Admin?");
printf("%-10s%-10s\n",name,is_admin(name)?"T":"F");
printf("1 toogle admin\n");
printf("2 exit\n");
bool valid = true;
do{
valid = true;
printf("Please input your choice\n>");
fflush(stdin);
scanf("%d", &choice);
if(choice == 1){
if(is_admin(name)){
remove_admin(name);
}else{
add_admin(name);
}
printf("Admin role toggled\n");
printf("Press any key to continue\n");
fflush(stdin);
getchar();
}else if(choice != 2){
printf("Invalid choice\n");
valid = false;
}
}while(!valid);
}while(choice != 2);
return;
}
struct Map* sortRole(struct linkedlist* list,int choice){
struct Map* map = malloc(sizeof(struct Map)*sizeofLinkedlist(list));
struct linkedlist* cur = getLinkedList(list,0);
for(int i = 0; i < sizeofLinkedlist(list); i++){
switch(choice){
case 1:
case 2:
map[i].key = i;
bool temp = !is_admin(cur->data);
bool* tempstar = malloc(sizeof(bool));
*tempstar = temp;
map[i].value = tempstar;
break;
case 3:
case 4:
map[i].key = i;
map[i].value = cur->data;
break;
}
cur = cur->next;
}
switch(choice){
case 1:
case 3:
qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_decending_str);
break;
case 2:
case 4:
qsort(map,sizeofLinkedlist(list),sizeof(struct Map),compare_ascending_str);
break;
}
return map;
}