Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record method for distributing merchandise #4733

Merged
merged 2 commits into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions app/Http/Controllers/MerchandiseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace App\Http\Controllers;

use App\Http\Requests\DistributeMerchandiseRequest;
use App\Http\Resources\DuesTransactionMerchandise as DuesTransactionMerchandiseResource;
use App\Http\Resources\Merchandise as MerchandiseResource;
use App\Http\Resources\User as UserResource;
Expand All @@ -15,7 +16,6 @@
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

class MerchandiseController extends Controller
Expand Down Expand Up @@ -69,7 +69,7 @@ public function getDistribution(Merchandise $merchandise, User $user): JsonRespo
'status' => 'error',
'message' => self::NO_DTM,
],
status: 400
status: 404
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was getting a stack trace back on stage for a random non-existent GTID. From this it looks like that case should have been returning a JSON error though

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be coming from the route model binding here:

Route::bind('gtid', static fn (string $value): User => User::whereGtid($value)->firstOrFail());

The controller method is either invoked with a fully-hydrated User model or doesn't get invoked at all.

);
}

Expand All @@ -84,8 +84,11 @@ public function getDistribution(Merchandise $merchandise, User $user): JsonRespo
);
}

public function distribute(Request $request, Merchandise $merchandise, User $user): JsonResponse
{
public function distribute(
DistributeMerchandiseRequest $request,
Merchandise $merchandise,
User $user
): JsonResponse {
if (! $merchandise->distributable) {
return response()->json(
data: [
Expand All @@ -104,7 +107,7 @@ public function distribute(Request $request, Merchandise $merchandise, User $use
'status' => 'error',
'message' => self::NO_DTM,
],
status: 400
status: 404
);
}

Expand All @@ -114,12 +117,13 @@ public function distribute(Request $request, Merchandise $merchandise, User $use
'status' => 'error',
'message' => self::ALREADY_DISTRIBUTED,
],
status: 400
status: 409
);
}

$dtm->provided_at = Carbon::now();
$dtm->provided_by = $request->user()->id;
$dtm->provided_via = $request->provided_via;
$dtm->save();

return response()->json(
Expand All @@ -141,6 +145,7 @@ private static function getDuesTransactionMerchandise(
'dues_transaction_merchandise.id',
'dues_transaction_merchandise.provided_at',
'dues_transaction_merchandise.provided_by',
'dues_transaction_merchandise.provided_via',
'dues_transaction_merchandise.merchandise_id'
)
->whereHas('transaction', static function (Builder $query) use ($user) {
Expand Down
33 changes: 33 additions & 0 deletions app/Http/Requests/DistributeMerchandiseRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class DistributeMerchandiseRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): true
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, array<string>>
*/
public function rules(): array
{
return [
'provided_via' => [
'required',
'string',
],
];
}
}
1 change: 1 addition & 0 deletions app/Http/Resources/DuesTransactionMerchandise.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function toArray(Request $request): array
'id' => $this->id,
'provided_at' => $this->provided_at,
'provided_by' => Manager::make($this->providedBy),
'provided_via' => $this->provided_via,
'merchandise' => $this->when($this->withMerchandise, $this->merchandise),
];
}
Expand Down
1 change: 1 addition & 0 deletions app/Models/DuesTransactionMerchandise.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* @property int $merchandise_id
* @property \Illuminate\Support\Carbon|null $provided_at
* @property int|null $provided_by
* @property ?string $provided_via
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \App\Models\User|null $providedBy
Expand Down
2 changes: 2 additions & 0 deletions app/Nova/Actions/DistributeMerchandise.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ static function (JoinClause $join) use ($provided_to): void {

$dtm->provided_at = Carbon::now();
$dtm->provided_by = $provided_by->id;
$dtm->provided_via = 'Nova';
$dtm->save();

return Action::message('Marked as picked up!');
Expand Down Expand Up @@ -136,6 +137,7 @@ static function (Builder $query) use ($resource): void {
->toArray()
)
->required()
->searchable()
->rules('required'),
];
}
Expand Down
8 changes: 7 additions & 1 deletion app/Nova/MerchandisePivotFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\DateTime;
use Laravel\Nova\Fields\Text;

