Skip to content

Commit db79d8c

Browse files
committed
fixed payroll issues
1 parent fa1c201 commit db79d8c

File tree

20 files changed

+192
-129
lines changed

20 files changed

+192
-129
lines changed

src/Client/Logistics.OfficeApp/src/app/layout/sidebar/sidebar.component.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
<p-button severity="secondary"
6868
[text]="true"
6969
[label]="item.label"
70-
(click)="item?.command({})">
70+
[routerLink]="item.routerLink"
71+
(onClick)="accountingPanel.hide()">
7172
</p-button>
7273
</div>
7374
}

src/Client/Logistics.OfficeApp/src/app/pages/accounting/edit-payroll/edit-payroll.component.html

+37-28
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,6 @@ <h1 class="text-center">{{title}}</h1>
3131
(onSelect)="handleAutoCompleteSelectEvent($event)">
3232
</p-autoComplete>
3333
</div>
34-
35-
<!-- <div *ngIf="isEditMode()" class="mb-3">
36-
<label for="paymentStatus" class="form-label">Payment Status</label>
37-
<p-dropdown formControlName="paymentStatus" styleClass="w-100" [options]="paymentStatuses"
38-
optionValue="value" optionLabel="description">
39-
</p-dropdown>
40-
</div> -->
41-
<!-- <div class="mb-3">
42-
<label for="paymentMethod" class="form-label">Payment Method</label>
43-
<p-dropdown formControlName="status" styleClass="w-100" [options]="paymentMethods"
44-
optionValue="value" optionLabel="description">
45-
</p-dropdown>
46-
</div> -->
4734

