Skip to content

Commit cfd845a

Browse files
authored
Merge pull request #16500 from marcusmoore/bug/sc-28644-command
Added command to fix bulk checkin action log entries
2 parents a98b277 + 9a8e5bf commit cfd845a

1 file changed

Lines changed: 151 additions & 0 deletions

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Models\Accessory;
6+
use App\Models\Actionlog;
7+
use Illuminate\Console\Command;
8+
use Illuminate\Database\Eloquent\Model;
9+
10+
class FixBulkAccessoryCheckinActionLogEntries extends Command
11+
{
12+
/**
13+
* The name and signature of the console command.
14+
*
15+
* @var string
16+
*/
17+
protected $signature = 'snipeit:fix-bulk-accessory-action-log-entries {--dry-run : Run the sync process but don\'t update the database} {--skip-backup : Skip pre-execution backup}';
18+
19+
/**
20+
* The console command description.
21+
*
22+
* @var string
23+
*/
24+
protected $description = 'This script attempts to fix timestamps and missing created_by values for bulk checkin entries in the log table';
25+
26+
private bool $dryrun = false;
27+
private bool $skipBackup = false;
28+
29+
/**
30+
* Execute the console command.
31+
*/
32+
public function handle()
33+
{
34+
$this->skipBackup = $this->option('skip-backup');
35+
$this->dryrun = $this->option('dry-run');
36+
37+
if ($this->dryrun) {
38+
$this->info('This is a DRY RUN - no changes will be saved.');
39+
$this->newLine();
40+
}
41+
42+
$logs = Actionlog::query()
43+
// only look for accessory checkin logs
44+
->where('item_type', Accessory::class)
45+
// that were part of a bulk checkin
46+
->where('note', 'Bulk checkin items')
47+
// logs that were improperly timestamped should have created_at in the 1970s
48+
->whereYear('created_at', '1970')
49+
->get();
50+
51+
if ($logs->isEmpty()) {
52+
$this->info('No logs found with incorrect timestamps.');
53+
return 0;
54+
}
55+
56+
$this->info('Found ' . $logs->count() . ' logs with incorrect timestamps:');
57+
58+
$this->table(
59+
['ID', 'Created By', 'Created At', 'Updated At'],
60+
$logs->map(function ($log) {
61+
return [
62+
$log->id,
63+
$log->created_by,
64+
$log->created_at,
65+
$log->updated_at,
66+
];
67+
})
68+
);
69+
70+
if (!$this->dryrun && !$this->confirm('Update these logs?')) {
71+
return 0;
72+
}
73+
74+
if (!$this->dryrun && !$this->skipBackup) {
75+
$this->info('Backing up the database before making changes...');
76+
$this->call('snipeit:backup');
77+
}
78+
79+
if ($this->dryrun) {
80+
$this->newLine();
81+
$this->info('DRY RUN. NOT ACTUALLY UPDATING LOGS.');
82+
}
83+
84+
foreach ($logs as $log) {
85+
$this->newLine();
86+
$this->info('Processing log id:' . $log->id);
87+
88+
// created_by was not being set for accessory bulk checkins
89+
// so let's see if there was another bulk checkin log
90+
// with the same timestamp and a created_by value we can use.
91+
if (is_null($log->created_by)) {
92+
$createdByFromSimilarLog = $this->getCreatedByAttributeFromSimilarLog($log);
93+
94+
if ($createdByFromSimilarLog) {
95+
$this->line(vsprintf('Updating log id:%s created_by to %s', [$log->id, $createdByFromSimilarLog]));
96+
$log->created_by = $createdByFromSimilarLog;
97+
} else {
98+
$this->warn(vsprintf('No created_by found for log id:%s', [$log->id]));
99+
$this->warn('Skipping updating this log since no similar log was found to update created_by from.');
100+
101+
// If we can't find a similar log then let's skip updating it
102+
continue;
103+
}
104+
}
105+
106+
$this->line(vsprintf('Updating log id:%s from %s to %s', [$log->id, $log->created_at, $log->updated_at]));
107+
$log->created_at = $log->updated_at;
108+
109+
if (!$this->dryrun) {
110+
Model::withoutTimestamps(function () use ($log) {
111+
$log->saveQuietly();
112+
});
113+
}
114+
}
115+
116+
$this->newLine();
117+
118+
if ($this->dryrun) {
119+
$this->info('DRY RUN. NO CHANGES WERE ACTUALLY MADE.');
120+
}
121+
122+
return 0;
123+
}
124+
125+
/**
126+
* Hopefully the bulk checkin included other items like assets or licenses
127+
* so we can use one of those logs to get the correct created_by value.
128+
*
129+
* This method attempts to find a bulk check in log that was
130+
* created at the same time as the log passed in.
131+
*/
132+
private function getCreatedByAttributeFromSimilarLog(Actionlog $log): null|int
133+
{
134+
$similarLog = Actionlog::query()
135+
->whereNotNull('created_by')
136+
->where([
137+
'action_type' => 'checkin from',
138+
'note' => 'Bulk checkin items',
139+
'target_id' => $log->target_id,
140+
'target_type' => $log->target_type,
141+
'created_at' => $log->updated_at,
142+
])
143+
->first();
144+
145+
if ($similarLog) {
146+
return $similarLog->created_by;
147+
}
148+
149+
return null;
150+
}
151+
}

0 commit comments

Comments
 (0)