summaryrefslogtreecommitdiff
path: root/src/cmd_employees.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd_employees.c')
-rw-r--r--src/cmd_employees.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/cmd_employees.c b/src/cmd_employees.c
index 788dd83..952bd2b 100644
--- a/src/cmd_employees.c
+++ b/src/cmd_employees.c
@@ -17,7 +17,7 @@
#define EMPLOYEE_COLUMNS \
"id,name,personal_no_enc,address,postal_code,city,bank_account," \
"salary_account,monthly_salary_ore,tax_table,tax_column,active," \
- "created_at,COALESCE(updated_at,'')"
+ "created_at,COALESCE(updated_at,''),email"
static int personal_no_valid(const char *s)
{
@@ -90,6 +90,8 @@ static yyjson_mut_val *employee_json(struct req *r, sqlite3_stmt *st)
sq(sqlite3_column_text(st, 12)));
yyjson_mut_obj_add_strcpy(r->rdoc, o, "updated_at",
sq(sqlite3_column_text(st, 13)));
+ yyjson_mut_obj_add_strcpy(r->rdoc, o, "email",
+ sq(sqlite3_column_text(st, 14)));
return o;
}
@@ -129,6 +131,7 @@ struct employee_input {
const char *city;
const char *bank_account;
const char *salary_account;
+ const char *email;
int64_t monthly_salary_ore;
int have_salary;
int64_t tax_table;
@@ -149,6 +152,7 @@ static void employee_input_read(struct req *r, struct employee_input *in)
in->city = arg_str(r->args, "city");
in->bank_account = arg_str(r->args, "bank_account");
in->salary_account = arg_str(r->args, "salary_account");
+ in->email = arg_str(r->args, "email");
in->have_salary = arg_int(r->args, "monthly_salary_ore",
&in->monthly_salary_ore);
in->have_table = arg_int(r->args, "tax_table", &in->tax_table);
@@ -210,6 +214,21 @@ static int employee_input_validate(struct req *r,
fail(r, "INVALID_ARGS", "tax_column must be between 1 and 6");
return -1;
}
+ if (in->email) {
+ size_t len = strlen(in->email);
+ if (len > 254) {
+ fail(r, "INVALID_ARGS", "email is too long");
+ return -1;
+ }
+ for (const char *p = in->email; *p; p++) {
+ unsigned char ch = (unsigned char)*p;
+ if (ch < 32 || ch == 127) {
+ fail(r, "INVALID_ARGS",
+ "email must not contain control characters");
+ return -1;
+ }
+ }
+ }
return 0;
}
@@ -346,6 +365,7 @@ static yyjson_mut_val *h_employee_create(struct req *r)
const char *postal = in.postal_code ? in.postal_code : "";
const char *city = in.city ? in.city : "";
const char *bank = in.bank_account ? in.bank_account : "";
+ const char *email = in.email ? in.email : "";
if (r->dry_run) {
free(stored);
@@ -365,6 +385,7 @@ static yyjson_mut_val *h_employee_create(struct req *r)
yyjson_mut_obj_add_int(r->rdoc, o, "tax_table", in.tax_table);
yyjson_mut_obj_add_int(r->rdoc, o, "tax_column", in.tax_column);
yyjson_mut_obj_add_bool(r->rdoc, o, "active", true);
+ yyjson_mut_obj_add_strcpy(r->rdoc, o, "email", email);
yyjson_mut_obj_add_bool(r->rdoc, o, "dry_run", true);
return o;
}
@@ -376,8 +397,8 @@ static yyjson_mut_val *h_employee_create(struct req *r)
r->db,
"INSERT INTO employees(org_id,name,personal_no_enc,address,"
"postal_code,city,bank_account,salary_account,monthly_salary_ore,"
- "tax_table,tax_column,created_at)"
- " VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12)",
+ "tax_table,tax_column,created_at,email)"
+ " VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13)",
-1, &st, NULL) != SQLITE_OK) {
free(stored);
return db_error(r);
@@ -394,6 +415,7 @@ static yyjson_mut_val *h_employee_create(struct req *r)
sqlite3_bind_int64(st, 10, in.tax_table);
sqlite3_bind_int64(st, 11, in.tax_column);
sqlite3_bind_text(st, 12, ts, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(st, 13, email, -1, SQLITE_TRANSIENT);
int rc = sqlite3_step(st);
sqlite3_finalize(st);
free(stored);
@@ -427,7 +449,7 @@ static yyjson_mut_val *h_employee_update(struct req *r)
if (employee_input_validate(r, &in, 0) != 0)
return NULL;
if (!in.name && !in.personal_no && !in.address && !in.postal_code &&
- !in.city && !in.bank_account && !in.salary_account &&
+ !in.city && !in.bank_account && !in.salary_account && !in.email &&
!in.have_salary && !in.have_table && !in.have_column &&
!in.have_active)
return fail(r, "INVALID_ARGS", "nothing to update");
@@ -457,7 +479,7 @@ static yyjson_mut_val *h_employee_update(struct req *r)
"CASE WHEN ?11<0 THEN tax_table ELSE ?11 END,"
"CASE WHEN ?12<0 THEN tax_column ELSE ?12 END,"
"CASE WHEN ?13<0 THEN active ELSE ?13 END,"
- "created_at,COALESCE(updated_at,'')"
+ "created_at,COALESCE(updated_at,''),COALESCE(?14,email)"
" FROM employees WHERE org_id=?1 AND id=?2",
-1, &st, NULL) != SQLITE_OK) {
free(stored);
@@ -477,6 +499,7 @@ static yyjson_mut_val *h_employee_update(struct req *r)
sqlite3_bind_int64(st, 11, in.have_table ? in.tax_table : -1);
sqlite3_bind_int64(st, 12, in.have_column ? in.tax_column : -1);
sqlite3_bind_int64(st, 13, in.have_active ? in.active : -1);
+ bind_text_or_null(st, 14, in.email);
yyjson_mut_val *o = NULL;
if (sqlite3_step(st) == SQLITE_ROW)
o = employee_json(r, st);
@@ -506,7 +529,8 @@ static yyjson_mut_val *h_employee_update(struct req *r)
" tax_table=CASE WHEN ?11<0 THEN tax_table ELSE ?11 END,"
" tax_column=CASE WHEN ?12<0 THEN tax_column ELSE ?12 END,"
" active=CASE WHEN ?13<0 THEN active ELSE ?13 END,"
- " updated_at=?14 WHERE org_id=?1 AND id=?2",
+ " email=COALESCE(?14,email),"
+ " updated_at=?15 WHERE org_id=?1 AND id=?2",
-1, &st, NULL) != SQLITE_OK) {
free(stored);
return db_error(r);
@@ -524,7 +548,8 @@ static yyjson_mut_val *h_employee_update(struct req *r)
sqlite3_bind_int64(st, 11, in.have_table ? in.tax_table : -1);
sqlite3_bind_int64(st, 12, in.have_column ? in.tax_column : -1);
sqlite3_bind_int64(st, 13, in.have_active ? in.active : -1);
- sqlite3_bind_text(st, 14, ts, -1, SQLITE_TRANSIENT);
+ bind_text_or_null(st, 14, in.email);
+ sqlite3_bind_text(st, 15, ts, -1, SQLITE_TRANSIENT);
int rc = sqlite3_step(st);
sqlite3_finalize(st);
free(stored);
@@ -617,6 +642,7 @@ static const struct cmd_arg args_employee_create[] = {
{ "postal_code", ARG_STR, 0, NULL, NULL, "Postal code" },
{ "city", ARG_STR, 0, NULL, NULL, "City" },
{ "bank_account", ARG_STR, 0, NULL, NULL, "Bank account for the net pay" },
+ { "email", ARG_STR, 0, NULL, NULL, "E-mail for lönebesked" },
{ "salary_account", ARG_STR, 0, NULL, NULL,
"Salary account, digits only; defaults to payroll_salary_account" },
{ "monthly_salary_ore", ARG_INT, 0, "0", NULL,
@@ -634,6 +660,7 @@ static const struct cmd_arg args_employee_update[] = {
{ "postal_code", ARG_STR, 0, NULL, NULL, "Postal code" },
{ "city", ARG_STR, 0, NULL, NULL, "City" },
{ "bank_account", ARG_STR, 0, NULL, NULL, "Bank account for the net pay" },
+ { "email", ARG_STR, 0, NULL, NULL, "E-mail for lönebesked" },
{ "salary_account", ARG_STR, 0, NULL, NULL, "Salary account, digits only" },
{ "monthly_salary_ore", ARG_INT, 0, NULL, NULL,
"Monthly gross salary in öre" },