Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

785 righe
34 KiB

  1. //
  2. // FuelEntryController.swift
  3. //
  4. //
  5. // Created by Bill Ryckman on 4/24/23.
  6. //
  7. import Vapor
  8. import FluentKit
  9. import FluentSQL
  10. struct FuelEntryV2Controller: RouteCollection {
  11. func boot(routes: RoutesBuilder) throws {
  12. let fuelEntries = routes.grouped("fuel_entries")
  13. let tokenAuthMiddleware = Token.authenticator()
  14. let guardMiddleware = User.guardMiddleware()
  15. let tokenAuthGroup = fuelEntries.grouped(tokenAuthMiddleware, guardMiddleware)
  16. tokenAuthGroup.get(use: filterLoadDate)
  17. tokenAuthGroup.get("main", use: filterLoadDate)
  18. tokenAuthGroup.get("timestamp", use: filterTimeStamp)
  19. tokenAuthGroup.get("images", use: filterImages)
  20. tokenAuthGroup.get("test", use: filtered)
  21. tokenAuthGroup.get("rpm", use: rpm)
  22. tokenAuthGroup.get("maxim", use: filtered)
  23. tokenAuthGroup.post(use: create)
  24. tokenAuthGroup.put( use: softdelete)
  25. tokenAuthGroup.group(":fuelEntryID") { fuelEntry in
  26. fuelEntry.delete(use: delete)
  27. }
  28. }
  29. func index(req: Request) async throws -> [FuelEntry] {
  30. return try await FuelEntry.query(on: req.db).all()
  31. }
  32. struct filteredreturn: Content{
  33. var fuelentries: [FuelEntry]
  34. var pages: Int
  35. }
  36. struct dload: Content{
  37. var id: UUID
  38. }
  39. @Sendable
  40. func softdelete(req: Request) async throws -> Response {
  41. let ids = try req.content.decode([dload].self)
  42. var msg: [String] = []
  43. for id in ids {
  44. guard let fe = try await FuelEntry.find(id.id, on: req.db) else {
  45. msg.append("create error message for item")
  46. continue
  47. }
  48. fe.downloaded = true
  49. try await fe.save(on: req.db)
  50. }
  51. let response = Response(status: .ok, body: "good")
  52. return response
  53. }
  54. fileprivate func queryParamExists(_ req: Request, _ param: String) async throws -> Bool {
  55. let x = try req.query.get(Bool.self, at: param) ? true : false
  56. print ("x: \(x)")
  57. return x
  58. }
  59. fileprivate func parseDate2(_ dateString: String, _ start: Bool = true) throws -> Date? {
  60. let currentDate = Calendar.current.startOfDay(for: Date())
  61. if(dateString.count == 0 && start){
  62. if(start) {
  63. return Calendar.current.date(byAdding: .day, value: -2, to: currentDate)
  64. } else {
  65. return currentDate
  66. }
  67. } else {
  68. let parts = dateString.split(separator: "-")
  69. if(parts.count != 3) {
  70. return nil
  71. }
  72. let year = Int(parts[0]) ?? nil
  73. if(year == nil) {
  74. return nil
  75. }
  76. let month = Int(parts[1]) ?? nil
  77. if(month == nil) {
  78. return nil
  79. }
  80. let day = Int(parts[2]) ?? nil
  81. if( day == nil ) {
  82. return nil
  83. }
  84. var dateComponents = DateComponents()
  85. dateComponents.year = year
  86. dateComponents.month = month
  87. dateComponents.day = day
  88. if(start) {
  89. dateComponents.hour = 0
  90. dateComponents.minute = 0
  91. dateComponents.second = 0
  92. } else {
  93. dateComponents.hour = 23
  94. dateComponents.minute = 59
  95. dateComponents.second = 59
  96. }
  97. let calendar = Calendar(identifier: .gregorian)
  98. return calendar.date(from: dateComponents)
  99. }
  100. }
  101. fileprivate func parseDate(_ dateString: String, _ start: Bool = true) throws -> Date? {
  102. if(dateString.count == 0){
  103. return nil
  104. } else {
  105. let parts = dateString.split(separator: "-")
  106. if(parts.count != 3) {
  107. throw Abort(.custom(code: 400,reasonPhrase: "Value at path '\(start ? "startdate" : "enddate")' was not of format 'yyyy-MM-dd'. Data found at '\(start ? "startdate" : "enddate")' was not properly formatted."))
  108. }
  109. let year = Int(parts[0]) ?? nil
  110. if(year == nil) {
  111. throw Abort(.custom(code: 400,reasonPhrase: "Value at path '\(start ? "startdate" : "enddate")' was not of format 'yyyy-MM-dd'. Data found at '\(start ? "startdate" : "enddate")' was not properly formatted. Year component must be in the format yyyy and must be an integer"))
  112. }
  113. let month = Int(parts[1]) ?? nil
  114. if(month == nil) {
  115. throw Abort(.custom(code: 400,reasonPhrase: "Value at path '\(start ? "startdate" : "enddate")' was not of format 'yyyy-MM-dd'. Data found at '\(start ? "startdate" : "enddate")' was not properly formatted. Month component must be in the format MM and must be an integer"))
  116. }
  117. let day = Int(parts[2]) ?? nil
  118. if( day == nil ) {
  119. throw Abort(.custom(code: 400,reasonPhrase: "Value at path '\(start ? "startdate" : "enddate")' was not of format 'yyyy-MM-dd'. Data found at '\(start ? "startdate" : "enddate")' was not properly formatted. Day component must be in the format dd and must be an integer"))
  120. }
  121. var dateComponents = DateComponents()
  122. dateComponents.year = year
  123. dateComponents.month = month
  124. dateComponents.day = day
  125. if(start) {
  126. dateComponents.hour = 0
  127. dateComponents.minute = 0
  128. dateComponents.second = 0
  129. } else {
  130. dateComponents.hour = 23
  131. dateComponents.minute = 59
  132. dateComponents.second = 59
  133. }
  134. let calendar = Calendar(identifier: .gregorian)
  135. return calendar.date(from: dateComponents)
  136. }
  137. }
  138. fileprivate func generateSQLNoImage(_ startdate: Date? = nil, _ enddate: Date? = nil) -> SQLQueryString {
  139. if(startdate == nil) {
  140. return SQLQueryString("select count(*) as total from \"fuel_entries\";")
  141. }
  142. if(enddate != nil) {
  143. return SQLQueryString("select count(*) as total from \"fuel_entries\" where \"loadDate\" >= \(bind: startdate) and \"loadDate\" <= \(bind: enddate) ;")
  144. } else {
  145. return SQLQueryString("select count(*) as total from \"fuel_entries\" where \"loadDate\" >= \(bind: startdate);")
  146. }
  147. }
  148. fileprivate func generateSQLImage(_ startdate: Date? = nil, _ enddate: Date? = nil) -> SQLQueryString {
  149. var sql: String = ""
  150. if(startdate == nil) {
  151. return SQLQueryString("select count(*) as total from \"fuel_entries\" where \"image\" is not null;")
  152. }
  153. if(enddate != nil) {
  154. sql = "select count(*) as total from \"fuel_entries\" where \"loadDate\" >= \(String(describing: startdate)) and \"loadDate\" <= \(String(describing: enddate)) and \"image\" is not null;"
  155. return SQLQueryString("select count(*) as total from \"fuel_entries\" where \"loadDate\" >= \(bind: startdate) and \"loadDate\" <= \(bind: enddate) and \"image\" is not null;")
  156. } else {
  157. sql = "select count(*) as total from \"fuel_entries\" where \"image\" is not null and \"loadDate\" >= '\(startdate ?? Date())';"
  158. return SQLQueryString(sql)
  159. }
  160. }
  161. struct CountRecords: Content {
  162. let total: Int
  163. }
  164. fileprivate func getCount(_ req: Request, _ sql: SQLQueryString) async throws -> Int {
  165. print(sql)
  166. if let db = req.db as? SQLDatabase {
  167. let answer = try await db
  168. .raw(sql)
  169. .first(decoding: CountRecords.self)
  170. return answer?.total ?? 0
  171. } else {
  172. return 0
  173. }
  174. }
  175. fileprivate func getPaging(_ page: Int, _ per: Int, _ records: Int) async throws -> [String: Any] {
  176. var vals: [String: Any] = [:]
  177. vals["page"] = page
  178. vals["per"] = per
  179. vals["records"] = records
  180. let lastpage = Int(ceil(Double(records) / Double(per)))
  181. vals["lastpage"] = (page == lastpage) ? true : false
  182. vals["offset"] = ( page * per) - per
  183. return vals
  184. }
  185. fileprivate func getParams(_ req: Request) async throws -> [qparam] {
  186. let urlComponents = URLComponents(string: req.url.description)!
  187. var params: [qparam] = []
  188. for queryItem in urlComponents.queryItems ?? [] {
  189. params.append(qparam(name: queryItem.name, value: queryItem.value ?? ""))
  190. }
  191. return params
  192. }
  193. fileprivate func getMaximError(_ req: Request, _ message: String) async throws -> returnObj {
  194. let rt = req.route!.description.replacingOccurrences(of: "GET ", with: "").replacingOccurrences(of: "PUT ", with: "").replacingOccurrences(of: "POST ", with: "").replacingOccurrences(of: "DELETE ", with: "")
  195. let method = req.method.rawValue
  196. let baseurl = "https://fueling.prelub.com"
  197. let data : [FuelEntry.Output] = []
  198. let meta = Meta(page: 0, per: 0, total: 0, lastpage: true, error: true, message: message, method: method, baseurl: baseurl, route: rt, querystring: "" )
  199. return returnObj(data: data, meta: meta)
  200. }
  201. @Sendable
  202. func filterLoadDate(req: Request) async throws -> Response {
  203. let rt = req.route!.description.replacingOccurrences(of: "GET ", with: "").replacingOccurrences(of: "PUT ", with: "").replacingOccurrences(of: "POST ", with: "").replacingOccurrences(of: "DELETE ", with: "")
  204. let method = req.method.rawValue
  205. let baseurl = "https://fueling.prelub.com"
  206. let qstring = req.query
  207. let components: Dictionary<String, String?> = try req.query.decode(Dictionary<String, String?>.self)
  208. var startdate : Date?
  209. var qs: [String] = []
  210. for component in components {
  211. qs.append( "\(component.key)=\(component.value ?? "nil")")
  212. }
  213. if(try qstring.get(String?.self, at: "startdate") != nil) {
  214. startdate = try parseDate2(qstring.get(String?.self, at: "startdate") ?? "")
  215. if(startdate == nil) {
  216. return try await(getMaximError(req, "startdate is invalid format. YYYY-MM-DD")) .encodeResponse(for: req)
  217. }
  218. } else {
  219. //throw error
  220. return try await getMaximError(req, "startdate is required").encodeResponse(for: req)
  221. }
  222. var enddate : Date?//= try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
  223. if(try qstring.get(String?.self, at: "enddate") != nil) {
  224. enddate = try parseDate2(qstring.get(String?.self, at: "enddate") ?? "", false)
  225. if(enddate == nil) {
  226. return try await getMaximError(req, "enddate is invalid format. YYYY-MM-DD").encodeResponse(for: req)
  227. }
  228. }
  229. let emptyData: Data? = Data()
  230. let page = try qstring.get(Int?.self, at: "page") ?? 1
  231. let per = try qstring.get(Int?.self, at: "per") ?? 10
  232. let qsStr = qs.joined(separator: "&")
  233. let records = try await getCount(req, generateSQLNoImage(startdate ?? nil, enddate ?? nil) )
  234. let paging = try await getPaging(page, per, records)
  235. let meta = Meta(page: page, per: per, total: records, lastpage: (paging["lastpage"] != nil) ? paging["lastpage"] as! Bool : false, error: false, message: "", method: method, baseurl: baseurl, route: rt, querystring: "?\(qsStr)")
  236. let query = try await FuelEntry.query(on: req.db)
  237. .field(\.$id)
  238. .field(\.$timestamp)
  239. .field(\.$userID)
  240. .field(\.$product)
  241. .field(\.$make)
  242. .field(\.$model)
  243. .field(\.$serialNumber)
  244. .field(\.$tankID)
  245. .field(\.$fuelAmount)
  246. .field(\.$fuelType)
  247. .field(\.$isOverride)
  248. .field(\.$latitude)
  249. .field(\.$longitude)
  250. .field(\.$downloaded)
  251. .field(\.$loaddate)
  252. .field(\.$tabletserial)
  253. .group(.and) {
  254. grp in
  255. grp.filter(\.$loaddate >= startdate)
  256. if( enddate != nil) {
  257. grp.filter(\.$loaddate <= enddate!)
  258. }
  259. }
  260. .sort(\.$loaddate, .ascending)
  261. .range(lower: (paging["offset"] as! Int), upper: (paging["offset"] as! Int) + (paging["per"] as! Int))
  262. .all().map{
  263. FuelEntry.Output(id: $0.id, timestamp: $0.timestamp, ssid: $0.userID, latitude: $0.latitude, longitude: $0.longitude, product: $0.product, make: $0.make, model: $0.model, serialNumber: $0.serialNumber, tankID: $0.tankID, fuelAmount: $0.fuelAmount, fuelType: $0.fuelType, isOverride: $0.isOverride, image: emptyData, loaddate: $0.loaddate, useremail: $0.tabletserial ?? "")
  264. }
  265. let response = returnObj(data: query, meta: meta)
  266. return try await response.encodeResponse(for: req)
  267. }
  268. @Sendable
  269. func filterImages(req: Request) async throws -> Response {
  270. let rt = req.route!.description.replacingOccurrences(of: "GET ", with: "").replacingOccurrences(of: "PUT ", with: "").replacingOccurrences(of: "POST ", with: "").replacingOccurrences(of: "DELETE ", with: "")
  271. let method = req.method.rawValue
  272. let baseurl = "https://fueling.prelub.com"
  273. let qstring = req.query
  274. let components: Dictionary<String, String?> = try req.query.decode(Dictionary<String, String?>.self)
  275. var startdate : Date?
  276. var qs: [String] = []
  277. for component in components {
  278. qs.append( "\(component.key)=\(component.value ?? "nil")")
  279. }
  280. if(try qstring.get(String?.self, at: "startdate") != nil) {
  281. startdate = try parseDate2(qstring.get(String?.self, at: "startdate") ?? "")
  282. if(startdate == nil) {
  283. return try await(getMaximError(req, "startdate is invalid format. YYYY-MM-DD")) .encodeResponse(for: req)
  284. }
  285. } else {
  286. //throw error
  287. return try await getMaximError(req, "startdate is required").encodeResponse(for: req)
  288. }
  289. var enddate : Date?//= try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
  290. if(try qstring.get(String?.self, at: "enddate") != nil) {
  291. enddate = try parseDate2(qstring.get(String?.self, at: "enddate") ?? "", false)
  292. if(enddate == nil) {
  293. return try await getMaximError(req, "enddate is invalid format. YYYY-MM-DD").encodeResponse(for: req)
  294. }
  295. }
  296. let page = try qstring.get(Int?.self, at: "page") ?? 1
  297. let per = try qstring.get(Int?.self, at: "per") ?? 5
  298. var records : Int = 0
  299. if(enddate == nil) {
  300. records = try await FuelEntry.query(on: req.db)
  301. .field(\.$id)
  302. .group(.and) {
  303. grp in
  304. grp.filter(\.$loaddate >= startdate)
  305. .filter(\.$image != nil)
  306. }
  307. .all()
  308. .count
  309. } else {
  310. records = try await FuelEntry.query(on: req.db)
  311. .field(\.$id)
  312. .group(.and) {
  313. grp in
  314. grp.filter(\.$loaddate >= startdate)
  315. .filter(\.$image != nil)
  316. .filter(\.$loaddate <= enddate)
  317. }
  318. .all()
  319. .count
  320. }
  321. let qsStr = qs.joined(separator: "&")
  322. let paging = try await getPaging(page, per, records)
  323. let meta = Meta(page: page, per: per, total: records, lastpage: (paging["lastpage"] != nil) ? paging["lastpage"] as! Bool : false, error: false, message: "", method: method, baseurl: baseurl, route: rt, querystring: "?\(qsStr)")
  324. let query = try await FuelEntry.query(on: req.db)
  325. .field(\.$id)
  326. .field(\.$timestamp)
  327. .field(\.$userID)
  328. .field(\.$product)
  329. .field(\.$make)
  330. .field(\.$model)
  331. .field(\.$serialNumber)
  332. .field(\.$tankID)
  333. .field(\.$fuelAmount)
  334. .field(\.$fuelType)
  335. .field(\.$isOverride)
  336. .field(\.$latitude)
  337. .field(\.$longitude)
  338. .field(\.$downloaded)
  339. .field(\.$loaddate)
  340. .field(\.$image)
  341. .field(\.$tabletserial)
  342. .group(.and) {
  343. grp in if(enddate != nil) {
  344. grp.filter(\.$loaddate >= startdate)
  345. .filter(\.$image != nil)
  346. .filter(\.$loaddate <= enddate!)
  347. } else {
  348. grp.filter(\.$loaddate >= startdate)
  349. .filter(\.$image != nil)
  350. }
  351. }
  352. .sort(\.$loaddate, .ascending)
  353. .range(lower: (paging["offset"] as! Int), upper: (paging["offset"] as! Int) + (paging["per"] as! Int))
  354. .all().map{
  355. FuelEntry.Output(id: $0.id, timestamp: $0.timestamp, ssid: $0.userID, latitude: $0.latitude, longitude: $0.longitude, product: $0.product, make: $0.make, model: $0.model, serialNumber: $0.serialNumber, tankID: $0.tankID, fuelAmount: $0.fuelAmount, fuelType: $0.fuelType, isOverride: $0.isOverride, image: $0.image, loaddate: $0.loaddate, useremail: $0.tabletserial ?? "")
  356. }
  357. let response = returnObj(data: query, meta: meta)
  358. return try await response.encodeResponse(for: req)
  359. }
  360. @Sendable
  361. func filterTimeStamp(req: Request) async throws -> Response {
  362. let rt = req.route!.description.replacingOccurrences(of: "GET ", with: "").replacingOccurrences(of: "PUT ", with: "").replacingOccurrences(of: "POST ", with: "").replacingOccurrences(of: "DELETE ", with: "")
  363. let method = req.method.rawValue
  364. let baseurl = "https://fueling.prelub.com"
  365. let qstring = req.query
  366. let components: Dictionary<String, String?> = try req.query.decode(Dictionary<String, String?>.self)
  367. var startdate : Date?
  368. var qs: [String] = []
  369. for component in components {
  370. qs.append( "\(component.key)=\(component.value ?? "nil")")
  371. }
  372. if(try qstring.get(String?.self, at: "startdate") != nil) {
  373. startdate = try parseDate2(qstring.get(String?.self, at: "startdate") ?? "")
  374. if(startdate == nil) {
  375. return try await(getMaximError(req, "startdate is invalid format. YYYY-MM-DD")) .encodeResponse(for: req)
  376. }
  377. } else {
  378. //throw error
  379. return try await getMaximError(req, "startdate is required").encodeResponse(for: req)
  380. }
  381. var enddate : Date?//= try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
  382. if(try qstring.get(String?.self, at: "enddate") != nil) {
  383. enddate = try parseDate2(qstring.get(String?.self, at: "enddate") ?? "", false)
  384. if(enddate == nil) {
  385. return try await getMaximError(req, "enddate is invalid format. YYYY-MM-DD").encodeResponse(for: req)
  386. }
  387. }
  388. let emptyData: Data? = Data()
  389. let page = try qstring.get(Int?.self, at: "page") ?? 1
  390. let per = try qstring.get(Int?.self, at: "per") ?? 10
  391. let records = try await getCount(req, generateSQLNoImage(startdate ?? nil, enddate ?? nil) )
  392. let paging = try await getPaging(page, per, records)
  393. let meta = Meta(page: page, per: per, total: records, lastpage: (paging["lastpage"] != nil) ? paging["lastpage"] as! Bool : false, error: false, message: "", method: method, baseurl: baseurl, route: rt, querystring: "?\(qs.joined(separator: "&"))")
  394. let query = try await FuelEntry.query(on: req.db)
  395. .field(\.$id)
  396. .field(\.$timestamp)
  397. .field(\.$userID)
  398. .field(\.$product)
  399. .field(\.$make)
  400. .field(\.$model)
  401. .field(\.$serialNumber)
  402. .field(\.$tankID)
  403. .field(\.$fuelAmount)
  404. .field(\.$fuelType)
  405. .field(\.$isOverride)
  406. .field(\.$latitude)
  407. .field(\.$longitude)
  408. .field(\.$downloaded)
  409. .field(\.$loaddate)
  410. .field(\.$tabletserial)
  411. .group(.and) {
  412. grp in
  413. grp.filter(\.$timestamp >= startdate ?? Calendar.current.startOfDay(for: Calendar.current.date(byAdding: .day, value: -2, to: Date())!))
  414. if( enddate != nil) {
  415. grp.filter(\.$timestamp <= enddate!)
  416. }
  417. }
  418. .sort(\.$loaddate, .ascending)
  419. .range(lower: (paging["offset"] as! Int), upper: (paging["offset"] as! Int) + (paging["per"] as! Int))
  420. .all().map{
  421. FuelEntry.Output(id: $0.id, timestamp: $0.timestamp, ssid: $0.userID, latitude: $0.latitude, longitude: $0.longitude, product: $0.product, make: $0.make, model: $0.model, serialNumber: $0.serialNumber, tankID: $0.tankID, fuelAmount: $0.fuelAmount, fuelType: $0.fuelType, isOverride: $0.isOverride, image: emptyData, loaddate: $0.loaddate, useremail: $0.tabletserial ?? "")
  422. }
  423. let response = returnObj(data: query, meta: meta)
  424. return try await response.encodeResponse(for: req)
  425. }
  426. @Sendable
  427. func filtered(req: Request) async throws -> Response {
  428. let qstring = req.query
  429. let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "")
  430. let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
  431. let image = try qstring.get(Bool?.self, at: "image") ?? false
  432. let serial = try qstring.get(String?.self, at: "serial") ?? nil
  433. let tank = try qstring.get(String?.self, at: "tank") ?? nil
  434. let previous = try qstring.get(Bool?.self, at: "previous") ?? false
  435. var query = FuelEntry.query(on: req.db)
  436. if(image){
  437. query = query
  438. .field(\.$id)
  439. .field(\.$timestamp)
  440. .field(\.$userID)
  441. .field(\.$product)
  442. .field(\.$make)
  443. .field(\.$model)
  444. .field(\.$serialNumber)
  445. .field(\.$tankID)
  446. .field(\.$fuelAmount)
  447. .field(\.$fuelType)
  448. .field(\.$isOverride)
  449. .field(\.$latitude)
  450. .field(\.$longitude)
  451. .field(\.$image)
  452. .field(\.$downloaded)
  453. .field(\.$loaddate)
  454. //.filter(\.$image != nil)
  455. } else {
  456. query = query
  457. .field(\.$id)
  458. .field(\.$timestamp)
  459. .field(\.$userID)
  460. .field(\.$product)
  461. .field(\.$make)
  462. .field(\.$model)
  463. .field(\.$serialNumber)
  464. .field(\.$tankID)
  465. .field(\.$fuelAmount)
  466. .field(\.$fuelType)
  467. .field(\.$isOverride)
  468. .field(\.$latitude)
  469. .field(\.$longitude)
  470. .field(\.$downloaded)
  471. .field(\.$loaddate)
  472. }
  473. query = query.group(.and){
  474. grp in
  475. if( startdate != nil) {
  476. grp.filter(\.$loaddate >= startdate)
  477. }
  478. if( enddate != nil) {
  479. grp.filter(\.$loaddate <= enddate!)
  480. }
  481. if( serial != nil) {
  482. grp.filter(\.$serialNumber == serial!)
  483. }
  484. if( tank != nil) {
  485. grp.filter(\.$tankID == tank!)
  486. }
  487. if(!previous){
  488. grp.filter(\.$pulldate == nil)
  489. }
  490. }
  491. query = query.sort(\.$loaddate, .ascending)
  492. if(image){
  493. //query = query.filter(\.$image)
  494. let wimage = try await query.paginate(for: req).map{
  495. img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitude: 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: previous == true ? img.pulldate : Date())
  496. }
  497. if(!previous){
  498. wimage.items.forEach{
  499. _ = $0.toFuelEntry().save(on: req.db)
  500. }
  501. }
  502. return try await wimage.encodeResponse(for: req)
  503. } else {
  504. let woimage = try await query.paginate(for: req).map{
  505. img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitude: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, image: nil, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: previous == true ? img.pulldate : Date())
  506. }
  507. if(!previous) {
  508. woimage.items.forEach {
  509. _ = $0.toFuelEntry().save(on: req.db)
  510. }
  511. }
  512. return try await woimage.encodeResponse(for: req)
  513. }
  514. }
  515. @Sendable
  516. func rpm(req: Request) async throws -> Response {
  517. let qstring = req.query
  518. let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "")
  519. let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
  520. let image = try qstring.get(Bool?.self, at: "image") ?? false
  521. let serial = try qstring.get(String?.self, at: "serial") ?? nil
  522. let tank = try qstring.get(String?.self, at: "tank") ?? nil
  523. let previous = try qstring.get(Bool?.self, at: "previous") ?? false
  524. var query = FuelEntry.query(on: req.db)
  525. if(image){
  526. query = query
  527. .field(\.$id)
  528. .field(\.$timestamp)
  529. .field(\.$userID)
  530. .field(\.$product)
  531. .field(\.$make)
  532. .field(\.$model)
  533. .field(\.$serialNumber)
  534. .field(\.$tankID)
  535. .field(\.$fuelAmount)
  536. .field(\.$fuelType)
  537. .field(\.$isOverride)
  538. .field(\.$latitude)
  539. .field(\.$longitude)
  540. .field(\.$image)
  541. .field(\.$downloaded)
  542. .field(\.$loaddate)
  543. } else {
  544. query = query
  545. .field(\.$id)
  546. .field(\.$timestamp)
  547. .field(\.$userID)
  548. .field(\.$product)
  549. .field(\.$make)
  550. .field(\.$model)
  551. .field(\.$serialNumber)
  552. .field(\.$tankID)
  553. .field(\.$fuelAmount)
  554. .field(\.$fuelType)
  555. .field(\.$isOverride)
  556. .field(\.$latitude)
  557. .field(\.$longitude)
  558. .field(\.$downloaded)
  559. .field(\.$loaddate)
  560. }
  561. query = query.group(.and){
  562. grp in
  563. if( startdate != nil) {
  564. grp.filter(\.$loaddate >= startdate!)
  565. }
  566. if( enddate != nil) {
  567. grp.filter(\.$loaddate <= enddate!)
  568. }
  569. if( serial != nil) {
  570. grp.filter(\.$serialNumber == serial!)
  571. }
  572. if( tank != nil) {
  573. grp.filter(\.$tankID == tank!)
  574. }
  575. if(!previous){
  576. grp.filter(\.$pulldate == nil)
  577. }
  578. }
  579. query = query.sort(\.$loaddate, .ascending).sort(\.$timestamp).sort(\.$serialNumber)
  580. if(image){
  581. //query = query.filter(\.$image)
  582. let wimage = try await query.paginate(for: req).map{
  583. img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitude: 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())
  584. }
  585. return try await wimage.encodeResponse(for: req)
  586. } else {
  587. let woimage = try await query.paginate(for: req).map{
  588. img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitude: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, image: nil, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date())
  589. }
  590. return try await woimage.encodeResponse(for: req)
  591. }
  592. }
  593. func create(req: Request) async throws -> [FuelEntry] {
  594. let fuelEntry = try req.content.decode([FuelEntry].self)
  595. for entry in fuelEntry {
  596. let data = entry.image ?? nil
  597. let length = data?.count
  598. if(data == nil || length == 0){
  599. entry.image = nil
  600. }
  601. }
  602. try await fuelEntry.create(on: req.db)
  603. return fuelEntry
  604. }
  605. func delete(req: Request) async throws -> HTTPStatus {
  606. guard let fuelEntry = try await FuelEntry.find(req.parameters.get("fuelEntryID"), on: req.db) else {
  607. throw Abort(.notFound)
  608. }
  609. try await fuelEntry.delete(on: req.db)
  610. return .noContent
  611. }
  612. @Sendable
  613. func getrpm(req: Request) async throws -> Response {
  614. let qstring = req.query
  615. let startdate = try parseDate(qstring.get(String?.self, at: "startdate") ?? "")
  616. let enddate = try parseDate(qstring.get(String?.self, at: "enddate") ?? "", false)
  617. let image = try qstring.get(Bool?.self, at: "image") ?? false
  618. let serial = try qstring.get(String?.self, at: "serial") ?? nil
  619. let tank = try qstring.get(String?.self, at: "tank") ?? nil
  620. let previous = try qstring.get(Bool?.self, at: "previous") ?? false
  621. var query = FuelEntry.query(on: req.db)
  622. if(image){
  623. query = query
  624. .field(\.$id)
  625. .field(\.$timestamp)
  626. .field(\.$userID)
  627. .field(\.$product)
  628. .field(\.$make)
  629. .field(\.$model)
  630. .field(\.$serialNumber)
  631. .field(\.$tankID)
  632. .field(\.$fuelAmount)
  633. .field(\.$fuelType)
  634. .field(\.$isOverride)
  635. .field(\.$latitude)
  636. .field(\.$longitude)
  637. .field(\.$image)
  638. .field(\.$downloaded)
  639. .field(\.$loaddate)
  640. } else {
  641. query = query
  642. .field(\.$id)
  643. .field(\.$timestamp)
  644. .field(\.$userID)
  645. .field(\.$product)
  646. .field(\.$make)
  647. .field(\.$model)
  648. .field(\.$serialNumber)
  649. .field(\.$tankID)
  650. .field(\.$fuelAmount)
  651. .field(\.$fuelType)
  652. .field(\.$isOverride)
  653. .field(\.$latitude)
  654. .field(\.$longitude)
  655. .field(\.$downloaded)
  656. .field(\.$loaddate)
  657. }
  658. query = query.group(.and){
  659. grp in
  660. if( startdate != nil) {
  661. grp.filter(\.$loaddate >= startdate!)
  662. }
  663. if( enddate != nil) {
  664. grp.filter(\.$loaddate <= enddate!)
  665. }
  666. if( serial != nil) {
  667. grp.filter(\.$serialNumber == serial!)
  668. }
  669. if( tank != nil) {
  670. grp.filter(\.$tankID == tank!)
  671. }
  672. if(!previous){
  673. grp.filter(\.$pulldate == nil)
  674. }
  675. }
  676. query = query.sort(\.$loaddate, .ascending).sort(\.$timestamp).sort(\.$serialNumber)
  677. if(image){
  678. //query = query.filter(\.$image)
  679. let wimage = try await query.paginate(for: req).map{
  680. img in FuelEntry.wimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitude: 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())
  681. }
  682. return try await wimage.encodeResponse(for: req)
  683. } else {
  684. let woimage = try await query.paginate(for: req).map{
  685. img in FuelEntry.woimage(id: img.id, timestamp: img.timestamp, userID: img.userID, latitude: img.latitude, longitude: img.longitude, product: img.product, make: img.make, model: img.model, serialNumber: img.serialNumber, tankID: img.tankID, fuelAmount: img.fuelAmount, fuelType: img.fuelType, image: nil, isOverride: img.isOverride, downloaded: img.downloaded == nil ? false : img.downloaded!, loaddate: img.loaddate == nil ? nil : img.loaddate, pulldate: Date())
  686. }
  687. return try await woimage.encodeResponse(for: req)
  688. }
  689. }
  690. }
  691. struct custMeta: Content {
  692. let per: Int
  693. let page: Int
  694. let total: Int
  695. let status: String?
  696. }
  697. struct PageRequest: Content {
  698. var page: Int
  699. var size: Int
  700. var status: String?
  701. // Add any other properties needed for pagination
  702. init(page: Int, size: Int, status: String? = nil) {
  703. self.page = page
  704. self.size = size
  705. self.status = status
  706. }
  707. }