import Fluent import Vapor // An intermediate between our api and view controllers that interacts with the // database. struct PurchaseOrderDB { func create( _ model: PurchaseOrder.Create, createdById: User.IDValue, on db: any Database ) async throws -> PurchaseOrder.DTO { guard let employee = try await Employee.find(model.createdForID, on: db) else { throw Abort(.notFound, reason: "Employee not found.") } guard employee.active else { throw Abort(.badRequest, reason: "Employee is not active, unable to generate a PO for in-active employees") } let purchaseOrder = model.toModel(createdByID: createdById) try await purchaseOrder.save(on: db) guard let loaded = try await get(id: purchaseOrder.requireID(), on: db) else { return purchaseOrder.toDTO() } return loaded } func fetchAll(on db: any Database) async throws -> [PurchaseOrder.DTO] { try await PurchaseOrder.allQuery(on: db) .sort(\.$id, .descending) .all().map { $0.toDTO() } } func fetchPage(_ page: Int, limit: Int, on db: any Database) async throws -> Page { try await PurchaseOrder.allQuery(on: db) .sort(\.$id, .descending) .paginate(PageRequest(page: page, per: limit)) .map { $0.toDTO() } } func get(id: PurchaseOrder.IDValue, on db: any Database) async throws -> PurchaseOrder.DTO? { try await PurchaseOrder.allQuery(on: db) .filter(\.$id == id) .first()?.toDTO() } func delete(id: PurchaseOrder.IDValue, on db: any Database) async throws { guard let purchaseOrder = try await PurchaseOrder.find(id, on: db) else { throw Abort(.notFound) } try await purchaseOrder.delete(on: db) } } private extension PurchaseOrder { static func allQuery(on db: any Database) -> QueryBuilder { PurchaseOrder.query(on: db) .with(\.$createdBy) .with(\.$createdFor) .with(\.$vendorBranch) { branch in branch.with(\.$vendor) } } }