// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract BloodBankSupplyChain { address public Owner; constructor() { Owner = msg.sender; } modifier onlyByOwner() { require(msg.sender == Owner); _; } enum STAGE { Init, DonorCollection, BloodBank, Hospital, Patient } uint256 public bloodCtr = 0; uint256 public donorCtr = 0; uint256 public bankCtr = 0; uint256 public hospitalCtr = 0; uint256 public patientCtr = 0; struct Blood { uint256 id; string group; uint256 units; uint256 donorID; uint256 bankID; uint256 hospitalID; uint256 patientID; STAGE stage; } mapping(uint256 => Blood) public BloodStock; function showStage(uint256 _bloodID) public view returns (string memory) { require(bloodCtr > 0); if (BloodStock[_bloodID].stage == STAGE.DonorCollection) return "Blood Collected from Donor"; else if (BloodStock[_bloodID].stage == STAGE.BloodBank) return "Stored in Blood Bank"; else if (BloodStock[_bloodID].stage == STAGE.Hospital) return "Transferred to Hospital"; else if (BloodStock[_bloodID].stage == STAGE.Patient) return "Transfused to Patient"; } struct Donor { address addr; uint256 id; string name; string bloodType; } mapping(uint256 => Donor) public Donors; struct Bank { address addr; uint256 id; string name; string location; } mapping(uint256 => Bank) public BloodBanks; struct Hospital { address addr; uint256 id; string name; string location; } mapping(uint256 => Hospital) public Hospitals; struct Patient { address addr; uint256 id; string name; string condition; } mapping(uint256 => Patient) public Patients; function addDonor( address _address, string memory _name, string memory _bloodType ) public onlyByOwner() { donorCtr++; Donors[donorCtr] = Donor(_address, donorCtr, _name, _bloodType); } function addBank( address _address, string memory _name, string memory _location ) public onlyByOwner() { bankCtr++; BloodBanks[bankCtr] = Bank(_address, bankCtr, _name, _location); } function addHospital( address _address, string memory _name, string memory _location ) public onlyByOwner() { hospitalCtr++; Hospitals[hospitalCtr] = Hospital(_address, hospitalCtr, _name, _location); } function addPatient( address _address, string memory _name, string memory _condition ) public onlyByOwner() { patientCtr++; Patients[patientCtr] = Patient(_address, patientCtr, _name, _condition); } function collectBlood(uint256 _bloodID) public { require(_bloodID > 0 && _bloodID <= bloodCtr); uint256 _id = findDonor(msg.sender); require(_id > 0); require(BloodStock[_bloodID].stage == STAGE.Init); BloodStock[_bloodID].donorID = _id; BloodStock[_bloodID].stage = STAGE.DonorCollection; } function findDonor(address _address) private view returns (uint256) { require(donorCtr > 0); for (uint256 i = 1; i <= donorCtr; i++) { if (Donors[i].addr == _address) return Donors[i].id; } return 0; } function storeBlood(uint256 _bloodID) public { require(_bloodID > 0 && _bloodID <= bloodCtr); uint256 _id = findBank(msg.sender); require(_id > 0); require(BloodStock[_bloodID].stage == STAGE.DonorCollection); BloodStock[_bloodID].bankID = _id; BloodStock[_bloodID].stage = STAGE.BloodBank; } function findBank(address _address) private view returns (uint256) { require(bankCtr > 0); for (uint256 i = 1; i <= bankCtr; i++) { if (BloodBanks[i].addr == _address) return BloodBanks[i].id; } return 0; } function transferToHospital(uint256 _bloodID, uint256 _hospitalID) public { require(_bloodID > 0 && _bloodID <= bloodCtr); require(_hospitalID > 0 && _hospitalID <= hospitalCtr); uint256 _id = findHospital(msg.sender); require(_id > 0); require(BloodStock[_bloodID].stage == STAGE.BloodBank); BloodStock[_bloodID].hospitalID = _hospitalID; BloodStock[_bloodID].stage = STAGE.Hospital; } function findHospital(address _address) private view returns (uint256) { require(hospitalCtr > 0); for (uint256 i = 1; i <= hospitalCtr; i++) { if (Hospitals[i].addr == _address) return Hospitals[i].id; } return 0; } function transfuseToPatient(uint256 _bloodID, uint256 _patientID) public { require(_bloodID > 0 && _bloodID <= bloodCtr); require(_patientID > 0 && _patientID <= patientCtr); uint256 _id = findPatient(msg.sender); require(_id > 0); require(BloodStock[_bloodID].stage == STAGE.Hospital); BloodStock[_bloodID].patientID = _patientID; BloodStock[_bloodID].stage = STAGE.Patient; } function findPatient(address _address) private view returns (uint256) { require(patientCtr > 0); for (uint256 i = 1; i <= patientCtr; i++) { if (Patients[i].addr == _address) return Patients[i].id; } return 0; } function addBlood(string memory _group, uint256 _units) public onlyByOwner() { require((donorCtr > 0) && (bankCtr > 0) && (hospitalCtr > 0) && (patientCtr > 0)); bloodCtr++; BloodStock[bloodCtr] = Blood( bloodCtr, _group, _units, 0, 0, 0, 0, STAGE.Init ); } }