aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2021-10-09 10:27:45 +0200
committerJoris2021-10-10 21:21:32 +0200
commitaf1177e814d19e63ce39c42fc7c5888e4b3d9604 (patch)
tree9e8d495f21a82e8cff92fe7692eb856b0e900e07
parenta370f989fe3b864676ed9aecf57f70e55e7958b2 (diff)
downloadbudget-af1177e814d19e63ce39c42fc7c5888e4b3d9604.tar.gz
budget-af1177e814d19e63ce39c42fc7c5888e4b3d9604.tar.bz2
budget-af1177e814d19e63ce39c42fc7c5888e4b3d9604.zip
Search by category
-rw-r--r--src/controller/payments.rs4
-rw-r--r--src/db/payments.rs48
-rw-r--r--src/queries.rs6
-rw-r--r--src/templates.rs1
-rw-r--r--templates/payment/create.html26
-rw-r--r--templates/payment/table.html20
6 files changed, 82 insertions, 23 deletions
diff --git a/src/controller/payments.rs b/src/controller/payments.rs
index ab4bd92..883f9e1 100644
--- a/src/controller/payments.rs
+++ b/src/controller/payments.rs
@@ -22,6 +22,7 @@ pub async fn table(
let payments =
db::payments::list_for_table(&wallet.pool, &query, PER_PAGE).await;
let max_page = (count.count as f32 / PER_PAGE as f32).ceil() as i64;
+ let categories = db::categories::list(&wallet.pool).await;
let mut context = Context::new();
context.insert("header", &templates::Header::Payments);
@@ -32,6 +33,7 @@ pub async fn table(
context.insert("query", &query);
context.insert("count", &count.count);
context.insert("total_cost", &count.total_cost);
+ context.insert("categories", &categories);
utils::template(
&wallet.assets,
@@ -99,6 +101,7 @@ pub async fn create(
search: None,
frequency: Some(create_payment.frequency),
highlight: Some(id),
+ category: None,
};
utils::redirect(&format!(
"/{}",
@@ -178,6 +181,7 @@ pub async fn update(
search: None,
frequency: Some(frequency),
highlight: Some(id),
+ category: None,
};
utils::redirect(&format!("/{}", queries::payments_url(query)))
} else {
diff --git a/src/db/payments.rs b/src/db/payments.rs
index 35e7f68..624ba9f 100644
--- a/src/db/payments.rs
+++ b/src/db/payments.rs
@@ -40,14 +40,19 @@ WHERE
payments.deleted_at IS NULL
AND payments.frequency = ?
{}
+ {}
"#,
- search_query(search.clone())
+ search_query(search.clone()),
+ category_query(payment_query.category)
);
- let res = bind_search(
- sqlx::query_as::<_, Count>(&query)
- .bind(payment_query.frequency.unwrap_or(Frequency::Punctual)),
- search,
+ let res = bind_category(
+ bind_search(
+ sqlx::query_as::<_, Count>(&query)
+ .bind(payment_query.frequency.unwrap_or(Frequency::Punctual)),
+ search,
+ ),
+ payment_query.category,
)
.fetch_one(pool)
.await;
@@ -93,18 +98,23 @@ WHERE
payments.deleted_at IS NULL
AND payments.frequency = ?
{}
+ {}
ORDER BY
payments.date DESC
LIMIT ?
OFFSET ?
"#,
- search_query(search.clone())
+ search_query(search.clone()),
+ category_query(payment_query.category)
);
- let res = bind_search(
- sqlx::query_as::<_, payment::Table>(&query)
- .bind(payment_query.frequency.unwrap_or(Frequency::Punctual)),
- search,
+ let res = bind_category(
+ bind_search(
+ sqlx::query_as::<_, payment::Table>(&query)
+ .bind(payment_query.frequency.unwrap_or(Frequency::Punctual)),
+ search,
+ ),
+ payment_query.category,
)
.bind(per_page)
.bind(offset)
@@ -159,6 +169,24 @@ fn bind_search<'a, Row: FromRow<'a, SqliteRow>>(
})
}
+fn category_query(category: Option<i64>) -> String {
+ if category.is_some() {
+ "AND category_id = ?".to_string()
+ } else {
+ "".to_string()
+ }
+}
+
+fn bind_category<'a, Row: FromRow<'a, SqliteRow>>(
+ query: sqlx::query::QueryAs<'a, Sqlite, Row, SqliteArguments<'a>>,
+ category: Option<i64>,
+) -> sqlx::query::QueryAs<'a, Sqlite, Row, SqliteArguments<'a>> {
+ match category {
+ Some(id) => query.bind(id),
+ _ => query,
+ }
+}
+
pub async fn list_for_stats(pool: &SqlitePool) -> Vec<payment::Stat> {
let query = r#"
SELECT
diff --git a/src/queries.rs b/src/queries.rs
index a7ba28c..df57bd8 100644
--- a/src/queries.rs
+++ b/src/queries.rs
@@ -7,6 +7,7 @@ pub struct Payments {
pub search: Option<String>,
pub frequency: Option<Frequency>,
pub highlight: Option<i64>,
+ pub category: Option<i64>,
}
pub fn payments_url(q: Payments) -> String {
@@ -38,6 +39,11 @@ pub fn payments_url(q: Payments) -> String {
_ => (),
};
+ match q.category {
+ Some(id) => params.push(format!("category={}", id)),
+ _ => (),
+ };
+
if params.is_empty() {
"".to_string()
} else {
diff --git a/src/templates.rs b/src/templates.rs
index 7e3753a..89b0ed8 100644
--- a/src/templates.rs
+++ b/src/templates.rs
@@ -36,6 +36,7 @@ fn payments_params(args: &HashMap<String, Value>) -> Result<Value> {
"search": args.get("search"),
"frequency": args.get("frequency"),
"highlight": args.get("highlight"),
+ "category": args.get("category"),
});
match serde_json::from_value(q) {
diff --git a/templates/payment/create.html b/templates/payment/create.html
index aea6fcd..5bae767 100644
--- a/templates/payment/create.html
+++ b/templates/payment/create.html
@@ -72,18 +72,20 @@
{% set category_id = form.category_id | default(value="") %}
- <label class="g-Form__Label" for="category_id">Catégorie</label>
- <select name="category_id" id="category_id" class="g-Form__Select" required>
- {% for category in categories %}
- <option
- value="{{ category.id }}"
- style="color: {{ category.color }}"
- {% if "" ~ category.id == category_id %} selected {% endif %}
- >
- {{ category.name }}
- </option>
- {% endfor %}
- </select>
+ <label class="g-Form__Label" for="category_id">
+ Catégorie
+ <select name="category_id" id="category_id" class="g-Form__Select" required>
+ {% for category in categories %}
+ <option
+ value="{{ category.id }}"
+ style="color: {{ category.color }}"
+ {% if "" ~ category.id == category_id %} selected {% endif %}
+ >
+ {{ category.name }}
+ </option>
+ {% endfor %}
+ </select>
+ </label>
{% set date = form.date | default(value=now() | date(format="%Y-%m-%d")) %}
diff --git a/templates/payment/table.html b/templates/payment/table.html
index 19b56b4..5234e05 100644
--- a/templates/payment/table.html
+++ b/templates/payment/table.html
@@ -44,6 +44,23 @@
class="g-Form__Input g-Payments__SearchInput"
value="{{ query.search }}"
/>
+
+ <label class="g-Form__Label">
+ Catégorie
+ <select name="category" class="g-Form__Select">
+ <option disabled selected value></option>
+ {% for category in categories %}
+ <option
+ value="{{ category.id }}"
+ style="color: {{ category.color }}"
+ {% if category.id == query.category %} selected {% endif %}
+ >
+ {{ category.name }}
+ </option>
+ {% endfor %}
+ </select>
+ </label>
+
<input type="submit" class="g-Button__Search" value="🔍">
</form>
{% endif %}
@@ -118,7 +135,8 @@
{{ paging::paging(
url="/" ~ payments_params(
search=query.search,
- frequency=query.frequency
+ frequency=query.frequency,
+ category=query.category
),
page=page,
max_page=max_page