| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
01fb068f45 | Add preliminary letter preparation step | 3 years ago |
|
|
2f930610ac | Add case details to assign panel + additional details to the complaince review | 3 years ago |
|
|
7109777587 | Modify business name flow based on feedback | 3 years ago |
| @@ -28,6 +28,8 @@ import { MultiFileUploadComponent } from './widgets/form/multi-file-upload/multi | |||||
| import { ReviewNonComplianceComponent } from './pages/investigate-business-entities-and-individuals/review-non-compliance/review-non-compliance.component'; | import { ReviewNonComplianceComponent } from './pages/investigate-business-entities-and-individuals/review-non-compliance/review-non-compliance.component'; | ||||
| import { ConcurComplianceReviewComponent } from './pages/investigate-business-entities-and-individuals/concur-compliance-review/concur-compliance-review.component'; | import { ConcurComplianceReviewComponent } from './pages/investigate-business-entities-and-individuals/concur-compliance-review/concur-compliance-review.component'; | ||||
| import { ClosingRemarksComponent } from './pages/investigate-business-entities-and-individuals/closing-remarks/closing-remarks.component'; | import { ClosingRemarksComponent } from './pages/investigate-business-entities-and-individuals/closing-remarks/closing-remarks.component'; | ||||
| import { PreparePreliminaryLetterComponent } from './pages/investigate-business-entities-and-individuals/prepare-preliminary-letter/prepare-preliminary-letter.component'; | |||||
| import { RespondToPreliminaryLetterComponent } from './pages/investigate-business-entities-and-individuals/respond-to-preliminary-letter/respond-to-preliminary-letter.component'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| @@ -54,7 +56,9 @@ import { ClosingRemarksComponent } from './pages/investigate-business-entities-a | |||||
| MultiFileUploadComponent, | MultiFileUploadComponent, | ||||
| ReviewNonComplianceComponent, | ReviewNonComplianceComponent, | ||||
| ConcurComplianceReviewComponent, | ConcurComplianceReviewComponent, | ||||
| ClosingRemarksComponent | |||||
| ClosingRemarksComponent, | |||||
| PreparePreliminaryLetterComponent, | |||||
| RespondToPreliminaryLetterComponent | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| @@ -31,6 +31,10 @@ export class NotificationsComponent implements OnInit { | |||||
| text: 'Concur non-compliance for Entity Corp.', | text: 'Concur non-compliance for Entity Corp.', | ||||
| timeStamp: '2 hours ago', | timeStamp: '2 hours ago', | ||||
| redirectionUrl: '/tabs/investigate-business-entities-and-individuals', | redirectionUrl: '/tabs/investigate-business-entities-and-individuals', | ||||
| }, { | |||||
| text: 'Prepare preliminary letter', | |||||
| timeStamp: '2 hours ago', | |||||
| redirectionUrl: '/tabs/investigate-business-entities-and-individuals', | |||||
| }, { | }, { | ||||
| text: 'Investigation complete', | text: 'Investigation complete', | ||||
| timeStamp: '1 hours ago', | timeStamp: '1 hours ago', | ||||
| @@ -1 +1,2 @@ | |||||
| <app-view-case-details></app-view-case-details> | |||||
| <app-select-entities></app-select-entities> | <app-select-entities></app-select-entities> | ||||
| @@ -38,7 +38,7 @@ | |||||
| *ngIf="state === 'REVIEW NON COMPLIANCE'" | *ngIf="state === 'REVIEW NON COMPLIANCE'" | ||||
| [panelRemarks]="panelRemarks" | [panelRemarks]="panelRemarks" | ||||
| [isNonCompliant]="isNonCompliant" | [isNonCompliant]="isNonCompliant" | ||||
| (onNonComplianceUpdate)="isNonCompliant = $event" | |||||
| (onNonComplianceUpdate)="updateIsNonCompliant($event)" | |||||
| ></app-review-non-compliance> | ></app-review-non-compliance> | ||||
| <app-concur-compliance-review | <app-concur-compliance-review | ||||
| @@ -50,6 +50,13 @@ | |||||
| (onIsConcurringUpdate)="isPanelConcurring = $event" | (onIsConcurringUpdate)="isPanelConcurring = $event" | ||||
| (onRemarksUpdate)="updatePanelRemarks($event)" | (onRemarksUpdate)="updatePanelRemarks($event)" | ||||
| ></app-concur-compliance-review> | ></app-concur-compliance-review> | ||||
| <app-prepare-preliminary-letter | |||||
| *ngIf="state === 'PREPARE PRELIMINARY LETTER'" | |||||
| ></app-prepare-preliminary-letter> | |||||
| <app-respond-to-preliminary-letter | |||||
| *ngIf="state === 'RESPOND TO PRELIMINARY LETTER'" | |||||
| ></app-respond-to-preliminary-letter> | |||||
| <div class="form-action-buttons"> | <div class="form-action-buttons"> | ||||
| <button class="common-button neutral" *ngIf="stateHistory.length > 0" (click)="goBack()"> | <button class="common-button neutral" *ngIf="stateHistory.length > 0" (click)="goBack()"> | ||||
| @@ -1,7 +1,7 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | import { Component, OnInit } from '@angular/core'; | ||||
| type State = 'VIEW INITIAL DETAILS'|'ENTER MORE DETAILS'|'ASSIGN COMMITTEE'|'REVIEW NON COMPLIANCE'|'CONCUR COMPLIANCE REVIEW'|'CLOSING REMARKS'; | |||||
| type Role = 'Investigator'|'Hod'|'Panel'; | |||||
| type State = 'VIEW INITIAL DETAILS'|'ENTER MORE DETAILS'|'ASSIGN COMMITTEE'|'REVIEW NON COMPLIANCE'|'CONCUR COMPLIANCE REVIEW'|'CLOSING REMARKS'|'PREPARE PRELIMINARY LETTER'|'RESPOND TO PRELIMINARY LETTER'; | |||||
| type Role = 'Investigator'|'Hod'|'Panel'|'Customer'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-investigate-business-entities-and-individuals', | selector: 'app-investigate-business-entities-and-individuals', | ||||
| @@ -26,16 +26,21 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
| constructor() { | constructor() { | ||||
| const panelRemarks = localStorage.getItem('panelRemarks'); | const panelRemarks = localStorage.getItem('panelRemarks'); | ||||
| if (panelRemarks) { | if (panelRemarks) { | ||||
| this.panelRemarks = panelRemarks; | this.panelRemarks = panelRemarks; | ||||
| } | } | ||||
| this.isNonCompliant = localStorage.getItem('isNonCompliant') === 'true'; | |||||
| const loginEmail = localStorage.getItem('loginEmail'); | const loginEmail = localStorage.getItem('loginEmail'); | ||||
| if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('hod')) { | if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('hod')) { | ||||
| this.loginRole = 'Hod'; | this.loginRole = 'Hod'; | ||||
| } else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('panel')) { | } else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('panel')) { | ||||
| this.loginRole = 'Panel'; | this.loginRole = 'Panel'; | ||||
| } else if (loginEmail && loginEmail.toLocaleLowerCase().startsWith('customer')) { | |||||
| this.loginRole = 'Customer'; | |||||
| } else { | } else { | ||||
| this.loginRole = 'Investigator'; | this.loginRole = 'Investigator'; | ||||
| } | } | ||||
| @@ -63,6 +68,14 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
| this.state = 'CLOSING REMARKS'; | this.state = 'CLOSING REMARKS'; | ||||
| this.executingRole = 'Investigator'; | this.executingRole = 'Investigator'; | ||||
| break; | break; | ||||
| case 'PREPARE PRELIMINARY LETTER': | |||||
| this.state = 'PREPARE PRELIMINARY LETTER'; | |||||
| this.executingRole = 'Investigator'; | |||||
| break; | |||||
| case 'RESPOND TO PRELIMINARY LETTER': | |||||
| this.state = 'RESPOND TO PRELIMINARY LETTER'; | |||||
| this.executingRole = 'Customer'; | |||||
| break; | |||||
| default: | default: | ||||
| this.state = 'VIEW INITIAL DETAILS'; | this.state = 'VIEW INITIAL DETAILS'; | ||||
| this.executingRole = 'Investigator'; | this.executingRole = 'Investigator'; | ||||
| @@ -71,6 +84,11 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
| this.canExecute = this.loginRole === this.executingRole; | this.canExecute = this.loginRole === this.executingRole; | ||||
| } | } | ||||
| updateIsNonCompliant(isNonCompliant: boolean) { | |||||
| this.isNonCompliant = isNonCompliant; | |||||
| localStorage.setItem('isNonCompliant', String(isNonCompliant)); | |||||
| } | |||||
| updatePanelRemarks(remarks: string) { | updatePanelRemarks(remarks: string) { | ||||
| this.panelRemarks = remarks; | this.panelRemarks = remarks; | ||||
| localStorage.setItem('panelRemarks', remarks); | localStorage.setItem('panelRemarks', remarks); | ||||
| @@ -105,10 +123,18 @@ export class InvestigateBusinessEntitiesAndIndividualsComponent implements OnIni | |||||
| if (!this.isPanelConcurring) { | if (!this.isPanelConcurring) { | ||||
| this.state = 'REVIEW NON COMPLIANCE'; | this.state = 'REVIEW NON COMPLIANCE'; | ||||
| } else { | } else { | ||||
| this.state = 'CLOSING REMARKS'; | |||||
| if (this.isNonCompliant) { | |||||
| this.state = 'PREPARE PRELIMINARY LETTER'; | |||||
| } else { | |||||
| this.state = 'CLOSING REMARKS'; | |||||
| } | |||||
| } | } | ||||
| this.executingRole = 'Investigator'; | this.executingRole = 'Investigator'; | ||||
| break; | break; | ||||
| case 'PREPARE PRELIMINARY LETTER': | |||||
| this.state = 'RESPOND TO PRELIMINARY LETTER'; | |||||
| this.executingRole = 'Customer'; | |||||
| break; | |||||
| } | } | ||||
| localStorage.setItem('state', this.state); | localStorage.setItem('state', this.state); | ||||
| @@ -0,0 +1,11 @@ | |||||
| <div class="form-holder"> | |||||
| <h3>Prepare preliminary letter for customer</h3> | |||||
| <div class="two-column-holder"> | |||||
| <app-generic-input | |||||
| type="text" | |||||
| label="Email" | |||||
| placeholder="e.g. entity-name@mail.com" | |||||
| ></app-generic-input> | |||||
| </div> | |||||
| <app-multi-file-upload [maxNoOfFiles]="1" label="Preliminary letter"></app-multi-file-upload> | |||||
| </div> | |||||
| @@ -0,0 +1,22 @@ | |||||
| .form-holder { | |||||
| width: calc(70% - 2rem); | |||||
| padding: 4rem; | |||||
| margin: 0 auto; | |||||
| } | |||||
| h3 { | |||||
| font-size: 2rem; | |||||
| color: var(--dark-grey); | |||||
| filter: brightness(80%); | |||||
| font-weight: 500; | |||||
| margin: 2rem 0; | |||||
| } | |||||
| .two-column-holder { | |||||
| display: grid; | |||||
| grid-template-columns: 1fr 1fr; | |||||
| & > * { | |||||
| width: calc(100% - 2rem); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { PreparePreliminaryLetterComponent } from './prepare-preliminary-letter.component'; | |||||
| describe('PreparePreliminaryLetterComponent', () => { | |||||
| let component: PreparePreliminaryLetterComponent; | |||||
| let fixture: ComponentFixture<PreparePreliminaryLetterComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [ PreparePreliminaryLetterComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| }); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(PreparePreliminaryLetterComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,15 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-prepare-preliminary-letter', | |||||
| templateUrl: './prepare-preliminary-letter.component.html', | |||||
| styleUrls: ['./prepare-preliminary-letter.component.scss'] | |||||
| }) | |||||
| export class PreparePreliminaryLetterComponent implements OnInit { | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1 @@ | |||||
| <p>respond-to-preliminary-letter works!</p> | |||||
| @@ -0,0 +1,25 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { RespondToPreliminaryLetterComponent } from './respond-to-preliminary-letter.component'; | |||||
| describe('RespondToPreliminaryLetterComponent', () => { | |||||
| let component: RespondToPreliminaryLetterComponent; | |||||
| let fixture: ComponentFixture<RespondToPreliminaryLetterComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [ RespondToPreliminaryLetterComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| }); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(RespondToPreliminaryLetterComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,15 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-respond-to-preliminary-letter', | |||||
| templateUrl: './respond-to-preliminary-letter.component.html', | |||||
| styleUrls: ['./respond-to-preliminary-letter.component.scss'] | |||||
| }) | |||||
| export class RespondToPreliminaryLetterComponent implements OnInit { | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| } | |||||
| } | |||||
| @@ -28,6 +28,17 @@ | |||||
| ></app-file> | ></app-file> | ||||
| </div> | </div> | ||||
| <div class="files-heading">Additional details:</div> | |||||
| <div class="files-holder"> | |||||
| <app-file | |||||
| name="Details from source" | |||||
| [sizeInBytes]="160000" | |||||
| extension="docx" | |||||
| link="/assets/files/document.docx" | |||||
| ></app-file> | |||||
| <p class="paragraph-of-text">Extra remarks that have been added from the source after collecting more information.</p> | |||||
| </div> | |||||
| <app-multi-file-upload label="Analysis documents"></app-multi-file-upload> | <app-multi-file-upload label="Analysis documents"></app-multi-file-upload> | ||||
| <app-textarea | <app-textarea | ||||
| @@ -25,6 +25,13 @@ h3 { | |||||
| margin-bottom: 25px; | margin-bottom: 25px; | ||||
| } | } | ||||
| .paragraph-of-text { | |||||
| font-size: 1.6rem; | |||||
| color: var(--dark-grey); | |||||
| margin: 10px 0 25px; | |||||
| line-height: 1.4; | |||||
| } | |||||
| .files-heading { | .files-heading { | ||||
| font-size: 1.4rem; | font-size: 1.4rem; | ||||
| color: var(--primary); | color: var(--primary); | ||||
| @@ -34,6 +41,7 @@ h3 { | |||||
| } | } | ||||
| .files-holder { | .files-holder { | ||||
| margin-bottom: 10px; | |||||
| & > * { | & > * { | ||||
| margin-right: 15px; | margin-right: 15px; | ||||
| } | } | ||||
| @@ -86,7 +86,7 @@ | |||||
| <div class="tab-content"> | <div class="tab-content"> | ||||
| <div *ngIf="selectedPaymentTab === 'overview'"> | <div *ngIf="selectedPaymentTab === 'overview'"> | ||||
| Reserve and purchase this business name for a set number of years | |||||
| Reserve and purchase this business name for a period of 120 days | |||||
| </div> | </div> | ||||
| <div *ngIf="selectedPaymentTab === 'details'"> | <div *ngIf="selectedPaymentTab === 'details'"> | ||||
| <p> | <p> | ||||
| @@ -95,15 +95,8 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="year-select-input-holder input-holder"> | |||||
| <select [(ngModel)]="noOfYears"> | |||||
| <option *ngFor="let year of years" [value]="year"> {{ year }} </option> | |||||
| </select> | |||||
| <img src="assets/icons/chevron-down.svg" alt="calendar icon"> | |||||
| <label> No of years </label> | |||||
| </div> | |||||
| <section class="total-price-container"> | <section class="total-price-container"> | ||||
| S$ {{ (noOfYears * perYearPrice).toFixed(2) }} | |||||
| S$ 15.00 | |||||
| </section> | </section> | ||||
| <div class="form-action-buttons"> | <div class="form-action-buttons"> | ||||
| @@ -139,7 +132,7 @@ | |||||
| </ul> | </ul> | ||||
| <div class="total-amount"> | <div class="total-amount"> | ||||
| <label> Paid Amount </label> <span> S$ {{ (noOfYears * perYearPrice).toFixed(2) }} </span> | |||||
| <label> Paid Amount </label> <span> S$ 15.00 </span> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -199,7 +192,7 @@ | |||||
| <div class="cell"> 39047729362923293 </div> | <div class="cell"> 39047729362923293 </div> | ||||
| <div class="cell"> {{ nameToCheck }} </div> | <div class="cell"> {{ nameToCheck }} </div> | ||||
| <div class="cell"> Application for a new business name </div> | <div class="cell"> Application for a new business name </div> | ||||
| <div class="cell"> {{ (noOfYears * perYearPrice).toFixed(2) }} </div> | |||||
| <div class="cell"> 15.00 </div> | |||||
| <div class="cell"> Completed </div> | <div class="cell"> Completed </div> | ||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| @@ -22,8 +22,6 @@ export class RegisterBusinessComponent implements OnInit { | |||||
| } | } | ||||
| selectedPaymentTab: 'overview'|'details' = 'overview'; | selectedPaymentTab: 'overview'|'details' = 'overview'; | ||||
| noOfYears: number = 3; | |||||
| perYearPrice: number = 15.0; | |||||
| years: Array<number> = (new Array(15)).fill(1).map((value, index) => index + 1); | years: Array<number> = (new Array(15)).fill(1).map((value, index) => index + 1); | ||||
| paymentChild: Window | null = null; | paymentChild: Window | null = null; | ||||
| @@ -40,9 +38,6 @@ export class RegisterBusinessComponent implements OnInit { | |||||
| 'LIMITED PARTNERSHIP', | 'LIMITED PARTNERSHIP', | ||||
| 'PUBLIC ACCOUNTING FIRM' | 'PUBLIC ACCOUNTING FIRM' | ||||
| ] | ] | ||||
| }, { | |||||
| name: 'Date of Incorporation', | |||||
| type: 'date' | |||||
| }, { | }, { | ||||
| name: 'Company Category', | name: 'Company Category', | ||||
| type: 'select', | type: 'select', | ||||
| @@ -56,14 +51,6 @@ export class RegisterBusinessComponent implements OnInit { | |||||
| name: 'Company Suffix', | name: 'Company Suffix', | ||||
| type: 'select', | type: 'select', | ||||
| options: ['LLC', 'LTD', 'PVT LTD', 'INC'] | options: ['LLC', 'LTD', 'PVT LTD', 'INC'] | ||||
| }, { | |||||
| name: 'Registrar Office City', | |||||
| type: 'select', | |||||
| options: ['CITY 1', 'CITY 2'] | |||||
| }, { | |||||
| name: 'Registered Office', | |||||
| type: 'select', | |||||
| options: ['OFFICE 1', 'OFFICE 2'] | |||||
| }, { | }, { | ||||
| name: 'Drop the Suffix "Limited" or "Berhad"?', | name: 'Drop the Suffix "Limited" or "Berhad"?', | ||||
| type: 'select', | type: 'select', | ||||
| @@ -8,7 +8,7 @@ | |||||
| [extension]="file.extension" | [extension]="file.extension" | ||||
| ></app-file> | ></app-file> | ||||
| </div> | </div> | ||||
| <label> | |||||
| <label *ngIf="isAddAllowed()"> | |||||
| <input class="hidden-file-input" type="file" ng2FileSelect [uploader]="uploader" multiple (onFileSelected)="handleFilesDrop($event)" /> | <input class="hidden-file-input" type="file" ng2FileSelect [uploader]="uploader" multiple (onFileSelected)="handleFilesDrop($event)" /> | ||||
| <div class="add-button"> | <div class="add-button"> | ||||
| <img src="../../../../assets/icons/plus.svg" alt="Add file"> | <img src="../../../../assets/icons/plus.svg" alt="Add file"> | ||||
| @@ -16,10 +16,11 @@ | |||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| <div ng2FileDrop | <div ng2FileDrop | ||||
| *ngIf="isAddAllowed()" | |||||
| [uploader]="uploader" | [uploader]="uploader" | ||||
| (onFileDrop)="handleFilesDrop($event)" | (onFileDrop)="handleFilesDrop($event)" | ||||
| class="file-drop-zone" | class="file-drop-zone" | ||||
| > | > | ||||
| Drag and drop files | |||||
| Drag and drop file(s) | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -15,7 +15,8 @@ interface FileInfo { | |||||
| }) | }) | ||||
| export class MultiFileUploadComponent implements OnInit { | export class MultiFileUploadComponent implements OnInit { | ||||
| @Input() label = ''; | @Input() label = ''; | ||||
| @Input() maxNoOfFiles?: number; | |||||
| uploader: FileUploader = new FileUploader({ | uploader: FileUploader = new FileUploader({ | ||||
| url: '' | url: '' | ||||
| }); | }); | ||||
| @@ -27,6 +28,10 @@ export class MultiFileUploadComponent implements OnInit { | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| } | } | ||||
| isAddAllowed() { | |||||
| return typeof this.maxNoOfFiles === 'undefined' || this.uploadedFiles.length < this.maxNoOfFiles; | |||||
| } | |||||
| handleFilesDrop(files: Array<File>) { | handleFilesDrop(files: Array<File>) { | ||||
| for (const file of files) { | for (const file of files) { | ||||
| const fileName = file.name; | const fileName = file.name; | ||||