Skip to content

Commit

Permalink
fix: general user can't get the total_amount
Browse files Browse the repository at this point in the history
  • Loading branch information
Reknij committed May 28, 2024
1 parent 9b7ec43 commit 487d37e
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 90 deletions.
132 changes: 42 additions & 90 deletions server/crates/statistical_module/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use ahash::{HashMap, HashMapExt};
use anyhow::Result;
use elerp_common::{
model::{action_type::ActionType, WebSocketFlags},
order_module::model::order::{GetOrdersQuery, OrderCurrency, OrderType},
set_to_string,
sql::in_or_not,
statistical_module::model::statistical_data::{GetStatisticalDataQuery, PopularSKU, SalesAmountWithCurrency, StatisticalData, StatisticalOrderCountData, StatisticalOrderData},
};
use futures::TryStreamExt;
use public_system::PublicSystem;
use sqlx::{Row, SqliteConnection};
use std::{borrow::Cow, sync::Arc};
use tokio::{sync::RwLock, task::JoinHandle};
use anyhow::Result;
use elerp_common::{model::{action_type::ActionType, WebSocketFlags}, order_module::model::order::{GetOrdersQuery, OrderCurrency, OrderType}, set_to_string, sql::in_or_not, statistical_module::model::statistical_data::{
GetStatisticalDataQuery, PopularSKU, SalesAmountWithCurrency, StatisticalData,
StatisticalOrderCountData, StatisticalOrderData,
}};

