import Fluent import Vapor /// The purchase order database model. /// /// # NOTE: An initial purchase order should be created with an `id` higher than our current PO /// so that subsequent PO's are generated with higher values than our current system produces. /// once the first one is set, the rest will auto-increment from there. final class PurchaseOrder: Model, Content, @unchecked Sendable { static let schema = "purchase_order" @ID(custom: "id", generatedBy: .database) var id: Int? @Field(key: "work_order") var workOrder: Int? @Field(key: "materials") var materials: String @Field(key: "customer") var customer: String @Field(key: "truck_stock") var truckStock: Bool @Parent(key: "created_by_id") var createdBy: User @Parent(key: "created_for_id") var createdFor: Employee @Parent(key: "vendor_branch_id") var vendorBranch: VendorBranch @Timestamp(key: "created_at", on: .create) var createdAt: Date? @Timestamp(key: "updated_at", on: .update) var updatedAt: Date? init() {} init( id: Int? = nil, workOrder: Int? = nil, materials: String, customer: String, truckStock: Bool, createdByID: User.IDValue, createdForID: Employee.IDValue, vendorBranchID: VendorBranch.IDValue, createdAt: Date? = nil, updatedAt: Date? = nil ) { self.id = id self.workOrder = workOrder self.materials = materials self.customer = customer self.truckStock = truckStock $createdBy.id = createdByID $createdFor.id = createdForID $vendorBranch.id = vendorBranchID self.createdAt = createdAt self.updatedAt = updatedAt } func toDTO() -> DTO { .init( id: id, workOrder: workOrder, materials: materials, customer: customer, truckStock: truckStock, createdBy: $createdBy.value?.toDTO(), createdFor: $createdFor.value?.toDTO(), vendorBranch: $vendorBranch.value, createdAt: createdAt, updatedAt: updatedAt ) } } extension PurchaseOrder { struct Create: Content { let id: Int? let workOrder: Int? let materials: String let customer: String let truckStock: Bool? let createdForID: Employee.IDValue let vendorBranchID: VendorBranch.IDValue func toModel(createdByID: User.IDValue) -> PurchaseOrder { .init( id: id, workOrder: workOrder, materials: materials, customer: customer, truckStock: truckStock ?? false, createdByID: createdByID, createdForID: createdForID, vendorBranchID: vendorBranchID, createdAt: nil, updatedAt: nil ) } } struct DTO: Content { let id: Int? let workOrder: Int? let materials: String let customer: String let truckStock: Bool let createdBy: User.DTO? let createdFor: Employee.DTO? let vendorBranch: VendorBranch? let createdAt: Date? let updatedAt: Date? } struct Migrate: AsyncMigration { let name = "CreatePurchaseOrder" func prepare(on database: any Database) async throws { try await database.schema(PurchaseOrder.schema) .field("id", .int, .identifier(auto: true)) .field("work_order", .int) .field("customer", .string, .required) .field("materials", .string, .required) .field("truck_stock", .bool, .required) .field("created_by_id", .uuid, .required, .references(User.schema, "id")) .field("created_for_id", .uuid, .required, .references(Employee.schema, "id")) .field("vendor_branch_id", .uuid, .required, .references(VendorBranch.schema, "id")) .field("created_at", .datetime) .field("updated_at", .datetime) .create() } func revert(on database: any Database) async throws { try await database.schema(PurchaseOrder.schema).delete() } } } extension PurchaseOrder.Create: Validatable { static func validations(_ validations: inout Validations) { validations.add("materials", as: String.self, is: !.empty) validations.add("customer", as: String.self, is: !.empty) } }