summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/PROTOCOL.md3
-rw-r--r--src/commands.c13
-rw-r--r--tests/test_core.c21
3 files changed, 31 insertions, 6 deletions
diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md
index 20617db..8ee1b2c 100644
--- a/docs/PROTOCOL.md
+++ b/docs/PROTOCOL.md
@@ -369,7 +369,8 @@ vouchers at posting time (`attachment_ids`) or afterwards via
rows, and `attachment.unlink` removes one (an unlinked attachment returns
to the inbox). One attachment may be linked to several vouchers (the link
key is the voucher/attachment pair); linking the same pair twice is a
-`CONFLICT`.
+`CONFLICT`. `attachment.list` with `voucher_id` returns every attachment
+linked to that voucher and each item carries that `voucher_id`.
### 7.6 Reports
diff --git a/src/commands.c b/src/commands.c
index 500c9a3..f03e0e4 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -3484,12 +3484,15 @@ static yyjson_mut_val *h_attachment_list(struct req *r)
r->db,
"SELECT a.id,a.filename,a.mime,a.size_bytes,a.created_at,a.sha256,"
"(SELECT va.voucher_id FROM voucher_attachments va"
- " WHERE va.org_id=a.org_id AND va.attachment_id=a.id LIMIT 1)"
+ " WHERE va.org_id=a.org_id AND va.attachment_id=a.id"
+ " AND (?2=0 OR va.voucher_id=?2)"
+ " ORDER BY va.voucher_id LIMIT 1)"
" FROM attachments a WHERE a.org_id=?1"
- " AND (?2=0 OR (SELECT va.voucher_id FROM voucher_attachments va"
- " WHERE va.org_id=a.org_id AND va.attachment_id=a.id LIMIT 1)=?2)"
- " AND (?3=0 OR NOT EXISTS(SELECT 1 FROM voucher_attachments va2"
- " WHERE va2.org_id=a.org_id AND va2.attachment_id=a.id))"
+ " AND (?2=0 OR EXISTS(SELECT 1 FROM voucher_attachments va2"
+ " WHERE va2.org_id=a.org_id AND va2.attachment_id=a.id"
+ " AND va2.voucher_id=?2))"
+ " AND (?3=0 OR NOT EXISTS(SELECT 1 FROM voucher_attachments va3"
+ " WHERE va3.org_id=a.org_id AND va3.attachment_id=a.id))"
" AND a.id>?4 ORDER BY a.id LIMIT ?5",
-1, &st, NULL) != SQLITE_OK)
return fail(r, "INTERNAL", "database error");
diff --git a/tests/test_core.c b/tests/test_core.c
index 66f8207..6520d4b 100644
--- a/tests/test_core.c
+++ b/tests/test_core.c
@@ -919,6 +919,8 @@ int main(void)
g_session, (int)org_id, (long long)att_id));
CHECK_OK(d);
CHECK(yyjson_arr_size(jget(d, "result.attachment_ids")) == 1);
+ int64_t rent_id = jint(d, "result.id");
+ CHECK(rent_id > 0);
yyjson_doc_free(d);
d = call(reqf("{\"v\":1,\"id\":\"61\",\"cmd\":\"attachment.list\","
@@ -996,6 +998,25 @@ int main(void)
CHECK_STR(d, "error.code", "NOT_FOUND");
yyjson_doc_free(d);
+ /* listing by voucher returns every linked attachment, with that voucher */
+ d = call(reqf("{\"v\":1,\"id\":\"61j\",\"cmd\":\"attachment.list\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)rent_id));
+ CHECK_OK(d);
+ CHECK(yyjson_arr_size(jget(d, "result.items")) == 1);
+ CHECK(jint(d, "result.items.0.id") == att_id);
+ CHECK(jint(d, "result.items.0.voucher_id") == rent_id);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61k\",\"cmd\":\"attachment.list\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)sale_id));
+ CHECK_OK(d);
+ CHECK(yyjson_arr_size(jget(d, "result.items")) == 1);
+ CHECK(jint(d, "result.items.0.id") == att_id);
+ CHECK(jint(d, "result.items.0.voucher_id") == sale_id);
+ yyjson_doc_free(d);
+
/* voucher.list reports the attachment count */
d = call(reqf("{\"v\":1,\"id\":\"61i\",\"cmd\":\"voucher.list\","
"\"session\":\"%s\",\"org\":%d,\"args\":{\"limit\":5}}",