Added: Profit / Loss Report

This commit is contained in:
Fahim 2021-09-09 18:41:37 +06:00
parent fe75cc546d
commit a5b28237ba
12 changed files with 441 additions and 6 deletions

View File

@ -28,6 +28,10 @@ class Purchase extends Model
});
}
public function scopeCompleted($query) {
return $query->where('status', 'Completed');
}
public function getShippingAmountAttribute($value) {
return $value / 100;
}

View File

@ -28,6 +28,10 @@ class PurchaseReturn extends Model
});
}
public function scopeCompleted($query) {
return $query->where('status', 'Completed');
}
public function getShippingAmountAttribute($value) {
return $value / 100;
}

View File

@ -2,7 +2,6 @@
namespace Modules\Reports\Http\Controllers;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Gate;
@ -10,6 +9,12 @@ use Illuminate\Support\Facades\Gate;
class ReportsController extends Controller
{
public function profitLossReport() {
abort_if(Gate::denies('access_profit_loss_report'), 403);
return view('reports::profit-loss.index');
}
public function paymentsReport() {
abort_if(Gate::denies('access_payments_report'), 403);

View File

@ -0,0 +1,16 @@
@extends('layouts.app')
@section('title', 'Profit / Loss Report')
@section('breadcrumb')
<ol class="breadcrumb border-0 m-0">
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
<li class="breadcrumb-item active">Profit Loss Report</li>
</ol>
@endsection
@section('content')
<div class="container-fluid">
<livewire:reports.profit-loss-report/>
</div>
@endsection

View File

@ -12,6 +12,9 @@
*/
Route::group(['middleware' => 'auth'], function () {
//Profit Loss Report
Route::get('/profit-loss-report', 'ReportsController@profitLossReport')
->name('profit-loss-report.index');
//Payments Report
Route::get('/payments-report', 'ReportsController@paymentsReport')
->name('payments-report.index');

View File

@ -28,6 +28,10 @@ class Sale extends Model
});
}
public function scopeCompleted($query) {
return $query->where('status', 'Completed');
}
public function getShippingAmountAttribute($value) {
return $value / 100;
}

View File

@ -28,6 +28,10 @@ class SaleReturn extends Model
});
}
public function scopeCompleted($query) {
return $query->where('status', 'Completed');
}
public function getShippingAmountAttribute($value) {
return $value / 100;
}

View File

