diff --git a/imphnen-dimentorin/src/payments/application/payment_service.rs b/imphnen-dimentorin/src/payments/application/payment_service.rs index 505563e..de1355f 100644 --- a/imphnen-dimentorin/src/payments/application/payment_service.rs +++ b/imphnen-dimentorin/src/payments/application/payment_service.rs @@ -152,32 +152,39 @@ impl PaymentService for PaymentServiceImpl { id: Uuid, actor_id: Uuid, ) -> Result { - // Admin / "Admin Pembayaran" only — check role via users table. - let user = UsersEntity::find_by_id(actor_id) - .one(self.db.as_ref()) - .await - .map_err(|e| AppError::InternalServerError(e.to_string()))? - .ok_or_else(|| AppError::NotFoundError("Actor not found".into()))?; - let role_id = user.role_id.ok_or_else(|| { - AppError::ForbiddenError("User has no role assigned".into()) - })?; - let roles = imphnen_entities::seaorm::auth::roles::Entity::find_by_id(role_id) - .one(self.db.as_ref()) - .await - .map_err(|e| AppError::InternalServerError(e.to_string()))? - .ok_or_else(|| AppError::ForbiddenError("Role not found".into()))?; - if roles.name != "Admin" && roles.name != "Admin Pembayaran" { - return Err(AppError::ForbiddenError( - "Only payment admin can confirm payments".into(), - )); - } - + // Payment can be confirmed by the session's mentor (they see the + // transfer arrive) or by an Admin / "Admin Pembayaran". let payment = self.payment_repo.find_by_id(id).await?; if payment.status != "pending" { return Err(AppError::ConflictError( "Payment is not pending".into(), )); } + let user = UsersEntity::find_by_id(actor_id) + .one(self.db.as_ref()) + .await + .map_err(|e| AppError::InternalServerError(e.to_string()))? + .ok_or_else(|| AppError::NotFoundError("Actor not found".into()))?; + // Mentor of the linked session may confirm; otherwise an + // Admin / "Admin Pembayaran" role is required. + let is_mentor = payment.mentor_id == actor_id; + if !is_mentor { + let role_id = user.role_id.ok_or_else(|| { + AppError::ForbiddenError("User has no role assigned".into()) + })?; + let roles = + imphnen_entities::seaorm::auth::roles::Entity::find_by_id(role_id) + .one(self.db.as_ref()) + .await + .map_err(|e| AppError::InternalServerError(e.to_string()))? + .ok_or_else(|| AppError::ForbiddenError("Role not found".into()))?; + if roles.name != "Admin" && roles.name != "Admin Pembayaran" { + return Err(AppError::ForbiddenError( + "Only the session mentor or a payment admin can confirm payments".into(), + )); + } + } + let paid = self.payment_repo .update_status(id, "paid", Some(payment.external_ref.clone().unwrap_or_default())) .await?;