Skip to content

Commit

Permalink
[#159] Property sectors APIs to post and patch & more refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
JamalG16 committed Nov 30, 2019
1 parent 87b6e92 commit e84d7be
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 62 deletions.
14 changes: 13 additions & 1 deletion backend/src/constants/FindOptionsFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FindOptions } from 'typeorm';
import { Property } from '../entities/Property';
import { User } from '../entities/User';
import { WorkOrder } from '../entities/WorkOrder';
import { PropertySector } from '../entities/PropertySector';

const PropertyFields : FindOptions<Property> = {
relations: ['activityStatus', 'propertyType', 'user'],
Expand Down Expand Up @@ -51,6 +52,7 @@ const UserFields : FindOptions<User> = {
id: true,
type: true,
},
phoneNumber: true,
},
};

Expand Down Expand Up @@ -130,5 +132,15 @@ const WorkOrderFieldsNoProperty : FindOptions<WorkOrder> = {
},
};

const PROPERTY_SECTOR_FIELDS : FindOptions<PropertySector> = {
relations: ['sector'],
select: {
id: true,
sector: {
id: true,
},
},
};

export { PropertyFields, UserFields, WorkOrderFields, PropertyFieldsNoUser,
WorkOrderFieldsNoProperty };
WorkOrderFieldsNoProperty, PROPERTY_SECTOR_FIELDS };
38 changes: 32 additions & 6 deletions backend/src/controllers/PropertyController.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import express, {Request, Response } from 'express';
import express, { Request, Response } from 'express';
import { PropertyService } from '../services/PropertyService';
import { PropertyMapper } from '../entity_mappers/PropertyMapper';
import auth from '../middleware/auth';
import handleError from '../utils/HttpUtils';
import { handleError } from '../utils/HttpUtils';
import { validateArrayBody } from '../middleware/requestValidation';
import { PROPERTY_SECTOR_FIELDS } from '../constants/BodyFields';
import { PropertySectorDTO } from '../dtos/PropertySectorDTO';
import { PropertySector } from '../entities/PropertySector';
import { PropertySectorService } from '../services/PropertySectorService';
import { PropertySectorMapper } from '../entity_mappers/PropertySectorMapper';

const propertyService = new PropertyService();
const propertyMapper = new PropertyMapper();
const propertySectorService = new PropertySectorService();
const propertySectorMapper = new PropertySectorMapper();

const propertyController = express.Router();

Expand All @@ -15,16 +23,34 @@ propertyController.get('/:id', auth, async(req: Request, res: Response) => {
return res.status(200).json(propertyMapper.toDTO(property));
} catch (err) {
return handleError(err, res);
}
})
}
});

propertyController.patch('/:id', auth, async(req: Request, res: Response) => {
try {
await propertyService.updatePropertyById(Number(req.params.id), req.body);
return res.status(204).end();
} catch (err) {
return handleError(err, res);
}
})
}
});

propertyController.post(
'/:propertyId/sectors', validateArrayBody(PROPERTY_SECTOR_FIELDS.createFields), auth,
async (req: Request, res: Response) => {
try {
const { propertyId } = req.params;
const propertySectorDTOs : PropertySectorDTO[] = req.body as PropertySectorDTO[];
const propertySectors : PropertySector[] = await propertySectorService
.createPropertySectors(
Number(propertyId),
propertySectorDTOs.map(propertySectorDTO =>
propertySectorMapper.fromDTO(propertySectorDTO)));
return res.status(200).json(propertySectors.map(propertySector =>
propertySectorMapper.toDTO(propertySector)));
} catch (err) {
return handleError(err, res);
}
});

export { propertyController };
32 changes: 13 additions & 19 deletions backend/src/controllers/PropertySectorsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,25 @@ import express, { Request, Response } from 'express';
import { PropertySectorService } from '../services/PropertySectorService';
import { PropertySectorMapper } from '../entity_mappers/PropertySectorMapper';
import auth from '../middleware/auth';
import handleError from '../utils/HttpUtils';
import validateBody from '../middleware/requestValidation';
import { handleError } from '../utils/HttpUtils';
import { PropertySectorDTO } from '../dtos/PropertySectorDTO';
import { PropertySector } from '../entities/PropertySector';
import { PROPERTY_SECTOR_FIELDS } from '../constants/BodyFields';

const propertySectorService = new PropertySectorService();
const propertySectorMapper = new PropertySectorMapper();

const propertySectorsController = express.Router({ mergeParams: true });

