-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.sql
236 lines (206 loc) · 5.89 KB
/
main.sql
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
create table Customers(
Card_id number primary key,
Password varchar2(50),
CName varchar2(50),
Ph_num number,
Balance number(10,2),
current_status varchar2(10)
);
--current_status : new_user, active, inactive
create table Products(
Product_id number primary key,
PName varchar2(50),
Price number(10,2)
);
create table Outlets(
Outlet_id number Primary key,
Password varchar2(50),
location varchar2(50)
);
create table Outlet_Menus(
Outlet_id number references Outlets(Outlet_id),
Product_id number references Products(Product_id)
);
create table Bills(
Bill_id number Primary key,
Card_id number references Customers(Card_id),
Outlet_ID number references Outlets(Outlet_id),
Amount number(10,2),
Bill_Date date
);
create table Purchases(
Bill_id number references Bills(Bill_id),
Product_id number references Products(Product_id),
Quantity number
);
create table Fin_transaction(
Trans_id number primary key,
Card_id number references Customers(Card_id),
Type varchar2(10),
Amount number,
Trans_date date
);
create sequence c_id_seq start with 1 increment by 1 minvalue 0;
create sequence o_id_seq start with 1 increment by 1 minvalue 0;
create sequence b_id_seq start with 1 increment by 1 minvalue 0;
create sequence t_id_seq start with 1 increment by 1 minvalue 0;
create sequence p_id_seq start with 1 increment by 1 minvalue 0;
--Outlet creates customer
create or replace procedure add_customer (CName varchar2, Phone_num in number, status out number)
as
num_unique number;
begin
status := 0;
if(Phone_num > 9999999999 OR Phone_num < 1000000000) then
status := 2;
return;
end if;
select count(*) into num_unique from Customers where Ph_num = Phone_num;
if(num_unique > 0) then
status := 3;
return;
end if;
insert into Customers values(c_id_seq.nextval, 'unset', CName, Phone_num, 0, 'new_user');
status := 1;
return;
end;
/
-- Update password by user or user creates password for the first time
create or replace procedure update_password (Ph_no in number, new_pwd in varchar2, status out number)
is
begin
status := 0;
update customers set Password = new_pwd where Ph_num = Ph_no;
status :=1;
return;
end;
/
create or replace procedure match_username (Phone_num in number, pwd out varchar2, status out number)
is
begin
status := 1;
if (Phone_num > 9999999999 OR Phone_num < 1000000000) then
status := 2;
return;
end if;
select count(*) into status from Customers where Ph_num = Phone_num;
if (status = 1) then
select password into pwd from Customers where Ph_num = Phone_num;
end if;
return;
end;
/
create or replace procedure login_user (Phone_num in number, status out number)
is
begin
status := 0;
update Customers set current_status = 'active' where Ph_num = Phone_num;
status := 1;
return;
end;
/
create or replace procedure logout_user (Phone_num in number, status out number)
is
begin
status := 0;
update Customers set current_status = 'inactive' where Ph_num = Phone_num;
status := 1;
return;
end;
/
create or replace procedure add_product (PName in varchar2, Price in number, status out number)
is
begin
status := 0;
insert into Products values(p_id_seq.nextval, PName, Price);
status := 1;
return;
end;
/
create or replace procedure update_price (P_id in number, new_price in number(10,2), status out number)
is
begin
status := 0;
update Products set price = new_price where Product_id = P_id;
status := 1;
return;
end;
/
create or replace procedure create_outlet (location in varchar2, pwd in varchar2, status out number)
is
begin
status := 0;
insert into Outlets values(o_id_seq.nextval, pwd, location);
status := 1;
return;
end;
/
create or replace procedure delete_outlet (O_id in number, status out number)
is
begin
status := 0;
delete Outlets where Outlet_id=O_id;
status := 1;
return;
end;
/
CREATE OR REPLACE TYPE MyType AS VARRAY(200) OF VARCHAR2(50);
/
create or replace type number_array as varray(100) of number;
/
create or replace procedure gen_bill (outlet_id in number, c_id in number, prods in number_array, qty in number_array, bill_id out number, status out number)
as
amount number(10,2);
prc number(10,2);
bal number(10,2);
begin
status := 0;
amount := 0;
for i in 1..prods.count loop
select price into prc from Products where Product_id = prods(i);
amount:= amount + qty(i)*prc;
end loop;
select Balance into bal from Customers where Card_id = c_id;
if (amount < bal) then
status := 2;
return;
end if;
bill_id := b_id_seq.nextval;
insert into Bills values(bill_id, c_id, outlet_id, amount, sysdate);
update Customers set Balance = Balance - amount where Card_id = c_id;
for i in 1..prods.count loop
insert into Purchases values(bill_id, prods(i), qty(i));
end loop;
status := 1;
end;
/
create or replace trigger reward
before insert on Bills
for each row
declare
bill_cnt number;
begin
select count(*) into bill_cnt from Bills where Card_id = :new.Card_id;
if (bill_cnt%2 = 0) then
insert into Fin_transaction values(t_id_seq.nextval, :new.Card_id, 'r', min(100, 0.02*:new.amount), sysdate);
end if;
end;
/
create or replace trigger sync_bal
before insert on Fin_transaction
for each row
declare
avail_bal number;
begin
select Balance into avail_bal from Customers where Card_id = :new.Card_id;
if (:new.type = 'w') then
if(avail_bal < :new.amount) then
raise_application_error(-20000, 'Insufficient Balance.');
else
update Customers set Balance = Balance - :new.amount where Card_id = :new.Card_id;
end if;
else
update Customers set Balance = Balance + :new.amount where Card_id = :new.Card_id;
end if;
end;
/