Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On-Demand Report backend #226

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion backend/sql/create_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ CREATE TABLE Person (
PRIMARY KEY (person_id)
);

CREATE TYPE trans_type AS ENUM ('donation', 'purchase', 'throw out' );
CREATE TYPE trans_type AS ENUM ('donation', 'purchase', 'throw out', 'checkout');
CREATE TABLE Transaction (
trans_id serial,
person_id int,
Expand Down
6 changes: 5 additions & 1 deletion backend/sql/dummy_data2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ WHERE email = '[email protected]';
INSERT INTO Transaction (person_id, date, trans_type, site)
VALUES ((SELECT MAX(person_id) FROM Person), NOW(), 'donation', 1),
-- Add old transaction with goods that have been expiring.
((SELECT MIN(person_id) FROM Person), NOW() - INTERVAL '3 weeks', 'donation', 1);
((SELECT MAX(person_id) FROM Person), NOW() - INTERVAL '3 weeks', 'donation', 1),
-- Add three purchase transactions of same person_id:
((SELECT MAX(person_id) FROM Person), NOW(), 'checkout', 1),
((SELECT MAX(person_id) FROM Person), NOW(), 'checkout', 1),
((SELECT MAX(person_id) FROM Person), NOW(), 'checkout', 1);

-- Insert test data for Trans_items
INSERT INTO Trans_items (trans_id, item_id, quantity, expiration)
Expand Down
61 changes: 61 additions & 0 deletions backend/sql/dummy_data3.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
-- Insert test data for Shelf
INSERT INTO Shelf (section_id, capacity)
VALUES ((SELECT MAX(section_id) FROM Section), 10),
((SELECT MAX(section_id) FROM Section), 5),
((SELECT MAX(section_id) FROM Section)-1, 7),
((SELECT MAX(section_id) FROM Section)-1, 15);

-- Insert test data for Aisle
INSERT INTO Aisle (site_id, info)
VALUES ((SELECT MAX(site_id) FROM Site), 'Fruit Aisle');

-- Insert test data for Section
INSERT INTO Section (aisle_id, stor_id)
VALUES ((SELECT MAX(aisle_id) FROM Aisle), (SELECT MAX(stor_id) FROM Storage_type)-2),
((SELECT MAX(aisle_id) FROM Aisle), (SELECT MAX(stor_id) FROM Storage_type)-2);

-- Insert test data for Shelf
INSERT INTO Shelf (section_id, capacity)
VALUES ((SELECT MAX(section_id) FROM Section), 10),
((SELECT MAX(section_id) FROM Section), 5),
((SELECT MAX(section_id) FROM Section)-1, 7),
((SELECT MAX(section_id) FROM Section)-1, 15);

-- Insert test data for Permissions
INSERT INTO Permissions (perm_num, description)
VALUES (1, 'Can view inventory'),
(2, 'Can edit inventory');

-- Insert test data for Empl_info
INSERT INTO Empl_info (perm_id, role)
VALUES ((SELECT MAX(perm_id) FROM Permissions), 'volunteer');

UPDATE Person SET empl_id = (SELECT MAX(empl_id) FROM Empl_info)
WHERE email = '[email protected]';

-- Insert test data for Transaction
INSERT INTO Transaction (person_id, date, trans_type, site)
VALUES ((SELECT MIN(person_id) FROM Person), NOW(), 'donation', 1),
-- Add three purchase transactions of same person_id:
((SELECT MIN(person_id) FROM Person), NOW(), 'checkout', 1),
((SELECT MIN(person_id) FROM Person), NOW(), 'checkout', 1),
((SELECT MIN(person_id) FROM Person), NOW(), 'checkout', 1);

-- Insert test data for Trans_items
INSERT INTO Trans_items (trans_id, item_id, quantity, expiration)
VALUES ((SELECT MIN(trans_id) FROM Transaction), 6, 7, NOW() + INTERVAL '3 weeks'),
((SELECT MIN(trans_id) FROM Transaction), 5, 5, NOW() + INTERVAL '1 week'),
-- Donate goods that expired 3 weeks ago, 1 week ago, and 1 week from now.
-- Old apples
((SELECT MAX(trans_id) FROM Transaction), 2, 10, NOW() - INTERVAL '2 weeks'),
-- Old oranges
((SELECT MAX(trans_id) FROM Transaction), 1, 3, NOW() - INTERVAL '3 weeks'),
-- Nearly old Milk
((SELECT MAX(trans_id) FROM Transaction), 4, 2, NOW() + INTERVAL '5 days');

-- Insert test data for Shelf_contents
INSERT INTO Shelf_contents (trans_item_id, shelf_id, store_date, quantity)
VALUES ((SELECT MAX(trans_item_id) FROM Trans_items), (SELECT MAX(shelf_id) FROM Shelf), NOW(), 10),
((SELECT MAX(trans_item_id) FROM Trans_items), (SELECT MAX(shelf_id) FROM Shelf), NOW(), 15);

REFRESH MATERIALIZED VIEW stock;
3 changes: 3 additions & 0 deletions backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ app.get('/feed', feedRouter);
app.get('/items', itemsRouter);
app.get('/items/expired', itemsRouter);
app.get('/items/nearly_expired', itemsRouter);
app.get('/items/total_donations', itemsRouter);
app.get('/items/total_checkouts', itemsRouter);
app.get('/items/unique_checkouts', itemsRouter);

app.get('/donors', donorRouter);
app.get('/lookupDonor', donorRouter);
Expand Down
54 changes: 25 additions & 29 deletions backend/src/routes/barcode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,43 @@ const axiosInstance = axios.create({
baseURL: "https://world.openfoodfacts.org/api/v2",
timeout: 3000
});



async function UPC_lookup(barcode: string) {
try {
var scannedItem = await axiosInstance.get('/search', {params: {code: barcode}});
var product_name = scannedItem.data.products[0].product_name_en;
return product_name;
} catch (error) {
console.error(error);
return null;
}
try {
var scannedItem = await axiosInstance.get('/search', {params: {code: barcode}});
var product_name = scannedItem.data.products[0].product_name_en;
return product_name;
} catch (error) {
console.error(error);
return null;
}
}

async function PLU_lookup(barcode: string) {
let product = await item.LookUpbarcode(barcode);
if (product !== null){
return JSON.stringify(product);
}
else {
return null
}
let product = await item.LookUpbarcode(barcode);
if (product !== null){
return JSON.stringify(product);
} else {
return null
}
}

router.get('/barcode', ensureAuthenticated, async (req: any, res: any) => {
if (!req.isAuthenticated()) {
const errors = [];
res.post('Unauthenticated');
} else {
const barcode = req.query.barcode;
if (barcode.length > 4) {
const result = await UPC_lookup(barcode);
res.send(result);
} else if (barcode.length === 4) {
const result = await PLU_lookup(barcode);
res.send(result);
}
else {
return res.status(404).send('Item not found');
} else {
const barcode = req.query.barcode;
if (barcode.length > 4) {
const result = await UPC_lookup(barcode);
res.send(result);
} else if (barcode.length === 4) {
const result = await PLU_lookup(barcode);
res.send(result);
} else {
return res.status(404).send('Item not found');
}
}
}
});

module.exports = router;
212 changes: 153 additions & 59 deletions backend/src/routes/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,74 +11,168 @@ initModels(sequelize);

router.get('/items/expired', ensureAuthenticated, function (req, res) {
const today = new Date();
return trans_items.findAll({
where: {
expiration: {
[Op.lte]: today

if (!req.isAuthenticated()) {
res.post("Unauthenticated");
} else {
return trans_items.findAll({
where: {
expiration: {
[Op.lte]: today
}
},
include: [{
model: transaction,
as: 'tran',
required: true,
attributes: ['date']
}, {
model: item,
as: 'item',
required: true,
attributes: ['name']
}],
attributes: ['trans_item_id', 'quantity', 'expiration'],
}).then((allItems) => {
if (allItems == null) {
console.log("There are no items to return");
res.json(JSON.stringify([]));
} else {
res.json(JSON.stringify(allItems));
}
},
include: [{
model: transaction,
as: 'tran',
required: true,
attributes: ['date']
}, {
model: item,
as: 'item',
required: true,
attributes: ['name']
}],
attributes: ['trans_item_id', 'quantity', 'expiration'],
}).then((allItems) => {
if (allItems == null) {
console.log("There are no items to return");
res.json(JSON.stringify([]));
} else {
res.json(JSON.stringify(allItems));
}
}).catch(() => {
console.log("There was an error retrieving nearly-expired items");
res.status(400);
res.send();
});
}).catch(() => {
console.log("There was an error retrieving nearly-expired items");
res.status(400);
res.send();
});
}
});

router.get('/items/nearly_expired', ensureAuthenticated, function (req, res) {
const today = new Date();
const twoDaysFromNow = new Date();
twoDaysFromNow.setTime(today.getTime() + (1000 * 60 * 60 * 24 * 2));

return trans_items.findAll({
where: {
expiration: {
[Op.lte]: twoDaysFromNow,
[Op.gte]: today,
if (!req.isAuthenticated()) {
res.post("Unauthenticated");
} else {
return trans_items.findAll({
where: {
expiration: {
[Op.lte]: twoDaysFromNow,
[Op.gte]: today,
}
},
include: [{
model: transaction,
as: 'tran',
required: true,
attributes: ['date']
}, {
model: item,
as: 'item',
required: true,
attributes: ['name']
}],
attributes: ['trans_item_id', 'quantity', 'expiration'],
}).then((allItems) => {
if (allItems == null) {
console.log("There are no items to return");
res.json(JSON.stringify([]));
} else {
res.json(JSON.stringify(allItems));
}
}).catch(() => {
console.log("There was an error retrieving nearly-expired items");
res.status(400);
res.send();
});
}
});

router.get('/items/total_donations', ensureAuthenticated, function (req, res) {

if (!req.isAuthenticated()) {
res.post("Unauthenticated");
} else {
return trans_items.findAll({
include: [{
model: transaction,
as: 'tran',
required: true,
where: {
trans_type: 'donation'
}
}],
}).then((allItems) => {
if (allItems == null) {
console.log("There are no donated items to return");
res.json(JSON.stringify([]));
} else {
res.json(allItems);
}
}).catch(() => {
console.log("There was an error retrieving total donations");
res.status(400);
res.send();
});
}
});

router.get('/items/total_checkouts', ensureAuthenticated, function (req, res) {

if (!req.isAuthenticated()) {
res.post("Unauthenticated");
} else {
return trans_items.findAll({
include: [{
model: transaction,
as: 'tran',
required: true,
where: {
trans_type: 'purchase'
}
}],
}).then((allItems) => {
if (allItems == null) {
console.log("There are no checked-out items to return");
res.json(JSON.stringify([]));
} else {
res.json(allItems);
}
}).catch(() => {
console.log("There was an error retrieving total checkouts");
res.status(400);
res.send();
});
}
});

router.get('/items/unique_checkouts', ensureAuthenticated, function (req, res) {

if (!req.isAuthenticated()) {
res.post("Unauthenticated");
} else {
return transaction.findAll({
attributes: [[Sequelize.fn('DISTINCT', Sequelize.col('person_id')) ,'person_id']],
distinct: true,
col: 'person_id',
where: {
trans_type: 'checkout'
}
}).then((allItems) => {
if (allItems == null) {
console.log("There are no student check-outs to return");
res.json(JSON.stringify([]));
} else {
res.json(allItems);
}
},
include: [{
model: transaction,
as: 'tran',
required: true,
attributes: ['date']
}, {
model: item,
as: 'item',
required: true,
attributes: ['name']
}],
attributes: ['trans_item_id', 'quantity', 'expiration'],
}).then((allItems) => {
if (allItems == null) {
console.log("There are no items to return");
res.json(JSON.stringify([]));
} else {
res.json(JSON.stringify(allItems));
}
}).catch(() => {
console.log("There was an error retrieving nearly-expired items");
res.status(400);
res.send();
});
}).catch(() => {
console.log("There was an error retrieving unique student checkouts");
res.status(400);
res.send();
});
}
});

module.exports = router;
Loading