OrdersController.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
  2. import Order, { OrderType } 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 BalanceRecord, { 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 = await request.validate({
  45. schema: schema.create({
  46. seriesId: schema.number.optional(),
  47. episodeId: schema.number.optional()
  48. })
  49. })
  50. if (!data.seriesId && !data.episodeId) {
  51. throw new BadRequestException('seriesId or episodeId must be provided')
  52. }
  53. const userBalance = await UserBalanceService.getBalance(user.id)
  54. const order = new Order()
  55. order.merge(data)
  56. order.userId = user.id
  57. let price: Decimal
  58. if (data.seriesId) {
  59. const series = await Series.findOrFail(data.seriesId)
  60. if (series.price.comparedTo(userBalance.balance) > 0) {
  61. throw new Error('not enough balance')
  62. }
  63. price = series.price
  64. } else {
  65. const episode = await Episode.findOrFail(data.episodeId)
  66. if (episode.price.comparedTo(userBalance.balance) > 0) {
  67. throw new Error('not enough balance')
  68. }
  69. price = episode.price
  70. }
  71. await UserBalanceService.modifiyBalance({
  72. userId: user.id,
  73. amount: price.negated(),
  74. type: BalanceRecordType.Purchase,
  75. seriesId: data.seriesId,
  76. episodeId: data.episodeId
  77. })
  78. return await Order.create({
  79. userId: user.id,
  80. price,
  81. type: data.seriesId ? OrderType.Series : OrderType.Episode,
  82. ...data
  83. })
  84. }
  85. public async show({ params }: HttpContextContract) {
  86. return await Order.findOrFail(params.id)
  87. }
  88. public async update({ response }: HttpContextContract) {
  89. response.notImplemented()
  90. }
  91. public async destroy({ response }: HttpContextContract) {
  92. response.notImplemented()
  93. }
  94. }