Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 187 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
InstancyServiceV2 | |
0.00% |
0 / 187 |
|
0.00% |
0 / 10 |
1806 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
createInstancyUser | |
0.00% |
0 / 54 |
|
0.00% |
0 / 1 |
132 | |||
updateMembership | |
0.00% |
0 / 58 |
|
0.00% |
0 / 1 |
132 | |||
userMembershipDetails | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getUserDetailsByEmailForAllSites | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
20 | |||
validateUser | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
authenticateUser | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
42 | |||
generateSessionID | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
12 | |||
callInstancyApi | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
hasError | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace App\Http\Services; |
4 | |
5 | use Carbon\Carbon; |
6 | use Illuminate\Support\Str; |
7 | use App\Http\Models\Auth\User; |
8 | use Illuminate\Support\Facades\Http; |
9 | use App\Exceptions\ExpectedException; |
10 | use App\Http\Models\Admin\Company; |
11 | use App\Http\Models\Admin\CompanyGroup; |
12 | |
13 | class InstancyServiceV2 |
14 | { |
15 | private $astrKey; |
16 | private $url; |
17 | private $sso_url; |
18 | private $siteGroupId; |
19 | private $action; |
20 | private $uniquePassword; |
21 | |
22 | public function __construct() |
23 | { |
24 | $this->url = "https://ondemand-admin.vengreso.com/InstancyService.asmx"; |
25 | $this->sso_url = "https://ondemand-master-admin.vengreso.com/InstancyService.asmx"; |
26 | $this->astrKey = "22A9838A-2196-47ED-8126-4321B7A07EF1"; |
27 | $this->siteGroupId = "388"; |
28 | $this->uniquePassword = '17$5I$jaFq@'; |
29 | |
30 | if (!isProduction() && !isLocalProduction()) { |
31 | $this->url = "https://ondemand-admin.instancy.net/instancyservice.asmx"; |
32 | $this->sso_url = "https://ondemand-master-admin.instancy.net/InstancyService.asmx"; |
33 | $this->astrKey = "A58ABE98-1B0D-41FC-9805-0F34D6B99E80"; |
34 | } |
35 | } |
36 | |
37 | /** |
38 | * Create Instancy User |
39 | * |
40 | * |
41 | * @return mixed |
42 | */ |
43 | public function createInstancyUser(string $email, string $groupId): array |
44 | { |
45 | $user = User::whereEmail($email)->first(); |
46 | if (!$user) { |
47 | return ["Error" => "User not found"]; |
48 | } |
49 | $First_Name = str_replace("'", " ", $user->first_name); |
50 | $Last_Name = str_replace("'", " ", $user->last_name); |
51 | $this->action = "CreateUser"; |
52 | |
53 | $parentId = $this->siteGroupId; |
54 | |
55 | if ($groupId) { |
56 | $parentId = $groupId; |
57 | } |
58 | |
59 | // Get the users subscription data. |
60 | // We are assuming that all the users have subscription records |
61 | // since this is only for pro users. |
62 | $subscription = $user->subscription("main"); |
63 | |
64 | if (!$subscription) { |
65 | throw new ExpectedException("The user with email $email needs to have an active subscription"); |
66 | } |
67 | |
68 | $end_date = Carbon::parse($subscription->ends_at)->toDateString(); |
69 | $start_date = $subscription->created_at->toDateString(); |
70 | |
71 | if ($subscription->stripe_status == "trialing") { |
72 | $end_date = Carbon::parse($subscription->trial_ends_at)->toDateString(); |
73 | } |
74 | |
75 | $MembershipType = "Annual"; |
76 | $MembershipDurationID = 30; // Sales pro yearly |
77 | |
78 | if ($subscription->plan && $subscription->plan->identifier == "sales-pro-monthly") { |
79 | $MembershipType = "Non-Annual"; |
80 | $MembershipDurationID = 32; // Sales pro yearly |
81 | } |
82 | |
83 | $instancyEmail = $email; |
84 | |
85 | if (!isProduction() && !isLocalProduction()) { |
86 | $instancyEmail = 'staging.' . $email; |
87 | } |
88 | |
89 | $xml = "<?xml version='1.0' encoding='iso-8859-1'?> |
90 | <InstancyWrapper> |
91 | <Request SiteID='$this->siteGroupId'> |
92 | <UserDetails> |
93 | <GroupID><![CDATA[$parentId]]></GroupID> |
94 | <First_Name><![CDATA[$First_Name]]></First_Name> |
95 | <Gender><![CDATA[1]]></Gender> |
96 | <Last_Name><![CDATA[$Last_Name]]></Last_Name> |
97 | <User_name><![CDATA[$instancyEmail]]></User_name> |
98 | <Email><![CDATA[$instancyEmail]]></Email> |
99 | <Password><![CDATA[FlyMSGWelcome#2024]]></Password> |
100 | <Mobile_Number><![CDATA[0000000000]]></Mobile_Number> |
101 | <Job_title>User</Job_title> |
102 | <Company_Name>Vengreso</Company_Name> |
103 | <MembershipDurationID>$MembershipDurationID</MembershipDurationID> |
104 | <PaymentType><![CDATA[Credit Card]]></PaymentType> |
105 | </UserDetails> |
106 | </Request> |
107 | </InstancyWrapper>"; |
108 | |
109 | $response = $this->callInstancyApi($xml); |
110 | $response = parseInstancyXml($response); |
111 | |
112 | $response = parseInstancyXml($response["value"]); |
113 | $response_status = $response['Response'][0]["@attributes"]["Result"]; |
114 | |
115 | if ($response_status == "Success") { |
116 | // Update the user profile with the instancy ID |
117 | $instancy_id = $response["UserDetails"][0]["UserID"][0]["value"]; |
118 | $user->instancy_id = $instancy_id; |
119 | $user->save(); |
120 | |
121 | $response["FlyMSGUser"] = [ |
122 | "InstancyID" => $instancy_id, |
123 | "Email" => $email |
124 | ]; |
125 | } else { |
126 | $result = $this->getUserDetailsByEmailForAllSites($email); |
127 | $result_status = $result['Response'][0]["@attributes"]["Result"]; |
128 | if ($result_status == "Success") { |
129 | // Get the user id and save it to the DB user profile |
130 | $instancy_id = $result['UserDetails'][0]['UserID'][0]['value']; |
131 | $response["FlyMSGUser"] = [ |
132 | "InstancyID" => $instancy_id, |
133 | "Email" => $email |
134 | ]; |
135 | } |
136 | } |
137 | |
138 | return $response; |
139 | } |
140 | |
141 | /** |
142 | * Update Membership on instancy. |
143 | * Used mostly to update the users membership expiry date. |
144 | * If a param $date is passed, it will be used as the new expiry date. |
145 | * |
146 | * @param string $email |
147 | * @param string $date of expiry |
148 | * |
149 | * @return array |
150 | */ |
151 | public function updateMembership($email, $date = null): array |
152 | { |
153 | $user = User::withTrashed()->whereEmail($email)->first(); |
154 | $group = CompanyGroup::find($user->company_group_id); |
155 | $company = Company::find($user->company_id); |
156 | |
157 | $groupId = false; |
158 | if ($group) { |
159 | $groupId = $group->instancy_id; |
160 | } elseif ($company) { |
161 | $groupId = $company->instancy_id; |
162 | } |
163 | |
164 | if (!$user) { |
165 | return ["Error" => "User not found"]; |
166 | } |
167 | |
168 | $instancy_id = $user->instancy_id; |
169 | if (!$instancy_id) { |
170 | $result = $this->getUserDetailsByEmailForAllSites($email); |
171 | $result_status = $result['Response'][0]["@attributes"]["Result"]; |
172 | if ($result_status == "Success") { |
173 | // Get the user id and save it to the DB user profile |
174 | $instancy_id = $result['UserDetails'][0]['UserID'][0]['value']; |
175 | $user->instancy_id = $instancy_id; |
176 | $user->save(); |
177 | } else { |
178 | $this->createInstancyUser($email, $groupId); |
179 | $result = $this->getUserDetailsByEmailForAllSites($email); |
180 | $result_status = $result['Response'][0]["@attributes"]["Result"]; |
181 | if ($result_status == "Success") { |
182 | // Get the user id and save it to the DB user profile |
183 | $instancy_id = $result['UserDetails'][0]['UserID'][0]['value']; |
184 | $user->instancy_id = $instancy_id; |
185 | $user->save(); |
186 | } |
187 | } |
188 | } |
189 | |
190 | // Get the users subscription data. |
191 | // We are assuming that all the users have subscription records |
192 | // since this is only for pro users. |
193 | $subscription = $user->subscription("main"); |
194 | |
195 | $end_date = Carbon::parse($subscription->ends_at)->toDateString(); |
196 | $start_date = $subscription->created_at->toDateString(); |
197 | |
198 | if ($subscription->stripe_status == "trialing") { |
199 | $end_date = Carbon::parse($subscription->trial_ends_at)->toDateString(); |
200 | } |
201 | |
202 | if ($subscription->stripe_status != "active" && $subscription->stripe_status != "trialing") { |
203 | // If not active, expire it by setting the expiry date to a day before |
204 | // today. |
205 | $end_date = Carbon::now()->toDateString(); |
206 | } |
207 | |
208 | $this->action = 'UpdateMemebrship'; |
209 | $siteID = $this->siteGroupId; |
210 | $end_date = $date ?? $end_date; |
211 | |
212 | $DurationName = "One Year"; |
213 | $MembershipType = "Annual"; |
214 | $MembershipDurationID = 30; // Sales pro yearly |
215 | |
216 | if ($subscription->plan?->identifier == "sales-pro-monthly") { |
217 | $DurationName = "One Month"; |
218 | $MembershipType = "Non-Annual"; |
219 | $MembershipDurationID = 32; // Sales pro yearly |
220 | } |
221 | |
222 | $xml = "<?xml version='1.0' encoding='iso-8859-1'?> |
223 | <InstancyWrapper> |
224 | <Request SiteID='$siteID'> |
225 | <UpdateMemebrship> |
226 | <MembershipID>40</MembershipID> |
227 | <UserID>$instancy_id</UserID> |
228 | <ExpiryDate>$end_date</ExpiryDate> |
229 | <StartDate>$start_date</StartDate> |
230 | <DurationName>$DurationName</DurationName> |
231 | <MembershipDurationID>$MembershipDurationID</MembershipDurationID> |
232 | <RecurringProfileID></RecurringProfileID> |
233 | <Paymentmode>Exempted</Paymentmode> |
234 | <Notes></Notes> |
235 | <Amount>0</Amount> |
236 | </UpdateMemebrship> |
237 | </Request> |
238 | </InstancyWrapper>"; |
239 | $response = $this->callInstancyApi($xml); |
240 | $response = parseInstancyXml($response); |
241 | $response = parseInstancyXml($response["value"]); |
242 | $response["FlyMSGUser"] = [ |
243 | "InstancyID" => $instancy_id, |
244 | "Email" => $email |
245 | ]; |
246 | |
247 | return $response; |
248 | } |
249 | |
250 | /** |
251 | * function to get the user membership details |
252 | */ |
253 | public function userMembershipDetails($data): array |
254 | { |
255 | return $this->getUserDetailsByEmailForAllSites($data['email']); |
256 | } |
257 | |
258 | /** |
259 | * Get Membership Details by Email |
260 | * Use this to get the details about the user and the membership |
261 | * but mostly to get the USER ID to backfill the missing |
262 | * ones on flymsg DB. |
263 | * |
264 | * @param string $email |
265 | * |
266 | * @return array $response |
267 | */ |
268 | public function getUserDetailsByEmailForAllSites($email): array |
269 | { |
270 | $user = User::whereEmail($email)->first(); |
271 | if (!$user) { |
272 | return ["Error" => "User not found"]; |
273 | } |
274 | |
275 | $instancy_id = $user->instancy_id; |
276 | |
277 | $instancyEmail = $email; |
278 | |
279 | if (!isProduction() && !isLocalProduction()) { |
280 | $instancyEmail = 'staging.' . $email; |
281 | } |
282 | |
283 | $this->action = 'GetUserInfoByEmailForAllSites'; |
284 | $siteID = $this->siteGroupId; |
285 | $xml = "<?xml version='1.0' encoding='iso-8859-1'?><InstancyWrapper><Request SiteID='$siteID'/><UserDetails><email><![CDATA[$instancyEmail]]></email></UserDetails></InstancyWrapper>"; |
286 | $response = $this->callInstancyApi($xml); |
287 | $response = parseInstancyXml($response); |
288 | $response = parseInstancyXml($response["value"]); |
289 | $response["FlyMSGUser"] = [ |
290 | "InstancyID" => $instancy_id, |
291 | "Email" => $email |
292 | ]; |
293 | return $response; |
294 | } |
295 | |
296 | public function validateUser(string $email): bool |
297 | { |
298 | $response = $this->getUserDetailsByEmailForAllSites($email); |
299 | return $this->hasError($response); |
300 | } |
301 | |
302 | public function authenticateUser(string $email) |
303 | { |
304 | $response = $this->generateSessionID($email); |
305 | |
306 | if ($this->hasError($response)) { |
307 | if ( |
308 | $response["Response"][0]["@attributes"]["ResultDescription"] != "User Membership Expired" && |
309 | $response["Response"][0]["@attributes"]["ResultDescription"] != "Account Deactivated" |
310 | ) { |
311 | // Attempt to create the user and authenticate again |
312 | // this preserves the old api. |
313 | |
314 | $user = User::firstWhere('email', $email); |
315 | $group = CompanyGroup::find($user->company_group_id); |
316 | $company = Company::find($user->company_id); |
317 | |
318 | $groupId = false; |
319 | if ($company) { |
320 | $groupId = $company->instancy_id; |
321 | } elseif ($group) { |
322 | $groupId = $group->instancy_id; |
323 | } |
324 | |
325 | $this->createInstancyUser($email, $groupId); |
326 | $response = $this->authenticateUser($email); |
327 | // Handle authentication error |
328 | return $response; // Or throw an exception |
329 | } |
330 | } |
331 | return $response; |
332 | } |
333 | |
334 | private function generateSessionID($email) |
335 | { |
336 | $api = $this->sso_url . '/AuthenticateUser'; |
337 | $siteID = $this->siteGroupId; |
338 | |
339 | $instancyEmail = $email; |
340 | |
341 | if (!isProduction() && !isLocalProduction()) { |
342 | $instancyEmail = 'staging.' . $email; |
343 | } |
344 | |
345 | $data = "<?xml version='1.0' encoding='iso-8859-1'?><InstancyWrapper><Request SiteID='$siteID'><UserDetails><UserID><![CDATA[-1]]></UserID><Email><![CDATA[$instancyEmail]]></Email><Password><![CDATA[$this->uniquePassword]]></Password></UserDetails></Request></InstancyWrapper>"; |
346 | $response = Http::withHeaders([ |
347 | 'Cookie' => 'ASP.NET_SessionId=fuhbkztcn41q4vteeipt5jmr', |
348 | 'Accept-Encoding' => '', |
349 | ])->asForm() |
350 | ->post($api, [ |
351 | 'astrKey' => $this->astrKey, |
352 | 'astrXML' => $data, |
353 | ]); |
354 | |
355 | $email = urlencode($email); |
356 | |
357 | $response = parseInstancyXml($response->body()); |
358 | $response = parseInstancyXml($response["value"]); |
359 | |
360 | return $response; |
361 | } |
362 | |
363 | private function callInstancyApi($xml) |
364 | { |
365 | $url = $this->url . '/' . $this->action; |
366 | $response = Http::withHeaders([ |
367 | 'Accept-Encoding' => '', |
368 | 'Content-Type' => 'application/x-www-form-urlencoded', |
369 | ])->asForm() |
370 | ->post($url, [ |
371 | 'astrKey' => $this->astrKey, |
372 | 'astrXML' => $xml, |
373 | ])->body(); |
374 | return $response; |
375 | } |
376 | |
377 | public function hasError($response) |
378 | { |
379 | return Str::contains(json_encode($response), ['Invalid User ID', 'Invalid Client ID', 'There is no row', 'Error']); |
380 | } |
381 | } |