list_item_first_bui;d test

This commit is contained in:
smarttommyau 2022-08-27 17:33:07 +08:00
parent acef6ad630
commit fcbd309c69
No known key found for this signature in database
GPG Key ID: D7832FC94BD13B6A
10 changed files with 568 additions and 51 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
main.exe

View File

@ -5,4 +5,18 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#endif
#include<math.h>
#endif
#ifndef MENU_H
#define MENU_H
#include "menu.h"
#endif //MENU_H
bool admin_menu(){
system("cls");
welcome_message();
return true;
}

View File

@ -1,4 +1,4 @@
#category, brand, product, price, cost, stock, barcode
#category, brand, product, price, stock, barcode
Test
Testing Co Ltd
Testing Product

View File

@ -5,18 +5,20 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif
#ifndef DNT_H
#define DNT_H
#include "dateNtime.h"
#endif // !DNT_H
typedef struct basic_db{
FILE *fp;
int row_count;
bool init_status;
//array of struct of row
};
//inventory
#define INVENTORY_DB "data_file_inventory.txt"
typedef struct inventory{
struct basic_db db;
struct inventory_row* row;
@ -27,15 +29,16 @@ typedef struct inventory_row{
char band[100];
char product[100];
double price;
double cost;
int stock;
long barcode;
bool isdeleted;//common for all rows,default is false
};
typedef enum INVENTORY {
category = 1, brand = 2, product = 3, price = 4, cost = 5, stock = 6 , barcode = 7
};
typedef enum {
category = 1, brand = 2, product = 3, price_inv = 4, stock = 5, barcode_inv = 6
}INVENTORY;
#define ENDOFINVENTORY 6
//transaction
#define TRANSACTION_DB "data_file_transaction.txt"
typedef struct transaction{
struct basic_db db;
struct transaction_row* row;
@ -48,12 +51,14 @@ typedef struct transaction_row{
double price;
int quantity;
long barcode;
bool isdeleted;//common for all rows,default is false
};
typedef enum TRANSACTION {
date = 1, time = 2, id = 3, price = 5, quantity = 4, barcode = 7
};
typedef enum {
date = 1, time = 2, id_tran = 3, price_tran = 5, quantity = 4, barcode_tran = 7
}TRANSACTION;
#define ENDOFTRANSACTION 7
//user
#define USER_DB "data_file_user.txt"
typedef struct user{
struct basic_db db;
struct user_row* row;
@ -63,50 +68,344 @@ typedef struct user_row{
char role[100];
long id;
bool isAdmin;
bool isdeleted;//common for all rows,default is false
};
typedef enum USER {
name = 1, role = 2,id = 3
};
typedef enum {
name = 1, role = 2, id_user = 3
}USER;
#define ENDOFUSER 3
//TODOLwrite function for these functions
//list of db func
bool read_db_invt(FILE* fp,enum INVENTORY inventory){
int basic_get_row_count(int end, FILE *fp){
fseek(fp, 0, SEEK_SET);//prevent pointer on wrong position
//get row count
int row_count = 0;
int colmun_count = 0;
while(!feof(fp)&&!ferror(fp)){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
continue;
}
colmun_count++;
if(colmun_count == end){
row_count++;
colmun_count = 0;
}
}
}
struct inventory read_db_invt(){//please open file in read mode
FILE* fp = fopen(INVENTORY_DB, "r");
struct inventory db;
//gets the number of rows in the file
int row_count = basic_get_row_count(ENDOFINVENTORY,fp);
db.row = (struct inventory_row*)malloc(row_count * sizeof(struct inventory_row));
db.db.row_count = row_count;
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
//read data
for(int i=0;i<row_count;i++){
db.row[i].isdeleted = false;
for(INVENTORY j=category;j<ENDOFINVENTORY;j++){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
j--;//decrement j to prevent skipping next column
}else{
switch(j){
case category:
strcpy(db.row[i].category,buffer);
break;
case brand:
strcpy(db.row[i].band,buffer);
break;
case product:
strcpy(db.row[i].product,buffer);
break;
case price_inv:
db.row[i].price = atof(buffer);
break;
case stock:
db.row[i].stock = atoi(buffer);
break;
case barcode_inv:
db.row[i].barcode = atol(buffer);
break;
}
}
}
}
if(ferror(fp)){
printf("Error in reading file\n");
db.db.init_status = false;
return db;
}
fclose(fp);
db.db.init_status = true;
return db;
}
struct transaction read_db_tran(){
FILE* fp = fopen(TRANSACTION_DB, "r");
struct transaction db;
//gets the number of rows in the file
int row_count = basic_get_row_count(ENDOFTRANSACTION,fp);
db.row = (struct transaction_row*)malloc(row_count * sizeof(struct transaction_row));
db.db.row_count = row_count;
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
//read data
for(int i=0;i<row_count;i++){
db.row[i].isdeleted = false;
for(TRANSACTION j=date;j<ENDOFTRANSACTION;j++){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
j--;//decrement j to prevent skipping next column
}else{
switch(j){
case date:
db.row[i].date = convert_to_date(buffer);
break;
case time:
db.row[i].time = convert_to_time(buffer);
break;
case id_tran:
db.row[i].id = atol(buffer);
break;
case price_tran:
db.row[i].price = atof(buffer);
break;
case quantity:
db.row[i].quantity = atoi(buffer);
break;
case barcode_tran:
db.row[i].barcode = atol(buffer);
break;
}
}
}
}
if(ferror(fp)){
printf("Error in reading file\n");
db.db.init_status = false;
return db;
}
fclose(fp);
db.db.init_status = true;
return db;
}
struct user read_db_user(){
FILE* fp = fopen(USER_DB,"r");
struct user db;
//gets the number of rows in the file
int row_count = basic_get_row_count(ENDOFUSER,fp);
db.row = (struct user_row*)malloc(row_count * sizeof(struct user_row));
db.db.row_count = row_count;
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
//read data
for(int i=0;i<row_count;i++){
db.row[i].isdeleted = false;
for(USER j=name;j<ENDOFUSER;j++){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
j--;//decrement j to prevent skipping next column
}else{
switch(j){
case name:
strcpy(db.row[i].name,buffer);
break;
case role:
strcpy(db.row[i].role,buffer);
break;
case id_user:
db.row[i].id = atol(buffer);
break;
}
}
}
}
if(ferror(fp)){
printf("Error in reading file\n");
db.db.init_status = false;
return db;
}
fclose(fp);
db.db.init_status = true;
return db;
}
bool update_db_invt(struct inventory* invt){
FILE* fpR = fopen(INVENTORY_DB,"r");
char temp[30] = INVENTORY_DB;
strcat(temp,".temp");
FILE* fpW = fopen(temp,"w");
if(fpR == NULL || fpW == NULL){
printf("Error in opening file\n");
return false;
}
for(int i=0;i<invt->db.row_count;i++){
if(invt->row[i].isdeleted == true){
continue;
}
for(INVENTORY j=category;j<ENDOFINVENTORY;j++){
char buffer[100];
do{
if(feof(fpR)){
break;
}
fgets(buffer, sizeof(buffer),fpR);
if(buffer[0] == '#'){//catch comment line and print back to new file
fputs(buffer,fpW);
}
}while(buffer[0] == '#');
switch(j){
case category:
fprintf(fpW,"%s",invt->row[i].category);
break;
case brand:
fprintf(fpW,"%s",invt->row[i].band);
break;
case product:
fprintf(fpW,"%s",invt->row[i].product);
break;
case price_inv:
fprintf(fpW,"%f",invt->row[i].price);
break;
case stock:
fprintf(fpW,"%d",invt->row[i].stock);
break;
case barcode_inv:
fprintf(fpW,"%ld",invt->row[i].barcode);
break;
}
fprintf(fpW,"\n");
}
}
//close file and replace old file with new file
fclose(fpR);
fclose(fpW);
remove(INVENTORY_DB);
rename(temp,INVENTORY_DB);
return true;
}
bool update_db_tran(struct transaction* tran){
FILE* fpR = fopen(TRANSACTION_DB,"r");
char temp[30] = TRANSACTION_DB;
strcat(temp,".temp");
FILE* fpW = fopen(temp,"w");
if(fpR == NULL || fpW == NULL){
printf("Error in opening file\n");
return false;
}
for(int i=0;i<tran->db.row_count;i++){
if(tran->row[i].isdeleted == true){
continue;
}
for(TRANSACTION j=date;j<ENDOFTRANSACTION;j++){
char buffer[100];
do{
if(feof(fpR)){
break;
}
fgets(buffer, sizeof(buffer),fpR);
if(buffer[0] == '#'){//catch comment line and print back to new file
fputs(buffer,fpW);
}
}while(buffer[0] == '#');
switch(j){
case date:
fprintf(fpW,"%d-%d-%d",tran->row[i].date.day,tran->row[i].date.month,tran->row[i].date.year);
break;
case time:
fprintf(fpW,"%d:%d:%d",tran->row[i].time.hour,tran->row[i].time.minute,tran->row[i].time.second);
break;
case id_tran:
fprintf(fpW,"%ld",tran->row[i].id);
break;
case price_tran:
fprintf(fpW,"%f",tran->row[i].price);
break;
case quantity:
fprintf(fpW,"%d",tran->row[i].quantity);
break;
case barcode_tran:
fprintf(fpW,"%ld",tran->row[i].barcode);
break;
}
fprintf(fpW,"\n");
}
}
//close file and replace old file with new file
fclose(fpR);
fclose(fpW);
remove(TRANSACTION_DB);
rename(temp,TRANSACTION_DB);
return true;
}
bool read_db_tran(FILE* fp,enum TRANSACTION transaction){
return true;
}
bool read_db_user(FILE* fp,enum USER user){
return true;
}
bool new_db_invt(FILE* fp,enum INVENTORY inventory){
return true;
}
bool new_db_tran(FILE* fp,enum TRANSACTION transaction){
return true;
}
bool new_db_user(FILE* fp,enum USER user){
return true;
}
bool edit_db_invt(FILE* fp,enum INVENTORY inventory){
return true;
}
bool edit_db_tran(FILE* fp,enum TRANSACTION transaction){
return true;
}
bool edit_db_user(FILE* fp,enum USER user){
return true;
}
bool rm_db_invt(FILE* fp,enum INVENTORY inventory){
return true;
}
bool rm_db_tran(FILE* fp,enum TRANSACTION transaction){
return true;
}
bool rm_db_user(FILE* fp,enum USER user){
bool update_db_user(struct user* user){
FILE* fpR = fopen(USER_DB,"r");
char temp[30] = USER_DB;
strcat(temp,".temp");
FILE* fpW = fopen(temp,"w");
if(fpR == NULL || fpW == NULL){
printf("Error in opening file\n");
return false;
}
for(int i=0;i<user->db.row_count;i++){
if(user->row[i].isdeleted == true){
continue;
}
for(USER j=name;j<ENDOFUSER;j++){
char buffer[100];
do{
if(feof(fpR)){
break;
}
fgets(buffer, sizeof(buffer),fpR);
if(buffer[0] == '#'){//catch comment line and print back to new file
fputs(buffer,fpW);
}
}while(buffer[0] == '#');
switch(j){
case name:
fprintf(fpW,"%s",user->row[i].name);
break;
case role:
fprintf(fpW,"%s",user->row[i].role);
break;
case id_user:
fprintf(fpW,"%ld",user->row[i].id);
break;
}
fprintf(fpW,"\n");
}
}
//close file and replace old file with new file
fclose(fpR);
fclose(fpW);
remove(USER_DB);
rename(temp,USER_DB);
return true;
}

View File

@ -5,6 +5,7 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif
//DATE
typedef struct date{

View File

@ -5,4 +5,5 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif

1
main.c
View File

@ -5,6 +5,7 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif
#ifndef CUSTOM_H
#define CUSTOM_H

1
menu.h
View File

@ -5,6 +5,7 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif

View File

@ -5,6 +5,7 @@
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif
#ifndef MENU_H
@ -12,9 +13,196 @@
#include "menu.h"
#endif //MENU_H
#ifndef SORT_H
#define SORT_H
#include "sorting.h"
#endif // !SORT_H
#define PAGE_SIZE 20
//for sort list
void list_items();
int normal_menu_user_choices();
bool normal_menu(){
system("cls");
welcome_message();
//the selection menu
int choice = normal_menu_user_choices();
switch (choice)
{
case 1://List items
list_items();
break;
case 2://Search item
// search_item();
break;
case 3://scan barcode
// scan_barcode();
break;
case 4://Exit
return false;
break;
default://invalid input
printf("Invalid choice\n");
return false;
break;
}
return true;
}
int normal_menu_user_choices(){
int choice;
printf("You can buy items inside the 2 option below\n");
printf("1. List items\n");
printf("2. Search item\n");
printf("3. Scan Barcodes\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
return choice;
}
//list items
void show_item(struct inventory db,int index);
void print_page(struct inventory db, int cur, int end,struct Map* map);
struct Map* sortItems(struct inventory db, int sort);
void list_items(){
system("cls");
welcome_message();
//get the list of items from the database
//print the list of items
//prompt user to select an item
//if user selects an item, display the item's details
int choice = -1;
int page = 0;
int page_size = PAGE_SIZE;
struct inventory db = read_db_invt();
int total_pages = ceil(db.db.row_count / page_size);
struct Map* map = NULL;
do{
//ooptions
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 band decending\n");
printf("6 sort band ascending\n");
printf("7 sort category decending\n");
printf("8 sort category ascending\n");
printf("List of items:\n");
//print items
if(map == NULL){
print_page(db, page * page_size, (page + 1== total_pages)?db.db.row_count:(page+1) * page_size,(struct Map*)NULL);
}else{//sorted)
print_page(db, page * page_size, (page + 1== total_pages)?db.db.row_count:(page+1) * page_size,map);
}
//page control
printf("%d next page\n", page_size+3);
printf("%d previous page\n", page_size+4);
printf("%d set page size\n", page_size+5);
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{
printf("Enter your choice: ");
scanf("%d", &choice);
if(choice <=8 && choice > 0){
printf("sorting...\n");
map = sortItems(db,choice);
}else if(choice == page_size+3){
page++;
}else if(choice == page_size+4 && page > 0){
page--;
}else if(choice == page_size+5){
printf("Enter page size: ");
scanf("%d", &page_size);
total_pages = ceil(db.db.row_count / page_size);
}else if(choice >= 0 && choice < db.db.row_count){
show_item(db,choice-9 + page_size*page);
}else{
printf("Invalid choice\n");
valid = false;
}
}while(!valid);
}while(choice != 0);
}
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;
switch(sort){
case 1:
case 2:
map[i].value = (int)db.row[i].product;
break;
case 3:
case 4:
map[i].value = (int)db.row[i].price*100;//presume there is no price contain 0.001
break;
case 5:
case 6:
map[i].value = (int)db.row[i].band;
break;
case 7:
case 8:
map[i].value = (int)db.row[i].category;
break;
}
}
switch (sort){
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;
}
void print_page(struct inventory db, int cur, int end,struct Map* map){
for (int i = cur; i < end; i++)
{
if(map != NULL){
printf("%d. %s\n", i + 1, db.row[map[i].key].product);
}
else{
printf("item%d. %s\n", i + 3, db.row[i].product);
}
}
}
void show_item(struct inventory db,int index){
system("cls");
printf("Product: %s\n", db.row[index].product);
printf("Catergory: %s\n", db.row[index].category);
printf("Band: %d\n", db.row[index].band);
printf("Price: $%lf\n", db.row[index].price);
printf("Stock: %d\n", db.row[index].stock);
printf("Barcode: %ld\n",db.row[index].barcode);
return;
}
retrurn true
}
//

11
sorting.h Normal file
View File

@ -0,0 +1,11 @@
typedef struct Map{
int key;
int value;
};
int compare_decending(const void *a, const void *b){
return (*(struct Map *)b).value - (*(struct Map *)a).value;
}
int compare_ascending(const void *a, const void *b){
return (*(struct Map *)a).value - (*(struct Map *)b).value;
}