@@ -5,28 +5,25 @@ import {
55 LetterVariant ,
66 PackSpecification ,
77 Supplier ,
8- SupplierAllocation ,
9- SupplierPack ,
108 VolumeGroup ,
119} from "@nhsdigital/nhs-notify-event-schemas-supplier-config" ;
1210import { LetterRequestPreparedEventV2 } from "@nhsdigital/nhs-notify-event-schemas-letter-rendering" ;
1311import z from "zod" ;
1412import { Unit } from "aws-embedded-metrics" ;
1513import { MetricEntry , MetricStatus , buildEMFObject } from "@internal/helpers" ;
1614import {
17- filterPacksForLetter ,
18- getPackSpecification ,
19- getPreferredSupplierPacks ,
20- getSupplierAllocationsForVolumeGroup ,
21- getSupplierDetails ,
22- getSuppliersWithValidPack ,
2315 getVariantDetails ,
2416 getVolumeGroupDetails ,
2517} from "../services/supplier-config" ;
18+ import { updateSupplierAllocation } from "../services/supplier-quotas" ;
2619import {
27- calculateSupplierAllocatedFactor ,
28- updateSupplierAllocation ,
29- } from "../services/supplier-quotas" ;
20+ eligibleSuppliers ,
21+ filterSuppliersWithCapacity ,
22+ preferredSupplierPack ,
23+ selectSupplierByFactor ,
24+ suppliersWithValidPack ,
25+ } from "./allocation-config" ;
26+
3027import { Deps } from "../config/deps" ;
3128
3229type SupplierSpec = {
@@ -85,87 +82,68 @@ async function getSupplierFromConfig(
8582 deps : Deps ,
8683) : Promise < SupplierDetails | undefined > {
8784 try {
88- const variantDetails : LetterVariant = await getVariantDetails (
85+ const letterVariant : LetterVariant = await getVariantDetails (
8986 letterEvent . data . letterVariantId ,
9087 deps ,
9188 ) ;
9289
93- const volumeGroupDetails : VolumeGroup = await getVolumeGroupDetails (
94- variantDetails . volumeGroupId ,
90+ const volumeGroup : VolumeGroup = await getVolumeGroupDetails (
91+ letterVariant . volumeGroupId ,
9592 deps ,
9693 ) ;
9794
98- const supplierAllocations : SupplierAllocation [ ] =
99- await getSupplierAllocationsForVolumeGroup (
100- variantDetails . volumeGroupId ,
101- deps ,
102- variantDetails . supplierId ,
103- ) ;
95+ const { supplierAllocations, suppliers : allocatedSuppliers } =
96+ await eligibleSuppliers ( volumeGroup , deps ) ;
10497
105- const supplierIds = supplierAllocations . map ( ( alloc ) => alloc . supplier ) ;
106-
107- const allocatedSuppliers : Supplier [ ] = await getSupplierDetails (
108- supplierIds ,
109- deps ,
110- ) ;
111-
112- const eligiblePacks : string [ ] = await filterPacksForLetter (
98+ const preferredPack : PackSpecification = await preferredSupplierPack (
11399 letterEvent ,
114- variantDetails . packSpecificationIds ,
115- deps ,
116- ) ;
117-
118- const preferredSupplierPacks : SupplierPack [ ] =
119- await getPreferredSupplierPacks ( eligiblePacks , allocatedSuppliers , deps ) ;
120-
121- const preferredPack : PackSpecification = await getPackSpecification (
122- preferredSupplierPacks [ 0 ] . packSpecificationId ,
100+ allocatedSuppliers ,
101+ letterVariant . packSpecificationIds ,
123102 deps ,
124103 ) ;
125104
126- const suppliersForPack : Supplier [ ] = await getSuppliersWithValidPack (
105+ const allSuppliersForPack : Supplier [ ] = await suppliersWithValidPack (
127106 allocatedSuppliers ,
128107 preferredPack . id ,
129108 deps ,
130109 ) ;
131110
132- let supplierAllocationsForPack : SupplierAllocation [ ] = [ ] ;
133- let supplierFactors : { supplierId : string ; factor : number } [ ] = [ ] ;
134- let selectedSupplierId = "unknown" ; // Default to first supplier if no allocations or factors can be calculated
135- if ( suppliersForPack && suppliersForPack . length > 0 ) {
136- supplierAllocationsForPack = supplierAllocations . filter ( ( alloc ) =>
137- suppliersForPack . some ( ( supplier ) => supplier . id === alloc . supplier ) ,
111+ const suppliersForPackWithCapacity : Supplier [ ] =
112+ await filterSuppliersWithCapacity (
113+ allSuppliersForPack ,
114+ volumeGroup . id ,
115+ deps ,
138116 ) ;
139117
140- supplierFactors = await calculateSupplierAllocatedFactor (
141- supplierAllocationsForPack ,
118+ // selected supplier id is determined by first calling selectSupplierByFactor for suppliers with capacity and if nothing is returned tryong again with all suppliers for pack
119+ const selectedSupplierId =
120+ ( await selectSupplierByFactor (
121+ suppliersForPackWithCapacity ,
122+ supplierAllocations ,
142123 deps ,
143- ) ;
124+ ) ) ??
125+ ( await selectSupplierByFactor (
126+ allSuppliersForPack ,
127+ supplierAllocations ,
128+ deps ,
129+ ) ) ;
144130
145- // Get the supplierid with the lowest factor
146- selectedSupplierId = supplierFactors [ 0 ] . supplierId ;
147- let lowestFactor = supplierFactors [ 0 ] . factor ;
148- for ( const supplierFactor of supplierFactors ) {
149- if ( supplierFactor . factor < lowestFactor ) {
150- lowestFactor = supplierFactor . factor ;
151- selectedSupplierId = supplierFactor . supplierId ;
152- }
153- }
131+ if ( ! selectedSupplierId ) {
132+ throw new Error (
133+ "No suppliers found with capacity or valid allocation factor for preferred pack" ,
134+ ) ;
154135 }
155136
156137 deps . logger . info ( {
157138 description : "Fetched supplier details for supplier allocations" ,
158139 variantId : letterEvent . data . letterVariantId ,
159- volumeGroupId : volumeGroupDetails . id ,
140+ volumeGroupId : volumeGroup . id ,
160141 supplierAllocationIds : supplierAllocations . map ( ( a ) => a . id ) ,
161142 allocatedSuppliers,
162- variantPacks : variantDetails . packSpecificationIds ,
163- eligiblePacks,
164- preferredSupplierPacks,
165- preferredPack,
166- suppliersForPack,
167- supplierAllocationsForPack,
168- supplierFactors,
143+ allSuppliersForPack : allSuppliersForPack . map ( ( s ) => s . id ) ,
144+ suppliersForPackWithCapacity : suppliersForPackWithCapacity . map (
145+ ( s ) => s . id ,
146+ ) ,
169147 selectedSupplierId,
170148 } ) ;
171149
@@ -176,7 +154,7 @@ async function getSupplierFromConfig(
176154 priority : 0 ,
177155 billingId : preferredPack . billingId ,
178156 } ,
179- volumeGroupId : volumeGroupDetails . id ,
157+ volumeGroupId : volumeGroup . id ,
180158 } ;
181159 deps . logger . info ( {
182160 description : "Resolved supplier details for letter event" ,
0 commit comments