@ -20,12 +20,12 @@ class HomeController extends Controller
{
public function index() {
$sales = Sale::where('status', 'Completed')->sum('total_amount');
$sale_returns = SaleReturn::where('status', 'Completed')->sum('total_amount');
$purchase_returns = PurchaseReturn::where('status', 'Completed')->sum('total_amount');
$sales = Sale::completed()->sum('total_amount');
$sale_returns = SaleReturn::completed()->sum('total_amount');
$purchase_returns = PurchaseReturn::completed()->sum('total_amount');
$product_costs = 0;
foreach (Sale::where('status', 'Completed')->with('saleDetails')->get() as $sale) {
foreach (Sale::completed()->with('saleDetails')->get() as $sale) {
foreach ($sale->saleDetails as $saleDetail) {
$product_costs += $saleDetail->product->product_cost;
}

View File

@ -42,6 +42,12 @@ class PaymentsReport extends Component
return view('livewire.reports.payments-report', [
'information' => $this->query ? $this->query->orderBy('date', 'desc')
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->when($this->payment_method, function ($query) {
return $query->where('payment_method', $this->payment_method);
})

View File

@ -0,0 +1,214 @@
<?php
namespace App\Http\Livewire\Reports;
use Livewire\Component;
use Modules\Expense\Entities\Expense;
use Modules\Purchase\Entities\Purchase;
use Modules\Purchase\Entities\PurchasePayment;
use Modules\PurchasesReturn\Entities\PurchaseReturn;
use Modules\PurchasesReturn\Entities\PurchaseReturnPayment;
use Modules\Sale\Entities\Sale;
use Modules\Sale\Entities\SalePayment;
use Modules\SalesReturn\Entities\SaleReturn;
use Modules\SalesReturn\Entities\SaleReturnPayment;
class ProfitLossReport extends Component
{
public $start_date;
public $end_date;
public $total_sales, $sales_amount;
public $total_purchases, $purchases_amount;
public $total_sale_returns, $sale_returns_amount;
public $total_purchase_returns, $purchase_returns_amount;
public $expenses_amount;
public $profit_amount;
public $payments_received_amount;
public $payments_sent_amount;
public $payments_net_amount;
protected $rules = [
'start_date' => 'required|date|before:end_date',
'end_date' => 'required|date|after:start_date'
];
public function mount() {
$this->start_date = '';
$this->end_date = '';
$this->total_sales = 0;
$this->sales_amount = 0;
$this->total_sale_returns = 0;
$this->sale_returns_amount = 0;
$this->total_purchases = 0;
$this->purchases_amount = 0;
$this->total_purchase_returns = 0;
$this->purchase_returns_amount = 0;
$this->payments_received_amount = 0;
$this->payments_sent_amount = 0;
$this->payments_net_amount = 0;
}
public function render() {
$this->setValues();
return view('livewire.reports.profit-loss-report');
}
public function generateReport() {
$this->validate();
}
public function setValues() {
$this->total_sales = Sale::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->count();
$this->sales_amount = Sale::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('total_amount') / 100;
$this->total_purchases = Purchase::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->count();
$this->purchases_amount = Purchase::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('total_amount') / 100;
$this->total_sale_returns = SaleReturn::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->count();
$this->sale_returns_amount = SaleReturn::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('total_amount') / 100;
$this->total_purchase_returns = PurchaseReturn::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->count();
$this->purchase_returns_amount = PurchaseReturn::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('total_amount') / 100;
$this->expenses_amount = Expense::when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('amount') / 100;
$this->profit_amount = $this->calculateProfit();
$this->payments_received_amount = $this->calculatePaymentsReceived();
$this->payments_sent_amount = $this->calculatePaymentsSent();
$this->payments_net_amount = $this->payments_received_amount - $this->payments_sent_amount;
}
public function calculateProfit() {
$product_costs = 0;
$revenue = $this->sales_amount - $this->sale_returns_amount;
$sales = Sale::completed()
->when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->with('saleDetails')->get();
foreach ($sales as $sale) {
foreach ($sale->saleDetails as $saleDetail) {
$product_costs += $saleDetail->product->product_cost;
}
}
$profit = $revenue - $product_costs;
return $profit;
}
public function calculatePaymentsReceived() {
$sale_payments = SalePayment::when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('amount') / 100;
$purchase_return_payments = PurchaseReturnPayment::when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('amount') / 100;
return $sale_payments + $purchase_return_payments;
}
public function calculatePaymentsSent() {
$purchase_payments = PurchasePayment::when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('amount') / 100;
$sale_return_payments = SaleReturnPayment::when($this->start_date, function ($query) {
return $query->whereDate('date', '>=', $this->start_date);
})
->when($this->end_date, function ($query) {
return $query->whereDate('date', '<=', $this->end_date);
})
->sum('amount') / 100;
return $purchase_payments + $sale_return_payments + $this->expenses_amount;
}
}

View File

@ -233,12 +233,19 @@
</li>
@endcan
@can('access_sales_report|access_purchases_report|access_sales_return_report|access_purchases_return_report|access_payments_reports')
@can('access_sales_report|access_purchases_report|access_sales_return_report|access_purchases_return_report|access_payments_reports|access_profit_loss_report')
<li class="c-sidebar-nav-item c-sidebar-nav-dropdown {{ request()->routeIs('*-report.index') ? 'c-show' : '' }}">
<a class="c-sidebar-nav-link c-sidebar-nav-dropdown-toggle" href="#">
<i class="c-sidebar-nav-icon bi bi-graph-up" style="line-height: 1;"></i> Reports
</a>
<ul class="c-sidebar-nav-dropdown-items">
@can('access_profit_loss_report')
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link {{ request()->routeIs('profit-loss-report.index') ? 'c-active' : '' }}" href="{{ route('profit-loss-report.index') }}">
<i class="c-sidebar-nav-icon bi bi-clipboard-data" style="line-height: 1;"></i> Profit / Loss Report
</a>
</li>
@endcan
@can('access_payments_report')
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link {{ request()->routeIs('payments-report.index') ? 'c-active' : '' }}" href="{{ route('payments-report.index') }}">

View File

@ -0,0 +1,168 @@
<div>
<div class="row">
<div class="col-12">
<div class="card border-0 shadow-sm">
<div class="card-body">
<form wire:submit.prevent="generateReport">
<div class="form-row">
<div class="col-lg-6">
<div class="form-group">
<label>Start Date <span class="text-danger">*</span></label>
<input wire:model.defer="start_date" type="date" class="form-control" name="start_date">
@error('start_date')
<span class="text-danger mt-1">{{ $message }}</span>
@enderror
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>End Date <span class="text-danger">*</span></label>
<input wire:model.defer="end_date" type="date" class="form-control" name="end_date">
@error('end_date')
<span class="text-danger mt-1">{{ $message }}</span>
@enderror
</div>
</div>
</div>
<div class="form-group mb-0">
<button type="submit" class="btn btn-primary">
<span wire:target="generateReport" wire:loading class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
<i wire:target="generateReport" wire:loading.remove class="bi bi-shuffle"></i>
Filter Report
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
{{-- Sales --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-receipt font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($sales_amount) }}</div>
<div class="text-uppercase font-weight-bold small ">{{ $total_sales }} Sales</div>
</div>
</div>
</div>
</div>
{{-- Sale Returns --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-arrow-return-left font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($sale_returns_amount) }}</div>
<div class="text-uppercase font-weight-bold small">{{ $total_sale_returns }} Sale Returns</div>
</div>
</div>
</div>
</div>
{{-- Profit --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-trophy font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($profit_amount) }}</div>
<div class="text-uppercase font-weight-bold small">Profit</div>
</div>
</div>
</div>
</div>
{{-- Purchases --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-bag font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($purchases_amount) }}</div>
<div class="text-uppercase font-weight-bold small">{{ $total_purchases }} Purchases</div>
</div>
</div>
</div>
</div>
{{-- Purchase Returns --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-arrow-return-right font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($purchase_returns_amount) }}</div>
<div class="text-uppercase font-weight-bold small">{{ $total_purchase_returns }} Purchase Returns</div>
</div>
</div>
</div>
</div>
{{-- Expenses --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-wallet2 font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($expenses_amount) }}</div>
<div class="text-uppercase font-weight-bold small">Expenses</div>
</div>
</div>
</div>
</div>
{{-- Payments Received --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-cash-stack font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($payments_received_amount) }}</div>
<div class="text-uppercase font-weight-bold small">Payments Received</div>
</div>
</div>
</div>
</div>
{{-- Payments Sent --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-cash-stack font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($payments_sent_amount) }}</div>
<div class="text-uppercase font-weight-bold small">Payments Sent</div>
</div>
</div>
</div>
</div>
{{-- Payments Net --}}
<div class="col-12 col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="bg-primary p-3 mfe-3 rounded">
<i class="bi bi-cash-stack font-2xl"></i>
</div>
<div>
<div class="text-value text-primary">{{ format_currency($payments_net_amount) }}</div>
<div class="text-uppercase font-weight-bold small">Payments Net</div>
</div>
</div>
</div>
</div>
</div>
</div>