diff --git a/src/config/permission.py b/src/config/permission.py index 9bfc109..80742d9 100644 --- a/src/config/permission.py +++ b/src/config/permission.py @@ -3,7 +3,11 @@ '/auth/logout', '/categories', '/events/', - '/tickets/' + '/tickets/', + '/users/update-profile', + '/users/topup', + '/users/withdraw', + ] admin_permission=[ @@ -14,11 +18,13 @@ ] user_permission=[ + ] event_organizer_permission=[ '/events/*', '!/events/verify', + ] permissions = { diff --git a/src/controllers/AuthController.py b/src/controllers/AuthController.py index 105fb65..6d46968 100644 --- a/src/controllers/AuthController.py +++ b/src/controllers/AuthController.py @@ -37,7 +37,7 @@ def me(): @AuthApp.route('/verify', methods=['post']) @isAuthenticated def verify(): - req = request.json + req = request result = authService.verify(req) if(result['status'] == 'failed'): return Response.error(result['data'],result['code']) diff --git a/src/controllers/EventController.py b/src/controllers/EventController.py index 964a62f..a5afb92 100644 --- a/src/controllers/EventController.py +++ b/src/controllers/EventController.py @@ -1,5 +1,6 @@ from flask import Blueprint from flask import request,g +from flask_cors import cross_origin from src.services.EventService import EventService from src.middlewares.AuthMiddleware import isAuthenticated import src.utils.getResponse as Response @@ -8,6 +9,7 @@ eventService = EventService() @EventApp.route('/', methods=['GET']) +@cross_origin(supports_credentials=True) def index(): _filter ={ "district" : request.args.get('district'), @@ -21,6 +23,13 @@ def index(): result = eventService.getAllEvent(_filter) return Response.success(result['data'],"success get all events") +@EventApp.route('/', methods=['GET']) +def detail(id): + result = eventService.getEventById(id) + if(result['status'] == 'failed'): + return Response.error(result['data'],result['code']) + + return Response.success(result['data'],"success get event by id") @EventApp.route('/', methods=['POST']) @isAuthenticated def store(): @@ -39,7 +48,11 @@ def verify(): return Response.error(result['data'],result['code']) return Response.success(result['data'],"success verify event") - +@EventApp.route('/my', methods=['GET']) +@isAuthenticated +def getMyEvent(): + result = eventService.getMyEvent(user_id=g.user['user_id']) + return Response.success(result['data'],"success get my event") @EventApp.route('/', methods=['PUT']) @isAuthenticated def update(id): @@ -57,4 +70,5 @@ def delete(id): if(result['status'] == 'failed'): return Response.error(result['data'],result['code']) - return Response.success(result['data'],"success delete event") \ No newline at end of file + return Response.success(result['data'],"success delete event") + diff --git a/src/controllers/UserController.py b/src/controllers/UserController.py index 61f8753..fbe33b8 100644 --- a/src/controllers/UserController.py +++ b/src/controllers/UserController.py @@ -1,5 +1,4 @@ -from flask import Blueprint -from flask import request +from flask import Blueprint,request,g from src.services.UserService import UserService as UserService from src.middlewares.AuthMiddleware import isAuthenticated import src.utils.getResponse as Response @@ -11,4 +10,31 @@ @isAuthenticated def index(): result = userService.getAllUser() - return Response.success(result['data'],"success get all user") \ No newline at end of file + return Response.success(result['data'],"success get all user") + +@UserApp.route('/update-profile', methods=['post']) +@isAuthenticated +def updateProfile(): + req = request.json + result = userService.updateProfile(data=req,id=g.user['user_id']) + if(result['status'] == 'failed'): + return Response.error(result['data'],result['code']) + return Response.success(result['data'],"success update profile user") + +@UserApp.route('/topup', methods=['post']) +@isAuthenticated +def topup(): + req = request.json + result = userService.topup(data=req,id=g.user['user_id']) + if(result['status'] == 'failed'): + return Response.error(result['data'],result['code']) + return Response.success(result['data'],"success topup user") + +@UserApp.route('/withdraw', methods=['post']) +@isAuthenticated +def withdraw(): + req = request.json + result = userService.withdraw(data=req,id=g.user['user_id']) + if(result['status'] == 'failed'): + return Response.error(result['data'],result['code']) + return Response.success(result['data'],"success withdraw user") \ No newline at end of file diff --git a/src/repositories/UserRepository.py b/src/repositories/UserRepository.py index 664f50a..1706160 100644 --- a/src/repositories/UserRepository.py +++ b/src/repositories/UserRepository.py @@ -27,5 +27,23 @@ def verifyUser(self,user_id): user = User.query.filter_by(user_id=user_id).first() if(not user) :return False user.status = 'ACTIVE' + db.session.commit() + return user + def updateProfile(self,id,data): + user = User.query.filter_by(user_id=id).first() + if(not user) :return False + user.name = data['name'] or user.name + user.email = data['email'] or user.email + user.password = bcrypt.hashpw(data['password'].encode('utf-8'), bcrypt.gensalt()) if data['password'] else user.password + db.session.commit() + return user + def updateBalance(self,id,nominal,operator): + user = User.query.filter_by(user_id=id).first() + if(not user) :return False + if(operator == 'plus'): + user.balance += nominal + if(operator == 'minus'): + user.balance -= nominal + db.session.commit() return user \ No newline at end of file diff --git a/src/services/EventService.py b/src/services/EventService.py index c39b911..25667bc 100644 --- a/src/services/EventService.py +++ b/src/services/EventService.py @@ -27,7 +27,15 @@ def getAllEvent(self,filter): except Exception as e: print(e) return EventService.failedOrSuccessRequest('failed', 500, str(e)) - + def getEventById(self,id): + try: + event = eventRepository.getEventById(id) + if not event: + return EventService.failedOrSuccessRequest('failed', 404, 'Event not found') + return EventService.failedOrSuccessRequest('success', 200, queryResultToDict([event],['user','category'])[0]) + except Exception as e: + return EventService.failedOrSuccessRequest('failed', 500, str(e)) + def createEvent(self,data,file,user_id): try: @@ -95,3 +103,9 @@ def verifyEvent(self,data): return self.failedOrSuccessRequest('failed',400,errorHandler(e.errors())) except Exception as e: return self.failedOrSuccessRequest('failed',400,str(e)) + def getMyEvent(self,user_id): + try: + data = eventRepository.getAllEventByUserId(user_id) + return EventService.failedOrSuccessRequest('success', 200, queryResultToDict(data,['user','category'])) + except Exception as e: + return EventService.failedOrSuccessRequest('failed', 500, str(e)) \ No newline at end of file diff --git a/src/services/TicketService.py b/src/services/TicketService.py index e6518df..d741a43 100644 --- a/src/services/TicketService.py +++ b/src/services/TicketService.py @@ -1,5 +1,7 @@ from src.repositories.TicketRepository import TicketRepository +from src.repositories.UserRepository import UserRepository +from src.repositories.EventRepository import EventRepository from src.utils.convert import queryResultToDict from src.services.Service import Service from src.utils.validator.TicketValidator import CreateNewTicketValidator @@ -7,6 +9,8 @@ from src.utils.sendMail import sendMail ticketRepository = TicketRepository() +userRepository = UserRepository() +eventRepository = EventRepository() class TicketService(Service): @staticmethod @@ -29,7 +33,15 @@ def createNewTicket(self,data,user_id): validate = CreateNewTicketValidator(**data) if(not validate): return self.failedOrSuccessRequest('failed', 400, validate.errors()) - + + user = userRepository.getUserById(user_id) + event = eventRepository.getEventById(data['event_id']) + if(not event): + return self.failedOrSuccessRequest('failed', 400, 'event not found') + if user.balance < event.price: + return self.failedOrSuccessRequest('failed', 400, 'balance not enough') + userRepository.updateBalance(id=user_id,nominal=event.price,operator='minus') + userRepository.updateBalance(id=event.user_id,nominal=event.price,operator='plus') data = ticketRepository.createNewTicket(data,user_id) sendMail( name=data.user.name, diff --git a/src/services/UserService.py b/src/services/UserService.py index 72bb656..33432a9 100644 --- a/src/services/UserService.py +++ b/src/services/UserService.py @@ -1,5 +1,7 @@ from src.repositories.UserRepository import UserRepository +from src.utils.errorHandler import errorHandler +from src.utils.validator.UserValidator import UpdateProfileValidator,UpdateBalanceValidator from src.utils.convert import queryResultToDict from src.services.Service import Service userRepository = UserRepository() @@ -20,4 +22,37 @@ def getAllUser(self): except Exception as e: return UserService.failedOrSuccessRequest('failed', 500, str(e)) - \ No newline at end of file + def updateProfile(self,data,id): + try: + validate = UpdateProfileValidator(**data) + if not validate: + return self.failedOrSuccessRequest('failed', 400, 'Validation failed') + user = userRepository.updateProfile(id=id,data=data) + if not user: + return self.failedOrSuccessRequest('failed', 400, 'user not found') + return self.failedOrSuccessRequest('success', 200, queryResultToDict([user])[0]) + except ValueError as e: + return self.failedOrSuccessRequest('failed', 500, errorHandler(e.errors())) + def topup(self,id,data): + try: + validate = UpdateBalanceValidator(**data) + if not validate: + return self.failedOrSuccessRequest('failed', 400, 'Validation failed') + user = userRepository.updateBalance(id=id,nominal=data['nominal'],operator='plus') + return self.failedOrSuccessRequest('success', 200, queryResultToDict([user])[0]) + except ValueError as e: + return self.failedOrSuccessRequest('failed', 500, errorHandler(e.errors())) + + def withdraw(self,id,data): + try: + validate = UpdateBalanceValidator(**data) + if not validate: + return self.failedOrSuccessRequest('failed', 400, 'Validation failed') + user = userRepository.getUserById(user_id=id) + if(user.balance < data['nominal']): + return self.failedOrSuccessRequest('failed', 400, 'balance not enough') + + user = userRepository.updateBalance(id=id,nominal=data['nominal'],operator='minus') + return self.failedOrSuccessRequest('success', 200, queryResultToDict([user])[0]) + except ValueError as e: + return self.failedOrSuccessRequest('failed', 500, errorHandler(e.errors())) \ No newline at end of file diff --git a/src/utils/validator/UserValidator.py b/src/utils/validator/UserValidator.py index e69de29..56457df 100644 --- a/src/utils/validator/UserValidator.py +++ b/src/utils/validator/UserValidator.py @@ -0,0 +1,8 @@ +from pydantic import BaseModel, constr, EmailStr +class UpdateProfileValidator(BaseModel): + name: str + email: EmailStr + password: constr(min_length=8, max_length=16) + +class UpdateBalanceValidator(BaseModel): + nominal: int \ No newline at end of file