ya_client_model/payment/
debit_note_event.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use strum_macros::Display;
4
5use super::DriverStatusProperty;
6
7#[derive(Clone, Debug, Serialize, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct DebitNoteEvent {
10    pub debit_note_id: String,
11    pub event_date: DateTime<Utc>,
12    #[serde(flatten)]
13    pub event_type: DebitNoteEventType,
14}
15
16#[derive(Clone, Debug, Display, Serialize, Deserialize)]
17#[serde(tag = "eventType")]
18pub enum DebitNoteEventType {
19    DebitNoteReceivedEvent,
20    DebitNoteAcceptedEvent,
21    DebitNoteRejectedEvent {
22        rejection: crate::payment::Rejection,
23    },
24    DebitNoteCancelledEvent,
25    DebitNoteSettledEvent,
26    DebitNotePaymentStatusEvent {
27        property: DriverStatusProperty,
28    },
29    DebitNotePaymentOkEvent,
30}
31
32impl DebitNoteEventType {
33    pub fn discriminant(&self) -> &'static str {
34        use DebitNoteEventType::*;
35        match self {
36            DebitNoteReceivedEvent => "RECEIVED",
37            DebitNoteAcceptedEvent => "ACCEPTED",
38            DebitNoteRejectedEvent { .. } => "REJECTED",
39            DebitNoteCancelledEvent => "CANCELLED",
40            DebitNoteSettledEvent => "SETTLED",
41            DebitNotePaymentStatusEvent { .. } => "PAYMENT_EVENT",
42            DebitNotePaymentOkEvent => "PAYMENT_OK",
43        }
44    }
45
46    pub fn details(&self) -> Option<serde_json::Value> {
47        use serde_json::to_value;
48        use DebitNoteEventType::*;
49
50        match self {
51            DebitNoteRejectedEvent { rejection } => to_value(rejection).ok(),
52            DebitNotePaymentStatusEvent { property } => to_value(property).ok(),
53            _ => None,
54        }
55    }
56
57    pub fn from_discriminant_and_details(
58        discriminant: &str,
59        details: Option<serde_json::Value>,
60    ) -> Option<Self> {
61        use serde_json::from_value;
62        use DebitNoteEventType::*;
63
64        Some(match (discriminant, details) {
65            ("RECEIVED", _) => DebitNoteReceivedEvent,
66            ("ACCEPTED", _) => DebitNoteAcceptedEvent,
67            ("REJECTED", Some(details)) => DebitNoteRejectedEvent {
68                rejection: from_value(details).ok()?,
69            },
70            ("CANCELLED", _) => DebitNoteCancelledEvent,
71            ("SETTLED", _) => DebitNoteSettledEvent,
72            ("PAYMENT_EVENT", Some(details)) => DebitNotePaymentStatusEvent {
73                property: from_value(details).ok()?,
74            },
75            ("PAYMENT_OK", _) => DebitNotePaymentOkEvent,
76            _ => None?,
77        })
78    }
79}
80
81#[cfg(test)]
82mod test {
83    use super::*;
84    use crate::payment::{Rejection, RejectionReason};
85    use bigdecimal::{BigDecimal, FromPrimitive};
86
87    #[test]
88    fn test_serialize_rejected_event_has_flat_rejection() {
89        let ie = DebitNoteEvent {
90            debit_note_id: "ajdik".to_string(),
91            event_date: DateTime::parse_from_str("2020-12-21T15:51:21.126645Z", "%+")
92                .unwrap()
93                .with_timezone(&Utc),
94            event_type: DebitNoteEventType::DebitNoteRejectedEvent {
95                rejection: Rejection {
96                    rejection_reason: RejectionReason::UnsolicitedService,
97                    total_amount_accepted: BigDecimal::from_f32(13.14).unwrap(),
98                    message: None,
99                },
100            },
101        };
102
103        assert_eq!(
104            "{\"debitNoteId\":\"ajdik\",\
105                \"eventDate\":\"2020-12-21T15:51:21.126645Z\",\
106                \"eventType\":\"DebitNoteRejectedEvent\",\
107                \"rejection\":{\
108                    \"rejectionReason\":\"UNSOLICITED_SERVICE\",\
109                    \"totalAmountAccepted\":\"13.14000\"\
110                }\
111             }",
112            serde_json::to_string(&ie).unwrap()
113        );
114    }
115}