propertySectorsController.post('/', validateBody(PROPERTY_SECTOR_FIELDS.createFields), auth,
async (req: Request, res: Response) => {
try {
const propertySectorDTOs : PropertySectorDTO[] = req.body as PropertySectorDTO[];
const propertySectors : PropertySector[] = await propertySectorService
.createPropertySectors(
Number(req.params.propertyId),
propertySectorDTOs.map(propertySectorDTO =>
propertySectorMapper.fromDTO(propertySectorDTO)));
return res.status(200).json(propertySectors.map(propertySector =>
propertySectorMapper.toDTO(propertySector)));
} catch (err) {
return handleError(err, res);
}
});
propertySectorsController.patch('/:propertySectorId', auth, async (req: Request, res: Response) => {
try {
const { propertySectorId } = req.params;
const propertySectorDTO : PropertySectorDTO = req.body as PropertySectorDTO;
await propertySectorService.update(
Number(propertySectorId),
propertySectorMapper.fromDTO(propertySectorDTO));
return res.status(204).end();
} catch (err) {
return handleError(err, res);
}
})

export { propertySectorsController };
4 changes: 2 additions & 2 deletions backend/src/controllers/PropertyWorkOrdersController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { WorkOrderService } from '../services/WorkOrderService';
import { WorkOrderMapper } from '../entity_mappers/WorkOrderMapper';
import { WorkOrderDTO } from '../dtos/WorkOrderDTO';
import auth from '../middleware/auth';
import handleError from '../utils/HttpUtils';
import validateBody from '../middleware/requestValidation';
import { handleError } from '../utils/HttpUtils';
import { validateBody } from '../middleware/requestValidation';
import { WorkOrderFields } from '../constants/BodyFields';

const propertyWorkOrdersController = express.Router({mergeParams: true});
Expand Down
4 changes: 2 additions & 2 deletions backend/src/controllers/UserController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import express, {Request, Response} from 'express';
import { UserService } from '../services/UserService';
import { UserMapper } from '../entity_mappers/UserMapper';
import auth from '../middleware/auth';
import handleError from '../utils/HttpUtils';
import validateBody from '../middleware/requestValidation';
import { handleError } from '../utils/HttpUtils';
import { validateBody } from '../middleware/requestValidation';
import { UserFields } from '../constants/BodyFields';
import { UserDTO } from 'src/dtos/UserDTO';

Expand Down
4 changes: 2 additions & 2 deletions backend/src/controllers/UserPropertiesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { PropertyService } from '../services/PropertyService';
import { PropertyDTO } from '../dtos/PropertyDTO';
import { PropertyMapper } from '../entity_mappers/PropertyMapper';
import auth from '../middleware/auth';
import handleError from '../utils/HttpUtils';
import validateBody from '../middleware/requestValidation';
import { handleError } from '../utils/HttpUtils';
import { validateBody } from '../middleware/requestValidation';
import { PropertyFields } from '../constants/BodyFields';

const userPropertiesController = express.Router({mergeParams: true});
Expand Down
4 changes: 2 additions & 2 deletions backend/src/controllers/WorkOrderController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import express, {Request, Response} from 'express';
import { WorkOrderService } from '../services/WorkOrderService';
import { WorkOrderMapper } from '../entity_mappers/WorkOrderMapper';
import auth from '../middleware/auth';
import handleError from '../utils/HttpUtils';
import {WorkOrderDTO} from 'src/dtos/WorkOrderDTO';
import { handleError } from '../utils/HttpUtils';
import { WorkOrderDTO } from 'src/dtos/WorkOrderDTO';

const workOrderService = new WorkOrderService();
const workOrderMapper = new WorkOrderMapper();
Expand Down
2 changes: 1 addition & 1 deletion backend/src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Router {
this.router.use('/api/properties', propertyController);
this.router.use('/api/workOrders', workOrderController);
this.router.use('/api/properties/:propertyId/workOrders', propertyWorkOrdersController);
this.router.use('/api/properties/:propertyId/sectors', propertySectorsController);
this.router.use('/api/propertySectors', propertySectorsController);
}

getRouter() {
Expand Down
1 change: 1 addition & 0 deletions backend/src/dtos/PropertySectorDTO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export class PropertySectorDTO {
property: PropertyDTO;
sector: SectorDTO;
sectorKind: string;
status: string;
}
5 changes: 4 additions & 1 deletion backend/src/entities/PropertySector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Entity, PrimaryGeneratedColumn, ManyToOne, JoinColumn } from 'typeorm';
import { Entity, PrimaryGeneratedColumn, ManyToOne, JoinColumn, Column } from 'typeorm';
import { Property } from './Property';
import { Sector } from './Sector';

Expand All @@ -19,4 +19,7 @@ export class PropertySector {
name: 'sector_id',
})
sector: Sector;

