use crate::error::{Error, Result};
use crate::http::{BaseClient, RequestOptions};
use crate::models::{
BondedDelivery, BondedDeliveryRequest, DeliveryCost, DeliveryData, DeliveryDataRequest,
DeliveryMatch, DeliveryMatchRequest, FactorySpotAgio, FactorySpotAgioRequest,
PlywoodDeliveryCommodity, PlywoodDeliveryCommodityRequest, RollDeliverySellerIntention,
RollDeliverySellerIntentionRequest, TcCongregateDelivery, TcCongregateDeliveryRequest,
TdBondedDelivery, TdBondedDeliveryRequest, WarehousePremiumResponse,
};
const PATH_GET_DELIVERY_DATA: &str = "/dceapi/forward/publicweb/deliverystat/delivery";
const PATH_GET_DELIVERY_MATCH: &str = "/dceapi/forward/publicweb/deliverystat/deliveryMatch";
const PATH_GET_DELIVERY_COST: &str = "/dceapi/forward/publicweb/deliverypara/deliveryCosts";
const PATH_GET_WAREHOUSE_PREMIUM: &str = "/dceapi/forward/publicweb/deliverypara/floatingAgio";
const PATH_GET_TC_CONGREGATE_DELIVERY: &str =
"/dceapi/forward/publicweb/DeliveryStatistics/tcCongregateDeliveryQuotes";
const PATH_GET_ROLL_DELIVERY_SELLER_INTENTION: &str =
"/dceapi/forward/publicweb/DeliveryStatistics/rollDeliverySellerIntention";
const PATH_GET_BONDED_DELIVERY: &str = "/dceapi/forward/publicweb/quotesdata/bondedDelivery";
const PATH_GET_TD_BONDED_DELIVERY: &str = "/dceapi/forward/publicweb/quotesdata/tdBondedDelivery";
const PATH_GET_FACTORY_SPOT_AGIO: &str =
"/dceapi/forward/publicweb/quotesdata/queryFactorySpotAgioQuotes";
const PATH_GET_PLYWOOD_DELIVERY_COMMODITY: &str =
"/dceapi/forward/publicweb/deliverystat/queryPlywoodDeliveryCommodity";
#[derive(Debug, Clone)]
pub struct DeliveryService {
client: BaseClient,
}
impl DeliveryService {
pub fn new(client: BaseClient) -> Self {
DeliveryService { client }
}
pub async fn get_delivery_data(
&self,
req: &DeliveryDataRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<DeliveryData>> {
self.client.do_post(PATH_GET_DELIVERY_DATA, req, opts).await
}
pub async fn get_delivery_match(
&self,
req: &DeliveryMatchRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<DeliveryMatch>> {
self.client
.do_post(PATH_GET_DELIVERY_MATCH, req, opts)
.await
}
pub async fn get_delivery_cost(
&self,
variety_id: &str,
variety_type: &str,
opts: Option<RequestOptions>,
) -> Result<Vec<DeliveryCost>> {
if variety_id.is_empty() {
return Err(Error::validation("variety_id", "variety_id is required"));
}
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
struct Request<'a> {
variety_id: &'a str,
variety_type: &'a str,
lang: &'a str,
}
let req = Request {
variety_id,
variety_type,
lang: "zh",
};
self.client
.do_post(PATH_GET_DELIVERY_COST, &req, opts)
.await
}
pub async fn get_warehouse_premium(
&self,
variety_id: &str,
trade_date: &str,
opts: Option<RequestOptions>,
) -> Result<WarehousePremiumResponse> {
if variety_id.is_empty() {
return Err(Error::validation("variety_id", "variety_id is required"));
}
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
struct Request<'a> {
variety_id: &'a str,
trade_date: &'a str,
}
let req = Request {
variety_id,
trade_date,
};
self.client
.do_post(PATH_GET_WAREHOUSE_PREMIUM, &req, opts)
.await
}
pub async fn get_tc_congregate_delivery(
&self,
req: &TcCongregateDeliveryRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<TcCongregateDelivery>> {
self.client
.do_post(PATH_GET_TC_CONGREGATE_DELIVERY, req, opts)
.await
}
pub async fn get_roll_delivery_seller_intention(
&self,
req: &RollDeliverySellerIntentionRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<RollDeliverySellerIntention>> {
self.client
.do_post(PATH_GET_ROLL_DELIVERY_SELLER_INTENTION, req, opts)
.await
}
pub async fn get_bonded_delivery(
&self,
req: &BondedDeliveryRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<BondedDelivery>> {
self.client
.do_post(PATH_GET_BONDED_DELIVERY, req, opts)
.await
}
pub async fn get_td_bonded_delivery(
&self,
req: &TdBondedDeliveryRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<TdBondedDelivery>> {
self.client
.do_post(PATH_GET_TD_BONDED_DELIVERY, req, opts)
.await
}
pub async fn get_factory_spot_agio(
&self,
req: &FactorySpotAgioRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<FactorySpotAgio>> {
self.client
.do_post(PATH_GET_FACTORY_SPOT_AGIO, req, opts)
.await
}
pub async fn get_plywood_delivery_commodity(
&self,
req: &PlywoodDeliveryCommodityRequest,
opts: Option<RequestOptions>,
) -> Result<Vec<PlywoodDeliveryCommodity>> {
self.client
.do_post(PATH_GET_PLYWOOD_DELIVERY_COMMODITY, req, opts)
.await
}
}