feat: Fixes release build failures and get's release dockerfile working.
This commit is contained in:
201
Sources/DatabaseClientLive/PurchaseOrders+live.swift
Normal file
201
Sources/DatabaseClientLive/PurchaseOrders+live.swift
Normal file
@@ -0,0 +1,201 @@
|
||||
import DatabaseClient
|
||||
import FluentKit
|
||||
import Foundation
|
||||
import SharedModels
|
||||
|
||||
public extension DatabaseClient.PurchaseOrders {
|
||||
|
||||
static func live(database: any Database) -> Self {
|
||||
.init { create in
|
||||
let model = try create.toModel()
|
||||
try await model.save(on: database)
|
||||
let fetched = try await PurchaseOrderModel.allQuery(on: database)
|
||||
.filter(\PurchaseOrderModel.$id == model.id!).first()!
|
||||
return try fetched.toDTO()
|
||||
} fetchAll: {
|
||||
try await PurchaseOrderModel.allQuery(on: database)
|
||||
.all()
|
||||
.map { try $0.toDTO() }
|
||||
} fetchPage: { request in
|
||||
try await PurchaseOrderModel.allQuery(on: database)
|
||||
.paginate(request)
|
||||
.map { try $0.toDTO() }
|
||||
} get: { id in
|
||||
try await PurchaseOrderModel.allQuery(on: database)
|
||||
.filter(\PurchaseOrderModel.$id == id)
|
||||
.first()
|
||||
.map { try $0.toDTO() }
|
||||
} delete: { id in
|
||||
guard let model = try await PurchaseOrderModel.find(id, on: database) else {
|
||||
throw NotFoundError()
|
||||
}
|
||||
try await model.delete(on: database)
|
||||
} search: { search, page in
|
||||
let query = PurchaseOrderModel.allQuery(on: database)
|
||||
|
||||
switch search {
|
||||
case let .employee(id):
|
||||
return try await query.filter(\PurchaseOrderModel.$createdFor.$id == id)
|
||||
.paginate(page)
|
||||
.map { try $0.toDTO() }
|
||||
|
||||
case let .customer(search):
|
||||
return try await query.filter(\PurchaseOrderModel.$customer ~~ search)
|
||||
.paginate(page)
|
||||
.map { try $0.toDTO() }
|
||||
|
||||
case let .vendor(id):
|
||||
return try await query.filter(\PurchaseOrderModel.$vendorBranch.$id == id)
|
||||
.paginate(page)
|
||||
.map { try $0.toDTO() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension Page where T == PurchaseOrder {
|
||||
static var empty: Self {
|
||||
.init(items: [], metadata: .init(page: 1, per: 1, total: 0))
|
||||
}
|
||||
}
|
||||
|
||||
extension PurchaseOrder {
|
||||
struct Migrate: AsyncMigration {
|
||||
|
||||
let name = "CreatePurchaseOrder"
|
||||
|
||||
func prepare(on database: any Database) async throws {
|
||||
try await database.schema(PurchaseOrderModel.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(UserModel.schema, "id"))
|
||||
.field("created_for_id", .uuid, .required, .references(EmployeeModel.schema, "id"))
|
||||
.field("vendor_branch_id", .uuid, .required, .references(VendorBranchModel.schema, "id"))
|
||||
.field("created_at", .datetime)
|
||||
.field("updated_at", .datetime)
|
||||
.create()
|
||||
}
|
||||
|
||||
func revert(on database: any Database) async throws {
|
||||
try await database.schema(PurchaseOrderModel.schema).delete()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension PurchaseOrder.Create {
|
||||
|
||||
func toModel() throws -> PurchaseOrderModel {
|
||||
try validate()
|
||||
return .init(
|
||||
materials: materials,
|
||||
customer: customer,
|
||||
truckStock: truckStock ?? false,
|
||||
createdByID: createdByID,
|
||||
createdForID: createdForID,
|
||||
vendorBranchID: vendorBranchID
|
||||
)
|
||||
}
|
||||
|
||||
func validate() throws {
|
||||
guard !materials.isEmpty else {
|
||||
throw ValidationError(message: "Materials should not be empty.")
|
||||
}
|
||||
guard !customer.isEmpty else {
|
||||
throw ValidationError(message: "Customer should not be empty.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 PurchaseOrderModel: Model, Codable, @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: UserModel
|
||||
|
||||
@Parent(key: "created_for_id")
|
||||
var createdFor: EmployeeModel
|
||||
|
||||
@Parent(key: "vendor_branch_id")
|
||||
var vendorBranch: VendorBranchModel
|
||||
|
||||
@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: UserModel.IDValue,
|
||||
createdForID: EmployeeModel.IDValue,
|
||||
vendorBranchID: VendorBranchModel.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() throws -> PurchaseOrder {
|
||||
try .init(
|
||||
id: requireID(),
|
||||
workOrder: workOrder,
|
||||
materials: materials,
|
||||
customer: customer,
|
||||
truckStock: truckStock,
|
||||
createdBy: createdBy.toDTO(),
|
||||
createdFor: createdFor.toDTO(),
|
||||
vendorBranch: vendorBranch.toDetail(),
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt
|
||||
)
|
||||
}
|
||||
|
||||
static func allQuery(on db: any Database) -> QueryBuilder<PurchaseOrderModel> {
|
||||
PurchaseOrderModel.query(on: db)
|
||||
.sort(\PurchaseOrderModel.$id, .descending)
|
||||
.with(\PurchaseOrderModel.$createdBy)
|
||||
.with(\PurchaseOrderModel.$createdFor)
|
||||
.with(\PurchaseOrderModel.$vendorBranch) { branch in
|
||||
branch.with(\VendorBranchModel.$vendor)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user