@@ -4,7 +4,7 @@ import { Joi, validate } from 'express-validation';
44import { container } from '..' ;
55import type { ProducerProductOptions } from '../interfaces/ProducerProductOptions' ;
66import { Controller , Delete , Get , Params , Post , Put , Request , Response } from '@decorators/express' ;
7- import { Producer , ProducerProduct , ProductionUnit , ShipmentEvent , ShipmentStatus , User } from '../entities' ;
7+ import { Carrier , Image , Producer , ProducerProduct , ProductionUnit , ShipmentEvent , ShipmentStatus , User } from '../entities' ;
88import { authenticationMiddleware , authorizationMiddleware } from '../middlewares' ;
99import { UniqueConstraintViolationException } from '@mikro-orm/core' ;
1010import { ConflictError } from '../errors/ConflictError' ;
@@ -984,4 +984,224 @@ export class ProducersController {
984984
985985 return res . status ( 201 ) . json ( shipment ) ;
986986 }
987+
988+ @Get ( '/:producerId/carriers' , [
989+ validate ( {
990+ params : Joi . object ( {
991+ producerId : Joi . number ( ) . min ( 1 ) . required ( )
992+ } ) ,
993+ query : Joi . object ( {
994+ page : Joi . number ( ) . min ( 1 ) . optional ( ) ,
995+ pageSize : Joi . number ( ) . min ( 1 ) . optional ( )
996+ } )
997+ } ) ,
998+ authenticationMiddleware ,
999+ authorizationMiddleware ( {
1000+ permissions : Permission . READ_OTHER_PRODUCER ,
1001+ otherValidations : [
1002+ ( user , req ) =>
1003+ user . id === Number ( req . params . producerId ) ||
1004+ throwError (
1005+ new ForbiddenError ( "User may not interact with others' production units" , {
1006+ user : user . id ,
1007+ producer : Number ( req . params . producerId )
1008+ } )
1009+ )
1010+ ]
1011+ } )
1012+ ] )
1013+ public async getCarriersOfProducer ( @Request ( ) req : Express . Request , @Response ( ) res : Express . Response , @Params ( 'producerId' ) producerId : number ) {
1014+ const producer = await container . producerGateway . findById ( producerId ) ;
1015+ if ( ! producer ) throw new NotFoundError ( 'Producer not found' ) ;
1016+
1017+ const options : PaginatedOptions = {
1018+ page : Number ( req . query . page ) || - 1 ,
1019+ size : Number ( req . query . pageSize ) || - 1
1020+ } ;
1021+
1022+ const carriers = await container . carrierGateway . findAllByProducerId ( producer . user . id , options ) ;
1023+
1024+ return res . status ( 200 ) . json ( carriers ) ;
1025+ }
1026+
1027+ @Post ( '/:producerId/carriers' , [
1028+ validate ( {
1029+ params : Joi . object ( {
1030+ producerId : Joi . number ( ) . min ( 1 ) . required ( )
1031+ } ) ,
1032+ body : Joi . object ( {
1033+ licensePlate : Joi . string ( ) . required ( ) ,
1034+ image : Joi . object ( {
1035+ name : Joi . string ( ) . required ( ) ,
1036+ url : Joi . string ( ) . required ( ) ,
1037+ alt : Joi . string ( ) . required ( )
1038+ } ) . required ( ) ,
1039+ productionUnitId : Joi . number ( ) . min ( 1 ) . required ( )
1040+ } )
1041+ } ) ,
1042+ authenticationMiddleware ,
1043+ authorizationMiddleware ( {
1044+ permissions : Permission . WRITE_OTHER_PRODUCER ,
1045+ otherValidations : [
1046+ ( user , req ) =>
1047+ user . id === Number ( req . params . producerId ) ||
1048+ throwError (
1049+ new ForbiddenError ( "User may not interact with others' production units" , {
1050+ user : user . id ,
1051+ producer : Number ( req . params . producerId )
1052+ } )
1053+ )
1054+ ]
1055+ } )
1056+ ] )
1057+ public async createCarrier ( @Request ( ) req : Express . Request , @Response ( ) res : Express . Response , @Params ( 'producerId' ) producerId : number ) {
1058+ const producer = await container . producerGateway . findById ( producerId ) ;
1059+ if ( ! producer ) throw new NotFoundError ( 'Producer not found' ) ;
1060+
1061+ const productionUnit = await container . productionUnitGateway . findOneFromProducer ( producer . user . id , req . body . productionUnitId ) ;
1062+ if ( ! productionUnit ) throw new NotFoundError ( 'Production unit not found' ) ;
1063+
1064+ const carrier = new Carrier ( req . body . licensePlate , productionUnit , new Image ( req . body . image . name , req . body . image . url , req . body . image . alt ) ) ;
1065+ await container . carrierGateway . createOrUpdate ( carrier ) ;
1066+
1067+ return res . status ( 201 ) . json ( carrier ) ;
1068+ }
1069+
1070+ @Get ( '/:producerId/carriers/:carrierId' , [
1071+ validate ( {
1072+ params : Joi . object ( {
1073+ producerId : Joi . number ( ) . min ( 1 ) . required ( ) ,
1074+ carrierId : Joi . number ( ) . min ( 1 ) . required ( )
1075+ } )
1076+ } ) ,
1077+ authenticationMiddleware ,
1078+ authorizationMiddleware ( {
1079+ permissions : Permission . READ_OTHER_PRODUCER ,
1080+ otherValidations : [
1081+ ( user , req ) =>
1082+ user . id === Number ( req . params . producerId ) ||
1083+ throwError (
1084+ new ForbiddenError ( "User may not interact with others' production units" , {
1085+ user : user . id ,
1086+ producer : Number ( req . params . producerId )
1087+ } )
1088+ )
1089+ ]
1090+ } )
1091+ ] )
1092+ public async getCarrierOfProducer (
1093+ @Response ( ) res : Express . Response ,
1094+ @Params ( 'producerId' ) producerId : number ,
1095+ @Params ( 'carrierId' ) carrierId : number
1096+ ) {
1097+ const producer = await container . producerGateway . findById ( producerId ) ;
1098+ if ( ! producer ) throw new NotFoundError ( 'Producer not found' ) ;
1099+
1100+ const carrier = await container . carrierGateway . findOneOfProducer ( producer . user . id , carrierId ) ;
1101+ if ( ! carrier ) throw new NotFoundError ( 'Carrier not found' ) ;
1102+
1103+ return res . status ( 200 ) . json ( {
1104+ id : carrier . id ,
1105+ licensePlate : carrier . licensePlate ,
1106+ status : carrier . status ,
1107+ image : carrier . image ,
1108+ productionUnit : carrier . productionUnit ,
1109+ lastShipmentEvent : carrier . getLastShipmentEvent ( )
1110+ } ) ;
1111+ }
1112+
1113+ @Put ( '/:producerId/carriers/:carrierId' , [
1114+ validate ( {
1115+ params : Joi . object ( {
1116+ producerId : Joi . number ( ) . min ( 1 ) . required ( ) ,
1117+ carrierId : Joi . number ( ) . min ( 1 ) . required ( )
1118+ } ) ,
1119+ body : Joi . object ( {
1120+ image : Joi . object ( {
1121+ name : Joi . string ( ) . required ( ) ,
1122+ url : Joi . string ( ) . required ( ) ,
1123+ alt : Joi . string ( ) . required ( )
1124+ } ) . required ( ) ,
1125+ productionUnitId : Joi . number ( ) . min ( 1 ) . required ( ) ,
1126+ status : Joi . string ( ) . valid ( CarrierStatus . Available , CarrierStatus . Unavailable ) . required ( )
1127+ } )
1128+ } ) ,
1129+ authenticationMiddleware ,
1130+ authorizationMiddleware ( {
1131+ permissions : Permission . WRITE_OTHER_PRODUCER ,
1132+ otherValidations : [
1133+ ( user , req ) =>
1134+ user . id === Number ( req . params . producerId ) ||
1135+ throwError (
1136+ new ForbiddenError ( "User may not interact with others' production units" , {
1137+ user : user . id ,
1138+ producer : Number ( req . params . producerId )
1139+ } )
1140+ )
1141+ ]
1142+ } )
1143+ ] )
1144+ public async updateCarrierOfProducer (
1145+ @Request ( ) req : Express . Request ,
1146+ @Response ( ) res : Express . Response ,
1147+ @Params ( 'producerId' ) producerId : number ,
1148+ @Params ( 'carrierId' ) carrierId : number
1149+ ) {
1150+ const producer = await container . producerGateway . findById ( producerId ) ;
1151+ if ( ! producer ) throw new NotFoundError ( 'Producer not found' ) ;
1152+
1153+ const carrier = await container . carrierGateway . findOneOfProducer ( producer . user . id , carrierId ) ;
1154+ if ( ! carrier ) throw new NotFoundError ( 'Carrier not found' ) ;
1155+
1156+ const productionUnit = await container . productionUnitGateway . findOneFromProducer ( producer . user . id , req . body . productionUnitId ) ;
1157+ if ( ! productionUnit ) throw new NotFoundError ( 'Production unit not found' ) ;
1158+
1159+ carrier . image = new Image ( req . body . image . name , req . body . image . url , req . body . image . alt ) ;
1160+ carrier . productionUnit = productionUnit ;
1161+ carrier . status = req . body . status ;
1162+ await container . carrierGateway . createOrUpdate ( carrier ) ;
1163+
1164+ return res . status ( 200 ) . json ( carrier ) ;
1165+ }
1166+
1167+ @Delete ( '/:producerId/carriers/:carrierId' , [
1168+ validate ( {
1169+ params : Joi . object ( {
1170+ producerId : Joi . number ( ) . min ( 1 ) . required ( ) ,
1171+ carrierId : Joi . number ( ) . min ( 1 ) . required ( )
1172+ } )
1173+ } ) ,
1174+ authenticationMiddleware ,
1175+ authorizationMiddleware ( {
1176+ permissions : Permission . WRITE_OTHER_PRODUCER ,
1177+ otherValidations : [
1178+ ( user , req ) =>
1179+ user . id === Number ( req . params . producerId ) ||
1180+ throwError (
1181+ new ForbiddenError ( "User may not interact with others' production units" , {
1182+ user : user . id ,
1183+ producer : Number ( req . params . producerId )
1184+ } )
1185+ )
1186+ ]
1187+ } )
1188+ ] )
1189+ public async deleteCarrierOfProducer (
1190+ @Response ( ) res : Express . Response ,
1191+ @Params ( 'producerId' ) producerId : number ,
1192+ @Params ( 'carrierId' ) carrierId : number
1193+ ) {
1194+ const producer = await container . producerGateway . findById ( producerId ) ;
1195+ if ( ! producer ) throw new NotFoundError ( 'Producer not found' ) ;
1196+
1197+ const carrier = await container . carrierGateway . findOneOfProducer ( producer . user . id , carrierId ) ;
1198+ if ( ! carrier ) throw new NotFoundError ( 'Carrier not found' ) ;
1199+
1200+ if ( carrier . status === CarrierStatus . Unavailable ) throw new ForbiddenError ( 'Carrier is unavailable so it cannot be deleted' ) ;
1201+
1202+ carrier . deletedAt = new Date ( ) ;
1203+ await container . carrierGateway . createOrUpdate ( carrier ) ;
1204+
1205+ return res . status ( 204 ) . send ( ) ;
1206+ }
9871207}
0 commit comments