CrimsonCare
CrimsonCare is a C project designed to provide a robust solution for blood management.
 
Loading...
Searching...
No Matches
blood_manager.c
Go to the documentation of this file.
1
33
39
44char* availableBloodGroups[8] = { "A+", "A-", "B+", "B-", "O+", "O-", "AB+", "AB-" };
45
59bool isValidBloodGroup(uint32_t id) {
60 return id <= (sizeof(availableBloodGroups) / sizeof(availableBloodGroups[0]));
61}
62
83bool addBloodGroup(uint32_t id, const char* bloodGroup, float price, uint32_t quantity) {
84 if (strcmp(bloodGroup, "") == 0) {
85 printf("Error: Invalid blood group data.\n");
86 return false;
87 }
88
89 if (!isValidBloodGroup(id)) {
90 printf("Error: Invalid blood group id.\n");
91 return false;
92 }
93
94 BloodStock* newGroup = (BloodStock*)malloc(sizeof(BloodStock));
95 if (!newGroup) {
96 printf("Error allocating memory for blood group: %s\n", strerror(errno));
97 return false;
98 }
99 strncpy(newGroup->bloodGroup, bloodGroup, BLOOD_GROUP_NAME_LENGTH - 1);
100 newGroup->bloodGroup[BLOOD_GROUP_NAME_LENGTH - 1] = '\0';
101 newGroup->price = price;
102 newGroup->quantity = quantity;
103 newGroup->id = id;
104 newGroup->next = NULL;
105
106 if (bloodHead == NULL) {
107 bloodHead = newGroup;
108 } else {
109 BloodStock* temp = bloodHead;
110 while (temp->next != NULL) {
111 temp = temp->next;
112 }
113 temp->next = newGroup;
114 }
115 return true;
116}
117
128void initializeBloodGroups(void) {
129 for (uint8_t i = 0; i < (sizeof(availableBloodGroups) / sizeof(availableBloodGroups[0])); i++) {
130 if (!addBloodGroup(i + 1, availableBloodGroups[i], 0.0, 0)) {
131 printf("Error: Failed to initialize blood group %s.\n", availableBloodGroups[i]);
132 }
133 }
134}
135
149void saveBloodGroups(void) {
150 errno = 0;
151 FILE* file = fopen("resources/db/blood_data.txt", "w");
152 if (!file) {
153 if (errno != ENOENT) {
154 printf("Error opening blood data file: %s\n", strerror(errno));
155 return;
156 }
157 }
158
159 BloodStock* temp = bloodHead;
160 while (temp != NULL) {
161 fprintf(file, "%u %s %.2f %u\n", temp->id, temp->bloodGroup, temp->price, temp->quantity);
162 temp = temp->next;
163 }
164 fclose(file);
165}
166
183bool updateBloodQuantity(uint32_t id, uint32_t newQuantity) {
184 if (!isValidBloodGroup(id)) {
185 printf("Error: Invalid blood group id.\n");
186 return false;
187 }
188
189 BloodStock* temp = bloodHead;
190 while (temp != NULL) {
191 if (temp->id == id) {
192 temp->quantity = newQuantity;
193 saveBloodGroups();
194 return true;
195 }
196 temp = temp->next;
197 }
198 return false;
199}
200
217bool updateBloodPrice(uint32_t id, float newPrice) {
218 if (!isValidBloodGroup(id)) {
219 printf("Error: Invalid blood group id.\n");
220 return false;
221 }
222
223 BloodStock* temp = bloodHead;
224 while (temp != NULL) {
225 if (temp->id == id) {
226 temp->price = newPrice;
227 saveBloodGroups();
228 return true;
229 }
230 temp = temp->next;
231 }
232 return false;
233}
234
249void loadBloodGroups(void) {
250 errno = 0;
251 FILE* file = fopen("resources/db/blood_data.txt", "r");
252 if (!file) {
253 if (errno == ENOENT) {
254 initializeBloodGroups();
255 return;
256 } else {
257 printf("Error opening blood data file: %s\n", strerror(errno));
258 freeBloodList();
259 return;
260 }
261 }
262
263 while (1) {
264 BloodStock* newBlood = (BloodStock*)malloc(sizeof(BloodStock));
265 if (!newBlood) {
266 printf("Error allocating memory for blood group: %s\n", strerror(errno));
267 freeBloodList();
268 fclose(file);
269 return;
270 }
271
272 if (fscanf(file, "%u %s %f %u", &newBlood->id, newBlood->bloodGroup, &newBlood->price, &newBlood->quantity) != 4) {
273 free(newBlood);
274 fclose(file);
275 break;
276 }
277
278 newBlood->next = NULL;
279
280 if (bloodHead == NULL) {
281 bloodHead = newBlood;
282 } else {
283 BloodStock* temp = bloodHead;
284 while (temp->next != NULL) {
285 temp = temp->next;
286 }
287 temp->next = newBlood;
288 }
289 }
290
291 fclose(file);
292}
293
313bool isBloodAvailable(uint32_t* id, TransactionType type) {
314 if (type != BUY && type != SELL) {
315 printf("Error: Invalid transaction type.\n");
316 return false;
317 }
318
319 if (id != NULL && !isValidBloodGroup(*id)) {
320 printf("Error: Invalid blood group id.\n");
321 return false;
322 }
323
324 BloodStock* temp = bloodHead;
325 while (temp != NULL) {
326 if (type == BUY) {
327 if (id == NULL) {
328 if (temp->price > 0 && temp->quantity > 0) {
329 return true;
330 }
331 } else {
332 if (temp->id == *id && temp->price > 0 && temp->quantity > 0) {
333 return true;
334 }
335 }
336 } else {
337 if (id == NULL) {
338 if (temp->price > 0) {
339 return true;
340 }
341 } else {
342 if (temp->id == *id && temp->price > 0) {
343 return true;
344 }
345 }
346 }
347 temp = temp->next;
348 }
349 return false;
350}
351
359void displayBloodGroups(void) {
360 for (uint32_t i = 0; i < (sizeof(availableBloodGroups) / sizeof(availableBloodGroups[0])); i++) {
361 printf("%u. %s\n", i + 1, availableBloodGroups[i]);
362 }
363}
364
374void displayBloodStocks(void) {
375 BloodStock* temp = bloodHead;
376 if (temp == NULL) {
377 printf("No blood available.\n");
378 return;
379 }
380 printf("\nAvailable Blood:\n");
381 while (temp != NULL) {
382 if (temp->price > 0.0) {
383 printf("%u. %s, Price: %.2f, Quantity: %u\n", temp->id, temp->bloodGroup, temp->price, temp->quantity);
384 } else {
385 printf("%u. %s, Price: N/A, Quantity: N/A\n", temp->id, temp->bloodGroup);
386 }
387 temp = temp->next;
388 }
389}
390
404char* getBloodGroupById(uint32_t id) {
405 if (!isValidBloodGroup(id)) {
406 printf("Error: Invalid blood group id.\n");
407 return NULL;
408 }
409
410 return availableBloodGroups[id - 1];
411}
412
420void freeBloodList(void) {
421 BloodStock* current = bloodHead;
422 while (current != NULL) {
423 BloodStock* temp = current;
424 current = current->next;
425 free(temp);
426 }
427 bloodHead = NULL;
428}
429
char * availableBloodGroups[8]
Blood groups.
Blood manager header file.
#define BLOOD_GROUP_NAME_LENGTH
Blood group name length.
BloodStock * bloodHead
Globally exposed blood stock head pointer.
Blood stock structure.
uint32_t quantity
uint32_t id
char bloodGroup[BLOOD_GROUP_NAME_LENGTH]
struct BloodStock * next
Transaction manager header file.
TransactionType
Transaction type enum.