class MerchandisePivotFields
{
Expand All @@ -16,10 +17,15 @@ public function __invoke(): array
{
return [
DateTime::make('Provided At')
->onlyOnIndex(),
->onlyOnIndex()
->sortable(),

BelongsTo::make('Provided By', 'providedBy', User::class)
->onlyOnIndex(),

Text::make('Provided Via')
->onlyOnIndex()
->sortable(),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

use App\Models\DuesTransactionMerchandise;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('dues_transaction_merchandise', static function (Blueprint $table): void {
$table->string('provided_via')->after('provided_by')->nullable();
});

DuesTransactionMerchandise::whereNotNull('provided_at')
->whereNull('provided_by')
->whereNull('provided_via')
->update(['provided_via' => 'Historical dues import']);

DuesTransactionMerchandise::whereNotNull('provided_at')
->whereNotNull('provided_by')
->whereColumn('provided_at', '=', 'updated_at')
->whereNull('provided_via')
->update(['provided_via' => 'Nova']);

DuesTransactionMerchandise::whereNotNull('provided_at')
->whereNotNull('provided_by')
->whereColumn('provided_at', '!=', 'updated_at')
->whereNull('provided_via')
->update(['provided_via' => 'Legacy web admin']);
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('dues_transaction_merchandise', static function (Blueprint $table): void {
$table->dropColumn('provided_via');
});
}
};
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ parameters:
- stubs/Permission.php
- stubs/Role.php
ignoreErrors:
- '#(?:Dynamic call to static method|Call to an undefined method) Illuminate\\Database\\Eloquent\\(?:Builder|Collection|Relations\\[a-zA-Z]+)?(?:<mixed>|<App\\Models\\[a-zA-Z,\\]+>|<Illuminate\\Database\\Eloquent\\Model>)?::(?:distinct|doesntHave|first|groupBy|has|havingRaw|join|leftJoin|orderBy|orderByRaw|orWhereNull|select|selectRaw|selectSub|where|whereBetween|whereHas|whereDate|whereNotIn|whereNotNull|count|whereIn|whereBetween|sum|distinct|paid|active|accessActive|inactive|role|pending|pendingSwag|accessInactive|visible|whereNull|current|start|end|availableForPurchase|userCanPurchase|pluck|orderByDesc|withTrashed|exists|limit|doesntExist|storeExcel|buzzCardAccessEligible|from|unpaid|whereRevoked|whereNotExists|orWhereDate)\(\)\.#'
- '#(?:Dynamic call to static method|Call to an undefined method) Illuminate\\Database\\Eloquent\\(?:Builder|Collection|Relations\\[a-zA-Z]+)?(?:<mixed>|<App\\Models\\[a-zA-Z,\\]+>|<Illuminate\\Database\\Eloquent\\Model>)?::(?:distinct|doesntHave|first|groupBy|has|havingRaw|join|leftJoin|orderBy|orderByRaw|orWhereNull|select|selectRaw|selectSub|where|whereBetween|whereHas|whereDate|whereNotIn|whereNotNull|count|whereIn|whereBetween|sum|distinct|paid|active|accessActive|inactive|role|pending|pendingSwag|accessInactive|visible|whereNull|current|start|end|availableForPurchase|userCanPurchase|pluck|orderByDesc|withTrashed|exists|limit|doesntExist|storeExcel|buzzCardAccessEligible|from|unpaid|whereRevoked|whereNotExists|orWhereDate|whereColumn)\(\)\.#'
- '#^Parameter \#1 \$attendance of static method App\\Models\\Attendance\:\:formatAsCsv\(\) expects iterable\<App\\Models\\Attendance\>, Illuminate\\Support\\Collection\<\(int\|string\), mixed\> given\.$#'
- '#^Parameter \#1 \$callback of method Illuminate\\Support\\Collection\<\(int\|string\),mixed\>\:\:mapWithKeys\(\) expects callable\(mixed, int\|string\)\: array, Closure\(object\)\: non\-empty\-array given\.$#'
- '#^Parameter \#1 \$callback of method Illuminate\\Support\\Collection\<\(int\|string\),mixed\>\:\:mapWithKeys\(\) expects callable\(mixed, int\|string\)\: array\<string, mixed\>, Closure\(object\)\: non\-empty\-array\<string, mixed\> given\.$#'
Expand Down
Loading