diff --git a/.eslintrc.js b/.eslintrc.js
index b679b6fa9..84311232b 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -16,4 +16,12 @@ module.exports = {
rules: {
"prettier/prettier": "error",
},
+ settings: {
+ react: {
+ // Version checking of react. Default is "detect", which
+ // fails at the root directory, since react is not installed
+ // here. Providing a dummy number supresses the warning
+ version: "16.0",
+ },
+ },
};
diff --git a/app/services/stakeholder-best-service.js b/app/services/stakeholder-best-service.js
index 995a703d7..a9b94e653 100644
--- a/app/services/stakeholder-best-service.js
+++ b/app/services/stakeholder-best-service.js
@@ -68,9 +68,11 @@ const search = async ({
s.donation_delivery_instructions, s.donation_notes, s.covid_notes,
s.category_notes, s.eligibility_notes, s.food_types, s.languages,
s.v_name, s.v_categories, s.v_address, s.v_phone, s.v_email,
- s.v_hours, s.verification_status_id, s.inactive_temporary,
+ s.v_hours, s.v_food_types, s.verification_status_id, s.inactive_temporary,
array_to_json(s.hours) as hours, s.category_ids,
s.neighborhood_id, s.is_verified,
+ s.food_bakery, s.food_dry_goods, s.food_produce,
+ s.food_dairy, s.food_prepared, s.food_meat,
${locationClause ? `${locationClause} AS distance,` : ""}
${buildLoginSelectsClause()}
from stakeholder_set as s
@@ -180,6 +182,12 @@ const search = async ({
covidNotes: row.covid_notes || "",
categoryNotes: row.category_notes || "",
eligibilityNotes: row.eligibility_notes || "",
+ foodBakery: row.food_bakery,
+ foodDryGoods: row.food_dry_goods,
+ foodProduce: row.food_produce,
+ foodDairy: row.food_dairy,
+ foodPrepared: row.food_prepared,
+ foodMeat: row.food_meat,
foodTypes: row.food_types || "",
languages: row.languages || "",
confirmedName: row.v_name,
@@ -188,6 +196,7 @@ const search = async ({
confirmedPhone: row.v_phone,
confirmedEmail: row.v_email,
confirmedHours: row.v_hours,
+ confirmedFoodTypes: row.v_food_types,
verificationStatusId: row.verification_status_id,
inactiveTemporary: row.inactive_temporary,
neighborhoodId: row.neighborhood_id,
@@ -231,8 +240,10 @@ const selectById = async (id) => {
s.donation_delivery_instructions, s.donation_notes, s.covid_notes,
s.category_notes, s.eligibility_notes, s.food_types, s.languages,
s.v_name, s.v_categories, s.v_address, s.v_phone, s.v_email,
- s.v_hours, s.verification_status_id, s.inactive_temporary,
+ s.v_hours, s.v_food_types, s.verification_status_id, s.inactive_temporary,
s.neighborhood_id, s.is_verified,
+ s.food_bakery, s.food_dry_goods, s.food_produce,
+ s.food_dairy, s.food_prepared, s.food_meat,
${buildLoginSelectsClause()}
from stakeholder_best s
${buildLoginJoinsClause()}
@@ -303,6 +314,12 @@ const selectById = async (id) => {
covidNotes: row.covid_notes || "",
categoryNotes: row.category_notes || "",
eligibilityNotes: row.eligibility_notes || "",
+ foodBakery: row.food_bakery,
+ foodDryGoods: row.food_dry_goods,
+ foodProduce: row.food_produce,
+ foodDairy: row.food_dairy,
+ foodPrepared: row.food_prepared,
+ foodMeat: row.food_meat,
foodTypes: row.food_types || "",
languages: row.languages || "",
confirmedName: row.v_name,
@@ -311,6 +328,7 @@ const selectById = async (id) => {
confirmedPhone: row.v_phone,
confirmedEmail: row.v_email,
confirmedHours: row.v_hours,
+ confirmedFoodTypes: row.v_food_types,
verificationStatusId: row.verification_status_id,
inactiveTemporary: row.inactive_temporary,
neighborhoodId: row.neighborhood_id,
diff --git a/app/services/stakeholder-log-service.js b/app/services/stakeholder-log-service.js
index dfa9d7bcc..308b7151c 100644
--- a/app/services/stakeholder-log-service.js
+++ b/app/services/stakeholder-log-service.js
@@ -31,8 +31,10 @@ const selectById = async (id) => {
s.donation_delivery_instructions, s.donation_notes, s.covid_notes,
s.category_notes, s.eligibility_notes, s.food_types, s.languages,
s.v_name, s.v_categories, s.v_address, s.v_phone, s.v_email,
- s.v_hours, s.verification_status_id, s.inactive_temporary,
+ s.v_hours, s.v_food_types, s.verification_status_id, s.inactive_temporary,
s.neighborhood_id,
+ s.food_bakery, s.food_dry_goods, s.food_produce,
+ s.food_dairy, s.food_prepared, s.food_meat,
${buildLoginSelectsClause()}
from stakeholder_log s
${buildLoginJoinsClause()}
@@ -107,11 +109,18 @@ const selectById = async (id) => {
confirmedPhone: row.v_phone,
confirmedEmail: row.v_email,
confirmedHours: row.v_hours,
+ confirmedFoodTypes: row.v_food_types,
verificationStatusId: row.verification_status_id,
inactiveTemporary: row.inactive_temporary,
neighborhoodId: row.neighborhood_id,
neighborhoodName: row.neighborhood_name,
completeCriticalPercent: row.complete_critical_percent,
+ foodBakery: row.food_bakery,
+ foodDryGoods: row.food_dry_goods,
+ foodProduce: row.food_produce,
+ foodDairy: row.food_dairy,
+ foodPrepared: row.food_prepared,
+ foodMeat: row.food_meat,
});
});
diff --git a/app/services/stakeholder-service.js b/app/services/stakeholder-service.js
index 694a0d63b..19254c574 100644
--- a/app/services/stakeholder-service.js
+++ b/app/services/stakeholder-service.js
@@ -86,10 +86,12 @@ const search = async ({
as claimed_date, s.claimed_login_id,
s.requirements, s.admin_notes, s.inactive, s.email, s.covid_notes,
s.v_name, s.v_categories, s.v_address, s.v_phone, s.v_email,
- s.v_hours, s.verification_status_id, s.inactive_temporary,
+ s.v_hours, s.v_food_types, s.verification_status_id, s.inactive_temporary,
s.neighborhood_id, n.name as neighborhood_name,
s.complete_critical_percent,
${locationClause ? `${locationClause} AS distance,` : ""}
+ s.food_bakery, s.food_dry_goods, s.food_produce,
+ s.food_dairy, s.food_prepared, s.food_meat,
${buildLoginSelectsClause()}
from stakeholder_set as s
left outer join neighborhood n on s.neighborhood_id = n.id
@@ -199,11 +201,18 @@ const search = async ({
confirmedPhone: row.v_phone,
confirmedEmail: row.v_email,
confirmedHours: row.v_hours,
+ confirmedFoodTypes: row.v_food_types,
verificationStatusId: row.verification_status_id,
inactiveTemporary: row.inactive_temporary,
neighborhoodId: row.neighborhood_id,
neighborhoodName: row.neighborhood_name,
completeCriticalPercent: row.complete_critical_percent,
+ foodBakery: row.food_bakery,
+ foodDryGoods: row.food_dry_goods,
+ foodProduce: row.food_produce,
+ foodDairy: row.food_dairy,
+ foodPrepared: row.food_prepared,
+ foodMeat: row.food_meat,
});
});
@@ -249,8 +258,10 @@ const selectById = async (id) => {
s.donation_delivery_instructions, s.donation_notes, s.covid_notes,
s.category_notes, s.eligibility_notes, s.food_types, s.languages,
s.v_name, s.v_categories, s.v_address, s.v_phone, s.v_email,
- s.v_hours, s.verification_status_id, s.inactive_temporary,
+ s.v_hours, s.v_food_types, s.verification_status_id, s.inactive_temporary,
s.neighborhood_id,
+ s.food_bakery, s.food_dry_goods, s.food_produce,
+ s.food_dairy, s.food_prepared, s.food_meat,
${buildLoginSelectsClause()}
from stakeholder s
${buildLoginJoinsClause()}
@@ -329,9 +340,16 @@ const selectById = async (id) => {
confirmedPhone: row.v_phone,
confirmedEmail: row.v_email,
confirmedHours: row.v_hours,
+ confirmedFoodTypes: row.v_food_types,
verificationStatusId: row.verification_status_id,
inactiveTemporary: row.inactive_temporary,
neighborhoodId: row.neighborhood_id,
+ foodBakery: row.food_bakery,
+ foodDryGoods: row.food_dry_goods,
+ foodProduce: row.food_produce,
+ foodDairy: row.food_dairy,
+ foodPrepared: row.food_prepared,
+ foodMeat: row.food_meat,
};
// Don't have a distance, since we didn't specify origin
@@ -541,8 +559,15 @@ const insert = async (model) => {
confirmedPhone,
confirmedEmail,
confirmedHours,
+ confirmedFoodTypes,
verificationStatusId,
inactiveTemporary,
+ foodBakery,
+ foodDryGoods,
+ foodProduce,
+ foodDairy,
+ foodPrepared,
+ foodMeat,
} = model;
try {
let hoursSqlValues = hours.length
@@ -562,66 +587,71 @@ const insert = async (model) => {
// (ARRAY['(2,Wed,13:02,13:04)', '(3,Thu,07:00,08:00)'])::stakeholder_hours[]); --array of stakeholder_hours
// objects, which are defined as a postgres type (see repo file for more detail on this type).
const invokeSprocSql = `CALL create_stakeholder(
- ${toSqlNumeric(0)}::INT,
- ${toSqlNumeric(tenantId)}::INT,
- ${toSqlString(name)}::VARCHAR, ${toSqlString(
- address1
- )}::VARCHAR, ${toSqlString(address2)}::VARCHAR,
- ${toSqlString(city)}::VARCHAR, ${toSqlString(
- state
- )}::VARCHAR, ${toSqlString(zip)}::VARCHAR,
- ${toSqlString(phone)}::VARCHAR,
- ${toSqlNumeric(latitude)}::NUMERIC, ${toSqlNumeric(longitude)}::NUMERIC,
- ${toSqlString(website)}::VARCHAR, ${toSqlBoolean(inactive)},
- ${toSqlString(notes)}::VARCHAR, ${toSqlString(requirements)}::VARCHAR,
- ${toSqlString(adminNotes)}::VARCHAR, ${toSqlNumeric(loginId)}::INT,
- ${toSqlString(parentOrganization)}::VARCHAR, ${toSqlString(
- physicalAccess
- )}::VARCHAR,
- ${toSqlString(email)}::VARCHAR, ${toSqlString(items)}::VARCHAR,
- ${toSqlString(services)}::VARCHAR, ${toSqlString(facebook)}::VARCHAR,
- ${toSqlString(twitter)}::VARCHAR, ${toSqlString(pinterest)}::VARCHAR,
- ${toSqlString(linkedin)}::VARCHAR, ${toSqlString(description)}::VARCHAR,
- ${toSqlTimestamp(submittedDate)}::TIMESTAMPTZ, ${toSqlNumeric(
- submittedLoginId
- )}::INT,
- ${toSqlTimestamp(approvedDate)}::TIMESTAMP,
- ${toSqlNumeric(reviewedLoginId)}::INT,
- ${toSqlTimestamp(assignedDate)}::TIMESTAMP, ${toSqlNumeric(
- assignedLoginId
- )}::INT,
- ${toSqlTimestamp(claimedDate)}::TIMESTAMP, ${toSqlNumeric(
- claimedLoginId
- )}::INT,
- ${toSqlString(reviewNotes)}::VARCHAR, ${toSqlString(instagram)}::VARCHAR,
- ${toSqlString(adminContactName)}::VARCHAR, ${toSqlString(
- adminContactPhone
- )}::VARCHAR,
- ${toSqlString(adminContactEmail)}::VARCHAR,
- ${toSqlString(donationContactName)}::VARCHAR,
- ${toSqlString(donationContactPhone)}::VARCHAR,
- ${toSqlString(donationContactEmail)}::VARCHAR,
- ${toSqlBoolean(donationPickup)},
- ${toSqlBoolean(donationAcceptFrozen)},
- ${toSqlBoolean(donationAcceptRefrigerated)},
- ${toSqlBoolean(donationAcceptPerishable)},
- ${toSqlString(donationSchedule)}::VARCHAR,
- ${toSqlString(donationDeliveryInstructions)}::VARCHAR,
- ${toSqlString(donationNotes)}::VARCHAR,
- ${toSqlString(covidNotes)}::VARCHAR,
- ${toSqlString(categoryNotes)}::VARCHAR,
- ${toSqlString(eligibilityNotes)}::VARCHAR,
- ${toSqlString(foodTypes)}::VARCHAR,
- ${toSqlString(languages)}::VARCHAR,
- ${toSqlBoolean(confirmedName)},
- ${toSqlBoolean(confirmedCategories)},
- ${toSqlBoolean(confirmedAddress)},
- ${toSqlBoolean(confirmedPhone)},
- ${toSqlBoolean(confirmedEmail)},
- ${toSqlBoolean(confirmedHours)},
- ${toSqlNumeric(verificationStatusId)}::INT,
- ${toSqlBoolean(inactiveTemporary)},
- ${categories}, ${formattedHours})`;
+ ${toSqlNumeric(0)}::INT,
+ ${toSqlNumeric(tenantId)}::INT,
+ ${toSqlString(name)}::VARCHAR,
+ ${toSqlString(address1)}::VARCHAR,
+ ${toSqlString(address2)}::VARCHAR,
+ ${toSqlString(city)}::VARCHAR,
+ ${toSqlString(state)}::VARCHAR,
+ ${toSqlString(zip)}::VARCHAR,
+ ${toSqlString(phone)}::VARCHAR,
+ ${toSqlNumeric(latitude)}::NUMERIC,
+ ${toSqlNumeric(longitude)}::NUMERIC,
+ ${toSqlString(website)}::VARCHAR, ${toSqlBoolean(inactive)},
+ ${toSqlString(notes)}::VARCHAR,
+ ${toSqlString(requirements)}::VARCHAR,
+ ${toSqlString(adminNotes)}::VARCHAR,
+ ${toSqlNumeric(loginId)}::INT,
+ ${toSqlString(parentOrganization)}::VARCHAR,
+ ${toSqlString(physicalAccess)}::VARCHAR,
+ ${toSqlString(email)}::VARCHAR,
+ ${toSqlString(items)}::VARCHAR,
+ ${toSqlString(services)}::VARCHAR, ${toSqlString(facebook)}::VARCHAR,
+ ${toSqlString(twitter)}::VARCHAR, ${toSqlString(pinterest)}::VARCHAR,
+ ${toSqlString(linkedin)}::VARCHAR, ${toSqlString(description)}::VARCHAR,
+ ${toSqlTimestamp(submittedDate)}::TIMESTAMPTZ,
+ ${toSqlNumeric(submittedLoginId)}::INT,
+ ${toSqlTimestamp(approvedDate)}::TIMESTAMP,
+ ${toSqlNumeric(reviewedLoginId)}::INT,
+ ${toSqlTimestamp(assignedDate)}::TIMESTAMP,
+ ${toSqlNumeric(assignedLoginId)}::INT,
+ ${toSqlTimestamp(claimedDate)}::TIMESTAMP,
+ ${toSqlNumeric(claimedLoginId)}::INT,
+ ${toSqlString(reviewNotes)}::VARCHAR,
+ ${toSqlString(instagram)}::VARCHAR,
+ ${toSqlString(adminContactName)}::VARCHAR,
+ ${toSqlString(adminContactPhone)}::VARCHAR,
+ ${toSqlString(adminContactEmail)}::VARCHAR,
+ ${toSqlString(donationContactName)}::VARCHAR,
+ ${toSqlString(donationContactPhone)}::VARCHAR,
+ ${toSqlString(donationContactEmail)}::VARCHAR,
+ ${toSqlBoolean(donationPickup)},
+ ${toSqlBoolean(donationAcceptFrozen)},
+ ${toSqlBoolean(donationAcceptRefrigerated)},
+ ${toSqlBoolean(donationAcceptPerishable)},
+ ${toSqlString(donationSchedule)}::VARCHAR,
+ ${toSqlString(donationDeliveryInstructions)}::VARCHAR,
+ ${toSqlString(donationNotes)}::VARCHAR,
+ ${toSqlString(covidNotes)}::VARCHAR,
+ ${toSqlString(categoryNotes)}::VARCHAR,
+ ${toSqlString(eligibilityNotes)}::VARCHAR,
+ ${toSqlString(foodTypes)}::VARCHAR,
+ ${toSqlString(languages)}::VARCHAR,
+ ${toSqlBoolean(confirmedName)},
+ ${toSqlBoolean(confirmedCategories)},
+ ${toSqlBoolean(confirmedAddress)},
+ ${toSqlBoolean(confirmedPhone)},
+ ${toSqlBoolean(confirmedEmail)},
+ ${toSqlBoolean(confirmedHours)},
+ ${toSqlBoolean(confirmedFoodTypes)},
+ ${toSqlNumeric(verificationStatusId)}::INT,
+ ${toSqlBoolean(inactiveTemporary)},
+ ${categories}, ${formattedHours},
+ ${toSqlBoolean(foodBakery)}, ${toSqlBoolean(foodDryGoods)},
+ ${toSqlBoolean(foodProduce)}, ${toSqlBoolean(foodDairy)},
+ ${toSqlBoolean(foodPrepared)}, ${toSqlBoolean(foodMeat)}
+ )`;
const stakeholderResult = await pool.query(invokeSprocSql);
const id = stakeholderResult.rows[0].s_id;
return { id };
@@ -787,8 +817,15 @@ const update = async (model) => {
confirmedPhone,
confirmedEmail,
confirmedHours,
+ confirmedFoodTypes,
verificationStatusId,
inactiveTemporary,
+ foodBakery,
+ foodDryGoods,
+ foodProduce,
+ foodDairy,
+ foodPrepared,
+ foodMeat,
} = model;
let hoursSqlValues = hours.length
@@ -812,70 +849,74 @@ const update = async (model) => {
// (ARRAY['(2,Wed,13:02,13:04)', '(3,Thu,07:00,08:00)'])::stakeholder_hours[]); --array of stakeholder_hours
// objects, which are defined as a postgres type (see repo file for more detail on this type).
const invokeSprocSql = `CALL update_stakeholder (
- ${toSqlString(name)}::VARCHAR, ${toSqlString(
- address1
- )}::VARCHAR, ${toSqlString(address2)}::VARCHAR,
- ${toSqlString(city)}::VARCHAR, ${toSqlString(
- state
- )}::VARCHAR, ${toSqlString(zip)}::VARCHAR, ${toSqlString(phone)}::VARCHAR,
- ${toSqlNumeric(latitude)}::NUMERIC, ${toSqlNumeric(
- longitude
- )}::NUMERIC, ${toSqlString(website)}::VARCHAR,
- ${toSqlBoolean(inactive)}, ${toSqlString(notes)}::VARCHAR, ${toSqlString(
- requirements
- )}::VARCHAR,
- ${toSqlString(adminNotes)}::VARCHAR, ${toSqlString(
- parentOrganization
- )}::VARCHAR, ${toSqlString(physicalAccess)}::VARCHAR,
- ${toSqlString(email)}::VARCHAR, ${toSqlString(
- items
- )}::VARCHAR, ${toSqlString(services)}::VARCHAR, ${toSqlString(
- facebook
- )}::VARCHAR,
- ${toSqlString(twitter)}::VARCHAR, ${toSqlString(
- pinterest
- )}::VARCHAR, ${toSqlString(linkedin)}::VARCHAR, ${toSqlString(
- description
- )}::VARCHAR,
- ${toSqlNumeric(loginId)}::INT, ${toSqlTimestamp(
- submittedDate
- )}::TIMESTAMPTZ, ${toSqlNumeric(submittedLoginId)}::INT,
- ${toSqlTimestamp(approvedDate)}::TIMESTAMP,
- ${toSqlNumeric(reviewedLoginId)}::INT,
- ${toSqlTimestamp(assignedDate)}::TIMESTAMP, ${toSqlNumeric(
- assignedLoginId
- )}::INT, ${toSqlTimestamp(claimedDate)}::TIMESTAMP,
- ${toSqlNumeric(claimedLoginId)}::INT, ${toSqlString(
- reviewNotes
- )}::VARCHAR, ${toSqlString(instagram)}::VARCHAR,
- ${toSqlString(adminContactName)}::VARCHAR, ${toSqlString(
- adminContactPhone
- )}::VARCHAR, ${toSqlString(adminContactEmail)}::VARCHAR,
- ${toSqlString(donationContactName)}::VARCHAR, ${toSqlString(
- donationContactPhone
- )}::VARCHAR, ${toSqlString(donationContactEmail)}::VARCHAR,
- ${toSqlBoolean(donationPickup)}, ${toSqlBoolean(
- donationAcceptFrozen
- )}, ${toSqlBoolean(donationAcceptRefrigerated)},
- ${toSqlBoolean(donationAcceptPerishable)}, ${toSqlString(
- donationSchedule
- )}::VARCHAR, ${toSqlString(donationDeliveryInstructions)}::VARCHAR,
- ${toSqlString(donationNotes)}::VARCHAR, ${toSqlString(
- covidNotes
- )}::VARCHAR, ${toSqlString(categoryNotes)}::VARCHAR,
- ${toSqlString(eligibilityNotes)}::VARCHAR, ${toSqlString(
- foodTypes
- )}::VARCHAR, ${toSqlString(languages)}::VARCHAR,
- ${toSqlBoolean(confirmedName)}, ${toSqlBoolean(
- confirmedCategories
- )}, ${toSqlBoolean(confirmedAddress)},
- ${toSqlBoolean(confirmedPhone)}, ${toSqlBoolean(
- confirmedEmail
- )}, ${toSqlBoolean(confirmedHours)},
- ${toSqlNumeric(verificationStatusId)}::INT, ${toSqlBoolean(
- inactiveTemporary
- )},
- ${id}, ${categories}, ${formattedHours})`;
+ ${toSqlString(name)}::VARCHAR,
+ ${toSqlString(address1)}::VARCHAR,
+ ${toSqlString(address2)}::VARCHAR,
+ ${toSqlString(city)}::VARCHAR,
+ ${toSqlString(state)}::VARCHAR,
+ ${toSqlString(zip)}::VARCHAR,
+ ${toSqlString(phone)}::VARCHAR,
+ ${toSqlNumeric(latitude)}::NUMERIC,
+ ${toSqlNumeric(longitude)}::NUMERIC,
+ ${toSqlString(website)}::VARCHAR,
+ ${toSqlBoolean(inactive)},
+ ${toSqlString(notes)}::VARCHAR,
+ ${toSqlString(requirements)}::VARCHAR,
+ ${toSqlString(adminNotes)}::VARCHAR,
+ ${toSqlString(parentOrganization)}::VARCHAR,
+ ${toSqlString(physicalAccess)}::VARCHAR,
+ ${toSqlString(email)}::VARCHAR,
+ ${toSqlString(items)}::VARCHAR,
+ ${toSqlString(services)}::VARCHAR,
+ ${toSqlString(facebook)}::VARCHAR,
+ ${toSqlString(twitter)}::VARCHAR,
+ ${toSqlString(pinterest)}::VARCHAR,
+ ${toSqlString(linkedin)}::VARCHAR,
+ ${toSqlString(description)}::VARCHAR,
+ ${toSqlNumeric(loginId)}::INT,
+ ${toSqlTimestamp(submittedDate)}::TIMESTAMPTZ,
+ ${toSqlNumeric(submittedLoginId)}::INT,
+ ${toSqlTimestamp(approvedDate)}::TIMESTAMP,
+ ${toSqlNumeric(reviewedLoginId)}::INT,
+ ${toSqlTimestamp(assignedDate)}::TIMESTAMP,
+ ${toSqlNumeric(assignedLoginId)}::INT,
+ ${toSqlTimestamp(claimedDate)}::TIMESTAMP,
+ ${toSqlNumeric(claimedLoginId)}::INT,
+ ${toSqlString(reviewNotes)}::VARCHAR,
+ ${toSqlString(instagram)}::VARCHAR,
+ ${toSqlString(adminContactName)}::VARCHAR,
+ ${toSqlString(adminContactPhone)}::VARCHAR,
+ ${toSqlString(adminContactEmail)}::VARCHAR,
+ ${toSqlString(donationContactName)}::VARCHAR,
+ ${toSqlString(donationContactPhone)}::VARCHAR,
+ ${toSqlString(donationContactEmail)}::VARCHAR,
+ ${toSqlBoolean(donationPickup)},
+ ${toSqlBoolean(donationAcceptFrozen)},
+ ${toSqlBoolean(donationAcceptRefrigerated)},
+ ${toSqlBoolean(donationAcceptPerishable)},
+ ${toSqlString(donationSchedule)}::VARCHAR,
+ ${toSqlString(donationDeliveryInstructions)}::VARCHAR,
+ ${toSqlString(donationNotes)}::VARCHAR,
+ ${toSqlString(covidNotes)}::VARCHAR,
+ ${toSqlString(categoryNotes)}::VARCHAR,
+ ${toSqlString(eligibilityNotes)}::VARCHAR,
+ ${toSqlString(foodTypes)}::VARCHAR,
+ ${toSqlString(languages)}::VARCHAR,
+ ${toSqlBoolean(confirmedName)},
+ ${toSqlBoolean(confirmedCategories)},
+ ${toSqlBoolean(confirmedAddress)},
+ ${toSqlBoolean(confirmedPhone)},
+ ${toSqlBoolean(confirmedEmail)}, ${toSqlBoolean(confirmedHours)},
+ ${toSqlBoolean(confirmedFoodTypes)},
+ ${toSqlNumeric(verificationStatusId)}::INT,
+ ${toSqlBoolean(inactiveTemporary)},
+ ${id},
+ ${categories},
+ ${formattedHours},
+ ${toSqlBoolean(foodBakery)}, ${toSqlBoolean(foodDryGoods)},
+ ${toSqlBoolean(foodProduce)}, ${toSqlBoolean(foodDairy)},
+ ${toSqlBoolean(foodPrepared)}, ${toSqlBoolean(foodMeat)}
+ )`;
try {
await pool.query(invokeSprocSql);
diff --git a/client/package-lock.json b/client/package-lock.json
index e1fadc0a2..9a7412c48 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "food-oasis-client",
- "version": "1.0.26",
+ "version": "1.0.28",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/client/src/components/Verification/OrganizationEdit.js b/client/src/components/Verification/OrganizationEdit.js
index d255fbe59..5ad1786f9 100644
--- a/client/src/components/Verification/OrganizationEdit.js
+++ b/client/src/components/Verification/OrganizationEdit.js
@@ -190,8 +190,15 @@ const emptyOrganization = {
confirmedEmail: false,
confirmedPhone: false,
confirmedHours: false,
+ confirmedFoodTypes: false,
verificationStatusId: VERIFICATION_STATUS.NEEDS_VERIFICATION,
inactiveTemporary: false,
+ foodBakery: false,
+ foodDryGoods: false,
+ foodProduce: false,
+ foodDairy: false,
+ foodPrepared: false,
+ foodMeat: false,
};
const OrganizationEdit = (props) => {
@@ -1091,113 +1098,244 @@ const OrganizationEdit = (props) => {
Details for Food Seekers to See
-
-
+
+
+ Food Types
+
+
+
+ setFieldValue(
+ "confirmedFoodTypes",
+ e.target.checked
+ )
+ }
+ onBlur={handleBlur}
+ size="medium"
+ />
+ }
+ label="Confirm Food Types"
+ />
+
-
-
+
+ setFieldValue("foodBakery", !values.foodBakery)
+ }
+ onBlur={handleBlur}
+ />
+ }
+ label="Baked Goods"
/>
-
-
+
+ setFieldValue("foodDryGoods", !values.foodDryGoods)
+ }
+ onBlur={handleBlur}
+ />
+ }
+ label="Dry Goods"
/>
-
-
+
+ setFieldValue("foodProduce", !values.foodProduce)
+ }
+ onBlur={handleBlur}
+ />
}
+ label="Produce"
/>
-
-
+
+ setFieldValue("foodDairy", !values.foodDairy)
+ }
+ onBlur={handleBlur}
+ />
}
+ label="Dairy"
/>
-
-
+
+ setFieldValue("foodPrepared", !values.foodPrepared)
+ }
+ onBlur={handleBlur}
+ />
+ }
+ label="Prepared Food"
/>
-
-
+
+ setFieldValue("foodMeat", !values.foodMeat)
+ }
+ onBlur={handleBlur}
+ />
+ }
+ label="Meat"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/src/components/Verification/VerificationAdminGrid.js b/client/src/components/Verification/VerificationAdminGrid.js
index 7f7f34c04..376a1b890 100644
--- a/client/src/components/Verification/VerificationAdminGrid.js
+++ b/client/src/components/Verification/VerificationAdminGrid.js
@@ -159,6 +159,12 @@ const adminColumns = [
formatter: confirmationFormatter,
width: 60,
},
+ {
+ key: "confirmedFoodTypes",
+ name: "FoodTypes",
+ formatter: confirmationFormatter,
+ width: 60,
+ },
{
key: "neighborhoodName",
name: "Neighborhood",
diff --git a/migrations/1604419645716_implement-food-type-checkboxes-678.js b/migrations/1604419645716_implement-food-type-checkboxes-678.js
new file mode 100644
index 000000000..adb33740b
--- /dev/null
+++ b/migrations/1604419645716_implement-food-type-checkboxes-678.js
@@ -0,0 +1,760 @@
+/* eslint-disable camelcase */
+
+exports.shorthands = undefined;
+
+exports.up = (pgm) => {
+ pgm.sql(
+ `
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS food_bakery boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS food_dry_goods boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS food_produce boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS food_dairy boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS food_prepared boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS food_meat boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder ADD COLUMN IF NOT EXISTS v_food_types boolean NOT NULL DEFAULT false;
+
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS food_bakery boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS food_dry_goods boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS food_produce boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS food_dairy boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS food_prepared boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS food_meat boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_best ADD COLUMN IF NOT EXISTS v_food_types boolean NOT NULL DEFAULT false;
+
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS food_bakery boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS food_dry_goods boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS food_produce boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS food_dairy boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS food_prepared boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS food_meat boolean NOT NULL DEFAULT false;
+ ALTER TABLE stakeholder_log ADD COLUMN IF NOT EXISTS v_food_types boolean NOT NULL DEFAULT false;
+ `
+ );
+
+ pgm.sql(
+ `
+ CREATE OR REPLACE PROCEDURE public.update_stakeholder(
+ s_name character varying,
+ s_address_1 character varying,
+ s_address_2 character varying,
+ s_city character varying,
+ s_state character varying,
+ s_zip character varying,
+ s_phone character varying,
+ s_latitude numeric,
+ s_longitude numeric,
+ s_website character varying,
+ s_inactive boolean,
+ s_notes character varying,
+ s_requirements character varying,
+ s_admin_notes character varying,
+ s_parent_organization character varying,
+ s_physical_access character varying,
+ s_email character varying,
+ s_items character varying,
+ s_services character varying,
+ s_facebook character varying,
+ s_twitter character varying,
+ s_pinterest character varying,
+ s_linkedin character varying,
+ s_description character varying,
+ s_modified_login_id integer,
+ s_submitted_date timestamp with time zone,
+ s_submitted_login_id integer,
+ s_approved_date timestamp without time zone,
+ s_reviewed_login_id integer,
+ s_assigned_date timestamp without time zone,
+ s_assigned_login_id integer,
+ s_claimed_date timestamp without time zone,
+ s_claimed_login_id integer,
+ s_review_notes character varying,
+ s_instagram character varying,
+ s_admin_contact_name character varying,
+ s_admin_contact_phone character varying,
+ s_admin_contact_email character varying,
+ s_donation_contact_name character varying,
+ s_donation_contact_phone character varying,
+ s_donation_contact_email character varying,
+ s_donation_pickup boolean,
+ s_donation_accept_frozen boolean,
+ s_donation_accept_refrigerated boolean,
+ s_donation_accept_perishable boolean,
+ s_donation_schedule character varying,
+ s_donation_delivery_instructions character varying,
+ s_donation_notes character varying,
+ s_covid_notes character varying,
+ s_category_notes character varying,
+ s_eligibility_notes character varying,
+ s_food_types character varying,
+ s_languages character varying,
+ s_v_name boolean,
+ s_v_categories boolean,
+ s_v_address boolean,
+ s_v_phone boolean,
+ s_v_email boolean,
+ s_v_hours boolean,
+ s_v_food_types boolean,
+ s_verification_status_id integer,
+ s_inactive_temporary boolean,
+ s_id integer,
+ categories integer[],
+ hours_array stakeholder_hours[],
+ s_food_bakery boolean,
+ s_food_dry_goods boolean,
+ s_food_produce boolean,
+ s_food_dairy boolean,
+ s_food_prepared boolean,
+ s_food_meat boolean)
+ LANGUAGE 'plpgsql'
+
+ AS $BODY$
+ DECLARE cat INT;
+ DECLARE hours_element stakeholder_hours;
+ DECLARE critical_percent INT;
+
+ BEGIN
+
+ SELECT CASE WHEN (s_inactive OR s_inactive_temporary) THEN
+ (s_v_name::integer + s_v_categories::integer + s_v_address::integer) *100/3
+ ELSE
+ (s_v_name::integer + s_v_categories::integer + s_v_address::integer
+ + s_v_email::integer + s_v_phone::integer + s_v_hours::integer
+ + s_v_food_types::integer) *100/7
+ END INTO critical_percent;
+
+ -- update the stakeholder table itself
+ UPDATE stakeholder
+ SET
+ name = s_name,
+ address_1 = s_address_1,
+ address_2 = s_address_2,
+ city = s_city,
+ state = s_state,
+ zip = s_zip,
+ phone = s_phone,
+ latitude = s_latitude,
+ longitude = s_longitude,
+ website = s_website,
+ inactive = s_inactive,
+ notes = s_notes,
+ requirements = s_requirements,
+ admin_notes = s_admin_notes,
+ parent_organization = s_parent_organization,
+ physical_access = s_physical_access,
+ email = s_email,
+ items = s_items,
+ services = s_services,
+ facebook = s_facebook,
+ twitter = s_twitter,
+ pinterest = s_pinterest,
+ linkedin = s_linkedin,
+ description = s_description,
+ modified_login_id = s_modified_login_id,
+ modified_date = CURRENT_TIMESTAMP,
+ submitted_date = s_submitted_date,
+ submitted_login_id = s_submitted_login_id,
+ approved_date = s_approved_date,
+ reviewed_login_id = s_reviewed_login_id,
+ assigned_date = s_assigned_date,
+ assigned_login_id = s_assigned_login_id,
+ claimed_date = s_claimed_date,
+ claimed_login_id = s_claimed_login_id,
+ review_notes = s_review_notes,
+ instagram = s_instagram,
+ admin_contact_name = s_admin_contact_name,
+ admin_contact_phone = s_admin_contact_phone,
+ admin_contact_email = s_admin_contact_email,
+ donation_contact_name = s_donation_contact_name,
+ donation_contact_phone = s_donation_contact_phone,
+ donation_contact_email = s_donation_contact_email,
+ donation_pickup = s_donation_pickup,
+ donation_accept_frozen = s_donation_accept_frozen,
+ donation_accept_refrigerated = s_donation_accept_refrigerated,
+ donation_accept_perishable = s_donation_accept_perishable,
+ donation_schedule = s_donation_schedule,
+ donation_delivery_instructions = s_donation_delivery_instructions,
+ donation_notes = s_donation_notes,
+ covid_notes = s_covid_notes,
+ category_notes = s_category_notes,
+ eligibility_notes = s_eligibility_notes,
+ food_types = s_food_types,
+ languages = s_languages,
+ v_name = s_v_name,
+ v_categories = s_v_categories,
+ v_address = s_v_address,
+ v_phone = s_v_phone,
+ v_email = s_v_email,
+ v_hours = s_v_hours,
+ v_food_types = s_v_food_types,
+ verification_status_id = s_verification_status_id,
+ inactive_temporary = s_inactive_temporary,
+ hours = hours_array,
+ category_ids = categories,
+ complete_critical_percent = critical_percent,
+ food_bakery = s_food_bakery,
+ food_dry_goods = s_food_dry_goods,
+ food_produce = s_food_produce,
+ food_dairy = s_food_dairy,
+ food_prepared = s_food_prepared,
+ food_meat = s_food_meat
+ WHERE
+ id=s_id;
+
+ -- delete previous stakeholder category
+ DELETE FROM stakeholder_category WHERE stakeholder_id=s_id;
+ -- ...and insert new stakeholder category(s)
+ FOREACH cat IN ARRAY categories
+ LOOP
+ INSERT INTO stakeholder_category
+ (stakeholder_id, category_id)
+ VALUES (s_id, cat);
+ END LOOP;
+ -- delete previous schedule
+ DELETE FROM stakeholder_schedule WHERE stakeholder_id=s_id;
+ -- ...and insert new schedule(s)
+ FOREACH hours_element IN ARRAY hours_array
+ LOOP
+ INSERT INTO stakeholder_schedule(
+ stakeholder_id, day_of_week, open, close, week_of_month
+ ) VALUES(
+ s_id,
+ hours_element.day_of_week,
+ hours_element.open::time without time zone,
+ hours_element.close::time without time zone,
+ hours_element.week_of_month
+ );
+ END LOOP;
+ COMMIT;
+ END;
+ $BODY$;
+ `
+ );
+
+ pgm.sql(`
+ CREATE OR REPLACE PROCEDURE public.create_stakeholder(
+ INOUT s_id integer,
+ s_tenant_id integer,
+ s_name character varying,
+ s_address_1 character varying,
+ s_address_2 character varying,
+ s_city character varying,
+ s_state character varying,
+ s_zip character varying,
+ s_phone character varying,
+ s_latitude numeric,
+ s_longitude numeric,
+ s_website character varying,
+ s_inactive boolean,
+ s_notes character varying,
+ s_requirements character varying,
+ s_admin_notes character varying,
+ s_created_login_id integer,
+ s_parent_organization character varying,
+ s_physical_access character varying,
+ s_email character varying,
+ s_items character varying,
+ s_services character varying,
+ s_facebook character varying,
+ s_twitter character varying,
+ s_pinterest character varying,
+ s_linkedin character varying,
+ s_description character varying,
+ s_submitted_date timestamp with time zone,
+ s_submitted_login_id integer,
+ s_approved_date timestamp without time zone,
+ s_reviewed_login_id integer,
+ s_assigned_date timestamp without time zone,
+ s_assigned_login_id integer,
+ s_claimed_date timestamp without time zone,
+ s_claimed_login_id integer,
+ s_review_notes character varying,
+ s_instagram character varying,
+ s_admin_contact_name character varying,
+ s_admin_contact_phone character varying,
+ s_admin_contact_email character varying,
+ s_donation_contact_name character varying,
+ s_donation_contact_phone character varying,
+ s_donation_contact_email character varying,
+ s_donation_pickup boolean,
+ s_donation_accept_frozen boolean,
+ s_donation_accept_refrigerated boolean,
+ s_donation_accept_perishable boolean,
+ s_donation_schedule character varying,
+ s_donation_delivery_instructions character varying,
+ s_donation_notes character varying,
+ s_covid_notes character varying,
+ s_category_notes character varying,
+ s_eligibility_notes character varying,
+ s_food_types character varying,
+ s_languages character varying,
+ s_v_name boolean,
+ s_v_categories boolean,
+ s_v_address boolean,
+ s_v_phone boolean,
+ s_v_email boolean,
+ s_v_hours boolean,
+ s_v_food_types boolean,
+ s_verification_status_id integer,
+ s_inactive_temporary boolean,
+ categories integer[],
+ hours_array stakeholder_hours[],
+ s_food_bakery boolean,
+ s_food_dry_goods boolean,
+ s_food_produce boolean,
+ s_food_dairy boolean,
+ s_food_prepared boolean,
+ s_food_meat boolean)
+ LANGUAGE 'plpgsql'
+
+ AS $BODY$
+ DECLARE cat INT;
+ DECLARE hours_element stakeholder_hours;
+ DECLARE critical_percent INT;
+ BEGIN
+ SELECT CASE WHEN (s_inactive OR s_inactive_temporary) THEN
+ (s_v_name::integer + s_v_categories::integer + s_v_address::integer) *100/3
+ ELSE
+ (s_v_name::integer + s_v_categories::integer + s_v_address::integer
+ + s_v_email::integer + s_v_phone::integer + s_v_hours::integer) *100/6
+ END INTO critical_percent;
+
+ INSERT INTO stakeholder (
+ tenant_id,
+ name, address_1, address_2, city, state, zip,
+ phone, latitude, longitude,
+ website, inactive, notes, requirements, admin_notes, created_login_id,
+ parent_organization, physical_access, email,
+ items, services, facebook, twitter, pinterest, linkedin, description,
+ submitted_date, submitted_login_id, approved_date, reviewed_login_id,
+ assigned_date, assigned_login_id, claimed_date, claimed_login_id,
+ review_notes, instagram, admin_contact_name,
+ admin_contact_phone, admin_contact_email,
+ donation_contact_name, donation_contact_phone,
+ donation_contact_email, donation_pickup,
+ donation_accept_frozen, donation_accept_refrigerated,
+ donation_accept_perishable, donation_schedule,
+ donation_delivery_instructions, donation_notes, covid_notes,
+ category_notes, eligibility_notes, food_types, languages,
+ v_name, v_categories, v_address,
+ v_phone, v_email, v_hours, v_food_types,
+ verification_status_id, inactive_temporary,
+ hours, category_ids, neighborhood_id, complete_critical_percent,
+ food_bakery, food_dry_goods , food_produce, food_dairy, food_prepared, food_meat)
+ VALUES (
+ s_tenant_id,
+ s_name, s_address_1, s_address_2, s_city, s_state, s_zip,
+ s_phone, s_latitude, s_longitude,
+ s_website, s_inactive, s_notes, s_requirements, s_admin_notes, s_created_login_id,
+ s_parent_organization, s_physical_access, s_email,
+ s_items, s_services, s_facebook, s_twitter, s_pinterest, s_linkedin, s_description,
+ s_submitted_date, s_submitted_login_id, s_approved_date, s_reviewed_login_id,
+ s_assigned_date, s_assigned_login_id, s_claimed_date, s_claimed_login_id,
+ s_review_notes, s_instagram, s_admin_contact_name,
+ s_admin_contact_phone, s_admin_contact_email,
+ s_donation_contact_name, s_donation_contact_phone,
+ s_donation_contact_email, s_donation_pickup,
+ s_donation_accept_frozen, s_donation_accept_refrigerated,
+ s_donation_accept_perishable, s_donation_schedule,
+ s_donation_delivery_instructions, s_donation_notes, s_covid_notes,
+ s_category_notes, s_eligibility_notes, s_food_types, s_languages,
+ s_v_name, s_v_categories, s_v_address,
+ s_v_phone, s_v_email, s_v_hours, s_v_food_types,
+ s_verification_status_id, s_inactive_temporary,
+ hours_array, categories,
+ (SELECT id FROM neighborhood WHERE ST_Contains(geometry, ST_Point(s_longitude, s_latitude)) LIMIT 1),
+ critical_percent,
+ s_food_bakery, s_food_dry_goods , s_food_produce, s_food_dairy, s_food_prepared, s_food_meat
+ ) RETURNING id INTO s_id;
+
+ -- insert new stakeholder category(s)
+ FOREACH cat IN ARRAY categories
+ LOOP
+ INSERT INTO stakeholder_category
+ (stakeholder_id, category_id)
+ VALUES (s_id, cat);
+ END LOOP;
+
+ -- insert new schedule(s)
+ FOREACH hours_element IN ARRAY hours_array
+ LOOP
+ INSERT INTO stakeholder_schedule(
+ stakeholder_id, day_of_week, open, close, week_of_month
+ ) VALUES(
+ s_id,
+ hours_element.day_of_week,
+ hours_element.open::time without time zone,
+ hours_element.close::time without time zone,
+ hours_element.week_of_month
+ );
+ END LOOP;
+ COMMIT;
+ END;
+ $BODY$;
+ `);
+
+ pgm.sql(`
+ DROP PROCEDURE IF EXISTS public.update_stakeholder(
+ varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,numeric,numeric,varchar,bool,
+ varchar,varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,varchar,
+ varchar,int4,timestamptz,int4,timestamp,int4,
+ timestamp,int4,timestamp,int4,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,varchar,
+ bool,bool,bool,bool,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,bool,bool,bool,bool,
+ bool,bool,int4,bool,int4,_int4,_stakeholder_hours);
+
+ DROP PROCEDURE IF EXISTS public.create_stakeholder(
+ int4,varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,numeric,
+ varchar,bool,varchar,varchar,varchar,int4,varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,timestamptz,int4,timestamp,int4,timestamp,
+ int4,timestamp,int4,varchar,varchar,varchar,varchar,varchar,varchar,varchar,
+ varchar,bool,bool,bool,bool,varchar,varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,bool,bool,bool,bool,bool,bool,int4,bool,_int4,_stakeholder_hours,int4);
+
+ DROP PROCEDURE IF EXISTS public.create_stakeholder(
+ varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,numeric,varchar,
+ bool,varchar,varchar,varchar,int4,varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,timestamptz,int4,timestamp,int4,
+ timestamp,int4,timestamp,int4,varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,bool,bool,bool,bool,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,bool,bool,bool,bool,bool,bool,int4,bool,_int4,
+ _stakeholder_hours,int4);
+
+ DROP PROCEDURE IF EXISTS public.create_stakeholder(
+ int4,varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,numeric,
+ varchar,bool,varchar,varchar,varchar,int4,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,varchar,timestamptz,int4,timestamp,
+ int4,timestamp,int4,timestamp,int4,varchar,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,bool,bool,bool,bool,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,bool,bool,bool,bool,bool,bool,int4,bool,_int4,
+ _stakeholder_hours);
+
+ DROP PROCEDURE IF EXISTS public.create_stakeholder(
+ varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,numeric,
+ varchar,bool,varchar,varchar,varchar,int4,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,varchar,timestamptz,int4,timestamp,
+ timestamp,int4,timestamp,int4,timestamp,int4,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,bool,bool,bool,bool,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,bool,bool,bool,bool,bool,bool,int4,bool,
+ _int4,_stakeholder_hours);
+
+ DROP PROCEDURE IF EXISTS public.create_stakeholder(
+ int4,int4,varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,
+ numeric,varchar,bool,varchar,varchar,varchar,int4,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,varchar,varchar,timestamptz,int4,
+ timestamp,int4,timestamp,int4,timestamp,int4,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,bool,bool,bool,bool,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,bool,bool,bool,bool,bool,bool,int4,bool,
+ _int4,_stakeholder_hours);
+
+ DROP PROCEDURE IF EXISTS public.create_stakeholder(
+ varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,numeric,
+ varchar,bool,varchar,varchar,varchar,int4,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,varchar,timestamptz,int4,timestamp,
+ timestamp,int4,timestamp,int4,timestamp,int4,varchar,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,bool,bool,bool,bool,varchar,varchar,varchar,
+ varchar,varchar,varchar,varchar,varchar,bool,bool,bool,bool,bool,bool,int4,bool,
+ _int4,_stakeholder_hours,int4);
+
+ `);
+
+ pgm.sql(`
+ CREATE OR REPLACE FUNCTION public.on_insert_or_update_stakeholder()
+ RETURNS trigger
+ LANGUAGE 'plpgsql'
+ COST 100
+ VOLATILE NOT LEAKPROOF
+ AS $BODY$
+ DECLARE
+ best_row stakeholder_log%ROWTYPE;
+ latest_version INTEGER;
+ is_verified BOOLEAN := false;
+ categoryid INTEGER;
+ BEGIN
+ INSERT INTO public.stakeholder_log
+ (id, tenant_id, version, name, address_1, address_2, city, state, zip,
+ phone, latitude, longitude, website, fm_id, notes,
+ created_date, created_login_id, modified_date, modified_login_id,
+ requirements, admin_notes, inactive, parent_organization,
+ physical_access, email, items, services, facebook, twitter,
+ pinterest,
+ linkedin,
+ description,
+ approved_date,
+ reviewed_login_id,
+ assigned_login_id,
+ agency_type,
+ assigned_date,
+ review_notes,
+ claimed_login_id,
+ claimed_date,
+ instagram,
+ admin_contact_name,
+ admin_contact_phone,
+ admin_contact_email,
+ donation_contact_name,
+ donation_contact_phone,
+ donation_contact_email,
+ donation_pickup,
+ donation_accept_frozen,
+ donation_accept_refrigerated,
+ donation_accept_perishable,
+ donation_schedule,
+ donation_delivery_instructions,
+ covid_notes,
+ donation_notes,
+ category_notes,
+ eligibility_notes,
+ food_types,
+ languages,
+ verification_status_id,
+ inactive_temporary,
+ v_name, v_categories, v_address, v_email, v_phone, v_hours, v_food_types,
+ hours, category_ids,
+ neighborhood_id,
+ complete_critical_percent,
+ food_bakery, food_dry_goods , food_produce, food_dairy, food_prepared, food_meat
+ )
+ VALUES (
+ NEW.id, NEW.tenant_id,
+ (SELECT greatest(max(version) + 1, 1) FROM public.stakeholder_log where id = NEW.id),
+ NEW.name,
+ NEW.address_1,
+ NEW.address_2,
+ NEW.city,
+ NEW.state,
+ NEW.zip,
+ NEW.phone,
+ NEW.latitude,
+ NEW.longitude,
+ NEW.website,
+ NEW.fm_id,
+ NEW.notes,
+ NEW.created_date,
+ NEW.created_login_id,
+ NEW.modified_date,
+ NEW.modified_login_id,
+ NEW.requirements,
+ NEW.admin_notes,
+ NEW.inactive,
+ NEW.parent_organization,
+ NEW.physical_access,
+ NEW.email,
+ NEW.items,
+ NEW.services,
+ NEW.facebook,
+ NEW.twitter,
+ NEW.pinterest,
+ NEW.linkedin,
+ NEW.description,
+ NEW.approved_date,
+ NEW.reviewed_login_id,
+ NEW.assigned_login_id,
+ NEW.agency_type,
+ NEW.assigned_date,
+ NEW.review_notes,
+ NEW.claimed_login_id,
+ NEW.claimed_date,
+ NEW.instagram,
+ NEW.admin_contact_name,
+ NEW.admin_contact_phone,
+ NEW.admin_contact_email,
+ NEW.donation_contact_name,
+ NEW.donation_contact_phone,
+ NEW.donation_contact_email,
+ NEW.donation_pickup,
+ NEW.donation_accept_frozen,
+ NEW.donation_accept_refrigerated,
+ NEW.donation_accept_perishable,
+ NEW.donation_schedule,
+ NEW.donation_delivery_instructions,
+ NEW.covid_notes,
+ NEW.donation_notes,
+ NEW.category_notes,
+ NEW.eligibility_notes,
+ NEW.food_types,
+ NEW.languages,
+ NEW.verification_status_id,
+ NEW.inactive_temporary,
+ NEW.v_name,
+ NEW.v_categories,
+ NEW.v_address,
+ NEW.v_email,
+ NEW.v_phone,
+ NEW.v_hours,
+ NEW.v_food_types,
+ NEW.hours,
+ NEW.category_ids,
+ (SELECT id FROM neighborhood WHERE ST_Contains(geometry, ST_Point(NEW.longitude, NEW.latitude)) LIMIT 1),
+ NEW.complete_critical_percent,
+ NEW.food_bakery, NEW.food_dry_goods , NEW.food_produce, NEW.food_dairy, NEW.food_prepared, NEW.food_meat
+ ) RETURNING version INTO latest_version;
+
+ -- We might need to select a new row as our "best" row for this stakeholder.
+ -- "best" is defined as the highest version in stakeholder_log with verification_status_id=4
+ -- (4 means "verified").
+ -- Barring that, the highest version is the "best".
+
+ SELECT * INTO best_row FROM stakeholder_log
+ WHERE id=NEW.id
+ AND verification_status_id=4
+ AND version=(select MAX(version) from stakeholder_log where id=NEW.id AND verification_status_id=4);
+
+ -- Is there anything in best_row? (there might not be, if there are no verified rows)
+ IF NOT FOUND THEN
+ -- Fall back on finding the highest version number, which *just so happens* to be this row!
+ SELECT * INTO best_row FROM stakeholder_log
+ WHERE id=NEW.id
+ AND version=latest_version;
+ ELSE
+ is_verified = true;
+ END IF;
+
+ IF FOUND THEN
+ DELETE FROM stakeholder_best where id=best_row.id;
+ INSERT INTO stakeholder_best
+ (id, tenant_id, name, address_1, address_2, city, state, zip,
+ phone, latitude, longitude, website, fm_id, notes,
+ created_date, created_login_id, modified_date, modified_login_id,
+ requirements, admin_notes, inactive, parent_organization,
+ physical_access, email, items, services, facebook, twitter,
+ pinterest,
+ linkedin,
+ description,
+ approved_date,
+ reviewed_login_id,
+ assigned_login_id,
+ agency_type,
+ assigned_date,
+ review_notes,
+ claimed_login_id,
+ claimed_date,
+ instagram,
+ admin_contact_name,
+ admin_contact_phone,
+ admin_contact_email,
+ donation_contact_name,
+ donation_contact_phone,
+ donation_contact_email,
+ donation_pickup,
+ donation_accept_frozen,
+ donation_accept_refrigerated,
+ donation_accept_perishable,
+ donation_schedule,
+ donation_delivery_instructions,
+ covid_notes,
+ donation_notes,
+ category_notes,
+ eligibility_notes,
+ food_types,
+ languages,
+ verification_status_id,
+ inactive_temporary,
+ v_name, v_categories, v_address, v_email, v_phone, v_hours, v_food_types,
+ hours, category_ids,
+ neighborhood_id,
+ complete_critical_percent,
+ food_bakery, food_dry_goods , food_produce, food_dairy, food_prepared, food_meat,
+ is_verified
+ )
+ VALUES (
+ best_row.id,
+ best_row.tenant_id,
+ best_row.name,
+ best_row.address_1,
+ best_row.address_2,
+ best_row.city,
+ best_row.state,
+ best_row.zip,
+ best_row.phone,
+ best_row.latitude,
+ best_row.longitude,
+ best_row.website,
+ best_row.fm_id,
+ best_row.notes,
+ best_row.created_date,
+ best_row.created_login_id,
+ best_row.modified_date,
+ best_row.modified_login_id,
+ best_row.requirements,
+ best_row.admin_notes,
+ best_row.inactive,
+ best_row.parent_organization,
+ best_row.physical_access,
+ best_row.email,
+ best_row.items,
+ best_row.services,
+ best_row.facebook,
+ best_row.twitter,
+ best_row.pinterest,
+ best_row.linkedin,
+ best_row.description,
+ best_row.approved_date,
+ best_row.reviewed_login_id,
+ best_row.assigned_login_id,
+ best_row.agency_type,
+ best_row.assigned_date,
+ best_row.review_notes,
+ best_row.claimed_login_id,
+ best_row.claimed_date,
+ best_row.instagram,
+ best_row.admin_contact_name,
+ best_row.admin_contact_phone,
+ best_row.admin_contact_email,
+ best_row.donation_contact_name,
+ best_row.donation_contact_phone,
+ best_row.donation_contact_email,
+ best_row.donation_pickup,
+ best_row.donation_accept_frozen,
+ best_row.donation_accept_refrigerated,
+ best_row.donation_accept_perishable,
+ best_row.donation_schedule,
+ best_row.donation_delivery_instructions,
+ best_row.covid_notes,
+ best_row.donation_notes,
+ best_row.category_notes,
+ best_row.eligibility_notes,
+ best_row.food_types,
+ best_row.languages,
+ best_row.verification_status_id,
+ best_row.inactive_temporary,
+ best_row.v_name,
+ best_row.v_categories,
+ best_row.v_address,
+ best_row.v_email,
+ best_row.v_phone,
+ best_row.v_hours,
+ best_row.v_food_types,
+ best_row.hours,
+ best_row.category_ids,
+ best_row.neighborhood_id,
+ best_row.complete_critical_percent,
+ best_row.food_bakery, best_row.food_dry_goods , best_row.food_produce,
+ best_row.food_dairy, best_row.food_prepared, best_row.food_meat,
+ is_verified);
+
+ /* Populate normalized stakeholder_best_category table */
+ IF best_row.category_ids IS NOT NULL THEN
+ FOREACH categoryid IN ARRAY best_row.category_ids
+ LOOP
+ INSERT INTO stakeholder_best_category
+ (stakeholder_id, category_id)
+ VALUES (best_row.id, categoryid);
+ END LOOP;
+ END IF;
+ ELSE
+ -- should probably log some sort of error, because this should never happen
+ RAISE EXCEPTION 'Could not find a best version of stakeholder id %', NEW.id;
+ END IF;
+
+ RETURN NEW;
+ END;
+ $BODY$;
+ `);
+};
+
+exports.down = () => {
+ // not reversible
+};