Skip to content

Commit 20b0231

Browse files
committed
Merge branch 'chauffeurs' of github.com:muneebhashone/city-link-api into notifications
2 parents b01b1ec + d6b8b3d commit 20b0231

16 files changed

+509
-12
lines changed

src/apartment/apartment-booking/apartment-booking.service.ts

-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ export const createApartmentBookingSummary = async (
169169
if (!discount)
170170
throw new Error('Discount selected for booking does not exist');
171171

172-
console.log({ apartment, discount });
173172

174173
const booking = await ApartmentBooking.create({
175174
...payload,

src/apartment/apartment.controller.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
deleteApartments,
77
getApartment,
88
getApartments,
9+
getMyApartments,
910
updateApartment,
1011
} from './apartment.service';
1112
import {
@@ -22,6 +23,15 @@ export const handleGetApartments = async (req: Request, res: Response) => {
2223
return errorResponse(res, (err as Error).message);
2324
}
2425
};
26+
export const handleGetMyApartments = async (req: Request, res: Response) => {
27+
try {
28+
const result = await getMyApartments({ id: req.user.sub });
29+
30+
return successResponse(res, undefined, result);
31+
} catch (err) {
32+
return errorResponse(res, (err as Error).message);
33+
}
34+
};
2535

2636
export const handleCreateApartment = async (
2737
req: Request<never, never, ApartmentCreateOrUpdateSchemaType>,
@@ -75,7 +85,8 @@ export const handleDeleteApartment = async (
7585
res: Response,
7686
) => {
7787
try {
78-
await deleteApartment({ id: req.params.id });
88+
const userId = req.user?.sub;
89+
await deleteApartment({ id: req.params.id }, { id: userId });
7990

8091
return successResponse(res, 'Apartment deleted successfully');
8192
} catch (err) {

src/apartment/apartment.router.ts

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
handleDeleteApartments,
88
handleGetApartment,
99
handleGetApartments,
10+
handleGetMyApartments,
1011
handleUpdateApartment,
1112
} from './apartment.controller';
1213
import {
@@ -24,6 +25,11 @@ apartmentRouter.get(
2425
validateZodSchema({ query: apartmentListQueryParamsSchema }),
2526
handleGetApartments,
2627
);
28+
apartmentRouter.get(
29+
'/my',
30+
canAccess('roles', ['SUPER_ADMIN', 'VENDOR']),
31+
handleGetMyApartments,
32+
);
2733

2834
apartmentRouter.post(
2935
'/',

src/apartment/apartment.service.ts

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { FilterQuery } from 'mongoose';
1+
import { FilterQuery, ObjectId } from 'mongoose';
22
import { ApartmentType } from '../types';
33
import { JwtPayload } from '../utils/auth.utils';
44
import { checkRecordForEmptyArrays } from '../utils/common.utils';
55
import { getPaginator, GetPaginatorReturnType } from '../utils/getPaginator';
6-
import { Apartment } from './apartment.model';
6+
import { Apartment, IApartment, IApartmentDocument } from './apartment.model';
77
import {
88
ApartmentCreateOrUpdateSchemaType,
99
ApartmentIdSchemaType,
1010
ApartmentListQueryParamsType,
1111
} from './apartment.schema';
12+
import { UserIdSchemaType } from '../user/user.schema';
1213

1314
export interface IGetApartment {
1415
results: ApartmentType[];
@@ -108,6 +109,27 @@ export const getApartment = async (
108109

109110
return result;
110111
};
112+
export const getMyApartments = async (
113+
userId: UserIdSchemaType,
114+
): Promise<IApartment[]> => {
115+
const result = await Apartment.find({
116+
owner: userId.id,
117+
}).populate([
118+
'propertyType',
119+
'typeOfPlace',
120+
'cancellationPolicies',
121+
'facilities',
122+
'houseRules',
123+
'discounts',
124+
'bookingType',
125+
]);
126+
127+
if (!result) {
128+
throw new Error('Apartment not found');
129+
}
130+
131+
return result;
132+
};
111133

112134
export const createApartment = async (
113135
body: ApartmentCreateOrUpdateSchemaType,
@@ -147,14 +169,18 @@ export const updateApartment = async (
147169

148170
export const deleteApartment = async (
149171
apartmentId: ApartmentIdSchemaType,
172+
userId: UserIdSchemaType,
150173
): Promise<void | Error> => {
151174
const { id } = apartmentId;
152-
const deleted = await Apartment.deleteOne({
153-
_id: id,
154-
});
155175

156-
if (deleted.deletedCount < 1) {
176+
const apartment = await Apartment.findById(id);
177+
178+
if (!apartment) {
157179
throw new Error('Apartment does not Exist');
180+
} else if (apartment?.owner?.toString() !== userId.id.toString()) {
181+
throw new Error('You do not have permission to delete this apartment.');
182+
} else {
183+
apartment.deleteOne();
158184
}
159185
};
160186

src/auth/auth.service.ts

-2
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,6 @@ export const googleLogin = async (
477477
payload: GoogleCallbackQuery,
478478
): Promise<UserType> => {
479479
const { code, error } = payload;
480-
console.log({ code, error });
481480
if (error) {
482481
throw new Error(error);
483482
}
@@ -490,7 +489,6 @@ export const googleLogin = async (
490489
const { access_token, refresh_token, expires_in } = tokenResponse;
491490

492491
const userInfoResponse = await getUserInfo(access_token);
493-
console.log({ userInfoResponse });
494492

495493
// const userInfo = (await userInfoResponse.) as GoogleUserInfo;
496494
const { id, email, name, picture } = userInfoResponse;

src/car/car-booking/car-booking.services.ts

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export const createCarBooking = async (
105105
bookingStatus: 'pending',
106106
owner: car.userId,
107107
});
108+
108109

109110
const booking = await carBooking.populate('carId');
110111

src/chauffeur/chauffeur-types.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const ChauffeurAvailability = {
2+
Available: 'available',
3+
InTransit: 'inTransit',
4+
};
5+
export interface IChauffeur {
6+
firstName: string;
7+
lastName: string;
8+
chauffeurName: string;
9+
phoneNo: string;
10+
photo: string;
11+
idFront: string;
12+
idBack: string;
13+
verificationPhoto: string;
14+
availabilityStatus: keyof typeof ChauffeurAvailability;
15+
isVerified: boolean;
16+
vendorId: string;
17+
}

src/chauffeur/chauffeur.controller.ts

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { Request, Response } from 'express';
2+
import { createCarBooking } from '../car/car-booking/car-booking.services';
3+
import { errorResponse, successResponse } from '../utils/api.utils';
4+
import {
5+
createChauffeur,
6+
deleteAllChauffeurs,
7+
deleteChauffeurById,
8+
getChauffeursByVendorID,
9+
getMyChauffeurs,
10+
updateChauffeurById,
11+
} from './chauffeur.services';
12+
import { ChauffeurBookingSchemaType } from './chauffeur.schema';
13+
import { JwtPayload } from '../utils/auth.utils';
14+
import { UserIdSchemaType } from '../user/user.schema';
15+
import seedChauffeurs from './chauffeur.seeder';
16+
export const handleCreateChauffeur = async (
17+
req: Request<never, never, ChauffeurBookingSchemaType>,
18+
res: Response,
19+
) => {
20+
try {
21+
if (!req.user || !req.user.sub) {
22+
return errorResponse(res, 'Unauthorized: User is not logged in');
23+
}
24+
25+
const newChauffeur = await createChauffeur(
26+
req.body,
27+
req.user as JwtPayload,
28+
);
29+
30+
return successResponse(res, 'Chauffeur created successfully', newChauffeur);
31+
} catch (err) {
32+
return errorResponse(
33+
res,
34+
(err as Error).message ||
35+
'An error occurred while creating the chauffeur',
36+
);
37+
}
38+
};
39+
export const handleGetMyChauffeurs = async (
40+
req: Request<never, never, ChauffeurBookingSchemaType>,
41+
res: Response,
42+
) => {
43+
try {
44+
if (!req.user || !req.user.sub) {
45+
return errorResponse(res, 'Unauthorized: User is not logged in');
46+
}
47+
48+
const newChauffeur = await getMyChauffeurs(req.user as JwtPayload);
49+
50+
return successResponse(res, undefined, newChauffeur);
51+
} catch (err) {
52+
return errorResponse(
53+
res,
54+
(err as Error).message ||
55+
'An error occurred while creating the chauffeur',
56+
);
57+
}
58+
};
59+
export const handleGetChauffeursByVendorID = async (
60+
req: Request<UserIdSchemaType, never, never>,
61+
res: Response,
62+
) => {
63+
try {
64+
const vendorId = req.params.id;
65+
66+
if (!req.user || !req.user.sub) {
67+
return errorResponse(res, 'Unauthorized: User is not logged in');
68+
}
69+
70+
const chauffeurs = await getChauffeursByVendorID({ id: vendorId });
71+
72+
return successResponse(
73+
res,
74+
'Chauffeurs retrieved successfully',
75+
chauffeurs,
76+
);
77+
} catch (err) {
78+
return errorResponse(
79+
res,
80+
(err as Error).message || 'An error occurred while retrieving chauffeurs',
81+
);
82+
}
83+
};
84+
export const handleUpdateChauffeurByID = async (
85+
req: Request<UserIdSchemaType, never, ChauffeurBookingSchemaType>,
86+
res: Response,
87+
) => {
88+
try {
89+
const chauffeurId = req.params.id;
90+
const updateData = req.body;
91+
92+
const updatedChauffeur = await updateChauffeurById(
93+
{ id: chauffeurId },
94+
updateData,
95+
);
96+
97+
if (!updatedChauffeur) {
98+
return errorResponse(res, 'Chauffeur not found');
99+
}
100+
101+
return successResponse(
102+
res,
103+
'Chauffeur updated successfully',
104+
updatedChauffeur,
105+
);
106+
} catch (err) {
107+
return errorResponse(
108+
res,
109+
(err as Error).message ||
110+
'An error occurred while updating the chauffeur',
111+
);
112+
}
113+
};
114+
115+
export const handleDeleteChauffeurByID = async (
116+
req: Request<UserIdSchemaType, never, never>,
117+
res: Response,
118+
) => {
119+
try {
120+
const chauffeurId = req.params.id;
121+
122+
await deleteChauffeurById({ id: chauffeurId });
123+
124+
return successResponse(res, 'Chauffeur deleted successfully');
125+
} catch (err) {
126+
return errorResponse(
127+
res,
128+
(err as Error).message ||
129+
'An error occurred while deleting the chauffeur',
130+
);
131+
}
132+
};
133+
134+
export const handleDeleteAllChauffeurs = async (
135+
req: Request<never, never, never>,
136+
res: Response,
137+
) => {
138+
try {
139+
await deleteAllChauffeurs();
140+
141+
return successResponse(res, 'All chauffeurs deleted successfully');
142+
} catch (err) {
143+
return errorResponse(
144+
res,
145+
(err as Error).message ||
146+
'An error occurred while deleting all chauffeurs',
147+
);
148+
}
149+
};
150+
export const handleSeedChauffeurs = async (req: Request, res: Response) => {
151+
try {
152+
await seedChauffeurs();
153+
return successResponse(res, 'Chauffeurs seeded successfully');
154+
} catch (err) {
155+
return errorResponse(
156+
res,
157+
(err as Error).message || 'An error occurred while seeding chauffeurs',
158+
);
159+
}
160+
};

src/chauffeur/chauffeur.model.ts

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import mongoose, { Schema } from 'mongoose';
2+
import { ChauffeurAvailability, IChauffeur } from './chauffeur-types';
3+
import { ChauffeurBookingSchemaType } from './chauffeur.schema';
4+
5+
const ChauffeurSchema = new Schema<IChauffeur>(
6+
{
7+
firstName: {
8+
type: String,
9+
required: true,
10+
maxlength: 255,
11+
},
12+
lastName: {
13+
type: String,
14+
required: true,
15+
maxlength: 255,
16+
},
17+
chauffeurName: {
18+
type: String,
19+
required: true,
20+
},
21+
phoneNo: {
22+
type: String,
23+
required: true,
24+
minlength: 10,
25+
maxlength: 15,
26+
},
27+
photo: {
28+
type: String,
29+
required: true,
30+
},
31+
idFront: {
32+
type: String,
33+
required: true,
34+
},
35+
idBack: {
36+
type: String,
37+
required: true,
38+
},
39+
verificationPhoto: {
40+
type: String,
41+
required: true,
42+
},
43+
availabilityStatus: {
44+
type: String,
45+
enum: Object.values(ChauffeurAvailability),
46+
required: true,
47+
},
48+
isVerified: {
49+
type: Boolean,
50+
required: true,
51+
},
52+
vendorId: {
53+
type: String,
54+
required: true,
55+
},
56+
},
57+
{ timestamps: true },
58+
);
59+
const Chauffeur = mongoose.model<IChauffeur>('Chauffer', ChauffeurSchema);
60+
export default Chauffeur;

0 commit comments

Comments
 (0)