feat: add lease end page and resolution forms with necessary services and components
- Implemented LeaseEndPage component for managing lease end processes. - Created LeaseEndResolutionForms component for handling agreement and closure submissions. - Added civil date formatting utilities for French date representation. - Developed styles for lease end resolution forms and rent due correction components. - Integrated HTTP service for lease end operations including notice recording, withdrawal acceptance, and closure. - Added unit tests for new components and services to ensure functionality.
This commit is contained in:
1 parent
3d42c9a256
commit
c1e6b905d5
114 files changed
+6582
-345
No files matched your search
@@ -1,4 +1,3 @@
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Component, computed, inject, signal } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@@ -19,15 +18,12 @@ import { formatEuro } from '../../services/rent-payment-format';
|
||||
import { PaymentAllocation, RentPayment } from '../../services/rent-payment.service';
|
||||
import { WorkspaceService } from '../../services/workspace.service';
|
||||
import { RentPaymentDialogResult, RENT_PAYMENT_DATA_STALE } from '../rent-payment-dialog-result';
|
||||
|
||||
interface PaymentFeedback {
|
||||
kind: 'success' | 'error';
|
||||
message: string;
|
||||
}
|
||||
import { RentDueCorrection } from '../rent-due-correction/rent-due-correction';
|
||||
import { formatFrenchCivilDate } from '../../services/civil-date';
|
||||
|
||||
@Component({
|
||||
selector: 'app-rent-payments-page',
|
||||
imports: [DatePipe, MatButtonModule, MatProgressBarModule, MatProgressSpinnerModule],
|
||||
imports: [MatButtonModule, MatProgressBarModule, MatProgressSpinnerModule, RentDueCorrection],
|
||||
templateUrl: './rent-payments-page.html',
|
||||
styleUrl: './rent-payments-page.css',
|
||||
})
|
||||
@@ -35,8 +31,9 @@ export class RentPaymentsPage {
|
||||
readonly workspace = inject(WorkspaceService);
|
||||
private readonly dialog = inject(MatDialog);
|
||||
readonly showFullSchedule = signal(false);
|
||||
readonly feedback = signal<PaymentFeedback | null>(null);
|
||||
readonly feedback = signal<{ kind: 'success' | 'error'; message: string } | null>(null);
|
||||
readonly formatEuro = formatEuro;
|
||||
readonly civilDate = formatFrenchCivilDate;
|
||||
readonly displayedRentDues = computed(() =>
|
||||
this.showFullSchedule()
|
||||
? sortRentDues(this.workspace.rentDues())
|
||||
@@ -227,14 +224,21 @@ function currentRentDues(rentDues: readonly RentDue[]): RentDue[] {
|
||||
|
||||
function currentSchedule(schedule: RentDue[]): RentDue[] {
|
||||
const nextDueIndex = schedule.findIndex((rentDue) => rentDue.timing === 'UPCOMING');
|
||||
const throughNextDue = nextDueIndex === -1 ? schedule : schedule.slice(0, nextDueIndex + 1);
|
||||
const lastCorrectionIndex = schedule.reduce(
|
||||
(lastCorrection, rentDue, index) => (rentDue.correctionRequired ? index : lastCorrection),
|
||||
-1,
|
||||
);
|
||||
const visibleEndIndex =
|
||||
nextDueIndex === -1 ? schedule.length - 1 : Math.max(nextDueIndex, lastCorrectionIndex);
|
||||
const throughNextDue = schedule.slice(0, visibleEndIndex + 1);
|
||||
const lastPaidIndex = throughNextDue.reduce(
|
||||
(lastPaid, rentDue, index) => (rentDue.settlement === 'PAID' ? index : lastPaid),
|
||||
-1,
|
||||
);
|
||||
const firstUnpaidIndex = throughNextDue.findIndex((rentDue) => rentDue.settlement !== 'PAID');
|
||||
const firstCorrectionIndex = throughNextDue.findIndex((rentDue) => rentDue.correctionRequired);
|
||||
const firstVisibleIndex = Math.min(
|
||||
...[lastPaidIndex, firstUnpaidIndex].filter((index) => index !== -1),
|
||||
...[lastPaidIndex, firstUnpaidIndex, firstCorrectionIndex].filter((index) => index !== -1),
|
||||
);
|
||||
|
||||
return firstVisibleIndex === Infinity ? [] : throughNextDue.slice(firstVisibleIndex);
|
||||
|
||||
Reference in new issue
Block a user