Sub-recipients
@@ -23,31 +29,35 @@
-
-
- {{ props.row.upload_id }}
-
-
-
-
-
-
+
+
+
+ {{ props.row.upload_id }}
+
+
+
+
+
+
+
+
+ -
+ {{ col }}:
+ {{ value }}
+
-
- -
- {{ col }}:
- {{ value }}
-
-
-
-
-
- Edit
-
-
-
- {{props.formattedRow[props.column.field]}}
-
+
+
+
+ Edit
+
+
+
+
+
+ {{props.formattedRow[props.column.field]}}
+
+
@@ -59,7 +69,7 @@ import moment from 'moment';
import 'vue-good-table/dist/vue-good-table.css';
import { VueGoodTable } from 'vue-good-table';
-import { getJson } from '../store/index';
+import { getJson, post } from '../store/index';
export default {
name: 'Subrecipients',
@@ -71,7 +81,9 @@ export default {
},
computed: {
rows() {
- return this.recipients.map((r) => ({ ...r, json: JSON.parse(r.record) }));
+ const rows = this.recipients.map((r) => ({ ...r, json: JSON.parse(r.record) }));
+ console.log(rows);
+ return rows;
},
columns() {
return [
@@ -123,6 +135,31 @@ export default {
this.$refs.recipientsTable.reset();
this.$refs.recipientsTable.changeSort([]);
},
+
+ /**
+ * Archive or restore a subrecipient.
+ *
+ * Call this method to archive or unarchive a subrecipient record.
+ *
+ * @param {*} id
+ * The ID of the subrecipient to archive or restore.
+ */
+ async archiveOrRestoreSubrecipient(id) {
+ this.loading = true;
+
+ const result = await post(`/api/subrecipients/archive/${id}`);
+ if (result.error) {
+ this.$store.commit('addAlert', {
+ text: `archiveOrRestoreSubrecipient Error (${result.status}): ${result.error}`,
+ level: 'err',
+ });
+ } else {
+ this.recipients = this.recipients.map((recipient) => (recipient.id === id ? result.recipient : recipient));
+ }
+
+ this.loading = false;
+ },
+
async loadRecipients() {
this.loading = true;
diff --git a/packages/server/__tests__/arpa_reporter/server/lib/audit-report.spec.js b/packages/server/__tests__/arpa_reporter/server/lib/audit-report.spec.js
index ccc087b2b..2cc5d8ba4 100644
--- a/packages/server/__tests__/arpa_reporter/server/lib/audit-report.spec.js
+++ b/packages/server/__tests__/arpa_reporter/server/lib/audit-report.spec.js
@@ -11,6 +11,8 @@ const audit_report = require('../../../../src/arpa_reporter/lib/audit-report');
const aws = require('../../../../src/lib/gost-aws');
const { withTenantId } = require('../helpers/with-tenant-id');
+const OLD_AUDIT_REPORT_BUCKET = process.env.AUDIT_REPORT_BUCKET;
+
function handleUploadFake(type) {
if (type === 'success') {
return () => {
@@ -26,7 +28,11 @@ function handleUploadFake(type) {
describe('audit report generation', () => {
const sandbox = sinon.createSandbox();
+ beforeEach(() => {
+ process.env.AUDIT_REPORT_BUCKET = 'arpa-audit-reports';
+ });
afterEach(() => {
+ process.env.AUDIT_REPORT_BUCKET = OLD_AUDIT_REPORT_BUCKET;
sandbox.restore();
});
it('sendEmailWithLink creates a presigned url and sends email to recipient', async () => {
diff --git a/packages/server/migrations/20240118000244_add_subrecipients_archived_col.js b/packages/server/migrations/20240118000244_add_subrecipients_archived_col.js
new file mode 100644
index 000000000..54ba31d2f
--- /dev/null
+++ b/packages/server/migrations/20240118000244_add_subrecipients_archived_col.js
@@ -0,0 +1,19 @@
+/**
+ * @param { import("knex").Knex } knex
+ * @returns { Promise }
+ */
+exports.up = function (knex) {
+ return knex.schema.table('arpa_subrecipients', (table) => {
+ table.timestamp('archived_at');
+ });
+};
+
+/**
+ * @param { import("knex").Knex } knex
+ * @returns { Promise }
+ */
+exports.down = function (knex) {
+ return knex.schema.table('arpa_subrecipients', (table) => {
+ table.dropColumn('archived_at');
+ });
+};
diff --git a/packages/server/src/arpa_reporter/db/arpa-subrecipients.js b/packages/server/src/arpa_reporter/db/arpa-subrecipients.js
index 5c983e5da..3b394f365 100644
--- a/packages/server/src/arpa_reporter/db/arpa-subrecipients.js
+++ b/packages/server/src/arpa_reporter/db/arpa-subrecipients.js
@@ -14,6 +14,29 @@ function baseQuery(trns) {
.leftJoin('users AS users2', 'arpa_subrecipients.updated_by', 'users2.id');
}
+/**
+ * Archive or restore a subrecipient.
+ *
+ * Call t his method to archive or restore an arpa_subrecipients table.
+ */
+async function archiveOrRestoreRecipient(id, { updatedByUser }, trns = knex) {
+ const query = trns('arpa_subrecipients')
+ .where('id', id)
+ .returning('*');
+
+ if (updatedByUser) {
+ query.update('updated_by', updatedByUser.id);
+ query.update('updated_at', knex.fn.now());
+ }
+
+ query.update(
+ 'archived_at',
+ knex.raw('CASE WHEN archived_at IS NULL THEN ?? ELSE NULL END', [knex.fn.now()]),
+ );
+
+ return query.then((rows) => rows[0]);
+}
+
async function createRecipient(recipient, trns = knex) {
const tenantId = useTenantId();
if (!(recipient.uei || recipient.tin)) {
@@ -70,10 +93,11 @@ async function listRecipients(trns = knex) {
}
async function listRecipientsForReportingPeriod(periodId, trns = knex) {
- return baseQuery(trns).where('reporting_period_id', periodId);
+ return baseQuery(trns).where('reporting_period_id', periodId).whereNotNull('archived_at');
}
module.exports = {
+ archiveOrRestoreRecipient,
createRecipient,
getRecipient,
findRecipient,
diff --git a/packages/server/src/arpa_reporter/routes/subrecipients.js b/packages/server/src/arpa_reporter/routes/subrecipients.js
index 83c3d8d36..5a7e960a4 100644
--- a/packages/server/src/arpa_reporter/routes/subrecipients.js
+++ b/packages/server/src/arpa_reporter/routes/subrecipients.js
@@ -3,7 +3,9 @@ const express = require('express');
const router = express.Router();
const { requireUser } = require('../../lib/access-helpers');
-const { listRecipients, getRecipient, updateRecipient } = require('../db/arpa-subrecipients');
+const {
+ listRecipients, getRecipient, updateRecipient, archiveOrRestoreRecipient,
+} = require('../db/arpa-subrecipients');
const { getRules } = require('../services/validation-rules');
router.get('/', requireUser, async (req, res) => {
@@ -46,6 +48,21 @@ router.post('/:id', requireUser, async (req, res) => {
res.json({ recipient: updatedRecipient });
});
+router.post('/archive/:id', requireUser, async (req, res) => {
+ const id = Number(req.params.id);
+ const { user } = req.session;
+
+ const recipient = await getRecipient(id);
+ if (!recipient || recipient.tenant_id !== req.session.user.tenant_id) {
+ res.sendStatus(404);
+ res.end();
+ return;
+ }
+
+ const updatedRecipient = await archiveOrRestoreRecipient(recipient.id, { updatedByUser: user });
+ res.json({ recipient: updatedRecipient });
+});
+
module.exports = router;
// NOTE: This file was copied from src/server/routes/subrecipients.js (git @ ada8bfdc98) in the arpa-reporter repo on 2022-09-23T20:05:47.735Z