done with timeSlots lookup
This commit is contained in:
parent
fee7f1a266
commit
53dd3ada4f
9 changed files with 193 additions and 56 deletions
24
README.md
24
README.md
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
}
|
70
src/index.ts
70
src/index.ts
|
@ -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));
|
||||
// }
|
||||
// }
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
|
@ -4,4 +4,10 @@ export interface Address {
|
|||
line2: string;
|
||||
country: string;
|
||||
postcode: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
export interface AvailableTimeslots {
|
||||
start_time: string;
|
||||
end_time: string;
|
||||
}
|
Loading…
Reference in a new issue