diff --git a/app/data/pricesPaidRepo.ts b/app/data/pricesPaidRepo.ts index 675f066b..fac7a8f3 100644 --- a/app/data/pricesPaidRepo.ts +++ b/app/data/pricesPaidRepo.ts @@ -2,107 +2,44 @@ import prisma from "./db"; const MINIMUM_NUMBER_OF_POSTCODES = 30; -interface pricesPaidParams { +interface PricesPaidParams { averagePrice: number; numberOfTransactions: number; granularityPostcode: string; } + const getPricesPaidByPostcodeAndHouseType = async ( postcodeDistrict: string, postcodeArea: string, postcodeSector: string, houseType: string -): Promise => { +): Promise => { try { - // create the progressive queries - let numberOfTransactions; // declare the variable for numbers of transactions retrieved - let granularityPostcode; // declare the granularity of the postcode - let averagePrice; - - const pricesPaidSector = await prisma.pricesPaid.aggregate({ + const summary = await prisma.pricesPaidSummary.findFirst({ where: { - propertyType: { - equals: houseType, - }, + propertyType: houseType, postcode: { - startsWith: postcodeSector, + in: [postcodeSector, postcodeDistrict, postcodeArea], + }, + transactionCount: { + gte: MINIMUM_NUMBER_OF_POSTCODES, }, }, - _count: { - id: true, - }, - _avg: { - price: true, + orderBy: { + // Coincidentally 'sector' comes before 'district' comes before 'area' + granularityLevel: "asc", }, }); - const numberPerSector = pricesPaidSector._count.id; - const isMinMetBySector = numberPerSector >= MINIMUM_NUMBER_OF_POSTCODES; - - if (!isMinMetBySector) { - const pricesPaidDistrict = await prisma.pricesPaid.aggregate({ - where: { - propertyType: { - equals: houseType, - }, - postcode: { - startsWith: postcodeDistrict, - }, - }, - _count: { - id: true, - }, - _avg: { - price: true, - }, - }); - - const numberPerDistrict = pricesPaidDistrict._count.id; - const isMinMetByDistrict = - numberPerDistrict >= MINIMUM_NUMBER_OF_POSTCODES; - - if (!isMinMetByDistrict) { - const pricesPaidArea = await prisma.pricesPaid.aggregate({ - where: { - propertyType: { - equals: houseType, - }, - postcode: { - startsWith: postcodeArea, - }, - }, - _count: { - id: true, - }, - _avg: { - price: true, - }, - }); - const numberPerArea = pricesPaidArea._count.id; - numberOfTransactions = numberPerArea; // check the granularity - granularityPostcode = postcodeArea; // granularity of the postcode when performing the average price search - averagePrice = pricesPaidArea._avg.price; - } else { - numberOfTransactions = numberPerDistrict; // check the granularity - granularityPostcode = postcodeDistrict; // granularity of the postcode - averagePrice = pricesPaidDistrict._avg.price; - } - } else { - numberOfTransactions = numberPerSector; // check the granularity - granularityPostcode = postcodeSector; // granularity of the postcode - averagePrice = pricesPaidSector._avg.price; - } - - if (averagePrice === null) { - throw new Error("Unable to calculate average price"); + if (!summary) { + throw new Error("Unable to find sufficient transaction data"); } - // Cast to string as 'not: null' clause in Prisma query does not type narrow return { - averagePrice, - numberOfTransactions, - granularityPostcode, - } as pricesPaidParams; + averagePrice: summary.averagePrice, + numberOfTransactions: summary.transactionCount, + granularityPostcode: summary.postcode, + }; } catch (error) { throw new Error( `Data error: Unable to get pricesPaid for postcode district ${postcodeDistrict} and houseType ${houseType}` diff --git a/app/models/testClasses.ts b/app/models/testClasses.ts index dfe8b4dc..e33d5410 100644 --- a/app/models/testClasses.ts +++ b/app/models/testClasses.ts @@ -59,7 +59,7 @@ function calculateFairhold(responseData: ResponseData) { property: property, forecastParameters: createForecastParameters(responseData.maintenancePercentage), }); - console.log(household); + return household; }