lago_client/queries/
credit_note.rs

1use lago_types::{
2    error::{LagoError, Result},
3    requests::credit_note::{
4        CreateCreditNoteRequest, GetCreditNoteRequest, ListCreditNotesRequest,
5        UpdateCreditNoteRequest,
6    },
7    responses::credit_note::{
8        CreateCreditNoteResponse, GetCreditNoteResponse, ListCreditNotesResponse,
9        UpdateCreditNoteResponse,
10    },
11};
12use url::Url;
13
14use crate::client::LagoClient;
15
16/// Credit note-related operations for the Lago client
17impl LagoClient {
18    /// Retrieves a list of credit notes with optional filtering parameters
19    ///
20    /// # Arguments
21    /// * `request` - Optional filtering parameters for the credit note list
22    ///
23    /// # Returns
24    /// A `Result` containing the list of credit notes or an error
25    ///
26    /// # Example
27    /// ```no_run
28    /// use lago_client::LagoClient;
29    /// use lago_types::requests::credit_note::ListCreditNotesRequest;
30    /// use lago_types::filters::credit_note::CreditNoteFilter;
31    ///
32    /// # async fn example() -> lago_types::error::Result<()> {
33    /// let client = LagoClient::from_env()?;
34    /// let request = ListCreditNotesRequest::new()
35    ///     .with_filters(CreditNoteFilter::new().with_external_customer_id("customer_123".to_string()));
36    /// let response = client.list_credit_notes(Some(request)).await?;
37    /// println!("Found {} credit notes", response.credit_notes.len());
38    /// # Ok(())
39    /// # }
40    /// ```
41    pub async fn list_credit_notes(
42        &self,
43        request: Option<ListCreditNotesRequest>,
44    ) -> Result<ListCreditNotesResponse> {
45        let request = request.unwrap_or_default();
46        let region = self.config.region()?;
47        let mut url = Url::parse(&format!("{}/credit_notes", region.endpoint()))
48            .map_err(|e| LagoError::Configuration(format!("Invalid URL: {e}")))?;
49
50        let query_params = request.to_query_params();
51
52        if !query_params.is_empty() {
53            let query_string = query_params
54                .iter()
55                .map(|(k, v)| format!("{k}={v}"))
56                .collect::<Vec<_>>()
57                .join("&");
58            url.set_query(Some(&query_string));
59        }
60
61        self.make_request("GET", url.as_str(), None::<&()>).await
62    }
63
64    /// Retrieves a specific credit note by its Lago ID
65    ///
66    /// # Arguments
67    /// * `request` - The request containing the Lago ID to retrieve
68    ///
69    /// # Returns
70    /// A `Result` containing the credit note data or an error
71    ///
72    /// # Example
73    /// ```no_run
74    /// use lago_client::LagoClient;
75    /// use lago_types::requests::credit_note::GetCreditNoteRequest;
76    ///
77    /// # async fn example() -> lago_types::error::Result<()> {
78    /// let client = LagoClient::from_env()?;
79    /// let request = GetCreditNoteRequest::new("1a901a90-1a90-1a90-1a90-1a901a901a90".to_string());
80    /// let response = client.get_credit_note(request).await?;
81    /// println!("Credit note number: {}", response.credit_note.number);
82    /// # Ok(())
83    /// # }
84    /// ```
85    pub async fn get_credit_note(
86        &self,
87        request: GetCreditNoteRequest,
88    ) -> Result<GetCreditNoteResponse> {
89        let region = self.config.region()?;
90        let url = format!("{}/credit_notes/{}", region.endpoint(), request.lago_id);
91        self.make_request("GET", &url, None::<&()>).await
92    }
93
94    /// Creates a new credit note
95    ///
96    /// Credit notes are issued to refund or credit customers for invoices,
97    /// either partially or in full.
98    ///
99    /// # Arguments
100    /// * `request` - The request containing the credit note data to create
101    ///
102    /// # Returns
103    /// A `Result` containing the created credit note or an error
104    ///
105    /// # Example
106    /// ```no_run
107    /// use lago_client::LagoClient;
108    /// use lago_types::requests::credit_note::{
109    ///     CreateCreditNoteInput, CreateCreditNoteItemInput, CreateCreditNoteRequest,
110    /// };
111    /// use lago_types::models::CreditNoteReason;
112    ///
113    /// # async fn example() -> lago_types::error::Result<()> {
114    /// let client = LagoClient::from_env()?;
115    /// let items = vec![
116    ///     CreateCreditNoteItemInput::new("fee_lago_id".to_string(), 1000),
117    /// ];
118    /// let input = CreateCreditNoteInput::new(
119    ///     "invoice_lago_id".to_string(),
120    ///     CreditNoteReason::Other,
121    ///     1000,
122    ///     0,
123    ///     items,
124    /// )
125    /// .with_description("Credit for billing error".to_string());
126    ///
127    /// let request = CreateCreditNoteRequest::new(input);
128    /// let response = client.create_credit_note(request).await?;
129    /// println!("Created credit note: {}", response.credit_note.number);
130    /// # Ok(())
131    /// # }
132    /// ```
133    pub async fn create_credit_note(
134        &self,
135        request: CreateCreditNoteRequest,
136    ) -> Result<CreateCreditNoteResponse> {
137        let region = self.config.region()?;
138        let url = format!("{}/credit_notes", region.endpoint());
139        self.make_request("POST", &url, Some(&request)).await
140    }
141
142    /// Updates an existing credit note
143    ///
144    /// Currently, only the refund_status can be updated on a credit note.
145    ///
146    /// # Arguments
147    /// * `request` - The request containing the Lago ID and update data
148    ///
149    /// # Returns
150    /// A `Result` containing the updated credit note or an error
151    ///
152    /// # Example
153    /// ```no_run
154    /// use lago_client::LagoClient;
155    /// use lago_types::requests::credit_note::{UpdateCreditNoteInput, UpdateCreditNoteRequest};
156    /// use lago_types::models::CreditNoteRefundStatus;
157    ///
158    /// # async fn example() -> lago_types::error::Result<()> {
159    /// let client = LagoClient::from_env()?;
160    /// let input = UpdateCreditNoteInput::new()
161    ///     .with_refund_status(CreditNoteRefundStatus::Succeeded);
162    ///
163    /// let request = UpdateCreditNoteRequest::new(
164    ///     "1a901a90-1a90-1a90-1a90-1a901a901a90".to_string(),
165    ///     input,
166    /// );
167    /// let response = client.update_credit_note(request).await?;
168    /// println!("Updated credit note: {}", response.credit_note.number);
169    /// # Ok(())
170    /// # }
171    /// ```
172    pub async fn update_credit_note(
173        &self,
174        request: UpdateCreditNoteRequest,
175    ) -> Result<UpdateCreditNoteResponse> {
176        let region = self.config.region()?;
177        let url = format!("{}/credit_notes/{}", region.endpoint(), request.lago_id);
178        self.make_request("PUT", &url, Some(&request)).await
179    }
180}