Skip to content

Commit

Permalink
implemented view-employee-payrolls page
Browse files Browse the repository at this point in the history
  • Loading branch information
suxrobGM committed Nov 20, 2023
1 parent 1954ff1 commit 14ca599
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {SearchableQuery} from '../searchableQuery';

export interface GetPayrollsQuery extends SearchableQuery {
employeeId?: string;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './payroll';
export * from './updatePayroll';
export * from './createPayroll';
export * from './getPayrollsQuery';
24 changes: 11 additions & 13 deletions src/Client/Logistics.OfficeApp/src/app/core/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
Payment,
CreatePayment,
UpdatePayment,
PagedQuery,
PagedIntervalQuery,
Invoice,
CreateInvoice,
Expand All @@ -43,6 +42,7 @@ import {
UpdatePayroll,
CreatePayroll,
ProcessPayment,
GetPayrollsQuery,
} from '../models';


Expand Down Expand Up @@ -287,7 +287,7 @@ export class ApiService {


// #region Payments API

getPayment(id: string): Observable<ResponseResult<Payment>> {
const url = `/payments/${id}`;
return this.get(url);
Expand Down Expand Up @@ -322,7 +322,7 @@ export class ApiService {


// #region Invoices API

getInvoice(id: string): Observable<ResponseResult<Invoice>> {
const url = `/invoices/${id}`;
return this.get(url);
Expand Down Expand Up @@ -352,14 +352,19 @@ export class ApiService {


// #region Payrolls API

getPayroll(id: string): Observable<ResponseResult<Payroll>> {
const url = `/payrolls/${id}`;
return this.get(url);
}

getPayrolls(query?: SearchableQuery): Observable<PagedResponseResult<Payroll>> {
const url = `/payrolls?${this.stringfySearchableQuery(query)}`;
getPayrolls(query?: GetPayrollsQuery): Observable<PagedResponseResult<Payroll>> {
let url = `/payrolls?${this.stringfySearchableQuery(query)}`;

if (query?.employeeId) {
url += `&employeeId=${query.employeeId}`;
}

return this.get(url);
}

Expand Down Expand Up @@ -435,13 +440,6 @@ export class ApiService {
return `search=${search}&orderBy=${orderBy}&page=${page}&pageSize=${pageSize}`;
}

private stringfyPagedQuery(query?: PagedQuery): string {
const orderBy = query?.orderBy ?? '';
const page = query?.page ?? 1;
const pageSize = query?.pageSize ?? 10;
return `orderBy=${orderBy}&page=${page}&pageSize=${pageSize}`;
}

private stringfyPagedIntervalQuery(query?: PagedIntervalQuery): string {
const startDate = query?.startDate.toJSON() ?? new Date().toJSON();
const endDate = query?.endDate?.toJSON();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {ListInvoicesComponent} from './list-invoices/list-invoices.component';
import {ViewInvoiceComponent} from './view-invoice/view-invoice.component';
import {ListPayrollComponent} from './list-payroll/list-payroll.component';
import {EditPayrollComponent} from './edit-payroll/edit-payroll.component';
import {ViewEmployeePayrollsComponent} from './view-employee-payrolls/view-employee-payrolls.component';


export const ACCOUNTING_ROUTES: Routes = [
Expand Down Expand Up @@ -82,4 +83,13 @@ export const ACCOUNTING_ROUTES: Routes = [
permission: Permissions.Payrolls.Edit,
},
},
{
path: 'employee-payrolls/:employeeId',
component: ViewEmployeePayrollsComponent,
canActivate: [AuthGuard],
data: {
breadcrumb: 'View Employee Payrolls',
permission: Permissions.Payrolls.View,
},
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<div class="d-flex align-items-center">
<h1>Employee Payrolls</h1>
<p-button
styleClass="text-black ms-2"
icon="bi bi-plus-square-fill"
size="large"
[rounded]="true"
[text]="true"
pTooltip="Add a new payroll"
[routerLink]="['/accounting/payrolls/add']">
</p-button>
</div>
<hr class="w-100">

@if (isLoadingEmployee || !employee) {
<div class="d-flex align-items-center">
<p-progressSpinner></p-progressSpinner>
<div class="ms-2">Loading employee data</div>
</div>
}
@else {
<p-card styleClass="mb-3">
<ng-template pTemplate="header">
<h4 class="ps-3 py-2">Payroll details</h4>
<hr class="w-100 m-0" />
</ng-template>

<div class="col-12 col-md-5">
<div class="row mb-3">
<div class="col-4">
<h6>Employee:</h6>
</div>
<div class="col-8">
{{employee.fullName}}
</div>
</div>
<div class="row mb-3">
<div class="col-4">
<h6>Position:</h6>
</div>
<div class="col-8">
{{employee.roles[0].displayName}}
</div>
</div>
<div class="row mb-3">
<div class="col-4">
<h6>Salary type:</h6>
</div>
<div class="col-8">
{{getSalaryTypeDesc(employee.salaryType)}}
</div>
</div>
<div class="row mb-3">
<div class="col-4">
<h6>Salary:</h6>
</div>
<div class="col-8">
@if (employee.salaryType === salaryType.ShareOfGross) {
{{employee.salary | percent}}
}
@else {
{{employee.salary | currency}}
}
</div>
</div>
</div>

</p-card>
}

<p-card>
<div class="row">
<div class="col-12">
<p-table [value]="payrolls" responsiveLayout="scroll" [lazy]="true"
[paginator]="true" [showCurrentPageReport]="true"
(onLazyLoad)="load($event)" [rows]="10" [(first)]="first"
[totalRecords]="totalRecords" [loading]="isLoadingPayrolls"
[rowsPerPageOptions]="[10,25,50]">

<ng-template pTemplate="header">
<tr>
<th>
Period
</th>
<th pSortableColumn="paymentAmount">
Payment Amount
<p-sortIcon field="paymentAmount"></p-sortIcon>
</th>
<th pSortableColumn="paymentStatus">
Payment Status
<p-sortIcon field="paymentStatus"></p-sortIcon>
</th>
<th pSortableColumn="paymentMethod">
Payment Method
<p-sortIcon field="paymentMethod"></p-sortIcon>
</th>
<th>Action</th>
</tr>
</ng-template>

<ng-template pTemplate="body" let-payroll>
<tr>
<td>{{payroll.startDate | date:'MMM d'}} - {{payroll.endDate | date:'mediumDate'}}</td>
<td>{{payroll.payment.amount | currency}}</td>
<td>
<app-payment-status-tag [paymentStatus]="payroll.payment.status"></app-payment-status-tag>
</td>
<td>{{getPaymentMethodDesc(payroll.payment.method)}}</td>
<td class="overflow-visible">
@if (payroll.payment.status === paymentStatus.Pending) {
<p-button
icon="bi bi-credit-card"
pTooltip="Make payment"
tooltipPosition="bottom"
[routerLink]="['/payment/payroll', payroll.id]">
</p-button>
}

<p-button class="ms-2"
icon="bi bi-pencil"
pTooltip="Edit payroll"
tooltipPosition="bottom"
[routerLink]="['/accounting/payrolls/edit', payroll.id]">
</p-button>
</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
</p-card>
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {Component, OnInit} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ActivatedRoute, RouterModule} from '@angular/router';
import {TableLazyLoadEvent, TableModule} from 'primeng/table';
import {TooltipModule} from 'primeng/tooltip';
import {CardModule} from 'primeng/card';
import {ButtonModule} from 'primeng/button';
import {ProgressSpinnerModule} from 'primeng/progressspinner';
import {
SalaryType,
PaymentStatus,
PaymentMethod,
PaymentMethodEnum,
SalaryTypeEnum,
} from '@core/enums';
import {Employee, Payroll} from '@core/models';
import {ApiService, ToastService} from '@core/services';
import {PaymentStatusTagComponent} from '@shared/components';


@Component({
selector: 'app-view-employee-payrolls',
standalone: true,
templateUrl: './view-employee-payrolls.component.html',
imports: [
CommonModule,
CardModule,
TooltipModule,
TableModule,
ButtonModule,
RouterModule,
PaymentStatusTagComponent,
ProgressSpinnerModule,
],
})
export class ViewEmployeePayrollsComponent implements OnInit {
private employeeId!: string;
public salaryType = SalaryType;
public paymentStatus = PaymentStatus;
public payrolls: Payroll[] = [];
public employee?: Employee;
public isLoadingEmployee = false;
public isLoadingPayrolls = false;
public totalRecords = 0;
public first = 0;

constructor(
private readonly apiService: ApiService,
private readonly route: ActivatedRoute,
private readonly toastService: ToastService)
{
}

ngOnInit(): void {
this.route.params.subscribe((params) => {
this.employeeId = params['employeeId'];
});

this.fetchEmployee();
}

load(event: TableLazyLoadEvent) {
this.isLoadingPayrolls = true;
const first = event.first ?? 1;
const rows = event.rows ?? 10;
const page = first / rows + 1;
const sortField = this.apiService.parseSortProperty(event.sortField as string, event.sortOrder);

this.apiService.getPayrolls({
orderBy: sortField,
page: page,
pageSize: rows,
employeeId: this.employeeId,
}).subscribe((result) => {
if (result.isSuccess && result.data) {
this.payrolls = result.data;
this.totalRecords = result.totalItems;
}

this.isLoadingPayrolls = false;
});
}

getPaymentMethodDesc(enumValue?: PaymentMethod): string {
if (enumValue == null) {
return 'N/A';
}

return PaymentMethodEnum.getValue(enumValue).description;
}

getSalaryTypeDesc(enumValue: SalaryType): string {
return SalaryTypeEnum.getValue(enumValue).description;
}

private fetchEmployee() {
this.isLoadingEmployee = true;

this.apiService.getEmployee(this.employeeId).subscribe((result) => {
if (result.data) {
this.employee = result.data;
}

this.isLoadingEmployee = false;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ <h1>List Employees</h1>
tooltipPosition="bottom"
[routerLink]="['/employees/edit', employee.id]">
</p-button>
<p-button
styleClass="ms-2"
icon="bi bi-file-earmark-ruled"
pTooltip="View employee payrolls"
tooltipPosition="bottom"
[routerLink]="['/accounting/employee-payrolls', employee.id]">
</p-button>
</td>
</tr>
</ng-template>
Expand Down
Loading

0 comments on commit 14ca599

Please sign in to comment.