This repository has been archived by the owner on Sep 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Bootstrap location models, validators, manager and routes
- Loading branch information
1 parent
b264571
commit f15125d
Showing
13 changed files
with
603 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; | ||
import { ApiDocument } from 'App/Helpers/Api/Document'; | ||
import Location, { LocationStatus } from 'App/Models/Location'; | ||
import LocationManager from 'App/Helpers/Managers/LocationManager'; | ||
|
||
// TODO(matthiasrohmer): Add permissions | ||
export default class LocationController { | ||
public async index(ctx: HttpContextContract) { | ||
const manager: LocationManager = new LocationManager(ctx); | ||
await manager.all(); | ||
|
||
return new ApiDocument(ctx, manager.toResources(), { | ||
paginator: manager.paginator, | ||
}); | ||
} | ||
|
||
public async store(ctx: HttpContextContract) { | ||
const manager: LocationManager = new LocationManager(ctx); | ||
await manager.create(); | ||
|
||
return new ApiDocument(ctx, manager.toResources()); | ||
} | ||
|
||
public async show(ctx: HttpContextContract) { | ||
const manager: LocationManager = new LocationManager(ctx); | ||
|
||
manager.include = 'address,types,subjects'; | ||
await manager.byId(); | ||
|
||
const location: Location = manager.instance; | ||
const publishable = await location.publishable(); | ||
|
||
return new ApiDocument(ctx, manager.toResources(), { publishable }); | ||
} | ||
|
||
public async update(ctx: HttpContextContract) { | ||
const manager: LocationManager = new LocationManager(ctx); | ||
await manager.update(); | ||
|
||
manager.include = 'address,types,subjects'; | ||
const location: Location = await manager.byId(); | ||
const publishable = await location.publishable(); | ||
|
||
if (publishable !== true) { | ||
location.status = LocationStatus.DRAFT; | ||
if (location.$isDirty) { | ||
await location.save(); | ||
} | ||
} | ||
|
||
return new ApiDocument(ctx, manager.toResources(), { | ||
publishable, | ||
}); | ||
} | ||
|
||
public async translate(ctx: HttpContextContract) { | ||
const manager: LocationManager = new LocationManager(ctx); | ||
await manager.byId(); | ||
await manager.translate(); | ||
|
||
return new ApiDocument(ctx, manager.toResources()); | ||
} | ||
|
||
// public async destroy(ctx: HttpContextContract) { | ||
// const { params, auth } = ctx; | ||
// if (!auth.user) { | ||
// throw new UnauthorizedException(); | ||
// } | ||
|
||
// const location = await Location.query() | ||
// .preload('address') | ||
// .where('cid', params.id) | ||
// .firstOrFail(); | ||
// const address = location.address; | ||
|
||
// await Promise.all([location.delete(), address.delete()]); | ||
|
||
// return new ApiDocument(ctx, {}, 'Location deleted successfully'); | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; | ||
import BaseManager from 'App/Helpers/Managers/BaseManager'; | ||
import Location from 'App/Models/Location'; | ||
import { | ||
CreateLocationValidator, | ||
UpdateLocationValidator, | ||
} from 'App/Validators/v1/LocationValidator'; | ||
import { LocationTranslationValidator } from 'App/Validators/v1/LocationTranslationValidator'; | ||
import Database from '@ioc:Adonis/Lucid/Database'; | ||
import Address from 'App/Models/Address'; | ||
|
||
export default class LocationManager extends BaseManager<typeof Location> { | ||
public ManagedModel = Location; | ||
|
||
public settings = { | ||
queryId: 'public_id', | ||
orderableBy: [ | ||
{ | ||
name: 'name', | ||
query: Database.raw( | ||
`(SELECT name FROM organizer_translations WHERE organizer_translations.organizer_id = organizers.id AND organizer_translations.language = '${this.language}')` | ||
), | ||
}, | ||
{ | ||
name: 'createdAt', | ||
attribute: 'created_at', | ||
}, | ||
{ | ||
name: 'updatedAt', | ||
attribute: 'updated_at', | ||
}, | ||
], | ||
}; | ||
|
||
public validators = { | ||
translate: LocationTranslationValidator, | ||
}; | ||
|
||
constructor(ctx: HttpContextContract) { | ||
super(ctx, Location); | ||
} | ||
|
||
public query() { | ||
return super.query().preload('address'); | ||
} | ||
|
||
private async $createAddress(location, attributes, trx) { | ||
const address = new Address(); | ||
await location.related(); | ||
address.fill(attributes); | ||
|
||
address.useTransaction(trx); | ||
await address.save(); | ||
await location.related('address').associate(address); | ||
|
||
return address; | ||
} | ||
|
||
public async create() { | ||
const { attributes, relations } = await this.ctx.request.validate( | ||
new CreateLocationValidator(this.ctx) | ||
); | ||
|
||
const location = new Location(); | ||
await Database.transaction(async (trx) => { | ||
location.useTransaction(trx); | ||
await location.save(); | ||
|
||
await location.related('translations').create({ | ||
name: attributes.name, | ||
description: attributes.description, | ||
language: this.language, | ||
}); | ||
|
||
if (relations?.address) { | ||
await this.$createAddress(location, relations.address.attributes, trx); | ||
} | ||
|
||
await this.$updateLinks(location, relations?.links); | ||
}); | ||
|
||
return await await this.byId(location.publicId); | ||
} | ||
|
||
public async update() { | ||
const { attributes, relations } = await this.ctx.request.validate( | ||
new UpdateLocationValidator(this.ctx) | ||
); | ||
|
||
const location = await this.byId(); | ||
await Database.transaction(async (trx) => { | ||
location.useTransaction(trx); | ||
if (location.$isDirty) { | ||
await location.save(); | ||
} | ||
|
||
if (relations?.address) { | ||
if (location.address) { | ||
location.address.merge(relations.address.attributes); | ||
await location.address.save(); | ||
} else { | ||
await this.$createAddress( | ||
location, | ||
relations.address.attributes, | ||
trx | ||
); | ||
} | ||
} | ||
|
||
await this.$updateLinks(location, relations?.links); | ||
}); | ||
|
||
return await this.byId(location.publicId); | ||
} | ||
|
||
public async translate() { | ||
const attributes = await this.$validateTranslation(); | ||
|
||
// Creating an organizer translation without a name is forbidden, | ||
// but initially creating one without a name is impossible. Hence fallback | ||
// to the initial name | ||
if (!attributes.name) { | ||
attributes.name = this.instance?.translations?.find((translation) => { | ||
return translation.name; | ||
})?.name; | ||
} | ||
|
||
await this.$saveTranslation(attributes); | ||
|
||
return this.byId(); | ||
} | ||
} |
Oops, something went wrong.