Skip to content

Commit 456faba

Browse files
committed
Add /leases/export route to core to fix missing filter passthrough
1 parent 39a95fc commit 456faba

File tree

2 files changed

+168
-0
lines changed
  • apps/property-tree/src/services/api/core/generated
  • core/src/services/lease-service

2 files changed

+168
-0
lines changed

apps/property-tree/src/services/api/core/generated/api-types.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,52 @@ export interface paths {
285285
};
286286
};
287287
};
288+
"/leases/export": {
289+
/**
290+
* Export leases to Excel
291+
* @description Export lease search results to Excel file. Uses same filters as /leases/search but without pagination.
292+
*/
293+
get: {
294+
parameters: {
295+
query?: {
296+
/** @description Free-text search (contract ID, tenant name, PNR, contact code, address) */
297+
q?: string;
298+
/** @description Object types (e.g., residence, parking) */
299+
objectType?: string[];
300+
/** @description Contract status filter (0=Current, 1=Upcoming, 2=AboutToEnd, 3=Ended) */
301+
status?: ("0" | "1" | "2" | "3")[];
302+
/** @description Minimum start date (YYYY-MM-DD) */
303+
startDateFrom?: string;
304+
/** @description Maximum start date (YYYY-MM-DD) */
305+
startDateTo?: string;
306+
/** @description Minimum end date (YYYY-MM-DD) */
307+
endDateFrom?: string;
308+
/** @description Maximum end date (YYYY-MM-DD) */
309+
endDateTo?: string;
310+
/** @description Property/estate names */
311+
property?: string[];
312+
/** @description Building codes */
313+
buildingCodes?: string[];
314+
/** @description Area codes (Område) */
315+
areaCodes?: string[];
316+
/** @description District names */
317+
districtNames?: string[];
318+
/** @description Building manager names (Kvartersvärd) */
319+
buildingManager?: string[];
320+
};
321+
};
322+
responses: {
323+
/** @description Excel file download */
324+
200: {
325+
content: never;
326+
};
327+
/** @description Internal server error */
328+
500: {
329+
content: never;
330+
};
331+
};
332+
};
333+
};
288334
"/leases/by-rental-property-id/{rentalPropertyId}": {
289335
/**
290336
* Get leases with related entities for a specific rental property id

core/src/services/lease-service/index.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,128 @@ export const routes = (router: KoaRouter) => {
320320
}
321321
})
322322

323+
/**
324+
* @swagger
325+
* /leases/export:
326+
* get:
327+
* summary: Export leases to Excel
328+
* tags:
329+
* - Lease service
330+
* description: Export lease search results to Excel file. Uses same filters as /leases/search but without pagination.
331+
* parameters:
332+
* - in: query
333+
* name: q
334+
* schema:
335+
* type: string
336+
* description: Free-text search (contract ID, tenant name, PNR, contact code, address)
337+
* - in: query
338+
* name: objectType
339+
* schema:
340+
* type: array
341+
* items:
342+
* type: string
343+
* description: Object types (e.g., residence, parking)
344+
* - in: query
345+
* name: status
346+
* schema:
347+
* type: array
348+
* items:
349+
* type: string
350+
* enum: ['0', '1', '2', '3']
351+
* description: Contract status filter (0=Current, 1=Upcoming, 2=AboutToEnd, 3=Ended)
352+
* - in: query
353+
* name: startDateFrom
354+
* schema:
355+
* type: string
356+
* format: date
357+
* description: Minimum start date (YYYY-MM-DD)
358+
* - in: query
359+
* name: startDateTo
360+
* schema:
361+
* type: string
362+
* format: date
363+
* description: Maximum start date (YYYY-MM-DD)
364+
* - in: query
365+
* name: endDateFrom
366+
* schema:
367+
* type: string
368+
* format: date
369+
* description: Minimum end date (YYYY-MM-DD)
370+
* - in: query
371+
* name: endDateTo
372+
* schema:
373+
* type: string
374+
* format: date
375+
* description: Maximum end date (YYYY-MM-DD)
376+
* - in: query
377+
* name: property
378+
* schema:
379+
* type: array
380+
* items:
381+
* type: string
382+
* description: Property/estate names
383+
* - in: query
384+
* name: buildingCodes
385+
* schema:
386+
* type: array
387+
* items:
388+
* type: string
389+
* description: Building codes
390+
* - in: query
391+
* name: areaCodes
392+
* schema:
393+
* type: array
394+
* items:
395+
* type: string
396+
* description: Area codes (Område)
397+
* - in: query
398+
* name: districtNames
399+
* schema:
400+
* type: array
401+
* items:
402+
* type: string
403+
* description: District names
404+
* - in: query
405+
* name: buildingManager
406+
* schema:
407+
* type: array
408+
* items:
409+
* type: string
410+
* description: Building manager names (Kvartersvärd)
411+
* produces:
412+
* - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
413+
* responses:
414+
* 200:
415+
* description: Excel file download
416+
* 500:
417+
* description: Internal server error
418+
* security:
419+
* - bearerAuth: []
420+
*/
421+
router.get('/leases/export', async (ctx) => {
422+
const metadata = generateRouteMetadata(ctx)
423+
424+
try {
425+
const result = await leasingAdapter.exportLeasesToExcel(ctx.query)
426+
427+
if (!result.ok) {
428+
logger.error({ err: result.err, metadata }, 'Lease export failed')
429+
ctx.status = 500
430+
ctx.body = { error: 'Internal server error', ...metadata }
431+
return
432+
}
433+
434+
ctx.set('Content-Type', result.data.contentType)
435+
ctx.set('Content-Disposition', result.data.contentDisposition)
436+
ctx.status = 200
437+
ctx.body = result.data.data
438+
} catch (error) {
439+
logger.error({ error, metadata }, 'Error exporting leases to Excel')
440+
ctx.status = 500
441+
ctx.body = { error: 'Internal server error', ...metadata }
442+
}
443+
})
444+
323445
/**
324446
* @swagger
325447
* /leases/by-rental-property-id/{rentalPropertyId}:

0 commit comments

Comments
 (0)