Skip to content

Commit

Permalink
- Payment endpoint can now accept client details (which will be saved…
Browse files Browse the repository at this point in the history
… in Order model); (#46)

- Added more tests and fixed some bugs
  • Loading branch information
pa-cholek authored Mar 9, 2022
1 parent 4694aff commit f29c903
Show file tree
Hide file tree
Showing 17 changed files with 327 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddClientInformationToOrderTable extends Migration
{
public function up(): void
{
Schema::table('orders', function (Blueprint $table) {
$table->string('client_name')->nullable();
$table->string('client_street')->nullable();
$table->string('client_postal')->nullable();
$table->string('client_city')->nullable();
$table->string('client_country')->nullable();
$table->string('client_company')->nullable();
$table->string('client_taxid')->nullable();
});
}

public function down(): void
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn([
'client_name',
'client_street',
'client_postal',
'client_city',
'client_country',
'client_company',
'client_taxid',
]);
});
}
}
67 changes: 67 additions & 0 deletions src/Dtos/ClientDetailsDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace EscolaLms\Cart\Dtos;

class ClientDetailsDto
{
protected ?string $name = null;
protected ?string $street = null;
protected ?string $city = null;
protected ?string $postal = null;
protected ?string $country = null;
protected ?string $company = null;
protected ?string $taxid = null;

public function __construct(
?string $name = null,
?string $street = null,
?string $city = null,
?string $postal = null,
?string $country = null,
?string $company = null,
?string $taxid = null
) {
$this->name = $name;
$this->street = $street;
$this->city = $city;
$this->postal = $postal;
$this->country = $country;
$this->company = $company;
$this->taxid = $taxid;
}

public function getName(): ?string
{
return $this->name;
}

public function getStreet(): ?string
{
return $this->street;
}

public function getCity(): ?string
{
return $this->city;
}

public function getPostal(): ?string
{
return $this->postal;
}

public function getCountry(): ?string
{
return $this->country;
}

public function getCompany(): ?string
{
return $this->company;
}

public function getTaxid(): ?string
{
return $this->taxid;
}
}
2 changes: 1 addition & 1 deletion src/Events/ProductRemovedFromCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

namespace EscolaLms\Cart\Events;

class ProductRemovedFromCart extends AbstractProductEvent
class ProductRemovedFromCart extends AbstractProductCartEvent
{
}
9 changes: 2 additions & 7 deletions src/Http/Controllers/Admin/ProductableAdminApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@

namespace EscolaLms\Cart\Http\Controllers\Admin;

