File: D:/HostingSpaces/SBogers10/komma.pro/app/KommaApp/Shop/Orders/Kms/OrderService.php
<?php
namespace App\KommaApp\Shop\Orders\Kms;
use App\Helpers\KommaHelpers;
use App\KommaApp\Forms\Models\Request;
use App\KommaApp\Kms\Core\AbstractTranslatableModel;
use App\KommaApp\Kms\Core\Attributes\Attribute;
use App\KommaApp\Kms\Core\HasImagesInterface;
use App\KommaApp\Kms\Core\Kms;
use App\KommaApp\Kms\Core\KmsInterface;
use App\KommaApp\Kms\Core\NestedSets\Nodes\EloquentNode;
use App\KommaApp\Kms\Core\Sections\AbstractSectionTabItem;
use App\KommaApp\Kms\Core\Sections\SectionService;
use App\KommaApp\Kms\Core\Sections\SectionTabItem;
use App\KommaApp\Kms\SidebarListItem;
use App\KommaApp\Languages\Models\Language;
use App\KommaApp\Shop\Categories\Kms\CategorizableInterface;
use App\KommaApp\Shop\Orders\Models\Order;
use App\KommaApp\Shop\Orders\Product\OrderedProduct;
use App\KommaApp\Shop\Orders\ProductComposite\OrderedProductComposite;
use App\KommaApp\Shop\Orders\ProductGroup\OrderedProductGroup;
use App\KommaApp\Users\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class OrderService extends SectionService implements OrderServiceInterface
{
protected $sortable = false;
/** @var Kms $kms */
protected $kms;
function __construct()
{
$this->forModelName = Order::class;
$this->kms = \App::make(KmsInterface::class);
parent::__construct();
}
/**
* Fills attributes with data from a model in this way:
*
* 1. First it looks if it needs to get the value from a translationModel.
* If so, gets it, fills the attribute and fills the next attribute if any
* 2. Then it looks if it needs to get the value from it's model.
* If so, gets it, fills the attribute and fills the next attribute if any
* 4. Then it looks if it needs to get the value from the images associated with it.
* If so, gets it, fills the attribute and fills the next attribute if any
* Please notice that if cases 1, 2 and 3 where true the value you may have set with setValue is overwritten.
*
* @param Collection $sectionTabItems A collection containing implementations AbstractSectionTabItem's
* @param Model $model
* @return Collection
*/
public function fillAttributesWithData(Collection $sectionTabItems, Model $model)
{
//Validate that each Collection item is an instance of AbstractSectionTabItem
$sectionTabItems->every(function ($item, $key) {
if (!is_a($item, AbstractSectionTabItem::class)) {
throw new \InvalidArgumentException("The attributes passed must be a Collection of AbstractSectionTabItem instances but was not");
}
});
$sectionTabItems->each(
function ($sectionTabItem, $key) use ($model) {
/** @var $sectionTabItem SectionTabItem */
/** @var Order $model */
if (!is_a($sectionTabItem->getAttribute(), Attribute::class)) {
throw new \InvalidArgumentException("One of the attributes in a AbstractSectionTabItem instance is not but must be an child instance of Attribute.");
}
$valueReference = $sectionTabItem->getAttribute()->getsValueFromReference();
if($valueReference == 'invoice_data')
{
$value = '<a href="'.route('users.show', ['user' => $model->id]).'">'.implode(' ', [$model->invoice_first_name, $model->invoice_last_name]).'</a><br>';
$value .= implode(' ', [$model->invoice_street, $model->invoice_house_number]).'<br>';
$value .= implode(' ', [$model->invoice_postal_code, $model->invoice_city]).'<br>';
$sectionTabItem->getAttribute()->setValue($value);
}
else if($valueReference == 'shipping_data')
{
$value = implode(' ', [$model->shipping_first_name, $model->shipping_last_name]).'<br>';
$value .= implode(' ', [$model->shipping_street, $model->shipping_house_number]).'<br>';
$value .= implode(' ', [$model->shipping_postal_code, $model->shipping_city]).'<br>';
$sectionTabItem->getAttribute()->setValue($value);
}
}
);
$filledAttributes = parent::fillAttributesWithData($sectionTabItems, $model);
return $filledAttributes;
}
/**
* Returns the order ids as a comma separated string for the CategorizableInterface implementation
*
* @param CategorizableInterface $model
* @return string Order ids, comma separated
*/
public function getOrderIdsForModel(CategorizableInterface $model): ?string
{
if(!$model->id) return null;
$idsCollection = $model->orders()->get(['order_id'])->map(function(Order $order ) {
return $order->order_id;
});
$idString = implode(',', $idsCollection->toArray());
if($idString == "") return null;
return $idString;
}
/**
* Returns all models for the sidebar menu in the backend
*
* @return array
*/
public function getModelsForSideBar():array
{
if(isset($this->orderBy)){
if($this->orderReverse) $models = $this->forModelName::orderBy($this->orderBy, 'desc');
else $models = $this->forModelName::orderBy($this->orderBy);
}
else $models = $this->forModelName::orderBy('id');
// If Site isset then we add it to the query, so
$site = $this->kms->getSite();
if($site && $siteId = $this->kms->getSite()->id) {
$models = $models->where('site_id', $siteId);
}
//If have an order status we also add that to the query
$status = \Request::route()->parameter('status');
if($status) $models->where('status', $status);
// Get the models
$models = $models->get();
// Preload translation to prevent individual queries
if(is_a(new $this->forModelName, AbstractTranslatableModel::class)){
$models = $models->load('translation');
}
// Preload images to prevent individual queries
if(is_a(new $this->forModelName, HasImagesInterface::class)){
$models = $models->load('images');
}
$sidebarList = [];
foreach ($models as $model) {
$sidebarListItem = new SidebarListItem();
$this->setThumbnail($model);
$this->generateThumbnail($model);
//Set the values for the sidebar
$sidebarListItem->setId($model->id);
$sidebarListItem->setStatus($model->active);
$title = KommaHelpers::str_limit_full_word($model->title, 75);
$sidebarListItem->setName($title);
$sidebarListItem->setThumbnail($model->thumbnail);
$sidebarList[] = $sidebarListItem;
}
return $sidebarList;
}
/**
* @param Order $order
* @param User $customer
* @return Order
*/
public function fillOrderWithCustomerInfo(Order $order, User $customer): Order
{
$order->invoice_first_name = $customer->first_name;
$order->invoice_last_name = $customer->last_name;
$order->invoice_email = $customer->email;
$order->invoice_company = $customer->company_name;
$order->invoice_country = $customer->country;
$order->invoice_postal_code = $customer->postal_code;
$order->invoice_city = $customer->city;
$order->invoice_street = $customer->street;
$order->invoice_house_number = $customer->house_number;
$order->invoice_telephone = $customer->telephone;
$order->shipping_first_name = $customer->first_name;
$order->shipping_last_name = $customer->last_name;
$order->shipping_email = $customer->email;
$order->shipping_company = $customer->company_name;
$order->shipping_country = $customer->country;
$order->shipping_postal_code = $customer->postal_code;
$order->shipping_city = $customer->city;
$order->shipping_street = $customer->street;
$order->shipping_house_number = $customer->house_number;
$order->shipping_telephone = $customer->telephone;
return $order;
}
/**
* Calculates the total order price and updates the orders total price.
* Then returns the order. Notice that this method does not save the order.
*
* The total price is in cents
*
* @param Order $order
* @return Order
*/
public function calculateTotalOrderPrice(Order $order): Order
{
$order->load(['orderedProducts', 'orderedProductGroups.orderedProducts', 'orderedProductComposites.orderedProductGroups.orderedProducts']);
$productsPrice = $order->orderedProducts->map(function(OrderedProduct $orderedProduct) { return $orderedProduct->price; })->sum();
$productGroupsPrice = $order->orderedProductGroups->map(function(OrderedProductGroup $orderedProductGroup) { return $orderedProductGroup->price; })->sum();
$productCompositesPrice = $order->orderedProductComposites->map(function(OrderedProductComposite $orderedProductComposite) { return $orderedProductComposite->price; })->sum();
//Prices are with discounts taken into account. So we can simply sum them and we are good to go
$order->total_price = $productsPrice + $productGroupsPrice + $productCompositesPrice;
return $order;
}
}