diff options
| -rw-r--r-- | src/commands.c | 90 | ||||
| -rw-r--r-- | tests/test_core.c | 28 |
2 files changed, 118 insertions, 0 deletions
diff --git a/src/commands.c b/src/commands.c index 5ccadfc..948c42c 100644 --- a/src/commands.c +++ b/src/commands.c @@ -675,6 +675,94 @@ static yyjson_mut_val *h_org_get(struct req *r) return o; } +static yyjson_mut_val *h_org_update(struct req *r) +{ + const char *name = arg_str(r->args, "name"); + const char *org_nr = arg_str(r->args, "org_nr"); + const char *vat_nr = arg_str(r->args, "vat_nr"); + const char *address = arg_str(r->args, "address"); + const char *postal = arg_str(r->args, "postal_code"); + const char *city = arg_str(r->args, "city"); + const char *country = arg_str(r->args, "country"); + const char *email = arg_str(r->args, "email"); + const char *phone = arg_str(r->args, "phone"); + const char *moms = arg_str(r->args, "moms_period"); + const char *framework = arg_str(r->args, "framework"); + int64_t fy_month = 0; + arg_int(r->args, "fiscal_year_start_month", &fy_month); + if (!name && !org_nr && !vat_nr && !address && !postal && !city && + !country && !email && !phone && !moms && !framework && fy_month == 0) + return fail(r, "INVALID_ARGS", "nothing to update"); + if (name && !*name) + return fail(r, "INVALID_ARGS", "name cannot be empty"); + if (fy_month && (fy_month < 1 || fy_month > 12)) + return fail(r, "INVALID_ARGS", "fiscal_year_start_month must be 1-12"); + if (moms && strcmp(moms, "month") != 0 && strcmp(moms, "quarter") != 0 && + strcmp(moms, "year") != 0) + return fail(r, "INVALID_ARGS", "moms_period must be month, quarter or year"); + if (framework && strcmp(framework, "K2") != 0 && + strcmp(framework, "K3") != 0) + return fail(r, "INVALID_ARGS", "framework must be K2 or K3"); + + sqlite3_stmt *st = NULL; + if (sqlite3_prepare_v2( + r->db, + "UPDATE orgs SET" + " name=COALESCE(?2,name), org_nr=COALESCE(?3,org_nr)," + " vat_nr=COALESCE(?4,vat_nr), address=COALESCE(?5,address)," + " postal_code=COALESCE(?6,postal_code), city=COALESCE(?7,city)," + " country=COALESCE(?8,country), email=COALESCE(?9,email)," + " phone=COALESCE(?10,phone)," + " fiscal_year_start_month=CASE WHEN ?11=0" + " THEN fiscal_year_start_month ELSE ?11 END," + " moms_period=COALESCE(?12,moms_period)," + " framework=COALESCE(?13,framework)" + " WHERE id=?1", + -1, &st, NULL) != SQLITE_OK) + return fail(r, "INTERNAL", "database error"); + sqlite3_bind_int64(st, 1, r->org_id); + const char *texts[9] = { name, org_nr, vat_nr, address, postal, + city, country, email, phone }; + for (int i = 0; i < 9; i++) { + if (texts[i]) + sqlite3_bind_text(st, i + 2, texts[i], -1, SQLITE_TRANSIENT); + else + sqlite3_bind_null(st, i + 2); + } + sqlite3_bind_int64(st, 11, fy_month); + if (moms) + sqlite3_bind_text(st, 12, moms, -1, SQLITE_TRANSIENT); + else + sqlite3_bind_null(st, 12); + if (framework) + sqlite3_bind_text(st, 13, framework, -1, SQLITE_TRANSIENT); + else + sqlite3_bind_null(st, 13); + int rc = sqlite3_step(st); + sqlite3_finalize(st); + if (rc != SQLITE_DONE) + return fail(r, "INTERNAL", sqlite3_errmsg(r->db)); + + char *reqjson = audit_args_json(r->args); + audit_append(r->db, r->org_id, r->sess->user_id, r->sess->token_id, + "org.update", reqjson, "OK", NULL); + free(reqjson); + + st = NULL; + if (sqlite3_prepare_v2(r->db, "SELECT " ORG_COLUMNS + " FROM orgs WHERE id=?1", + -1, &st, NULL) != SQLITE_OK) + return fail(r, "INTERNAL", "database error"); + sqlite3_bind_int64(st, 1, r->org_id); + yyjson_mut_val *o = NULL; + if (sqlite3_step(st) == SQLITE_ROW) + o = org_json(r, st); + sqlite3_finalize(st); + if (!o) + return fail(r, "NOT_FOUND", "org not found"); + return o; +} + static yyjson_mut_val *h_org_member_list(struct req *r) { yyjson_mut_val *items = yyjson_mut_arr(r->rdoc); @@ -3572,6 +3660,8 @@ const struct command g_commands[] = { { "org.list", "List orgs for the current user", PERM_READ, 0, 0, 0, h_org_list }, { "org.get", "Get org details", PERM_READ, 1, 0, 0, h_org_get }, + { "org.update", "Update org details (owner)", PERM_OWNER, 1, 1, 1, + h_org_update }, { "org.member_list", "List org members", PERM_READ, 1, 0, 0, h_org_member_list }, { "org.member_add", "Add a member to the org", PERM_OWNER, 1, 1, 1, diff --git a/tests/test_core.c b/tests/test_core.c index 5960665..a9910e9 100644 --- a/tests/test_core.c +++ b/tests/test_core.c @@ -393,6 +393,34 @@ int main(void) CHECK_STR(d, "result.items.0.role", "owner"); yyjson_doc_free(d); + d = call(reqf("{\"v\":1,\"id\":\"8b\",\"cmd\":\"org.update\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"org_nr\":\"559331-2126\",\"vat_nr\":\"SE559331212601\"," + "\"address\":\"Lingonvägen 9\",\"postal_code\":\"192 48\"," + "\"city\":\"Sollentuna\",\"email\":\"a@b.se\"," + "\"phone\":\"+46700000000\"}}", + g_session, (int)org_id)); + CHECK_OK(d); + CHECK_STR(d, "result.vat_nr", "SE559331212601"); + CHECK_STR(d, "result.org_nr", "559331-2126"); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"8c\",\"cmd\":\"org.get\"," + "\"session\":\"%s\",\"org\":%d}", + g_session, (int)org_id)); + CHECK_OK(d); + CHECK_STR(d, "result.address", "Lingonvägen 9"); + CHECK_STR(d, "result.postal_code", "192 48"); + CHECK_STR(d, "result.city", "Sollentuna"); + yyjson_doc_free(d); + + d = call(reqf("{\"v\":1,\"id\":\"8d\",\"cmd\":\"org.update\"," + "\"session\":\"%s\",\"org\":%d,\"args\":" + "{\"moms_period\":\"week\"}}", + g_session, (int)org_id)); + CHECK_STR(d, "error.code", "INVALID_ARGS"); + yyjson_doc_free(d); + d = call(reqf("{\"v\":1,\"id\":\"9\",\"cmd\":\"session.use_org\"," "\"session\":\"%s\",\"args\":{\"org\":%d}}", g_session, (int)org_id)); |
