diff --git a/Sources/App/Controllers/Api/PurchaseOrderApiController.swift b/Sources/App/Controllers/Api/PurchaseOrderApiController.swift index 12d521e..4bdbb50 100644 --- a/Sources/App/Controllers/Api/PurchaseOrderApiController.swift +++ b/Sources/App/Controllers/Api/PurchaseOrderApiController.swift @@ -1,10 +1,12 @@ +import Dependencies import Fluent import Vapor // TODO: Add update route. struct PurchaseOrderApiController: RouteCollection { - private let purchaseOrders = PurchaseOrderDB() + + @Dependency(\.purchaseOrders) var purchaseOrders func boot(routes: any RoutesBuilder) throws { let protected = routes.apiProtected(route: "purchase-orders") @@ -18,7 +20,7 @@ struct PurchaseOrderApiController: RouteCollection { @Sendable func index(req: Request) async throws -> [PurchaseOrder.DTO] { - try await purchaseOrders.fetchAll(on: req.db) + try await purchaseOrders.fetchAll() } @Sendable @@ -27,15 +29,14 @@ struct PurchaseOrderApiController: RouteCollection { let model = try req.content.decode(PurchaseOrder.Create.self) return try await purchaseOrders.create( model, - createdById: req.auth.require(User.self).requireID(), - on: req.db + req.auth.require(User.self).requireID() ) } @Sendable func get(req: Request) async throws -> PurchaseOrder.DTO { guard let id = req.parameters.get("id", as: PurchaseOrder.IDValue.self), - let purchaseOrder = try await purchaseOrders.get(id: id, on: req.db) + let purchaseOrder = try await purchaseOrders.get(id) else { throw Abort(.notFound) } @@ -47,7 +48,7 @@ struct PurchaseOrderApiController: RouteCollection { guard let id = req.parameters.get("id", as: PurchaseOrder.IDValue.self) else { throw Abort(.badRequest, reason: "Purchase order id not provided.") } - try await purchaseOrders.delete(id: id, on: req.db) + try await purchaseOrders.delete(id) return .ok } diff --git a/Sources/App/Controllers/Api/UserApiController.swift b/Sources/App/Controllers/Api/UserApiController.swift index 7f21f99..3e457ba 100644 --- a/Sources/App/Controllers/Api/UserApiController.swift +++ b/Sources/App/Controllers/Api/UserApiController.swift @@ -1,9 +1,11 @@ +import Dependencies import Fluent import Vapor // TODO: Add update and get by id. struct UserApiController: RouteCollection { - let users = UserDB() + + @Dependency(\.users) var users func boot(routes: any RoutesBuilder) throws { let unProtected = routes.apiUnprotected(route: "users") @@ -19,7 +21,7 @@ struct UserApiController: RouteCollection { @Sendable func index(req: Request) async throws -> [User.DTO] { - try await users.fetchAll(on: req.db) + try await users.fetchAll() } @Sendable @@ -33,13 +35,13 @@ struct UserApiController: RouteCollection { } try User.Create.validate(content: req) let model = try req.content.decode(User.Create.self) - return try await users.create(model, on: req.db) + return try await users.create(model) } @Sendable func login(req: Request) async throws -> UserToken { let user = try req.auth.require(User.self) - return try await users.login(user: user, on: req.db) + return try await users.login(user) } // @Sendable @@ -53,7 +55,7 @@ struct UserApiController: RouteCollection { guard let id = req.parameters.get("id", as: User.IDValue.self) else { throw Abort(.badRequest, reason: "User id not provided") } - try await users.delete(id: id, on: req.db) + try await users.delete(id) return .ok } } diff --git a/Sources/App/Controllers/Api/VendorApiController.swift b/Sources/App/Controllers/Api/VendorApiController.swift index 304cb94..419be31 100644 --- a/Sources/App/Controllers/Api/VendorApiController.swift +++ b/Sources/App/Controllers/Api/VendorApiController.swift @@ -1,8 +1,10 @@ +import Dependencies import Fluent import Vapor struct VendorApiController: RouteCollection { - private let vendors = VendorDB() + + @Dependency(\.vendors) var vendors func boot(routes: any RoutesBuilder) throws { let protected = routes.apiProtected(route: "vendors") @@ -17,14 +19,14 @@ struct VendorApiController: RouteCollection { @Sendable func index(req: Request) async throws -> [Vendor.DTO] { let params = try req.query.decode(VendorsIndexQuery.self) - return try await vendors.fetchAll(withBranches: params.branches, on: req.db) + return try await vendors.fetchAll(params.fetchRequest) } @Sendable func create(req: Request) async throws -> Vendor.DTO { try Vendor.Create.validate(content: req) let model = try req.content.decode(Vendor.Create.self) - return try await vendors.create(model, on: req.db) + return try await vendors.create(model) } @Sendable @@ -34,7 +36,7 @@ struct VendorApiController: RouteCollection { } try Vendor.Update.validate(content: req) let updates = try req.content.decode(Vendor.Update.self) - return try await vendors.update(id: id, with: updates, on: req.db) + return try await vendors.update(id, updates) } @Sendable @@ -42,11 +44,16 @@ struct VendorApiController: RouteCollection { guard let id = req.parameters.get("id", as: Vendor.IDValue.self) else { throw Abort(.badRequest, reason: "Vendor id not provided.") } - try await vendors.delete(id: id, on: req.db) + try await vendors.delete(id) return .ok } } struct VendorsIndexQuery: Content { let branches: Bool? + + var fetchRequest: VendorDB.FetchRequest { + if branches == true { return .withBranches } + return .default + } } diff --git a/Sources/App/Controllers/Api/VendorBranchApiController.swift b/Sources/App/Controllers/Api/VendorBranchApiController.swift index 458b431..e07fe45 100644 --- a/Sources/App/Controllers/Api/VendorBranchApiController.swift +++ b/Sources/App/Controllers/Api/VendorBranchApiController.swift @@ -1,8 +1,10 @@ +import Dependencies import Fluent import Vapor struct VendorBranchApiController: RouteCollection { - private let vendorBranches = VendorBranchDB() + + @Dependency(\.vendorBranches) var vendorBranches func boot(routes: any RoutesBuilder) throws { let prefix = routes.apiProtected(route: "vendors") @@ -21,7 +23,7 @@ struct VendorBranchApiController: RouteCollection { @Sendable func index(req: Request) async throws -> [VendorBranch.DTO] { - try await vendorBranches.fetchAll(on: req.db) + try await vendorBranches.fetchAll() } @Sendable @@ -29,7 +31,7 @@ struct VendorBranchApiController: RouteCollection { guard let id = req.parameters.get("vendorID", as: Vendor.IDValue.self) else { throw Abort(.badRequest, reason: "Vendor id not provided.") } - return try await vendorBranches.fetch(for: id, on: req.db) + return try await vendorBranches.fetchForVendor(id) } @Sendable @@ -39,7 +41,7 @@ struct VendorBranchApiController: RouteCollection { } try VendorBranch.Create.validate(content: req) let model = try req.content.decode(VendorBranch.Create.self) - return try await vendorBranches.create(model, for: id, on: req.db) + return try await vendorBranches.create(model, id) } @Sendable @@ -49,7 +51,7 @@ struct VendorBranchApiController: RouteCollection { } try VendorBranch.Update.validate(content: req) let updates = try req.content.decode(VendorBranch.Update.self) - return try await vendorBranches.update(id: id, with: updates, on: req.db) + return try await vendorBranches.update(id, updates) } @Sendable @@ -57,7 +59,7 @@ struct VendorBranchApiController: RouteCollection { guard let id = req.parameters.get("id", as: VendorBranch.IDValue.self) else { throw Abort(.badRequest, reason: "Vendor branch id not provided.") } - try await vendorBranches.delete(id: id, on: req.db) + try await vendorBranches.delete(id) return .ok } diff --git a/Sources/App/Controllers/DB/PurchaseOrderDB.swift b/Sources/App/Controllers/DB/PurchaseOrderDB.swift index 5786874..99fa7bf 100644 --- a/Sources/App/Controllers/DB/PurchaseOrderDB.swift +++ b/Sources/App/Controllers/DB/PurchaseOrderDB.swift @@ -1,56 +1,72 @@ +import Dependencies +import DependenciesMacros import Fluent import Vapor -// An intermediate between our api and view controllers that interacts with the -// database. -struct PurchaseOrderDB { +extension DependencyValues { + // An intermediate between our api and view controllers that interacts with the + // database. + var purchaseOrders: PurchaseOrdersDB { + get { self[PurchaseOrdersDB.self] } + set { self[PurchaseOrdersDB.self] = newValue } + } +} - 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.") - } +@DependencyClient +struct PurchaseOrdersDB: Sendable { + var create: @Sendable (PurchaseOrder.Create, User.IDValue) async throws -> PurchaseOrder.DTO + var fetchAll: @Sendable () async throws -> [PurchaseOrder.DTO] + var fetchPage: @Sendable (PageRequest) async throws -> Page + var get: @Sendable (PurchaseOrder.IDValue) async throws -> PurchaseOrder.DTO? + // var update: @Sendable (PurchaseOrder.IDValue, PurchaseOrder.Update) async throws -> PurchaseOrder.DTO + var delete: @Sendable (PurchaseOrder.IDValue) async throws -> Void +} - guard employee.active else { - throw Abort(.badRequest, reason: "Employee is not active, unable to generate a PO for in-active employees") - } +extension PurchaseOrdersDB: TestDependencyKey { + static let testValue: PurchaseOrdersDB = Self() - 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 + static func live(database db: any Database) -> Self { + .init( + create: { model, createdById in + 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 PurchaseOrder.get(purchaseOrder.requireID(), on: db) else { + return purchaseOrder.toDTO() + } + return loaded + + }, + fetchAll: { + try await PurchaseOrder.allQuery(on: db) + .sort(\.$id, .descending) + .all().map { $0.toDTO() } + }, + fetchPage: { request in + try await PurchaseOrder.allQuery(on: db) + .sort(\.$id, .descending) + .paginate(request) + .map { $0.toDTO() } + }, + get: { id in + try await PurchaseOrder.get(id, on: db) + }, + delete: { id in + guard let purchaseOrder = try await PurchaseOrder.find(id, on: db) else { + throw Abort(.notFound) + } + try await purchaseOrder.delete(on: db) + } + ) } - 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 { @@ -62,4 +78,10 @@ private extension PurchaseOrder { branch.with(\.$vendor) } } + + static func get(_ id: PurchaseOrder.IDValue, on db: any Database) async throws -> PurchaseOrder.DTO? { + try await PurchaseOrder.allQuery(on: db) + .filter(\.$id == id) + .first()?.toDTO() + } } diff --git a/Sources/App/Controllers/DB/UserDB.swift b/Sources/App/Controllers/DB/UserDB.swift index 1048d58..9233663 100644 --- a/Sources/App/Controllers/DB/UserDB.swift +++ b/Sources/App/Controllers/DB/UserDB.swift @@ -1,36 +1,56 @@ +import Dependencies +import DependenciesMacros import Fluent import Vapor -struct UserDB { - - func create(_ model: User.Create, on db: any Database) async throws -> User.DTO { - guard model.password == model.confirmPassword else { - throw Abort(.badRequest, reason: "Passwords did not match.") - } - let user = try User( - username: model.username, - email: model.email, - passwordHash: Bcrypt.hash(model.password) - ) - try await user.save(on: db) - return user.toDTO() +extension DependencyValues { + var users: UserDB { + get { self[UserDB.self] } + set { self[UserDB.self] = newValue } + } +} + +@DependencyClient +struct UserDB: Sendable { + var create: @Sendable (User.Create) async throws -> User.DTO + var delete: @Sendable (User.IDValue) async throws -> Void + var fetchAll: @Sendable () async throws -> [User.DTO] + var login: @Sendable (User) async throws -> UserToken +} + +extension UserDB: TestDependencyKey { + static let testValue: UserDB = Self() + + static func live(database db: any Database) -> Self { + self.init( + create: { model in + guard model.password == model.confirmPassword else { + throw Abort(.badRequest, reason: "Passwords did not match.") + } + let user = try User( + username: model.username, + email: model.email, + passwordHash: Bcrypt.hash(model.password) + ) + try await user.save(on: db) + return user.toDTO() + + }, + delete: { id in + guard let user = try await User.find(id, on: db) else { + throw Abort(.notFound) + } + try await user.delete(on: db) + + }, + fetchAll: { + try await User.query(on: db).all().map { $0.toDTO() } + }, + login: { user in + let token = try user.generateToken() + try await token.save(on: db) + return token + } + ) } - - func login(user: User, on db: any Database) async throws -> UserToken { - let token = try user.generateToken() - try await token.save(on: db) - return token - } - - func fetchAll(on db: any Database) async throws -> [User.DTO] { - try await User.query(on: db).all().map { $0.toDTO() } - } - - func delete(id: User.IDValue, on db: any Database) async throws { - guard let user = try await User.find(id, on: db) else { - throw Abort(.notFound) - } - try await user.delete(on: db) - } - } diff --git a/Sources/App/Controllers/DB/VendorBranchDB.swift b/Sources/App/Controllers/DB/VendorBranchDB.swift index 4943c57..cd217f3 100644 --- a/Sources/App/Controllers/DB/VendorBranchDB.swift +++ b/Sources/App/Controllers/DB/VendorBranchDB.swift @@ -1,62 +1,80 @@ +import Dependencies +import DependenciesMacros import Fluent import Vapor -struct VendorBranchDB { - - func create( - _ model: VendorBranch.Create, - for vendorID: Vendor.IDValue, - on db: any Database - ) async throws -> VendorBranch.DTO { - let branch = model.toModel() - guard let vendor = try await Vendor.find(vendorID, on: db) else { - throw Abort(.badRequest, reason: "Vendor does not exist.") - } - try await vendor.$branches.create(branch, on: db) - return branch.toDTO() - } - - func fetchAll(withVendor: Bool? = nil, on db: any Database) async throws -> [VendorBranch.DTO] { - var query = VendorBranch.query(on: db) - if withVendor == true { - query = query.with(\.$vendor) - } - return try await query.all().map { $0.toDTO() } - } - - func fetch(for vendorID: Vendor.IDValue, on db: any Database) async throws -> [VendorBranch.DTO] { - guard let vendor = try await Vendor.query(on: db) - .filter(\.$id == vendorID) - .with(\.$branches) - .first() - else { - throw Abort(.notFound) - } - - return vendor.branches.map { $0.toDTO() } - } - - func get(id: VendorBranch.IDValue, on db: any Database) async throws -> VendorBranch.DTO? { - try await VendorBranch.find(id, on: db).map { $0.toDTO() } - } - - func update( - id: VendorBranch.IDValue, - with updates: VendorBranch.Update, - on db: any Database - ) async throws -> VendorBranch.DTO { - guard let branch = try await VendorBranch.find(id, on: db) else { - throw Abort(.notFound) - } - branch.applyUpdates(updates) - try await branch.save(on: db) - return branch.toDTO() - } - - func delete(id: VendorBranch.IDValue, on db: any Database) async throws { - guard let branch = try await VendorBranch.find(id, on: db) else { - throw Abort(.notFound) - } - try await branch.delete(on: db) +public extension DependencyValues { + var vendorBranches: VendorBranchDB { + get { self[VendorBranchDB.self] } + set { self[VendorBranchDB.self] = newValue } + } +} + +@DependencyClient +public struct VendorBranchDB: Sendable { + var create: @Sendable (VendorBranch.Create, Vendor.IDValue) async throws -> VendorBranch.DTO + var delete: @Sendable (VendorBranch.IDValue) async throws -> Void + var fetchAll: @Sendable (Bool) async throws -> [VendorBranch.DTO] + var fetchForVendor: @Sendable (Vendor.IDValue) async throws -> [VendorBranch.DTO] + var get: @Sendable (VendorBranch.IDValue) async throws -> VendorBranch.DTO? + var update: @Sendable (VendorBranch.IDValue, VendorBranch.Update) async throws -> VendorBranch.DTO + + func fetchAll() async throws -> [VendorBranch.DTO] { + try await fetchAll(false) + } +} + +extension VendorBranchDB: TestDependencyKey { + public static let testValue: VendorBranchDB = Self() + + static func live(database db: any Database) -> Self { + .init( + create: { model, vendorID in + let branch = model.toModel() + guard let vendor = try await Vendor.find(vendorID, on: db) else { + throw Abort(.badRequest, reason: "Vendor does not exist.") + } + try await vendor.$branches.create(branch, on: db) + return branch.toDTO() + }, + delete: { id in + guard let branch = try await VendorBranch.find(id, on: db) else { + throw Abort(.notFound) + } + try await branch.delete(on: db) + }, + fetchAll: { withVendor in + var query = VendorBranch.query(on: db) + if withVendor == true { + query = query.with(\.$vendor) + } + return try await query.all().map { $0.toDTO() } + + }, + fetchForVendor: { vendorID in + guard let vendor = try await Vendor.query(on: db) + .filter(\.$id == vendorID) + .with(\.$branches) + .first() + else { + throw Abort(.notFound) + } + + return vendor.branches.map { $0.toDTO() } + + }, + get: { id in + + try await VendorBranch.find(id, on: db).map { $0.toDTO() } + }, + update: { id, updates in + guard let branch = try await VendorBranch.find(id, on: db) else { + throw Abort(.notFound) + } + branch.applyUpdates(updates) + try await branch.save(on: db) + return branch.toDTO() + } + ) } } diff --git a/Sources/App/Controllers/DB/VendorDB.swift b/Sources/App/Controllers/DB/VendorDB.swift index 7e74fda..2078574 100644 --- a/Sources/App/Controllers/DB/VendorDB.swift +++ b/Sources/App/Controllers/DB/VendorDB.swift @@ -1,47 +1,85 @@ +import Dependencies +import DependenciesMacros import Fluent import Vapor -struct VendorDB { - func create(_ model: Vendor.Create, on db: any Database) async throws -> Vendor.DTO { - let model = model.toModel() - try await model.save(on: db) - return model.toDTO() +public extension DependencyValues { + var vendors: VendorDB { + get { self[VendorDB.self] } + set { self[VendorDB.self] = newValue } + } +} + +@DependencyClient +public struct VendorDB: Sendable { + var create: @Sendable (Vendor.Create) async throws -> Vendor.DTO + var delete: @Sendable (Vendor.IDValue) async throws -> Void + var fetchAll: @Sendable (FetchRequest) async throws -> [Vendor.DTO] + var get: @Sendable (Vendor.IDValue, GetRequest) async throws -> Vendor.DTO? + var update: @Sendable (Vendor.IDValue, Vendor.Update) async throws -> Vendor.DTO + + enum FetchRequest { + case `default` + case withBranches + } + + enum GetRequest { + case `default` + case withBranches + } + + func fetchAll() async throws -> [Vendor.DTO] { + try await fetchAll(.default) + } + + func get(_ id: Vendor.IDValue) async throws -> Vendor.DTO? { + try await get(id, .default) + } +} + +extension VendorDB: TestDependencyKey { + public static let testValue: VendorDB = Self() + + static func live(database db: any Database) -> Self { + .init( + create: { model in + let model = model.toModel() + try await model.save(on: db) + return model.toDTO() + + }, + delete: { id in + guard let vendor = try await Vendor.find(id, on: db) else { + throw Abort(.notFound) + } + try await vendor.delete(on: db) + + }, + fetchAll: { request in + var query = Vendor.query(on: db).sort(\.$name, .ascending) + let withBranches = request == .withBranches + if withBranches { + query = query.with(\.$branches) + } + return try await query.all().map { $0.toDTO(includeBranches: withBranches) } + + }, + get: { id, request in + var query = Vendor.query(on: db).filter(\.$id == id) + let withBranches = request == .withBranches + if withBranches { + query = query.with(\.$branches) + } + return try await query.first().map { $0.toDTO(includeBranches: withBranches) } + + }, + update: { id, updates in + guard let vendor = try await Vendor.find(id, on: db) else { + throw Abort(.notFound) + } + vendor.applyUpdates(updates) + return vendor.toDTO() + } + ) } - - func fetchAll(withBranches: Bool? = nil, on db: any Database) async throws -> [Vendor.DTO] { - var query = Vendor.query(on: db).sort(\.$name, .ascending) - if withBranches == true { - query = query.with(\.$branches) - } - return try await query.all().map { $0.toDTO(includeBranches: withBranches) } - } - - func get(id: Vendor.IDValue, withBranches: Bool? = nil, on db: any Database) async throws -> Vendor.DTO? { - var query = Vendor.query(on: db).filter(\.$id == id) - - if withBranches == true { - query = query.with(\.$branches) - } - return try await query.first().map { $0.toDTO(includeBranches: withBranches) } - } - - func update( - id: Vendor.IDValue, - with updates: Vendor.Update, - on db: any Database - ) async throws -> Vendor.DTO { - guard let vendor = try await Vendor.find(id, on: db) else { - throw Abort(.notFound) - } - vendor.applyUpdates(updates) - return vendor.toDTO() - } - - func delete(id: Vendor.IDValue, on db: any Database) async throws { - guard let vendor = try await Vendor.find(id, on: db) else { - throw Abort(.notFound) - } - try await vendor.delete(on: db) - } - } diff --git a/Sources/App/Controllers/View/EmployeeViewController.swift b/Sources/App/Controllers/View/EmployeeViewController.swift index 2f680ba..9b7b3fe 100644 --- a/Sources/App/Controllers/View/EmployeeViewController.swift +++ b/Sources/App/Controllers/View/EmployeeViewController.swift @@ -23,7 +23,7 @@ struct EmployeeViewController: RouteCollection { @Sendable func index(req: Request) async throws -> View { - return try await req.view.render("employees/index", EmployeesCTX()) + return try await req.view.render("employees/index", EmployeesCTX(db: employees)) } @Sendable @@ -31,7 +31,7 @@ struct EmployeeViewController: RouteCollection { try Employee.Create.validate(content: req) let model = try req.content.decode(Employee.Create.self) _ = try await employees.create(model) - return try await req.view.render("employees/index", EmployeesCTX(oob: true)) + return try await req.view.render("employees/index", EmployeesCTX(oob: true, db: employees)) } @Sendable @@ -63,7 +63,7 @@ struct EmployeeViewController: RouteCollection { @Sendable func update(req: Request) async throws -> View { _ = try await api.update(req: req) - return try await req.view.render("employees/index", EmployeesCTX(oob: true)) + return try await req.view.render("employees/index", EmployeesCTX(oob: true, db: employees)) } @Sendable @@ -80,11 +80,11 @@ private struct EmployeesCTX: Content { init( oob: Bool = false, - employee: Employee? = nil + employee: Employee? = nil, + db: EmployeeDB ) async throws { - @Dependency(\.employees) var employees self.oob = oob - self.employees = try await employees.fetchAll() + self.employees = try await db.fetchAll() self.form = .init(employee: employee.map { $0.toDTO() }) } } diff --git a/Sources/App/Controllers/View/PurchaseOrderViewController.swift b/Sources/App/Controllers/View/PurchaseOrderViewController.swift index 508a089..dd1e26c 100644 --- a/Sources/App/Controllers/View/PurchaseOrderViewController.swift +++ b/Sources/App/Controllers/View/PurchaseOrderViewController.swift @@ -1,11 +1,13 @@ +import Dependencies import Fluent import Vapor struct PurchaseOrderViewController: RouteCollection { + @Dependency(\.purchaseOrders) var purchaseOrders + private let employeesApi = EmployeeApiController() private let branches = VendorBranchDB() private let api = ApiController() - private let api2 = PurchaseOrderDB() func boot(routes: any RoutesBuilder) throws { let pos = routes.protected.grouped("purchase-orders") @@ -20,7 +22,9 @@ struct PurchaseOrderViewController: RouteCollection { @Sendable func index(req: Request) async throws -> View { let params = try? req.query.decode(PurchaseOrderIndex.self) - let purchaseOrdersPage = try await api2.fetchPage(params?.page ?? 1, limit: params?.limit ?? 50, on: req.db) + let purchaseOrdersPage = try await purchaseOrders.fetchPage( + .init(page: params?.page ?? 1, per: params?.limit ?? 50) + ) let branches = try await self.branches.getBranches(req: req) let employees = try await employeesApi.index(req: req) req.logger.debug("Branches: \(branches)") @@ -38,7 +42,7 @@ struct PurchaseOrderViewController: RouteCollection { guard let id = req.parameters.get("id", as: PurchaseOrder.IDValue.self) else { throw Abort(.badRequest, reason: "Id not supplied.") } - let purchaseOrder = try await api2.get(id: id, on: req.db) + let purchaseOrder = try await purchaseOrders.get(id) return try await req.view.render("purchaseOrders/detail", ["purchaseOrder": purchaseOrder]) } @@ -47,7 +51,7 @@ struct PurchaseOrderViewController: RouteCollection { try PurchaseOrder.FormCreate.validate(content: req) let createdById = try req.auth.require(User.self).requireID() let create = try req.content.decode(PurchaseOrder.FormCreate.self).toCreate() - let purchaseOrder = try await api2.create(create, createdById: createdById, on: req.db) + let purchaseOrder = try await purchaseOrders.create(create, createdById) return try await req.view.render("purchaseOrders/table-row", purchaseOrder) } } diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 5b1e77b..4788530 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -34,6 +34,10 @@ public func configure(_ app: Application) async throws { try withDependencies { $0.employees = .live(database: app.db(.sqlite)) + $0.purchaseOrders = .live(database: app.db(.sqlite)) + $0.users = .live(database: app.db(.sqlite)) + $0.vendorBranches = .live(database: app.db(.sqlite)) + $0.vendors = .live(database: app.db(.sqlite)) } operation: { // register routes try routes(app)