CrimsonCare
CrimsonCare is a C project designed to provide a robust solution for blood management.
 
Loading...
Searching...
No Matches
transaction_manager.c
Go to the documentation of this file.
1
33#include "../include/misc.h"
35
68bool logTransaction(TransactionType type, const char* name, uint32_t bloodId, uint32_t quantity, const char* date, const char* token) {
69 errno = 0;
70 FILE* file = fopen("resources/db/transactions.log", "a");
71 if (!file) {
72 if (errno != ENOENT) {
73 printf("Error opening transaction log file: %s\n", strerror(errno));
74 }
75 return false;
76 }
77
78 if (containsPipe(name)) {
79 printf("Error: Entity name cannot contain a pipe character.\n");
80 return false;
81 }
82
83 if (type != BUY && type != SELL) {
84 printf("Error: Invalid transaction type.\n");
85 return false;
86 }
87
88 if (!isValidBloodGroup(bloodId)) {
89 printf("Error: Invalid blood group.\n");
90 return false;
91 }
92
93 if (strcmp(name, "") == 0 || quantity <= 0) {
94 printf("Error: Invalid transaction parameters.\n");
95 return false;
96 }
97
98 if (!isValidDate(date)) {
99 printf("Error: Invalid date format.\n");
100 return false;
101 }
102
103 if (token) {
104 fprintf(file, "%s|%s|%u|%u|%s|%s\n", (type == BUY ? "Buy" : "Sell"), name, bloodId, quantity, date, token);
105 } else {
106 fprintf(file, "%s|%s|%u|%u|%s\n", (type == BUY ? "Buy" : "Sell"), name, bloodId, quantity, date);
107 }
108
109 fclose(file);
110 return true;
111}
112
141bool addTransaction(TransactionType type, const char* name, uint32_t bloodId, uint32_t quantity) {
142 if (strcmp(name, "") == 0 || quantity <= 0) {
143 printf("Error: Invalid transaction parameters.\n");
144 return false;
145 }
146
147 if (containsPipe(name)) {
148 printf("Error: Entity name cannot contain a pipe character.\n");
149 return false;
150 }
151
152 if (type != BUY && type != SELL) {
153 printf("Error: Invalid transaction type.\n");
154 return false;
155 }
156
157 if (!isBloodAvailable(&bloodId, type)) {
158 printf("No stock available for blood group: %s\n", getBloodGroupById(bloodId));
159 return false;
160 }
161
162 if (type == BUY) {
163 if (!validateHospitalCode(name)) {
164 printf("Error: Invalid hospital code.\n");
165 return false;
166 }
167 }
168
170 char token[MAX_TRANSACTION_TOKEN_LENGTH] = "";
171
172 if (type == SELL) {
173 printf("Enter the date and time of donation (YYYY-MM-DD): ");
174 fgets(date, sizeof(date), stdin);
175 date[strcspn(date, "\n")] = 0;
176 if (!isValidDate(date)) {
177 printf("Error: Invalid date format.\n");
178 return false;
179 }
180 formatDate(date);
181 } else {
182 BloodStock* stock = bloodHead;
183 while (stock != NULL) {
184 if (stock->id == bloodId) {
185 if (stock->quantity < quantity) {
186 printf("Not enough stock for blood group: %s. Available quantity: %u\n", getBloodGroupById(bloodId), stock->quantity);
187 return false;
188 }
189
190 stock->quantity -= quantity;
191 saveBloodGroups();
192 break;
193 }
194 stock = stock->next;
195 }
196 time_t now = time(NULL);
197 strftime(date, sizeof(date), "%Y-%m-%d", localtime(&now));
198 }
199
200 if (type == SELL) {
201 srand(time(NULL));
202 sprintf(token, "TOKEN_%d", rand() % 10000);
203 printf("Sell token generated for %s: %s\n", name, token);
204 }
205
206 if (!logTransaction(type, name, bloodId, quantity, date, type == SELL ? token : NULL)) {
207 return false;
208 }
209
210 return true;
211}
212
223 errno = 0;
224 FILE* file = fopen("resources/db/transactions.log", "r");
225 if (!file) {
226 if (errno == ENOENT) {
227 printf("No registered transactions found.\n");
228 } else {
229 printf("Error opening transaction log file: %s\n", strerror(errno));
230 }
231 return;
232 }
233
234 char line[256];
235 bool hasLogs = false;
236 bool firstLog = true;
237 char prevLine[256] = { 0 };
238
239 while (fgets(line, sizeof(line), file) != NULL) {
240 char type[MAX_TRANSACTION_TOKEN_LENGTH] = "";
241 char name[MAX_TRANSACTION_TOKEN_LENGTH] = "";
242 uint32_t bloodId = 0;
243 uint32_t quantity = 0;
244 char date[MAX_TRANSACTION_TOKEN_LENGTH] = "";
245 char token[MAX_TRANSACTION_TOKEN_LENGTH] = "";
246
247 if (firstLog) {
248 printf("\nRegistered Transactions:\n");
249 firstLog = false;
250 }
251
252 if (sscanf(line, "%[^|]|%[^|]|%u|%u|%[^|]|%[^|\n]",
253 type,
254 name,
255 &bloodId,
256 &quantity,
257 date,
258 token) >= 5) {
259
260 hasLogs = true;
261
262 if (prevLine[0] != '\0') {
263 printf("\t----------------------------------\n");
264 }
265
266 printf("\tType: %s\n"
267 "\tEntity: %s\n"
268 "\tBlood Group: %s\n"
269 "\tQuantity: %u\n"
270 "\tDate: %s",
271 type,
272 name,
273 getBloodGroupById(bloodId),
274 quantity,
275 date);
276
277 if (token[0] != '\0') {
278 printf("\n\tToken: %s\n", token);
279 }
280
281 strncpy(prevLine, line, sizeof(prevLine) - 1);
282 prevLine[sizeof(prevLine) - 1] = '\0';
283 }
284 }
285
286 if (!hasLogs) {
287 printf("No registered transactions found.\n");
288 }
289
290 fclose(file);
291}
Blood manager header file.
BloodStock * bloodHead
Globally exposed blood stock head pointer.
Hospital manager header file.
Misc header file.
Blood stock structure.
uint32_t quantity
uint32_t id
struct BloodStock * next
void displayTransactions(void)
Display all transactions.
Transaction manager header file.
#define MAX_TRANSACTION_TOKEN_LENGTH
Maximum transaction token length.
TransactionType
Transaction type enum.
#define MAX_TRANSACTION_DATE_LENGTH
Maximum transaction date length.