Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 99
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessAdminUserInvitationAsyncJob
0.00% covered (danger)
0.00%
0 / 99
0.00% covered (danger)
0.00%
0 / 8
600
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 handle
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 backoff
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 created
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 updated
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 createOrUpdateUserInfo
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 validateUpdatedFields
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
2
 parseFields
0.00% covered (danger)
0.00%
0 / 61
0.00% covered (danger)
0.00%
0 / 1
182
1<?php
2
3namespace App\Jobs;
4
5use App\Traits\ObjectMapper;
6use Illuminate\Bus\Queueable;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Bus\Dispatchable;
9use Illuminate\Queue\InteractsWithQueue;
10use Illuminate\Queue\SerializesModels;
11use App\Http\Models\Admin\AdminUserInvitation;
12use App\Http\Models\Admin\Company;
13use App\Http\Models\Admin\CompanyGroup;
14use App\Http\Models\UserInfo;
15use Carbon\Carbon;
16use MongoDB\BSON\UTCDateTime;
17
18class ProcessAdminUserInvitationAsyncJob implements ShouldQueue
19{
20    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, ObjectMapper;
21
22    public $tries = 5;
23
24    public function __construct(
25        public AdminUserInvitation $user,
26        public string $action
27    ) {}
28
29    public function handle(): void
30    {
31        if ($this->action === 'created') {
32            $this->created($this->user);
33        } elseif ($this->action === 'updated') {
34            $this->updated($this->user);
35        }
36    }
37
38    public function backoff()
39    {
40        return [10, 30, 60, 120, 300];
41    }
42
43    private function created(AdminUserInvitation $user): void
44    {
45        $created = $user->toArray();
46
47        $parsedFields = $this->parseFields($created, $user);
48
49        $this->createOrUpdateUserInfo($parsedFields);
50    }
51
52    private function updated(AdminUserInvitation $user): void
53    {
54        $updated = $user->toArray();
55
56        if (!empty($updated)) {
57            $fields = $this->validateUpdatedFields($updated);
58
59            if (!empty($fields)) {
60                $parsedFields = $this->parseFields($updated, $user);
61
62                $this->createOrUpdateUserInfo($parsedFields);
63            }
64        }
65    }
66
67    private function createOrUpdateUserInfo(array $data)
68    {
69        $userInfo = UserInfo::firstOrNew(['email' => $data['email']]);
70
71        $userInfo->fill($data);
72        $userInfo->save();
73    }
74
75    private function validateUpdatedFields(array $updated): array
76    {
77        $hubspotFields = [
78            'first_name',
79            'last_name',
80            'email',
81            'email_verified_at',
82            'created_at',
83            'updated_at',
84            'id',
85            'signup_source',
86            'company_id',
87            'stripe_id',
88            'status',
89            'avatar',
90            'hubspot_id',
91            'instancy_id',
92            'group_id',
93            'heap_analytics_id',
94            'company_group_id',
95        ];
96
97        return array_filter($updated, fn($key) => in_array($key, $hubspotFields), ARRAY_FILTER_USE_KEY);
98    }
99
100    private function parseFields(array $fields, AdminUserInvitation $user): array
101    {
102        $map = [
103            'first_name' => [],
104            'last_name' => [],
105            'email' => [],
106            'signup_source' => [],
107            'group_id' => [],
108            'hubspot_id' => [],
109            'instancy_id' => [],
110            'avatar' => [],
111            'status' => [],
112            'heap_analytics_id' => [],
113            'company_group_id' => ['rename' => 'group_id'],
114            'id' => ['rename' => 'user_id'],
115        ];
116
117        $result = $this->mapObject($fields, $map);
118
119        $result['user_id'] = $user->id;
120
121        if (!empty($fields['first_name']) || !empty($fields['last_name'])) {
122            $result['full_name'] = $user->first_name . ' ' . $user->last_name;
123        }
124
125        if (!empty($fields['stripe_id'])) {
126            $result['df_stripe_customer_id'] = $fields['stripe_id'];
127            $result['stripe_id'] = $fields['stripe_id'];
128        }
129
130        if (!empty($fields['created_at'])) {
131            $carbonCreationDate = Carbon::parse($fields['created_at']);
132            $result['account_creation_date'] = new UTCDateTime($carbonCreationDate->getTimestamp() * 1000);
133            $result['user_created_at'] = new UTCDateTime($carbonCreationDate->getTimestamp() * 1000);
134        }
135
136        if (!empty($fields['updated_at'])) {
137            $carbonUpdateDate = Carbon::parse($fields['updated_at']);
138            $result['user_updated_at'] = new UTCDateTime($carbonUpdateDate->getTimestamp() * 1000);
139        }
140
141        if (!empty($fields['email_verified_at'])) {
142            $carbonDate = Carbon::createFromTimestamp($fields['email_verified_at']->toDateTime()->getTimestamp());
143            $result['email_verified_at'] = new UTCDateTime($carbonDate->getTimestamp() * 1000);
144        }
145
146        if (!empty($fields['email'])) {
147            $result['email_domain'] = strrchr($user->email, "@");
148            $result['email_domain_count'] = UserInfo::where('email_domain', $result['email_domain'])->count();
149
150            $userInfoDispatcher = UserInfo::getEventDispatcher();
151            UserInfo::unsetEventDispatcher();
152
153            UserInfo::where('email_domain', $result['email_domain'])->update(['email_domain_count' => $result['email_domain_count']]);
154
155            if ($userInfoDispatcher) {
156                UserInfo::setEventDispatcher($userInfoDispatcher);
157            }
158        }
159
160        if (!empty($fields['status'])) {
161            $result['status_date'] = now();
162        }
163
164        if (!empty($fields['company_id'])) {
165            $companyName = Company::find($fields['company_id'])->name;
166            $result['company'] = $companyName;
167            $result['company_name'] = $companyName;
168        } else {
169            $result['company'] = 'Individual';
170            $result['company_name'] = 'Individual';
171        }
172
173        if (!empty($fields['company_group_id'])) {
174            $group = CompanyGroup::find($fields['company_group_id']);
175            $parentGroup = CompanyGroup::where('id', $group->parent_id)->first();
176
177            if ($parentGroup) {
178                $result['group_id'] = $parentGroup->id;
179                $result['group_name'] = $parentGroup->name;
180                $result['subgroup_id'] = $group->id;
181                $result['subgroup_name'] = $group->name;
182            } else {
183                $result['group_id'] = $group->id;
184                $result['group_name'] = $group->name;
185            }
186        } else {
187            $result['group_name'] = null;
188        }
189
190        $result['is_invitation'] = true;
191        $result['is_invite'] = true;
192
193        return $result;
194    }
195}