OrdersController.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
  2. import Order from 'App/Models/Order'
  3. import PaginationService from 'App/Services/PaginationService'
  4. import { schema } from '@ioc:Adonis/Core/Validator'
  5. import { BadRequestException } from 'App/Exceptions/Common'
  6. import Series from 'App/Models/Series'
  7. import Episode from 'App/Models/Episode'
  8. import UserBalanceService from 'App/Services/UserBalanceService'
  9. import Decimal from 'decimal.js'
  10. import { BalanceRecordType } from 'App/Models/BalanceRecord'
  11. export default class OrdersController {
  12. private paginationService = new PaginationService(Order)
  13. public async index({ request, auth }: HttpContextContract) {
  14. const page = await this.paginationService.paginate({
  15. ...request.all(),
  16. userId: auth.user!.id
  17. })
  18. const seriesIds = new Set(
  19. page
  20. .all()
  21. .map((record) => record.seriesId)
  22. .filter((id) => !!id)
  23. )
  24. const series = await Series.findMany(Array.from(seriesIds))
  25. const episodeIds = new Set(
  26. page
  27. .all()
  28. .map((record) => record.episodeId)
  29. .filter((id) => !!id)
  30. )
  31. const episodes = await Episode.findMany(Array.from(episodeIds))
  32. page.all().forEach((record) => {
  33. if (record.seriesId) {
  34. record.series = series.find((s) => s.id === record.seriesId)
  35. }
  36. if (record.episodeId) {
  37. record.episode = episodes.find((e) => e.id === record.episodeId)
  38. }
  39. })
  40. return page
  41. }
  42. public async store({ request, auth }: HttpContextContract) {
  43. const user = auth.user!
  44. const data: {
  45. seriesId?: number
  46. episodeId?: number
  47. price?: Decimal
  48. type?: BalanceRecordType
  49. userId?: number
  50. } = await request.validate({
  51. schema: schema.create({
  52. seriesId: schema.number.optional(),
  53. episodeId: schema.number.optional()
  54. })
  55. })
  56. if (!data.seriesId && !data.episodeId) {
  57. throw new BadRequestException('seriesId or episodeId must be provided')
  58. }
  59. const userBalance = await UserBalanceService.getBalance(user.id)
  60. if (data.seriesId) {
  61. const series = await Series.findOrFail(data.seriesId)
  62. if (series.price.comparedTo(userBalance.balance) > 0) {
  63. throw new Error('not enough balance')
  64. }
  65. data.price = series.price
  66. data.type = BalanceRecordType.Purchase
  67. } else {
  68. const episode = await Episode.findOrFail(data.episodeId)
  69. if (episode.price.comparedTo(userBalance.balance) > 0) {
  70. throw new Error('not enough balance')
  71. }
  72. data.seriesId = episode.seriesId
  73. data.price = episode.price
  74. data.type = BalanceRecordType.Purchase
  75. }
  76. data.userId = user.id
  77. await UserBalanceService.modifiyBalance({
  78. userId: user.id,
  79. amount: data.price.negated(),
  80. type: data.type,
  81. seriesId: data.seriesId,
  82. episodeId: data.episodeId
  83. })
  84. return await Order.create(data)
  85. }
  86. public async show({ params }: HttpContextContract) {
  87. return await Order.findOrFail(params.id)
  88. }
  89. public async update({ response }: HttpContextContract) {
  90. response.notImplemented()
  91. }
  92. public async destroy({ response }: HttpContextContract) {
  93. response.notImplemented()
  94. }
  95. }