1 module konnexengine.crowd.funding.blueprint;
2 
3 import std.uuid : UUID, sha1UUID;
4 import std.conv : to;
5 import std.datetime : SysTime, Clock;
6 
7 // TODO: Localise imports
8 import konnexengine.user.blueprint : User;
9 import konnexengine.social.engagement : Comment;
10 import money : currency;
11 
12 /// CampaignInterface: `interface`
13 interface CampaignInterface
14 {
15 	/// id(): `UUID @property`
16 	@property UUID id();
17 	@property UUID ownerID();
18 	@property string title();
19 	@property string title(string input);
20 	@property string summary();
21 	@property string summary(string input);
22 	@property string overview();
23 	@property string overview(string input);
24 	@property Goal[UUID] goals();
25 	@property Goal[UUID] goals(Goal input);
26 	@property string raised();
27 	@property string raised(string input);
28 	@property User[UUID] supporters();
29 	@property User[UUID] supporters(User input);
30 	@property Donation[UUID] donations();
31 	@property Donation[UUID] donations(Donation input);
32 	@property Update[UUID] updates();
33 	@property Update[UUID] updates(Update input);
34 	@property Comment[UUID] comments();
35 	@property Comment[UUID] comments(Comment input);
36 	@property SysTime createdAt();
37 	@property SysTime launchedAt();
38 }
39 
40 /// Campaign: `class implements CampaignInterface`
41 class Campaign : CampaignInterface
42 {
43 	/// constructor for a new campaign
44 	this(string title, UUID owner)
45 	{
46 		this.c_created_at = Clock.currTime();
47 		auto id = sha1UUID(title, sha1UUID(owner.to!string));
48 		this.c_id = id;
49 		this.c_owner = owner;
50 		this.c_title = title;
51 	}
52 
53 	/// Constructor for an existing campaign
54 	this(UUID id)
55 	{
56 		this.c_id = id;
57 		// TODO: Pull in rest of existing campaign
58 	}
59 
60 	private
61 	{
62 		UUID c_id;
63 		UUID c_owner;
64 		string c_title;
65 		string c_summary;
66 		string c_overview;
67 		Goal[UUID] c_goals;
68 		string c_raised;
69 		User[UUID] c_supporters;
70 		Donation[UUID] c_donations;
71 		Update[UUID] c_updates;
72 		Comment[UUID] c_comments;
73 		SysTime c_created_at;
74 		SysTime c_launched_at;
75 	}
76 
77 	/// function id (): `returns UUID @property getter`
78 	@property UUID id()
79 	{
80 		return c_id;
81 	}
82 
83 	/// @property ownerID (): `returns UUID @property getter`
84 	@property UUID ownerID()
85 	{
86 		return c_owner;
87 	}
88 
89 	/// @property title (): `returns string @property getter`
90 	@property string title()
91 	{
92 		return c_title;
93 	}
94 
95 	@property string title(string input)
96 	{
97 		return c_title = "" ~ input;
98 	}
99 
100 	@property string summary()
101 	{
102 		return c_summary;
103 	}
104 
105 	@property string summary(string input)
106 	{
107 		return c_summary = "" ~ input;
108 	}
109 
110 	@property string overview()
111 	{
112 		return c_overview;
113 	}
114 
115 	@property string overview(string input)
116 	{
117 		return c_overview = "" ~ input;
118 	}
119 
120 	@property Goal[UUID] goals()
121 	{
122 		return c_goals;
123 	}
124 
125 	@property Goal[UUID] goals(Goal input)
126 	{
127 		c_goals[input.id] = input;
128 		return c_goals;
129 	}
130 
131 	@property string raised()
132 	{
133 		return c_raised;
134 	}
135 
136 	@property string raised(string input)
137 	{
138 		return c_raised = "" ~ input;
139 	}
140 
141 	@property User[UUID] supporters()
142 	{
143 		return c_supporters;
144 	}
145 
146 	@property User[UUID] supporters(User input)
147 	{
148 		c_supporters[input.id] = input;
149 		return c_supporters;
150 	}
151 
152 	@property Donation[UUID] donations()
153 	{
154 		return c_donations;
155 	}
156 
157 	@property Donation[UUID] donations(Donation input)
158 	{
159 		c_donations[input.id] = input;
160 		return c_donations;
161 	}
162 
163 	@property Update[UUID] updates()
164 	{
165 		return c_updates;
166 	}
167 
168 	@property Update[UUID] updates(Update input)
169 	{
170 		c_updates[input.id] = input;
171 		return c_updates;
172 	}
173 
174 	@property Comment[UUID] comments()
175 	{
176 		return c_comments;
177 	}
178 
179 	@property Comment[UUID] comments(Comment input)
180 	{
181 		c_comments[input.id] = input;
182 		return c_comments;
183 	}
184 
185 	@property SysTime createdAt()
186 	{
187 		return c_created_at;
188 	}
189 
190 	@property SysTime launchedAt()
191 	{
192 		return c_launched_at;
193 	}
194 }
195 ///
196 unittest
197 {
198 	auto owner = sha1UUID("owner", sha1UUID("namespace"));
199 	auto campaign = new Campaign("Amazing New Campaign", owner);
200 	assert(is(typeof(campaign.id()) == UUID));
201 	assert(is(typeof(campaign.ownerID()) == UUID));
202 	assert(is(typeof(campaign.title()) == string));
203 	assert(is(typeof(campaign.createdAt()) == SysTime));
204 }
205 
206 class Goal
207 {
208 
209 	this()
210 	{
211 		auto id = sha1UUID(amount ~ title, sha1UUID(amount ~ description));
212 	}
213 
214 	private
215 	{
216 		UUID id;
217 		string amount;
218 		string title;
219 		string description;
220 		SysTime achieved;
221 	}
222 
223 }
224 
225 ///
226 struct Donation
227 {
228 	UUID id;
229 	UUID donor;
230 	ulong amount;
231 }
232 
233 ///
234 struct Update
235 {
236 	UUID id;
237 	string title;
238 	string detail;
239 	Comment[] comments;
240 }