From c34e7dce4474f3b3f8a35c0727867fd1d00ee7aa Mon Sep 17 00:00:00 2001 From: Petr Utkin <103509683+PetruccioU@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:11:14 +1300 Subject: [PATCH 01/10] 14 api putsurcharges for approving surcharge report (#49) * putSurcharge Interface and Usecase created and exported * index files are updated main for new api, others for module exporting * putSurchargeInterface created with request * domain index updated * putSurchargeUsecase created with request and SurchargeStatus * PutSurhcargeRepository created with request * missing module export fixed * rate recalculation added to putSurchargeUsecase * GetSurchargeRepository, Usecase and Interface fixed to return image name * PutSurcharge interface, Usecase and Repository updated * putSurchargeUsecase updated to recieve totalAmount and surchargeAmount together * GetAllSurcharges return image name * GetImageInterface created and exported with model * GetImageUsecase created and exported along with request/response entity * GetImageRepository created with DTO and exported * getSurcharges Usecase and Interface with Response updated to return id, also getSurchargeUsecase * PutSurchargeRepository updated * GetImageInterface and repository updated * action parameter added to put surcharge api to specify rejection or confirmation of the surcarge * comment out * iamge api added to admin dashboard * rate calculator updated * image interface export indes.ts moved * PutSurchargeRepository updated to move image on confirmation or rejection to specific folders * GetImageRepository updated to return image from any folder of the bucket * comment out * name added * rateCalculatorHelper fixed to be applied in PutSurcharge api * Sample code of overload. --------- Co-authored-by: Bonsung Koo --- functions/src/data/firebase/Firebase.ts | 2 + functions/src/data/firebase/index.ts | 3 +- .../src/data/image/get/image/DTO/ImageDTO.ts | 3 + .../image/get/image/GetImageRepository.ts | 28 ++++++++ functions/src/data/image/index.ts | 2 + .../places/DTO/GetPlacesRepositoryRequest.ts | 5 ++ .../place/get/places/GetPlacesRepository.ts | 36 +++++++--- functions/src/data/place/index.ts | 3 +- .../DTO/GetSurchargesRepositoryResponse.ts | 1 + .../surcharge/get/getSurchargesRepository.ts | 40 ++++++----- functions/src/data/surcharge/index.ts | 4 +- .../put/DTO/PutSurchargeRepositoryRequest.ts | 16 +++++ .../surcharge/put/PutSurchargeRepository.ts | 66 +++++++++++++++++ .../image/entity/GetImageUsecaseRequest.ts | 3 + .../image/entity/GetImageUsecaseResponse.ts | 3 + .../domain/image/get/image/getImageUsecase.ts | 11 +++ functions/src/domain/image/index.ts | 1 + .../place/get/places/getPlacesUsecase.ts | 37 +++++++++- functions/src/domain/place/index.ts | 2 +- .../get/entity/GetSurchargeUsecaseResponse.ts | 2 + .../surcharge/get/getSurchargeUsecase.ts | 1 + .../surcharge/get/getSurchargesUsecase.ts | 16 +++-- .../surcharge/helpers/rateCalculatorHelper.ts | 16 ++--- functions/src/domain/surcharge/index.ts | 5 +- .../domain/surcharge/post/RateCalculator.ts | 3 +- .../put/entity/PutSurchargeUsecaseRequest.ts | 6 ++ .../surcharge/put/entity/SurchargeStatus.ts | 7 ++ .../surcharge/put/putSurchargeUsecase.ts | 72 +++++++++++++++++++ functions/src/index.ts | 6 +- .../image/get/image/getImageInterface.ts | 24 +++++++ .../image/model/GetImageInterfaceResponse.ts | 10 +++ functions/src/interface/image/index.ts | 1 + .../place/get/places/getPlacesInterface.ts | 4 +- .../surcharge/get/getSurchargesInterface.ts | 4 +- functions/src/interface/surcharge/index.ts | 5 +- .../models/PutSurchargeInterfaceRequest.ts | 6 ++ .../surcharge/put/putSurchargeInterface.ts | 20 ++++++ .../shared/constants/LocationRestrictions.ts | 12 ++++ functions/src/shared/constants/index.ts | 1 + 39 files changed, 429 insertions(+), 58 deletions(-) create mode 100644 functions/src/data/image/get/image/DTO/ImageDTO.ts create mode 100644 functions/src/data/image/get/image/GetImageRepository.ts create mode 100644 functions/src/data/image/index.ts create mode 100644 functions/src/data/place/get/places/DTO/GetPlacesRepositoryRequest.ts create mode 100644 functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts create mode 100644 functions/src/data/surcharge/put/PutSurchargeRepository.ts create mode 100644 functions/src/domain/image/get/image/entity/GetImageUsecaseRequest.ts create mode 100644 functions/src/domain/image/get/image/entity/GetImageUsecaseResponse.ts create mode 100644 functions/src/domain/image/get/image/getImageUsecase.ts create mode 100644 functions/src/domain/image/index.ts create mode 100644 functions/src/domain/surcharge/put/entity/PutSurchargeUsecaseRequest.ts create mode 100644 functions/src/domain/surcharge/put/entity/SurchargeStatus.ts create mode 100644 functions/src/domain/surcharge/put/putSurchargeUsecase.ts create mode 100644 functions/src/interface/image/get/image/getImageInterface.ts create mode 100644 functions/src/interface/image/get/image/model/GetImageInterfaceResponse.ts create mode 100644 functions/src/interface/image/index.ts create mode 100644 functions/src/interface/surcharge/put/models/PutSurchargeInterfaceRequest.ts create mode 100644 functions/src/interface/surcharge/put/putSurchargeInterface.ts create mode 100644 functions/src/shared/constants/LocationRestrictions.ts create mode 100644 functions/src/shared/constants/index.ts diff --git a/functions/src/data/firebase/Firebase.ts b/functions/src/data/firebase/Firebase.ts index 31e25e0..23d1868 100644 --- a/functions/src/data/firebase/Firebase.ts +++ b/functions/src/data/firebase/Firebase.ts @@ -1,9 +1,11 @@ import { initializeApp } from "firebase-admin/app" import { firestore } from "firebase-admin" import { getStorage } from "firebase-admin/storage" +// import { getDownloadURL } from "firebase-admin/storage" initializeApp() +// export {getDownloadURL} export const database = firestore() export const storage = getStorage() export { File } from '@google-cloud/storage' \ No newline at end of file diff --git a/functions/src/data/firebase/index.ts b/functions/src/data/firebase/index.ts index 0075b07..87d4261 100644 --- a/functions/src/data/firebase/index.ts +++ b/functions/src/data/firebase/index.ts @@ -1,3 +1,4 @@ export { database } from "./Firebase" export { storage } from "./Firebase" -export { File } from './Firebase' \ No newline at end of file +export { File } from './Firebase' +// export {getDownloadURL} from './Firebase' \ No newline at end of file diff --git a/functions/src/data/image/get/image/DTO/ImageDTO.ts b/functions/src/data/image/get/image/DTO/ImageDTO.ts new file mode 100644 index 0000000..36ad4ec --- /dev/null +++ b/functions/src/data/image/get/image/DTO/ImageDTO.ts @@ -0,0 +1,3 @@ +export type ImageDTO = { + image: string | [] +} \ No newline at end of file diff --git a/functions/src/data/image/get/image/GetImageRepository.ts b/functions/src/data/image/get/image/GetImageRepository.ts new file mode 100644 index 0000000..5db213d --- /dev/null +++ b/functions/src/data/image/get/image/GetImageRepository.ts @@ -0,0 +1,28 @@ +import { storage } from "@data/firebase"; +import { ImageDTO } from "@data/image"; + +export async function GetImageRepository(image: string): Promise { + try { + const imageRef = storage.bucket().file(image); + if (!imageRef) { + console.log('Image does not exist in Firebase Storage'); + return { image: [] }; // Empty Base64 string if image doesn't exist + } + + const [fileBuffer] = await imageRef.download(); + if (!fileBuffer) { + console.log('Failed to download image from Firebase Storage'); + return { image: [] }; // Empty Base64 string if download fails + } + + // Convert file buffer to Base64 + const base64Image = fileBuffer.toString('base64'); + const imageResult: ImageDTO = { + image: base64Image, + }; + return imageResult; + } catch (error) { + console.error('Error fetching image data:', error); + throw error; + } +} diff --git a/functions/src/data/image/index.ts b/functions/src/data/image/index.ts new file mode 100644 index 0000000..3f81dd8 --- /dev/null +++ b/functions/src/data/image/index.ts @@ -0,0 +1,2 @@ +export { ImageDTO } from "./get/image/DTO/ImageDTO" +export { GetImageRepository } from "./get/image/GetImageRepository" \ No newline at end of file diff --git a/functions/src/data/place/get/places/DTO/GetPlacesRepositoryRequest.ts b/functions/src/data/place/get/places/DTO/GetPlacesRepositoryRequest.ts new file mode 100644 index 0000000..8763a34 --- /dev/null +++ b/functions/src/data/place/get/places/DTO/GetPlacesRepositoryRequest.ts @@ -0,0 +1,5 @@ +export type GetPlacesRepositoryRequest = { + searchText: string + nextPageToken?: string + userLocation?: { latitude: number, longitude: number } +} \ No newline at end of file diff --git a/functions/src/data/place/get/places/GetPlacesRepository.ts b/functions/src/data/place/get/places/GetPlacesRepository.ts index 0c9870d..610713f 100644 --- a/functions/src/data/place/get/places/GetPlacesRepository.ts +++ b/functions/src/data/place/get/places/GetPlacesRepository.ts @@ -1,21 +1,35 @@ import { PlaceDTO } from "../place/DTO/PlaceDTO" import { AddressComponentsDTO } from "../place/DTO/AddressComponentsDTO" import { GetPlacesRepositoryResponse } from "./DTO/GetPlacesRepositoryResponse" +import { GetPlacesRepositoryRequest } from "./DTO/GetPlacesRepositoryRequest" +import { locationRestrictionOfNZ } from "@shared/constants" -export const locationRestrictionOfNZ = { - rectangle: { - low: { - latitude: -47.0, - longitude: 166.0, - }, - high: { - latitude: -34.0, - longitude: 178.0, - }, + +export function GetPlacesRepository(request: GetPlacesRepositoryRequest): Promise +export function GetPlacesRepository(placesId: string[]): Promise + +export async function GetPlacesRepository(param: GetPlacesRepositoryRequest | string[]): Promise { + if (Array.isArray(param)) { + return await _GetPlacesFromFirestore(param) + } else { + const request = param as GetPlacesRepositoryRequest + return await _GetPlacesFromGoogle(request.searchText, request.nextPageToken, request.userLocation) + } +} + +async function _GetPlacesFromFirestore(placeIds: string[]): Promise { + + /* + Here you have to acess to Firestore and get the places by placeIds. + Return nextPageToken as undefined. + */ + + return { + places: [], } } -export async function GetPlacesRepository( +async function _GetPlacesFromGoogle( searchText: string, nextPageToken?: string, userLocation?: { latitude: number, longitude: number } diff --git a/functions/src/data/place/index.ts b/functions/src/data/place/index.ts index b3d21da..55912d3 100644 --- a/functions/src/data/place/index.ts +++ b/functions/src/data/place/index.ts @@ -3,5 +3,4 @@ export { PostPlaceRepositoryRequest } from './post/place/DTO/PostPlaceRepository export { PlaceDTO } from './get/place/DTO/PlaceDTO' export { GetPlacesRepository } from './get/places/GetPlacesRepository' export { GetPlaceRepository } from './get/place/GetPlaceRepository' -export { PostPlaceRepository } from './post/place/PostPlaceRepository' -export { locationRestrictionOfNZ } from './get/places/GetPlacesRepository' \ No newline at end of file +export { PostPlaceRepository } from './post/place/PostPlaceRepository' \ No newline at end of file diff --git a/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts b/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts index e8b4721..6ff6128 100644 --- a/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts +++ b/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts @@ -8,6 +8,7 @@ export enum SurchargeStatus { export type GetSurchargesRepositoryResponse = { id: string + image?: string placeInformation: string reportedDate: Timestamp rate: number diff --git a/functions/src/data/surcharge/get/getSurchargesRepository.ts b/functions/src/data/surcharge/get/getSurchargesRepository.ts index c8e7f11..427f180 100644 --- a/functions/src/data/surcharge/get/getSurchargesRepository.ts +++ b/functions/src/data/surcharge/get/getSurchargesRepository.ts @@ -1,5 +1,6 @@ import { GetSurchargesRepositoryResponse, SurchargeStatus } from './DTO/GetSurchargesRepositoryResponse' import { database } from "@data/firebase" +// import { storage, getDownloadURL } from "@data/firebase" export function GetSurchargesRepository(placeId: string): Promise export function GetSurchargesRepository(placeIds: string[]): Promise @@ -80,30 +81,37 @@ async function _GetSurcharges(placeIds: string[]): Promise { try { - const surcharges = await database - .collection('surcharges') - .get() - if (!surcharges){ - console.log('There is no surcharges data yet') - return {} - } else{ - const AllSurcharges = surcharges.docs.map((surcharge) => { - const data = surcharge.data() + const surcharges = await database.collection('surcharges').get(); + + if (surcharges.empty) { + console.log('There is no surcharges data yet'); + return {}; + } + + // Fetch all surcharges and handle image retrieval + const AllSurcharges = await Promise.all( + surcharges.docs.map(async (surcharge) => { + const data = surcharge.data(); + // const fileName = data.image; + // const file = storage.bucket().file(fileName); + // const url = await getDownloadURL(file) return { id: surcharge.id, - placeInformation: data.placeInformation, // Convert Firestore reference to string + image: data.image, // Download url + placeInformation: data.placeInformation, // Convert Firestore reference to string if necessary rate: data.rate, reportedDate: data.reportedDate, // Keep as Firestore Timestamp totalAmount: data.totalAmount, surchargeAmount: data.surchargeAmount, - surchargeStatus: data.surchargeStatus - } + surchargeStatus: data.surchargeStatus, + }; }) - console.log("All surcharges fetched successfully:", AllSurcharges); - return AllSurcharges - } + ); + + console.log('All surcharges fetched successfully:'); + return AllSurcharges; } catch (error) { - console.error("Error fetching surcharges:", error); + console.error('Error fetching surcharges:', error); throw error; } } \ No newline at end of file diff --git a/functions/src/data/surcharge/index.ts b/functions/src/data/surcharge/index.ts index e412cc4..fb05121 100644 --- a/functions/src/data/surcharge/index.ts +++ b/functions/src/data/surcharge/index.ts @@ -1,5 +1,7 @@ export { GetSurchargesRepository } from './get/getSurchargesRepository' export { PostSurchargeRepo } from "./post/postSurchargeRepository" export {SurchargeStatus} from "./post/DTO/PostSurchargeRepositoryRequest" +export { PutSurchargeRepository } from "./put/PutSurchargeRepository" export { GetSurchargesRepositoryResponse } from './get/DTO/GetSurchargesRepositoryResponse' -export { PostSurchargeRepositoryRequest } from './post/DTO/PostSurchargeRepositoryRequest' \ No newline at end of file +export { PostSurchargeRepositoryRequest } from './post/DTO/PostSurchargeRepositoryRequest' +export { PutSurchargeRepositoryRequest } from './put/DTO/PutSurchargeRepositoryRequest' \ No newline at end of file diff --git a/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts b/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts new file mode 100644 index 0000000..d8eb7f9 --- /dev/null +++ b/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts @@ -0,0 +1,16 @@ +export enum SurchargeStatus { + REPORTED = 'REPORTED', + CONFIRMED = 'CONFIRMED', + UNKNOWN = 'UNKNOWN', + REJECTED = 'REJECTED', + AUTO_GENERATED = 'AUTO_GENERATED' +} + +export type PutSurchargeRepositoryRequest = { + id: string, + rate?: number, + surchargeAmount?: number, + totalAmount?: number, + surchargeStatus: SurchargeStatus, + action: string +} \ No newline at end of file diff --git a/functions/src/data/surcharge/put/PutSurchargeRepository.ts b/functions/src/data/surcharge/put/PutSurchargeRepository.ts new file mode 100644 index 0000000..ed53733 --- /dev/null +++ b/functions/src/data/surcharge/put/PutSurchargeRepository.ts @@ -0,0 +1,66 @@ +import { SurchargeStatus } from "@domain/surcharge"; +import { PutSurchargeRepositoryRequest } from "./DTO/PutSurchargeRepositoryRequest"; +import { database } from "@data/firebase" +import { storage } from "@data/firebase"; + +export async function PutSurchargeRepository(request: PutSurchargeRepositoryRequest): Promise { + try { + console.log("PutSurchargeRepository ID: ", request.id) + const dbRef = database.collection('surcharges') + const docRef = dbRef.doc(request.id) + const doc = await docRef.get() + const surcharge = doc.data() + + if (!docRef || !surcharge ) { + throw new Error("Surcharge data is undefined for the given id in PutSurchargeRepository.") + } else { + function newFolder(surchargeImage: string, status: SurchargeStatus){ + if (request.action === "CONFIRM" && status === SurchargeStatus.REPORTED){ + return `confirmed/${surchargeImage.substring(9)}` // from "reported/..." to "confirmed/.." + } else if (request.action === "REJECT" && status === SurchargeStatus.REPORTED){ + return `rejected/${surchargeImage.substring(9)}` // from "reported/..." to "rejected/.." + } else if (request.action === "CONFIRM" && status === SurchargeStatus.REJECTED){ + return `confirmed/${surchargeImage.substring(9)}` // from "rejected/..." to "confirmed/.." + } else if (request.action === "REJECT" && status === SurchargeStatus.CONFIRMED){ + return `rejected/${surchargeImage.substring(10)}` // from "confirmed/..." to "rejected/.." + } else return surchargeImage + } + + try { + const imageRef = storage.bucket().file(surcharge.image); + const [fileBuffer] = await imageRef.download(); + const newFileRef = storage.bucket().file(newFolder(surcharge.image, surcharge.surchargeStatus)); + await newFileRef.save(fileBuffer, { contentType: 'image/jpeg' }); + await imageRef.delete(); + console.log(`Image moved to ${newFileRef.name} and deleted from the previous location.`); + } catch (error) { + console.error("An error occurred while moving the image:", error); + } + + + await docRef.set({ + image: newFolder(surcharge.image, surcharge.surchargeStatus), + placeInformation: surcharge.placeInformation, + rate: request.rate ?? surcharge.rate, + reportedDate: surcharge.reportedDate, + surchargeAmount: request.surchargeAmount ?? surcharge.surchargeAmount, + surchargeStatus: request.surchargeStatus, + totalAmount: request.totalAmount ?? surcharge.totalAmount + }); + + // return { + // image: imageNameWithNewFolder, + // placeInformation: surcharge.placeInformation, + // rate: request.rate ?? surcharge.rate, + // reportedDate: surcharge.reportedDate, + // surchargeAmount: request.surchargeAmount ?? surcharge.surchargeAmount, + // surchargeStatus: request.surchargeStatus, + // totalAmount: request.totalAmount ?? surcharge.totalAmount + // } + console.log("Surcharge confirmed in PutSurchargeRepository:"); + } + } catch (error) { + console.error("Error updating surcharge:", error); + throw error; // Re-throw the error for higher-level handling if needed + } +} \ No newline at end of file diff --git a/functions/src/domain/image/get/image/entity/GetImageUsecaseRequest.ts b/functions/src/domain/image/get/image/entity/GetImageUsecaseRequest.ts new file mode 100644 index 0000000..3786101 --- /dev/null +++ b/functions/src/domain/image/get/image/entity/GetImageUsecaseRequest.ts @@ -0,0 +1,3 @@ +export interface GetImageUsecaseRequest { + image: string +} \ No newline at end of file diff --git a/functions/src/domain/image/get/image/entity/GetImageUsecaseResponse.ts b/functions/src/domain/image/get/image/entity/GetImageUsecaseResponse.ts new file mode 100644 index 0000000..dbb7a5b --- /dev/null +++ b/functions/src/domain/image/get/image/entity/GetImageUsecaseResponse.ts @@ -0,0 +1,3 @@ +export interface GetImageUsecaseResponse { + image: string | [] +} \ No newline at end of file diff --git a/functions/src/domain/image/get/image/getImageUsecase.ts b/functions/src/domain/image/get/image/getImageUsecase.ts new file mode 100644 index 0000000..12fd13c --- /dev/null +++ b/functions/src/domain/image/get/image/getImageUsecase.ts @@ -0,0 +1,11 @@ +import { GetImageUsecaseRequest } from "./entity/GetImageUsecaseRequest"; +import { GetImageUsecaseResponse } from "./entity/GetImageUsecaseResponse"; +import { GetImageRepository } from '@data/image' + +export const getImageUsecase = async (request: GetImageUsecaseRequest): Promise => { + const result = await GetImageRepository(request.image); + + return { + image: result.image, + }; +}; diff --git a/functions/src/domain/image/index.ts b/functions/src/domain/image/index.ts new file mode 100644 index 0000000..bcd9c74 --- /dev/null +++ b/functions/src/domain/image/index.ts @@ -0,0 +1 @@ +export { getImageUsecase } from "./get/image/getImageUsecase" \ No newline at end of file diff --git a/functions/src/domain/place/get/places/getPlacesUsecase.ts b/functions/src/domain/place/get/places/getPlacesUsecase.ts index 7679859..74ff90b 100644 --- a/functions/src/domain/place/get/places/getPlacesUsecase.ts +++ b/functions/src/domain/place/get/places/getPlacesUsecase.ts @@ -2,18 +2,49 @@ import { GetSurchargesRepository, SurchargeStatus } from "@data/surcharge" import { GetPlacesUsecaseRequest } from "./entity/GetPlacesUsecaseRequest" import { GetPlacesUsecaseResponse } from "./entity/GetPlacesUsecaseResponse" import { GetPlacesRepository } from "@data/place" +import { locationRestrictionOfNZ } from "@shared/constants" -import { locationRestrictionOfNZ } from "@data/place" +export function GetPlacesUsecase(request: GetPlacesUsecaseRequest): Promise +export function GetPlacesUsecase(placeIds: string[]): Promise -export const getPlacesUsecase = async (request: GetPlacesUsecaseRequest): Promise => { +export async function GetPlacesUsecase(param: GetPlacesUsecaseRequest | string[]): Promise { + if (Array.isArray(param)) { + return await _GetPlacesByPlaceId(param) + } else { + return await _GetPlacesByRequest(param) + } + +} + +async function _GetPlacesByPlaceId(placeId: string[]): Promise { + + /* + I think you can start here, and of course you need a repository for getting places by placeId + I made a snippet for you, and it can be found in GetPlacesRepository.ts + Return nextPageToken as undefined. + */ + + return { + places: [], + nextPageToken: undefined, + } +} + +async function _GetPlacesByRequest(request: GetPlacesUsecaseRequest): Promise { if (request.userLocation) { if (!isPointInRectangle(request.userLocation, locationRestrictionOfNZ)) { throw new Error("User location is out of New Zealand") } } - const resultPlaces = await GetPlacesRepository(request.searchText, request.nextPageToken, request.userLocation) + const resultPlaces = await GetPlacesRepository( + { + searchText: request.searchText, + nextPageToken: request.nextPageToken, + userLocation: request.userLocation, + } + ) const resultPlaceIds = resultPlaces.places.map((place) => { return place.id diff --git a/functions/src/domain/place/index.ts b/functions/src/domain/place/index.ts index 2d0b7da..a0467ac 100644 --- a/functions/src/domain/place/index.ts +++ b/functions/src/domain/place/index.ts @@ -1,2 +1,2 @@ -export { getPlacesUsecase } from "./get/places/getPlacesUsecase" +export { GetPlacesUsecase } from "./get/places/GetPlacesUsecase" export { getPlaceUsecase } from "./get/place/getPlaceUsecase" \ No newline at end of file diff --git a/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts b/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts index 20fcd71..6f0e054 100644 --- a/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts +++ b/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts @@ -5,6 +5,8 @@ export enum SurchargeStatus{ } export type GetSurchargeUsecaseResponse = { + id: string, + image?: string, placeInformation: string; rate: number, reportedDate: number diff --git a/functions/src/domain/surcharge/get/getSurchargeUsecase.ts b/functions/src/domain/surcharge/get/getSurchargeUsecase.ts index d93f8c6..cab744c 100644 --- a/functions/src/domain/surcharge/get/getSurchargeUsecase.ts +++ b/functions/src/domain/surcharge/get/getSurchargeUsecase.ts @@ -7,6 +7,7 @@ export const getSurchargeUsecase = async (request: GetSurchargeUsecaseRequest): const result = await GetSurchargesRepository(request.placeId) return { + id: result.id, placeInformation: result.placeInformation, rate: result.rate, reportedDate: result.reportedDate.toMillis(), diff --git a/functions/src/domain/surcharge/get/getSurchargesUsecase.ts b/functions/src/domain/surcharge/get/getSurchargesUsecase.ts index 97babf1..79cb65b 100644 --- a/functions/src/domain/surcharge/get/getSurchargesUsecase.ts +++ b/functions/src/domain/surcharge/get/getSurchargesUsecase.ts @@ -6,17 +6,19 @@ export const getSurchargesUsecase = async (): Promise { return { - placeInformation: surcharge.placeInformation, - rate: surcharge.rate, - reportedDate: surcharge.reportedDate.toMillis(), - totalAmount: surcharge.totalAmount, - surchargeAmount: surcharge.surchargeAmount, - surchargeStatus: surcharge.surchargeStatus + id: surcharge.id, + image: surcharge.image, + placeInformation: surcharge.placeInformation, + rate: surcharge.rate, + reportedDate: surcharge.reportedDate.toMillis(), + totalAmount: surcharge.totalAmount, + surchargeAmount: surcharge.surchargeAmount, + surchargeStatus: surcharge.surchargeStatus } }) return result } catch (error) { - console.error("Error posting surcharge:", error); + console.error("Error at getSurchargesUsecase:", error); throw error; } diff --git a/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts b/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts index 62d0d69..d166651 100644 --- a/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts +++ b/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts @@ -4,16 +4,16 @@ export function rateCalculatorHelper( surchargeAmount: number ): number { if (typeof rate === 'undefined' || rate <= 0) { - const purchaseAmount = totalAmount - surchargeAmount; - + throw new Error('Invalid input: rate amount must be greater than 0.'); + } else { + if (surchargeAmount <= 0 || totalAmount <= 0) { + throw new Error('Invalid input: surchargeAmount and totalAmount must be greater than 0.'); + } + const purchaseAmount = totalAmount - surchargeAmount if (purchaseAmount <= 0) { throw new Error('Invalid input: purchaseAmount amount must be greater than 0.'); } - if (surchargeAmount <= 0) { - throw new Error('Invalid input: surchargeAmount amount must be greater than 0.'); - } - return Math.round((surchargeAmount / purchaseAmount) * 100); + const rate = (surchargeAmount / purchaseAmount) * 100 + return Number(rate.toFixed(1)) } - - return rate; } diff --git a/functions/src/domain/surcharge/index.ts b/functions/src/domain/surcharge/index.ts index 8adb4c4..cb74466 100644 --- a/functions/src/domain/surcharge/index.ts +++ b/functions/src/domain/surcharge/index.ts @@ -1,6 +1,9 @@ export { getSurchargeUsecase } from "./get/getSurchargeUsecase" export { getSurchargesUsecase } from "./get/getSurchargesUsecase" export { postSurchargeUsecase } from "./post/postSurchargeUsecase" -export { PostSurchargeUsecaseRequest } from './post/entity/PostSurchargeUsecaseRequest' +export { putSurchargeUsecase } from "./put/putSurchargeUsecase" export { GetSurchargeUsecaseResponse } from './get/entity/GetSurchargeUsecaseResponse' export { GetSurchargeUsecaseRequest } from './get/entity/GetSurchargeUsecaseRequest' +export { PostSurchargeUsecaseRequest } from './post/entity/PostSurchargeUsecaseRequest' +export { PutSurchargeUsecaseRequest } from "./put/entity/PutSurchargeUsecaseRequest" +export { SurchargeStatus } from './put/entity/SurchargeStatus' \ No newline at end of file diff --git a/functions/src/domain/surcharge/post/RateCalculator.ts b/functions/src/domain/surcharge/post/RateCalculator.ts index de7ab61..7fee235 100644 --- a/functions/src/domain/surcharge/post/RateCalculator.ts +++ b/functions/src/domain/surcharge/post/RateCalculator.ts @@ -3,5 +3,6 @@ export function RateCalculator( surchargeAmount: number ): number { const purchaseAmount = totalAmount - surchargeAmount - return Math.round((surchargeAmount / purchaseAmount) * 100) + const rate = (surchargeAmount / purchaseAmount) * 100 + return Number(rate.toFixed(1)) } \ No newline at end of file diff --git a/functions/src/domain/surcharge/put/entity/PutSurchargeUsecaseRequest.ts b/functions/src/domain/surcharge/put/entity/PutSurchargeUsecaseRequest.ts new file mode 100644 index 0000000..50842db --- /dev/null +++ b/functions/src/domain/surcharge/put/entity/PutSurchargeUsecaseRequest.ts @@ -0,0 +1,6 @@ +export type PutSurchargeUsecaseRequest = { + id: string, + surchargeAmount? : number, + totalAmount? : number, + action: string +} \ No newline at end of file diff --git a/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts b/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts new file mode 100644 index 0000000..7b60cfd --- /dev/null +++ b/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts @@ -0,0 +1,7 @@ +export enum SurchargeStatus { + REPORTED = 'REPORTED', + CONFIRMED = 'CONFIRMED', + UNKNOWN = 'UNKNOWN', + REJECTED = 'REJECTED', + AUTO_GENERATED = 'AUTO_GENERATED' + } \ No newline at end of file diff --git a/functions/src/domain/surcharge/put/putSurchargeUsecase.ts b/functions/src/domain/surcharge/put/putSurchargeUsecase.ts new file mode 100644 index 0000000..1371fb4 --- /dev/null +++ b/functions/src/domain/surcharge/put/putSurchargeUsecase.ts @@ -0,0 +1,72 @@ +import { PutSurchargeUsecaseRequest } from "@domain/surcharge" +// import { GetSurchargesRepository } from "@data/surcharge" +import { PutSurchargeRepository } from "@data/surcharge" +import { SurchargeStatus } from "./entity/SurchargeStatus" +import { rateCalculatorHelper } from "../helpers/rateCalculatorHelper"; + +export const putSurchargeUsecase = async ( + request: PutSurchargeUsecaseRequest +): Promise<{ id: string; surchargeAmount?: number; totalAmount?: number; rate?: number; surchargeStatus: SurchargeStatus; action: string }> => { + let newRate: number | undefined = undefined; + + if (request.totalAmount && request.surchargeAmount) { + newRate = rateCalculatorHelper( + undefined, + request.totalAmount, + request.surchargeAmount + ); + return await returnUpdatedSurcharge( + request.id, + newRate, + request.totalAmount, + request.surchargeAmount, + request.action + ); + } else { + return await returnUpdatedSurcharge( + request.id, + undefined, + undefined, + undefined, + request.action + ); + } +}; + +async function returnUpdatedSurcharge( + id: string, + rate: number | undefined, + totalAmount: number | undefined, + surchargeAmount: number | undefined, + action: string +): Promise<{ + id: string; + surchargeAmount?: number; + totalAmount?: number; + rate?: number; + surchargeStatus: SurchargeStatus; + action: string +}> { + let status = SurchargeStatus.REPORTED + if(action === "CONFIRM"){ + status = SurchargeStatus.CONFIRMED + } else if(action === "REJECT"){ + status = SurchargeStatus.REJECTED + } + const updatedSurcharge = { + id: id, + surchargeAmount: surchargeAmount, + totalAmount: totalAmount, + rate: rate, + surchargeStatus: status, + action: action + }; + + console.log( + "putSurchargeUsecase surchargeAmount and totalAmount:", + updatedSurcharge + ); + + await PutSurchargeRepository(updatedSurcharge); + return updatedSurcharge; +} \ No newline at end of file diff --git a/functions/src/index.ts b/functions/src/index.ts index be89366..f400122 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -3,7 +3,8 @@ require('module-alias/register') import express from "express"; import { onRequest } from "firebase-functions/v2/https"; import { getPlaceInterface, getPlacesInterface } from "@interface/place"; -import { getSurchargeInterface, postSurchargeInterface, getSurchargesInterface } from "@interface/surcharge"; +import { getSurchargeInterface, postSurchargeInterface, getSurchargesInterface, putSurchargeInterface } from "@interface/surcharge"; +import { getImageInterface } from "@interface/image"; import { AdminAuth } from "@shared/authentication"; import { MobileAuth } from "@shared/authentication"; import { WrappingResponse } from "@shared/middleware"; @@ -33,7 +34,8 @@ const admin = express() admin.use(cors(corsOptions)) admin.use(AdminAuth) admin.get("/surcharges", getSurchargesInterface) -//admin.put("/surcharge", putSurchargeInterface) +admin.put("/surcharge", putSurchargeInterface) +admin.get("/image", getImageInterface) exports.admin = onRequest(admin) // For Mobile APIs diff --git a/functions/src/interface/image/get/image/getImageInterface.ts b/functions/src/interface/image/get/image/getImageInterface.ts new file mode 100644 index 0000000..62cddd9 --- /dev/null +++ b/functions/src/interface/image/get/image/getImageInterface.ts @@ -0,0 +1,24 @@ +import express from "express"; +import { getImageUsecase } from "@domain/image"; +import { Response } from "./model/GetImageInterfaceResponse"; + +export const getImageInterface = async (request: express.Request, response: Response) => { + const image = (request.query.image as string) || undefined; + + if (!image) { + response.status(400).send({ message: "Missing image name" }); + return; + } + + try { + const result = await getImageUsecase({ image: image }); + // console.log("getImageInterface result: ", result.image) + + response.status(200).send({ + image: result.image, + }); + } catch (error) { + console.error("Error fetching image data:", error); + response.status(500).send({ message: "Internal server error" }); + } +}; diff --git a/functions/src/interface/image/get/image/model/GetImageInterfaceResponse.ts b/functions/src/interface/image/get/image/model/GetImageInterfaceResponse.ts new file mode 100644 index 0000000..d4565e8 --- /dev/null +++ b/functions/src/interface/image/get/image/model/GetImageInterfaceResponse.ts @@ -0,0 +1,10 @@ +import express from "express" + +export interface GetPlaceInterfaceResponse { + image: string +} + +export interface Response extends express.Response { + status(status: number): any + send(data: GetPlaceInterfaceResponse): any +} \ No newline at end of file diff --git a/functions/src/interface/image/index.ts b/functions/src/interface/image/index.ts new file mode 100644 index 0000000..63c2d36 --- /dev/null +++ b/functions/src/interface/image/index.ts @@ -0,0 +1 @@ +export { getImageInterface } from "./get/image/getImageInterface" \ No newline at end of file diff --git a/functions/src/interface/place/get/places/getPlacesInterface.ts b/functions/src/interface/place/get/places/getPlacesInterface.ts index 5700e72..b946055 100644 --- a/functions/src/interface/place/get/places/getPlacesInterface.ts +++ b/functions/src/interface/place/get/places/getPlacesInterface.ts @@ -1,5 +1,5 @@ import express from "express" -import { getPlacesUsecase } from "@domain/place" +import { GetPlacesUsecase } from "@domain/place" import { Response } from "./model/GetPlacesInterfaceResponse" export const getPlacesInterface = async (request: express.Request, response: Response) => { @@ -22,7 +22,7 @@ export const getPlacesInterface = async (request: express.Request, response: Res } try { - const places = await getPlacesUsecase({ searchText, nextPageToken, userLocation: userLocation() }) + const places = await GetPlacesUsecase({ searchText, nextPageToken, userLocation: userLocation() }) response.status(200).send({ places: places.places.map((place) => { diff --git a/functions/src/interface/surcharge/get/getSurchargesInterface.ts b/functions/src/interface/surcharge/get/getSurchargesInterface.ts index 3b34d76..88fde73 100644 --- a/functions/src/interface/surcharge/get/getSurchargesInterface.ts +++ b/functions/src/interface/surcharge/get/getSurchargesInterface.ts @@ -1,4 +1,4 @@ -import { getSurchargesUsecase } from "@domain/surcharge"; +import { getSurchargesUsecase } from "@domain/surcharge" import { Response, Request } from "express"; export const getSurchargesInterface = async (req: Request, res: Response) => { @@ -6,6 +6,8 @@ export const getSurchargesInterface = async (req: Request, res: Response) => { const surcharges = await getSurchargesUsecase(); res.status(200).send( surcharges.map((surcharge) => ({ + id: surcharge.id, + image: surcharge.image, placeInformation: surcharge.placeInformation, rate: surcharge.rate, reportedDate: surcharge.reportedDate, diff --git a/functions/src/interface/surcharge/index.ts b/functions/src/interface/surcharge/index.ts index 8d67ad6..7ccf6c2 100644 --- a/functions/src/interface/surcharge/index.ts +++ b/functions/src/interface/surcharge/index.ts @@ -1,3 +1,6 @@ export { getSurchargeInterface } from "./get/getSurchargeInterface" -export { getSurchargesInterface } from "./get/getSurchargesInterface" export { postSurchargeInterface } from "./post/postSurchargeInterface" +export { putSurchargeInterface } from "./put/putSurchargeInterface" +export { PostSurchargeInterfaceRequest } from "./post/models/PostSurchargeInterfaceRequest" +export { PutSurchargeInterfaceRequest } from "./put/models/PutSurchargeInterfaceRequest" +export { getSurchargesInterface } from "./get/getSurchargesInterface" diff --git a/functions/src/interface/surcharge/put/models/PutSurchargeInterfaceRequest.ts b/functions/src/interface/surcharge/put/models/PutSurchargeInterfaceRequest.ts new file mode 100644 index 0000000..be42c16 --- /dev/null +++ b/functions/src/interface/surcharge/put/models/PutSurchargeInterfaceRequest.ts @@ -0,0 +1,6 @@ +export type PutSurchargeInterfaceRequest = { + id: string, + surchargeAmount? : number, + totalAmount? : number, + action: string +} \ No newline at end of file diff --git a/functions/src/interface/surcharge/put/putSurchargeInterface.ts b/functions/src/interface/surcharge/put/putSurchargeInterface.ts new file mode 100644 index 0000000..b01b520 --- /dev/null +++ b/functions/src/interface/surcharge/put/putSurchargeInterface.ts @@ -0,0 +1,20 @@ +import { PutSurchargeInterfaceRequest } from "@interface/surcharge" +import { Request, Response } from "express"; +import { putSurchargeUsecase } from "@domain/surcharge" + +export const putSurchargeInterface = async (req: Request, res: Response): Promise => { + try { + let { id, surchargeAmount, totalAmount, action } = req.body; + const surcharge: PutSurchargeInterfaceRequest = { + id: id, + surchargeAmount: surchargeAmount, + totalAmount: totalAmount, + action: action, + }; + await putSurchargeUsecase(surcharge); + res.status(200).send({ message: "Surcharge successfully confirmed." }); + } catch (error) { + console.error("Error in putSurchargeInterface:", error); + res.status(500).send({ message: "An error occurred while verifying the surcharge." }); + } +}; diff --git a/functions/src/shared/constants/LocationRestrictions.ts b/functions/src/shared/constants/LocationRestrictions.ts new file mode 100644 index 0000000..96f5e29 --- /dev/null +++ b/functions/src/shared/constants/LocationRestrictions.ts @@ -0,0 +1,12 @@ +export const locationRestrictionOfNZ = { + rectangle: { + low: { + latitude: -47.0, + longitude: 166.0, + }, + high: { + latitude: -34.0, + longitude: 178.0, + }, + } +} \ No newline at end of file diff --git a/functions/src/shared/constants/index.ts b/functions/src/shared/constants/index.ts new file mode 100644 index 0000000..b54577a --- /dev/null +++ b/functions/src/shared/constants/index.ts @@ -0,0 +1 @@ +export { locationRestrictionOfNZ } from "./LocationRestrictions" \ No newline at end of file From 98289c0359185eb9790a38dff1e5ebaf61cb08b4 Mon Sep 17 00:00:00 2001 From: Bonsung Koo Date: Tue, 28 Jan 2025 15:26:58 +1300 Subject: [PATCH 02/10] GitHub Action for validating build is added. #51 (#52) --- .github/workflows/build-validator.yml | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/build-validator.yml diff --git a/.github/workflows/build-validator.yml b/.github/workflows/build-validator.yml new file mode 100644 index 0000000..fd94fb8 --- /dev/null +++ b/.github/workflows/build-validator.yml @@ -0,0 +1,28 @@ +name: Validate Build + +on: + pull_reuqest: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22.0 + + - name: Install Dependencies + run: | + cd functions + npm install + + - name: Build + run: | + cd functions + npm run build \ No newline at end of file From 9b342a85011f5a359074123d22ea9cbcf83fcb87 Mon Sep 17 00:00:00 2001 From: Bonsung Koo Date: Tue, 28 Jan 2025 15:33:30 +1300 Subject: [PATCH 03/10] Broken github action file is fixed. #51 (#53) --- .github/workflows/build-validator.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-validator.yml b/.github/workflows/build-validator.yml index fd94fb8..f4fe839 100644 --- a/.github/workflows/build-validator.yml +++ b/.github/workflows/build-validator.yml @@ -2,6 +2,7 @@ name: Validate Build on: pull_reuqest: + types: [opened, synchronize, reopened] jobs: build: From 4d8e788977137cb04fc4379771e45e88bad80371 Mon Sep 17 00:00:00 2001 From: Bonsung Koo Date: Tue, 28 Jan 2025 15:52:54 +1300 Subject: [PATCH 04/10] GitHub Action for validating build is added. #51 (#54) --- .github/workflows/build-validator.yml | 2 +- .../get/places/{getPlacesUsecase.ts => GetPlacesUsecase.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename functions/src/domain/place/get/places/{getPlacesUsecase.ts => GetPlacesUsecase.ts} (100%) diff --git a/.github/workflows/build-validator.yml b/.github/workflows/build-validator.yml index f4fe839..47405c5 100644 --- a/.github/workflows/build-validator.yml +++ b/.github/workflows/build-validator.yml @@ -1,7 +1,7 @@ name: Validate Build on: - pull_reuqest: + pull_request: types: [opened, synchronize, reopened] jobs: diff --git a/functions/src/domain/place/get/places/getPlacesUsecase.ts b/functions/src/domain/place/get/places/GetPlacesUsecase.ts similarity index 100% rename from functions/src/domain/place/get/places/getPlacesUsecase.ts rename to functions/src/domain/place/get/places/GetPlacesUsecase.ts From 81c09493b65fa48ecdce8648155efe4ed8f644d4 Mon Sep 17 00:00:00 2001 From: Petr Utkin <103509683+PetruccioU@users.noreply.github.com> Date: Wed, 29 Jan 2025 21:17:51 +1300 Subject: [PATCH 05/10] 50 overload getplacesusecase getplacesrepository (#55) * GetPlacesUsecase updated, also PlaceDTO and Place type * GetPlacesRepository updated along with GetPlacesRepositoryResponse and PostPlaceRepositoryRequest * getPlacesWithSurchargesInterface crated, introduced into index and exported * totalAmount, surchargeAmount and reportedDate added to getPlacesWithSurchargesInterface * GetPlaces api updated --- .../src/data/place/get/place/DTO/PlaceDTO.ts | 2 +- .../places/DTO/GetPlacesRepositoryResponse.ts | 2 +- .../place/get/places/GetPlacesRepository.ts | 51 +++++++--- .../place/DTO/PostPlaceRepositoryRequest.ts | 2 +- .../place/entity/GetPlaceUsecaseResponse.ts | 3 + .../place/get/places/GetPlacesUsecase.ts | 99 ++++++++++++------- functions/src/index.ts | 3 +- .../getPlacesWithSurchargesInterface.ts | 44 +++++++++ functions/src/interface/place/index.ts | 3 +- functions/src/shared/types/place/Place.ts | 2 +- 10 files changed, 156 insertions(+), 55 deletions(-) create mode 100644 functions/src/interface/place/get/places/getPlacesWithSurchargesInterface.ts diff --git a/functions/src/data/place/get/place/DTO/PlaceDTO.ts b/functions/src/data/place/get/place/DTO/PlaceDTO.ts index 4f64caa..eb15602 100644 --- a/functions/src/data/place/get/place/DTO/PlaceDTO.ts +++ b/functions/src/data/place/get/place/DTO/PlaceDTO.ts @@ -6,5 +6,5 @@ export type PlaceDTO = { id: string, displayName: LocalizedTextDTO, addressComponents: AddressComponentsDTO[], - location: LatLngDTO + location: LatLngDTO | null } \ No newline at end of file diff --git a/functions/src/data/place/get/places/DTO/GetPlacesRepositoryResponse.ts b/functions/src/data/place/get/places/DTO/GetPlacesRepositoryResponse.ts index bd6d781..be9eb55 100644 --- a/functions/src/data/place/get/places/DTO/GetPlacesRepositoryResponse.ts +++ b/functions/src/data/place/get/places/DTO/GetPlacesRepositoryResponse.ts @@ -1,6 +1,6 @@ import { PlaceDTO } from "../../place/DTO/PlaceDTO"; export type GetPlacesRepositoryResponse = { - places: PlaceDTO[], + places: PlaceDTO[] | [], nextPageToken?: string } \ No newline at end of file diff --git a/functions/src/data/place/get/places/GetPlacesRepository.ts b/functions/src/data/place/get/places/GetPlacesRepository.ts index 610713f..0ae0471 100644 --- a/functions/src/data/place/get/places/GetPlacesRepository.ts +++ b/functions/src/data/place/get/places/GetPlacesRepository.ts @@ -3,10 +3,10 @@ import { AddressComponentsDTO } from "../place/DTO/AddressComponentsDTO" import { GetPlacesRepositoryResponse } from "./DTO/GetPlacesRepositoryResponse" import { GetPlacesRepositoryRequest } from "./DTO/GetPlacesRepositoryRequest" import { locationRestrictionOfNZ } from "@shared/constants" - +import { database } from "@data/firebase" export function GetPlacesRepository(request: GetPlacesRepositoryRequest): Promise -export function GetPlacesRepository(placesId: string[]): Promise +export function GetPlacesRepository(placesIds: string[]): Promise export async function GetPlacesRepository(param: GetPlacesRepositoryRequest | string[]): Promise { if (Array.isArray(param)) { @@ -17,15 +17,44 @@ export async function GetPlacesRepository(param: GetPlacesRepositoryRequest | st } } -async function _GetPlacesFromFirestore(placeIds: string[]): Promise { - - /* - Here you have to acess to Firestore and get the places by placeIds. - Return nextPageToken as undefined. - */ - - return { - places: [], +async function _GetPlacesFromFirestore( + placesIds: string[] +): Promise { + try { + const placesSnapshot = await database + .collection('places') + .where("id", "in", placesIds) + .get(); + + if (placesSnapshot.empty) { + console.log("Places data are undefined for the given places IDs."); + return { places: [], nextPageToken: undefined }; + } else { + const matchedPlaces = placesSnapshot.docs.map((doc) => { + const data = doc.data() as PlaceDTO; + return { + id: data.id, + displayName: { + text: data.displayName.text, + languageCode: data.displayName.languageCode, + }, + addressComponents: data.addressComponents.map((component: AddressComponentsDTO) => { + return { + longText: component.longText, + shortText: component.shortText, + types: component.types, + languageCode: data.displayName.languageCode, + } + }), + location: null, + }; + }); + + return { places: matchedPlaces, nextPageToken: undefined }; + } + } catch (error) { + console.error("Error fetching places:", error); + throw error; } } diff --git a/functions/src/data/place/post/place/DTO/PostPlaceRepositoryRequest.ts b/functions/src/data/place/post/place/DTO/PostPlaceRepositoryRequest.ts index 8413e1a..d596c18 100644 --- a/functions/src/data/place/post/place/DTO/PostPlaceRepositoryRequest.ts +++ b/functions/src/data/place/post/place/DTO/PostPlaceRepositoryRequest.ts @@ -19,5 +19,5 @@ export interface PostPlaceRepositoryRequest { id: string; displayName: displayName, addressComponents: AddressComponentsDTO[], - location: LatLngDTO + location: LatLngDTO | null } diff --git a/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts b/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts index 2dfb8d9..66e2b97 100644 --- a/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts +++ b/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts @@ -28,7 +28,10 @@ export type GetPlaceUsecaseResponse = { displayName: displayName, addressComponents: addressComponents[], location?: LatLng, + image?: string, rate?: number, reportedDate?: Timestamp, + totalAmount?: number, + surchargeAmount?: number, surchargeStatus?: SurchargeStatus } \ No newline at end of file diff --git a/functions/src/domain/place/get/places/GetPlacesUsecase.ts b/functions/src/domain/place/get/places/GetPlacesUsecase.ts index 74ff90b..878cc0a 100644 --- a/functions/src/domain/place/get/places/GetPlacesUsecase.ts +++ b/functions/src/domain/place/get/places/GetPlacesUsecase.ts @@ -4,56 +4,79 @@ import { GetPlacesUsecaseResponse } from "./entity/GetPlacesUsecaseResponse" import { GetPlacesRepository } from "@data/place" import { locationRestrictionOfNZ } from "@shared/constants" -export function GetPlacesUsecase(request: GetPlacesUsecaseRequest): Promise -export function GetPlacesUsecase(placeIds: string[]): Promise - -export async function GetPlacesUsecase(param: GetPlacesUsecaseRequest | string[]): Promise { +export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string[]): Promise { + let resultPlaces; + + if (Array.isArray(request)) { + + try { + const allSurcharges = await GetSurchargesRepository({}) + const allSurchargesIds = allSurcharges.map((surcharge) => { + return surcharge.id + }) + resultPlaces = await GetPlacesRepository(allSurchargesIds) + + // const resultSurcharges = await GetSurchargesRepository(resultPlaceIds) + + const placesWithSurcharges = resultPlaces.places.map((place) => { + return { + id: place.id, + displayName: { + text: place.displayName.text, + languageCode: place.displayName.languageCode, + }, + addressComponents: place.addressComponents.map((component) => ({ + longText: component.longText, + shortText: component.shortText, + types: component.types, + languageCode: component.languageCode, + })), + location: place.location + ? { + latitude: place.location.latitude, + longitude: place.location.longitude, + } + : undefined, + image: allSurcharges.find((surcharge) => surcharge.id === place.id)?.image, + rate: allSurcharges.find((surcharge) => surcharge.id === place.id)?.rate, + totalAmount: allSurcharges.find((surcharge) => surcharge.id === place.id)?.totalAmount, + reportedDate: allSurcharges.find((surcharge) => surcharge.id === place.id)?.reportedDate, + surchargeAmount: allSurcharges.find((surcharge) => surcharge.id === place.id)?.surchargeAmount, + surchargeStatus: allSurcharges.find((surcharge) => surcharge.id === place.id)?.surchargeStatus as SurchargeStatus, + } + }) + + return { + places: placesWithSurcharges, + nextPageToken: undefined, + } + + } catch (error) { + throw error + } - if (Array.isArray(param)) { - return await _GetPlacesByPlaceId(param) } else { - return await _GetPlacesByRequest(param) - } -} - -async function _GetPlacesByPlaceId(placeId: string[]): Promise { - - /* - I think you can start here, and of course you need a repository for getting places by placeId - I made a snippet for you, and it can be found in GetPlacesRepository.ts - Return nextPageToken as undefined. - */ - - return { - places: [], - nextPageToken: undefined, - } -} - -async function _GetPlacesByRequest(request: GetPlacesUsecaseRequest): Promise { - if (request.userLocation) { - if (!isPointInRectangle(request.userLocation, locationRestrictionOfNZ)) { - throw new Error("User location is out of New Zealand") + if (request.userLocation) { + if (!isPointInRectangle(request.userLocation, locationRestrictionOfNZ)) { + throw new Error("User location is out of New Zealand") + } } + resultPlaces = await GetPlacesRepository( + { + searchText: request.searchText, + nextPageToken: request.nextPageToken, + userLocation: request.userLocation, + } + ) } - const resultPlaces = await GetPlacesRepository( - { - searchText: request.searchText, - nextPageToken: request.nextPageToken, - userLocation: request.userLocation, - } - ) - const resultPlaceIds = resultPlaces.places.map((place) => { return place.id }) try { - const resultSurcharges = await GetSurchargesRepository(resultPlaceIds) - const placesWithSurcharges = resultPlaces.places.map((place) => { return { id: place.id, diff --git a/functions/src/index.ts b/functions/src/index.ts index f400122..50d4c41 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -2,7 +2,7 @@ require('module-alias/register') import express from "express"; import { onRequest } from "firebase-functions/v2/https"; -import { getPlaceInterface, getPlacesInterface } from "@interface/place"; +import { getPlaceInterface, getPlacesInterface, getPlacesWithSurchargesInterface } from "@interface/place"; import { getSurchargeInterface, postSurchargeInterface, getSurchargesInterface, putSurchargeInterface } from "@interface/surcharge"; import { getImageInterface } from "@interface/image"; import { AdminAuth } from "@shared/authentication"; @@ -36,6 +36,7 @@ admin.use(AdminAuth) admin.get("/surcharges", getSurchargesInterface) admin.put("/surcharge", putSurchargeInterface) admin.get("/image", getImageInterface) +admin.get("/places", getPlacesWithSurchargesInterface); exports.admin = onRequest(admin) // For Mobile APIs diff --git a/functions/src/interface/place/get/places/getPlacesWithSurchargesInterface.ts b/functions/src/interface/place/get/places/getPlacesWithSurchargesInterface.ts new file mode 100644 index 0000000..b6d83f6 --- /dev/null +++ b/functions/src/interface/place/get/places/getPlacesWithSurchargesInterface.ts @@ -0,0 +1,44 @@ +import express from "express" +import { GetPlacesUsecase } from "@domain/place" +import { Response } from "./model/GetPlacesInterfaceResponse" + +export const getPlacesWithSurchargesInterface = async (request: express.Request, response: Response) => { + + try { + const places = await GetPlacesUsecase([]) + + response.status(200).send({ + places: places.places.map((place) => { + return { + id: place.id, + displayName: { + text: place.displayName.text, + languageCode: place.displayName.languageCode + }, + addressComponents: place.addressComponents.map((component) => { + return { + longText: component.longText, + shortText: component.shortText, + types: component.types, + languageCode: component.languageCode + } + }), + location: place.location ? { + latitude: place.location.latitude, + longitude: place.location.longitude + } : undefined, + image: place.image, + surchargeStatus: place.surchargeStatus, + totalAmount: place.totalAmount, + surchargeAmount: place.surchargeAmount, + reportedDate: place.reportedDate, + rate: place.rate + } + }), + nextPageToken: places.nextPageToken + }) + + } catch (error: unknown) { + response.status(500).send({ message: error }) + } +} \ No newline at end of file diff --git a/functions/src/interface/place/index.ts b/functions/src/interface/place/index.ts index 2ab68b5..f004a87 100644 --- a/functions/src/interface/place/index.ts +++ b/functions/src/interface/place/index.ts @@ -1,2 +1,3 @@ export { getPlaceInterface } from "./get/place/getPlaceInterface" -export { getPlacesInterface } from "./get/places/getPlacesInterface" \ No newline at end of file +export { getPlacesInterface } from "./get/places/getPlacesInterface" +export { getPlacesWithSurchargesInterface } from "./get/places/getPlacesWithSurchargesInterface" \ No newline at end of file diff --git a/functions/src/shared/types/place/Place.ts b/functions/src/shared/types/place/Place.ts index 544f274..4c3599d 100644 --- a/functions/src/shared/types/place/Place.ts +++ b/functions/src/shared/types/place/Place.ts @@ -6,5 +6,5 @@ export type Place = { id: string, displayName: LocalizedText, addressComponents: AddressComponents[], - location?: LatLng + location?: LatLng | null } \ No newline at end of file From b6d74b03199de0bf445d8fdbeaabf436bfca216a Mon Sep 17 00:00:00 2001 From: Bonsung Koo Date: Fri, 31 Jan 2025 10:02:48 +1300 Subject: [PATCH 06/10] Checking authorisation scheme on admin api calls #56 (#57) close #56 --- functions/src/shared/authentication/AdminAuth.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/functions/src/shared/authentication/AdminAuth.ts b/functions/src/shared/authentication/AdminAuth.ts index 6c5570a..58b7333 100644 --- a/functions/src/shared/authentication/AdminAuth.ts +++ b/functions/src/shared/authentication/AdminAuth.ts @@ -8,13 +8,20 @@ export const AdminAuth = async ( next: NextFunction ) => { - const idToken = request.headers.authorization + const authorization = request.headers.authorization - if (!idToken) { - response.status(400).send({ message: 'Bad request' }) + if (!authorization) { + response.status(401).send() return } + const [scheme, idToken] = authorization.split(' ') + + if (scheme !== 'Bearer') { + response.status(401).send() + return + } + try { await admin.auth().verifyIdToken(idToken) next() From d787c930aa5960c0b5711d2d02ba53c62bb3cbb9 Mon Sep 17 00:00:00 2001 From: Petr Utkin <103509683+PetruccioU@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:53:40 +1300 Subject: [PATCH 07/10] 'AUTO_GENERATED', 'REJECTED' added (#60) --- .../data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts | 4 +++- .../data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts | 4 ++-- .../domain/place/get/place/entity/GetPlaceUsecaseResponse.ts | 4 +++- .../surcharge/get/entity/GetSurchargeUsecaseResponse.ts | 4 +++- functions/src/domain/surcharge/put/entity/SurchargeStatus.ts | 4 ++-- functions/src/shared/types/surcharge/SurchargeStatus.ts | 4 +++- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts b/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts index 6ff6128..c1a8189 100644 --- a/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts +++ b/functions/src/data/surcharge/get/DTO/GetSurchargesRepositoryResponse.ts @@ -3,7 +3,9 @@ import { Timestamp } from "firebase-admin/firestore"; export enum SurchargeStatus { REPORTED = 'REPORTED', CONFIRMED = 'CONFIRMED', - UNKNOWN = 'UNKNOWN' + UNKNOWN = 'UNKNOWN', + AUTO_GENERATED = 'AUTO_GENERATED', + REJECTED = 'REJECTED' } export type GetSurchargesRepositoryResponse = { diff --git a/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts b/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts index d8eb7f9..3eb578b 100644 --- a/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts +++ b/functions/src/data/surcharge/put/DTO/PutSurchargeRepositoryRequest.ts @@ -2,8 +2,8 @@ export enum SurchargeStatus { REPORTED = 'REPORTED', CONFIRMED = 'CONFIRMED', UNKNOWN = 'UNKNOWN', - REJECTED = 'REJECTED', - AUTO_GENERATED = 'AUTO_GENERATED' + AUTO_GENERATED = 'AUTO_GENERATED', + REJECTED = 'REJECTED' } export type PutSurchargeRepositoryRequest = { diff --git a/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts b/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts index 66e2b97..bedcc45 100644 --- a/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts +++ b/functions/src/domain/place/get/place/entity/GetPlaceUsecaseResponse.ts @@ -20,7 +20,9 @@ type addressComponents = { export enum SurchargeStatus{ REPORTED = 'REPORTED', CONFIRMED = 'CONFIRMED', - UNKNOWN = 'UNKNOWN' + UNKNOWN = 'UNKNOWN', + AUTO_GENERATED = 'AUTO_GENERATED', + REJECTED = 'REJECTED' } export type GetPlaceUsecaseResponse = { diff --git a/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts b/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts index 6f0e054..e62b957 100644 --- a/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts +++ b/functions/src/domain/surcharge/get/entity/GetSurchargeUsecaseResponse.ts @@ -1,7 +1,9 @@ export enum SurchargeStatus{ REPORTED = 'REPORTED', CONFIRMED = 'CONFIRMED', - UNKNOWN = 'UNKNOWN' + UNKNOWN = 'UNKNOWN', + AUTO_GENERATED = 'AUTO_GENERATED', + REJECTED = 'REJECTED' } export type GetSurchargeUsecaseResponse = { diff --git a/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts b/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts index 7b60cfd..23db250 100644 --- a/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts +++ b/functions/src/domain/surcharge/put/entity/SurchargeStatus.ts @@ -2,6 +2,6 @@ export enum SurchargeStatus { REPORTED = 'REPORTED', CONFIRMED = 'CONFIRMED', UNKNOWN = 'UNKNOWN', - REJECTED = 'REJECTED', - AUTO_GENERATED = 'AUTO_GENERATED' + AUTO_GENERATED = 'AUTO_GENERATED', + REJECTED = 'REJECTED' } \ No newline at end of file diff --git a/functions/src/shared/types/surcharge/SurchargeStatus.ts b/functions/src/shared/types/surcharge/SurchargeStatus.ts index d23552f..ee5b728 100644 --- a/functions/src/shared/types/surcharge/SurchargeStatus.ts +++ b/functions/src/shared/types/surcharge/SurchargeStatus.ts @@ -1,5 +1,7 @@ export enum SurchargeStatus { REPORTED = 'REPORTED', CONFIRMED = 'CONFIRMED', - UNKNOWN = 'UNKNOWN' + UNKNOWN = 'UNKNOWN', + AUTO_GENERATED = 'AUTO_GENERATED', + REJECTED = 'REJECTED' } \ No newline at end of file From 98b27cdcc838c1fb1fd21bf2b085dcea2c297146 Mon Sep 17 00:00:00 2001 From: Petr Utkin <103509683+PetruccioU@users.noreply.github.com> Date: Sun, 2 Feb 2025 19:54:23 +1300 Subject: [PATCH 08/10] rateCalculatorHelper updated (#59) --- .../surcharge/helpers/rateCalculatorHelper.ts | 21 +++++++------------ .../surcharge/put/putSurchargeUsecase.ts | 1 - 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts b/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts index d166651..e27e59d 100644 --- a/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts +++ b/functions/src/domain/surcharge/helpers/rateCalculatorHelper.ts @@ -1,19 +1,14 @@ export function rateCalculatorHelper( - rate: number | undefined, totalAmount: number, surchargeAmount: number ): number { - if (typeof rate === 'undefined' || rate <= 0) { - throw new Error('Invalid input: rate amount must be greater than 0.'); - } else { - if (surchargeAmount <= 0 || totalAmount <= 0) { - throw new Error('Invalid input: surchargeAmount and totalAmount must be greater than 0.'); - } - const purchaseAmount = totalAmount - surchargeAmount - if (purchaseAmount <= 0) { - throw new Error('Invalid input: purchaseAmount amount must be greater than 0.'); - } - const rate = (surchargeAmount / purchaseAmount) * 100 - return Number(rate.toFixed(1)) + if (surchargeAmount <= 0 || totalAmount <= 0) { + throw new Error('Invalid input: surchargeAmount and totalAmount must be greater than 0.'); } + const purchaseAmount = totalAmount - surchargeAmount + if (purchaseAmount <= 0) { + throw new Error('Invalid input: purchaseAmount amount must be greater than 0.'); + } + const rate = (surchargeAmount / purchaseAmount) * 100 + return Number(rate.toFixed(1)) } diff --git a/functions/src/domain/surcharge/put/putSurchargeUsecase.ts b/functions/src/domain/surcharge/put/putSurchargeUsecase.ts index 1371fb4..8e5f419 100644 --- a/functions/src/domain/surcharge/put/putSurchargeUsecase.ts +++ b/functions/src/domain/surcharge/put/putSurchargeUsecase.ts @@ -11,7 +11,6 @@ export const putSurchargeUsecase = async ( if (request.totalAmount && request.surchargeAmount) { newRate = rateCalculatorHelper( - undefined, request.totalAmount, request.surchargeAmount ); From 19d0c0a28ce0c200bca994295568cfdd267e23af Mon Sep 17 00:00:00 2001 From: Petr Utkin <103509683+PetruccioU@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:52:17 +1300 Subject: [PATCH 09/10] GetFranchiseRepository created and used into GetSurchargesRepository #61 (#62) * GetFranchiseRepository created and used into GetSurchargesRepository * GetFranchiseRepository used in getPlaceUsecase * Change surcharge information only when it is UNKNOWN. close #61 --------- Co-authored-by: Bonsung Koo --- .../get/franchise/GetFranchiseRepository.ts | 24 +++++++++++++++ functions/src/data/franchise/index.ts | 1 + .../surcharge/get/getSurchargesRepository.ts | 1 - .../domain/place/get/place/getPlaceUsecase.ts | 19 ++++++++++-- .../place/get/places/GetPlacesUsecase.ts | 29 +++++++++++++++---- 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 functions/src/data/franchise/get/franchise/GetFranchiseRepository.ts create mode 100644 functions/src/data/franchise/index.ts diff --git a/functions/src/data/franchise/get/franchise/GetFranchiseRepository.ts b/functions/src/data/franchise/get/franchise/GetFranchiseRepository.ts new file mode 100644 index 0000000..3f3b4ec --- /dev/null +++ b/functions/src/data/franchise/get/franchise/GetFranchiseRepository.ts @@ -0,0 +1,24 @@ +import { database } from '@data/firebase'; + +export async function GetFranchiseRepository(): Promise { + try { + let franchises = [] + const franchisesSnapshot = await database.collection('franchises').get(); + if (franchisesSnapshot.empty) { + console.log("No franchises."); + return []; + } + for (const doc of franchisesSnapshot.docs) { + const data = doc.id; + // console.log("GetFranchiseRepository data: ", JSON.stringify(data)); + franchises.push(data.toLowerCase()) + } + // console.log("GetFranchiseRepository franchises: ", franchises) + return franchises + } catch (error) { + console.error('Error fetching franchises data:', error); + throw error; + } +} + + diff --git a/functions/src/data/franchise/index.ts b/functions/src/data/franchise/index.ts new file mode 100644 index 0000000..21f7e85 --- /dev/null +++ b/functions/src/data/franchise/index.ts @@ -0,0 +1 @@ +export {GetFranchiseRepository} from "./get/franchise/GetFranchiseRepository" \ No newline at end of file diff --git a/functions/src/data/surcharge/get/getSurchargesRepository.ts b/functions/src/data/surcharge/get/getSurchargesRepository.ts index 427f180..a087e08 100644 --- a/functions/src/data/surcharge/get/getSurchargesRepository.ts +++ b/functions/src/data/surcharge/get/getSurchargesRepository.ts @@ -37,7 +37,6 @@ async function _GetSurcharge(placeId: string): Promise => { const result = await GetPlaceRepository(request.id); const surchargeData = await GetSurchargesRepository(request.id); + const franchisesNames = await GetFranchiseRepository() + + const name = result.displayName.text + let rate = surchargeData?.rate ?? undefined + let status = surchargeData?.surchargeStatus ?? SurchargeStatus.UNKNOWN + + franchisesNames.forEach(element => { + if (status === SurchargeStatus.UNKNOWN) { + if(name.toLowerCase().includes(element)){ + status = SurchargeStatus.AUTO_GENERATED + rate = 0.0 + } + } + }) return { id: result.id, @@ -24,8 +39,8 @@ export const getPlaceUsecase = async (request: GetPlaceUsecaseRequest): Promise< latitude: result.location?.latitude ?? 0, longitude: result.location?.longitude ?? 0, }, - rate: surchargeData?.rate ?? undefined, + rate: rate, reportedDate: surchargeData?.reportedDate ?? undefined, // Default to 0 if reportedDate is undefined - surchargeStatus: surchargeData?.surchargeStatus ?? SurchargeStatus.UNKNOWN, + surchargeStatus: status, }; }; diff --git a/functions/src/domain/place/get/places/GetPlacesUsecase.ts b/functions/src/domain/place/get/places/GetPlacesUsecase.ts index 878cc0a..55a859d 100644 --- a/functions/src/domain/place/get/places/GetPlacesUsecase.ts +++ b/functions/src/domain/place/get/places/GetPlacesUsecase.ts @@ -2,6 +2,7 @@ import { GetSurchargesRepository, SurchargeStatus } from "@data/surcharge" import { GetPlacesUsecaseRequest } from "./entity/GetPlacesUsecaseRequest" import { GetPlacesUsecaseResponse } from "./entity/GetPlacesUsecaseResponse" import { GetPlacesRepository } from "@data/place" +import { GetFranchiseRepository } from "@data/franchise" import { locationRestrictionOfNZ } from "@shared/constants" export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string[]): Promise { @@ -17,7 +18,7 @@ export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string resultPlaces = await GetPlacesRepository(allSurchargesIds) // const resultSurcharges = await GetSurchargesRepository(resultPlaceIds) - + const placesWithSurcharges = resultPlaces.places.map((place) => { return { id: place.id, @@ -45,12 +46,12 @@ export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string surchargeStatus: allSurcharges.find((surcharge) => surcharge.id === place.id)?.surchargeStatus as SurchargeStatus, } }) - + return { places: placesWithSurcharges, nextPageToken: undefined, } - + } catch (error) { throw error } @@ -76,8 +77,26 @@ export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string }) try { + const resultSurcharges = await GetSurchargesRepository(resultPlaceIds) + const franchisesNames = await GetFranchiseRepository() + const placesWithSurcharges = resultPlaces.places.map((place) => { + + const name = place.displayName.text + + let rate = resultSurcharges.find((surcharge) => surcharge.id === place.id)?.rate + let status = resultSurcharges.find((surcharge) => surcharge.id === place.id)?.surchargeStatus as SurchargeStatus ?? SurchargeStatus.UNKNOWN + + franchisesNames.forEach(element => { + if (status === SurchargeStatus.UNKNOWN) { + if(name.toLowerCase().includes(element)){ + status = SurchargeStatus.AUTO_GENERATED + rate = 0.0 + } + } + }) + return { id: place.id, displayName: { @@ -96,8 +115,8 @@ export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string longitude: place.location.longitude, } : undefined, - rate: resultSurcharges.find((surcharge) => surcharge.id === place.id)?.rate, - surchargeStatus: resultSurcharges.find((surcharge) => surcharge.id === place.id)?.surchargeStatus as SurchargeStatus, + rate: rate, + surchargeStatus: status } }) From 420fdf1fc6276fe11de1a8332e93e0d7d17a57e8 Mon Sep 17 00:00:00 2001 From: Bonsung Koo Date: Thu, 6 Feb 2025 16:26:16 +1300 Subject: [PATCH 10/10] If there is not any result, server will return 404 error. #23 (#63) --- functions/src/data/place/get/places/GetPlacesRepository.ts | 4 +--- functions/src/domain/place/get/places/GetPlacesUsecase.ts | 5 +++-- .../src/interface/place/get/places/getPlacesInterface.ts | 5 ++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/functions/src/data/place/get/places/GetPlacesRepository.ts b/functions/src/data/place/get/places/GetPlacesRepository.ts index 0ae0471..6eaabbd 100644 --- a/functions/src/data/place/get/places/GetPlacesRepository.ts +++ b/functions/src/data/place/get/places/GetPlacesRepository.ts @@ -129,9 +129,7 @@ async function _GetPlacesFromGoogle( } - const data = await response.json() - - throw new Error(data) + throw new Error(response.statusText) } catch (error) { throw error diff --git a/functions/src/domain/place/get/places/GetPlacesUsecase.ts b/functions/src/domain/place/get/places/GetPlacesUsecase.ts index 55a859d..a2ae659 100644 --- a/functions/src/domain/place/get/places/GetPlacesUsecase.ts +++ b/functions/src/domain/place/get/places/GetPlacesUsecase.ts @@ -78,8 +78,9 @@ export async function GetPlacesUsecase(request: GetPlacesUsecaseRequest | string try { - const resultSurcharges = await GetSurchargesRepository(resultPlaceIds) - const franchisesNames = await GetFranchiseRepository() + const [resultSurcharges, franchisesNames] = await Promise.all( + [GetSurchargesRepository(resultPlaceIds), GetFranchiseRepository()] + ) const placesWithSurcharges = resultPlaces.places.map((place) => { diff --git a/functions/src/interface/place/get/places/getPlacesInterface.ts b/functions/src/interface/place/get/places/getPlacesInterface.ts index b946055..d57182e 100644 --- a/functions/src/interface/place/get/places/getPlacesInterface.ts +++ b/functions/src/interface/place/get/places/getPlacesInterface.ts @@ -52,12 +52,15 @@ export const getPlacesInterface = async (request: express.Request, response: Res }) } catch (error: unknown) { + if (error instanceof Error) { if (error.message === "User location is out of New Zealand") { response.status(403).send({ message: error.message }) return } } - response.status(500).send({ message: error }) + + response.status(404).send() + } } \ No newline at end of file