Skip to content

Commit 6f1fb28

Browse files
authored
feat: corp projects (#719)
* feat: corp projects * style: styleci * feat: thanks r'tree for review
1 parent abf0c33 commit 6f1fb28

15 files changed

Lines changed: 704 additions & 0 deletions

File tree

src/Acl/EsiRolesMap.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ class EsiRolesMap
142142
'corporation.summary',
143143
'corporation.market',
144144
],
145+
'Project Manager' => [
146+
'corporation.projects',
147+
],
145148
];
146149

147150
/**

src/Config/Permissions/corporation.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,8 @@
183183
'label' => 'web::permissions.corporation_tracking_label',
184184
'description' => 'web::permissions.corporation_tracking_description',
185185
],
186+
'projects' => [
187+
'label' => 'web::permissions.corporation_projects_label',
188+
'description' => 'web::permissions.corporation_projects_description',
189+
],
186190
];

src/Config/package.corporation.menu.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@
6464
'highlight_view' => 'industry',
6565
'route' => 'seatcore::corporation.view.industry',
6666
],
67+
[
68+
'name' => 'project',
69+
'label' => 'web::seat.project',
70+
'plural' => true,
71+
'permission' => 'corporation.projects',
72+
'highlight_view' => 'projects',
73+
'route' => 'seatcore::corporation.view.projects',
74+
],
6775
[
6876
'name' => 'killmails',
6977
'label' => 'web::seat.killmails',

src/Config/web.jobnames.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
'transactions' => \Seat\Eveapi\Jobs\Wallet\Corporation\Transactions::class,
7777
'starbases' => \Seat\Eveapi\Jobs\Corporation\Starbases::class,
7878
'structures' => \Seat\Eveapi\Jobs\Corporation\Structures::class,
79+
'projects' => \Seat\Eveapi\Jobs\CorporationProjects\Projects::class,
7980
],
8081
'alliance' => [
8182
'contacts' => [
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<?php
2+
3+
/*
4+
* This file is part of SeAT
5+
*
6+
* Copyright (C) 2015 to present Leon Jacobs
7+
*
8+
* This program is free software; you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation; either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License along
19+
* with this program; if not, write to the Free Software Foundation, Inc.,
20+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*/
22+
23+
namespace Seat\Web\Http\Controllers\Corporation;
24+
25+
use Seat\Eveapi\Models\Corporation\CorporationInfo;
26+
use Seat\Eveapi\Models\CorporationProjects\CorporationProject;
27+
use Seat\Web\Http\Controllers\Controller;
28+
use Seat\Web\Http\DataTables\Corporation\Financial\ProjectDataTable;
29+
use Seat\Web\Http\DataTables\Scopes\CorporationScope;
30+
31+
/**
32+
* Class StructureController.
33+
*
34+
* @package Seat\Web\Http\Controllers\Corporation
35+
*/
36+
class ProjectController extends Controller
37+
{
38+
/**
39+
* @param \Seat\Eveapi\Models\Corporation\CorporationInfo $corporation
40+
* @param \Seat\Web\Http\DataTables\Corporation\Military\StructureDataTable $dataTable
41+
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
42+
*/
43+
public function getProjects(CorporationInfo $corporation, ProjectDataTable $dataTable)
44+
{
45+
46+
return $dataTable->addScope(new CorporationScope('corporation.projects', [$corporation->corporation_id]))
47+
->render('web::corporation.projects.list', compact('corporation'));
48+
}
49+
50+
/**
51+
* @param \Seat\Eveapi\Models\Corporation\CorporationInfo $corporation
52+
* @param string $project_id
53+
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
54+
*/
55+
public function getProject(CorporationInfo $corporation, string $project_id)
56+
{
57+
$project = CorporationProject::with('contributors', 'creator')
58+
->where('id', $project_id)
59+
->first();
60+
$config = $this->normalizeProjectConfiguration($project->configuration);
61+
62+
return view('web::corporation.projects.modals.content', compact('corporation', 'project', 'config'));
63+
}
64+
65+
/**
66+
* Normalize project configuration into an array of items:
67+
* [ ['key'=>'...', 'label'=>'...', 'value'=>'...', 'description'=>null], ... ]
68+
*/
69+
protected function normalizeProjectConfiguration($configuration): array
70+
{
71+
if (is_string($configuration)) {
72+
// sometimes stored as JSON string
73+
$decoded = json_decode($configuration, true);
74+
if (json_last_error() === JSON_ERROR_NONE) {
75+
$configuration = $decoded;
76+
}
77+
}
78+
79+
// If null or empty
80+
if (empty($configuration)) {
81+
return [];
82+
}
83+
84+
$items = [];
85+
86+
// Case: configuration is an array of option objects
87+
if (is_array($configuration) && array_values($configuration) === $configuration) {
88+
foreach ($configuration as $i => $opt) {
89+
if (is_array($opt)) {
90+
$items[] = [
91+
'key' => $opt['name'] ?? "option_{$i}",
92+
'label' => $opt['display_name'] ?? $opt['name'] ?? "Option {$i}",
93+
'value' => isset($opt['value']) ? $opt['value'] : (isset($opt['default']) ? $opt['default'] : null),
94+
'description' => $opt['description'] ?? null,
95+
];
96+
} else {
97+
// primitive in array
98+
$items[] = [
99+
'key' => "option_{$i}",
100+
'label' => "Option {$i}",
101+
'value' => (string) $opt,
102+
'description' => null,
103+
];
104+
}
105+
}
106+
107+
return $items;
108+
}
109+
110+
// Case: configuration is an associative object/array of named options
111+
if (is_array($configuration)) {
112+
foreach ($configuration as $k => $v) {
113+
if (is_array($v) || is_object($v)) {
114+
$vArr = (array) $v;
115+
$items[] = [
116+
'key' => $k,
117+
'label' => $vArr['label'] ?? $vArr['name'] ?? $k,
118+
'value' => $vArr['value'] ?? $vArr['default'] ?? json_encode($vArr),
119+
'description' => $vArr['description'] ?? null,
120+
];
121+
} else {
122+
$items[] = [
123+
'key' => $k,
124+
'label' => $k,
125+
'value' => $v,
126+
'description' => null,
127+
];
128+
}
129+
}
130+
131+
return $items;
132+
}
133+
134+
// Case: object (stdClass)
135+
if (is_object($configuration)) {
136+
$arr = (array) $configuration;
137+
foreach ($arr as $k => $v) {
138+
if (is_object($v) || is_array($v)) {
139+
$vArr = (array) $v;
140+
$items[] = [
141+
'key' => $k,
142+
'label' => $vArr['label'] ?? $vArr['name'] ?? $k,
143+
'value' => $vArr['value'] ?? $vArr['default'] ?? json_encode($vArr),
144+
'description' => $vArr['description'] ?? null,
145+
];
146+
} else {
147+
$items[] = [
148+
'key' => $k,
149+
'label' => $k,
150+
'value' => $v,
151+
'description' => null,
152+
];
153+
}
154+
}
155+
156+
return $items;
157+
}
158+
159+
// Fallback: stringify whatever it is
160+
return [
161+
[
162+
'key' => 'raw',
163+
'label' => 'Configuration',
164+
'value' => is_scalar($configuration) ? (string) $configuration : json_encode($configuration),
165+
'description' => null,
166+
],
167+
];
168+
}
169+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
/*
4+
* This file is part of SeAT
5+
*
6+
* Copyright (C) 2015 to present Leon Jacobs
7+
*
8+
* This program is free software; you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation; either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License along
19+
* with this program; if not, write to the Free Software Foundation, Inc.,
20+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*/
22+
23+
namespace Seat\Web\Http\DataTables\Corporation\Financial;
24+
25+
use Illuminate\Http\JsonResponse;
26+
use Seat\Eveapi\Models\CorporationProjects\CorporationProject;
27+
use Yajra\DataTables\Services\DataTable;
28+
29+
/**
30+
* Class StructureDataTable.
31+
*
32+
* @package Seat\Web\Http\DataTables\Corporation\Financial
33+
*/
34+
class ProjectDataTable extends DataTable
35+
{
36+
/**
37+
* @return \Illuminate\Http\JsonResponse
38+
*
39+
* @throws \Exception
40+
*/
41+
public function ajax(): JsonResponse
42+
{
43+
return datatables()
44+
->eloquent($this->applyScopes($this->query()))
45+
->editColumn('state', function ($row) {
46+
return ucfirst(str_replace('_', ' ', $row->state));
47+
})
48+
->addColumn('progress', function ($raw) {
49+
$row = (object) [
50+
'min' => 0,
51+
'value' => $raw->progress_current,
52+
'max' => $raw->progress_desired,
53+
'showval' => true,
54+
];
55+
56+
return view('web::partials.progress', compact('row'))->render();
57+
})
58+
->addColumn('reward', function ($raw) use (&$rawColumns) {
59+
if (is_null($raw->reward_initial) || $raw->reward_initial == 0) {
60+
return trans('web::seat.no_reward');
61+
} else {
62+
$row = (object) [
63+
'min' => 0,
64+
'value' => $raw->reward_initial - $raw->reward_remaining,
65+
'max' => $raw->reward_initial,
66+
'showval' => true,
67+
];
68+
$rawColumns[] = 'reward';
69+
70+
return view('web::partials.progress', compact('row'))->render();
71+
}
72+
})
73+
->editColumn('action', function ($row) use ($rawColumns) {
74+
return view('web::corporation.projects.buttons.action', compact('row'))->render();
75+
})
76+
->rawColumns(['action', 'progress', 'reward'])
77+
->toJson();
78+
}
79+
80+
/**
81+
* @return \Yajra\DataTables\Html\Builder
82+
*/
83+
public function html()
84+
{
85+
return $this->builder()
86+
->postAjax()
87+
->columns($this->getColumns())
88+
->addAction()
89+
->addTableClass('table-striped table-hover')
90+
->parameters([
91+
'drawCallback' => 'function() { $("[data-toggle=tooltip]").tooltip(); }',
92+
]);
93+
}
94+
95+
/**
96+
* @return \Illuminate\Database\Eloquent\Builder
97+
*/
98+
public function query()
99+
{
100+
return CorporationProject::withCount('contributors');
101+
}
102+
103+
/**
104+
* @return array
105+
*/
106+
public function getColumns()
107+
{
108+
return [
109+
['data' => 'name', 'title' => trans_choice('web::seat.name', 1)],
110+
['data' => 'last_modified', 'title' => trans_choice('web::seat.last_modified', 1)],
111+
['data' => 'state', 'title' => trans('web::seat.state')],
112+
['data' => 'progress', 'title' => trans('web::seat.progress'), 'orderable' => false],
113+
['data' => 'reward', 'title' => trans('web::seat.reward'), 'orderable' => false],
114+
['data' => 'contributors_count', 'title' => trans_choice('web::seat.contributor', 2)],
115+
];
116+
}
117+
}

src/Http/Routes/Corporation/View.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,13 @@
214214
Route::post('/{corporation}/transactions/export')
215215
->uses('WalletController@transactions')
216216
->middleware('can:corporation.transaction,corporation');
217+
218+
Route::get('/{corporation}/projects')
219+
->name('seatcore::corporation.view.projects')
220+
->uses('ProjectController@getProjects')
221+
->middleware('can:corporation.projects,corporation');
222+
223+
Route::get('/{corporation}/project/{project_id}')
224+
->name('seatcore::corporation.view.projects.details')
225+
->uses('ProjectController@getProject')
226+
->middleware('can:corporation.projects,corporation');

src/WebServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ private function register_settings()
582582
'esi-universe.read_structures.v1',
583583
'esi-wallet.read_character_wallet.v1',
584584
'esi-wallet.read_corporation_wallets.v1',
585+
'esi-corporations.read_projects.v1',
585586
],
586587
],
587588
]);

0 commit comments

Comments
 (0)