Packages fixtures: drop 'unknown' treatment + add 10 verified packages
Dash fix: PackageDetail no longer renders em-dash placeholder rows for Optionals. The 10 fixture entries that used `treatment: 'unknown'` are removed; the Optional type narrows to IncludedTreatment only; the dead 'unknown' branch in optionalsForStep/optionalsForComparison is gone. The rule going forward: an Optional/Extra exists on a package when the package actually offers it. ComparisonTable already handles absence correctly via buildMergedSections + lookupValue → 'Not Included'. Package distribution expanded (max 5 per provider, randomised): parsons: 3 → 5 (+ traditional-burial, memorial-service) rankins: 2 → 3 (+ direct-cremation) killick: 2 → 3 (+ traditional-burial) mackay: 1 → 4 (+ premium, simple, memorial-service) mannings: 1 → 4 (+ premium, simple, direct-cremation) Each new package follows the canonical-essentials rule: same 9 Essentials line items, only prices/treatments vary. Optionals + Extras composed per package. Mackay + Mannings comparison maps rewritten from single-package to the indexed-array pattern used by parsons/rankins/killick, and their bundle entries now slice(0,1)/slice(1) so an "Other packages from this provider" section appears. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -134,26 +134,32 @@ const sumEssentials = (p: EssentialsPrices): number => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ─── Optionals helpers ───────────────────────────────────────────────────────
|
// ─── Optionals helpers ───────────────────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// Rule: Optionals an Extras list an item ONLY when that package actually
|
||||||
|
// offers it. Missing items are not placeholders — they're just absent. In
|
||||||
|
// PackageDetail that means the row isn't rendered. In ComparisonTable the
|
||||||
|
// cross-join (see `buildMergedSections` + `lookupValue`) surfaces the row
|
||||||
|
// as "Not Included" for any column that doesn't include it.
|
||||||
|
|
||||||
interface Optional {
|
interface Optional {
|
||||||
name: string;
|
name: string;
|
||||||
treatment: IncludedTreatment | 'unknown';
|
treatment: IncludedTreatment;
|
||||||
}
|
}
|
||||||
|
|
||||||
const optionalsForStep = (items: Optional[]): PackageSection => ({
|
const optionalsForStep = (items: Optional[]): PackageSection => ({
|
||||||
heading: 'Optionals',
|
heading: 'Optionals',
|
||||||
items: items.map<PackageLineItem>((it) =>
|
items: items.map<PackageLineItem>((it) => ({
|
||||||
it.treatment === 'unknown'
|
name: it.name,
|
||||||
? { name: it.name, price: 0, priceLabel: '—' }
|
price: 0,
|
||||||
: { name: it.name, price: 0, priceLabel: labelFor(it.treatment) },
|
priceLabel: labelFor(it.treatment),
|
||||||
),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
const optionalsForComparison = (items: Optional[]): ComparisonSection => ({
|
const optionalsForComparison = (items: Optional[]): ComparisonSection => ({
|
||||||
heading: 'Optionals',
|
heading: 'Optionals',
|
||||||
items: items.map((it) => ({
|
items: items.map((it) => ({
|
||||||
name: it.name,
|
name: it.name,
|
||||||
value: { type: it.treatment === 'unknown' ? 'unknown' : it.treatment },
|
value: { type: it.treatment },
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -226,6 +232,28 @@ const parsonsDeluxeEssentials: EssentialsPrices = {
|
|||||||
service: 5384.9,
|
service: 5384.9,
|
||||||
transport: 'complimentary',
|
transport: 'complimentary',
|
||||||
};
|
};
|
||||||
|
const parsonsTraditionalEssentials: EssentialsPrices = {
|
||||||
|
coffin: 2200,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'complimentary',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 4534.9,
|
||||||
|
transport: 'complimentary',
|
||||||
|
};
|
||||||
|
const parsonsMemorialEssentials: EssentialsPrices = {
|
||||||
|
coffin: 900,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'complimentary',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 3034.9,
|
||||||
|
transport: 'complimentary',
|
||||||
|
};
|
||||||
|
|
||||||
const parsonsForStep: PackageData[] = [
|
const parsonsForStep: PackageData[] = [
|
||||||
{
|
{
|
||||||
@@ -290,10 +318,58 @@ const parsonsForStep: PackageData[] = [
|
|||||||
{ name: 'Saturday Service Fee', value: 'complimentary' },
|
{ name: 'Saturday Service Fee', value: 'complimentary' },
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'traditional-burial',
|
||||||
|
name: 'Traditional Burial Package',
|
||||||
|
price: sumEssentials(parsonsTraditionalEssentials),
|
||||||
|
description:
|
||||||
|
'A traditional funeral service followed by burial, including a full procession and graveside committal.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(parsonsTraditionalEssentials),
|
||||||
|
optionalsForStep([
|
||||||
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
|
{ name: 'Flowers', treatment: 'complimentary' },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||||
|
{ name: 'Catering', value: 1100 },
|
||||||
|
{ name: 'Newspaper Notice', value: 350 },
|
||||||
|
{ name: 'Saturday Service Fee', value: 880 },
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'memorial-service',
|
||||||
|
name: 'Memorial Service Package',
|
||||||
|
price: sumEssentials(parsonsMemorialEssentials),
|
||||||
|
description:
|
||||||
|
'A memorial service held after the cremation, giving families time to plan a personalised gathering.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(parsonsMemorialEssentials),
|
||||||
|
optionalsForStep([
|
||||||
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
|
{ name: 'Flowers', treatment: 'complimentary' },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||||
|
{ name: 'Catering', value: 'poa' },
|
||||||
|
{ name: 'Newspaper Notice', value: 280 },
|
||||||
|
]),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx) => {
|
const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx) => {
|
||||||
const ess = [parsonsEverydayEssentials, parsonsEssentialEssentials, parsonsDeluxeEssentials][idx];
|
const ess = [
|
||||||
|
parsonsEverydayEssentials,
|
||||||
|
parsonsEssentialEssentials,
|
||||||
|
parsonsDeluxeEssentials,
|
||||||
|
parsonsTraditionalEssentials,
|
||||||
|
parsonsMemorialEssentials,
|
||||||
|
][idx];
|
||||||
const allOptionals: Optional[][] = [
|
const allOptionals: Optional[][] = [
|
||||||
[
|
[
|
||||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
@@ -312,6 +388,17 @@ const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx)
|
|||||||
{ name: 'Flowers', treatment: 'complimentary' },
|
{ name: 'Flowers', treatment: 'complimentary' },
|
||||||
{ name: 'Webstreaming', treatment: 'complimentary' },
|
{ name: 'Webstreaming', treatment: 'complimentary' },
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
|
{ name: 'Flowers', treatment: 'complimentary' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
|
{ name: 'Flowers', treatment: 'complimentary' },
|
||||||
|
],
|
||||||
];
|
];
|
||||||
const optionals = allOptionals[idx];
|
const optionals = allOptionals[idx];
|
||||||
const extras: Extra[] = [
|
const extras: Extra[] = [
|
||||||
@@ -331,6 +418,17 @@ const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx)
|
|||||||
{ name: 'Newspaper Notice', value: 350 },
|
{ name: 'Newspaper Notice', value: 350 },
|
||||||
{ name: 'Saturday Service Fee', value: 'complimentary' as const },
|
{ name: 'Saturday Service Fee', value: 'complimentary' as const },
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||||
|
{ name: 'Catering', value: 1100 },
|
||||||
|
{ name: 'Newspaper Notice', value: 350 },
|
||||||
|
{ name: 'Saturday Service Fee', value: 880 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||||
|
{ name: 'Catering', value: 'poa' as const },
|
||||||
|
{ name: 'Newspaper Notice', value: 280 },
|
||||||
|
],
|
||||||
][idx];
|
][idx];
|
||||||
return {
|
return {
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
@@ -376,6 +474,17 @@ const rankinsPremiumEssentials: EssentialsPrices = {
|
|||||||
service: 4034.9,
|
service: 4034.9,
|
||||||
transport: 'included',
|
transport: 'included',
|
||||||
};
|
};
|
||||||
|
const rankinsDirectEssentials: EssentialsPrices = {
|
||||||
|
coffin: 800,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 434.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
|
||||||
const rankinsForStep: PackageData[] = [
|
const rankinsForStep: PackageData[] = [
|
||||||
{
|
{
|
||||||
@@ -386,7 +495,6 @@ const rankinsForStep: PackageData[] = [
|
|||||||
sections: [
|
sections: [
|
||||||
essentialsForStep(rankinsStandardEssentials),
|
essentialsForStep(rankinsStandardEssentials),
|
||||||
optionalsForStep([
|
optionalsForStep([
|
||||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
|
||||||
{ name: 'Online Notice', treatment: 'included' },
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
{ name: 'Flowers', treatment: 'included' },
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
@@ -418,13 +526,20 @@ const rankinsForStep: PackageData[] = [
|
|||||||
{ name: 'Newspaper Notice', value: 280 },
|
{ name: 'Newspaper Notice', value: 280 },
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'direct-cremation',
|
||||||
|
name: 'Direct Cremation',
|
||||||
|
price: sumEssentials(rankinsDirectEssentials),
|
||||||
|
description: 'An unattended cremation with no service — the lowest-cost option.',
|
||||||
|
sections: [essentialsForStep(rankinsDirectEssentials), optionalsForStep([])],
|
||||||
|
extras: extrasForStep([]),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx) => {
|
const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx) => {
|
||||||
const ess = [rankinsStandardEssentials, rankinsPremiumEssentials][idx];
|
const ess = [rankinsStandardEssentials, rankinsPremiumEssentials, rankinsDirectEssentials][idx];
|
||||||
const allOptionals: Optional[][] = [
|
const allOptionals: Optional[][] = [
|
||||||
[
|
[
|
||||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
|
||||||
{ name: 'Online Notice', treatment: 'included' },
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
{ name: 'Flowers', treatment: 'included' },
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
@@ -435,6 +550,7 @@ const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx)
|
|||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
{ name: 'Flowers', treatment: 'included' },
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
],
|
],
|
||||||
|
[],
|
||||||
];
|
];
|
||||||
const optionals = allOptionals[idx];
|
const optionals = allOptionals[idx];
|
||||||
const extras: Extra[] = [
|
const extras: Extra[] = [
|
||||||
@@ -448,6 +564,7 @@ const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx)
|
|||||||
{ name: 'Catering', value: 950 },
|
{ name: 'Catering', value: 950 },
|
||||||
{ name: 'Newspaper Notice', value: 280 },
|
{ name: 'Newspaper Notice', value: 280 },
|
||||||
],
|
],
|
||||||
|
[],
|
||||||
][idx];
|
][idx];
|
||||||
return {
|
return {
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
@@ -495,6 +612,18 @@ const killickSimpleEssentials: EssentialsPrices = {
|
|||||||
service: 1534.9,
|
service: 1534.9,
|
||||||
transport: 'complimentary',
|
transport: 'complimentary',
|
||||||
};
|
};
|
||||||
|
const killickTraditionalEssentials: EssentialsPrices = {
|
||||||
|
coffin: 2500,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'complimentary',
|
||||||
|
govLevy: 45.1,
|
||||||
|
govLevyLabel: 'Government Levy — Cremation',
|
||||||
|
mortuary: 440,
|
||||||
|
service: 4234.9,
|
||||||
|
transport: 'complimentary',
|
||||||
|
};
|
||||||
|
|
||||||
const killickForStep: PackageData[] = [
|
const killickForStep: PackageData[] = [
|
||||||
{
|
{
|
||||||
@@ -508,7 +637,6 @@ const killickForStep: PackageData[] = [
|
|||||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
{ name: 'Flowers', treatment: 'unknown' },
|
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
extras: extrasForStep([
|
extras: extrasForStep([
|
||||||
@@ -524,27 +652,47 @@ const killickForStep: PackageData[] = [
|
|||||||
description: 'A direct cremation without a service.',
|
description: 'A direct cremation without a service.',
|
||||||
sections: [
|
sections: [
|
||||||
essentialsForStep(killickSimpleEssentials),
|
essentialsForStep(killickSimpleEssentials),
|
||||||
optionalsForStep([
|
optionalsForStep([{ name: 'Online Notice', treatment: 'complimentary' }]),
|
||||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
|
||||||
{ name: 'Viewing Fee', treatment: 'unknown' },
|
|
||||||
]),
|
|
||||||
],
|
],
|
||||||
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'traditional-burial',
|
||||||
|
name: 'Traditional Burial Package',
|
||||||
|
price: sumEssentials(killickTraditionalEssentials),
|
||||||
|
description:
|
||||||
|
'A traditional burial service with chapel use, full procession, and graveside committal.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(killickTraditionalEssentials),
|
||||||
|
optionalsForStep([
|
||||||
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 550 } },
|
||||||
|
{ name: 'Catering', value: 'poa' },
|
||||||
|
{ name: 'Saturday Service Fee', value: 800 },
|
||||||
|
]),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const killickForComparison: ComparisonPackage[] = killickForStep.map((pkg, idx) => {
|
const killickForComparison: ComparisonPackage[] = killickForStep.map((pkg, idx) => {
|
||||||
const ess = [killickClassicEssentials, killickSimpleEssentials][idx];
|
const ess = [killickClassicEssentials, killickSimpleEssentials, killickTraditionalEssentials][
|
||||||
|
idx
|
||||||
|
];
|
||||||
const allOptionals: Optional[][] = [
|
const allOptionals: Optional[][] = [
|
||||||
[
|
[
|
||||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
{ name: 'Flowers', treatment: 'unknown' },
|
|
||||||
],
|
],
|
||||||
|
[{ name: 'Online Notice', treatment: 'complimentary' }],
|
||||||
[
|
[
|
||||||
|
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||||
{ name: 'Viewing Fee', treatment: 'unknown' },
|
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
const optionals = allOptionals[idx];
|
const optionals = allOptionals[idx];
|
||||||
@@ -555,6 +703,11 @@ const killickForComparison: ComparisonPackage[] = killickForStep.map((pkg, idx)
|
|||||||
{ name: 'Saturday Service Fee', value: 800 },
|
{ name: 'Saturday Service Fee', value: 800 },
|
||||||
],
|
],
|
||||||
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 550 } },
|
||||||
|
{ name: 'Catering', value: 'poa' as const },
|
||||||
|
{ name: 'Saturday Service Fee', value: 800 },
|
||||||
|
],
|
||||||
][idx];
|
][idx];
|
||||||
return {
|
return {
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
@@ -589,6 +742,39 @@ const mackayEverydayEssentials: EssentialsPrices = {
|
|||||||
service: 2430.35,
|
service: 2430.35,
|
||||||
transport: 'included',
|
transport: 'included',
|
||||||
};
|
};
|
||||||
|
const mackayPremiumEssentials: EssentialsPrices = {
|
||||||
|
coffin: 2200,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 4034.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
const mackaySimpleEssentials: EssentialsPrices = {
|
||||||
|
coffin: 800,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 434.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
const mackayMemorialEssentials: EssentialsPrices = {
|
||||||
|
coffin: 900,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 2834.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
|
||||||
const mackayForStep: PackageData[] = [
|
const mackayForStep: PackageData[] = [
|
||||||
{
|
{
|
||||||
@@ -599,7 +785,6 @@ const mackayForStep: PackageData[] = [
|
|||||||
sections: [
|
sections: [
|
||||||
essentialsForStep(mackayEverydayEssentials),
|
essentialsForStep(mackayEverydayEssentials),
|
||||||
optionalsForStep([
|
optionalsForStep([
|
||||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
|
||||||
{ name: 'Online Notice', treatment: 'included' },
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
{ name: 'Flowers', treatment: 'included' },
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
@@ -611,9 +796,101 @@ const mackayForStep: PackageData[] = [
|
|||||||
{ name: 'Saturday Service Fee', value: 750 },
|
{ name: 'Saturday Service Fee', value: 750 },
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'premium',
|
||||||
|
name: 'Premium Funeral Service',
|
||||||
|
price: sumEssentials(mackayPremiumEssentials),
|
||||||
|
description: 'An enhanced service with premium coffin selection and expanded inclusions.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(mackayPremiumEssentials),
|
||||||
|
optionalsForStep([
|
||||||
|
{ name: 'Digital Recording', treatment: 'included' },
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||||
|
{ name: 'Catering', value: 1100 },
|
||||||
|
{ name: 'Newspaper Notice', value: 320 },
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'simple',
|
||||||
|
name: 'Simple Cremation',
|
||||||
|
price: sumEssentials(mackaySimpleEssentials),
|
||||||
|
description: 'A direct cremation without a formal service.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(mackaySimpleEssentials),
|
||||||
|
optionalsForStep([{ name: 'Online Notice', treatment: 'included' }]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'memorial-service',
|
||||||
|
name: 'Memorial Service Package',
|
||||||
|
price: sumEssentials(mackayMemorialEssentials),
|
||||||
|
description:
|
||||||
|
'A memorial service held separately from the cremation, allowing time for planning and family gatherings.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(mackayMemorialEssentials),
|
||||||
|
optionalsForStep([
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||||
|
{ name: 'Catering', value: 'poa' },
|
||||||
|
]),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const mackayForComparison: ComparisonPackage[] = mackayForStep.map((pkg) => ({
|
const mackayForComparison: ComparisonPackage[] = mackayForStep.map((pkg, idx) => {
|
||||||
|
const ess = [
|
||||||
|
mackayEverydayEssentials,
|
||||||
|
mackayPremiumEssentials,
|
||||||
|
mackaySimpleEssentials,
|
||||||
|
mackayMemorialEssentials,
|
||||||
|
][idx];
|
||||||
|
const allOptionals: Optional[][] = [
|
||||||
|
[
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Digital Recording', treatment: 'included' },
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
|
],
|
||||||
|
[{ name: 'Online Notice', treatment: 'included' }],
|
||||||
|
[
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
],
|
||||||
|
];
|
||||||
|
const optionals = allOptionals[idx];
|
||||||
|
const extras: Extra[] = [
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 450 } },
|
||||||
|
{ name: 'Catering', value: 'poa' as const },
|
||||||
|
{ name: 'Saturday Service Fee', value: 750 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||||
|
{ name: 'Catering', value: 1100 },
|
||||||
|
{ name: 'Newspaper Notice', value: 320 },
|
||||||
|
],
|
||||||
|
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||||
|
{ name: 'Catering', value: 'poa' as const },
|
||||||
|
],
|
||||||
|
][idx];
|
||||||
|
return {
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
name: pkg.name,
|
name: pkg.name,
|
||||||
price: pkg.price,
|
price: pkg.price,
|
||||||
@@ -626,20 +903,12 @@ const mackayForComparison: ComparisonPackage[] = mackayForStep.map((pkg) => ({
|
|||||||
verified: true,
|
verified: true,
|
||||||
},
|
},
|
||||||
sections: [
|
sections: [
|
||||||
essentialsForComparison(mackayEverydayEssentials),
|
essentialsForComparison(ess),
|
||||||
optionalsForComparison([
|
optionalsForComparison(optionals),
|
||||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
extrasForComparison(extras),
|
||||||
{ name: 'Online Notice', treatment: 'included' },
|
|
||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
|
||||||
{ name: 'Flowers', treatment: 'included' },
|
|
||||||
]),
|
|
||||||
extrasForComparison([
|
|
||||||
{ name: 'Allowance for Celebrant', value: { allowance: 450 } },
|
|
||||||
{ name: 'Catering', value: 'poa' },
|
|
||||||
{ name: 'Saturday Service Fee', value: 750 },
|
|
||||||
]),
|
|
||||||
],
|
],
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// ─── Mannings (verified, NSW) ────────────────────────────────────────────────
|
// ─── Mannings (verified, NSW) ────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -654,6 +923,39 @@ const manningsStandardEssentials: EssentialsPrices = {
|
|||||||
service: 2114.9,
|
service: 2114.9,
|
||||||
transport: 'included',
|
transport: 'included',
|
||||||
};
|
};
|
||||||
|
const manningsPremiumEssentials: EssentialsPrices = {
|
||||||
|
coffin: 2100,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 3734.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
const manningsSimpleEssentials: EssentialsPrices = {
|
||||||
|
coffin: 750,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 284.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
const manningsDirectEssentials: EssentialsPrices = {
|
||||||
|
coffin: 600,
|
||||||
|
cremationCert: 350,
|
||||||
|
crematorium: 660,
|
||||||
|
deathReg: 70,
|
||||||
|
dressing: 'included',
|
||||||
|
govLevy: 45.1,
|
||||||
|
mortuary: 440,
|
||||||
|
service: 34.9,
|
||||||
|
transport: 'included',
|
||||||
|
};
|
||||||
|
|
||||||
const manningsForStep: PackageData[] = [
|
const manningsForStep: PackageData[] = [
|
||||||
{
|
{
|
||||||
@@ -666,7 +968,6 @@ const manningsForStep: PackageData[] = [
|
|||||||
optionalsForStep([
|
optionalsForStep([
|
||||||
{ name: 'Online Notice', treatment: 'included' },
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
{ name: 'Flowers', treatment: 'unknown' },
|
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
extras: extrasForStep([
|
extras: extrasForStep([
|
||||||
@@ -674,9 +975,83 @@ const manningsForStep: PackageData[] = [
|
|||||||
{ name: 'Catering', value: 'poa' },
|
{ name: 'Catering', value: 'poa' },
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'premium',
|
||||||
|
name: 'Premium Funeral Service',
|
||||||
|
price: sumEssentials(manningsPremiumEssentials),
|
||||||
|
description: 'A more elaborate service with an upgraded coffin and broader inclusions.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(manningsPremiumEssentials),
|
||||||
|
optionalsForStep([
|
||||||
|
{ name: 'Digital Recording', treatment: 'included' },
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||||
|
{ name: 'Catering', value: 950 },
|
||||||
|
{ name: 'Newspaper Notice', value: 280 },
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'simple',
|
||||||
|
name: 'Simple Cremation',
|
||||||
|
price: sumEssentials(manningsSimpleEssentials),
|
||||||
|
description: 'A straightforward cremation without a chapel service.',
|
||||||
|
sections: [
|
||||||
|
essentialsForStep(manningsSimpleEssentials),
|
||||||
|
optionalsForStep([{ name: 'Online Notice', treatment: 'included' }]),
|
||||||
|
],
|
||||||
|
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'direct-cremation',
|
||||||
|
name: 'Direct Cremation',
|
||||||
|
price: sumEssentials(manningsDirectEssentials),
|
||||||
|
description: 'An unattended cremation with no service — the lowest-cost option.',
|
||||||
|
sections: [essentialsForStep(manningsDirectEssentials), optionalsForStep([])],
|
||||||
|
extras: extrasForStep([]),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const manningsForComparison: ComparisonPackage[] = manningsForStep.map((pkg) => ({
|
const manningsForComparison: ComparisonPackage[] = manningsForStep.map((pkg, idx) => {
|
||||||
|
const ess = [
|
||||||
|
manningsStandardEssentials,
|
||||||
|
manningsPremiumEssentials,
|
||||||
|
manningsSimpleEssentials,
|
||||||
|
manningsDirectEssentials,
|
||||||
|
][idx];
|
||||||
|
const allOptionals: Optional[][] = [
|
||||||
|
[
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Digital Recording', treatment: 'included' },
|
||||||
|
{ name: 'Online Notice', treatment: 'included' },
|
||||||
|
{ name: 'Viewing Fee', treatment: 'included' },
|
||||||
|
{ name: 'Flowers', treatment: 'included' },
|
||||||
|
],
|
||||||
|
[{ name: 'Online Notice', treatment: 'included' }],
|
||||||
|
[],
|
||||||
|
];
|
||||||
|
const optionals = allOptionals[idx];
|
||||||
|
const extras: Extra[] = [
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 400 } },
|
||||||
|
{ name: 'Catering', value: 'poa' as const },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||||
|
{ name: 'Catering', value: 950 },
|
||||||
|
{ name: 'Newspaper Notice', value: 280 },
|
||||||
|
],
|
||||||
|
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
||||||
|
[],
|
||||||
|
][idx];
|
||||||
|
return {
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
name: pkg.name,
|
name: pkg.name,
|
||||||
price: pkg.price,
|
price: pkg.price,
|
||||||
@@ -689,18 +1064,12 @@ const manningsForComparison: ComparisonPackage[] = manningsForStep.map((pkg) =>
|
|||||||
verified: true,
|
verified: true,
|
||||||
},
|
},
|
||||||
sections: [
|
sections: [
|
||||||
essentialsForComparison(manningsStandardEssentials),
|
essentialsForComparison(ess),
|
||||||
optionalsForComparison([
|
optionalsForComparison(optionals),
|
||||||
{ name: 'Online Notice', treatment: 'included' },
|
extrasForComparison(extras),
|
||||||
{ name: 'Viewing Fee', treatment: 'included' },
|
|
||||||
{ name: 'Flowers', treatment: 'unknown' },
|
|
||||||
]),
|
|
||||||
extrasForComparison([
|
|
||||||
{ name: 'Allowance for Celebrant', value: { allowance: 400 } },
|
|
||||||
{ name: 'Catering', value: 'poa' },
|
|
||||||
]),
|
|
||||||
],
|
],
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// ─── Wollongong City (tier 3 — itemised but unverified, mostly unknowns) ─────
|
// ─── Wollongong City (tier 3 — itemised but unverified, mostly unknowns) ─────
|
||||||
|
|
||||||
@@ -832,13 +1201,13 @@ export const packagesByProvider: Record<string, PackageBundle> = {
|
|||||||
forComparison: killickForComparison,
|
forComparison: killickForComparison,
|
||||||
},
|
},
|
||||||
mackay: {
|
mackay: {
|
||||||
matching: mackayForStep,
|
matching: mackayForStep.slice(0, 1),
|
||||||
other: [],
|
other: mackayForStep.slice(1),
|
||||||
forComparison: mackayForComparison,
|
forComparison: mackayForComparison,
|
||||||
},
|
},
|
||||||
mannings: {
|
mannings: {
|
||||||
matching: manningsForStep,
|
matching: manningsForStep.slice(0, 1),
|
||||||
other: [],
|
other: manningsForStep.slice(1),
|
||||||
forComparison: manningsForComparison,
|
forComparison: manningsForComparison,
|
||||||
},
|
},
|
||||||
'wollongong-city': {
|
'wollongong-city': {
|
||||||
|
|||||||
Reference in New Issue
Block a user