const std = @import("std"); const httpz = @import("../.deps/http.zig/src/httpz.zig"); const models = @import("../db/models.zig"); const ztime = @import("../.deps/time.zig"); const utils = @import("../utils.zig"); const auth = @import("auth.zig"); const handler = @import("../http_handler.zig"); // pub fn getBudget(req: *httpz.Request, res: *httpz.Response) !void { // const db = handler.getDb(); // var gpa = std.heap.GeneralPurposeAllocator(.{}){}; // const allocator = gpa.allocator(); // const id_str = req.param("id"); // if (id_str == null) { // res.status = 400; // res.body = "Bad Request: No Id"; // return; // } // const id = std.fmt.parseInt(u32, id_str.?, 0) catch { // res.status = 401; // res.body = "Bad Request: Bad Id"; // return; // }; // const budget = try db.selectOneById(models.Budget, allocator, id); // if (budget == null) { // res.status = 404; // res.body = "Budget not found"; // return; // } // try res.json(budget.?, .{}); // } // const BudgetPostReq = struct { // id: ?u32, // family_id: u32, // name: []const u8, // created_at: ?u64, // updated_at: ?u64, // hide: u8, // }; // pub fn putBudget(req: *httpz.Request, res: *httpz.Response) !void { // var db = handler.getDb(); // var gpa = std.heap.GeneralPurposeAllocator(.{}){}; // const allocator = gpa.allocator(); // const body_data = req.json(models.Budget) catch |err| { // std.debug.print("Malformed body: {any}\n", .{err}); // handler.returnError("Bad Request: Malformed Body", 400, res); // return; // }; // if (body_data == null) { // handler.returnError("Bad Request: No Data", 400, res); // return; // } // var body = body_data.?; // // Add Budget // const now = @intCast(u64, std.time.milliTimestamp()); // // Update existing Budget // body.updated_at = now; // try db.updateById(models.Budget, body); // const query = models.createSelectOnIdQuery(models.Transaction); // const updated_budget = try db.selectOne(models.Budget, allocator, query, .{ .id = body.id }); // if (updated_budget) |budget| { // try handler.returnData(budget, res); // } else { // handler.returnError("Internal Server Error", 500, res); // } // return; // } // pub fn postBudget(req: *httpz.Request, res: *httpz.Response) !void { // comptime { // const putReqLen = @typeInfo(BudgetPostReq).Struct.fields.len; // const budgetLen = @typeInfo(models.Budget).Struct.fields.len; // if (putReqLen != budgetLen) { // @compileError(std.fmt.comptimePrint("BudgetPostReq does not equal Budget model struct, fields inconsistent", .{})); // } // } // var db = handler.getDb(); // var gpa = std.heap.GeneralPurposeAllocator(.{}){}; // const allocator = gpa.allocator(); // const body_data = req.json(BudgetPostReq) catch |err| { // std.debug.print("Malformed body: {any}\n", .{err}); // handler.returnError("Bad request: Malformed Body", 400, res); // return; // }; // if (body_data == null) { // handler.returnError("Bad request: No Data", 400, res); // return; // } // var body = body_data.?; // if (body.id != null) { // handler.returnError("Bad Request: ID", 400, res); // } // // Add Budget // const now = @intCast(u64, std.time.milliTimestamp()); // // Create Budget // body.created_at = now; // body.updated_at = now; // try db.insert(models.Budget, utils.removeStructFields(body, &[_]u8{0})); // // Get Budget // const query = try models.createSelectOnFieldQuery(models.Budget, null, "created_at", "="); // const updated_budget = try db.selectOne(models.Budget, allocator, query, .{ .created_at = body.created_at }); // if (updated_budget) |budget| { // try handler.returnData(budget, res); // } else { // handler.returnError("Internal Server Error", 500, res); // } // return; // } const BudgetCatPostReq = struct { id: ?u32, budget_id: u32, amount: f64, name: []const u8, color: []const u8, created_at: ?u64, updated_at: ?u64, hide: u8, }; pub fn postBudgetCategory(req: *httpz.Request, res: *httpz.Response) !void { comptime { const putReqLen = @typeInfo(BudgetCatPostReq).Struct.fields.len; const budgetLen = @typeInfo(models.BudgetCategory).Struct.fields.len; if (putReqLen != budgetLen) { @compileError(std.fmt.comptimePrint("BudgetCatPutReq does not equal Budget model struct, fields inconsistent", .{})); } } var db = handler.getDb(); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); const body_data = req.json(BudgetCatPostReq) catch |err| { std.debug.print("Malformed body: {any}\n", .{err}); handler.returnError("Bad request: Malformed Body", 400, res); return; }; if (body_data == null) { handler.returnError("Bad request: No Data", 400, res); return; } var body = body_data.?; if (body.id != null) { handler.returnError("Bad request: ID", 400, res); return; } const budget = try db.selectOneById(models.Budget, allocator, body.budget_id); if (budget == null) { handler.returnError("No budget found", 404, res); } _ = auth.verifyRequest(req, res, null, budget.?.family_id) catch { return; }; // Add Budget const now = @intCast(u64, std.time.milliTimestamp()); // Create Budget body.created_at = now; body.updated_at = now; try db.insert(models.BudgetCategory, utils.removeStructFields(body, &[_]u8{0})); // Get Budget const query = try models.createSelectOnFieldQuery(models.BudgetCategory, null, "created_at", "="); const updated_budget_cat = try db.selectOne(models.BudgetCategory, allocator, query, .{ .created_at = body.created_at }); if (updated_budget_cat == null) { std.debug.print("Could not find inserted budget", .{}); handler.returnError("Internal Server Error", 500, res); return; } try handler.returnData(updated_budget_cat.?, res); } pub fn putBudgetCategory(req: *httpz.Request, res: *httpz.Response) !void { var db = handler.getDb(); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); const body_data = req.json(models.BudgetCategory) catch |err| { std.debug.print("Malformed body: {any}\n", .{err}); handler.returnError("Bad request: Malformed Body", 400, res); return; }; if (body_data == null) { handler.returnError("Bad request: No Data", 400, res); return; } var budget_category = body_data.?; const budget = try db.selectOneById(models.Budget, allocator, budget_category.budget_id); if (budget == null) { handler.returnError("No budget found", 404, res); } _ = auth.verifyRequest(req, res, null, budget.?.family_id) catch { return; }; const now = @intCast(u64, std.time.milliTimestamp()); // Update existing Budget budget_category.updated_at = now; try db.updateById(models.BudgetCategory, budget_category); const query = models.createSelectOnIdQuery(models.BudgetCategory); const updated_budget_cat = try db.selectOne(models.BudgetCategory, allocator, query, .{ .id = budget_category.id }); if (updated_budget_cat == null) { std.debug.print("Could not find inserted budget", .{}); handler.returnError("Internal Server Error", 500, res); return; } try handler.returnData(updated_budget_cat.?, res); return; } const deleteIdReq = struct { id: u32, }; pub fn deleteBudgetCategory(req: *httpz.Request, res: *httpz.Response) !void { var db = handler.getDb(); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); const body = handler.getReqJson(req, res, deleteIdReq) catch { return; }; const budget_category = try db.selectOneById(models.BudgetCategory, allocator, body.id); if (budget_category == null) { return handler.returnError("Cannot find budget", 404, res); } const budget = try db.selectOneById(models.Budget, allocator, budget_category.?.budget_id); if (budget == null) { return handler.returnError("Cannot find budget", 404, res); } _ = auth.verifyRequest(req, res, null, budget.?.family_id) catch { return; }; try db.updateHideById(models.BudgetCategory, true, body.id); const updated_budget_category = try db.selectOneById(models.BudgetCategory, allocator, body.id); if (budget_category == null) { return handler.returnError("Could not delete category", 500, res); } return try handler.returnData(updated_budget_category.?, res); }