ya_client_model/payment/
debit_note_event.rs1use 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}