forked from MazenDB/GPO
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GPO.sol
305 lines (230 loc) · 8.85 KB
/
GPO.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
pragma solidity =0.6.0;
contract Registration {
address payable GPO;
uint constant manufacuterFee=1;
uint constant HealthProviderPFee=1;
mapping(address=>bool) manufacturers;
mapping(address=>bool) distributors;
mapping(address=>bool) healthproviders;
event ManufacturerRegistered(address manufactuer);
event DistributorRegistered(address distributor);
event HealthProviderRegistered(address healthProvider);
modifier onlyGPO{
require(msg.sender == GPO,
"Sender not authorized."
);
_;
}
constructor() public{
GPO=msg.sender;
}
function registerManufacturer() public payable{
require(!manufacturers[msg.sender] && !distributors[msg.sender] && !healthproviders[msg.sender],
"Address already used");
require(msg.value>=manufacuterFee,
"Admission fee insufficient");
manufacturers[msg.sender]=true;
emit ManufacturerRegistered(msg.sender);
}
function registerDistributor(address d) public onlyGPO{
require(!manufacturers[d] && !distributors[d] && !healthproviders[d],
"Address already used");
distributors[d]=true;
emit DistributorRegistered(d);
}
function registerProvider() public payable{
require(!manufacturers[msg.sender] && !distributors[msg.sender] && !healthproviders[msg.sender],
"Address already used");
require(msg.value>=HealthProviderPFee,
"Admission fee insufficient");
healthproviders[msg.sender]=true;
emit HealthProviderRegistered(msg.sender);
}
function manufacturerExists(address m) public view returns(bool){
return manufacturers[m];
}
function distributorExists(address d) public view returns(bool){
return distributors[d];
}
function HPExists(address h) public view returns(bool){
return healthproviders[h];
}
function isGPO(address payable g) public view returns(bool){
return (g==GPO);
}
}
contract PurchaseNegotiation{
Registration registrationContract;
uint public contractAddresses;
enum status{
NewContract,
Negotiating,
PriceConfirmed,
PriceRejected,
ContractClosed
}
struct contractType{
address manufacturer;
address distributor;
uint productID;
uint quantity;
uint price;
status orderStatus;
}
mapping(uint=>contractType) public contracts;
event NewContractPublished(uint contractAddress, uint quantityOrdered, address manufacturer);
event PriceNegotiation(uint contractAddress, uint newPrice);
event ContractConfirmed(uint contractAddress, uint quantity, address manufacturer, uint price);
event ContractClosed(uint contractAddress);
modifier onlyGPO{
require(registrationContract.isGPO(msg.sender),
"Sender not authorized."
);
_;
}
modifier onlyManufacturer{
require(registrationContract.manufacturerExists(msg.sender),
"Sender not authorized."
);
_;
}
constructor(address registrationAddress)public {
registrationContract=Registration(registrationAddress);
contractAddresses=uint(keccak256(abi.encodePacked(msg.sender,now,address(this))));
}
function newContract(uint productID, uint quantity, address manufacturer) public onlyGPO {
require(registrationContract.manufacturerExists(manufacturer),
"Manufacturer address not recognized."
);
contractAddresses++;
contracts[contractAddresses]=contractType(manufacturer,address(0),productID,quantity,0,status.NewContract);
emit NewContractPublished(contractAddresses, quantity, manufacturer);
}
function negotiateContract(uint contractAddress, uint newPrice) public onlyManufacturer{
require(contracts[contractAddress].orderStatus==status.NewContract || contracts[contractAddress].orderStatus==status.PriceRejected,
"Contract not available for price negotiation."
);
require(contracts[contractAddress].manufacturer==msg.sender,
"Manufacturer not authorized"
);
emit PriceNegotiation(contractAddress, newPrice);
contracts[contractAddress].price=newPrice;
contracts[contractAddress].orderStatus=status.Negotiating;
}
function contractStatus(uint contractAddress, bool accepted) public onlyGPO{
require(contracts[contractAddress].orderStatus==status.Negotiating,
"Contract not available for price negotiation."
);
if(accepted){
contracts[contractAddress].orderStatus=status.PriceConfirmed;
emit ContractConfirmed(contractAddress, contracts[contractAddress].quantity, contracts[contractAddress].manufacturer, contracts[contractAddress].price);
}
else{
contracts[contractAddress].orderStatus=status.PriceRejected;
}
}
function assignDistributor(uint contractAddress, address distributor) public onlyGPO{
require(contracts[contractAddress].orderStatus==status.PriceConfirmed,
"Contract not confirmed."
);
require(registrationContract.distributorExists(distributor),
"Distributor adaddress not valid"
);
contracts[contractAddress].distributor=distributor;
emit ContractClosed(contractAddress);
}
}
contract PurchaseOrders{
Registration registrationContract;
struct PO_type{
address healthProvider;
address distributor;
bool delivered;
}
mapping(uint=>PO_type) POs;
modifier onlyDistributor{
require(registrationContract.distributorExists(msg.sender),
"Sender not authorized."
);
_;
}
modifier onlyHP{
require(registrationContract.HPExists(msg.sender),
"Sender not authorized."
);
_;
}
constructor(address registrationAddress)public {
registrationContract=Registration(registrationAddress);
}
event POsubmitted(uint POnumber, address healthProvider, address distributor);
event OrderDelivered(uint POnumber);
function submitPO(uint POnumber, address distributor) public onlyHP{
POs[POnumber]=PO_type(msg.sender,distributor,false);
emit POsubmitted(POnumber,msg.sender, distributor);
}
function deliverStatus(uint POnumber)public onlyDistributor{
require(POs[POnumber].distributor==msg.sender,
"Distributor not authorized"
);
POs[POnumber].delivered=true;
emit OrderDelivered(POnumber);
}
}
contract RebatesSettelment{
Registration registrationContract;
mapping(uint=>uint) rebateRequests;
modifier onlyDistributor{
require(registrationContract.distributorExists(msg.sender),
"Sender not authorized."
);
_;
}
modifier onlyManufacturer{
require(registrationContract.manufacturerExists(msg.sender),
"Sender not authorized."
);
_;
}
event RequestSubmitted(uint contractAddress, address distributor, address manufacturer, uint amountRequested);
event RequestApproved(uint contractAddress);
constructor(address registrationAddress)public {
registrationContract=Registration(registrationAddress);
}
function submitRebateRequest(uint contractAddress, uint amount, address manufacturer) public onlyDistributor{
require(registrationContract.manufacturerExists(manufacturer),
"Manufacturer address not authorized."
);
rebateRequests[contractAddress]=amount;
emit RequestSubmitted(contractAddress,msg.sender,manufacturer,amount);
}
function approveRebateRequest(uint contractAddress, address payable distributor) public payable onlyManufacturer{
require(rebateRequests[contractAddress]>0,
"Rebate request not submitted for this contract."
);
require(msg.value>=rebateRequests[contractAddress],
"Transferred amount insufficient."
);
rebateRequests[contractAddress]=0;
emit RequestApproved(contractAddress);
distributor.transfer(msg.value);
}
}
contract LoyaltyRebates{
Registration registrationContract;
modifier onlyGPO{
require(registrationContract.isGPO(msg.sender),
"Sender not authorized."
);
_;
}
constructor(address registrationAddress)public {
registrationContract=Registration(registrationAddress);
}
function sendLoyaltyRebate(address payable healthProvider) payable public onlyGPO{
require(registrationContract.HPExists(healthProvider),
"Health provider address not recognized."
);
healthProvider.transfer(msg.value);
}
}