147 lines
4.8 KiB
Zig
147 lines
4.8 KiB
Zig
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 handler = @import("../http_handler.zig");
|
|
|
|
pub fn fetchTransFromDb(allocator: std.mem.Allocator, budget_id: u32) !?[]models.Transaction {
|
|
var db = handler.getDb();
|
|
const now = ztime.DateTime.now();
|
|
const beginningOfMonth = ztime.DateTime.init(now.years, now.months, 0, 0, 0, 0);
|
|
|
|
comptime {
|
|
if (!std.mem.eql(u8, @typeInfo(models.Transaction).Struct.fields[7].name, "date")) {
|
|
return error{TransactionModelError};
|
|
}
|
|
}
|
|
const transactions = try db.selectAllWhere(
|
|
models.Transaction,
|
|
allocator,
|
|
"WHERE budget_id = ? AND date > ? AND hide = ?",
|
|
.{ .budget_id = budget_id, .date = beginningOfMonth.toUnixMilli(), .hide = 0 },
|
|
null,
|
|
);
|
|
return transactions;
|
|
}
|
|
|
|
pub fn getTransactions(req: *httpz.Request, res: *httpz.Response) !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
|
|
const budget_id_str = req.param("budget_id");
|
|
if (budget_id_str == null) {
|
|
handler.returnError("Bad request", 400, res);
|
|
return;
|
|
}
|
|
const budget_id = std.fmt.parseInt(u32, budget_id_str.?, 0) catch {
|
|
handler.returnError("Bad request", 400, res);
|
|
return;
|
|
};
|
|
|
|
const transactions = try fetchTransFromDb(allocator, budget_id);
|
|
|
|
if (transactions == null) {
|
|
res.status = 200;
|
|
res.body = "";
|
|
return;
|
|
}
|
|
// std.debug.print("Transactions got:\n", .{});
|
|
// for (transactions.?) |transaction| {
|
|
// std.debug.print("\t{any}\n", .{transaction});
|
|
// }
|
|
try handler.returnData(.{ .transactions = transactions.? }, res);
|
|
}
|
|
|
|
pub fn putTransaction(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.Transaction) 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 transaction = body_data.?;
|
|
|
|
// Add Transaction
|
|
const now = @intCast(u64, std.time.milliTimestamp());
|
|
// Update existing Transaction
|
|
transaction.updated_at = now;
|
|
try db.updateById(models.Transaction, transaction);
|
|
|
|
const query = models.createSelectOnIdQuery(models.Transaction);
|
|
const updated_trans = try db.selectOne(models.Transaction, allocator, query, .{ .id = transaction.id });
|
|
if (updated_trans) |trans| {
|
|
try handler.returnData(trans, res);
|
|
} else {
|
|
handler.returnError("Internal Server Error", 500, res);
|
|
}
|
|
return;
|
|
}
|
|
|
|
const TransPostReq = struct {
|
|
id: ?u32,
|
|
amount: f64,
|
|
type: []const u8,
|
|
memo: ?[]const u8,
|
|
budget_id: u32,
|
|
added_by_user_id: u32,
|
|
budget_category_id: ?u32,
|
|
date: u64,
|
|
created_at: ?u64,
|
|
updated_at: ?u64,
|
|
hide: u8,
|
|
};
|
|
|
|
pub fn postTransaction(req: *httpz.Request, res: *httpz.Response) !void {
|
|
comptime {
|
|
const putReqLen = @typeInfo(TransPostReq).Struct.fields.len;
|
|
const transLen = @typeInfo(models.Transaction).Struct.fields.len;
|
|
if (putReqLen != transLen) {
|
|
@compileError(std.fmt.comptimePrint("TransactionPutReq does not equal Transaction model struct, fields inconsistent", .{}));
|
|
}
|
|
}
|
|
var db = handler.getDb();
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
|
|
const body_data = req.json(TransPostReq) 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 now = @intCast(u64, std.time.milliTimestamp());
|
|
body.created_at = now;
|
|
body.updated_at = now;
|
|
|
|
try db.insert(models.Transaction, utils.removeStructFields(body, &[_]u8{0}));
|
|
|
|
// Get new Transaction
|
|
const query = try models.createSelectOnFieldQuery(models.Transaction, null, "created_at", "=");
|
|
const updated_tran = try db.selectOne(models.Transaction, allocator, query, .{ .created_at = body.created_at });
|
|
if (updated_tran) |tran| {
|
|
try handler.returnData(tran, res);
|
|
} else {
|
|
handler.returnError("Internal Server Error", 500, res);
|
|
}
|
|
return;
|
|
}
|