|
1 |
| -import { FilterQuery, UpdateQuery } from "mongoose"; |
| 1 | +import { ObjectId } from "mongodb"; |
| 2 | +import { Document, FilterQuery, UpdateQuery } from "mongoose"; |
| 3 | +import * as XLSX from "xlsx"; |
2 | 4 |
|
| 5 | +import { ReferralModel } from "@/models/referral"; |
| 6 | +import { RenterModel } from "@/models/renter"; |
3 | 7 | import { Unit, UnitModel } from "@/models/units";
|
| 8 | +import { UserModel } from "@/models/user"; |
4 | 9 |
|
5 | 10 | type UserReadOnlyFields = "approved" | "createdAt" | "updatedAt";
|
6 | 11 |
|
@@ -223,3 +228,62 @@ export const getUnits = async (filters: FilterParams) => {
|
223 | 228 |
|
224 | 229 | return filteredUnits;
|
225 | 230 | };
|
| 231 | + |
| 232 | +const sheetFromData = (data: Document[]) => { |
| 233 | + const sanitizedData = data.map((doc) => { |
| 234 | + // remove unneeded keys and convert all values to strings |
| 235 | + const { _id, __v, ...rest } = doc.toJSON() as Record<string, string>; |
| 236 | + const sanitizedRest = Object.keys(rest).reduce<Record<string, string>>((acc, key) => { |
| 237 | + const value = rest[key]; |
| 238 | + if ((value as unknown) instanceof ObjectId) { |
| 239 | + acc[key] = value.toString(); |
| 240 | + } else if (Array.isArray(value)) { |
| 241 | + acc[key] = JSON.stringify(value); |
| 242 | + } else { |
| 243 | + acc[key] = value; |
| 244 | + } |
| 245 | + return acc; |
| 246 | + }, {}); |
| 247 | + |
| 248 | + return { |
| 249 | + id: _id.toString(), |
| 250 | + ...sanitizedRest, |
| 251 | + }; |
| 252 | + }); |
| 253 | + return XLSX.utils.json_to_sheet(sanitizedData); |
| 254 | +}; |
| 255 | + |
| 256 | +export const exportUnits = async (filters: FilterParams) => { |
| 257 | + const unitsData = await getUnits(filters); |
| 258 | + |
| 259 | + const unitIds = unitsData.map((unit) => unit._id); |
| 260 | + const referralsData = await ReferralModel.find().where("unit").in(unitIds).exec(); |
| 261 | + |
| 262 | + const renterCandidateIds = [ |
| 263 | + ...new Set(referralsData.map((referral) => referral.renterCandidate)), |
| 264 | + ]; |
| 265 | + const renterCandidates = await RenterModel.find().where("_id").in(renterCandidateIds).exec(); |
| 266 | + |
| 267 | + const housingLocatorIds = [ |
| 268 | + ...new Set(referralsData.map((referral) => referral.assignedHousingLocator)), |
| 269 | + ]; |
| 270 | + const referringStaffIds = [ |
| 271 | + ...new Set(referralsData.map((referral) => referral.assignedReferringStaff)), |
| 272 | + ]; |
| 273 | + const staffIds = housingLocatorIds.concat(referringStaffIds); |
| 274 | + const staffData = await UserModel.find().where("_id").in(staffIds).exec(); |
| 275 | + |
| 276 | + // Generate Excel workbook |
| 277 | + const unitsSheet = sheetFromData(unitsData); |
| 278 | + const referralsSheet = sheetFromData(referralsData); |
| 279 | + const renterCandidatesSheet = sheetFromData(renterCandidates); |
| 280 | + const staffSheet = sheetFromData(staffData); |
| 281 | + |
| 282 | + const workbook = XLSX.utils.book_new(); |
| 283 | + XLSX.utils.book_append_sheet(workbook, unitsSheet, "Units"); |
| 284 | + XLSX.utils.book_append_sheet(workbook, referralsSheet, "Referrals"); |
| 285 | + XLSX.utils.book_append_sheet(workbook, renterCandidatesSheet, "Renter Candidates"); |
| 286 | + XLSX.utils.book_append_sheet(workbook, staffSheet, "Staff"); |
| 287 | + |
| 288 | + return XLSX.write(workbook, { type: "buffer", bookType: "xlsx" }) as Buffer; |
| 289 | +}; |
0 commit comments