dev_mashfiq #33
|
@ -11,6 +11,7 @@ import { EnumLetterOrganizationType } from '../../_models/enums';
|
|||
import { LetterRequest } from '../../_models/Letter-Request/Letter-Request';
|
||||
import { AuthorizedPerson } from '../../adhoc-feature/authorized-persons/authorizedPerson';
|
||||
import { WFMovementTran } from '../../_models/Work-Flow/wFMovementTran';
|
||||
import { SearchEmployee } from 'src/app/_models/Employee/searchEmployee';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -233,6 +234,10 @@ export class LetterRequestService {
|
|||
getImage(id: number) {
|
||||
return this.apiService.httpGet<any>('/LetterRequest/getImage' + '/' + id);
|
||||
}
|
||||
generatedExceptiinLetter(type: number, param: SearchEmployee[]) {
|
||||
return this.apiService.httpPost('/LetterRequest/generatedExceptiinLetter/' + type , param);
|
||||
// return this.apiService.httpDownloadFile('/LetterRequest/generatedExceptiinLetter/' + type , param);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import {LetterRequestByAdminApprovalComponent} from './letter-request-by-admin-a
|
|||
import {ApproveFinancialDataComponent} from './approve-financial-data/approve-financial-data.component';
|
||||
import {AuthorizedPersonsComponent} from './authorized-persons/authorized-persons.component';
|
||||
import { LetterGenerateComponent } from './letter-generate/letter-generate.component';
|
||||
import { ExceptionLetterGenerateComponent } from './exception-letter-generate/exception-letter-generate.component';
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
|
@ -31,6 +32,7 @@ const routes: Routes = [
|
|||
{path: 'letter-generate', component: LetterGenerateComponent, canActivate: [AuthGuard]},
|
||||
{path: 'workflow-delegation-by-employee', component: WorkflowDelegationByEmployeeComponent, canActivate: [AuthGuard]},
|
||||
{path: 'delegation-from-admin-panel', component: DelegationFromAdminPanelComponent, canActivate: [AuthGuard]},
|
||||
{path: 'exception-letter-generate', component: ExceptionLetterGenerateComponent, canActivate: [AuthGuard]},
|
||||
//{path: 'letter-request-by-employee-and-approval', component: LetterRequestByEmployeeAndApprovalComponent, canActivate: [AuthGuard]},
|
||||
//{path: 'letter-request-approval', component: LetterRequestApprovalComponent, canActivate: [AuthGuard]},
|
||||
//{path: 'letter-print-by-admin-panel', component: LetterPrintByAdminPanelComponent, canActivate: [AuthGuard]},
|
||||
|
|
|
@ -49,13 +49,14 @@ import { ApproveFinancialDataComponent } from './approve-financial-data/approve-
|
|||
import { AuthorizedPersonsComponent } from './authorized-persons/authorized-persons.component';
|
||||
import { AuthorizedPersonComponent } from './authorized-persons/authorized-person/authorized-person.component';
|
||||
import { LetterGenerateComponent } from './letter-generate/letter-generate.component';
|
||||
import { ExceptionLetterGenerateComponent } from './exception-letter-generate/exception-letter-generate.component';
|
||||
|
||||
@NgModule({
|
||||
|
||||
declarations: [workflowRuleComponent, WorkFlowSetupComponent, WorkFlowSetupNewComponent, WorkFlowAdministrativeStatusComponent,
|
||||
WorkFlowAdminComponent, WorkflowDelegationByEmployeeComponent, DelegationFromAdminPanelComponent,
|
||||
LetterRequestApprovalComponent, LetterPrintByAdminPanelComponent,
|
||||
LetterRequestByAdminApprovalComponent, ApproveFinancialDataComponent, AuthorizedPersonsComponent, AuthorizedPersonComponent, LetterGenerateComponent
|
||||
LetterRequestByAdminApprovalComponent, ApproveFinancialDataComponent, AuthorizedPersonsComponent, AuthorizedPersonComponent, LetterGenerateComponent, ExceptionLetterGenerateComponent
|
||||
],
|
||||
|
||||
imports: [
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<app-loading-panel> </app-loading-panel>
|
||||
<div class="card" style="padding:10px;">
|
||||
<div class="p-grid">
|
||||
<div class="p-col-12">
|
||||
<div class="p-grid">
|
||||
<div class="p-col-4 p-md-2">
|
||||
<label>Employee(s)</label>
|
||||
</div>
|
||||
<div class="p-col-8 p-md-4">
|
||||
<!-- <app-employee-picker (ItemSelected)="GetSelectedEmployee($event)" [setSelectedEmp]="selectedEmps"
|
||||
[MultiSelect]="true"></app-employee-picker> -->
|
||||
<app-employee-picker (ItemSelected)="GetSelectedEmployee($event)"
|
||||
[MultiSelect]="true"></app-employee-picker>
|
||||
</div>
|
||||
<div class="p-col-4 p-md-2">
|
||||
<label>Letter</label>
|
||||
</div>
|
||||
<div class="p-col-8 p-md-4">
|
||||
<kendo-dropdownlist [(ngModel)]="selectedreportType" [data]="reportTypes" [textField]="'text'"
|
||||
[valueField]="'value'" [defaultItem]="{ text: 'Select Letter..', value: null }"
|
||||
(valueChange)="onSelectReport($event)">
|
||||
</kendo-dropdownlist>
|
||||
</div>
|
||||
<div class="p-col-12">
|
||||
<kendo-grid #grid [data]="selectedEmps" [kendoGridSelectBy]="'employeeID'" [selectedKeys]="mySelection" [pageable]="false" [sortable]="true" [reorderable]="true"
|
||||
[resizable]="true">
|
||||
<!-- <ng-template kendoGridToolbarTemplate>
|
||||
<button type="button" kendoButton icon="delete" class="kt-delete" (click)="onClickRemoveAll()">
|
||||
Remove All
|
||||
</button>
|
||||
<kendo-grid-spacer></kendo-grid-spacer>
|
||||
<label>Attendance Count: {{employeeList.length}} </label>
|
||||
</ng-template> -->
|
||||
<kendo-grid-checkbox-column [resizable]="false" [width]="45" showSelectAll="true">
|
||||
</kendo-grid-checkbox-column>
|
||||
<kendo-grid-column field="employeeNo" title="Employee No" [width]="150">
|
||||
</kendo-grid-column>
|
||||
<kendo-grid-column field="name" title="Employee Name" [width]="220">
|
||||
</kendo-grid-column>
|
||||
<kendo-grid-column field="departmentName" title="Department" [width]="220">
|
||||
</kendo-grid-column>
|
||||
<kendo-grid-column field="gradeName" title="Grade" [width]="220">
|
||||
</kendo-grid-column>
|
||||
<!-- <kendo-grid-column title="Actions" width="25%" align="middle">
|
||||
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
|
||||
<button kendoButton class="kt-delete" icon="delete" style="width: fit-content;"
|
||||
(click)="onClickRemove(dataItem)">Remove</button>
|
||||
</ng-template>
|
||||
</kendo-grid-column> -->
|
||||
</kendo-grid>
|
||||
<div class="p-col-12" align="right">
|
||||
<button kendoButton icon="upload" type="button" (click)="generateLetter()" [primary] = true>Generate</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,162 @@
|
|||
import { error } from 'console';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { DynamicPicker, EnumDynamicpickerType } from '../../picker/dynamic-picker/Dynamic-Picker';
|
||||
import { SearchEmployee } from 'src/app/_models/Employee/searchEmployee';
|
||||
import { Router } from '@angular/router';
|
||||
import { ApiService } from 'src/app/app.api.service';
|
||||
import { HRMNotificationService } from 'src/app/app.notification.service';
|
||||
import { loadingPanelService } from 'src/app/hrm-loding panel/loding.panel.service';
|
||||
import { BasicService } from 'src/app/_services/Basic/basic.service';
|
||||
import { Department } from 'src/app/_models/Basic/department';
|
||||
import { Grade } from 'src/app/_models/Basic/grade';
|
||||
import { EnumStatus } from '../../_models/enums';
|
||||
import { Employee } from 'src/app/_models/Employee/employee';
|
||||
import { LetterRequestService } from 'src/app/_services/letter-request/letter-request.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
@Component({
|
||||
selector: 'app-exception-letter-generate',
|
||||
templateUrl: './exception-letter-generate.component.html',
|
||||
styleUrls: ['./exception-letter-generate.component.scss']
|
||||
})
|
||||
export class ExceptionLetterGenerateComponent implements OnInit {
|
||||
|
||||
public selectedEmps: SearchEmployee[] = [];
|
||||
public mySelection: number[] = [];
|
||||
|
||||
public selectedreportType: EnumExceptionLetterTemplateType;
|
||||
public reportTypes = Object.keys(EnumExceptionLetterTemplateType)
|
||||
.filter(key => !isNaN(Number(EnumExceptionLetterTemplateType[key])))
|
||||
.map(key => ({
|
||||
text: key.replace(/_/g, ' '),
|
||||
value: EnumExceptionLetterTemplateType[key]
|
||||
}));
|
||||
public allDepartments: Department[];
|
||||
public allGrades: Grade[];
|
||||
|
||||
constructor(
|
||||
public router: Router, public loadingPanel: loadingPanelService,
|
||||
public notificationService: HRMNotificationService,
|
||||
public apiService: ApiService,
|
||||
public basicService: BasicService, public letterRequestService: LetterRequestService) {
|
||||
this.apiService.selectedMenuName = 'Employee Letter Generation';
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// this.basicService.getAllDepartment(EnumStatus.Active).subscribe(
|
||||
// (resp) => {
|
||||
// this.allDepartments = resp;
|
||||
// },
|
||||
// (err: any) => {
|
||||
// this.notificationService.showError(err.error);
|
||||
// }
|
||||
// );
|
||||
// this.basicService.getAllGrade(EnumStatus.Active).subscribe(
|
||||
// (resp) => {
|
||||
// this.allGrades = resp;
|
||||
// },
|
||||
// (err: any) => {
|
||||
// this.notificationService.showError(err.error);
|
||||
// }
|
||||
// );
|
||||
}
|
||||
public GetSelectedEmployee(childData) {
|
||||
this.selectedEmps = childData;
|
||||
// this.selectedEmps.forEach(element => {
|
||||
// element.departmentName = this.allDepartments.find(d => d.id == element.departmentID).name;
|
||||
// element.gradeName = this.allDepartments.find(g => g.id == element.gradeID).name;
|
||||
// });
|
||||
}
|
||||
|
||||
public onSelectReport(value: any) {
|
||||
debugger;
|
||||
}
|
||||
generateLetter() {
|
||||
let employeeDataToGenerate: SearchEmployee[] = [];
|
||||
this.selectedEmps.forEach(element => {
|
||||
this.mySelection.forEach(item => {
|
||||
if (element.employeeID == item) employeeDataToGenerate.push(element);
|
||||
});
|
||||
});
|
||||
this.selectedreportType;
|
||||
if (this.selectedreportType == undefined || this.selectedreportType['value'] == null) {
|
||||
this.notificationService.showWarning("Please select a Letter to Generate");
|
||||
return;
|
||||
}
|
||||
if (employeeDataToGenerate.length <= 0) {
|
||||
this.notificationService.showWarning("Please select Employee to Generate Letter");
|
||||
return;
|
||||
}
|
||||
this.loadingPanel.ShowLoadingPanel = true;
|
||||
this.letterRequestService.generatedExceptiinLetter(this.selectedreportType['value'], employeeDataToGenerate).subscribe(
|
||||
(resp: any[]) => {
|
||||
debugger
|
||||
if (resp.length > 0) {
|
||||
resp.forEach(fileData => {
|
||||
// this.downloadBlob(new Blob([fileData.fileContents], { type: 'application/msword' }), 'application/msword', fileData.fileDownloadName);
|
||||
this.downloadFileWord(fileData.fileContents, fileData.fileDownloadName);
|
||||
});
|
||||
}
|
||||
|
||||
this.loadingPanel.ShowLoadingPanel = false;
|
||||
},
|
||||
(err: any) => {
|
||||
this.notificationService.showError(err.error);
|
||||
this.loadingPanel.ShowLoadingPanel = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private downloadBlob(data: any, type: string, fileName: string): void {
|
||||
const blob: Blob = new Blob([data], { type: type });
|
||||
// const fileName: string = this.workOrderBillReceive.UploadAttachment[0].OriginalFileName;
|
||||
// const fileName: string = fileName;
|
||||
const objectUrl: string = URL.createObjectURL(blob);
|
||||
const a: HTMLAnchorElement = document.createElement('a') as HTMLAnchorElement;
|
||||
|
||||
a.href = objectUrl;
|
||||
a.download = fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
downloadFileWord(blobContent, fileName) {
|
||||
// const blob = new Blob([this.b64toBlob(blobContent, 'application/data:application/vnd.openxmlformats-officedocument.wordprocessingml.document', 1024)], {});
|
||||
// saveAs(blob, fileName + '.docx');
|
||||
const blob = new Blob([this.b64toBlob(blobContent, 'application/msword', 1024)], {});
|
||||
saveAs(blob, fileName);
|
||||
}
|
||||
|
||||
b64toBlob(b64Data, contentType, sliceSize) {
|
||||
const byteCharacters = atob(b64Data);
|
||||
const byteArrays = [];
|
||||
|
||||
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
||||
const slice = byteCharacters.slice(offset, offset + sliceSize);
|
||||
|
||||
const byteNumbers = new Array(slice.length);
|
||||
for (let i = 0; i < slice.length; i++) {
|
||||
byteNumbers[i] = slice.charCodeAt(i);
|
||||
}
|
||||
|
||||
const byteArray = new Uint8Array(byteNumbers);
|
||||
byteArrays.push(byteArray);
|
||||
}
|
||||
|
||||
const blob = new Blob(byteArrays, { type: contentType });
|
||||
return blob;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export enum EnumExceptionLetterTemplateType {
|
||||
Letter_Template_Staff = 1,
|
||||
Letter_Template_Worker = 2
|
||||
}
|
|
@ -55,6 +55,7 @@
|
|||
|
||||
<div class="card" *ngIf="showPopUp" class="blur-background">
|
||||
<kendo-window [height]="600" title="{{PDFTitle}}" *ngIf="showPopUp" (close)="closeForm()" [style]="{'min-width': '70%','max-width': '100%', 'max-height': '100%'}">
|
||||
<app-loading-panel></app-loading-panel>
|
||||
<div class='embed-responsive'>
|
||||
<iframe class="pdf-viewer" id="pdf-viewer-ml" type='application/pdf' [zoom]="zoomLevel"></iframe>
|
||||
</div>
|
||||
|
|
|
@ -60,6 +60,7 @@ export class LetterGenerateComponent implements OnInit {
|
|||
};
|
||||
}
|
||||
this.showPopUp = true;
|
||||
this.loadingPanelService.ShowLoadingPanel = true;
|
||||
this.reportService.getAppointmentLetter(data).subscribe(
|
||||
(resp: any) => {
|
||||
if (this.reportType === 'PDF'){
|
||||
|
|
|
@ -11,11 +11,13 @@ using AutoMapper.Configuration;
|
|||
using Google.Protobuf.WellKnownTypes;
|
||||
using HRM.BO;
|
||||
using HRM.DA;
|
||||
using HRM.Report;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NPOI.HPSF;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using static HRM.Report.PayrollDataSet.PayrollDataSet;
|
||||
|
@ -783,6 +785,88 @@ namespace HRM.UI.Controllers
|
|||
}
|
||||
|
||||
|
||||
[HttpPost("generatedExceptiinLetter/{letterType}")]
|
||||
public ActionResult generatedExceptiinLetter(int letterType, List<SearchEmployee> employees)
|
||||
{
|
||||
CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);
|
||||
int payrollTypeId = currentUser.PayrollTypeID.GetValueOrDefault();
|
||||
//string downloadPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\Downloads";
|
||||
string downloadPath = System.Environment.CurrentDirectory + "\\Documents\\LetterTempFolder\\";
|
||||
string lFileName = string.Empty;
|
||||
|
||||
|
||||
//List<string> sFilePaths = new List<string>();
|
||||
List<Tuple<byte[], string, string>> filesWithContents = new List<Tuple<byte[], string, string>>();
|
||||
List<FileContentResult> files = new List<FileContentResult>();
|
||||
|
||||
LetterTemplte ltemplate = new LetterTemplte();
|
||||
|
||||
byte[] bytes = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (letterType == 1)
|
||||
{
|
||||
ltemplate.SetObjectID(FixedLetterTemplte.Staff_Appointment_Letter);
|
||||
|
||||
ltemplate.ID = 2;
|
||||
ltemplate.Description = "Letter Template Staff";
|
||||
ltemplate.Subject = "Letter Template Staff";
|
||||
ltemplate.Type = EnumDocType.Desktop_Letter;
|
||||
ltemplate.TypeID = (int)EnumDocType.Desktop_Letter;
|
||||
|
||||
lFileName = "Staff.doc";
|
||||
}
|
||||
else
|
||||
{
|
||||
ltemplate.SetObjectID(FixedLetterTemplte.Worker_Appointment_Letter);
|
||||
|
||||
ltemplate.ID = 3;
|
||||
ltemplate.Description = "Letter Template Worker";
|
||||
ltemplate.Subject = "Letter Template Worker";
|
||||
ltemplate.Type = EnumDocType.Desktop_Letter;
|
||||
ltemplate.TypeID = (int)EnumDocType.Desktop_Letter;
|
||||
|
||||
lFileName = "Worker.doc";
|
||||
|
||||
}
|
||||
|
||||
if (employees != null && employees.Count > 0)
|
||||
{
|
||||
foreach (var emp in employees)
|
||||
{
|
||||
string sFilePath = new rptEmployee().Generate(ltemplate, emp.EmployeeID, payrollTypeId, downloadPath, lFileName);
|
||||
byte[] buffer = new byte[16 * 1024];
|
||||
buffer = System.IO.File.ReadAllBytes(sFilePath);
|
||||
string contentType = GetFileType(sFilePath);
|
||||
var name = lFileName;
|
||||
if (System.IO.File.Exists(sFilePath))
|
||||
{
|
||||
System.IO.File.Delete(sFilePath);
|
||||
}
|
||||
|
||||
//sFilePaths.Add(sFilePath);
|
||||
filesWithContents.Add(new Tuple<byte[], string, string>(buffer, emp.EmployeeNo + "_" + name, contentType));
|
||||
|
||||
var file = File(buffer, contentType, emp.EmployeeNo + "_" + name);
|
||||
//return file;
|
||||
files.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//return Ok(filesWithContents);
|
||||
return Ok(files);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user