4835
@if (selectedEmployee && computedPayroll) {
4936
<h4>Payment details</h4>
@@ -53,7 +40,7 @@ <h4>Payment details</h4>
5340
<p><strong>Employee's Salary Type:</strong> {{getSalaryTypeDesc(selectedEmployee.salaryType)}}</p>
5441
<p>
5542
<strong>Employee's Salary:</strong>
56-
@if (isShareOfGrossSalary()) {
43+
@if (selectedEmployee.salaryType === salaryType.ShareOfGross) {
5744
{{selectedEmployee.salary | percent}}
5845
}
5946
@else {
@@ -62,21 +49,43 @@ <h4>Payment details</h4>
6249
</p>
6350
<p><strong>Expected Payment:</strong> {{computedPayroll.payment.amount | currency}}</p>
6451
}
52+
53+
@if (isEditMode()) {
54+
<div class="mb-3">
55+
<label for="paymentStatus" class="form-label">Payment Status</label>
56+
<p-dropdown formControlName="paymentStatus" styleClass="w-100" [options]="paymentStatuses"
57+
optionValue="value" optionLabel="description">
58+
</p-dropdown>
59+
</div>
60+
61+
@if (form.get('paymentStatus')?.value === paymentStatus.Paid) {
62+
<h4>Payment details</h4>
63+
<hr/>
64+
65+
<div class="mb-3">
66+
<label for="paymentMethod" class="form-label">Payment Method</label>
67+
<p-dropdown formControlName="paymentMethod" styleClass="w-100" [options]="paymentMethods"
68+
optionValue="value" optionLabel="description">
69+
</p-dropdown>
70+
</div>
71+
72+
<h5>Billing address</h5>
73+
<app-address-form formControlName="paymentBillingAddress"></app-address-form>
74+
}
75+
}
6576

66-
<div>
67-
<p-button type="submit"
68-
class="mt-3"
69-
icon="bi bi-pencil-square"
70-
label="Save"
71-
[disabled]="isLoading">
72-
</p-button>
73-
<p-button type="button"
74-
class="mt-3 ms-2"
75-
icon="bi bi-arrow-left-square"
76-
label="Back to list"
77-
[routerLink]="['/accounting/payrolls']">
78-
</p-button>
79-
</div>
77+
<p-button type="submit"
78+
class="mt-3"
79+
icon="bi bi-pencil-square"
80+
label="Save"
81+
[disabled]="isLoading || !form.valid || computedPayroll?.payment?.amount === 0">
82+
</p-button>
83+
<p-button type="button"
84+
class="mt-3 ms-2"
85+
icon="bi bi-arrow-left-square"
86+
label="Back to list"
87+
[routerLink]="['/accounting/payrolls']">
88+
</p-button>
8089
</form>
8190
</p-card>
8291
</div>

src/Client/Logistics.OfficeApp/src/app/pages/accounting/edit-payroll/edit-payroll.component.ts

+51-8
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ import {ButtonModule} from 'primeng/button';
1212
import {CreatePayroll, Employee, Payroll, UpdatePayroll} from '@core/models';
1313
import {ApiService, ToastService} from '@core/services';
1414
import {PredefinedDateRanges} from '@core/helpers';
15-
import {SalaryType, SalaryTypeEnum} from '@core/enums';
16-
import {ValidationSummaryComponent} from '@shared/components';
15+
import {
16+
PaymentMethod,
17+
PaymentMethodEnum,
18+
PaymentStatus,
19+
PaymentStatusEnum,
20+
SalaryType,
21+
SalaryTypeEnum,
22+
convertEnumToArray,
23+
} from '@core/enums';
24+
import {AddressFormComponent, ValidationSummaryComponent} from '@shared/components';
1725
import {DateUtils} from '@shared/utils';
1826

1927

@@ -33,9 +41,14 @@ import {DateUtils} from '@shared/utils';
3341
ReactiveFormsModule,
3442
CalendarModule,
3543
ButtonModule,
44+
AddressFormComponent,
3645
],
3746
})
3847
export class EditPayrollComponent implements OnInit {
48+
public salaryType = SalaryType;
49+
public paymentStatus = PaymentStatus;
50+
public paymentStatuses = convertEnumToArray(PaymentStatusEnum);
51+
public paymentMethods = convertEnumToArray(PaymentMethodEnum);
3952
public title = 'Edit payroll';
4053
public id: string | null = null;
4154
public isLoading = false;
@@ -54,8 +67,15 @@ export class EditPayrollComponent implements OnInit {
5467
const lastWeek = [PredefinedDateRanges.getLastWeek().startDate, PredefinedDateRanges.getLastWeek().endDate]
5568

5669
this.form = new FormGroup<PayrollForm>({
57-
employee: new FormControl<Employee | null>(null, {validators: Validators.required}),
58-
dateRange: new FormControl<Date[]>(lastWeek, {validators: Validators.required, nonNullable: true}),
70+
employee: new FormControl(null, {validators: Validators.required}),
71+
dateRange: new FormControl(lastWeek, {validators: Validators.required, nonNullable: true}),
72+
paymentStatus: new FormControl(null),
73+
paymentMethod: new FormControl(null),
74+
paymentBillingAddress: new FormControl(null),
75+
});
76+
77+
this.form.get('paymentStatus')?.valueChanges.subscribe((status) => {
78+
this.setConditionalValidators(status);
5979
});
6080
}
6181

@@ -127,14 +147,28 @@ export class EditPayrollComponent implements OnInit {
127147
return this.id != null && this.id !== '';
128148
}
129149

130-
isShareOfGrossSalary() {
131-
return this.selectedEmployee?.salaryType === SalaryType.ShareOfGross;
132-
}
133-
134150
getSalaryTypeDesc(salaryType: SalaryType): string {
135151
return SalaryTypeEnum.getDescription(salaryType);
136152
}
137153

154+
private setConditionalValidators(paymentStatus: PaymentStatus | null) {
155+
if (!paymentStatus) {
156+
return;
157+
}
158+
159+
const paymentMethodControl = this.form.get('paymentMethod');
160+
const billingAddressControl = this.form.get('paymentBillingAddress');
161+
162+
if (paymentStatus === PaymentStatus.Paid) {
163+
paymentMethodControl?.setValidators(Validators.required);
164+
billingAddressControl?.setValidators(Validators.required);
165+
}
166+
else {
167+
paymentMethodControl?.clearValidators();
168+
billingAddressControl?.clearValidators();
169+
}
170+
}
171+
138172
private fetchPayroll() {
139173
if (!this.id) {
140174
return;
@@ -146,7 +180,13 @@ export class EditPayrollComponent implements OnInit {
146180
this.form.patchValue({
147181
employee: payroll.employee,
148182
dateRange: [new Date(payroll.startDate), new Date(payroll.endDate)],
183+
paymentMethod: payroll.payment.method,
184+
paymentStatus: payroll.payment.status,
185+
paymentBillingAddress: payroll.payment.billingAddress,
149186
});
187+
188+
this.computedPayroll = payroll;
189+
this.selectedEmployee = payroll.employee;
150190
}
151191

152192
this.isLoading = false;
@@ -199,4 +239,7 @@ export class EditPayrollComponent implements OnInit {
199239
interface PayrollForm {
200240
employee: FormControl<Employee | null>;
201241
dateRange: FormControl<Date[]>;
242+
paymentStatus: FormControl<PaymentStatus | null>;
243+
paymentMethod: FormControl<PaymentMethod | null>;
244+
paymentBillingAddress: FormControl<string | null>;
202245
}

src/Client/Logistics.OfficeApp/src/app/pages/accounting/list-payroll/list-payroll.component.html

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ <h1>Payrolls</h1>
9494
<p-button class="ms-2"
9595
icon="bi bi-pencil"
9696
pTooltip="Edit payroll"
97+
tooltipPosition="bottom"
9798
[routerLink]="['/accounting/payrolls/edit', payroll.id]">
9899
</p-button>
99100
</td>

src/Client/Logistics.OfficeApp/src/app/pages/load/list-loads/list-loads.component.ts

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ export class ListLoadComponent {
7474
if (result.isSuccess && result.data) {
7575
this.loads = result.data;
7676
this.totalRecords = result.totalItems;
77+
console.log(this.loads);
78+
7779
}
7880

7981
this.isLoading = false;

src/Client/Logistics.OfficeApp/src/app/pages/payment/process-payment/process-payment.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ <h1 class="text-center">{{title}}</h1>
22
<hr class="w-100">
33

44
<div class="row justify-content-center mx-0">
5-
<div class="col-12 col-xl-6">
5+
<div class="col-12 col-lg-6 col-xl-8">
66
<p-card>
77
<div class="row mb-3">
88
<div class="col-12">

src/Client/Logistics.OfficeApp/src/app/pages/payment/process-payment/process-payment.component.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,15 @@ export class ProcessPaymentComponent implements OnInit {
8787
}
8888

8989
submit() {
90-
if (!this.form.valid || !this.payroll || !this.invoice) {
90+
const paymentId = this.payroll?.payment.id ?? this.invoice?.payment.id;
91+
92+
if (!this.form.valid || !paymentId) {
9193
return;
9294
}
9395

9496
this.isLoading = true;
9597
const command: ProcessPayment = {
96-
paymentId: this.payroll.payment.id ?? this.invoice.payment.id,
98+
paymentId: paymentId,
9799
paymentMethod: this.form.value.paymentMethod!,
98100
billingAddress: this.form.value.billingAddress!,
99101
cardholderName: this.form.value.cardholderName!,

src/Core/Logistics.Application.Tenant/Commands/Load/CreateLoad/CreateLoadHandler.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ protected override async Task<ResponseResult> HandleValidated(
4141
refId = latestLoad.RefId + 1;
4242

4343
var load = Load.Create(
44-
refId,
44+
refId,
45+
req.DeliveryCost,
4546
req.OriginAddress!,
4647
req.OriginAddressLat,
4748
req.OriginAddressLong,
@@ -54,7 +55,6 @@ protected override async Task<ResponseResult> HandleValidated(
5455

5556
load.Name = req.Name;
5657
load.Distance = req.Distance;
57-
load.DeliveryCost = req.DeliveryCost;
5858

5959
await _tenantRepository.AddAsync(load);
6060
var changes = await _tenantRepository.UnitOfWork.CommitAsync();

src/Core/Logistics.Application.Tenant/Commands/Payroll/UpdatePayroll/UpdatePayrollCommand.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ namespace Logistics.Application.Tenant.Commands;
66
public class UpdatePayrollCommand : IRequest<ResponseResult>
77
{
88
public string Id { get; set; } = default!;
9-
public DateTime StartDate { get; set; }
10-
public DateTime EndDate { get; set; }
9+
public DateTime? StartDate { get; set; }
10+
public DateTime? EndDate { get; set; }
1111
public string? EmployeeId { get; set; }
12-
public PaymentMethod? Method { get; set; }
13-
public decimal? Amount { get; set; }
14-
public PaymentStatus? Status { get; set; }
12+
public PaymentStatus? PaymentStatus { get; set; }
13+
public PaymentMethod? PaymentMethod { get; set; }
14+
public string? PaymentBillingAddress { get; set; }
1515
}

src/Core/Logistics.Application.Tenant/Commands/Payroll/UpdatePayroll/UpdatePayrollHandler.cs

+29-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
namespace Logistics.Application.Tenant.Commands;
1+
using Logistics.Shared.Enums;
22

3-
internal sealed class UpdatePayrollHandler : RequestHandler<UpdatePaymentCommand, ResponseResult>
3+
namespace Logistics.Application.Tenant.Commands;
4+
5+
internal sealed class UpdatePayrollHandler : RequestHandler<UpdatePayrollCommand, ResponseResult>
46
{
57
private readonly ITenantRepository _tenantRepository;
68

@@ -10,35 +12,42 @@ public UpdatePayrollHandler(ITenantRepository tenantRepository)
1012
}
1113

1214
protected override async Task<ResponseResult> HandleValidated(
13-
UpdatePaymentCommand req, CancellationToken cancellationToken)
15+
UpdatePayrollCommand req, CancellationToken cancellationToken)
1416
{
15-
var payment = await _tenantRepository.GetAsync<Payment>(req.Id);
16-
17-
if (payment is null)
18-
return ResponseResult.CreateError($"Could not find a payment with ID '{req.Id}'");
17+
var payroll = await _tenantRepository.GetAsync<Payroll>(req.Id);
1918

20-
if (req.PaymentFor.HasValue && payment.PaymentFor != req.PaymentFor)
21-
{
22-
payment.PaymentFor = req.PaymentFor.Value;
23-
}
24-
if (req.Method.HasValue && payment.Method != req.Method)
19+
if (payroll is null)
2520
{
26-
payment.Method = req.Method.Value;
21+
return ResponseResult.CreateError($"Could not find a payroll with ID '{req.Id}'");
2722
}
28-
if (req.Status.HasValue && payment.Status != req.Status)
23+
24+
if (!string.IsNullOrEmpty(req.EmployeeId) && req.EmployeeId != payroll.EmployeeId)
2925
{
30-
payment.SetStatus(req.Status.Value);
26+
var employee = await _tenantRepository.GetAsync<Employee>(req.EmployeeId);
27+
28+
if (employee is null)
29+
{
30+
return ResponseResult.CreateError($"Could not find an employer with ID '{req.EmployeeId}'");
31+
}
32+
33+
payroll.Employee = employee;
3134
}
32-
if (req.Amount.HasValue && payment.Amount != req.Amount)
35+
36+
if (req is { StartDate: not null, EndDate: not null } && payroll.StartDate != req.StartDate &&
37+
payroll.EndDate != req.EndDate)
3338
{
34-
payment.Amount = req.Amount.Value;
39+
payroll.StartDate = req.StartDate.Value;
40+
payroll.EndDate = req.EndDate.Value;
3541
}
36-
if (!string.IsNullOrEmpty(req.Comment) && payment.Comment != req.Comment)
42+
43+
if (req.PaymentStatus.HasValue && payroll.Payment.Status != req.PaymentStatus)
3744
{
38-
payment.Comment = req.Comment;
45+
payroll.Payment.SetStatus(req.PaymentStatus.Value);
46+
payroll.Payment.Method = req.PaymentMethod;
47+
payroll.Payment.BillingAddress = req.PaymentBillingAddress;
3948
}
4049

41-
_tenantRepository.Update(payment);
50+
_tenantRepository.Update(payroll);
4251
await _tenantRepository.UnitOfWork.CommitAsync();
4352
return ResponseResult.CreateSuccess();
4453
}

src/Core/Logistics.Application.Tenant/Commands/Payroll/UpdatePayroll/UpdatePayrollValidator.cs

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ internal sealed class UpdatePayrollValidator : AbstractValidator<UpdatePayrollCo
77
public UpdatePayrollValidator()
88
{
99
RuleFor(i => i.StartDate).LessThan(i => i.EndDate);
10-
RuleFor(i => i.Amount).GreaterThanOrEqualTo(0);
1110
RuleFor(i => i.Id).NotEmpty();
1211
}
1312
}

src/Core/Logistics.DbMigrator/Core/InvoiceGenerator.cs

-33
This file was deleted.

0 commit comments

Comments
 (0)