From e1d679bf0352357e090cfc32e3540d5aa7435b1b Mon Sep 17 00:00:00 2001 From: Mike Carman Date: Thu, 17 Apr 2025 11:42:28 -0400 Subject: [PATCH] Fueling service changes per Andy added startdate and enddate perameter as well as previous parameter --- .../UserInterfaceState.xcuserstate | Bin 41646 -> 53622 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 62 ----- .../Controllers/FuelEntryV2Controller.swift | 245 +++++++++++------- Sources/App/Migrations/CreateFuelEntry.swift | 16 ++ Sources/App/Models/FuelEntry.swift | 50 ++++ Sources/App/configure.swift | 3 +- 6 files changed, 217 insertions(+), 159 deletions(-) diff --git a/.swiftpm/xcode/package.xcworkspace/xcuserdata/mcarman.xcuserdatad/UserInterfaceState.xcuserstate b/.swiftpm/xcode/package.xcworkspace/xcuserdata/mcarman.xcuserdatad/UserInterfaceState.xcuserstate index b0a30050ea0b594a3f9afd11ce6d8da71804e10f..135f485e06c630a4ea99cd89bfdbc3220b9cc565 100644 GIT binary patch literal 53622 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 SKS%D1{(s;ZECGy3`HkKK5~TFZ%?1?xUF9*^k-j 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 z%0A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 - - - - - - - - - - - - - - diff --git a/Sources/App/Controllers/FuelEntryV2Controller.swift b/Sources/App/Controllers/FuelEntryV2Controller.swift index 4ab233f..2fa8b85 100644 --- a/Sources/App/Controllers/FuelEntryV2Controller.swift +++ b/Sources/App/Controllers/FuelEntryV2Controller.swift @@ -16,10 +16,10 @@ struct FuelEntryV2Controller: RouteCollection { let tokenAuthGroup = fuelEntries.grouped(tokenAuthMiddleware, guardMiddleware) tokenAuthGroup.get(use: index) tokenAuthGroup.get("test", use: filtered) -// fuelEntries.get("with-images", use: getAllEntriesWithImages) + tokenAuthGroup.get("rpm", use: rpm) + tokenAuthGroup.get("maxim", use: filtered) tokenAuthGroup.post(use: create) tokenAuthGroup.put( use: softdelete) -// fuelEntries.post("upload-image", use: uploadImage) tokenAuthGroup.group(":fuelEntryID") { fuelEntry in fuelEntry.delete(use: delete) } @@ -55,28 +55,134 @@ struct FuelEntryV2Controller: RouteCollection { return response } + fileprivate func parseDate(_ dateString: String, _ start: Bool = true) -> Date? { + if(dateString.count == 0){ + return nil + } else { + let parts = dateString.split(separator: "-") + let year = Int(parts[0])! + let month = Int(parts[1])! + let day = Int(parts[2])! + var dateComponents = DateComponents() + dateComponents.year = year + dateComponents.month = month + dateComponents.day = day + if(start) { + dateComponents.hour = 0 + dateComponents.minute = 0 + dateComponents.second = 0 + } else { + dateComponents.hour = 23 + dateComponents.minute = 59 + dateComponents.second = 59 + } + let calendar = Calendar(identifier: .gregorian) + return calendar.date(from: dateComponents) + } + } + @Sendable func filtered(req: Request) async throws -> Response { - - var image: Bool - var serial: String - var tank: String let qstring = req.query - if let qimage = try? qstring.get(Bool.self, at: "image"){ - image = qimage + let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "") + let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false) + let image = try qstring.get(Bool?.self, at: "image") ?? false + let serial = try qstring.get(String?.self, at: "serial") ?? nil + let tank = try qstring.get(String?.self, at: "tank") ?? nil + let previous = try qstring.get(Bool?.self, at: "previous") ?? false + + + var query = FuelEntry.query(on: req.db) + if(image){ + query = query + .field(\.$id) + .field(\.$timestamp) + .field(\.$userID) + .field(\.$product) + .field(\.$make) + .field(\.$model) + .field(\.$serialNumber) + .field(\.$tankID) + .field(\.$fuelAmount) + .field(\.$fuelType) + .field(\.$isOverride) + .field(\.$latitude) + .field(\.$longitude) + .field(\.$image) + .field(\.$downloaded) + .field(\.$loaddate) + //.filter(\.$image != nil) + } else { - image = false + query = query + .field(\.$id) + .field(\.$timestamp) + .field(\.$userID) + .field(\.$product) + .field(\.$make) + .field(\.$model) + .field(\.$serialNumber) + .field(\.$tankID) + .field(\.$fuelAmount) + .field(\.$fuelType) + .field(\.$isOverride) + .field(\.$latitude) + .field(\.$longitude) + .field(\.$downloaded) + .field(\.$loaddate) } - if let qserial = try? qstring.get(String.self, at: "serial"){ - serial = qserial - } else { - serial = "" + + query = query.group(.and){ + grp in + if( startdate != nil) { + grp.filter(\.$loaddate >= startdate!) + } + if( enddate != nil) { + grp.filter(\.$loaddate <= enddate!) + } + if( serial != nil) { + grp.filter(\.$serialNumber == serial!) + } + if( tank != nil) { + grp.filter(\.$tankID == tank!) + } + if(!previous){ + grp.filter(\.$pulldate == nil) + } + } - if let qtank = try? qstring.get(String.self, at: "tank"){ - tank = qtank + query = query.sort(\.$loaddate, .ascending) + + if(image){ + //query = query.filter(\.$image) + let wimage = try await query.paginate(for: req).map{ + img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, image: img.image == nil ? Data(): img.image, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date()) + } + wimage.items.forEach{ + _ = $0.toFuelEntry().save(on: req.db) + } + return try await wimage.encodeResponse(for: req) } else { - tank = "" + let woimage = try await query.paginate(for: req).map{ + img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date()) + } + woimage.items.forEach { + _ = $0.toFuelEntry().save(on: req.db) + } + return try await woimage.encodeResponse(for: req) } + } + + @Sendable + func rpm(req: Request) async throws -> Response { + let qstring = req.query + let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "") + let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false) + let image = try qstring.get(Bool?.self, at: "image") ?? false + let serial = try qstring.get(String?.self, at: "serial") ?? nil + let tank = try qstring.get(String?.self, at: "tank") ?? nil + let previous = try qstring.get(Bool?.self, at: "previous") ?? false + var query = FuelEntry.query(on: req.db) if(image){ @@ -96,6 +202,7 @@ struct FuelEntryV2Controller: RouteCollection { .field(\.$longitude) .field(\.$image) .field(\.$downloaded) + .field(\.$loaddate) //.filter(\.$image != nil) } else { @@ -114,44 +221,45 @@ struct FuelEntryV2Controller: RouteCollection { .field(\.$latitude) .field(\.$longitude) .field(\.$downloaded) + .field(\.$loaddate) } - if(serial.count > 0){ - query = query - .filter(\.$serialNumber == serial) - } - if(tank.count > 0){ - query = query - .filter(\.$tankID == tank) + + query = query.group(.and){ + grp in + if( startdate != nil) { + grp.filter(\.$loaddate >= startdate!) + } + if( enddate != nil) { + grp.filter(\.$loaddate <= enddate!) + } + if( serial != nil) { + grp.filter(\.$serialNumber == serial!) + } + if( tank != nil) { + grp.filter(\.$tankID == tank!) + } + if(!previous){ + grp.filter(\.$pulldate == nil) + } + } + query = query.sort(\.$loaddate, .ascending).sort(\.$timestamp).sort(\.$serialNumber) + if(image){ //query = query.filter(\.$image) let wimage = try await query.paginate(for: req).map{ - img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, image: img.image == nil ? Data(): img.image, downloaded: img.downloaded == nil ? false : img.downloaded!) + img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, image: img.image == nil ? Data(): img.image, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date()) } return try await wimage.encodeResponse(for: req) } else { let woimage = try await query.paginate(for: req).map{ - img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!) + img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitutde: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date()) } return try await woimage.encodeResponse(for: req) } -// let result = try await query.paginate(for: req) -// return try await result.encodeResponse(for: req) } -// func getAllEntriesWithImages(req: Request) async throws -> [FuelEntry] { -// let fuelEntries = try await FuelEntry.query(on: req.db).all() -// -// for var fuelEntry in fuelEntries { -// if let imagePath = fuelEntry.image { -// let fileURL = URL(fileURLWithPath: imagePath) -// if let imageData = try? Data(contentsOf: fileURL) { -// fuelEntry.imageData = imageData -// } -// } -// } -// return fuelEntries -// } + func create(req: Request) async throws -> [FuelEntry] { let fuelEntry = try req.content.decode([FuelEntry].self) @@ -159,37 +267,7 @@ struct FuelEntryV2Controller: RouteCollection { return fuelEntry } - //Create with image file written to server storage instead of database -// func create(req: Request) async throws -> [FuelEntry] { -// let fuelEntries = try await req.content.decode([FuelEntry].self) -// let directory = DirectoryConfiguration.detect().workingDirectory + "Images/" -// -// var updatedFuelEntries: [FuelEntry] = [] -// -// for fuelEntry in fuelEntries { -// let updatedFuelEntry = try await { () async throws -> FuelEntry in -// var updatedFuelEntry = fuelEntry -// -// if let imageData = updatedFuelEntry.imageData { -// let imageFilename = "\(updatedFuelEntry.id!).png" -// let tempImageURL = URL(fileURLWithPath: directory + imageFilename) -// try await imageData.write(to: tempImageURL) -// updatedFuelEntry.image = tempImageURL.absoluteString -// } -// -// do { -// _ = try await updatedFuelEntry.save(on: req.db) -// return updatedFuelEntry -// } catch { -// throw Abort(.internalServerError, reason: "Error saving FuelEntry: \(error)") -// } -// }() -// -// updatedFuelEntries.append(updatedFuelEntry) -// } -// -// return updatedFuelEntries -// } + func delete(req: Request) async throws -> HTTPStatus { guard let fuelEntry = try await FuelEntry.find(req.parameters.get("fuelEntryID"), on: req.db) else { @@ -198,31 +276,6 @@ struct FuelEntryV2Controller: RouteCollection { try await fuelEntry.delete(on: req.db) return .noContent } - -// func uploadImage(req: Request) async throws -> FuelEntry { -// let fuelEntryID: UUID = try req.parameters.require("id") -// -// let file = try await req.content.decode(File.self) -// let filename = fuelEntryID.uuidString + ".png" // Generate a unique filename for the uploaded image -// let directory = DirectoryConfiguration.detect().workingDirectory + "Images/" -// -// if let imageData = file.data.getData(at: 0, length: file.data.readableBytes) { -// do { -// try Data(imageData).write(to: URL(fileURLWithPath: directory + filename)) // Save the uploaded image to server -// } catch { -// throw Abort(.internalServerError, reason: "Failed to save image file") -// } -// -// // Update FuelEntry model after saving the image -// if let fuelEntry = try await FuelEntry.find(fuelEntryID, on: req.db) { -// return fuelEntry -// } else { -// throw Abort(.notFound, reason: "FuelEntry not found") -// } -// } else { -// throw Abort(.badRequest, reason: "Failed to extract image data") -// } -// } } struct PageRequest: Content { diff --git a/Sources/App/Migrations/CreateFuelEntry.swift b/Sources/App/Migrations/CreateFuelEntry.swift index 197121d..591435d 100755 --- a/Sources/App/Migrations/CreateFuelEntry.swift +++ b/Sources/App/Migrations/CreateFuelEntry.swift @@ -96,3 +96,19 @@ struct AddDownloadedBool: AsyncMigration { } } +struct AddLoadDateAndPullDate: AsyncMigration { + func prepare(on database: Database) async throws { + try await database.schema("fuel_entries") + .field("loadDate", .datetime) + .field("pullDate", .datetime) + .update() + } + + func revert(on database: Database) async throws { + try await database.schema("fuel_entries") + .deleteField("loadDate") + .deleteField("pullDate") + .update() + } +} + diff --git a/Sources/App/Models/FuelEntry.swift b/Sources/App/Models/FuelEntry.swift index 507dce0..12ff4c9 100755 --- a/Sources/App/Models/FuelEntry.swift +++ b/Sources/App/Models/FuelEntry.swift @@ -26,6 +26,29 @@ final class FuelEntry: Model, Content { let fuelType: String let isOverride: Bool let downloaded: Bool? + let loaddate: Date? + let pulldate: Date? + func toFuelEntry() -> FuelEntry { + var entry = FuelEntry() + entry.id = self.id + entry.timestamp = self.timestamp + entry.userID = self.userID + entry.latitude = self.latitude + entry.longitude = self.longitutde + entry.product = self.product + entry.make = self.make + entry.model = self.model + entry.serialNumber = self.serialNumber + entry.tankID = self.tankID + entry.fuelAmount = self.fuelAmount + entry.fuelType = self.fuelType + entry.isOverride = self.isOverride + entry.downloaded = self.downloaded + entry.loaddate = self.loaddate + entry.pulldate = self.pulldate + entry._$idExists = self.id == nil ? false : true + return entry + } } struct wimage: Content{ @@ -44,6 +67,30 @@ final class FuelEntry: Model, Content { let isOverride: Bool let image: Data? let downloaded: Bool? + let loaddate: Date? + let pulldate: Date? + func toFuelEntry() -> FuelEntry { + var entry = FuelEntry() + entry.id = self.id + entry.timestamp = self.timestamp + entry.userID = self.userID + entry.latitude = self.latitude + entry.longitude = self.longitutde + entry.product = self.product + entry.make = self.make + entry.model = self.model + entry.serialNumber = self.serialNumber + entry.tankID = self.tankID + entry.fuelAmount = self.fuelAmount + entry.fuelType = self.fuelType + entry.isOverride = self.isOverride + entry.image = self.image + entry.downloaded = self.downloaded + entry.loaddate = self.loaddate + entry.pulldate = self.pulldate + entry._$idExists = self.id == nil ? false : true + return entry + } } @ID(key: .id) @@ -91,6 +138,9 @@ final class FuelEntry: Model, Content { @Field(key: "downloaded") var downloaded: Bool? + @Timestamp(key: "loadDate", on: .create) var loaddate: Date? + @Timestamp(key: "pullDate", on: .none) var pulldate: Date? + // var imageData: Data? init() {} diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 9946914..ffaf095 100755 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -10,7 +10,7 @@ public func configure(_ app: Application) async throws { app.routes.defaultMaxBodySize = "128mb" // let timeout = HTTPClient.Configuration.Timeout(connect: .seconds(300), read: .seconds(300)) // app.http.client.configuration.timeout = timeout - app.databases.use(.postgres(hostname: "127.0.0.1", port: 5432, username: "mcarman", password: "@ng31F@rm0823262", database: "fueling"), as: .psql) + app.databases.use(.postgres(hostname: "127.0.0.1", port: 5433, username: "mcarman", password: "@ng31F@rm0823262", database: "fueling"), as: .psql) // app.databases.use(DatabaseConfigurationFactory.postgres(configuration: .init( // hostname: Environment.get("DATABASE_HOST") ?? "localhost", // port: Environment.get("DATABASE_PORT").flatMap(Int.init(_:)) ?? 5433, @@ -31,6 +31,7 @@ public func configure(_ app: Application) async throws { app.migrations.add(UpdateTokens1()) app.migrations.add(UpdateUser2_AddTokenfield()) app.migrations.add(UpdateUser3_RemoveTokenfield()) + app.migrations.add(AddLoadDateAndPullDate()) try await app.autoMigrate().get() // register routes