devhub_shared/proposal/
timeline.rs

1use near_sdk::near;
2
3pub type TimelineStatus = TimelineStatusV2;
4type ReviewStatus = ReviewStatusV2;
5
6#[near(serializers=[borsh, json])]
7#[derive(Clone, Debug)]
8#[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")]
9pub enum TimelineStatusV1 {
10    Draft,
11    Review(ReviewStatusV1),
12    Approved(ReviewStatusV1),
13    Rejected(ReviewStatusV1),
14    ApprovedConditionally(ReviewStatusV1),
15    PaymentProcessing(PaymentProcessingStatusV1),
16    Funded(FundedStatusV1),
17    Cancelled(ReviewStatusV1),
18}
19
20#[near(serializers=[borsh, json])]
21#[derive(Clone, Debug)]
22#[serde(tag = "timeline_version")]
23pub enum VersionedTimelineStatus {
24    V1(TimelineStatusV2),
25}
26
27#[near(serializers=[borsh, json])]
28#[derive(Clone, Debug)]
29#[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")]
30pub enum TimelineStatusV2 {
31    Draft,
32    Review(ReviewStatusV2),
33    Approved(ReviewStatusV2),
34    Rejected(ReviewStatusV2),
35    ApprovedConditionally(ReviewStatusV2),
36    PaymentProcessing(PaymentProcessingStatusV2),
37    Funded(FundedStatusV2),
38    Cancelled(ReviewStatusV2),
39}
40
41fn convert_review_status_to_v1(
42    review_status: ReviewStatusV1,
43    kyc_verified: bool,
44) -> ReviewStatusV2 {
45    ReviewStatusV2 {
46        sponsor_requested_review: review_status.sponsor_requested_review,
47        reviewer_completed_attestation: review_status.reviewer_completed_attestation,
48        kyc_verified: kyc_verified,
49    }
50}
51
52impl From<PaymentProcessingStatusV1> for PaymentProcessingStatusV2 {
53    fn from(value: PaymentProcessingStatusV1) -> Self {
54        PaymentProcessingStatusV2 {
55            review_status: convert_review_status_to_v1(value.review_status, value.kyc_verified),
56            kyc_verified_deprecated: false,
57            test_transaction_sent: value.test_transaction_sent,
58            request_for_trustees_created: value.request_for_trustees_created,
59        }
60    }
61}
62
63impl From<FundedStatusV1> for FundedStatusV2 {
64    fn from(value: FundedStatusV1) -> Self {
65        FundedStatusV2 {
66            payment_processing_status: value.payment_processing_status.into(),
67            trustees_released_payment: value.trustees_released_payment,
68            payouts: value.payouts,
69        }
70    }
71}
72
73impl From<TimelineStatusV1> for TimelineStatusV2 {
74    fn from(value: TimelineStatusV1) -> Self {
75        match value {
76            TimelineStatusV1::Draft => TimelineStatusV2::Draft,
77            TimelineStatusV1::Review(review_status) => {
78                TimelineStatusV2::Review(convert_review_status_to_v1(review_status, false))
79            }
80            TimelineStatusV1::Approved(review_status) => {
81                TimelineStatusV2::Approved(convert_review_status_to_v1(review_status, false))
82            }
83            TimelineStatusV1::Rejected(review_status) => {
84                TimelineStatusV2::Rejected(convert_review_status_to_v1(review_status, false))
85            }
86            TimelineStatusV1::ApprovedConditionally(review_status) => {
87                TimelineStatusV2::ApprovedConditionally(convert_review_status_to_v1(
88                    review_status,
89                    false,
90                ))
91            }
92            TimelineStatusV1::PaymentProcessing(payment_processing_status) => {
93                TimelineStatusV2::PaymentProcessing(payment_processing_status.into())
94            }
95            TimelineStatusV1::Funded(funded_status) => {
96                TimelineStatusV2::Funded(funded_status.into())
97            }
98            TimelineStatusV1::Cancelled(review_status) => {
99                TimelineStatusV2::Cancelled(convert_review_status_to_v1(review_status, false))
100            }
101        }
102    }
103}
104
105impl VersionedTimelineStatus {
106    pub fn latest_version(self) -> TimelineStatus {
107        self.into()
108    }
109}
110
111impl From<VersionedTimelineStatus> for TimelineStatusV2 {
112    fn from(value: VersionedTimelineStatus) -> Self {
113        match value {
114            VersionedTimelineStatus::V1(v1) => v1,
115        }
116    }
117}
118
119impl From<TimelineStatusV2> for VersionedTimelineStatus {
120    fn from(value: TimelineStatusV2) -> Self {
121        VersionedTimelineStatus::V1(value)
122    }
123}
124
125impl From<TimelineStatusV1> for VersionedTimelineStatus {
126    fn from(value: TimelineStatusV1) -> Self {
127        VersionedTimelineStatus::V1(value.into())
128    }
129}
130
131impl TimelineStatus {
132    pub fn is_draft(&self) -> bool {
133        matches!(self, TimelineStatus::Draft)
134    }
135
136    pub fn is_empty_review(&self) -> bool {
137        match self {
138            TimelineStatus::Review(review_status) => {
139                !review_status.sponsor_requested_review
140                    && !review_status.reviewer_completed_attestation
141            }
142            _ => false,
143        }
144    }
145
146    pub fn is_review(&self) -> bool {
147        matches!(self, TimelineStatus::Review(..))
148    }
149
150    pub fn is_cancelled(&self) -> bool {
151        matches!(self, TimelineStatus::Cancelled(..))
152    }
153
154    pub fn can_be_cancelled(&self) -> bool {
155        match self {
156            TimelineStatus::Draft => true,
157            TimelineStatus::Review(..) => true,
158            _ => false,
159        }
160    }
161
162    pub fn was_approved(&self) -> bool {
163        match self {
164            TimelineStatus::Approved(..) => true,
165            TimelineStatus::ApprovedConditionally(..) => true,
166            TimelineStatus::PaymentProcessing(..) => true,
167            TimelineStatus::Funded(..) => true,
168            _ => false,
169        }
170    }
171
172    pub fn get_review_status(&self) -> &ReviewStatus {
173        match self {
174            TimelineStatus::Review(review_status)
175            | TimelineStatus::Approved(review_status)
176            | TimelineStatus::Rejected(review_status)
177            | TimelineStatus::ApprovedConditionally(review_status)
178            | TimelineStatus::Cancelled(review_status) => review_status.into(),
179            TimelineStatus::PaymentProcessing(payment_processing_status) => {
180                &payment_processing_status.review_status
181            }
182            TimelineStatus::Funded(funded_status) => {
183                &funded_status.payment_processing_status.review_status
184            }
185            TimelineStatus::Draft => &ReviewStatus {
186                sponsor_requested_review: false,
187                reviewer_completed_attestation: false,
188                kyc_verified: false,
189            },
190        }
191    }
192}
193
194#[near(serializers=[borsh, json])]
195#[derive(Clone, Debug)]
196pub struct ReviewStatusV1 {
197    sponsor_requested_review: bool,
198    reviewer_completed_attestation: bool,
199}
200
201#[near(serializers=[borsh, json])]
202#[derive(Clone, Debug)]
203pub struct ReviewStatusV2 {
204    sponsor_requested_review: bool,
205    reviewer_completed_attestation: bool,
206    kyc_verified: bool,
207}
208
209#[near(serializers=[borsh, json])]
210#[derive(Clone, Debug)]
211pub struct PaymentProcessingStatusV1 {
212    #[serde(flatten)]
213    review_status: ReviewStatusV1,
214    kyc_verified: bool,
215    test_transaction_sent: bool,
216    request_for_trustees_created: bool,
217}
218
219#[near(serializers=[borsh, json])]
220#[derive(Clone, Debug)]
221pub struct PaymentProcessingStatusV2 {
222    #[serde(flatten)]
223    review_status: ReviewStatusV2,
224    #[serde(default)]
225    kyc_verified_deprecated: bool,
226    test_transaction_sent: bool,
227    request_for_trustees_created: bool,
228}
229
230#[near(serializers=[borsh, json])]
231#[derive(Clone, Debug)]
232pub struct FundedStatusV1 {
233    #[serde(flatten)]
234    payment_processing_status: PaymentProcessingStatusV1,
235    trustees_released_payment: bool,
236    payouts: Vec<String>,
237}
238
239#[near(serializers=[borsh, json])]
240#[derive(Clone, Debug)]
241pub struct FundedStatusV2 {
242    #[serde(flatten)]
243    payment_processing_status: PaymentProcessingStatusV2,
244    trustees_released_payment: bool,
245    payouts: Vec<String>,
246}