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

feat: geo 496 backend external include report and calculation history data to the report if it exists #408

10 changes: 8 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"eslint.enable": false
}
"eslint.enable": false,
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
},
"[sql]": {
"editor.defaultFormatter": "inferrinizzard.prettier-sql-vscode"
}
}
11 changes: 10 additions & 1 deletion backend-external/src/v1/routes/pay-transparency-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const router = express.Router();
* type: boolean
* calculation_code:
* type: string
* Report:
* ReportItem:
* type: object
* properties:
* report_id:
Expand Down Expand Up @@ -70,6 +70,15 @@ const router = express.Router();
* type: array
* items:
* $ref: "#/components/schemas/CalculatedData"
* Report:
* allOf:
* - $ref: "#/components/schemas/ReportItem"
* - type: object
* properties:
* history:
* type: array
* items:
* $ref: "#/components/schemas/ReportItem"
*
* PaginatedReports:
* type: object
Expand Down
4 changes: 4 additions & 0 deletions backend/db/migrations/V1.0.22__report_id_fk_in_history.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SET
search_path TO pay_transparency;

ALTER TABLE report_history ADD CONSTRAINT report_history_report_id FOREIGN KEY (report_id) REFERENCES pay_transparency_report (report_id);
12 changes: 8 additions & 4 deletions backend/src/v1/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,21 @@ model pay_transparency_report {
revision Decimal @db.Decimal
data_constraints String? @db.VarChar(3000)
is_unlocked Boolean @default(true)
report_unlock_date DateTime? @db.Timestamp(6)
reporting_year Decimal @db.Decimal
report_unlock_date DateTime? @db.Timestamp(6)
pay_transparency_calculated_data pay_transparency_calculated_data[]
naics_code_pay_transparency_report_naics_codeTonaics_code naics_code @relation("pay_transparency_report_naics_codeTonaics_code", fields: [naics_code], references: [naics_code], onDelete: NoAction, onUpdate: NoAction, map: "pay_transparency_report_naics_code_fk")
employee_count_range employee_count_range @relation(fields: [employee_count_range_id], references: [employee_count_range_id], onDelete: NoAction, onUpdate: NoAction, map: "pay_transparency_report_employee_count_range_id_fk")
pay_transparency_company pay_transparency_company @relation(fields: [company_id], references: [company_id], onDelete: NoAction, onUpdate: NoAction, map: "report_pt_company_id_fk")
pay_transparency_user pay_transparency_user @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction, map: "report_pt_user_id_fk")
report_history report_history[]

@@unique([company_id, user_id, reporting_year, report_status], map: "pay_transparency_report_uk")
@@index([report_id, company_id])
@@index([create_date, report_status])
@@index([company_id, report_start_date, report_end_date, report_status])
@@index([company_id, create_date, report_start_date, report_end_date, report_status])
@@index([company_id, create_date, reporting_year, report_status], map: "pay_transparency_report_company_id_create_date_report_year_idx")
@@index([company_id, reporting_year, report_status], map: "pay_transparency_report_company_id_reporting_year_report_idx")
@@index([report_unlock_date, is_unlocked])
}

model pay_transparency_user {
Expand Down Expand Up @@ -165,13 +168,14 @@ model report_history {
naics_code String @db.VarChar(5)
data_constraints String? @db.VarChar(3000)
revision Decimal @db.Decimal
report_unlock_date DateTime? @db.Timestamp(6)
is_unlocked Boolean @default(true)
reporting_year Decimal @db.Decimal
report_unlock_date DateTime? @db.Timestamp(6)
calculated_data_history calculated_data_history[]
pay_transparency_company pay_transparency_company @relation(fields: [company_id], references: [company_id], onDelete: NoAction, onUpdate: NoAction, map: "report_history_company_id_fk")
employee_count_range employee_count_range @relation(fields: [employee_count_range_id], references: [employee_count_range_id], onDelete: NoAction, onUpdate: NoAction, map: "report_history_employee_count_range_id_fk")
naics_code_report_history_naics_codeTonaics_code naics_code @relation("report_history_naics_codeTonaics_code", fields: [naics_code], references: [naics_code], onDelete: NoAction, onUpdate: NoAction)
pay_transparency_report pay_transparency_report @relation(fields: [report_id], references: [report_id], onDelete: NoAction, onUpdate: NoAction, map: "report_history_report_id")
pay_transparency_user pay_transparency_user @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction, map: "report_history_user_id_fk")
}

Expand Down
6 changes: 4 additions & 2 deletions backend/src/v1/routes/external-consumer-routes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ const REPORT = {
{
value: faker.number.float(),
is_suppressed: false,
calculation_code: `${faker.number.int()}`,
calculation_code: { calculation_code: `${faker.number.int()}` },
},
],
report_history: [],
};