use EscolaLms\Cart\Events\ProductAttached;
use EscolaLms\Cart\Events\ProductDetached;
use EscolaLms\Cart\Http\Requests\Admin\ProductableAttachRequest;
use EscolaLms\Cart\Http\Requests\Admin\ProductableDetachRequest;
use EscolaLms\Cart\Http\Requests\ProductAttachRequest;
use EscolaLms\Cart\Http\Requests\ProductDetachRequest;
use EscolaLms\Cart\Http\Swagger\Admin\ProductableAdminSwagger;
use EscolaLms\Cart\Http\Swagger\Admin\ProductAdminSwagger;
use EscolaLms\Cart\Services\Contracts\ProductServiceContract;
use EscolaLms\Cart\Services\Contracts\ShopServiceContract;
use EscolaLms\Core\Http\Controllers\EscolaLmsBaseController;
Expand All @@ -28,15 +23,15 @@ public function __construct(ProductServiceContract $productService, ShopServiceC

public function attach(ProductableAttachRequest $request): JsonResponse
{
$productable = $this->productService->findProductable($request->getProductType(), $request->getProductId());
$productable = $this->productService->findProductable($request->getProductableType(), $request->getProductableId());
$user = $request->getUser();
$this->productService->attachProductableToUser($productable, $user);
return $this->sendSuccess(__('Productable attached to user'));
}

public function detach(ProductableDetachRequest $request): JsonResponse
{
$productable = $this->productService->findProductable($request->getProductType(), $request->getProductId());
$productable = $this->productService->findProductable($request->getProductableType(), $request->getProductableId());
$user = $request->getUser();
$this->productService->detachProductableFromUser($productable, $user);
return $this->sendSuccess(__('Productable detached from user'));
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Controllers/CartApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function pay(PaymentRequest $request): JsonResponse
try {
$cart = $this->shopService->cartForUser($request->user());
$paymentMethodDto = PaymentMethodDto::instantiateFromRequest($request);
$this->shopService->purchaseCart($cart, $paymentMethodDto);
$this->shopService->purchaseCart($cart, $request->toClientDetailsDto(), $paymentMethodDto);

return $this->sendSuccess(__("Payment successful"));
} catch (\Exception $e) {
Expand Down
26 changes: 24 additions & 2 deletions src/Http/Requests/PaymentRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace EscolaLms\Cart\Http\Requests;

use EscolaLms\Cart\Dtos\ClientDetailsDto;
use EscolaLms\Cart\Enums\CartPermissionsEnum;
use Illuminate\Foundation\Http\FormRequest;

class PaymentRequest extends FormRequest
Expand All @@ -13,7 +15,7 @@ class PaymentRequest extends FormRequest
*/
public function authorize()
{
return true;
return $this->user()->can(CartPermissionsEnum::BUY_PRODUCTS);
}

/**
Expand All @@ -24,7 +26,27 @@ public function authorize()
public function rules()
{
return [
'paymentMethodId' => ['required', 'nullable']
'paymentMethodId' => ['required', 'nullable'],
'client_name' => ['sometimes', 'string'],
'client_street' => ['sometimes', 'string'],
'client_postal' => ['sometimes', 'string'],
'client_city' => ['sometimes', 'string'],
'client_country' => ['sometimes', 'string'],
'client_company' => ['sometimes', 'string'],
'client_taxid' => ['sometimes', 'string', 'required_with:client_company'],
];
}

public function toClientDetailsDto(): ClientDetailsDto
{
return new ClientDetailsDto(
$this->input('client_name'),
$this->input('client_street'),
$this->input('client_city'),
$this->input('client_postal'),
$this->input('client_country'),
$this->input('client_company'),
$this->input('client_taxid')
);
}
}
7 changes: 7 additions & 0 deletions src/Http/Resources/OrderResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public function toArray($request)
'tax' => $this->tax,
'created_at' => $this->created_at,
'user_id' => $this->user_id,
'client_name' => $this->client_name,
'client_street' => $this->client_street,
'client_postal' => $this->client_postal,
'client_city' => $this->client_city,
'client_country' => $this->client_country,
'client_company' => $this->client_company,
'client_taxid' => $this->client_taxid,
];
}
}
16 changes: 15 additions & 1 deletion src/Models/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
* @property int $tax
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $client_name
* @property string|null $client_street
* @property string|null $client_postal
* @property string|null $client_city
* @property string|null $client_country
* @property string|null $client_company
* @property string|null $client_taxid
* @property-read int $quantity
* @property-read string $status_name
* @property-read \EscolaLms\Cart\Support\OrderItemCollection|\EscolaLms\Cart\Models\OrderItem[] $items
Expand All @@ -50,10 +57,17 @@
* @method static OrderModelQueryBuilder|Order newModelQuery()
* @method static OrderModelQueryBuilder|Order newQuery()
* @method static OrderModelQueryBuilder|Order query()
* @method static OrderModelQueryBuilder|Order whereClientCity($value)
* @method static OrderModelQueryBuilder|Order whereClientCompany($value)
* @method static OrderModelQueryBuilder|Order whereClientCountry($value)
* @method static OrderModelQueryBuilder|Order whereClientName($value)
* @method static OrderModelQueryBuilder|Order whereClientPostal($value)
* @method static OrderModelQueryBuilder|Order whereClientStreet($value)
* @method static OrderModelQueryBuilder|Order whereClientTaxid($value)
* @method static OrderModelQueryBuilder|Order whereCreatedAt($value)
* @method static OrderModelQueryBuilder|Order whereHasBuyable(string $buyable_type, int $buyable_id)
* @method static OrderModelQueryBuilder|Order whereHasProduct(int $product_id)
* @method static OrderModelQueryBuilder|Order whereHasProductable(Model $productable)
* @method static OrderModelQueryBuilder|Order whereHasProductable(\Illuminate\Database\Eloquent\Model $productable)
* @method static OrderModelQueryBuilder|Order whereHasProductableClass(string $productable_type)
* @method static OrderModelQueryBuilder|Order whereHasProductableClassAndId(string $productable_type, int $productable_id)
* @method static OrderModelQueryBuilder|Order whereId($value)
Expand Down
2 changes: 1 addition & 1 deletion src/Models/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
* @method static ProductModelQueryBuilder|Product whereDoesntHaveProductablesNotOwnedByUser(?\EscolaLms\Core\Models\User $user = null)
* @method static ProductModelQueryBuilder|Product whereDuration($value)
* @method static ProductModelQueryBuilder|Product whereExtraFees($value)
* @method static ProductModelQueryBuilder|Product whereHasProductable(Model $productable)
* @method static ProductModelQueryBuilder|Product whereHasProductable(\Illuminate\Database\Eloquent\Model $productable)
* @method static ProductModelQueryBuilder|Product whereHasProductableClass(string $productable_type)
* @method static ProductModelQueryBuilder|Product whereHasProductableClassAndId(string $productable_type, int $productable_id)
* @method static ProductModelQueryBuilder|Product whereHasProductablesBuyableByUser(?\EscolaLms\Core\Models\User $user = null)
Expand Down
3 changes: 2 additions & 1 deletion src/Services/Contracts/OrderServiceContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace EscolaLms\Cart\Services\Contracts;

use EscolaLms\Cart\Dtos\ClientDetailsDto;
use EscolaLms\Cart\Dtos\OrdersSearchDto;
use EscolaLms\Cart\Models\Cart;
use EscolaLms\Cart\Models\Order;
Expand All @@ -15,7 +16,7 @@ public function searchAndPaginateOrders(OrdersSearchDto $searchDto, ?OrderDto $s

public function find(int $id): Model;

public function createOrderFromCart(Cart $cart): Order;
public function createOrderFromCart(Cart $cart, ?ClientDetailsDto $clientDetailsDto = null): Order;

public function setPaid(Order $order): void;
public function setCancelled(Order $order): void;
Expand Down
3 changes: 2 additions & 1 deletion src/Services/Contracts/ShopServiceContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace EscolaLms\Cart\Services\Contracts;

use EscolaLms\Cart\Dtos\ClientDetailsDto;
use EscolaLms\Cart\Models\Cart;
use EscolaLms\Cart\Models\Product;
use EscolaLms\Cart\Services\CartManager;
Expand All @@ -23,5 +24,5 @@ public function updateProductQuantity(Cart $cart, Product $buyable, int $quantit
public function removeProductFromCart(Cart $cart, Product $buyable): void;
public function removeItemFromCart(Cart $cart, int $cartItemId): void;

public function purchaseCart(Cart $cart, PaymentMethodContract $paymentMethod = null): void;
public function purchaseCart(Cart $cart, ?ClientDetailsDto $clientDeails = null, ?PaymentMethodContract $paymentMethod = null): void;
}
12 changes: 11 additions & 1 deletion src/Services/OrderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace EscolaLms\Cart\Services;

use EscolaLms\Cart\Dtos\ClientDetailsDto;
use EscolaLms\Cart\Dtos\OrdersSearchDto;
use EscolaLms\Cart\Enums\OrderStatus;
use EscolaLms\Cart\Events\OrderCancelled;
Expand Down Expand Up @@ -76,8 +77,10 @@ public function find($id): Model
return Order::findOrFail($id);
}

public function createOrderFromCart(Cart $cart): Order
public function createOrderFromCart(Cart $cart, ?ClientDetailsDto $clientDetailsDto = null): Order
{
$optionalClientDetailsDto = optional($clientDetailsDto);

/** @var User $user */
$user = User::find($cart->user_id);

Expand All @@ -90,6 +93,13 @@ public function createOrderFromCart(Cart $cart): Order
$order->subtotal = $cartManager->total();
$order->tax = $cartManager->taxInt();
$order->status = OrderStatus::PROCESSING;
$order->client_name = $optionalClientDetailsDto->getName() ?? $order->user->name;
$order->client_street = $optionalClientDetailsDto->getStreet();
$order->client_postal = $optionalClientDetailsDto->getPostal();
$order->client_city = $optionalClientDetailsDto->getCity();
$order->client_country = $optionalClientDetailsDto->getCountry();
$order->client_company = $optionalClientDetailsDto->getCompany();
$order->client_taxid = $optionalClientDetailsDto->getTaxid();
$order->save();

foreach ($cart->items as $item) {
Expand Down
15 changes: 12 additions & 3 deletions src/Services/ShopService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace EscolaLms\Cart\Services;

use EscolaLms\Cart\Dtos\ClientDetailsDto;
use EscolaLms\Cart\Events\ProductAddedToCart;
use EscolaLms\Cart\Events\ProductRemovedFromCart;
use EscolaLms\Cart\Http\Resources\CartResource;
use EscolaLms\Cart\Models\Cart;
use EscolaLms\Cart\Models\CartItem;
use EscolaLms\Cart\Models\Product;
use EscolaLms\Cart\Services\CartManager;
use EscolaLms\Cart\Services\Contracts\OrderServiceContract;
Expand Down Expand Up @@ -38,9 +41,9 @@ public function cartManagerForCart(Cart $cart): CartManager
return new CartManager($cart);
}

public function purchaseCart(Cart $cart, PaymentMethodContract $paymentMethod = null): void
public function purchaseCart(Cart $cart, ?ClientDetailsDto $clientDetailsDto = null, ?PaymentMethodContract $paymentMethod = null): void
{
$order = $this->orderService->createOrderFromCart($cart);
$order = $this->orderService->createOrderFromCart($cart, $clientDetailsDto);

$paymentProcessor = $order->process();
$paymentProcessor->purchase($paymentMethod);
Expand All @@ -67,13 +70,19 @@ public function removeProductFromCart(Cart $cart, Product $product): void
$item = $cartManager->findProduct($product);
if ($item) {
$cartManager->remove($item->getKey());
event(new ProductRemovedFromCart($product, $cart));
}
}

public function removeItemFromCart(Cart $cart, int $cartItemId): void
{
$cartManager = $this->cartManagerForCart($cart);
$cartManager->remove($cartItemId);
$cartItem = CartItem::find($cartItemId);
if ($cartItem) {
$product = $cartItem->buyable;
$cartManager->remove($cartItemId);
event(new ProductRemovedFromCart($product, $cart));
}
}

public function addUniqueProductToCart(Cart $cart, Product $product): void
Expand Down
1 change: 1 addition & 0 deletions src/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
Route::get('/orders', [OrderAdminApiController::class, 'index']);
Route::get('/orders/{id}', [OrderAdminApiController::class, 'read']);

Route::get('/products', [ProductAdminApiController::class, 'index']);
Route::post('/products', [ProductAdminApiController::class, 'create']);
Route::get('/products/{id}', [ProductAdminApiController::class, 'read'])->whereNumber('id');
Route::put('/products/{id}', [ProductAdminApiController::class, 'update'])->whereNumber('id');
Expand Down
Loading

0 comments on commit f29c903

Please sign in to comment.