diff options
Diffstat (limited to 'backend')
-rw-r--r-- | backend/migrations/2020-12-25-041256_cart_quantity/down.sql | 4 | ||||
-rw-r--r-- | backend/migrations/2020-12-25-041256_cart_quantity/up.sql | 3 | ||||
-rw-r--r-- | backend/migrations/2020-12-25-150728_transaction_date/down.sql | 4 | ||||
-rw-r--r-- | backend/migrations/2020-12-25-150728_transaction_date/up.sql | 4 | ||||
-rw-r--r-- | backend/src/bin/server.rs | 18 | ||||
-rw-r--r-- | backend/src/handlers/cart_items.rs | 131 | ||||
-rw-r--r-- | backend/src/handlers/mod.rs | 1 | ||||
-rw-r--r-- | backend/src/handlers/transaction.rs | 74 | ||||
-rw-r--r-- | backend/src/handlers/users.rs | 4 | ||||
-rw-r--r-- | backend/src/models.rs | 28 | ||||
-rw-r--r-- | backend/src/schema.rs | 2 |
11 files changed, 253 insertions, 20 deletions
diff --git a/backend/migrations/2020-12-25-041256_cart_quantity/down.sql b/backend/migrations/2020-12-25-041256_cart_quantity/down.sql new file mode 100644 index 0000000..94aec7a --- /dev/null +++ b/backend/migrations/2020-12-25-041256_cart_quantity/down.sql | |||
@@ -0,0 +1,4 @@ | |||
1 | -- This file should undo anything in `up.sql` | ||
2 | |||
3 | alter table cart_items | ||
4 | drop column quantity; | ||
diff --git a/backend/migrations/2020-12-25-041256_cart_quantity/up.sql b/backend/migrations/2020-12-25-041256_cart_quantity/up.sql new file mode 100644 index 0000000..314c11c --- /dev/null +++ b/backend/migrations/2020-12-25-041256_cart_quantity/up.sql | |||
@@ -0,0 +1,3 @@ | |||
1 | -- Your SQL goes here | ||
2 | alter table cart_items | ||
3 | add quantity integer default 1; | ||
diff --git a/backend/migrations/2020-12-25-150728_transaction_date/down.sql b/backend/migrations/2020-12-25-150728_transaction_date/down.sql new file mode 100644 index 0000000..18fe306 --- /dev/null +++ b/backend/migrations/2020-12-25-150728_transaction_date/down.sql | |||
@@ -0,0 +1,4 @@ | |||
1 | -- This file should undo anything in `up.sql` | ||
2 | |||
3 | alter table transaction | ||
4 | drop column order_date; | ||
diff --git a/backend/migrations/2020-12-25-150728_transaction_date/up.sql b/backend/migrations/2020-12-25-150728_transaction_date/up.sql new file mode 100644 index 0000000..76f9820 --- /dev/null +++ b/backend/migrations/2020-12-25-150728_transaction_date/up.sql | |||
@@ -0,0 +1,4 @@ | |||
1 | -- Your SQL goes here | ||
2 | |||
3 | alter table transaction | ||
4 | add order_date date not null default curdate(); | ||
diff --git a/backend/src/bin/server.rs b/backend/src/bin/server.rs index 7c67e4f..310914e 100644 --- a/backend/src/bin/server.rs +++ b/backend/src/bin/server.rs | |||
@@ -5,7 +5,7 @@ use actix_web::{web, App, HttpServer}; | |||
5 | use diesel::r2d2::{ConnectionManager, Pool}; | 5 | use diesel::r2d2::{ConnectionManager, Pool}; |
6 | use diesel::MysqlConnection; | 6 | use diesel::MysqlConnection; |
7 | use furby::handlers::smoke::manual_hello; | 7 | use furby::handlers::smoke::manual_hello; |
8 | use furby::handlers::{cart_items, product, rating, users}; | 8 | use furby::handlers::{cart_items, product, rating, transaction, users}; |
9 | use rand::Rng; | 9 | use rand::Rng; |
10 | 10 | ||
11 | #[actix_web::main] | 11 | #[actix_web::main] |
@@ -48,6 +48,7 @@ async fn main() -> std::io::Result<()> { | |||
48 | web::scope("/user") | 48 | web::scope("/user") |
49 | .route("/existing", web::post().to(users::name_exists)) | 49 | .route("/existing", web::post().to(users::name_exists)) |
50 | .route("/login", web::post().to(users::login)) | 50 | .route("/login", web::post().to(users::login)) |
51 | .route("/logout", web::post().to(users::logout)) | ||
51 | .route("/{uname}", web::get().to(users::user_details)) | 52 | .route("/{uname}", web::get().to(users::user_details)) |
52 | .route("/new", web::post().to(users::new_user)) | 53 | .route("/new", web::post().to(users::new_user)) |
53 | .route( | 54 | .route( |
@@ -75,6 +76,10 @@ async fn main() -> std::io::Result<()> { | |||
75 | "/items", | 76 | "/items", |
76 | web::get().to(cart_items::get_user_cart_items), | 77 | web::get().to(cart_items::get_user_cart_items), |
77 | ) | 78 | ) |
79 | .route( | ||
80 | "/total", | ||
81 | web::get().to(cart_items::get_user_cart_total), | ||
82 | ) | ||
78 | .route("/add", web::post().to(cart_items::add_to_cart)) | 83 | .route("/add", web::post().to(cart_items::add_to_cart)) |
79 | .route( | 84 | .route( |
80 | "/remove", | 85 | "/remove", |
@@ -86,6 +91,17 @@ async fn main() -> std::io::Result<()> { | |||
86 | .route("/add", web::post().to(rating::add_rating)) | 91 | .route("/add", web::post().to(rating::add_rating)) |
87 | .route("/remove", web::post().to(rating::remove_rating)), | 92 | .route("/remove", web::post().to(rating::remove_rating)), |
88 | ) | 93 | ) |
94 | .service( | ||
95 | web::scope("/transaction") | ||
96 | .route( | ||
97 | "/checkout", | ||
98 | web::post().to(transaction::checkout_cart), | ||
99 | ) | ||
100 | .route( | ||
101 | "/list", | ||
102 | web::get().to(transaction::list_transactions), | ||
103 | ), | ||
104 | ) | ||
89 | .route("/hey", web::get().to(manual_hello)) | 105 | .route("/hey", web::get().to(manual_hello)) |
90 | }) | 106 | }) |
91 | .bind("127.0.0.1:7878")? | 107 | .bind("127.0.0.1:7878")? |
diff --git a/backend/src/handlers/cart_items.rs b/backend/src/handlers/cart_items.rs index 25baaeb..e17f4c4 100644 --- a/backend/src/handlers/cart_items.rs +++ b/backend/src/handlers/cart_items.rs | |||
@@ -7,7 +7,7 @@ use actix_identity::Identity; | |||
7 | use actix_web::{web, HttpResponse, Responder}; | 7 | use actix_web::{web, HttpResponse, Responder}; |
8 | use diesel::prelude::*; | 8 | use diesel::prelude::*; |
9 | use log::{error, info}; | 9 | use log::{error, info}; |
10 | use serde::Deserialize; | 10 | use serde::Serialize; |
11 | 11 | ||
12 | pub async fn add_to_cart( | 12 | pub async fn add_to_cart( |
13 | cookie: Identity, | 13 | cookie: Identity, |
@@ -27,16 +27,41 @@ pub async fn add_to_cart( | |||
27 | let new_cart_item = AddCartItem { | 27 | let new_cart_item = AddCartItem { |
28 | cart_id: selected_user.id, | 28 | cart_id: selected_user.id, |
29 | product_id: item_details, | 29 | product_id: item_details, |
30 | quantity: Some(1), | ||
30 | }; | 31 | }; |
31 | info!( | 32 | info!( |
32 | "cart id: {:?}, product id {:?}", | 33 | "cart id: {:?}, product id {:?}", |
33 | selected_user.id, item_details | 34 | selected_user.id, item_details |
34 | ); | 35 | ); |
35 | diesel::insert_into(cart_items) | 36 | let current_entry = cart_items |
36 | .values((cart_id.eq(selected_user.id), product_id.eq(item_details))) | 37 | .filter(cart_id.eq(selected_user.id)) |
37 | .execute(&conn) | 38 | .filter(product_id.eq(item_details)) |
38 | .expect("Coundn't connect to DB"); | 39 | .limit(1) |
39 | HttpResponse::Ok().body("Inserted successfully!") | 40 | .first::<CartItem>(&conn); |
41 | match current_entry { | ||
42 | Ok(v) => { | ||
43 | info!("Item already present in cart, increasing quantity."); | ||
44 | let old_quantity = v.quantity.unwrap_or(1); | ||
45 | diesel::update( | ||
46 | cart_items | ||
47 | .filter(cart_id.eq(selected_user.id)) | ||
48 | .filter(product_id.eq(item_details)), | ||
49 | ) | ||
50 | .set(quantity.eq(old_quantity + 1)) | ||
51 | .execute(&conn) | ||
52 | .unwrap(); | ||
53 | return HttpResponse::Ok() | ||
54 | .body("Updated quantity successfully!"); | ||
55 | } | ||
56 | Err(_) => { | ||
57 | info!("Item not present, adding to cart."); | ||
58 | diesel::insert_into(cart_items) | ||
59 | .values(new_cart_item) | ||
60 | .execute(&conn) | ||
61 | .expect("Couldn't connect to DB"); | ||
62 | HttpResponse::Ok().body("Inserted successfully!") | ||
63 | } | ||
64 | } | ||
40 | } else { | 65 | } else { |
41 | error!("Unauthorized add to cart action!"); | 66 | error!("Unauthorized add to cart action!"); |
42 | return HttpResponse::Unauthorized() | 67 | return HttpResponse::Unauthorized() |
@@ -58,15 +83,44 @@ pub async fn remove_from_cart( | |||
58 | .limit(1) | 83 | .limit(1) |
59 | .first::<Customer>(&conn) | 84 | .first::<Customer>(&conn) |
60 | .expect("Couldn't connect to DB"); | 85 | .expect("Couldn't connect to DB"); |
61 | 86 | let current_entry = cart_items | |
62 | diesel::delete( | 87 | .filter(cart_id.eq(selected_user.id)) |
63 | cart_items | 88 | .filter(product_id.eq(item_details)) |
64 | .filter(cart_id.eq(selected_user.id)) | 89 | .limit(1) |
65 | .filter(product_id.eq(item_details)), | 90 | .first::<CartItem>(&conn); |
66 | ) | 91 | match current_entry { |
67 | .execute(&conn) | 92 | Ok(v) => { |
68 | .expect("Coundn't connect to DB"); | 93 | info!("Item already present in cart, increasing quantity."); |
69 | HttpResponse::Ok().body("Removed successfully!") | 94 | let old_quantity = v.quantity.unwrap_or(1); |
95 | if old_quantity == 1 { | ||
96 | diesel::delete( | ||
97 | cart_items | ||
98 | .filter(cart_id.eq(selected_user.id)) | ||
99 | .filter(product_id.eq(item_details)), | ||
100 | ) | ||
101 | .execute(&conn) | ||
102 | .expect("Coundn't connect to DB"); | ||
103 | } else { | ||
104 | diesel::update( | ||
105 | cart_items | ||
106 | .filter(cart_id.eq(selected_user.id)) | ||
107 | .filter(product_id.eq(item_details)), | ||
108 | ) | ||
109 | .set(quantity.eq(old_quantity - 1)) | ||
110 | .execute(&conn) | ||
111 | .unwrap(); | ||
112 | return HttpResponse::Ok() | ||
113 | .body("Updated quantity successfully!"); | ||
114 | } | ||
115 | return HttpResponse::Ok() | ||
116 | .body("Updated quantity successfully!"); | ||
117 | } | ||
118 | Err(_) => { | ||
119 | info!("Item not present."); | ||
120 | return HttpResponse::InternalServerError() | ||
121 | .body("Item not found!"); | ||
122 | } | ||
123 | } | ||
70 | } else { | 124 | } else { |
71 | error!("Unauthorized add to cart action!"); | 125 | error!("Unauthorized add to cart action!"); |
72 | return HttpResponse::Unauthorized() | 126 | return HttpResponse::Unauthorized() |
@@ -74,6 +128,12 @@ pub async fn remove_from_cart( | |||
74 | } | 128 | } |
75 | } | 129 | } |
76 | 130 | ||
131 | #[derive(Serialize)] | ||
132 | struct UserCartItem { | ||
133 | product_item: Product, | ||
134 | quantity: i32, | ||
135 | } | ||
136 | |||
77 | pub async fn get_user_cart_items( | 137 | pub async fn get_user_cart_items( |
78 | cookie: Identity, | 138 | cookie: Identity, |
79 | pool: web::Data<TPool>, | 139 | pool: web::Data<TPool>, |
@@ -92,11 +152,15 @@ pub async fn get_user_cart_items( | |||
92 | let cart_products = user_cart_items | 152 | let cart_products = user_cart_items |
93 | .into_iter() | 153 | .into_iter() |
94 | .map(|item| { | 154 | .map(|item| { |
95 | prod::product | 155 | let p = prod::product |
96 | .filter(prod::id.eq(item.product_id)) | 156 | .filter(prod::id.eq(item.product_id)) |
97 | .limit(1) | 157 | .limit(1) |
98 | .first::<Product>(&conn) | 158 | .first::<Product>(&conn) |
99 | .expect("Couldn't connect to db") | 159 | .expect("Couldn't connect to db"); |
160 | UserCartItem { | ||
161 | product_item: p, | ||
162 | quantity: item.quantity.unwrap_or(1), | ||
163 | } | ||
100 | }) | 164 | }) |
101 | .collect::<Vec<_>>(); | 165 | .collect::<Vec<_>>(); |
102 | return HttpResponse::Ok().json(&cart_products); | 166 | return HttpResponse::Ok().json(&cart_products); |
@@ -105,3 +169,36 @@ pub async fn get_user_cart_items( | |||
105 | .body("Need to be logged in to add to cart!"); | 169 | .body("Need to be logged in to add to cart!"); |
106 | } | 170 | } |
107 | } | 171 | } |
172 | |||
173 | pub async fn get_user_cart_total( | ||
174 | cookie: Identity, | ||
175 | pool: web::Data<TPool>, | ||
176 | ) -> impl Responder { | ||
177 | let conn = pool.get().unwrap(); | ||
178 | if let Some(uname) = cookie.identity() { | ||
179 | let selected_user = customer | ||
180 | .filter(username.eq(&uname)) | ||
181 | .limit(1) | ||
182 | .first::<Customer>(&conn) | ||
183 | .expect("Couldn't connect to DB"); | ||
184 | let user_cart_items = cart_items | ||
185 | .filter(cart_id.eq(selected_user.id)) | ||
186 | .load::<CartItem>(&conn) | ||
187 | .expect("Couldn't connect to DB"); | ||
188 | let cart_total: f32 = user_cart_items | ||
189 | .into_iter() | ||
190 | .map(|item| { | ||
191 | let p = prod::product | ||
192 | .filter(prod::id.eq(item.product_id)) | ||
193 | .limit(1) | ||
194 | .first::<Product>(&conn) | ||
195 | .expect("Couldn't connect to db"); | ||
196 | return p.price * item.quantity.unwrap_or(1) as f32; | ||
197 | }) | ||
198 | .sum(); | ||
199 | return HttpResponse::Ok().json(&cart_total); | ||
200 | } else { | ||
201 | return HttpResponse::Unauthorized() | ||
202 | .body("Need to be logged in to add to cart!"); | ||
203 | } | ||
204 | } | ||
diff --git a/backend/src/handlers/mod.rs b/backend/src/handlers/mod.rs index 9416857..e4ecb3a 100644 --- a/backend/src/handlers/mod.rs +++ b/backend/src/handlers/mod.rs | |||
@@ -2,4 +2,5 @@ pub mod cart_items; | |||
2 | pub mod product; | 2 | pub mod product; |
3 | pub mod rating; | 3 | pub mod rating; |
4 | pub mod smoke; | 4 | pub mod smoke; |
5 | pub mod transaction; | ||
5 | pub mod users; | 6 | pub mod users; |
diff --git a/backend/src/handlers/transaction.rs b/backend/src/handlers/transaction.rs new file mode 100644 index 0000000..1e87312 --- /dev/null +++ b/backend/src/handlers/transaction.rs | |||
@@ -0,0 +1,74 @@ | |||
1 | use crate::models::{AddTransaction, CartItem, Customer, Product, Transaction}; | ||
2 | use crate::schema::cart_items::dsl::*; | ||
3 | use crate::schema::customer::dsl::*; | ||
4 | use crate::schema::product::dsl as prod; | ||
5 | use crate::schema::transaction::dsl::*; | ||
6 | use crate::TPool; | ||
7 | |||
8 | use actix_identity::Identity; | ||
9 | use actix_web::{web, HttpResponse, Responder}; | ||
10 | use diesel::prelude::*; | ||
11 | use log::{error, info}; | ||
12 | |||
13 | pub async fn checkout_cart( | ||
14 | pool: web::Data<TPool>, | ||
15 | pmt_kind: String, | ||
16 | cookie: Identity, | ||
17 | ) -> impl Responder { | ||
18 | let conn = pool.get().unwrap(); | ||
19 | info!("Checkout cart for user: {:?}", cookie.identity()); | ||
20 | if let Some(uname) = cookie.identity() { | ||
21 | let selected_user = customer | ||
22 | .filter(username.eq(&uname)) | ||
23 | .limit(1) | ||
24 | .first::<Customer>(&conn) | ||
25 | .expect("Couldn't connect to DB"); | ||
26 | let user_cart_items = cart_items | ||
27 | .filter(cart_id.eq(selected_user.id)) | ||
28 | .load::<CartItem>(&conn) | ||
29 | .expect("Couldn't connect to DB"); | ||
30 | let cart_total = user_cart_items.into_iter().fold(0., |acc, item| { | ||
31 | let item_price = prod::product | ||
32 | .filter(prod::id.eq(item.product_id)) | ||
33 | .limit(1) | ||
34 | .first::<Product>(&conn) | ||
35 | .unwrap() | ||
36 | .price; | ||
37 | acc + item.quantity.unwrap_or(1) as f32 * item_price | ||
38 | }); | ||
39 | let transaction_entry = AddTransaction { | ||
40 | customer_id: Some(selected_user.id), | ||
41 | amount: cart_total, | ||
42 | payment_type: pmt_kind, | ||
43 | }; | ||
44 | diesel::insert_into(transaction) | ||
45 | .values(transaction_entry) | ||
46 | .execute(&conn) | ||
47 | .expect("Coundn't connect to DB"); | ||
48 | return HttpResponse::Ok().body("Transaction performed successfully"); | ||
49 | } else { | ||
50 | return HttpResponse::Unauthorized().body("Login first"); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | pub async fn list_transactions( | ||
55 | pool: web::Data<TPool>, | ||
56 | cookie: Identity, | ||
57 | ) -> impl Responder { | ||
58 | let conn = pool.get().unwrap(); | ||
59 | if let Some(uname) = cookie.identity() { | ||
60 | let selected_user = customer | ||
61 | .filter(username.eq(&uname)) | ||
62 | .limit(1) | ||
63 | .first::<Customer>(&conn) | ||
64 | .expect("Couldn't connect to DB"); | ||
65 | let user_transactions = transaction | ||
66 | .filter(customer_id.eq(selected_user.id)) | ||
67 | .load::<Transaction>(&conn) | ||
68 | .expect("Couldn't connect to DB"); | ||
69 | return HttpResponse::Ok().json(&user_transactions); | ||
70 | } else { | ||
71 | return HttpResponse::Unauthorized() | ||
72 | .body("Need to be logged in to add to cart!"); | ||
73 | } | ||
74 | } | ||
diff --git a/backend/src/handlers/users.rs b/backend/src/handlers/users.rs index 24fb591..a043c1f 100644 --- a/backend/src/handlers/users.rs +++ b/backend/src/handlers/users.rs | |||
@@ -58,7 +58,7 @@ pub async fn login( | |||
58 | login_details: web::Json<Login>, | 58 | login_details: web::Json<Login>, |
59 | ) -> impl Responder { | 59 | ) -> impl Responder { |
60 | info!("Login hit"); | 60 | info!("Login hit"); |
61 | if let Some(uname) = cookie.identity() { | 61 | if cookie.identity().is_some() { |
62 | info!("Found existing cookie: {:?}", cookie.identity()); | 62 | info!("Found existing cookie: {:?}", cookie.identity()); |
63 | return HttpResponse::Ok().finish(); | 63 | return HttpResponse::Ok().finish(); |
64 | } | 64 | } |
@@ -84,7 +84,7 @@ pub async fn login( | |||
84 | 84 | ||
85 | pub async fn logout(cookie: Identity) -> impl Responder { | 85 | pub async fn logout(cookie: Identity) -> impl Responder { |
86 | cookie.forget(); | 86 | cookie.forget(); |
87 | HttpResponse::Found().header("location", "/").finish() | 87 | HttpResponse::Ok().body("Successful logout.") |
88 | } | 88 | } |
89 | 89 | ||
90 | pub async fn user_details( | 90 | pub async fn user_details( |
diff --git a/backend/src/models.rs b/backend/src/models.rs index a104209..bf531ad 100644 --- a/backend/src/models.rs +++ b/backend/src/models.rs | |||
@@ -35,6 +35,8 @@ pub struct Product { | |||
35 | pub kind: Option<String>, | 35 | pub kind: Option<String>, |
36 | pub price: f32, | 36 | pub price: f32, |
37 | pub description: Option<String>, | 37 | pub description: Option<String>, |
38 | pub src: Option<String>, | ||
39 | pub ios_src: Option<String>, | ||
38 | } | 40 | } |
39 | 41 | ||
40 | #[derive(Insertable, Deserialize)] | 42 | #[derive(Insertable, Deserialize)] |
@@ -48,6 +50,12 @@ pub struct NewProduct { | |||
48 | 50 | ||
49 | #[serde(skip_serializing_if = "Option::is_none")] | 51 | #[serde(skip_serializing_if = "Option::is_none")] |
50 | pub description: Option<String>, | 52 | pub description: Option<String>, |
53 | |||
54 | #[serde(skip_serializing_if = "Option::is_none")] | ||
55 | pub src: Option<String>, | ||
56 | |||
57 | #[serde(skip_serializing_if = "Option::is_none")] | ||
58 | pub ios_src: Option<String>, | ||
51 | } | 59 | } |
52 | 60 | ||
53 | #[derive(Deserialize)] | 61 | #[derive(Deserialize)] |
@@ -63,6 +71,7 @@ pub struct UpdateProduct { | |||
63 | pub struct CartItem { | 71 | pub struct CartItem { |
64 | pub cart_id: i32, | 72 | pub cart_id: i32, |
65 | pub product_id: i32, | 73 | pub product_id: i32, |
74 | pub quantity: Option<i32>, | ||
66 | } | 75 | } |
67 | 76 | ||
68 | #[derive(Insertable, Deserialize)] | 77 | #[derive(Insertable, Deserialize)] |
@@ -70,6 +79,7 @@ pub struct CartItem { | |||
70 | pub struct AddCartItem { | 79 | pub struct AddCartItem { |
71 | pub cart_id: i32, | 80 | pub cart_id: i32, |
72 | pub product_id: i32, | 81 | pub product_id: i32, |
82 | pub quantity: Option<i32>, | ||
73 | } | 83 | } |
74 | 84 | ||
75 | /* Rating */ | 85 | /* Rating */ |
@@ -95,3 +105,21 @@ pub struct AddRating { | |||
95 | pub product_id: i32, | 105 | pub product_id: i32, |
96 | pub customer_id: i32, | 106 | pub customer_id: i32, |
97 | } | 107 | } |
108 | |||
109 | /* Transaction */ | ||
110 | #[derive(Queryable, Serialize)] | ||
111 | pub struct Transaction { | ||
112 | pub id: i32, | ||
113 | pub payment_type: String, | ||
114 | pub amount: f32, | ||
115 | pub customer_id: Option<i32>, | ||
116 | pub order_date: NaiveDate, | ||
117 | } | ||
118 | |||
119 | #[derive(Insertable, Deserialize)] | ||
120 | #[table_name = "transaction"] | ||
121 | pub struct AddTransaction { | ||
122 | pub payment_type: String, | ||
123 | pub amount: f32, | ||
124 | pub customer_id: Option<i32>, | ||
125 | } | ||
diff --git a/backend/src/schema.rs b/backend/src/schema.rs index f08221a..1419bc0 100644 --- a/backend/src/schema.rs +++ b/backend/src/schema.rs | |||
@@ -2,6 +2,7 @@ table! { | |||
2 | cart_items (cart_id, product_id) { | 2 | cart_items (cart_id, product_id) { |
3 | cart_id -> Integer, | 3 | cart_id -> Integer, |
4 | product_id -> Integer, | 4 | product_id -> Integer, |
5 | quantity -> Nullable<Integer>, | ||
5 | } | 6 | } |
6 | } | 7 | } |
7 | 8 | ||
@@ -43,6 +44,7 @@ table! { | |||
43 | payment_type -> Varchar, | 44 | payment_type -> Varchar, |
44 | amount -> Float, | 45 | amount -> Float, |
45 | customer_id -> Nullable<Integer>, | 46 | customer_id -> Nullable<Integer>, |
47 | order_date -> Date, | ||
46 | } | 48 | } |
47 | } | 49 | } |
48 | 50 | ||