describe('external-consumer-routes', () => {
Expand All @@ -84,7 +85,7 @@ describe('external-consumer-routes', () => {
{
calculation_code:
REPORT.pay_transparency_calculated_data[0]
.calculation_code,
.calculation_code.calculation_code,
is_suppressed:
REPORT.pay_transparency_calculated_data[0].is_suppressed,
value: REPORT.pay_transparency_calculated_data[0].value,
Expand Down Expand Up @@ -122,6 +123,7 @@ describe('external-consumer-routes', () => {
revision: REPORT.revision,
update_date: REPORT.update_date.toISOString(),
user_comment: REPORT.user_comment,
history: [],
},
],
totalRecords: 1,
Expand Down
11 changes: 7 additions & 4 deletions backend/src/v1/routes/report-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ reportRouter.put(
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).end();
}

const reportId: string = req.params.reportId;
let reportId: string = req.params.reportId;
const report_to_publish = await reportService.getReportById(
bceidBusinessGuid,
reportId,
Expand All @@ -105,15 +105,18 @@ reportRouter.put(
}

try {
await reportService.publishReport(report_to_publish);
reportId = await reportService.publishReport(report_to_publish);
} catch (error) {
logger.error(error);
return res.status(HttpStatus.BAD_REQUEST).send(error.message);
}

try {
const reportHtml = await reportService.getReportHtml(req, reportId);
res.type('html').status(200).send(reportHtml);
const report = await reportService.getReportById(
bceidBusinessGuid,
reportId,
);
res.status(200).send(report);
} catch (e) {
logger.error(e);
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).end();
Expand Down
187 changes: 145 additions & 42 deletions backend/src/v1/services/external-consumer-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,46 @@ const testData = {
{
value: faker.number.float(),
is_suppressed: false,
calculation_code: `${faker.number.int()}`,
calculation_code: { calculation_code: `${faker.number.int()}` },
},
],
report_history: [
{
report_id: faker.string.uuid(),
company_id: faker.string.uuid(),
naics_code: '11',
create_date: faker.date.past(),
update_date: faker.date.past(),
data_constraints: faker.lorem.sentence(),
user_comment: faker.lorem.sentence(),
revision: '12',
report_start_date: faker.date.past(),
report_end_date: faker.date.past(),
report_status: 'Published',
pay_transparency_company: {
company_name: faker.company.name(),
province: faker.location.state(),
bceid_business_guid: faker.string.uuid(),
country: faker.location.country(),
city: faker.location.city(),
postal_code: faker.location.zipCode(),
address_line1: faker.location.streetAddress(),
address_line2: faker.location.streetAddress(),
},
employee_count_range: {
employee_count_range: '50-299',
},
naics_code_report_history_naics_codeTonaics_code: {
naics_code: '11',
naics_label: faker.lorem.words(3),
},
calculated_data_history: [
{
value: faker.number.float(),
is_suppressed: false,
calculation_code: { calculation_code: `${faker.number.int()}` },
},
],
},
],
};
Expand All @@ -66,67 +105,131 @@ describe('external-consumer-service', () => {
mockFindMany.mockReturnValue([testData]);
const results = await externalConsumerService.exportDataWithPagination();
expect(results.page).toBe(0);
expect(results.pageSize).toBe(1000),
expect(results.totalRecords).toBe(1);
expect(results.records[0]).toEqual({
calculated_data: [
{
calculation_code: testData.pay_transparency_calculated_data[0].calculation_code,
is_suppressed: testData.pay_transparency_calculated_data[0].is_suppressed,
value: testData.pay_transparency_calculated_data[0].value,
},
],
company_address_line1: testData.pay_transparency_company.address_line1,
company_address_line2: testData.pay_transparency_company.address_line2,
company_bceid_business_guid: testData.pay_transparency_company.bceid_business_guid,
company_city: testData.pay_transparency_company.city,
company_country: testData.pay_transparency_company.country,
company_id: testData.company_id,
company_name:testData.pay_transparency_company.company_name,
company_postal_code: testData.pay_transparency_company.postal_code,
company_province: testData.pay_transparency_company.province,
create_date: testData.create_date,
data_constraints: testData.data_constraints,
employee_count_range: testData.employee_count_range.employee_count_range,
naics_code: testData.naics_code_pay_transparency_report_naics_codeTonaics_code.naics_code,
naics_code_label: testData.naics_code_pay_transparency_report_naics_codeTonaics_code.naics_label,
report_end_date: testData.report_end_date,
report_id: testData.report_id,
report_start_date: testData.report_start_date,
report_status: testData.report_status,
revision: testData.revision,
update_date: testData.update_date,
user_comment: testData.user_comment,
})
expect(results.pageSize).toBe(1000), expect(results.totalRecords).toBe(1);
expect(results.records[0]).toStrictEqual({
calculated_data: [
{
is_suppressed:
testData.pay_transparency_calculated_data[0].is_suppressed,
value: testData.pay_transparency_calculated_data[0].value,
calculation_code:
testData.pay_transparency_calculated_data[0].calculation_code
.calculation_code,
},
],
company_address_line1: testData.pay_transparency_company.address_line1,
company_address_line2: testData.pay_transparency_company.address_line2,
company_bceid_business_guid:
testData.pay_transparency_company.bceid_business_guid,
company_city: testData.pay_transparency_company.city,
company_country: testData.pay_transparency_company.country,
company_id: testData.company_id,
company_name: testData.pay_transparency_company.company_name,
company_postal_code: testData.pay_transparency_company.postal_code,
company_province: testData.pay_transparency_company.province,
create_date: testData.create_date,
data_constraints: testData.data_constraints,
employee_count_range: testData.employee_count_range.employee_count_range,
naics_code:
testData.naics_code_pay_transparency_report_naics_codeTonaics_code
.naics_code,
naics_code_label:
testData.naics_code_pay_transparency_report_naics_codeTonaics_code
.naics_label,
report_end_date: testData.report_end_date,
report_id: testData.report_id,
report_start_date: testData.report_start_date,
report_status: testData.report_status,
revision: testData.revision,
update_date: testData.update_date,
user_comment: testData.user_comment,
history: [
{
calculated_data: [
{
is_suppressed:
testData.report_history[0].calculated_data_history[0].is_suppressed,
value: testData.report_history[0].calculated_data_history[0].value,
calculation_code:
testData.report_history[0].calculated_data_history[0].calculation_code
.calculation_code,
},
],
company_address_line1:
testData.report_history[0].pay_transparency_company.address_line1,
company_address_line2:
testData.report_history[0].pay_transparency_company.address_line2,
company_bceid_business_guid:
testData.report_history[0].pay_transparency_company.bceid_business_guid,
company_city: testData.report_history[0].pay_transparency_company.city,
company_country: testData.report_history[0].pay_transparency_company.country,
company_id: testData.report_history[0].company_id,
company_name: testData.report_history[0].pay_transparency_company.company_name,
company_postal_code: testData.report_history[0].pay_transparency_company.postal_code,
company_province: testData.report_history[0].pay_transparency_company.province,
create_date: testData.report_history[0].create_date,
data_constraints: testData.report_history[0].data_constraints,
employee_count_range:
testData.report_history[0].employee_count_range.employee_count_range,
naics_code:
testData.report_history[0].naics_code_report_history_naics_codeTonaics_code
.naics_code,
naics_code_label:
testData.report_history[0].naics_code_report_history_naics_codeTonaics_code
.naics_label,
report_end_date: testData.report_history[0].report_end_date,
report_id: testData.report_history[0].report_id,
report_start_date: testData.report_history[0].report_start_date,
report_status: testData.report_history[0].report_status,
revision: testData.report_history[0].revision,
update_date: testData.report_history[0].update_date,
user_comment: testData.report_history[0].user_comment,
},
],
});
});

it('should parse date strings', async () => {
mockCount.mockReturnValue(1);
mockFindMany.mockReturnValue([testData]);
const results = await externalConsumerService.exportDataWithPagination("2024-01-01", '2024-01-01', -1, -1);
const results = await externalConsumerService.exportDataWithPagination(
'2024-01-01',
'2024-01-01',
-1,
-1,
);
expect(results.page).toBe(0);
expect(results.pageSize).toBe(1000),
expect(results.totalRecords).toBe(1);
expect(results.pageSize).toBe(1000), expect(results.totalRecords).toBe(1);
});

it('should fail parse invalid date strings', async () => {
mockCount.mockReturnValue(1);
mockFindMany.mockReturnValue([testData]);
try {
await externalConsumerService.exportDataWithPagination("20241-01-01", '20241-01-01', -1, -1);
await externalConsumerService.exportDataWithPagination(
'20241-01-01',
'20241-01-01',
-1,
-1,
);
} catch (error) {
expect(error.message).toBe(
'Failed to parse dates. Please use date format YYYY-MM-dd',
);
expect(error.message).toBe(
'Failed to parse dates. Please use date format YYYY-MM-dd',
);
}
});
it('should fail when endDate is before the startDate', async () => {
mockCount.mockReturnValue(1);
mockFindMany.mockReturnValue([testData]);
try {
await externalConsumerService.exportDataWithPagination("2024-01-01", '2023-01-01', -1, -1);
await externalConsumerService.exportDataWithPagination(
'2024-01-01',
'2023-01-01',
-1,
-1,
);
} catch (error) {
expect(error.message).toBe('Start date must be before the end date.');
expect(error.message).toBe('Start date must be before the end date.');
}
});
});
Loading