added discount summary report

This commit is contained in:
Cihan Şentürk 2025-05-14 16:21:59 +03:00 committed by GitHub
parent 56ac86ad3c
commit 8dc32979ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 227 additions and 1 deletions

View File

@ -158,11 +158,42 @@ abstract class Report
]; ];
} }
public function getDiscount()
{
return [
'item' => trans('settings.localisation.discount_location.item'),
'total' => trans('settings.localisation.discount_location.total'),
'both' => trans('settings.localisation.discount_location.both'),
];
}
public function applyDateFilter($event) public function applyDateFilter($event)
{ {
$event->model->dateFilter($event->args['date_field']); $event->model->dateFilter($event->args['date_field']);
} }
public function applyDiscountFilter($event)
{
$input = request('search', '');
$discount = $this->getSearchStringValue('discount', 'both', $input);
switch ($discount) {
case 'item':
$discount_types = ['item_discount'];
break;
case 'total':
$discount_types = ['discount'];
break;
default:
$discount_types = ['item_discount', 'discount'];
break;
}
$event->model->whereHas('totals', function ($query) use ($discount_types) {
$query->whereIn('code', $discount_types);
});
}
public function applySearchStringFilter($event) public function applySearchStringFilter($event)
{ {
$input = request('search', ''); $input = request('search', '');

View File

@ -588,7 +588,6 @@ abstract class Report
$url .= $parameters; $url .= $parameters;
} }
return $url; return $url;
} }
@ -607,6 +606,11 @@ abstract class Report
return $this->getSearchStringValue('period', $this->getSetting('period')); return $this->getSearchStringValue('period', $this->getSetting('period'));
} }
public function getDiscount()
{
return $this->getSearchStringValue('discount');
}
public function getFields() public function getFields()
{ {
return [ return [

View File

@ -13,6 +13,7 @@ class AddCustomers extends Listener
protected $classes = [ protected $classes = [
'App\Reports\IncomeSummary', 'App\Reports\IncomeSummary',
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\DiscountSummary',
]; ];
/** /**

View File

@ -14,6 +14,7 @@ class AddDate extends Listener
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\ProfitLoss', 'App\Reports\ProfitLoss',
'App\Reports\TaxSummary', 'App\Reports\TaxSummary',
'App\Reports\DiscountSummary',
]; ];
/** /**

View File

@ -0,0 +1,52 @@
<?php
namespace App\Listeners\Report;
use App\Abstracts\Listeners\Report as Listener;
use App\Events\Report\FilterApplying;
use App\Events\Report\FilterShowing;
class AddDiscount extends Listener
{
protected $classes = [
'App\Reports\DiscountSummary',
];
/**
* Handle filter showing event.
*
* @param $event
* @return void
*/
public function handleFilterShowing(FilterShowing $event)
{
if ($this->skipThisClass($event)) {
return;
}
$event->class->filters['discounts'] = $this->getDiscount();
$event->class->filters['keys']['discounts'] = 'discount';
$event->class->filters['defaults']['discounts'] = 'both';
$event->class->filters['operators']['discounts'] = [
'equal' => true,
'not_equal' => false,
'range' => false,
];
}
/**
* Handle filter applying event.
*
* @param $event
* @return void
*/
public function handleFilterApplying(FilterApplying $event)
{
if ($this->skipThisClass($event)) {
return;
}
// Apply discount filter
$this->applyDiscountFilter($event);
}
}

View File

@ -20,6 +20,7 @@ class AddIncomeExpenseCategories extends Listener
{ {
$classes = [ $classes = [
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\DiscountSummary',
]; ];
if (empty($event->class) || !in_array(get_class($event->class), $classes)) { if (empty($event->class) || !in_array(get_class($event->class), $classes)) {
@ -42,6 +43,7 @@ class AddIncomeExpenseCategories extends Listener
$classes = [ $classes = [
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\ProfitLoss', 'App\Reports\ProfitLoss',
'App\Reports\DiscountSummary',
]; ];
if (empty($event->class) || !in_array(get_class($event->class), $classes)) { if (empty($event->class) || !in_array(get_class($event->class), $classes)) {

View File

@ -13,6 +13,7 @@ class AddPeriod extends Listener
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\ProfitLoss', 'App\Reports\ProfitLoss',
'App\Reports\TaxSummary', 'App\Reports\TaxSummary',
'App\Reports\DiscountSummary',
]; ];
/** /**

View File

@ -13,6 +13,7 @@ class AddSearchString extends Listener
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\ProfitLoss', 'App\Reports\ProfitLoss',
'App\Reports\TaxSummary', 'App\Reports\TaxSummary',
'App\Reports\DiscountSummary',
]; ];
/** /**

View File

@ -13,6 +13,7 @@ class AddVendors extends Listener
protected $classes = [ protected $classes = [
'App\Reports\ExpenseSummary', 'App\Reports\ExpenseSummary',
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\DiscountSummary',
]; ];
/** /**

View File

@ -149,5 +149,6 @@ class Event extends Provider
'App\Listeners\Report\AddBasis', 'App\Listeners\Report\AddBasis',
'App\Listeners\Report\AddPeriod', 'App\Listeners\Report\AddPeriod',
'App\Listeners\Report\AddDate', 'App\Listeners\Report\AddDate',
'App\Listeners\Report\AddDiscount',
]; ];
} }

View File

@ -0,0 +1,125 @@
<?php
namespace App\Reports;
use App\Abstracts\Report;
use App\Models\Document\Document;
use App\Utilities\Recurring;
use App\Utilities\Date;
use App\Traits\Currencies;
use App\Events\Report\TotalCalculating;
use App\Events\Report\TotalCalculated;
class DiscountSummary extends Report
{
use Currencies;
public $default_name = 'reports.discount_summary';
public $icon = 'sell';
public $type = 'summary';
public $chart = [
'income' => [
'bar' => [
'colors' => [
'#8bb475',
],
],
'donut' => [
//
],
],
'expense' => [
'bar' => [
'colors' => [
'#fb7185',
],
],
'donut' => [
//
],
],
];
public function setTables()
{
$this->tables = [
'income' => trans_choice('general.incomes', 1),
'expense' => trans_choice('general.expenses', 2),
];
}
public function setData()
{
$invoices = $this->applyFilters(Document::invoice()->with('totals')->accrued(), ['date_field' => 'issued_at'])->get();
Recurring::reflect($invoices, 'issued_at');
$this->setTotals($invoices, 'issued_at', false, 'income');
// Bills
$bills = $this->applyFilters(Document::bill()->with('totals')->accrued(), ['date_field' => 'issued_at'])->get();
Recurring::reflect($bills, 'issued_at');
$this->setTotals($bills, 'issued_at', false, 'expense');
}
public function setTotals($items, $date_field, $check_type = false, $table = 'default', $with_tax = true)
{
event(new TotalCalculating($this, $items, $date_field, $check_type, $table, $with_tax));
$group_field = $this->getSetting('group') . '_id';
foreach ($items as $item) {
// Make groups extensible
$item = $this->applyGroups($item);
$date = $this->getFormattedDate(Date::parse($item->$date_field));
if (!isset($item->$group_field)) {
continue;
}
$group = $item->$group_field;
$totals = $item->totals;
foreach ($totals as $total) {
if (! in_array($total->code, ['item_discount', 'discount'])) {
continue;
}
if (
!isset($this->row_values[$table][$group])
|| !isset($this->row_values[$table][$group][$date])
|| !isset($this->footer_totals[$table][$date])
) {
continue;
}
$amount = $this->convertToDefault($total->amount, $item->currency_code, $item->currency_rate);
$type = ($item->type === Document::INVOICE_TYPE || $item->type === 'income') ? 'income' : 'expense';
if (($check_type == false) || ($type == 'income')) {
$this->row_values[$table][$group][$date] += $amount;
$this->footer_totals[$table][$date] += $amount;
} else {
$this->row_values[$table][$group][$date] -= $amount;
$this->footer_totals[$table][$date] -= $amount;
}
}
}
event(new TotalCalculated($this, $items, $date_field, $check_type, $table, $with_tax));
}
public function getFields()
{
return [
$this->getGroupField(),
$this->getPeriodField(),
];
}
}

View File

@ -22,6 +22,7 @@ class Reports
'App\Reports\IncomeExpenseSummary', 'App\Reports\IncomeExpenseSummary',
'App\Reports\TaxSummary', 'App\Reports\TaxSummary',
'App\Reports\ProfitLoss', 'App\Reports\ProfitLoss',
'App\Reports\DiscountSummary',
]; ];
Module::enabled()->each(function ($module) use (&$list) { Module::enabled()->each(function ($module) use (&$list) {

View File

@ -59,6 +59,7 @@ class Permissions extends Seeder
'reports-income-expense-summary' => 'r', 'reports-income-expense-summary' => 'r',
'reports-profit-loss' => 'r', 'reports-profit-loss' => 'r',
'reports-tax-summary' => 'r', 'reports-tax-summary' => 'r',
'reports-discount-summary' => 'r',
'settings-categories' => 'c,r,u,d', 'settings-categories' => 'c,r,u,d',
'settings-company' => 'r,u', 'settings-company' => 'r,u',
'settings-currencies' => 'c,r,u,d', 'settings-currencies' => 'c,r,u,d',
@ -105,6 +106,7 @@ class Permissions extends Seeder
'reports-income-expense-summary' => 'r', 'reports-income-expense-summary' => 'r',
'reports-profit-loss' => 'r', 'reports-profit-loss' => 'r',
'reports-tax-summary' => 'r', 'reports-tax-summary' => 'r',
'reports-discount-summary' => 'r',
'settings-categories' => 'c,r,u,d', 'settings-categories' => 'c,r,u,d',
'settings-company' => 'r,u', 'settings-company' => 'r,u',
'settings-currencies' => 'c,r,u,d', 'settings-currencies' => 'c,r,u,d',
@ -151,6 +153,7 @@ class Permissions extends Seeder
'reports-income-expense-summary' => 'r', 'reports-income-expense-summary' => 'r',
'reports-profit-loss' => 'r', 'reports-profit-loss' => 'r',
'reports-tax-summary' => 'r', 'reports-tax-summary' => 'r',
'reports-discount-summary' => 'r',
'modules-home' => 'r', 'modules-home' => 'r',
'modules-item' => 'r', 'modules-item' => 'r',
'modules-my' => 'r', 'modules-my' => 'r',

View File

@ -77,6 +77,7 @@ return [
'contact_persons' => 'Contact Person|Contact Persons', 'contact_persons' => 'Contact Person|Contact Persons',
'bank_feeds' => 'Bank Feed|Bank Feeds', 'bank_feeds' => 'Bank Feed|Bank Feeds',
'receipts' => 'Receipt|Receipts', 'receipts' => 'Receipt|Receipts',
'discounts' => 'Discount|Discounts',
'ofx' => 'OFX', 'ofx' => 'OFX',
'mt940' => 'MT940', 'mt940' => 'MT940',

View File

@ -10,6 +10,7 @@ return [
'expense_summary' => 'Expense Summary', 'expense_summary' => 'Expense Summary',
'income_expense_summary' => 'Income vs Expense', 'income_expense_summary' => 'Income vs Expense',
'tax_summary' => 'Tax Summary', 'tax_summary' => 'Tax Summary',
'discount_summary' => 'Discount Summary',
'gross_profit' => 'Gross Profit', 'gross_profit' => 'Gross Profit',
'net_profit' => 'Net Profit', 'net_profit' => 'Net Profit',
'total_expenses' => 'Total Expenses', 'total_expenses' => 'Total Expenses',