diff options
author | Joris | 2021-10-09 10:27:45 +0200 |
---|---|---|
committer | Joris | 2021-10-10 21:21:32 +0200 |
commit | af1177e814d19e63ce39c42fc7c5888e4b3d9604 (patch) | |
tree | 9e8d495f21a82e8cff92fe7692eb856b0e900e07 | |
parent | a370f989fe3b864676ed9aecf57f70e55e7958b2 (diff) |
Search by category
-rw-r--r-- | src/controller/payments.rs | 4 | ||||
-rw-r--r-- | src/db/payments.rs | 48 | ||||
-rw-r--r-- | src/queries.rs | 6 | ||||
-rw-r--r-- | src/templates.rs | 1 | ||||
-rw-r--r-- | templates/payment/create.html | 26 | ||||
-rw-r--r-- | templates/payment/table.html | 20 |
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 |