import Dependencies import Elementary import SharedModels import Vapor import VaporElementary struct PurchaseOrderViewController: RouteCollection { @Dependency(\.database.employees) var employees @Dependency(\.database.vendorBranches) var vendorBranches @Dependency(\.database.purchaseOrders) var purchaseOrders func boot(routes: any RoutesBuilder) throws { let route = routes.protected.grouped("purchase-orders") route.get(use: index) route.get("next", use: nextPage) route.post(use: create(req:)) route.group("create") { $0.get(use: form) $0.get("vendor-branch-select", use: vendorBranchSelect(req:)) $0.get("employee-select", use: employeeSelect(req:)) } route.group(":id") { $0.get(use: get) } } @Sendable func index(req: Request) async throws -> HTMLResponse { let page = try? req.query.decode(IndexQuery.self) return try await req.render { try await mainPage(PurchaseOrderForm(), page: page ?? .default) } } @Sendable func nextPage(req: Request) async throws -> HTMLResponse { let query = try req.query.decode(IndexQuery.self) let page = try await purchaseOrders.fetchPage(.init(page: query.page, per: query.limit)) return await req.render { PurchaseOrderTable.Rows(page: page) } } @Sendable func form(req: Request) async throws -> HTMLResponse { // guard req.isHtmxRequest else { // return try await req.render { // try await mainPage(PurchaseOrderForm(shouldShow: true), page: .default) // } // } return await req.render { PurchaseOrderForm(shouldShow: true) } } @Sendable func vendorBranchSelect(req: Request) async throws -> HTMLResponse { let branches = try await vendorBranches.fetchAllWithDetail() return await req.render { PurchaseOrderForm.VendorSelect(vendorBranches: branches) } } @Sendable func employeeSelect(req: Request) async throws -> HTMLResponse { let employees = try await self.employees.fetchAll() return await req.render { PurchaseOrderForm.EmployeeSelect(employees: employees) } } @Sendable func get(req: Request) async throws -> HTMLResponse { let purchaseOrder = try await purchaseOrders.get(req.ensureIDPathComponent(as: Int.self)) let form = PurchaseOrderForm(purchaseOrder: purchaseOrder, shouldShow: true) guard req.isHtmxRequest else { return try await req.render { try await mainPage(form, page: .default) } } return await req.render { form } } @Sendable func create(req: Request) async throws -> HTMLResponse { let create = try req.content.decode(PurchaseOrder.CreateIntermediate.self) let user = try req.auth.require(User.self) let purchaseOrder = try await purchaseOrders.create(create.toCreate(createdByID: user.id)) return await req.render { PurchaseOrderTable.Row(purchaseOrder: purchaseOrder) } } private func mainPage( _ html: C, page: IndexQuery ) async throws -> some SendableHTMLDocument where C: Sendable { let page = try await purchaseOrders.fetchPage(.init(page: page.page, per: page.limit)) return MainPage(displayNav: true, route: .purchaseOrders) { div(.class("container")) { html PurchaseOrderTable(page: page) } } } } struct IndexQuery: Content { let page: Int let limit: Int static var `default`: Self { .init(page: 1, limit: 25) } }