fix signin signout and apply the new style
This commit is contained in:
@@ -4,6 +4,46 @@ import { sendNotification, sendTransactionalEmail } from '../../services/notific
|
||||
import { marketplaceReservationEmail, type Lang } from '../../lib/emailTranslations'
|
||||
import * as repo from './marketplace.repo'
|
||||
|
||||
function normalizeLocation(value?: string | null) {
|
||||
const normalized = value?.trim()
|
||||
return normalized ? normalized : null
|
||||
}
|
||||
|
||||
function normalizeLocationList(values?: string[] | null) {
|
||||
if (!Array.isArray(values)) return []
|
||||
return values
|
||||
.map((value) => normalizeLocation(value))
|
||||
.filter((value): value is string => Boolean(value))
|
||||
}
|
||||
|
||||
function includesLocation(values: string[], target: string) {
|
||||
const key = target.toLocaleLowerCase()
|
||||
return values.some((value) => value.toLocaleLowerCase() === key)
|
||||
}
|
||||
|
||||
function matchesVehicleLocationRules(
|
||||
vehicle: { pickupLocations?: string[]; dropoffLocations?: string[]; allowDifferentDropoff?: boolean },
|
||||
params: { pickupLocation?: string; dropoffLocation?: string; dropoffMode?: 'same' | 'different' },
|
||||
) {
|
||||
const pickupLocation = normalizeLocation(params.pickupLocation)
|
||||
const dropoffLocation = normalizeLocation(params.dropoffLocation)
|
||||
const pickupLocations = normalizeLocationList(vehicle.pickupLocations)
|
||||
const dropoffLocations = normalizeLocationList(vehicle.dropoffLocations)
|
||||
|
||||
if (pickupLocation && pickupLocations.length > 0 && !includesLocation(pickupLocations, pickupLocation)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (params.dropoffMode === 'different') {
|
||||
if (!vehicle.allowDifferentDropoff) return false
|
||||
if (dropoffLocation && dropoffLocations.length > 0 && !includesLocation(dropoffLocations, dropoffLocation)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export async function getPublicOffers() {
|
||||
return repo.findPublicOffers()
|
||||
}
|
||||
@@ -34,7 +74,8 @@ export async function getListedCompanies(params: {
|
||||
}
|
||||
|
||||
export async function searchVehicles(params: {
|
||||
city?: string; startDate?: string; endDate?: string; category?: string
|
||||
city?: string; pickupLocation?: string; dropoffLocation?: string; dropoffMode?: 'same' | 'different'
|
||||
startDate?: string; endDate?: string; category?: string
|
||||
maxPrice?: number; transmission?: string; make?: string; model?: string
|
||||
page?: number; pageSize?: number
|
||||
}) {
|
||||
@@ -54,10 +95,12 @@ export async function searchVehicles(params: {
|
||||
where.company = { ...where.company, brand: { isListedOnMarketplace: true, publicCity: { contains: params.city, mode: 'insensitive' } } }
|
||||
}
|
||||
|
||||
const vehicles = await repo.findPublishedVehicles(where, (page - 1) * pageSize, pageSize)
|
||||
const vehicles = await repo.findPublishedVehicles(where)
|
||||
const locationFiltered = vehicles.filter((vehicle) => matchesVehicleLocationRules(vehicle, params))
|
||||
const pagedVehicles = locationFiltered.slice((page - 1) * pageSize, page * pageSize)
|
||||
|
||||
const availability = await Promise.all(
|
||||
vehicles.map(async (v) => {
|
||||
pagedVehicles.map(async (v) => {
|
||||
const a = await getVehicleAvailabilitySummary(v.id, {
|
||||
range: params.startDate && params.endDate
|
||||
? { startDate: new Date(params.startDate), endDate: new Date(params.endDate) }
|
||||
@@ -68,7 +111,7 @@ export async function searchVehicles(params: {
|
||||
)
|
||||
const availMap = new Map(availability)
|
||||
|
||||
return vehicles.map((v) => ({
|
||||
return pagedVehicles.map((v) => ({
|
||||
...v,
|
||||
availability: availMap.get(v.id)?.available ?? null,
|
||||
availabilityStatus: availMap.get(v.id)?.status ?? 'AVAILABLE',
|
||||
@@ -79,7 +122,7 @@ export async function searchVehicles(params: {
|
||||
export async function createMarketplaceReservation(body: {
|
||||
vehicleId: string; companySlug: string; firstName: string; lastName: string
|
||||
email: string; phone?: string; startDate: string; endDate: string
|
||||
notes?: string; language?: string
|
||||
pickupLocation?: string; returnLocation?: string; notes?: string; language?: string
|
||||
}) {
|
||||
const startDate = new Date(body.startDate)
|
||||
const endDate = new Date(body.endDate)
|
||||
@@ -91,6 +134,24 @@ export async function createMarketplaceReservation(body: {
|
||||
const vehicle = await repo.findVehicleForMarketplace(body.vehicleId, body.companySlug)
|
||||
if (!vehicle) throw new NotFoundError('Vehicle not found')
|
||||
|
||||
const pickupLocation = normalizeLocation(body.pickupLocation)
|
||||
const returnLocation = normalizeLocation(body.returnLocation) ?? pickupLocation
|
||||
const pickupLocations = normalizeLocationList(vehicle.pickupLocations)
|
||||
const dropoffLocations = normalizeLocationList(vehicle.dropoffLocations)
|
||||
|
||||
if (pickupLocation && pickupLocations.length > 0 && !includesLocation(pickupLocations, pickupLocation)) {
|
||||
throw new AppError('Selected pickup location is not available for this vehicle', 400, 'invalid_pickup_location')
|
||||
}
|
||||
|
||||
if (pickupLocation && returnLocation && pickupLocation.toLocaleLowerCase() !== returnLocation.toLocaleLowerCase()) {
|
||||
if (!vehicle.allowDifferentDropoff) {
|
||||
throw new AppError('This vehicle must be returned to the same pickup location', 400, 'same_dropoff_required')
|
||||
}
|
||||
if (dropoffLocations.length > 0 && !includesLocation(dropoffLocations, returnLocation)) {
|
||||
throw new AppError('Selected return location is not available for this vehicle', 400, 'invalid_return_location')
|
||||
}
|
||||
}
|
||||
|
||||
const availability = await getVehicleAvailabilitySummary(body.vehicleId, { range: { startDate, endDate } })
|
||||
if (!availability.available) {
|
||||
throw new AppError('Vehicle is not available for the selected dates', 409, 'unavailable', {
|
||||
@@ -107,7 +168,7 @@ export async function createMarketplaceReservation(body: {
|
||||
|
||||
const reservation = await repo.createMarketplaceReservation({
|
||||
companyId: vehicle.companyId, vehicleId: body.vehicleId, customerId: customer.id,
|
||||
startDate, endDate, dailyRate: vehicle.dailyRate, totalDays, totalAmount, notes: body.notes,
|
||||
startDate, endDate, pickupLocation, returnLocation, dailyRate: vehicle.dailyRate, totalDays, totalAmount, notes: body.notes,
|
||||
})
|
||||
|
||||
const lang = (body.language ?? 'fr') as Lang
|
||||
|
||||
Reference in New Issue
Block a user