@Column()
status: string;
}
20 changes: 12 additions & 8 deletions backend/src/entity_mappers/PropertySectorMapper.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { ObjectMapper } from './ObjectMapper';
import { Sector } from '../entities/Sector';
import { SectorDTO } from '../dtos/SectorDTO';
import { SectorType as SectorTypeEnum } from '../enums/SectorType';
import { SectorKind as SectorKindEnum } from '../enums/SectorKind';
import { BadRequestError } from '../errors/BadRequestError';
import {PropertySector} from "../entities/PropertySector";
import {PropertySectorDTO} from "../dtos/PropertySectorDTO";
import {PropertyMapper} from "./PropertyMapper";
import {SectorMapper} from "./SectorTypeMapper";
import { PropertySector } from '../entities/PropertySector';
import { PropertySectorDTO } from '../dtos/PropertySectorDTO';
import { PropertyMapper } from './PropertyMapper';
import { SectorMapper } from './SectorTypeMapper';
import { ActivityStatusMapper } from './ActivityStatusMapper';
import { ActivityStatusDTO } from '../dtos/ActivityStatusDTO';

class PropertySectorMapper implements ObjectMapper<PropertySector, PropertySectorDTO> {

private propertyMapper : PropertyMapper = new PropertyMapper();
private sectorMapper : SectorMapper = new SectorMapper();
private activityStatusMapper : ActivityStatusMapper = new ActivityStatusMapper();

toDTO(propertySector: PropertySector) : PropertySectorDTO {

Expand All @@ -24,6 +23,7 @@ class PropertySectorMapper implements ObjectMapper<PropertySector, PropertySecto
if (propertySector.sector) {
propertySectorDTO.sector = this.sectorMapper.toDTO(propertySector.sector);
}
propertySectorDTO.status = propertySector.status;
return propertySectorDTO;
}

Expand All @@ -33,6 +33,10 @@ class PropertySectorMapper implements ObjectMapper<PropertySector, PropertySecto
propertySector.sector = this.sectorMapper.fromDTO(
new SectorDTO(propertySectorDTO.sectorKind));
}
if (propertySectorDTO.status) {
propertySector.status = this.activityStatusMapper.fromDTO(
new ActivityStatusDTO(propertySectorDTO.status)).status;
}
return propertySector;
}
}
Expand Down
34 changes: 26 additions & 8 deletions backend/src/middleware/requestValidation.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
import { Request, Response, NextFunction } from 'express';
import { UnprocessableEntity } from '../errors/UnprocessableEntity';

const validateBody = (parameters: any) => (req: Request, res: Response, next: NextFunction) => {
var missingParameters = [];
for(const parameter of parameters) {
if(!req.body[parameter]) {
export const validateBody = (parameters: any) => (
req: Request, res: Response, next: NextFunction) => {
const missingParameters = [];
for (const parameter of parameters) {
if (!req.body[parameter]) {
missingParameters.push(parameter);
}
}
}
if (missingParameters.length > 0) {
res.status(422).json(new UnprocessableEntity(
`Request body missing [${missingParameters.toString()}].`))
`Request body missing [${missingParameters.toString()}].`));
} else {
next();
}
}
};

export default validateBody;
export const validateArrayBody = (parameters: any) => (
req: Request, res: Response, next: NextFunction) => {
const missingParameters = new Set();
for (const object of req.body) {
for (const parameter of parameters) {
if (!object[parameter]) {
missingParameters.add(parameter);
}
}
}
if (missingParameters.size > 0) {
res.status(422).json(new UnprocessableEntity(
'At least one request object is missing parameter ' +
`[${Array.from(missingParameters).toString()}].`));
} else {
next();
}
}
19 changes: 19 additions & 0 deletions backend/src/repositories/PropertySectorRepository.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import { PropertySector } from '../entities/PropertySector';
import { BaseRepository } from './BaseRepository';
import { Property } from '../entities/Property';
import { PROPERTY_SECTOR_FIELDS } from '../constants/FindOptionsFields';
import { FindOptions } from 'typeorm';
import { Sector } from '../entities/Sector';

class PropertySectorRepository extends BaseRepository<PropertySector> {

async save(propertySectors: PropertySector[]) {
return await this.getRepositoryConnection(PropertySector).save(propertySectors);
}

async update(id: number, propertySector: PropertySector) {
return await this.getRepositoryConnection(PropertySector).update(
{ id }, propertySector);
}

async getSectorsByProperty(property: Property) {
const findOptions : FindOptions<PropertySector> = PROPERTY_SECTOR_FIELDS;
findOptions.where = { property };
return await this.getRepositoryConnection(PropertySector).find(findOptions);
}

async getPropertySectorById(id: number) {
return await this.getRepositoryConnection(PropertySector).findOne({ id });
}
}

export { PropertySectorRepository };
Loading

0 comments on commit e84d7be

Please sign in to comment.