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}