Merge pull request #5080 from devansh-webkul/total-unpaid-invoices

Displayed total unpaid invoices on the dashboard #5001
This commit is contained in:
Glenn Hermans 2021-08-17 01:18:32 +02:00 committed by GitHub
commit eba4ddf417
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 166 additions and 113 deletions

View File

@ -2,12 +2,13 @@
namespace Webkul\Admin\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Webkul\Sales\Repositories\OrderRepository;
use Webkul\Sales\Repositories\OrderItemRepository;
use Illuminate\Support\Facades\DB;
use Webkul\Customer\Repositories\CustomerRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Sales\Repositories\InvoiceRepository;
use Webkul\Sales\Repositories\OrderItemRepository;
use Webkul\Sales\Repositories\OrderRepository;
class DashboardController extends Controller
{
@ -19,56 +20,63 @@ class DashboardController extends Controller
protected $_config;
/**
* OrderRepository object
* Order repository instance.
*
* @var \Webkul\Sales\Repositories\OrderRepository
*/
protected $orderRepository;
/**
* OrderItemRepository object
* Order item repository instance.
*
* @var \Webkul\Sales\Repositories\OrderItemRepository
*/
protected $orderItemRepository;
/**
* CustomerRepository object
* Invoice repository instance.
*
* @var \Webkul\Sales\Repositories\InvoiceRepository
*/
protected $invoiceRepository;
/**
* Customer repository instance.
*
* @var \Webkul\Customer\Repositories\CustomerRepository
*/
protected $customerRepository;
/**
* ProductInventoryRepository object
* Product inventory repository instance.
*
* @var \Webkul\Product\Repositories\ProductInventoryRepository
*/
protected $productInventoryRepository;
/**
* string object
* Start date.
*
* @var \Illuminate\Support\Carbon
*/
protected $startDate;
/**
* string object
* Last start date.
*
* @var \Illuminate\Support\Carbon
*/
protected $lastStartDate;
/**
* string object
* End date.
*
* @var \Illuminate\Support\Carbon
*/
protected $endDate;
/**
* string object
* Last end date.
*
* @var \Illuminate\Support\Carbon
*/
@ -86,10 +94,10 @@ class DashboardController extends Controller
public function __construct(
OrderRepository $orderRepository,
OrderItemRepository $orderItemRepository,
InvoiceRepository $invoiceRepository,
CustomerRepository $customerRepository,
ProductInventoryRepository $productInventoryRepository
)
{
) {
$this->_config = request('_config');
$this->middleware('admin');
@ -98,27 +106,13 @@ class DashboardController extends Controller
$this->orderItemRepository = $orderItemRepository;
$this->invoiceRepository = $invoiceRepository;
$this->customerRepository = $customerRepository;
$this->productInventoryRepository = $productInventoryRepository;
}
/**
* Returns percentage difference
*
* @param int $previous
* @param int $current
* @return int
*/
public function getPercentageChange($previous, $current)
{
if (! $previous) {
return $current ? 100 : 0;
}
return ($current - $previous) / $previous * 100;
}
/**
* Display a listing of the resource.
*
@ -129,9 +123,12 @@ class DashboardController extends Controller
$this->setStartEndDate();
$statistics = [
/**
* These are the stats with percentage change.
*/
'total_customers' => [
'previous' => $previous = $this->getCustomersBetweenDates($this->lastStartDate, $this->lastEndDate)->count(),
'current' => $current = $this->getCustomersBetweenDates($this->startDate, $this->endDate)->count(),
'previous' => $previous = $this->getCustomersBetweenDates($this->lastStartDate, $this->lastEndDate),
'current' => $current = $this->getCustomersBetweenDates($this->startDate, $this->endDate),
'progress' => $this->getPercentageChange($previous, $current),
],
'total_orders' => [
@ -149,6 +146,11 @@ class DashboardController extends Controller
'current' => $current = $this->currentOrders()->avg('base_grand_total_invoiced') - $this->currentOrders()->avg('base_grand_total_refunded'),
'progress' => $this->getPercentageChange($previous, $current),
],
/**
* These are the normal stats.
*/
'total_unpaid_invoices' => $this->getTotalPendingInvoices(),
'top_selling_categories' => $this->getTopSellingCategories(),
'top_selling_products' => $this->getTopSellingProducts(),
'customer_with_most_sales' => $this->getCustomerWithMostSales(),
@ -168,28 +170,69 @@ class DashboardController extends Controller
}
/**
* Returns the list of top selling categories
* Sets start and end date.
*
* @return void
*/
public function setStartEndDate()
{
$this->startDate = request()->get('start')
? Carbon::createFromTimeString(request()->get('start') . " 00:00:01")
: Carbon::createFromTimeString(Carbon::now()->subDays(30)->format('Y-m-d') . " 00:00:01");
$this->endDate = request()->get('end')
? Carbon::createFromTimeString(request()->get('end') . " 23:59:59")
: Carbon::now();
if ($this->endDate > Carbon::now()) {
$this->endDate = Carbon::now();
}
$this->lastStartDate = clone $this->startDate;
$this->lastEndDate = clone $this->startDate;
$this->lastStartDate->subDays($this->startDate->diffInDays($this->endDate));
}
/**
* Returns percentage difference
*
* @param int $previous
* @param int $current
* @return int
*/
public function getPercentageChange($previous, $current)
{
if (! $previous) {
return $current ? 100 : 0;
}
return ($current - $previous) / $previous * 100;
}
/**
* Returns the list of top selling categories.
*
* @return \Illuminate\Support\Collection
*/
public function getTopSellingCategories()
{
return $this->orderItemRepository->getModel()
->leftJoin('products', 'order_items.product_id', 'products.id')
->leftJoin('product_categories', 'products.id', 'product_categories.product_id')
->leftJoin('categories', 'product_categories.category_id', 'categories.id')
->leftJoin('category_translations', 'categories.id', 'category_translations.category_id')
->where('category_translations.locale', app()->getLocale())
->where('order_items.created_at', '>=', $this->startDate)
->where('order_items.created_at', '<=', $this->endDate)
->addSelect(DB::raw('SUM(qty_invoiced - qty_refunded) as total_qty_invoiced'))
->addSelect(DB::raw('COUNT(' . DB::getTablePrefix() . 'products.id) as total_products'))
->addSelect('order_items.id', 'categories.id as category_id', 'category_translations.name')
->groupBy('categories.id')
->havingRaw('SUM(qty_invoiced - qty_refunded) > 0')
->orderBy('total_qty_invoiced', 'DESC')
->limit(5)
->get();
->leftJoin('products', 'order_items.product_id', 'products.id')
->leftJoin('product_categories', 'products.id', 'product_categories.product_id')
->leftJoin('categories', 'product_categories.category_id', 'categories.id')
->leftJoin('category_translations', 'categories.id', 'category_translations.category_id')
->where('category_translations.locale', app()->getLocale())
->where('order_items.created_at', '>=', $this->startDate)
->where('order_items.created_at', '<=', $this->endDate)
->addSelect(DB::raw('SUM(qty_invoiced - qty_refunded) as total_qty_invoiced'))
->addSelect(DB::raw('COUNT(' . DB::getTablePrefix() . 'products.id) as total_products'))
->addSelect('order_items.id', 'categories.id as category_id', 'category_translations.name')
->groupBy('categories.id')
->havingRaw('SUM(qty_invoiced - qty_refunded) > 0')
->orderBy('total_qty_invoiced', 'DESC')
->limit(5)
->get();
}
/**
@ -200,36 +243,36 @@ class DashboardController extends Controller
public function getStockThreshold()
{
return $this->productInventoryRepository->getModel()
->leftJoin('products', 'product_inventories.product_id', 'products.id')
->select(DB::raw('SUM(qty) as total_qty'))
->addSelect('product_inventories.product_id')
->groupBy('product_id')
->orderBy('total_qty', 'ASC')
->limit(5)
->get();
->leftJoin('products', 'product_inventories.product_id', 'products.id')
->select(DB::raw('SUM(qty) as total_qty'))
->addSelect('product_inventories.product_id')
->groupBy('product_id')
->orderBy('total_qty', 'ASC')
->limit(5)
->get();
}
/**
* Returns top selling products
* Returns top selling products.
*
* @return \Illuminate\Support\Collection
*/
public function getTopSellingProducts()
{
return $this->orderItemRepository->getModel()
->select(DB::raw('SUM(qty_ordered) as total_qty_ordered'))
->addSelect('id', 'product_id', 'product_type', 'name')
->where('order_items.created_at', '>=', $this->startDate)
->where('order_items.created_at', '<=', $this->endDate)
->whereNull('parent_id')
->groupBy('product_id')
->orderBy('total_qty_ordered', 'DESC')
->limit(5)
->get();
->select(DB::raw('SUM(qty_ordered) as total_qty_ordered'))
->addSelect('id', 'product_id', 'product_type', 'name')
->where('order_items.created_at', '>=', $this->startDate)
->where('order_items.created_at', '<=', $this->endDate)
->whereNull('parent_id')
->groupBy('product_id')
->orderBy('total_qty_ordered', 'DESC')
->limit(5)
->get();
}
/**
* Returns top selling products
* Returns cutomer with most sales.
*
* @return \Illuminate\Support\Collection
*/
@ -238,48 +281,22 @@ class DashboardController extends Controller
$dbPrefix = DB::getTablePrefix();
return $this->orderRepository->getModel()
->leftJoin('refunds', 'orders.id', 'refunds.order_id')
->select(DB::raw("(SUM({$dbPrefix}orders.base_grand_total) - SUM(IFNULL({$dbPrefix}refunds.base_grand_total, 0))) as total_base_grand_total"))
->addSelect(DB::raw("COUNT({$dbPrefix}orders.id) as total_orders"))
->addSelect('orders.id', 'customer_id', 'customer_email', 'customer_first_name', 'customer_last_name')
->where('orders.created_at', '>=', $this->startDate)
->where('orders.created_at', '<=', $this->endDate)
->where('orders.status', '<>', 'closed')
->where('orders.status', '<>', 'canceled')
->groupBy('customer_email')
->orderBy('total_base_grand_total', 'DESC')
->limit(5)
->get();
->leftJoin('refunds', 'orders.id', 'refunds.order_id')
->select(DB::raw("(SUM({$dbPrefix}orders.base_grand_total) - SUM(IFNULL({$dbPrefix}refunds.base_grand_total, 0))) as total_base_grand_total"))
->addSelect(DB::raw("COUNT({$dbPrefix}orders.id) as total_orders"))
->addSelect('orders.id', 'customer_id', 'customer_email', 'customer_first_name', 'customer_last_name')
->where('orders.created_at', '>=', $this->startDate)
->where('orders.created_at', '<=', $this->endDate)
->where('orders.status', '<>', 'closed')
->where('orders.status', '<>', 'canceled')
->groupBy('customer_email')
->orderBy('total_base_grand_total', 'DESC')
->limit(5)
->get();
}
/**
* Sets start and end date
*
* @return void
*/
public function setStartEndDate()
{
$this->startDate = request()->get('start')
? Carbon::createFromTimeString(request()->get('start') . " 00:00:01")
: Carbon::createFromTimeString(Carbon::now()->subDays(30)->format('Y-m-d') . " 00:00:01");
$this->endDate = request()->get('end')
? Carbon::createFromTimeString(request()->get('end') . " 23:59:59")
: Carbon::now();
if ($this->endDate > Carbon::now()) {
$this->endDate = Carbon::now();
}
$this->lastStartDate = clone $this->startDate;
$this->lastEndDate = clone $this->startDate;
$this->lastStartDate->subDays($this->startDate->diffInDays($this->endDate));
// $this->lastEndDate->subDays($this->lastStartDate->diffInDays($this->lastEndDate));
}
/**
* Returns previous order query
* Returns previous order query.
*
* @return Illuminate\Database\Query\Builder
*/
@ -289,7 +306,7 @@ class DashboardController extends Controller
}
/**
* Returns current order query
* Returns current order query.
*
* @return Illuminate\Database\Query\Builder
*/
@ -299,7 +316,7 @@ class DashboardController extends Controller
}
/**
* Returns orders between two dates
* Returns orders between two dates.
*
* @param \Illuminate\Support\Carbon $start
* @param \Illuminate\Support\Carbon $end
@ -313,16 +330,31 @@ class DashboardController extends Controller
}
/**
* Returns customers between two dates
* Returns customers between two dates.
*
* @param \Illuminate\Support\Carbon $start
* @param \Illuminate\Support\Carbon $end
* @return Illuminate\Database\Query\Builder
* @return int
*/
private function getCustomersBetweenDates($start, $end)
{
return $this->customerRepository->scopeQuery(function ($query) use ($start, $end) {
return $query->where('customers.created_at', '>=', $start)->where('customers.created_at', '<=', $end);
});
return $this->customerRepository
->where('customers.created_at', '>=', $start)
->where('customers.created_at', '<=', $end)
->count();
}
}
/**
* Returns total pending invoices between two dates.
*
* @param \Illuminate\Support\Carbon $start
* @param \Illuminate\Support\Carbon $end
* @return string
*/
private function getTotalPendingInvoices()
{
return $this->invoiceRepository
->where('state', 'pending')
->sum('grand_total');
}
}

