done with timeSlots lookup

This commit is contained in:
Kfir Dayan 2023-04-26 13:35:39 +03:00
parent fee7f1a266
commit 53dd3ada4f
9 changed files with 193 additions and 56 deletions

View file

@ -18,6 +18,30 @@ install pg MacOS -
Start Postgres -
brew services start postgresql
Postgres CLI -
psql postgres
init POSTGRES Database -
CREATE DATABASE drop_shopping;
create tables -
timeSlots -
CREATE TABLE time_slots (
id SERIAL PRIMARY KEY,
start_time TIME NOT NULL,
end_time TIME NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
holidays -
CREATE TABLE holidays (
id SERIAL PRIMARY KEY,
holiday_date DATE NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
knex for migration files
npx knex migrate:make create_addresses_table

View file

@ -1,7 +1,17 @@
[
{
"holidays": [
"2023-05-01",
"2023-06-12",
"2023-09-25"
]
"name": "New Year's Day",
"date": "2023-01-17",
"country": "US"
},
{
"name": "Mother's Day",
"date": "2023-09-18",
"country": "US"
},
{
"name": "Independence Day",
"date": "2023-09-17",
"country": "GB"
}
]

View file

@ -1,10 +1,39 @@
{
"timeSlots": [
"08:00 - 10:00",
"10:00 - 12:00",
"12:00 - 14:00",
"14:00 - 16:00",
"16:00 - 18:00",
"18:00 - 20:00"
"courier_available_timeslots": [
{
"start_time": "2023-09-17 08:00:00",
"end_time": "2023-09-17 09:00:00",
"supported_postcodes": [
"W1H 1LJ",
"2222222"
]
},
{
"start_time": "2023-09-17 09:00:00",
"end_time": "2023-09-17 10:00:00",
"supported_postcodes": [
"1111111",
"2222222",
"3333333"
]
},
{
"start_time": "2023-09-17 09:00:00",
"end_time": "2023-09-17 10:00:00",
"supported_postcodes": [
"4444444",
"5555555",
"6666666"
]
},
{
"start_time": "2023-09-18 14:00:00",
"end_time": "2023-09-18 15:00:00",
"supported_postcodes": [
"W1H 1LJ",
"5555555",
"6666666"
]
}
]
}

View file

@ -13,12 +13,14 @@ export const resolveAddress = async (searchTerm: string): Promise<Address> => {
const response = await axios.get(`https://api.geoapify.com/v1/geocode/search?text=${searchTerm}&format=json&apiKey=${GEOCODING_API_KEY}`);
if (response.data.results.length > 0) {
const result = response.data.results[0];
console.log(result)
return {
country: result.country,
street: result.street,
line1: result.address_line1,
line2: result.address_line2,
postcode: result.postcode
postcode: result.postcode,
code: result.country_code.toUpperCase()
}
} else {
throw new Error('No results found');

View file

@ -1,12 +1,16 @@
import { Request, Response } from 'express';
import { resolveAddress } from './geocoding';
import { Address } from './types';
import { Address, AvailableTimeslots } from './types';
// DOME
import { getAvailableTimeSlots } from './services/timeslotsService';
import { getHolidays } from './services/holidaysService';
export const resolveAddressHandler = (req: Request, res: Response) => {
console.info("resolveAddressHandler called");
if (!req.body.searchTerm) {
res.status(400).json({ error: 'Missing searchTerm' });
return;
}
const address: Promise<Address> = resolveAddress(req.body.searchTerm);
address.then((result) => {
console.info("resolveAddressHandler result: ", result);
@ -14,10 +18,16 @@ export const resolveAddressHandler = (req: Request, res: Response) => {
})
};
export const timeslotsHandler = (req: Request, res: Response) => {
export const timeslotsHandler = async (req: Request, res: Response) => {
// TODO: Implement timeslots functionality
if (!req.body.address) {
res.status(400).json({ error: 'Missing address' });
return;
}
const address: Address = req.body.address;
const timeSlots: AvailableTimeslots[] = await availableTimeSlots(address);
const availableTimeSlotsResult = await filterOutHolidaysByCountryCode(address, timeSlots);
res.status(200).json(availableTimeSlotsResult);
};
export const deliveriesHandler = (req: Request, res: Response) => {
@ -35,3 +45,41 @@ export const dailyDeliveriesHandler = (req: Request, res: Response) => {
export const weeklyDeliveriesHandler = (req: Request, res: Response) => {
// TODO: Implement weekly deliveries functionality
};
async function filterOutHolidaysByCountryCode(address: Address, availableTimeSlot: AvailableTimeslots[]) {
const countryCode = address.code;
const holidays = await getHolidays();
const filteredAvailableTimeSlot = [];
console.log(availableTimeSlot)
holidays.forEach((holiday) => {
if(holiday.country === countryCode) {
availableTimeSlot.forEach((timeSlot) => {
if(timeSlot.start_time.split(' ')[0] !== holiday.date) {
filteredAvailableTimeSlot.push(timeSlot)
}
})
}
});
return filteredAvailableTimeSlot;
}
async function availableTimeSlots(address: Address) {
const availableTimeSlot = [];
const timeslots = await getAvailableTimeSlots();
// check by postcode if any available timeslots
for (const timeslot of timeslots.courier_available_timeslots) {
if (timeslot.supported_postcodes.includes(address.postcode)) {
availableTimeSlot.push({
start_time: timeslot.start_time,
end_time: timeslot.end_time
});
}
}
return availableTimeSlot;
}

View file

@ -8,40 +8,52 @@ app.listen(PORT, () => {
console.log("STARTING ... ")
if (env === 'development') {
console.log("Generating mock data files")
generateMockDataFiles();
// generateMockDataFiles();
}
console.log(`Server is running on port ${PORT}`);
});
const generateMockDataFiles = () => {
// const generateMockDataFiles = () => {
if (!fs.existsSync('./data')) {
fs.mkdirSync('./data');
}
// if (!fs.existsSync('./data')) {
// fs.mkdirSync('./data');
// }
if (!fs.existsSync('./data/timeSlots.json')) {
const timeSlots = {
timeSlots: [
"08:00 - 10:00",
"10:00 - 12:00",
"12:00 - 14:00",
"14:00 - 16:00",
"16:00 - 18:00",
"18:00 - 20:00"
]
}
fs.writeFileSync('./data/timeSlots.json', JSON.stringify(timeSlots));
}
// if (!fs.existsSync('./data/timeSlots.json')) {
// const timeSlots = {
// timeSlots: [
// "08:00 - 10:00",
// "10:00 - 12:00",
// "12:00 - 14:00",
// "14:00 - 16:00",
// "16:00 - 18:00",
// "18:00 - 20:00"
// ]
// }
// fs.writeFileSync('./data/timeSlots.json', JSON.stringify(timeSlots));
// }
if (!fs.existsSync('./data/holidays.json')) {
const holidays = {
holidays: [
"2023-05-01",
"2023-06-12",
"2023-09-25"
]
}
fs.writeFileSync('./data/holidays.json', JSON.stringify(holidays));
}
}
// if (!fs.existsSync('./data/holidays.json')) {
// const holidays = {
// "holidays": [
// {
// "name": "New Year's Day",
// "date": "2023-01-17",
// "country": "US"
// },
// {
// "name": "Mother's Day",
// "date": "2023-09-18",
// "country": "US"
// },
// {
// "name": "Independence Day",
// "date": "2023-10-17",
// "country": "US"
// }
// ]
// }
// fs.writeFileSync('./data/holidays.json', JSON.stringify(holidays));
// }
// }

View file

@ -4,9 +4,9 @@ import { resolveAddressHandler, timeslotsHandler, deliveriesHandler, cancelDeliv
const router = express.Router();
router.post('/resolve-address', resolveAddressHandler);
router.post('/timeslots', timeslotsHandler);
router.get('/deliveries/daily', dailyDeliveriesHandler);
router.get('/deliveries/weekly', weeklyDeliveriesHandler);
router.post('/timeslots', timeslotsHandler);
router.post('/deliveries', deliveriesHandler);
router.delete('/deliveries/:id', cancelDeliveryHandler);

View file

@ -12,9 +12,15 @@ exports.seed = async function(knex) {
const holidays = require('../data/holidays.json');
const timeslots = require('../data/timeslots.json');
console.log(holidays)
// Insert the holiday dates into the holidays table
for (const date of holidays) {
await knex('holidays').insert({ date });
console.log(date)
await knex('holidays').insert( {
name: "test",
date: "2020-12-25",
country: "US"
} );
}
// Insert the time slots into the timeslots table

View file

@ -4,4 +4,10 @@ export interface Address {
line2: string;
country: string;
postcode: string;
code: string;
}
export interface AvailableTimeslots {
start_time: string;
end_time: string;
}