768 lines
23 KiB
C
768 lines
23 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 DNT_H
|
|
#define DNT_H
|
|
#include "dateNtime.h"
|
|
#endif // !DNT_H
|
|
//linked list
|
|
#ifndef likely
|
|
#define likely(x) __builtin_expect(!!(x), 1)
|
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
#endif
|
|
typedef struct linkedlist{
|
|
struct linkedlist* next;
|
|
struct linkedlist* prev;
|
|
void* data;
|
|
}linkedlist;
|
|
//linked list functions
|
|
int sizeofLinkedlist(struct linkedlist* list){
|
|
linkedlist* start = list;
|
|
int size = 0;
|
|
linkedlist* current = list;
|
|
while (current != NULL){
|
|
size++;
|
|
current = current->next;
|
|
}
|
|
current = start;
|
|
while(current->prev != NULL){
|
|
size++;
|
|
current = current->prev;
|
|
}
|
|
return size;
|
|
}
|
|
struct linkedlist* getLinkedList(struct linkedlist* list,int pos){
|
|
linkedlist* cur = list;
|
|
while(cur->prev != NULL){
|
|
cur = cur->prev;
|
|
}
|
|
struct linkedlist* start = cur;
|
|
for(int i=0;i<pos;i++){
|
|
cur = cur->next;
|
|
if(cur == NULL){
|
|
return start;//return start if pos is out of bounds
|
|
}
|
|
}
|
|
return cur;
|
|
}
|
|
typedef struct basic_db{
|
|
int row_count;
|
|
bool init_status;//not really used can be useful
|
|
//array of struct of row
|
|
}basic_db;
|
|
|
|
//inventory
|
|
#define INVENTORY_DB "data_file_inventory.txt"
|
|
typedef struct inventory{
|
|
struct basic_db db;
|
|
struct inventory_row* row;
|
|
|
|
}inventory;
|
|
typedef struct inventory_row{
|
|
char category[100];
|
|
char brand[100];
|
|
char product[100];
|
|
double price;
|
|
int stock;
|
|
long barcode;
|
|
bool isdeleted;//common for all rows,default is false
|
|
}inventory_row;
|
|
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;
|
|
|
|
}transaction;
|
|
typedef struct transaction_row{
|
|
struct Date date;
|
|
struct Time time;
|
|
long id;
|
|
double price;
|
|
int quantity;
|
|
long barcode;
|
|
bool isdeleted;//common for all rows,default is false
|
|
}transaction_row;
|
|
typedef enum {
|
|
date = 1, TIME = 2, id_tran = 3, price_tran = 4, quantity = 5, barcode_tran = 6
|
|
}TRANSACTION;
|
|
#define ENDOFTRANSACTION 6
|
|
//user
|
|
#define USER_DB "data_file_user.txt"
|
|
typedef struct user{
|
|
struct basic_db db;
|
|
struct user_row* row;
|
|
}user;
|
|
typedef struct user_row{
|
|
char name[100];
|
|
char role[100];
|
|
long id;
|
|
bool isdeleted;//common for all rows,default is false
|
|
}user_row;
|
|
|
|
typedef enum {
|
|
name = 1, role = 2, id_user = 3
|
|
}USER;
|
|
#define ENDOFUSER 3
|
|
|
|
//admin verify
|
|
#define ADMIN_DB "data_file_admin.txt"
|
|
//func for admin verify
|
|
|
|
bool is_admin(char* role){
|
|
FILE* fp = fopen(ADMIN_DB,"r");
|
|
if(fp == NULL){
|
|
printf("Error opening file\n");
|
|
return false;
|
|
}
|
|
char line[100];
|
|
while(fgets(line,100,fp) != NULL){
|
|
if(unlikely(line[0] == '#')) continue;
|
|
|
|
while(line[strlen(line)-1] == '\n' || (int)line[strlen(line)-1] == 13)
|
|
line[strlen(line)-1] = '\0';
|
|
|
|
if(strcmp(line,role) == 0){
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return false;
|
|
}
|
|
|
|
void add_admin(char* role){
|
|
FILE* fp = fopen(ADMIN_DB,"a");
|
|
if(fp == NULL){
|
|
printf("Error opening file\n");
|
|
return;
|
|
}
|
|
fprintf(fp,"%s\n",role);
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
|
|
void remove_admin(char* role){
|
|
FILE* fp = fopen(ADMIN_DB,"r");
|
|
if(fp == NULL){
|
|
printf("Error opening file\n");
|
|
return;
|
|
}
|
|
char temp[30] = ADMIN_DB;
|
|
strcat(temp,".temp");
|
|
FILE* fp2 = fopen(temp,"w");
|
|
if(fp2 == NULL){
|
|
printf("Error opening file\n");
|
|
return;
|
|
}
|
|
char line[100];
|
|
while(fgets(line,100,fp) != NULL){
|
|
if(unlikely(line[0] == '#')) {
|
|
fprintf(fp2,"%s",line);
|
|
continue;
|
|
}
|
|
while(line[strlen(line)-1] == '\n' || (int)line[strlen(line)-1] == 13)//remove newline for compare
|
|
line[strlen(line)-1] = '\0';
|
|
if(strcmp(line,role) != 0){
|
|
fprintf(fp2,"%s\n",line);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
fclose(fp2);
|
|
remove(ADMIN_DB);
|
|
rename(temp,ADMIN_DB);
|
|
return;
|
|
}
|
|
//list of db func
|
|
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(unlikely(buffer[0] == '#' || buffer[0] == '\0')){//catch comment line and ignore
|
|
continue;
|
|
}
|
|
colmun_count++;
|
|
if(colmun_count == end){
|
|
row_count++;
|
|
colmun_count = 0;
|
|
}
|
|
}
|
|
return row_count;
|
|
}
|
|
|
|
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(unlikely(buffer[0] == '#')){//catch comment line and ignore
|
|
j--;//decrement j to prevent skipping next column
|
|
}else{
|
|
buffer[strlen(buffer)] = '\0';
|
|
while(buffer[strlen(buffer)-1] == '\n' || (int)buffer[strlen(buffer)-1] == 13){
|
|
buffer[strlen(buffer)-1] = '\0';
|
|
|
|
}
|
|
|
|
switch(j){
|
|
case category:
|
|
strcpy(db.row[i].category,buffer);
|
|
break;
|
|
case brand:
|
|
strcpy(db.row[i].brand,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(unlikely(buffer[0] == '#')){//catch comment line and ignore
|
|
j--;//decrement j to prevent skipping next column
|
|
}else{
|
|
buffer[strlen(buffer)] = '\0';
|
|
while(buffer[strlen(buffer)-1] == '\n' || (int)buffer[strlen(buffer)-1] == 13){
|
|
buffer[strlen(buffer)-1] = '\0';
|
|
|
|
}
|
|
|
|
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(unlikely(buffer[0] == '#')){//catch comment line and ignore
|
|
j--;//decrement j to prevent skipping next column
|
|
}else{
|
|
buffer[strlen(buffer)] = '\0';//prevent any garbage value
|
|
while(buffer[strlen(buffer)-1] == '\n' || (int)buffer[strlen(buffer)-1] == 13){
|
|
buffer[strlen(buffer)-1] = '\0';
|
|
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
struct linkedlist* role_list_db(){
|
|
struct user db = read_db_user();
|
|
struct linkedlist* list = (struct linkedlist*)malloc(sizeof(struct linkedlist));
|
|
//put unqie user role into linked list in acending order
|
|
struct linkedlist* current = list;
|
|
//initial the first node
|
|
current->data = db.row[0].role;
|
|
current->next = NULL;
|
|
current->prev = NULL;
|
|
for(int i=1;i<db.db.row_count;i++){
|
|
char* role = db.row[i].role;
|
|
int diff = strcmp(current->data,role);
|
|
if(diff == 0){
|
|
continue;
|
|
}else if(diff > 0){
|
|
while(diff > 0){
|
|
if(diff == 0){
|
|
break;
|
|
}else if(diff < 0){
|
|
//insert before current
|
|
struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist));
|
|
new->data = role;
|
|
new->next = current;
|
|
new->prev = current->prev;
|
|
current->prev->next = new;
|
|
current->prev = new;
|
|
break;
|
|
}else{
|
|
if(current->next == NULL){
|
|
//insert after current
|
|
struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist));
|
|
new->data = role;
|
|
new->next = NULL;
|
|
new->prev = current;
|
|
current->next = new;
|
|
break;
|
|
}else{
|
|
current = current->next;
|
|
diff = strcmp(current->data,role);
|
|
}
|
|
}
|
|
}
|
|
}else{
|
|
while(diff < 0){
|
|
if(diff == 0){
|
|
break;
|
|
}else if(diff > 0){
|
|
//insert after current
|
|
struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist));
|
|
new->data = role;
|
|
new->next = current;
|
|
new->prev = current->prev;
|
|
current->prev->next = new;
|
|
current->prev = new;
|
|
break;
|
|
}else{
|
|
if(current->prev == NULL){
|
|
//insert before current
|
|
struct linkedlist* new = (struct linkedlist*)malloc(sizeof(struct linkedlist));
|
|
new->data = role;
|
|
new->next = current;
|
|
new->prev = NULL;
|
|
current->prev = new;
|
|
break;
|
|
}else{
|
|
current = current->prev;
|
|
diff = strcmp(current->data,role);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
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].barcode == -1024 || invt.row[i].isdeleted == true)//skip create new row
|
|
continue;
|
|
for(INVENTORY j=category;j<=ENDOFINVENTORY;j++){
|
|
char buffer[100];
|
|
do{
|
|
if(unlikely(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].brand);
|
|
break;
|
|
case product:
|
|
fprintf(fpW,"%s",invt.row[i].product);
|
|
break;
|
|
case price_inv:
|
|
fprintf(fpW,"%.1f",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(unlikely(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-%02d-%02d",tran.row[i].date.year,tran.row[i].date.month,tran.row[i].date.day);
|
|
break;
|
|
case TIME:
|
|
fprintf(fpW,"%02d:%02d:%02d",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,"%.1f",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 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(unlikely(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;
|
|
}
|
|
|
|
bool append_inventory(struct inventory_row* row){
|
|
FILE* fp = fopen(INVENTORY_DB,"a");
|
|
if(fp == NULL){
|
|
printf("Error in opening file\n");
|
|
return false;
|
|
}
|
|
fprintf(fp,"%s\n",row->category);
|
|
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;
|
|
}
|
|
|
|
bool append_transaction_db(struct transaction_row* row){
|
|
FILE* fp = fopen(TRANSACTION_DB,"a");
|
|
if(fp == NULL){
|
|
printf("Error in opening file\n");
|
|
return false;
|
|
}
|
|
fprintf(fp,"%04d-%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;
|
|
}
|
|
|
|
bool append_user(struct user_row* row){
|
|
FILE* fp = fopen(USER_DB,"a");
|
|
if(fp == NULL){
|
|
printf("Error in opening file\n");
|
|
return false;
|
|
}
|
|
fprintf(fp,"%s\n",row->name);
|
|
fprintf(fp,"%s\n",row->role);
|
|
fprintf(fp,"%ld\n",row->id);
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
|
|
//checkout db support,
|
|
|
|
typedef struct cart{//linked list
|
|
struct inventory_row* row;//pointer to the row
|
|
int quantity;//quantity of the item
|
|
struct cart* next;
|
|
}cart;
|
|
|
|
|
|
bool append_transaction(struct cart* cart,struct user_row* user){
|
|
FILE* fp = fopen(TRANSACTION_DB,"a");
|
|
if(fp == NULL){
|
|
printf("Error in opening file\n");
|
|
return false;
|
|
}
|
|
|
|
struct Date date = get_date();
|
|
struct Time time = get_time();
|
|
struct cart* temp = cart;
|
|
if(temp == NULL)
|
|
return false;
|
|
|
|
do{
|
|
|
|
fprintf(fp,"%d-%02d-%02d\n",date.year,date.month,date.day);
|
|
fprintf(fp,"%02d:%02d:%02d\n",time.hour,time.minute,time.second);
|
|
fprintf(fp,"%ld\n",user->id);
|
|
fprintf(fp,"%f\n",temp->row->price);
|
|
fprintf(fp,"%d\n",temp->quantity);
|
|
fprintf(fp,"%ld\n",temp->row->barcode);
|
|
if(temp->next == NULL)
|
|
break;
|
|
temp = temp->next;
|
|
}while(temp->next != NULL);//this while condition just for safety,as it should already break in the if statement
|
|
fclose(fp);
|
|
return true;
|
|
}
|
|
|
|
bool update_stock_N_checkout(struct cart* cart,struct user_row* user){
|
|
struct inventory invt = read_db_invt();
|
|
struct cart* temp = cart;
|
|
if(temp == NULL)
|
|
return false;
|
|
do{
|
|
for(int i=0;i<invt.db.row_count;i++){
|
|
|
|
if(invt.row[i].barcode == temp->row->barcode){
|
|
invt.row[i].stock -= temp->quantity;
|
|
break;
|
|
}
|
|
}
|
|
if(temp->next == NULL)
|
|
break;
|
|
temp = temp->next;
|
|
}while(temp->next != NULL);//this while condition just for safety,as it should already break in the if statement
|
|
if(!append_transaction(cart,user)){
|
|
return false;
|
|
}
|
|
if(!update_db_invt(invt)){
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//user
|
|
struct user_row* get_user(long userid){
|
|
struct user_row* user = (struct user_row*)malloc(sizeof(struct user_row));
|
|
FILE* fp = fopen(USER_DB,"r");
|
|
if(fp == NULL){
|
|
printf("Error in opening file\n");
|
|
return NULL;
|
|
}
|
|
char buffer[100];
|
|
|
|
//gets the number of rows in the file
|
|
int row_count = basic_get_row_count(ENDOFUSER,fp);
|
|
|
|
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
|
|
|
|
//read data
|
|
for(int i=0;i<row_count;i++){
|
|
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{
|
|
buffer[strlen(buffer)] = '\0';
|
|
while(buffer[strlen(buffer)-1] == '\n' || (int)buffer[strlen(buffer)-1] == 13){
|
|
buffer[strlen(buffer)-1] = '\0';
|
|
}
|
|
|
|
switch(j){
|
|
case name:
|
|
strcpy(user->name,buffer);
|
|
break;
|
|
case role:
|
|
strcpy(user->role,buffer);
|
|
break;
|
|
case id_user:
|
|
user->id = atol(buffer);
|
|
if(user->id == userid){
|
|
fclose(fp);
|
|
return user;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return NULL;
|
|
} |