feat: Initial purchase order views, login seems to be broken though.
This commit is contained in:
@@ -1,196 +1,103 @@
|
||||
// import Dependencies
|
||||
// import Fluent
|
||||
// import Vapor
|
||||
//
|
||||
// struct PurchaseOrderViewController: RouteCollection {
|
||||
// @Dependency(\.employees) var employees
|
||||
// @Dependency(\.purchaseOrders) var purchaseOrders
|
||||
// @Dependency(\.vendorBranches) var vendorBranches
|
||||
//
|
||||
// func boot(routes: any RoutesBuilder) throws {
|
||||
// let pos = routes.protected.grouped("purchase-orders")
|
||||
//
|
||||
// pos.get(use: index(req:))
|
||||
// pos.group("details", "close") {
|
||||
// $0.get(use: detailClose(req:))
|
||||
// }
|
||||
// pos.post(use: create(req:))
|
||||
// pos.group(":id") {
|
||||
// $0.get(use: detail(req:))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Sendable
|
||||
// func index(req: Request) async throws -> View {
|
||||
// let params = try? req.query.decode(PurchaseOrderIndex.self)
|
||||
// let purchaseOrdersPage = try await purchaseOrders.fetchPage(
|
||||
// .init(page: params?.page ?? 1, per: params?.limit ?? 50)
|
||||
// )
|
||||
// let branches = try await vendorBranches.getBranches(req: req)
|
||||
// let employees = try await employees.fetchAll()
|
||||
// req.logger.debug("Branches: \(branches)")
|
||||
// return try await req.view.render(
|
||||
// "purchaseOrders/index",
|
||||
// PurchaseOrderCTX(
|
||||
// page: purchaseOrdersPage,
|
||||
// form: .create(branches: branches, employees: employees)
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// @Sendable
|
||||
// func detail(req: Request) async throws -> View {
|
||||
// guard let id = req.parameters.get("id", as: PurchaseOrder.IDValue.self) else {
|
||||
// throw Abort(.badRequest, reason: "Id not supplied.")
|
||||
// }
|
||||
// let purchaseOrder = try await purchaseOrders.get(id)
|
||||
// return try await req.view.render("purchaseOrders/detail", ["purchaseOrderDetail": purchaseOrder])
|
||||
// }
|
||||
//
|
||||
// @Sendable
|
||||
// func detailClose(req: Request) async throws -> View {
|
||||
// return try await req.view.render("purchaseOrders/detail")
|
||||
// }
|
||||
//
|
||||
// @Sendable
|
||||
// func create(req: Request) async throws -> View {
|
||||
// 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 purchaseOrders.create(create, createdById)
|
||||
// return try await req.view.render("purchaseOrders/table-row", purchaseOrder)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private struct PurchaseOrderIndex: Content {
|
||||
// let page: Int?
|
||||
// let limit: Int?
|
||||
// }
|
||||
//
|
||||
// private struct PurchaseOrderCTX: Content {
|
||||
// let purchaseOrderDetail: PurchaseOrder.DTO?
|
||||
// let purchaseOrders: [PurchaseOrder.DTO]
|
||||
// let page: Int
|
||||
// let limit: Int
|
||||
// let hasNext: Bool
|
||||
// let hasPrevious: Bool
|
||||
// let form: PurchaseOrderFormCTX?
|
||||
//
|
||||
// init(
|
||||
// detail: PurchaseOrder.DTO? = nil,
|
||||
// page: Page<PurchaseOrder.DTO>,
|
||||
// form: PurchaseOrderFormCTX?
|
||||
// ) {
|
||||
// self.purchaseOrderDetail = detail
|
||||
// self.purchaseOrders = page.items
|
||||
// self.page = page.metadata.page
|
||||
// self.limit = page.metadata.per
|
||||
// self.hasNext = page.metadata.hasNext
|
||||
// self.hasPrevious = page.metadata.page > 1
|
||||
// self.form = form
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private extension PageMetadata {
|
||||
// var hasNext: Bool {
|
||||
// total > (page * per)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private struct PurchaseOrderFormCTX: Content {
|
||||
//
|
||||
// let htmxForm: HtmxFormCTX<Context>
|
||||
//
|
||||
// struct Context: Content {
|
||||
// let branches: [VendorBranch.FormDTO]
|
||||
// let employees: [Employee.DTO]
|
||||
// }
|
||||
//
|
||||
// static func create(branches: [VendorBranch.FormDTO], employees: [Employee.DTO]) -> Self {
|
||||
// .init(htmxForm: .init(
|
||||
// formClass: "po-form",
|
||||
// formId: "po-form",
|
||||
// htmxTargetUrl: .post("/purchase-orders"),
|
||||
// htmxTarget: "#po-table-body",
|
||||
// htmxPushUrl: false,
|
||||
// htmxResetAfterRequest: true,
|
||||
// htmxSwapOob: nil,
|
||||
// htmxSwap: .afterbegin,
|
||||
// context: .init(branches: branches, employees: employees)
|
||||
// ))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension VendorBranch {
|
||||
// struct FormDTO: Content {
|
||||
// let id: UUID
|
||||
// let name: String
|
||||
// let vendor: Vendor.DTO
|
||||
// }
|
||||
//
|
||||
// func toFormDTO() throws -> VendorBranch.FormDTO {
|
||||
// try .init(
|
||||
// id: requireID(),
|
||||
// name: name,
|
||||
// vendor: vendor.toDTO()
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private extension PurchaseOrder {
|
||||
// struct FormCreate: Content {
|
||||
// let id: Int?
|
||||
// let workOrder: String?
|
||||
// let materials: String
|
||||
// let customer: String
|
||||
// let truckStock: Bool?
|
||||
// let createdForID: Employee.IDValue
|
||||
// let vendorBranchID: VendorBranch.IDValue
|
||||
//
|
||||
// // TODO: Remove.
|
||||
// func toModel(createdByID: User.IDValue) -> PurchaseOrder {
|
||||
// .init(
|
||||
// id: id,
|
||||
// workOrder: workOrder != nil ? (workOrder == "" ? nil : Int(workOrder!)) : nil,
|
||||
// materials: materials,
|
||||
// customer: customer,
|
||||
// truckStock: truckStock ?? false,
|
||||
// createdByID: createdByID,
|
||||
// createdForID: createdForID,
|
||||
// vendorBranchID: vendorBranchID,
|
||||
// createdAt: nil,
|
||||
// updatedAt: nil
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// func toCreate() -> PurchaseOrder.Create {
|
||||
// .init(
|
||||
// id: id,
|
||||
// workOrder: workOrder != nil ? (workOrder == "" ? nil : Int(workOrder!)) : nil,
|
||||
// materials: materials,
|
||||
// customer: customer,
|
||||
// truckStock: truckStock,
|
||||
// createdForID: createdForID,
|
||||
// vendorBranchID: vendorBranchID
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private extension VendorBranchDB {
|
||||
//
|
||||
// func getBranches(req: Request) async throws -> [VendorBranch.FormDTO] {
|
||||
// try await VendorBranch.query(on: req.db)
|
||||
// .with(\.$vendor)
|
||||
// .all()
|
||||
// .map { try $0.toFormDTO() }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// extension PurchaseOrder.FormCreate: Validatable {
|
||||
//
|
||||
// static func validations(_ validations: inout Validations) {
|
||||
// validations.add("materials", as: String.self, is: !.empty)
|
||||
// validations.add("customer", as: String.self, is: !.empty)
|
||||
// }
|
||||
// }
|
||||
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<C: HTML>(
|
||||
_ 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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user