Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
12.50% covered (danger)
12.50%
4 / 32
25.00% covered (danger)
25.00%
2 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProcessCompanyAsyncJob
12.50% covered (danger)
12.50%
4 / 32
25.00% covered (danger)
25.00%
2 / 8
235.05
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handle
50.00% covered (danger)
50.00%
2 / 4
0.00% covered (danger)
0.00%
0 / 1
4.12
 backoff
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleted
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 updated
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
42
 updateUserInfo
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 validateUpdatedFields
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 parseFields
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Jobs;
4
5use App\Http\Models\Admin\Company;
6use App\Http\Models\UserInfo;
7use App\Http\Services\RoleplayAddonLifecycleService;
8use App\Traits\ObjectMapper;
9use Illuminate\Bus\Queueable;
10use Illuminate\Contracts\Queue\ShouldQueue;
11use Illuminate\Foundation\Bus\Dispatchable;
12use Illuminate\Queue\InteractsWithQueue;
13use Illuminate\Queue\SerializesModels;
14
15class ProcessCompanyAsyncJob implements ShouldQueue
16{
17    use Dispatchable, InteractsWithQueue, ObjectMapper, Queueable, SerializesModels;
18
19    public $tries = 5;
20
21    public function __construct(
22        public Company $company,
23        public string $action
24    ) {}
25
26    public function handle(): void
27    {
28        if ($this->action === 'updated') {
29            $this->updated($this->company);
30        } elseif ($this->action === 'deleted') {
31            $this->deleted($this->company);
32        }
33    }
34
35    public function backoff()
36    {
37        return [10, 30, 60, 120, 300];
38    }
39
40    private function deleted(Company $company): void
41    {
42        $this->updateUserInfo([], $company, true);
43
44        // Company deletion cascades to users' corporate roleplay addons.
45        try {
46            app(RoleplayAddonLifecycleService::class)->cancelCompanyAddonForAllUsers($company);
47        } catch (\Throwable $e) {
48            \Log::warning('RoleplayAddonLifecycleService cascade on company delete failed: '.$e->getMessage());
49        }
50    }
51
52    private function updated(Company $company): void
53    {
54        $updated = $company->getDirty();
55
56        // If this update just flipped the company into a deactivated state
57        // (expiration / manual deactivation) strip corporate roleplay addons
58        // off every user so they fall back to freemium.
59        if (array_key_exists('deactivated_at', $updated) && ! empty($updated['deactivated_at'])) {
60            try {
61                app(RoleplayAddonLifecycleService::class)->cancelCompanyAddonForAllUsers($company);
62            } catch (\Throwable $e) {
63                \Log::warning('RoleplayAddonLifecycleService cascade on company deactivation failed: '.$e->getMessage());
64            }
65        }
66
67        if (! empty($updated)) {
68            $fields = $this->validateUpdatedFields($updated);
69
70            if (! empty($fields)) {
71                $parsedFields = $this->parseFields($updated);
72
73                $this->updateUserInfo($parsedFields, $company);
74            }
75        }
76    }
77
78    private function updateUserInfo(array $data, Company $company, ?bool $delete = false)
79    {
80        if ($delete) {
81            UserInfo::where('company_id', $company->id)->update(['company_name' => '', 'company' => '']);
82        } elseif ($data['company_name']) {
83            UserInfo::where('company_id', $company->id)->update(['company_name' => $data['company_name'], 'company' => $data['company_name']]);
84        }
85    }
86
87    private function validateUpdatedFields(array $updated): array
88    {
89        $hubspotFields = [
90            'name',
91        ];
92
93        return array_filter($updated, fn ($key) => in_array($key, $hubspotFields), ARRAY_FILTER_USE_KEY);
94    }
95
96    private function parseFields(array $fields): array
97    {
98        $map = [
99            'name' => ['rename' => 'company_name'],
100        ];
101
102        return $this->mapObject($fields, $map);
103    }
104}