aboutsummaryrefslogtreecommitdiff
path: root/backend/src/handlers/product.rs
diff options
context:
space:
mode:
Diffstat (limited to 'backend/src/handlers/product.rs')
-rw-r--r--backend/src/handlers/product.rs138
1 files changed, 138 insertions, 0 deletions
diff --git a/backend/src/handlers/product.rs b/backend/src/handlers/product.rs
new file mode 100644
index 0000000..41a47a0
--- /dev/null
+++ b/backend/src/handlers/product.rs
@@ -0,0 +1,138 @@
1use crate::models::{Customer, NewProduct, Product, Rating, UpdateProduct};
2use crate::schema::customer::dsl as cust;
3use crate::schema::product::dsl::*;
4use crate::schema::rating::dsl as rating;
5use crate::TPool;
6
7use actix_web::{web, HttpResponse, Responder};
8use chrono::naive::NaiveDate;
9use diesel::prelude::*;
10use log::{error, info};
11use serde::{Deserialize, Serialize};
12
13pub async fn new_product(
14 pool: web::Data<TPool>,
15 item: web::Json<NewProduct>,
16) -> impl Responder {
17 info!("New product hit: {:?}", item.name);
18 let conn = pool.get().unwrap();
19 diesel::insert_into(product)
20 .values(item.into_inner())
21 .execute(&conn)
22 .expect("Coundn't connect to DB");
23 HttpResponse::Ok().body("Inserted successfully!")
24}
25
26pub async fn product_details(
27 pool: web::Data<TPool>,
28 product_id: web::Path<i32>,
29) -> impl Responder {
30 let conn = pool.get().unwrap();
31 let product_id = product_id.into_inner();
32 info!("Fetching product details for {}", product_id);
33 let selected_product = product
34 .filter(id.eq(&product_id))
35 .limit(1)
36 .first::<Product>(&conn);
37 match selected_product {
38 Ok(m) => {
39 info!("Found product: {}", product_id);
40 HttpResponse::Ok().json(m)
41 }
42 Err(_) => {
43 error!("Product not found: {}", product_id);
44 HttpResponse::NotFound().finish()
45 }
46 }
47}
48
49pub async fn update_product(
50 pool: web::Data<TPool>,
51 product_id: web::Path<i32>,
52 product_details: web::Json<UpdateProduct>,
53) -> impl Responder {
54 let conn = pool.get().unwrap();
55 let product_id = product_id.into_inner();
56 let product_details = product_details.into_inner();
57 info!("Updating product: {:?}", product_id);
58 match diesel::update(product.filter(id.eq(product_id)))
59 .set((
60 name.eq(product_details.name),
61 kind.eq(product_details.kind),
62 price.eq(product_details.price),
63 description.eq(product_details.description),
64 ))
65 .execute(&conn)
66 {
67 Ok(_) => {
68 return HttpResponse::Ok().body("Changed product successfully")
69 }
70 _ => {
71 return HttpResponse::InternalServerError()
72 .body("Unable to update record")
73 }
74 }
75}
76
77pub async fn get_all_products(pool: web::Data<TPool>) -> impl Responder {
78 let conn = pool.get().unwrap();
79 info!("Generating and returning catalog ...");
80 match product.load::<Product>(&conn) {
81 Ok(products) => return HttpResponse::Ok().json(&products),
82 Err(_) => {
83 return HttpResponse::InternalServerError()
84 .body("Unable to fetch product catalog")
85 }
86 }
87}
88
89#[derive(Serialize, Deserialize, Debug)]
90struct ProductRating {
91 pub comment_text: Option<String>,
92 pub comment_date: NaiveDate,
93 pub product_name: String,
94 pub customer_name: String,
95 pub stars: Option<i32>,
96}
97
98pub async fn get_product_reviews(
99 pool: web::Data<TPool>,
100 product_id: web::Path<i32>,
101) -> impl Responder {
102 let conn = pool.get().unwrap();
103 info!("Fetching product reviews for {}", product_id);
104 let pid = product_id.into_inner();
105 let rating_entries = rating::rating
106 .filter(rating::product_id.eq(pid))
107 .load::<Rating>(&conn)
108 .expect("Couldn't connect to DB");
109 let json_ratings = rating_entries
110 .into_iter()
111 .map(move |p| {
112 let selected_product = product
113 .filter(id.eq(&p.product_id.unwrap()))
114 .limit(1)
115 .first::<Product>(&conn)
116 .unwrap()
117 .name
118 .clone();
119
120 let selected_customer = cust::customer
121 .filter(cust::id.eq(&p.customer_id.unwrap()))
122 .limit(1)
123 .first::<Customer>(&conn)
124 .unwrap()
125 .username
126 .clone();
127
128 ProductRating {
129 comment_text: p.comment_text,
130 comment_date: p.comment_date.unwrap(),
131 product_name: selected_product,
132 customer_name: selected_customer,
133 stars: p.stars,
134 }
135 })
136 .collect::<Vec<_>>();
137 return HttpResponse::Ok().json(&json_ratings);
138}