var push = require('../push/push'); var axios = require('axios') const { query, nonQuery } = require("../db-config/postgresql-common"); const stringSimilarity = require('string-similarity'); //Create User Info async function updateUser(uid, mid, name, picture, email) { try { await nonQuery('INSERT INTO "User" (username, name, picture, email, message_id) VALUES ($1, $2, $3, $4, $5);', [uid, name, picture, email, mid]); return 'done' } catch (error) { console.error(error); return error } } async function realUpdateUser(uid, mid, name, picture, email){ console.log("DBCONNECT UPDATE PIC: ", picture) try { await nonQuery('Update "User" set message_id = $1, name = $2, picture = $3, email = $4 WHERE username = $5', [mid, name, picture, email, uid]); return 'done' } catch (error){ console.error(error); return error } } async function getmessageids(sl_id) { try { let members = await query('SELECT row_to_json("User") AS obj FROM "Shoppinglist_member" JOIN "User" USING (username) WHERE sl_id = $1;', [sl_id]); let admin = await query('SELECT row_to_json("User") AS obj FROM "Shoppinglist_admin" JOIN "User" USING (username) WHERE sl_id = $1;', [sl_id]); return users_to_array(admin, members); } catch (error) { } } async function getUser(uid){ try { var users = await query('SELECT row_to_json("User") AS obj FROM "User" WHERE username = $1;', [uid]); return users; } catch (error) { console.error("Error", error); } } async function searchUsers(searchstring) { try { let users = await query('SELECT row_to_json("User") AS obj FROM "User";'); var output = []; for(let item of users) { if(item.name != null) { if(item.name.includes(searchstring)) { output.push(item); } } } return output; } catch (error) { console.error(error); } } //SELECT own shopping lists async function getShoppinglistsAdmin(username) { try { let result = await query('SELECT row_to_json("Shoppinglist") AS obj FROM "Shoppinglist" JOIN "Shoppinglist_admin" USING (sl_id) WHERE \ username = $1', [username]); return result; } catch (error) { console.error(error); } } //SELECT own shopping lists async function getShoppinglistsByLink(link) { try { console.log("PPPPP LIIINK:", link) let result = await query('SELECT row_to_json("Shoppinglist") AS obj FROM "Shoppinglist" WHERE invitelink = $1', [link]); return result; } catch (error) { console.error(error); } } //SELECT shared shopping lists async function getShoppinglistsShared(username) { try { let result = await query('SELECT row_to_json("Shoppinglist") AS obj FROM "Shoppinglist" JOIN "Shoppinglist_member" USING (sl_id) WHERE username = $1;', [username]); console.log(result); return result; } catch (error) { console.error(error); } } //INSERT new Shoppinglist async function newShoppinglist(name, description, username, color) { //generate sl_id let sl_id = genID(10); //insert user if not exists try { await nonQuery('INSERT INTO "User" (username) VALUES ($1);', [username]); } catch (error) { console.error(error); } //insert shoppinglist try { await nonQuery('INSERT INTO "Shoppinglist" (sl_id, name, description, color) VALUES ($1, $2, $3, $4);', [sl_id, name, description, color]); } catch (error) { console.error(error); } //insert admin try { await nonQuery('INSERT INTO "Shoppinglist_admin" (username, sl_id) VALUES ($1, $2);', [username, sl_id]); } catch (error) { console.error(error); } return getShoppinglistsAdmin(username); } //rename Shoppinglist async function editShoppinglist(sl_id, newname, newdescription, newcolor, uid) { try { let shoppinglist = await query('SELECT row_to_json("Shoppinglist") AS obj FROM "Shoppinglist" WHERE sl_id = $1;', [sl_id]); if (shoppinglist.name != newname && newname != undefined) { await nonQuery('UPDATE "Shoppinglist" SET name = $1 WHERE sl_id = $2;', [newname, sl_id]); } if (shoppinglist.description != newdescription && newdescription != undefined) { await nonQuery('UPDATE "Shoppinglist" SET description = $1 WHERE sl_id = $2;', [newdescription, sl_id]); } if (shoppinglist.color != newcolor && newcolor != undefined) { await nonQuery('UPDATE "Shoppinglist" SET color = $1 WHERE sl_id = $2;', [newcolor, sl_id]); } return getShoppinglistsAdmin(uid); } catch (error) { console.error(error); } } /*async function generateUser() { //insert user try { await nonQuery('INSERT INTO "User" (username) VALUES ($1);', [username]); } catch (error) { console.error(error); } }*/ //get shoppinglist content async function displayShoppinglist(sl_id) { try { let shoppinglist = await query('SELECT row_to_json("Shoppinglist") AS obj FROM "Shoppinglist" WHERE sl_id = $1;', [sl_id]); let groups = await query('SELECT row_to_json("Group") AS obj FROM "Group" JOIN "Shoppinglist" USING (sl_id) WHERE sl_id = $1;', [sl_id]); let items = await query('SELECT row_to_json("Item") AS obj FROM "Item" JOIN "Group" USING (group_id) WHERE "Group".sl_id = $1;', [sl_id]); let members = await query('SELECT row_to_json("User") as obj FROM "User" JOIN "Shoppinglist_member" USING (username) WHERE sl_id = $1', [sl_id]); let admin = await query('SELECT row_to_json("User") as obj FROM "User" JOIN "Shoppinglist_admin" USING (username) WHERE sl_id = $1', [sl_id]); return items_in_groups(groups, items, sl_id, admin, members, shoppinglist[0].name, shoppinglist[0].description, shoppinglist[0].invitelink, shoppinglist[0].color); } catch (error) { console.error(error); } } //delete shoppinglist async function deleteShoppinglist(sl_id,uid) { try { await nonQuery('DELETE FROM "Shoppinglist_admin" WHERE sl_id = $1', [sl_id]); await nonQuery('DELETE FROM "Shoppinglist_member" WHERE sl_id = $1', [sl_id]); await nonQuery('DELETE FROM "Group" WHERE sl_id = $1', [sl_id]); await nonQuery('DELETE FROM "Item" WHERE sl_id = $1', [sl_id]); await nonQuery('DELETE FROM "Shoppinglist" WHERE sl_id = $1', [sl_id]); return getShoppinglistsAdmin(uid); } catch (error) { console.error(error); } } //add group into shoppinglist async function addGroup(sl_id, name, color, hidden) { try { let grid = genID(10); await nonQuery('INSERT INTO "Group" (group_id, sl_id, name, color, hidden) VALUES ($1, $2, $3, $4, $5);', [grid, sl_id, name, color, hidden]); } catch (error) { console.error(error); } push.sendMultiplePush(await getmessageids(sl_id), "Gruppe wurde hinzugefügt!", "Die Gruppe " + name + " wurde hinzugefügt!"); return displayShoppinglist(sl_id); } //add item into group async function addItem(group_id, sl_id, name, count) { try { let itid = genID(10) await nonQuery('INSERT INTO "Item" VALUES ($1, $2, $3, $4, $5);', [itid, group_id, sl_id, name, count]); } catch (error) { console.error(error); } push.sendMultiplePush(await getmessageids(sl_id), "Item wurde hinzugefügt!", "Das Item " + name + " wurde hinzugefügt!"); return displayShoppinglist(sl_id); } //Edit Group async function editGroup(sl_id, group_id, name, color, hidden) { try { let group = await query('SELECT row_to_json("Group") AS obj FROM "Group" WHERE group_id = $1 AND sl_id = $2', [sl_id, group_id]); if (group.name != name && name != undefined) { await nonQuery('UPDATE "Group" SET name = $1 WHERE group_id = $2 AND sl_id = $3;', [name, group_id, sl_id]); } if (group.color != color && color != undefined) { await nonQuery('UPDATE "Group" SET color = $1 WHERE group_id = $2 AND sl_id = $3;', [color, group_id, sl_id]); } if (group.hidden != hidden && hidden != undefined) { await nonQuery('UPDATE "Group" SET hidden = $1 WHERE group_id = $2 AND sl_id = $3;', [hidden, group_id, sl_id]); } return displayShoppinglist(sl_id); } catch (error) { console.error(error); } push.sendMultiplePush(await getmessageids(sl_id), "Gruppe wurde bearbeitet!", "Die Gruppe " + name + " wurde bearbeitet!"); } //Edit Item async function editItem(sl_id, group_id, item_id, name, count) { try { let item = query('SELECT row_to_json("Item") FROM "Item" WHERE item_id = $1 AND group_id = $2 AND sl_id = $3', [item_id, group_id, sl_id]); if (item.name != name && name != undefined) { await nonQuery('UPDATE "Item" SET name = $1 WHERE item_id = $2 AND group_id = $3 AND sl_id = $4', [name, item_id, group_id, sl_id]); } if (item.count != count && count != undefined) { await nonQuery('UPDATE "Item" SET count = $1 WHERE item_id = $2 AND group_id = $3 AND sl_id = $4', [count, item_id, group_id, sl_id]); } return displayShoppinglist(sl_id); } catch (error) { console.error(error); } push.sendMultiplePush(await getmessageids(sl_id), "Item wurde bearbeitet!", "Das Item " + name + " wurde bearbeitet!"); } //Delete Group async function deleteGroup(group_id, sl_id) { try { //Alle Items der Group löschen nonQuery('DELETE FROM "Item" WHERE group_id = $1 AND sl_id = $2', [group_id, sl_id]); //Leere Gruppe löschen nonQuery('DELETE FROM "Group" WHERE group_id = $1 AND sl_id = $2', [group_id, sl_id]); } catch (error) { console.error(error); } // push.sendMultiplePush(await getmessageids(sl_id), "Gruppe wurde gelöscht!", "Die Gruppe " + name + " wurde gelöscht!"); return displayShoppinglist(sl_id); } //Delete Item async function deleteItem(item_id, group_id, sl_id) { try { nonQuery('DELETE FROM "Item" WHERE item_id = $1 AND group_id = $2 AND sl_id = $3;', [item_id, group_id, sl_id]); } catch (error) { console.error(error); } //push.sendMultiplePush(await getmessageids(sl_id), "Item wurde gelöscht!", "Das Item " + name + " wurde gelöscht!"); return displayShoppinglist(sl_id); } //Move to Done Purchases (delete items from shoppinglist & move into done_purchases table) async function moveDoneItems(uid, sl_id, billcontent) { try { //Get Items From Shoppinglist let items = await query('SELECT row_to_json("Item") AS obj FROM "Item" JOIN "Group" USING (group_id) WHERE "Group".sl_id = $1;', [sl_id]); let removeableItems = compareData(items, billcontent); var today = new Date(); var dd = today.getDate(); var mm = today.getMonth() + 1; var yyyy = today.getFullYear(); if (dd < 10) { dd = '0' + dd } if (mm < 10) { mm = '0' + mm } today = mm + '/' + dd + '/' + yyyy; for (let item of removeableItems) { await nonQuery('INSERT INTO "Done_Purchase" (purchased_item_id, username, name, date, count) VALUES($1,$2,$3,$4,$5);', [genID(10), uid, item.item.name, today, item.count]); } for (let item of removeableItems) { await nonQuery('DELETE FROM "Item" WHERE item_id = $1 AND group_id = $2 AND sl_id = $3;', [item.item_id, item.group_id, item.sl_id]); console.log(item); } return "done" } catch (error) { console.error(error); } } async function moveDoneItemMan(uid, sl_id, group_id, item_id) { try { let item = await query('SELECT row_to_json("Item") as obj FROM "Item" WHERE item_id = $3 AND group_id = $2 AND sl_id = $1', [sl_id, group_id, item_id]); var today = new Date(); var dd = today.getDate(); var mm = today.getMonth() + 1; var yyyy = today.getFullYear(); if (dd < 10) { dd = '0' + dd } if (mm < 10) { mm = '0' + mm } today = mm + '/' + dd + '/' + yyyy; await nonQuery('INSERT INTO "Done_Purchase" (purchased_item_id, username, name, date, count) VALUES($1,$2,$3,$4,$5);', [genID(10), uid, item[0].name, today, item[0].count]); await nonQuery('DELETE FROM "Item" WHERE item_id = $1 AND group_id = $2 AND sl_id = $3;', [item_id, group_id, sl_id]); return await { shoppinglist: await displayShoppinglist(sl_id), doneitems: await getDonePurchases(uid) } } catch(error) { console.error(error); } } //GET Done_Purchases async function getDonePurchases(uid) { try { let result = await query('SELECT row_to_json("Done_Purchase") AS obj FROM "Done_Purchase" WHERE username = $1;', [uid]); return result; } catch (error) { console.error(error); } } async function getUserDB(uid) { try { let user = await query('SELECT row_to_json("User") AS obj FROM "User" WHERE username = $1;', [uid]); return user; } catch (error) { console.error("Error", error); } } async function deleteDonePurchase(pid, uid) { try { await nonQuery('DELETE FROM "Done_Purchase" WHERE purchased_item_id = $1 ', [pid]); return getDonePurchases(uid); } catch (error) { console.error("Error", error); } } // Invite System async function verifyInvite(link, user_id) { try { console.log("LIIINK: ", link); console.log("UID: ", user_id); let result = await query('SELECT row_to_json("Shoppinglist") AS obj FROM "Shoppinglist" WHERE invitelink = $1;', [link]); let sl_id = result[0].sl_id; console.log("!!! SL ID: ", sl_id); await nonQuery('INSERT INTO "Shoppinglist_member" (username, sl_id) VALUES ($1, $2);', [user_id, sl_id]); } catch (error) { console.error(error); } } async function createInvite(sl_id) { try { let output = generateInviteLink(sl_id); var link; axios({ method: 'POST', url: 'https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=AIzaSyCuvwf78cmSDoZ2yS4XxHZhnjUn7yIHYfw', data: { "dynamicLinkInfo": { "domainUriPrefix": "https://invite.dergeorg.at/invite", "link": "https://smartshopper.cf/invite/" + output+"?slid="+sl_id, "androidInfo": { "androidPackageName": "at.smartshopper.smartshopperapp" } } } }) .then(async function(result) { console.log("ShortLink: ", result.data.shortLink); link = result.data.shortLink; link= link.replace("https://invite.dergeorg.at/invite/", ""); console.log("generated link: ", link, " \nSL_id ", sl_id) await nonQuery('UPDATE "Shoppinglist" SET invitelink = $1, dynamiclink = $2 WHERE sl_id = $3;', [output, link, sl_id]); return result.data.shortLink; }) .catch(err => console.error(err)); } catch (error) { console.error(error); } } //Create invite link for your own shoppinglist function generateInviteLink(actsl_id) { var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var output = ""; for (let i = 0; i < 50; i++) { output += possible.charAt(Math.floor(Math.random() * possible.length)); } return output } //User manuell einladen async function manInvite(sl_id, uid) { try { await nonQuery('INSERT INTO "Shoppinglist_member" (username, sl_id) VALUES ($1, $2);', [uid, sl_id]); } catch (error) { console.error(error); } } //member von shoppinglist entfernen async function removeMember(uid, sl_id) { console.log(uid, " ", sl_id) try { await nonQuery('DELETE FROM "Shoppinglist_member" WHERE username = $1 AND sl_id = $2', [uid, sl_id]); return await displayShoppinglist(sl_id); } catch (error) { console.error(error); } } //Random ID generate function genID(length) { var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var output = ""; for (let i = 0; i < length; i++) { output += possible.charAt(Math.floor(Math.random() * possible.length)); } return output; } function items_in_groups(groups, items, sl_id, sl_admin, sl_members, name, description, invitelink, color) { let result = { sl_id: sl_id, name: name, description: description, invitelink: invitelink, color: color, admin: { username: sl_admin[0].username, email: sl_admin[0].email, name: sl_admin[0].name, picture: sl_admin[0].picture, message_id: sl_admin[0].message_id }, members: sl_members, groups: [] }; for (let item of groups) { result.groups.push({ group_id: item.group_id, name: item.name, color: item.color, content: items.filter(function (obj) { return obj.group_id == item.group_id }) }); } return result; } function users_to_array(admin, members) { let users = []; users.push(admin[0].message_id); for (let item of members) { users.push(item.message_id); } return users; } //Compare Data function compareData(listitems, doneitems) { let output = []; for (let item of listitems) { if (probability(item.name, doneitems).best > 0.6) { output.push({item: item, count: probability(item.name, doneitems).count}); } else if (probability(item.name.toUpperCase(), doneitems.toUpperCase()).best > 0.6) { output.push({item: item, count: probability(item.name, doneitems).count}); output.push(item); } else if (probability(item.name.toLowerCase(), doneitems.toLowerCase()).best > 0.6) { output.push({item: item, count: probability(item.name, doneitems).count}); output.push(item); } } return output; } function probability(cur_item, data) { let best = 0; let pos; let count = 0; let numbers = "123456789"; for (let i = 0; i < data.length; i++) { let prob = stringSimilarity.compareTwoStrings(cur_item, data.slice(i, i + cur_item.length)); if (prob > best) { best = prob; pos = i; } } for(let i = pos; i >= 0; i--) { if(numbers.includes(data.charAt(i)) == true) { count = data.charAt(i); break; } } return { best: best, count: count }; } module.exports = { getShoppinglistsAdmin, getShoppinglistsShared, newShoppinglist, displayShoppinglist, deleteShoppinglist, addGroup, addItem, verifyInvite, createInvite, editShoppinglist, editGroup, editItem, deleteGroup, deleteItem, manInvite, updateUser, moveDoneItems, getDonePurchases, getShoppinglistsByLink, searchUsers, removeMember, moveDoneItemMan, getUser, getUserDB, realUpdateUser, deleteDonePurchase }