mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
feat(checkout): implement reward order confirmation UI
Implement the complete UI for the reward order confirmation page including address displays, order item lists, and supporting helper functions. Features: - Add order confirmation addresses component displaying billing, delivery, and pickup branch addresses - Implement order confirmation item list with order type icons and item details - Add helper functions for order type feature checking and address/branch deduplication - Integrate store computed properties for payers, shipping addresses, and target branches - Apply responsive layout with Tailwind CSS styling
This commit is contained in:
@@ -0,0 +1,498 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
areAddresseesEqual,
|
||||
areBranchesEqual,
|
||||
deduplicateAddressees,
|
||||
deduplicateBranches,
|
||||
} from './deduplicate-addressees.helper';
|
||||
import {
|
||||
DisplayAddresseeDTO,
|
||||
DisplayBranchDTO,
|
||||
AddressDTO,
|
||||
} from '@generated/swagger/oms-api';
|
||||
|
||||
describe('areAddresseesEqual', () => {
|
||||
const sampleAddress: AddressDTO = {
|
||||
street: 'Teststraße',
|
||||
streetNumber: '123',
|
||||
city: 'Berlin',
|
||||
zipCode: '10115',
|
||||
country: 'DEU',
|
||||
};
|
||||
|
||||
const createAddressee = (
|
||||
firstName: string,
|
||||
lastName: string,
|
||||
address?: AddressDTO,
|
||||
): DisplayAddresseeDTO => ({
|
||||
firstName,
|
||||
lastName,
|
||||
address,
|
||||
gender: 0, // NotSet
|
||||
});
|
||||
|
||||
it('should return true when both addressees are undefined', () => {
|
||||
// Act
|
||||
const result = areAddresseesEqual(undefined, undefined);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when only first addressee is undefined', () => {
|
||||
// Arrange
|
||||
const addressee = createAddressee('John', 'Doe', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(undefined, addressee);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when only second addressee is undefined', () => {
|
||||
// Arrange
|
||||
const addressee = createAddressee('John', 'Doe', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee, undefined);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when addressees have same name and address', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Doe', { ...sampleAddress });
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when addressees have different first names', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('Jane', 'Doe', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when addressees have different last names', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Smith', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when addressees have different addresses', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Doe', {
|
||||
...sampleAddress,
|
||||
street: 'Other Street',
|
||||
});
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when both addressees have no address', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe');
|
||||
const addressee2 = createAddressee('John', 'Doe');
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when one has address and other does not', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Doe');
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle empty string names', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('', '', sampleAddress);
|
||||
const addressee2 = createAddressee('', '', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should treat undefined names as empty strings', () => {
|
||||
// Arrange
|
||||
const addressee1: DisplayAddresseeDTO = {
|
||||
gender: 0, // NotSet
|
||||
address: sampleAddress,
|
||||
};
|
||||
const addressee2: DisplayAddresseeDTO = {
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
gender: 0, // NotSet
|
||||
address: sampleAddress,
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = areAddresseesEqual(addressee1, addressee2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deduplicateAddressees', () => {
|
||||
const sampleAddress: AddressDTO = {
|
||||
street: 'Teststraße',
|
||||
streetNumber: '123',
|
||||
city: 'Berlin',
|
||||
zipCode: '10115',
|
||||
country: 'DEU',
|
||||
};
|
||||
|
||||
const createAddressee = (
|
||||
firstName: string,
|
||||
lastName: string,
|
||||
address?: AddressDTO,
|
||||
): DisplayAddresseeDTO => ({
|
||||
firstName,
|
||||
lastName,
|
||||
address,
|
||||
gender: 0, // NotSet
|
||||
});
|
||||
|
||||
it('should return empty array when input is empty', () => {
|
||||
// Arrange
|
||||
const addressees: DisplayAddresseeDTO[] = [];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should filter out undefined values', () => {
|
||||
// Arrange
|
||||
const addressee = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressees = [undefined, addressee, undefined];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toEqual(addressee);
|
||||
});
|
||||
|
||||
it('should return single item when array has one addressee', () => {
|
||||
// Arrange
|
||||
const addressee = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressees = [addressee];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toEqual(addressee);
|
||||
});
|
||||
|
||||
it('should return all items when no duplicates exist', () => {
|
||||
// Arrange
|
||||
const addressees = [
|
||||
createAddressee('John', 'Doe', sampleAddress),
|
||||
createAddressee('Jane', 'Smith', sampleAddress),
|
||||
createAddressee('Bob', 'Johnson', {
|
||||
...sampleAddress,
|
||||
street: 'Other Street',
|
||||
}),
|
||||
];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(3);
|
||||
});
|
||||
|
||||
it('should remove duplicate addressees keeping first occurrence', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Doe', { ...sampleAddress });
|
||||
const addressees = [addressee1, addressee2];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toBe(addressee1); // First occurrence kept
|
||||
});
|
||||
|
||||
it('should handle multiple duplicates and keep only first', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Doe', { ...sampleAddress });
|
||||
const addressee3 = createAddressee('John', 'Doe', { ...sampleAddress });
|
||||
const addressees = [addressee1, addressee2, addressee3];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toBe(addressee1);
|
||||
});
|
||||
|
||||
it('should not consider different names but same address as duplicates', () => {
|
||||
// Arrange
|
||||
const addressees = [
|
||||
createAddressee('John', 'Doe', sampleAddress),
|
||||
createAddressee('Jane', 'Doe', sampleAddress),
|
||||
];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should not consider same names but different addresses as duplicates', () => {
|
||||
// Arrange
|
||||
const addressees = [
|
||||
createAddressee('John', 'Doe', sampleAddress),
|
||||
createAddressee('John', 'Doe', {
|
||||
...sampleAddress,
|
||||
street: 'Other Street',
|
||||
}),
|
||||
];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should handle complex scenario with mixed duplicates and unique items', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('John', 'Doe', sampleAddress);
|
||||
const addressee2 = createAddressee('John', 'Doe', { ...sampleAddress }); // Duplicate of 1
|
||||
const addressee3 = createAddressee('Jane', 'Smith', sampleAddress);
|
||||
const addressee4 = createAddressee('Jane', 'Smith', { ...sampleAddress }); // Duplicate of 3
|
||||
const addressee5 = createAddressee('Bob', 'Johnson', sampleAddress);
|
||||
const addressees = [
|
||||
addressee1,
|
||||
addressee2,
|
||||
addressee3,
|
||||
addressee4,
|
||||
addressee5,
|
||||
undefined,
|
||||
];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(3);
|
||||
expect(result[0]).toBe(addressee1);
|
||||
expect(result[1]).toBe(addressee3);
|
||||
expect(result[2]).toBe(addressee5);
|
||||
});
|
||||
|
||||
it('should preserve order of first occurrences', () => {
|
||||
// Arrange
|
||||
const addressee1 = createAddressee('Alice', 'Wonder', sampleAddress);
|
||||
const addressee2 = createAddressee('Bob', 'Builder', sampleAddress);
|
||||
const addressee3 = createAddressee('Alice', 'Wonder', { ...sampleAddress }); // Duplicate
|
||||
const addressees = [addressee1, addressee2, addressee3];
|
||||
|
||||
// Act
|
||||
const result = deduplicateAddressees(addressees);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0]).toBe(addressee1);
|
||||
expect(result[1]).toBe(addressee2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('areBranchesEqual', () => {
|
||||
const sampleAddress: AddressDTO = {
|
||||
street: 'Teststraße',
|
||||
streetNumber: '123',
|
||||
city: 'Berlin',
|
||||
zipCode: '10115',
|
||||
country: 'DEU',
|
||||
};
|
||||
|
||||
const createBranch = (
|
||||
name: string,
|
||||
address?: AddressDTO,
|
||||
): DisplayBranchDTO => ({
|
||||
name,
|
||||
address,
|
||||
});
|
||||
|
||||
it('should return true when both branches are undefined', () => {
|
||||
// Act
|
||||
const result = areBranchesEqual(undefined, undefined);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when only first branch is undefined', () => {
|
||||
// Arrange
|
||||
const branch = createBranch('Branch 1', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areBranchesEqual(undefined, branch);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when branches have same name and address', () => {
|
||||
// Arrange
|
||||
const branch1 = createBranch('Branch 1', sampleAddress);
|
||||
const branch2 = createBranch('Branch 1', { ...sampleAddress });
|
||||
|
||||
// Act
|
||||
const result = areBranchesEqual(branch1, branch2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when branches have different names', () => {
|
||||
// Arrange
|
||||
const branch1 = createBranch('Branch 1', sampleAddress);
|
||||
const branch2 = createBranch('Branch 2', sampleAddress);
|
||||
|
||||
// Act
|
||||
const result = areBranchesEqual(branch1, branch2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when branches have different addresses', () => {
|
||||
// Arrange
|
||||
const branch1 = createBranch('Branch 1', sampleAddress);
|
||||
const branch2 = createBranch('Branch 1', {
|
||||
...sampleAddress,
|
||||
street: 'Other Street',
|
||||
});
|
||||
|
||||
// Act
|
||||
const result = areBranchesEqual(branch1, branch2);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deduplicateBranches', () => {
|
||||
const sampleAddress: AddressDTO = {
|
||||
street: 'Teststraße',
|
||||
streetNumber: '123',
|
||||
city: 'Berlin',
|
||||
zipCode: '10115',
|
||||
country: 'DEU',
|
||||
};
|
||||
|
||||
const createBranch = (
|
||||
name: string,
|
||||
address?: AddressDTO,
|
||||
): DisplayBranchDTO => ({
|
||||
name,
|
||||
address,
|
||||
});
|
||||
|
||||
it('should return empty array when input is empty', () => {
|
||||
// Arrange
|
||||
const branches: DisplayBranchDTO[] = [];
|
||||
|
||||
// Act
|
||||
const result = deduplicateBranches(branches);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should filter out undefined values', () => {
|
||||
// Arrange
|
||||
const branch = createBranch('Branch 1', sampleAddress);
|
||||
const branches = [undefined, branch, undefined];
|
||||
|
||||
// Act
|
||||
const result = deduplicateBranches(branches);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toEqual(branch);
|
||||
});
|
||||
|
||||
it('should remove duplicate branches keeping first occurrence', () => {
|
||||
// Arrange
|
||||
const branch1 = createBranch('Branch 1', sampleAddress);
|
||||
const branch2 = createBranch('Branch 1', { ...sampleAddress });
|
||||
const branches = [branch1, branch2];
|
||||
|
||||
// Act
|
||||
const result = deduplicateBranches(branches);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toBe(branch1);
|
||||
});
|
||||
|
||||
it('should return all items when no duplicates exist', () => {
|
||||
// Arrange
|
||||
const branches = [
|
||||
createBranch('Branch 1', sampleAddress),
|
||||
createBranch('Branch 2', sampleAddress),
|
||||
createBranch('Branch 3', {
|
||||
...sampleAddress,
|
||||
street: 'Other Street',
|
||||
}),
|
||||
];
|
||||
|
||||
// Act
|
||||
const result = deduplicateBranches(branches);
|
||||
|
||||
// Assert
|
||||
expect(result).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,207 @@
|
||||
import {
|
||||
DisplayAddresseeDTO,
|
||||
DisplayBranchDTO,
|
||||
} from '@generated/swagger/oms-api';
|
||||
|
||||
/**
|
||||
* Internal model representing an entity with name and address for comparison.
|
||||
* This allows for type-safe comparison without casting.
|
||||
*/
|
||||
interface EntityWithNameAndAddress {
|
||||
readonly name: string;
|
||||
readonly address: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an addressee-like object to a comparable entity.
|
||||
*/
|
||||
function toComparableAddressee(
|
||||
addressee: Pick<DisplayAddresseeDTO, 'firstName' | 'lastName' | 'address'>,
|
||||
): EntityWithNameAndAddress {
|
||||
const firstName = addressee.firstName ?? '';
|
||||
const lastName = addressee.lastName ?? '';
|
||||
const name = `${firstName}|${lastName}`.trim();
|
||||
return {
|
||||
name,
|
||||
address: addressee.address ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a branch-like object to a comparable entity.
|
||||
*/
|
||||
function toComparableBranch(
|
||||
branch: Pick<DisplayBranchDTO, 'name' | 'address'>,
|
||||
): EntityWithNameAndAddress {
|
||||
return {
|
||||
name: branch.name ?? '',
|
||||
address: branch.address ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two entities for equality based on name and address.
|
||||
*/
|
||||
function areEntitiesEqual(
|
||||
entity1: EntityWithNameAndAddress,
|
||||
entity2: EntityWithNameAndAddress,
|
||||
): boolean {
|
||||
if (entity1.name !== entity2.name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const address1Str = JSON.stringify(entity1.address);
|
||||
const address2Str = JSON.stringify(entity2.address);
|
||||
|
||||
return address1Str === address2Str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two DisplayAddresseeDTO objects for equality based on name and address.
|
||||
* Two addressees are considered equal if they have the same firstName, lastName, and address.
|
||||
*
|
||||
* @param addressee1 - First addressee to compare
|
||||
* @param addressee2 - Second addressee to compare
|
||||
* @returns true if addressees are equal, false otherwise
|
||||
*/
|
||||
export function areAddresseesEqual(
|
||||
addressee1: DisplayAddresseeDTO | undefined,
|
||||
addressee2: DisplayAddresseeDTO | undefined,
|
||||
): boolean {
|
||||
if (!addressee1 && !addressee2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!addressee1 || !addressee2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return areEntitiesEqual(
|
||||
toComparableAddressee(addressee1),
|
||||
toComparableAddressee(addressee2),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two DisplayBranchDTO objects for equality based on name and address.
|
||||
* Two branches are considered equal if they have the same name and address.
|
||||
*
|
||||
* @param branch1 - First branch to compare
|
||||
* @param branch2 - Second branch to compare
|
||||
* @returns true if branches are equal, false otherwise
|
||||
*/
|
||||
export function areBranchesEqual(
|
||||
branch1: DisplayBranchDTO | undefined,
|
||||
branch2: DisplayBranchDTO | undefined,
|
||||
): boolean {
|
||||
if (!branch1 && !branch2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!branch1 || !branch2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return areEntitiesEqual(
|
||||
toComparableBranch(branch1),
|
||||
toComparableBranch(branch2),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if an object can be compared as an addressee.
|
||||
*/
|
||||
function hasAddresseeShape(
|
||||
obj: unknown,
|
||||
): obj is Pick<DisplayAddresseeDTO, 'firstName' | 'lastName' | 'address'> {
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj === 'object' &&
|
||||
('firstName' in obj || 'lastName' in obj || 'address' in obj)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if an object can be compared as a branch.
|
||||
*/
|
||||
function hasBranchShape(
|
||||
obj: unknown,
|
||||
): obj is Pick<DisplayBranchDTO, 'name' | 'address'> {
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj === 'object' &&
|
||||
('name' in obj || 'address' in obj)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes duplicate addressees from an array, keeping only the first occurrence.
|
||||
* Two addressees are considered duplicates if they have the same firstName, lastName, and address.
|
||||
*
|
||||
* @param addressees - Array of addressees to deduplicate
|
||||
* @returns Deduplicated array with only first occurrence of each unique addressee
|
||||
*/
|
||||
export function deduplicateAddressees<
|
||||
T extends Pick<DisplayAddresseeDTO, 'firstName' | 'lastName' | 'address'>,
|
||||
>(addressees: readonly (T | undefined)[]): T[] {
|
||||
const result: T[] = [];
|
||||
const seen: T[] = [];
|
||||
|
||||
for (const addressee of addressees) {
|
||||
if (!addressee || !hasAddresseeShape(addressee)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isDuplicate = seen.some((seenAddressee) =>
|
||||
hasAddresseeShape(seenAddressee)
|
||||
? areEntitiesEqual(
|
||||
toComparableAddressee(seenAddressee),
|
||||
toComparableAddressee(addressee),
|
||||
)
|
||||
: false,
|
||||
);
|
||||
|
||||
if (!isDuplicate) {
|
||||
result.push(addressee);
|
||||
seen.push(addressee);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes duplicate branches from an array, keeping only the first occurrence.
|
||||
* Two branches are considered duplicates if they have the same name and address.
|
||||
*
|
||||
* @param branches - Array of branches to deduplicate
|
||||
* @returns Deduplicated array with only first occurrence of each unique branch
|
||||
*/
|
||||
export function deduplicateBranches<
|
||||
T extends Pick<DisplayBranchDTO, 'name' | 'address'>,
|
||||
>(branches: readonly (T | undefined)[]): T[] {
|
||||
const result: T[] = [];
|
||||
const seen: T[] = [];
|
||||
|
||||
for (const branch of branches) {
|
||||
if (!branch || !hasBranchShape(branch)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isDuplicate = seen.some((seenBranch) =>
|
||||
hasBranchShape(seenBranch)
|
||||
? areEntitiesEqual(
|
||||
toComparableBranch(seenBranch),
|
||||
toComparableBranch(branch),
|
||||
)
|
||||
: false,
|
||||
);
|
||||
|
||||
if (!isDuplicate) {
|
||||
result.push(branch);
|
||||
seen.push(branch);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,2 +1,8 @@
|
||||
export {
|
||||
areAddresseesEqual,
|
||||
areBranchesEqual,
|
||||
deduplicateAddressees,
|
||||
deduplicateBranches,
|
||||
} from './deduplicate-addressees.helper';
|
||||
export * from './get-customer-name.component';
|
||||
export * from './get-primary-bonus-card.helper';
|
||||
|
||||
Reference in New Issue
Block a user