#[derive(Debug, Clone)]
pub struct StatisticalModule {
Expand All @@ -32,30 +35,14 @@ impl StatisticalModule {
while let Ok(flag) = rx.recv().await {
let mut map = t2.last_data.write().await;
match flag {
WebSocketFlags::AddArea(_) => {
map.values_mut().for_each(|data| data.area_count += 1)
}
WebSocketFlags::RemoveArea(_) => {
map.values_mut().for_each(|data| data.area_count -= 1)
}
WebSocketFlags::AddPerson(_) => {
map.values_mut().for_each(|data| data.person_count += 1)
}
WebSocketFlags::RemovePerson(_) => {
map.values_mut().for_each(|data| data.person_count -= 1)
}
WebSocketFlags::AddSKUCategory(_) => map
.values_mut()
.for_each(|data| data.sku_category_count += 1),
WebSocketFlags::RemoveSKUCategory(_) => map
.values_mut()
.for_each(|data| data.sku_category_count -= 1),
WebSocketFlags::AddSKU(_) => {
map.values_mut().for_each(|data| data.sku_count += 1)
}
WebSocketFlags::RemoveSKU(_) => {
map.values_mut().for_each(|data| data.sku_count -= 1)
}
WebSocketFlags::AddArea(_) => map.values_mut().for_each(|data| data.area_count += 1),
WebSocketFlags::RemoveArea(_) => map.values_mut().for_each(|data| data.area_count -= 1),
WebSocketFlags::AddPerson(_) => map.values_mut().for_each(|data| data.person_count += 1),
WebSocketFlags::RemovePerson(_) => map.values_mut().for_each(|data| data.person_count -= 1),
WebSocketFlags::AddSKUCategory(_) => map.values_mut().for_each(|data| data.sku_category_count += 1),
WebSocketFlags::RemoveSKUCategory(_) => map.values_mut().for_each(|data| data.sku_category_count -= 1),
WebSocketFlags::AddSKU(_) => map.values_mut().for_each(|data| data.sku_count += 1),
WebSocketFlags::RemoveSKU(_) => map.values_mut().for_each(|data| data.sku_count -= 1),

WebSocketFlags::AddWarehouse(_)
| WebSocketFlags::RemoveWarehouse(_)
Expand All @@ -82,21 +69,11 @@ impl StatisticalModule {
this
}

async fn read(
&self,
query: &GetStatisticalDataQuery,
action: ActionType,
tx: &mut SqliteConnection,
) -> Result<StatisticalData> {
async fn read(&self, query: &GetStatisticalDataQuery, action: ActionType, tx: &mut SqliteConnection) -> Result<StatisticalData> {
let mut order_query = query.get_order_query();
let order_query_str = order_query.get_where_condition();
{
if let Some(data) = self
.last_data
.read()
.await
.get(&(action, Cow::Borrowed(&order_query_str)))
{
if let Some(data) = self.last_data.read().await.get(&(action, Cow::Borrowed(&order_query_str))) {
return Ok(data.clone());
}
}
Expand All @@ -114,38 +91,24 @@ impl StatisticalModule {
order_query.order_type = Some(OrderType::StockOut);
let total_amount = self.get_total_amount(&order_query, action, tx).await?;
let max = self.ps.get_config().limit.statistics;
let most_popular_skus = self
.read_popular_skus(max as usize, order_query, action, tx)
.await?;
let most_popular_skus = self.read_popular_skus(max as usize, order_query, action, tx).await?;

let data = StatisticalData {
area_count,
person_count,
warehouse_count,
sku_category_count,
sku_count,
order: StatisticalOrderData {
total_count,
total_amount,
},
order: StatisticalOrderData { total_count, total_amount },
order_category_count,
most_popular_skus,
};
self.last_data
.write()
.await
.insert((action, Cow::Owned(order_query_str)), data.clone());
self.last_data.write().await.insert((action, Cow::Owned(order_query_str)), data.clone());

Ok(data)
}

async fn read_popular_skus(
&self,
max: usize,
mut query: GetOrdersQuery,
action: ActionType,
tx: &mut SqliteConnection,
) -> Result<Vec<PopularSKU>> {
async fn read_popular_skus(&self, max: usize, mut query: GetOrdersQuery, action: ActionType, tx: &mut SqliteConnection) -> Result<Vec<PopularSKU>> {
let reverse = query.reverse.as_ref();
let mut oi_conditions = vec!["orders.id=oi.order_id".to_owned()];
if let Some(v) = &query.items {
Expand Down Expand Up @@ -195,22 +158,12 @@ impl StatisticalModule {
Ok(arr)
}

pub async fn get(
&self,
query: &GetStatisticalDataQuery,
action: ActionType,
tx: &mut SqliteConnection,
) -> Result<StatisticalData> {
pub async fn get(&self, query: &GetStatisticalDataQuery, action: ActionType, tx: &mut SqliteConnection) -> Result<StatisticalData> {
let data = self.read(&query, action, tx).await?;
Ok(data)
}

pub async fn get_total_count(
&self,
query: &GetOrdersQuery,
action: ActionType,
tx: &mut SqliteConnection,
) -> Result<StatisticalOrderCountData> {
pub async fn get_total_count(&self, query: &GetOrdersQuery, action: ActionType, tx: &mut SqliteConnection) -> Result<StatisticalOrderCountData> {
let qw = query.get_where_condition();
let inner = self.get_order_inner(action);
let mut data = StatisticalOrderCountData {
Expand Down Expand Up @@ -250,26 +203,29 @@ impl StatisticalModule {
*ref_count = count;
}
}
data.any_count = data.stock_in_count
+ data.stock_out_count
+ data.return_count
+ data.exchange_count
+ data.calibration_count
+ data.calibration_strict_count
+ data.verification_count
+ data.verification_strict_count;
Ok(data)
}

pub async fn get_total_amount(
&self,
query: &GetOrdersQuery,
action: ActionType,
tx: &mut SqliteConnection,
) -> Result<Vec<SalesAmountWithCurrency>> {
pub async fn get_total_amount(&self, query: &GetOrdersQuery, action: ActionType, tx: &mut SqliteConnection) -> Result<Vec<SalesAmountWithCurrency>> {
let qw = query.get_where_condition();
let inner = self.get_order_inner(action);
if let Ok(rows) = sqlx::query(&format!(
"SELECT warehouse_id, currency, SUM(total_amount) AS any,
"SELECT orders.warehouse_id, orders.currency, SUM(total_amount) AS any,
SUM(CASE WHEN order_payment_status='Unsettled' THEN total_amount ELSE 0.0 END) AS unsettled,
SUM(CASE WHEN order_payment_status='Settled' THEN total_amount_settled ELSE 0.0 END) AS settled,
SUM(CASE WHEN order_payment_status='PartialSettled' THEN total_amount_settled ELSE 0.0 END) AS partial_settled
FROM orders
{inner}
{qw}
GROUP BY currency"
GROUP BY orders.currency"
))
.fetch_all(&mut *tx)
.await
Expand All @@ -281,9 +237,7 @@ impl StatisticalModule {
settled: row.get("settled"),
unsettled: row.get("unsettled"),
partial_settled: row.get("partial_settled"),
currency: row
.try_get("currency")
.unwrap_or(OrderCurrency::Unknown),
currency: row.try_get("currency").unwrap_or(OrderCurrency::Unknown),
})
.collect();
arr.sort_by(|a, b| b.cmp(a));
Expand All @@ -303,13 +257,11 @@ impl StatisticalModule {
}

async fn get_count(&self, table: &str, tx: &mut SqliteConnection) -> Result<i64> {
Ok(
sqlx::query(&format!("SELECT COUNT(*) as count FROM {table}"))
.fetch(&mut *tx)
.try_next()
.await?
.map(|row| row.get("count"))
.unwrap_or(0),
)
Ok(sqlx::query(&format!("SELECT COUNT(*) as count FROM {table}"))
.fetch(&mut *tx)
.try_next()
.await?
.map(|row| row.get("count"))
.unwrap_or(0))
}
}
3 changes: 3 additions & 0 deletions server/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use person_module::PersonModule;
use public_system::PublicSystem;
use sku_category_module::SKUCategoryModule;
use sku_module::SKUModule;
use statistical_module::StatisticalModule;
use user_system::UserSystem;
use warehouse_module::WarehouseModule;

Expand All @@ -34,6 +35,7 @@ pub struct TestContext {
pub order_payment: OrderPaymentModule,
pub guest_order: GuestOrderModule,
pub inventory: InventoryModule,
pub statistical: StatisticalModule,
}

pub struct TestPrelude {
Expand Down Expand Up @@ -69,6 +71,7 @@ pub async fn init_ctx() -> TestContext {
order_payment: OrderPaymentModule::new(ps.clone()).await,
guest_order: GuestOrderModule::new(ps.clone()).await,
inventory: InventoryModule::new(ps.clone()).await,
statistical: StatisticalModule::new(ps.clone()).await,
ps,
}
}
Expand Down
65 changes: 65 additions & 0 deletions server/tests/test_statistical_module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use elerp_common::{
model::action_type::ActionType,
order_module::model::order::{GetOrdersQuery, Order, OrderCurrency, OrderItem, OrderPaymentStatus, OrderType}, warehouse_module::model::fn_argument::{UserInfoID, WarehouseIsFrom},
};

mod common;

#[tokio::test]
async fn test_module() {
let c = common::init_ctx().await;
let p = common::prelude(&c).await;

let mut tx = c.ps.begin_tx(true).await.unwrap();

for n in 0..10 {
let mut order = Order {
id: 0,
created_by_user_id: 0,
updated_by_user_id: 0,
date: 0,
last_updated_date: 0,
person_in_charge_id: 0,
order_category_id: p.order_category1.id,
from_guest_order_id: 0,
currency: OrderCurrency::USD,
items: Some(vec![
OrderItem {
sku_id: p.sku1.id,
quantity: 1000,
price: 18.5,
exchanged: false,
},
OrderItem {
sku_id: p.sku2.id,
quantity: 2500,
price: 10.0,
exchanged: false,
},
]),
total_amount: 0.0,
total_amount_settled: 0.0,
order_payment_status: OrderPaymentStatus::None,
warehouse_id: p.warehouse1.id,
person_related_id: p.person1.id,
description: format!("Testing order #{n}"),
order_type: OrderType::StockOut,
is_record: true,
};
c.order.preprocess(&mut order, &p.user1, true, p.person2.id);
c.order.add(order, tx.as_mut()).await.unwrap();
}
let q = GetOrdersQuery::empty();
let total_count = c.statistical.get_total_count(&q, ActionType::Admin, tx.as_mut()).await.unwrap();
assert_eq!(total_count.stock_out_count, 10);
assert_eq!(total_count.any_count, total_count.stock_out_count);
let total_count = c.statistical.get_total_count(&q, p.user1.as_action_type(true), tx.as_mut()).await.unwrap();
assert_eq!(total_count.any_count, 0);
let data = c.statistical.get_total_amount(&q, p.user1.as_action_type(false), tx.as_mut()).await.unwrap();
assert!(data.is_empty());
c.warehouse.link(p.warehouse1.id, p.user1.id, tx.as_mut()).await.unwrap();
assert!(c.warehouse.is_linked(WarehouseIsFrom::ID(p.warehouse1.id), UserInfoID::ID(p.user1.id), tx.as_mut()).await.unwrap());
let data = c.statistical.get_total_amount(&q, p.user1.as_action_type(true), tx.as_mut()).await.unwrap();
assert!(!data.is_empty());
assert_eq!(data[0].any, 435000.0);
}
14 changes: 14 additions & 0 deletions server/tests/test_warehouse_module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use elerp_common::warehouse_module::model::fn_argument::{UserInfoID, WarehouseIsFrom};

mod common;

#[tokio::test]
async fn test_link() {
let c = common::init_ctx().await;
let p = common::prelude(&c).await;

let mut tx = c.ps.begin_tx(true).await.unwrap();

c.warehouse.link(p.warehouse1.id, p.user1.id, tx.as_mut()).await.unwrap();
assert!(c.warehouse.is_linked(WarehouseIsFrom::ID(p.warehouse1.id), UserInfoID::ID(p.user1.id), tx.as_mut()).await.unwrap())
}

0 comments on commit 487d37e

Please sign in to comment.