View File

@ -138,6 +138,7 @@ return [
'total-orders' => 'مجموع الطلبات',
'total-sale' => 'مجموع المبيعات',
'average-sale' => 'متوسط مبيعات الطلبات',
'total-unpaid-invoices' => 'إجمالي الفواتير غير المسددة',
'increased' => ':progress% زيادة',
'decreased' => ':progress% نقصان',
'sales' => 'المبيعات',

View File

@ -137,6 +137,7 @@ return [
'total-orders' => 'Anzahl Aufträge',
'total-sale' => 'Gesamterlös',
'average-sale' => 'Durchschnitt pro Verkauf',
'total-unpaid-invoices' => 'Gesamtzahl unbezahlter Rechnungen',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Vertrieb',

View File

@ -144,6 +144,7 @@ return [
'total-orders' => 'Total Orders',
'total-sale' => 'Total Sale',
'average-sale' => 'Average Order Sale',
'total-unpaid-invoices' => 'Total Unpaid Invoices',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Sales',

View File

@ -144,6 +144,7 @@ return [
'total-orders' => 'Total Pedidos',
'total-sale' => 'Total Ventas',
'average-sale' => 'Promedio de pedidos vendidos',
'total-unpaid-invoices' => 'Facturas impagas totales',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Ventas',

View File

@ -138,6 +138,7 @@ return [
'total-orders' => 'همه سفارشات',
'total-sale' => 'مجموع فروش',
'average-sale' => 'میانگین فروش',
'total-unpaid-invoices' => 'مجموع فاکتورهای پرداخت نشده',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'فروش ها',

View File

@ -144,6 +144,7 @@ return [
'total-orders' => 'Total des commandes',
'total-sale' => 'Vente totale',
'average-sale' => 'Vente de commande moyenne',
'total-unpaid-invoices' => 'Total des factures impayées',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Ventes',
@ -166,7 +167,7 @@ return [
'update-success' => 'Sélectionné :resource a été mise à jour avec succès',
'no-resource' => 'La ressource prévue est insuffisante pour l\'action',
],
'id' => 'identifiant',
'status' => 'Statut',
'code' => 'Code',

View File

@ -137,6 +137,7 @@ return [
'total-orders' => 'Totale Ordini',
'total-sale' => 'Totale Vendite',
'average-sale' => 'Media Ordine di Vendita',
'total-unpaid-invoices' => 'Totale fatture non pagate',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Vendite',

View File

@ -137,6 +137,7 @@ return [
'total-orders' => 'Totaal aantal bestellingen',
'total-sale' => 'Verkooptotaal',
'average-sale' => 'Gemiddelde orderwaarde',
'total-unpaid-invoices' => 'Totaal onbetaalde facturen',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Verkopen',

View File

@ -136,6 +136,7 @@ return [
'total-orders' => 'Zamówienia ogółem',
'total-sale' => 'Całkowita sprzedaż',
'average-sale' => 'Średnia sprzedaż na zamówienie',
'total-unpaid-invoices' => 'Łącznie nieopłacone faktury',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Sprzedaż',

View File

@ -137,6 +137,7 @@ return [
'total-orders' => 'Total de Pedidos',
'total-sale' => 'Total de Vendas',
'average-sale' => 'Média por Pedido',
'total-unpaid-invoices' => 'Total de faturas não pagas',
'increased' => ':progress% AumentoMai',
'decreased' => ':progress% Redução',
'sales' => 'Vendas',

View File

@ -135,6 +135,7 @@ return [
'total-orders' => 'Tplam Sipariş',
'total-sale' => 'Tplam Satış',
'average-sale' => 'Ortalama Satış',
'total-unpaid-invoices' => 'Toplam Ödenmemiş Faturalar',
'increased' => ':progress%',
'decreased' => ':progress%',
'sales' => 'Satış',

View File

@ -125,6 +125,16 @@
</div>
</div>
<div class="dashboard-card">
<div class="title">
{{ __('admin::app.dashboard.total-unpaid-invoices') }}
</div>
<div class="data">
{{ core()->formatBasePrice($statistics['total_unpaid_invoices']) }}
</div>
</div>
</div>
<div class="graph-stats">