Skip to content

Commit

Permalink
feat: [contracts] add computed statuses for view one contract
Browse files Browse the repository at this point in the history
  • Loading branch information
dragos1195 committed Sep 27, 2024
1 parent afaa2d2 commit 30add67
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { DocumentContractStatus } from 'src/modules/documents/enums/contract-status.enum';
import { DocumentContractComputedStatuses } from 'src/modules/documents/enums/contract-status.enum';
import { IDocumentContractWebItemModel } from 'src/modules/documents/models/document-contract-web-item.model';

export class DocumentContractWebItemPresenter {
Expand Down Expand Up @@ -66,9 +66,9 @@ export class DocumentContractWebItemPresenter {
@Expose()
@ApiProperty({
description: 'The status of the document contract',
enum: DocumentContractStatus,
enum: DocumentContractComputedStatuses,
})
status: DocumentContractStatus;
status: DocumentContractComputedStatuses;

@Expose()
@ApiProperty({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class DocumentClientWebViewStatus1727360448699
implements MigrationInterface
{
name = 'DocumentClientWebViewStatus1727360448699';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DELETE FROM "typeorm_metadata" WHERE "type" = $1 AND "name" = $2 AND "schema" = $3`,
['VIEW', 'DocumentContractWebItemView', 'public'],
);
await queryRunner.query(`DROP VIEW "DocumentContractWebItemView"`);
await queryRunner.query(`CREATE VIEW "DocumentContractWebItemView" AS
SELECT
dc.id as "document_id",
dc.document_number,
dc.document_start_date,
dc.document_end_date,
CASE
WHEN dc.status = 'APPROVED' AND
dc.document_start_date <= CURRENT_DATE AND
dc.document_end_date >= CURRENT_DATE
THEN 'ACTIVE'
WHEN dc.status = 'APPROVED' AND
dc.document_start_date > CURRENT_DATE
THEN 'NOT_STARTED'
WHEN dc.status = 'APPROVED' AND
dc.document_end_date < CURRENT_DATE
THEN 'EXPIRED'
ELSE dc.status::text
END AS "status",
dc.file_path as "document_file_path",
dc.document_template_id,
dt."name" as "document_template_name",
dc.volunteer_id,
dc.volunteer_data->>'name' as "volunteer_name",
dc.created_by_admin_id,
"adminUser"."name" as "created_by_admin_name",
dc.rejection_date,
dc.rejection_reason,
dc.rejected_by_id,
"rejectionUser".name as "rejected_by_name",
dc.organization_id,
dc.created_on,
dc.updated_on
FROM
document_contract dc
LEFT JOIN volunteer v ON v.id = dc.id
LEFT JOIN document_template dt on dt.id = dc.document_template_id
LEFT JOIN "user" "adminUser" ON dc.created_by_admin_id = "adminUser".id
LEFT JOIN "user" "rejectionUser" ON dc.rejected_by_id = "rejectionUser".id
`);
await queryRunner.query(
`INSERT INTO "typeorm_metadata"("database", "schema", "table", "type", "name", "value") VALUES (DEFAULT, $1, DEFAULT, $2, $3, $4)`,
[
'public',
'VIEW',
'DocumentContractWebItemView',
'SELECT\n dc.id as "document_id",\n dc.document_number,\n dc.document_start_date,\n dc.document_end_date,\n CASE \n WHEN dc.status = \'APPROVED\' AND \n dc.document_start_date <= CURRENT_DATE AND \n dc.document_end_date >= CURRENT_DATE \n THEN \'ACTIVE\'\n WHEN dc.status = \'APPROVED\' AND \n dc.document_start_date > CURRENT_DATE \n THEN \'NOT_STARTED\'\n WHEN dc.status = \'APPROVED\' AND \n dc.document_end_date < CURRENT_DATE \n THEN \'EXPIRED\'\n ELSE dc.status::text\n END AS "status",\n dc.file_path as "document_file_path",\n dc.document_template_id,\n dt."name" as "document_template_name",\n dc.volunteer_id,\n dc.volunteer_data->>\'name\' as "volunteer_name",\n dc.created_by_admin_id, \n "adminUser"."name" as "created_by_admin_name",\n \n dc.rejection_date,\n dc.rejection_reason,\n dc.rejected_by_id,\n "rejectionUser".name as "rejected_by_name",\n\n dc.organization_id,\n\n dc.created_on, \n dc.updated_on\n FROM\n document_contract dc\n LEFT JOIN volunteer v ON v.id = dc.id\n LEFT JOIN document_template dt on dt.id = dc.document_template_id\n LEFT JOIN "user" "adminUser" ON dc.created_by_admin_id = "adminUser".id\n LEFT JOIN "user" "rejectionUser" ON dc.rejected_by_id = "rejectionUser".id',
],
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`DELETE FROM "typeorm_metadata" WHERE "type" = $1 AND "name" = $2 AND "schema" = $3`,
['VIEW', 'DocumentContractWebItemView', 'public'],
);
await queryRunner.query(`DROP VIEW "DocumentContractWebItemView"`);
await queryRunner.query(`CREATE VIEW "DocumentContractWebItemView" AS SELECT
dc.id as "document_id",
dc.document_number,
dc.document_start_date,
dc.document_end_date,
dc.status,
dc.file_path as "document_file_path",
dc.document_template_id,
dt."name" as "document_template_name",
dc.volunteer_id,
dc.volunteer_data->>'name' as "volunteer_name",
dc.created_by_admin_id,
"adminUser"."name" as "created_by_admin_name",
dc.rejection_date,
dc.rejection_reason,
dc.rejected_by_id,
"rejectionUser".name as "rejected_by_name",
dc.organization_id,
dc.created_on,
dc.updated_on
FROM
document_contract dc
LEFT JOIN volunteer v ON v.id = dc.id
LEFT JOIN document_template dt on dt.id = dc.document_template_id
LEFT JOIN "user" "adminUser" ON dc.created_by_admin_id = "adminUser".id
LEFT JOIN "user" "rejectionUser" ON dc.rejected_by_id = "rejectionUser".id`);
await queryRunner.query(
`INSERT INTO "typeorm_metadata"("database", "schema", "table", "type", "name", "value") VALUES (DEFAULT, $1, DEFAULT, $2, $3, $4)`,
[
'public',
'VIEW',
'DocumentContractWebItemView',
'SELECT\n dc.id as "document_id",\n dc.document_number,\n dc.document_start_date,\n dc.document_end_date,\n dc.status,\n dc.file_path as "document_file_path",\n dc.document_template_id,\n dt."name" as "document_template_name",\n dc.volunteer_id,\n dc.volunteer_data->>\'name\' as "volunteer_name",\n dc.created_by_admin_id, \n "adminUser"."name" as "created_by_admin_name",\n \n dc.rejection_date,\n dc.rejection_reason,\n dc.rejected_by_id,\n "rejectionUser".name as "rejected_by_name",\n\n dc.organization_id,\n\n dc.created_on, \n dc.updated_on\n FROM\n document_contract dc\n LEFT JOIN volunteer v ON v.id = dc.id\n LEFT JOIN document_template dt on dt.id = dc.document_template_id\n LEFT JOIN "user" "adminUser" ON dc.created_by_admin_id = "adminUser".id\n LEFT JOIN "user" "rejectionUser" ON dc.rejected_by_id = "rejectionUser".id',
],
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Column, ViewColumn, ViewEntity } from 'typeorm';
import { DocumentContractStatus } from '../enums/contract-status.enum';
import {
DocumentContractComputedStatuses,
DocumentContractStatus,
} from '../enums/contract-status.enum';

@ViewEntity('DocumentContractWebItemView', {
/*
Expand Down Expand Up @@ -35,7 +38,19 @@ import { DocumentContractStatus } from '../enums/contract-status.enum';
dc.document_number,
dc.document_start_date,
dc.document_end_date,
dc.status,
CASE
WHEN dc.status = 'APPROVED' AND
dc.document_start_date <= CURRENT_DATE AND
dc.document_end_date >= CURRENT_DATE
THEN 'ACTIVE'
WHEN dc.status = 'APPROVED' AND
dc.document_start_date > CURRENT_DATE
THEN 'NOT_STARTED'
WHEN dc.status = 'APPROVED' AND
dc.document_end_date < CURRENT_DATE
THEN 'EXPIRED'
ELSE dc.status::text
END AS "status",
dc.file_path as "document_file_path",
dc.document_template_id,
dt."name" as "document_template_name",
Expand Down Expand Up @@ -80,7 +95,7 @@ export class DocumentContractWebItemView {
documentFilePath: string;

@ViewColumn({ name: 'status' })
status: DocumentContractStatus;
status: DocumentContractComputedStatuses;

@ViewColumn({ name: 'document_template_id' })
documentTemplateId: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { DocumentContractWebItemView } from '../entities/document-contract-web-item.entity';
import { DocumentContractStatus } from '../enums/contract-status.enum';
import { DocumentContractComputedStatuses } from '../enums/contract-status.enum';

export interface IDocumentContractWebItemModel {
documentId: string;
documentNumber: string;
documentStartDate: Date;
documentEndDate: Date;
documentFilePath: string;
status: DocumentContractStatus;
status: DocumentContractComputedStatuses;
volunteerId: string;
volunteerName: string;
organizationId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface IGetDocumentContractResponse {
documentStartDate: string;
documentEndDate: string;
documentFilePath: string | null;
status: DocumentContractStatus;
status: DocumentContractStatusForFilter;
volunteerId: string;
volunteerName: string;
organizationId: string;
Expand Down
46 changes: 23 additions & 23 deletions frontend/src/components/ContractInfoContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
formatDate,
} from '../common/utils/utils';
import StatusWithMarker from './StatusWithMarker';
import { DocumentContractStatus } from '../common/enums/document-contract-status.enum';
import { DocumentContractStatusForFilter } from '../common/enums/document-contract-status.enum';
import Button from './Button';
import { useApproveDocumentContractMutation } from '../services/document-contracts/document-contracts.service';
import Spinner from './Spinner';
Expand Down Expand Up @@ -135,39 +135,39 @@ export const ContractInfoContent = ({
label={t('contract.generated_on')}
value={formatDate(contract.createdOn, 'dd/MM/yyy')}
/>
{contract.status === DocumentContractStatus.APPROVED && (
{contract.status === DocumentContractStatusForFilter.ACTIVE && (
<FormReadOnlyElement
label={t('contract.signed_on')}
value={formatDate(contract.updatedOn, 'dd/MM/yyy')}
/>
)}
{/* rejection date, by and reason */}
{(contract.status === DocumentContractStatus.REJECTED_NGO ||
contract.status === DocumentContractStatus.REJECTED_VOLUNTEER) && (
<FormReadOnlyElement
label={t('contract.rejected_on')}
value={formatDate(contract.rejectionDate, 'dd/MM/yyy')}
/>
)}
{contract.status === DocumentContractStatus.REJECTED_NGO && (
{(contract.status === DocumentContractStatusForFilter.REJECTED_NGO ||
contract.status === DocumentContractStatusForFilter.REJECTED_VOLUNTEER) && (
<FormReadOnlyElement
label={t('contract.rejected_on')}
value={formatDate(contract.rejectionDate, 'dd/MM/yyy')}
/>
)}
{contract.status === DocumentContractStatusForFilter.REJECTED_NGO && (
<FormReadOnlyElement
label={t('contract.rejected_by')}
value={contract.rejectedByName || '-'}
/>
)}
{(contract.status === DocumentContractStatus.REJECTED_NGO ||
contract.status === DocumentContractStatus.REJECTED_VOLUNTEER) && (
<FormReadOnlyElement
label={t('contract.rejection_reason')}
value={
contract.status === DocumentContractStatus.REJECTED_VOLUNTEER
? t(`contract.rejection.${contract.rejectionReason}`)
: contract.rejectionReason || '-'
}
/>
)}
{(contract.status === DocumentContractStatusForFilter.REJECTED_NGO ||
contract.status === DocumentContractStatusForFilter.REJECTED_VOLUNTEER) && (
<FormReadOnlyElement
label={t('contract.rejection_reason')}
value={
contract.status === DocumentContractStatusForFilter.REJECTED_VOLUNTEER
? t(`contract.rejection.${contract.rejectionReason}`)
: contract.rejectionReason || '-'
}
/>
)}
</div>
{contract.status === DocumentContractStatus.PENDING_NGO_REPRESENTATIVE_SIGNATURE && (
{contract.status === DocumentContractStatusForFilter.PENDING_NGO_REPRESENTATIVE_SIGNATURE && (
<footer className="p-6 flex flex-row-reverse gap-4 border-t w-full xs:max-w-xs sm:max-w-md fixed bottom-0 right-0 bg-white">
<Button
label={t('contract.actions.sign')}
Expand All @@ -187,7 +187,7 @@ export const ContractInfoContent = ({
/>
</footer>
)}
{contract.status === DocumentContractStatus.PENDING_APPROVAL_NGO && (
{contract.status === DocumentContractStatusForFilter.PENDING_APPROVAL_NGO && (
<footer className="p-6 flex flex-row-reverse gap-4 border-t w-full xs:max-w-xs sm:max-w-md fixed bottom-0 right-0 bg-white">
<Button
label={t('contract.actions.send_to_signing')}
Expand Down

0 comments on commit 30add67

Please sign in to comment.