1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use reqwest::Client;
use yaserde::ser::to_string;

use crate::client::error::{ApiError, HttpClientError, OpenApiClientError};
use crate::dto::ticket_request;
use crate::models::auth_response::{AuthResponse, AuthResponseResult, AuthResponseToken};
use crate::models::ticket::TicketResponse;
use crate::traits::check_query::CheckQueryTrait;
use crate::traits::ticket::TicketResponseTrait;

pub mod error;

pub struct OpenApiClient {
    http_client: Client,
    master_token: String,
    user_token: Option<AuthResponseToken>,
}

impl OpenApiClient {
    pub fn new(master_token: &String) -> Self {
        OpenApiClient {
            http_client: Client::new(),
            master_token: master_token.to_string(),
            user_token: None,
        }
    }
    pub async fn authorize(&mut self) -> Result<AuthResponse, OpenApiClientError> {
        let model = crate::models::auth_request::AuthRequest::new(&self.master_token);
        let auth_request = self.http_client
            .post("https://openapi.nalog.ru:8090/open-api/AuthService/0.1")
            .body(model.to_string())
            .send()
            .await;
        match auth_request {
            Ok(response) => {
                match response.text().await {
                    Ok(xml_string) => {
                        let auth_response = AuthResponse::new(&xml_string);
                        match auth_response.clone() {
                            Ok(res) => {
                                match res.result {
                                    AuthResponseResult::Ok(token) => {
                                        self.user_token = Some(token)
                                    }
                                    _ => {}
                                }
                            }
                            _ => {}
                        };
                        auth_response
                    }
                    Err(error) => {
                        Err(OpenApiClientError::FnsApiError(ApiError { message: error.to_string() }))
                    }
                }
            }
            Err(error) => {
                Err(OpenApiClientError::HttpClientError(HttpClientError { message: error.to_string() }))
            }
        }
    }
    pub async fn get_ticket(&self, check_query: impl CheckQueryTrait) -> Result<Box<dyn TicketResponseTrait>, OpenApiClientError> {
        match &self.user_token {
            None => {
                Err(OpenApiClientError::Error(String::from("Отсутствует FNS-OpenApi-UserToken")))
            }
            Some(user_token) => {
                let ticket_request = ticket_request::Envelope {
                    body: ticket_request::Body {
                        send_message_request: ticket_request::SendMessageRequest {
                            message: ticket_request::Message {
                                get_ticket_request: ticket_request::GetTicketRequest {
                                    get_ticket_info: ticket_request::GetTicketInfo {
                                        sum: check_query.s(),
                                        date: check_query.t(),
                                        r#fn: check_query.r#fn(),
                                        type_operation: check_query.n(),
                                        fiscal_document_id: check_query.i(),
                                        fiscal_sign: check_query.fp(),
                                    }
                                }
                            }
                        }
                    }
                };
                let ticket_info_response = self.http_client.post("https://openapi.nalog.ru:8090/open-api/ais3/KktService/0.1")
                    .body(to_string(&ticket_request).unwrap())
                    .header("FNS-OpenApi-Token", &self.master_token)
                    .header("FNS-OpenApi-UserToken", &user_token.value)
                    .send()
                    .await;
                match ticket_info_response {
                    Ok(response) => {
                        match response.text().await {
                            Ok(text) => {
                                Ok(TicketResponse::new(text))
                            }
                            Err(error) => {
                                Err(OpenApiClientError::FnsApiError(ApiError { message: error.to_string() }))
                            }
                        }
                    }
                    Err(error) => {
                        Err(OpenApiClientError::HttpClientError(HttpClientError::new(error)))
                    }
                }
                //
            }
        }
        // match ticket_info_response {
        //     Ok(response) => {
        //         let header = response.headers();
        //         let content_type = header[CONTENT_TYPE].to_str().unwrap();
        //         let mut headers = HeaderMap::new();
        //         headers.insert(header::CONTENT_TYPE, content_type.parse().unwrap());
        //         (StatusCode::OK, headers, response.text().await.unwrap().to_string()).into_response()
        //     }
        //     Err(e) => {
        //         (StatusCode::BAD_GATEWAY, e.to_string()).into_response()
        //     }
        // }
    }
}