1use crate::error::{Error, Result};
4use crate::http::{BaseClient, RequestOptions};
5use crate::models::{
6 BondedDelivery, BondedDeliveryRequest, DeliveryCost, DeliveryData, DeliveryDataRequest,
7 DeliveryMatch, DeliveryMatchRequest, FactorySpotAgio, FactorySpotAgioRequest,
8 PlywoodDeliveryCommodity, PlywoodDeliveryCommodityRequest, RollDeliverySellerIntention,
9 RollDeliverySellerIntentionRequest, TcCongregateDelivery, TcCongregateDeliveryRequest,
10 TdBondedDelivery, TdBondedDeliveryRequest, WarehousePremiumResponse,
11};
12
13const PATH_GET_DELIVERY_DATA: &str = "/dceapi/forward/publicweb/deliverystat/delivery";
15
16const PATH_GET_DELIVERY_MATCH: &str = "/dceapi/forward/publicweb/deliverystat/deliveryMatch";
18
19const PATH_GET_DELIVERY_COST: &str = "/dceapi/forward/publicweb/deliverypara/deliveryCosts";
21
22const PATH_GET_WAREHOUSE_PREMIUM: &str = "/dceapi/forward/publicweb/deliverypara/floatingAgio";
24
25const PATH_GET_TC_CONGREGATE_DELIVERY: &str =
27 "/dceapi/forward/publicweb/DeliveryStatistics/tcCongregateDeliveryQuotes";
28
29const PATH_GET_ROLL_DELIVERY_SELLER_INTENTION: &str =
31 "/dceapi/forward/publicweb/DeliveryStatistics/rollDeliverySellerIntention";
32
33const PATH_GET_BONDED_DELIVERY: &str = "/dceapi/forward/publicweb/quotesdata/bondedDelivery";
35
36const PATH_GET_TD_BONDED_DELIVERY: &str = "/dceapi/forward/publicweb/quotesdata/tdBondedDelivery";
38
39const PATH_GET_FACTORY_SPOT_AGIO: &str =
41 "/dceapi/forward/publicweb/quotesdata/queryFactorySpotAgioQuotes";
42
43const PATH_GET_PLYWOOD_DELIVERY_COMMODITY: &str =
45 "/dceapi/forward/publicweb/deliverystat/queryPlywoodDeliveryCommodity";
46
47#[derive(Debug, Clone)]
49pub struct DeliveryService {
50 client: BaseClient,
51}
52
53impl DeliveryService {
54 pub fn new(client: BaseClient) -> Self {
56 DeliveryService { client }
57 }
58
59 pub async fn get_delivery_data(
65 &self,
66 req: &DeliveryDataRequest,
67 opts: Option<RequestOptions>,
68 ) -> Result<Vec<DeliveryData>> {
69 self.client.do_post(PATH_GET_DELIVERY_DATA, req, opts).await
70 }
71
72 pub async fn get_delivery_match(
78 &self,
79 req: &DeliveryMatchRequest,
80 opts: Option<RequestOptions>,
81 ) -> Result<Vec<DeliveryMatch>> {
82 self.client
83 .do_post(PATH_GET_DELIVERY_MATCH, req, opts)
84 .await
85 }
86
87 pub async fn get_delivery_cost(
94 &self,
95 variety_id: &str,
96 variety_type: &str,
97 opts: Option<RequestOptions>,
98 ) -> Result<Vec<DeliveryCost>> {
99 if variety_id.is_empty() {
100 return Err(Error::validation("variety_id", "variety_id is required"));
101 }
102
103 #[derive(serde::Serialize)]
104 #[serde(rename_all = "camelCase")]
105 struct Request<'a> {
106 variety_id: &'a str,
107 variety_type: &'a str,
108 lang: &'a str,
109 }
110
111 let req = Request {
112 variety_id,
113 variety_type,
114 lang: "zh",
115 };
116 self.client
117 .do_post(PATH_GET_DELIVERY_COST, &req, opts)
118 .await
119 }
120
121 pub async fn get_warehouse_premium(
128 &self,
129 variety_id: &str,
130 trade_date: &str,
131 opts: Option<RequestOptions>,
132 ) -> Result<WarehousePremiumResponse> {
133 if variety_id.is_empty() {
134 return Err(Error::validation("variety_id", "variety_id is required"));
135 }
136
137 #[derive(serde::Serialize)]
138 #[serde(rename_all = "camelCase")]
139 struct Request<'a> {
140 variety_id: &'a str,
141 trade_date: &'a str,
142 }
143
144 let req = Request {
145 variety_id,
146 trade_date,
147 };
148 self.client
149 .do_post(PATH_GET_WAREHOUSE_PREMIUM, &req, opts)
150 .await
151 }
152
153 pub async fn get_tc_congregate_delivery(
161 &self,
162 req: &TcCongregateDeliveryRequest,
163 opts: Option<RequestOptions>,
164 ) -> Result<Vec<TcCongregateDelivery>> {
165 self.client
166 .do_post(PATH_GET_TC_CONGREGATE_DELIVERY, req, opts)
167 .await
168 }
169
170 pub async fn get_roll_delivery_seller_intention(
178 &self,
179 req: &RollDeliverySellerIntentionRequest,
180 opts: Option<RequestOptions>,
181 ) -> Result<Vec<RollDeliverySellerIntention>> {
182 self.client
183 .do_post(PATH_GET_ROLL_DELIVERY_SELLER_INTENTION, req, opts)
184 .await
185 }
186
187 pub async fn get_bonded_delivery(
195 &self,
196 req: &BondedDeliveryRequest,
197 opts: Option<RequestOptions>,
198 ) -> Result<Vec<BondedDelivery>> {
199 self.client
200 .do_post(PATH_GET_BONDED_DELIVERY, req, opts)
201 .await
202 }
203
204 pub async fn get_td_bonded_delivery(
212 &self,
213 req: &TdBondedDeliveryRequest,
214 opts: Option<RequestOptions>,
215 ) -> Result<Vec<TdBondedDelivery>> {
216 self.client
217 .do_post(PATH_GET_TD_BONDED_DELIVERY, req, opts)
218 .await
219 }
220
221 pub async fn get_factory_spot_agio(
229 &self,
230 req: &FactorySpotAgioRequest,
231 opts: Option<RequestOptions>,
232 ) -> Result<Vec<FactorySpotAgio>> {
233 self.client
234 .do_post(PATH_GET_FACTORY_SPOT_AGIO, req, opts)
235 .await
236 }
237
238 pub async fn get_plywood_delivery_commodity(
246 &self,
247 req: &PlywoodDeliveryCommodityRequest,
248 opts: Option<RequestOptions>,
249 ) -> Result<Vec<PlywoodDeliveryCommodity>> {
250 self.client
251 .do_post(PATH_GET_PLYWOOD_DELIVERY_COMMODITY, req, opts)
252 .await
253 }
254}