179 lines
6.3 KiB
PHP
179 lines
6.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Market;
|
|
|
|
use App\Http\Controllers\Helpers\ResponseHelper;
|
|
use App\Models\Market\CooperativeResolution;
|
|
use App\Models\Market\CooperativeVote;
|
|
use App\Models\Market\Organization;
|
|
use App\Models\Market\CooperativeMember;
|
|
use Hypervel\Http\Request;
|
|
use Hypervel\Support\Facades\Auth;
|
|
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
|
|
use App\Enums\UserActions;
|
|
use Hypervel\Support\Str;
|
|
|
|
class GovernanceController
|
|
{
|
|
public function listResolutions(Request $request)
|
|
{
|
|
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ViewResolutions)) {
|
|
return ResponseHelper::returnUnauthorized();
|
|
}
|
|
|
|
$orgHash = $request->input('org_hash');
|
|
if (!$orgHash) {
|
|
return ResponseHelper::returnIncorrectDetails();
|
|
}
|
|
|
|
$org = Organization::where('hashkey', $orgHash)->first();
|
|
if (!$org) {
|
|
return ResponseHelper::returnError('Organization not found', 404);
|
|
}
|
|
|
|
$resolutions = CooperativeResolution::where('organization_id', $org->id)
|
|
->where('is_active', true)
|
|
->withCount(['votes as yes_votes' => function($query) {
|
|
$query->where('vote_cast', 'YES');
|
|
}])
|
|
->withCount(['votes as no_votes' => function($query) {
|
|
$query->where('vote_cast', 'NO');
|
|
}])
|
|
->withCount(['votes as abstain_votes' => function($query) {
|
|
$query->where('vote_cast', 'ABSTAIN');
|
|
}])
|
|
->orderBy('created_at', 'desc')
|
|
->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $resolutions
|
|
]);
|
|
}
|
|
|
|
public function createResolution(Request $request)
|
|
{
|
|
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::CreateResolution)) {
|
|
return ResponseHelper::returnUnauthorized();
|
|
}
|
|
|
|
$orgHash = $request->input('org_hash');
|
|
$title = $request->input('title');
|
|
$description = $request->input('description');
|
|
|
|
if (!$orgHash || !$title) {
|
|
return ResponseHelper::returnIncorrectDetails();
|
|
}
|
|
|
|
$org = Organization::where('hashkey', $orgHash)->first();
|
|
if (!$org) {
|
|
return ResponseHelper::returnError('Organization not found', 404);
|
|
}
|
|
|
|
$resolution = new CooperativeResolution([
|
|
'hashkey' => Str::random(64),
|
|
'organization_id' => $org->id,
|
|
'title' => trim($title),
|
|
'description' => trim($description ?? ''),
|
|
'status' => 'PROPOSED',
|
|
'created_by' => Auth::id(),
|
|
'is_active' => true,
|
|
]);
|
|
|
|
if ($resolution->save()) {
|
|
return ResponseHelper::returnSuccessResponse($resolution, $resolution->hashkey, 'Resolution created successfully');
|
|
}
|
|
|
|
return ResponseHelper::returnError('Failed to create resolution');
|
|
}
|
|
|
|
public function castVote(Request $request)
|
|
{
|
|
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::VoteResolution)) {
|
|
return ResponseHelper::returnUnauthorized();
|
|
}
|
|
|
|
$resolutionHash = $request->input('resolution_hash');
|
|
$vote = $request->input('vote'); // YES, NO, ABSTAIN
|
|
|
|
if (!$resolutionHash || !in_array($vote, ['YES', 'NO', 'ABSTAIN'])) {
|
|
return ResponseHelper::returnIncorrectDetails();
|
|
}
|
|
|
|
$resolution = CooperativeResolution::where('hashkey', $resolutionHash)->first();
|
|
if (!$resolution) {
|
|
return ResponseHelper::returnError('Resolution not found', 404);
|
|
}
|
|
|
|
// Check if user is a member of the organization
|
|
$isMember = CooperativeMember::where('organization_id', $resolution->organization_id)
|
|
->where('user_id', Auth::id())
|
|
->where('is_active', true)
|
|
->exists();
|
|
|
|
if (!$isMember) {
|
|
return ResponseHelper::returnError('Only active members can vote on resolutions', 403);
|
|
}
|
|
|
|
// Check for existing vote
|
|
$existingVote = CooperativeVote::where('resolution_id', $resolution->id)
|
|
->where('user_id', Auth::id())
|
|
->first();
|
|
|
|
if ($existingVote) {
|
|
$existingVote->vote_cast = $vote;
|
|
$existingVote->updated_by = Auth::id();
|
|
if ($existingVote->save()) {
|
|
return ResponseHelper::returnSuccessResponse($existingVote, $existingVote->hashkey, 'Vote updated successfully');
|
|
}
|
|
} else {
|
|
$newVote = new CooperativeVote([
|
|
'hashkey' => Str::random(64),
|
|
'resolution_id' => $resolution->id,
|
|
'user_id' => Auth::id(),
|
|
'vote_cast' => $vote,
|
|
'created_by' => Auth::id(),
|
|
'is_active' => true,
|
|
]);
|
|
if ($newVote->save()) {
|
|
return ResponseHelper::returnSuccessResponse($newVote, $newVote->hashkey, 'Vote cast successfully');
|
|
}
|
|
}
|
|
|
|
return ResponseHelper::returnError('Failed to record vote');
|
|
}
|
|
|
|
public function updateResolutionStatus(Request $request)
|
|
{
|
|
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ManageOrganizations)) {
|
|
return ResponseHelper::returnUnauthorized();
|
|
}
|
|
|
|
$resolutionHash = $request->input('resolution_hash');
|
|
$status = $request->input('status'); // APPROVED, RESCINDED
|
|
|
|
if (!$resolutionHash || !in_array($status, ['APPROVED', 'RESCINDED', 'PROPOSED'])) {
|
|
return ResponseHelper::returnIncorrectDetails();
|
|
}
|
|
|
|
$resolution = CooperativeResolution::where('hashkey', $resolutionHash)->first();
|
|
if (!$resolution) {
|
|
return ResponseHelper::returnError('Resolution not found', 404);
|
|
}
|
|
|
|
$resolution->status = $status;
|
|
$resolution->updated_by = Auth::id();
|
|
if ($status === 'APPROVED') {
|
|
$resolution->date_approved = now();
|
|
}
|
|
|
|
if ($resolution->save()) {
|
|
return ResponseHelper::returnSuccessResponse($resolution, $resolution->hashkey, 'Resolution status updated');
|
|
}
|
|
|
|
return ResponseHelper::returnError('Failed to update resolution status');
|
|
}
|
|
}
|