diff --git a/app/Abstracts/Listeners/Report.php b/app/Abstracts/Listeners/Report.php index 2a4ebe127..f50f0acfc 100644 --- a/app/Abstracts/Listeners/Report.php +++ b/app/Abstracts/Listeners/Report.php @@ -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) { $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) { $input = request('search', ''); diff --git a/app/Abstracts/Report.php b/app/Abstracts/Report.php index d540d4395..65a6e2375 100644 --- a/app/Abstracts/Report.php +++ b/app/Abstracts/Report.php @@ -588,7 +588,6 @@ abstract class Report $url .= $parameters; } - return $url; } @@ -607,6 +606,11 @@ abstract class Report return $this->getSearchStringValue('period', $this->getSetting('period')); } + public function getDiscount() + { + return $this->getSearchStringValue('discount'); + } + public function getFields() { return [ diff --git a/app/Listeners/Report/AddCustomers.php b/app/Listeners/Report/AddCustomers.php index 9239ca3b8..9d39f0f09 100644 --- a/app/Listeners/Report/AddCustomers.php +++ b/app/Listeners/Report/AddCustomers.php @@ -13,6 +13,7 @@ class AddCustomers extends Listener protected $classes = [ 'App\Reports\IncomeSummary', 'App\Reports\IncomeExpenseSummary', + 'App\Reports\DiscountSummary', ]; /** diff --git a/app/Listeners/Report/AddDate.php b/app/Listeners/Report/AddDate.php index f7b595eb7..46c7d329e 100644 --- a/app/Listeners/Report/AddDate.php +++ b/app/Listeners/Report/AddDate.php @@ -14,6 +14,7 @@ class AddDate extends Listener 'App\Reports\IncomeExpenseSummary', 'App\Reports\ProfitLoss', 'App\Reports\TaxSummary', + 'App\Reports\DiscountSummary', ]; /** diff --git a/app/Listeners/Report/AddDiscount.php b/app/Listeners/Report/AddDiscount.php new file mode 100644 index 000000000..87c96ddf0 --- /dev/null +++ b/app/Listeners/Report/AddDiscount.php @@ -0,0 +1,52 @@ +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); + } +} diff --git a/app/Listeners/Report/AddIncomeExpenseCategories.php b/app/Listeners/Report/AddIncomeExpenseCategories.php index aa225daea..3f9a681d5 100644 --- a/app/Listeners/Report/AddIncomeExpenseCategories.php +++ b/app/Listeners/Report/AddIncomeExpenseCategories.php @@ -20,6 +20,7 @@ class AddIncomeExpenseCategories extends Listener { $classes = [ 'App\Reports\IncomeExpenseSummary', + 'App\Reports\DiscountSummary', ]; if (empty($event->class) || !in_array(get_class($event->class), $classes)) { @@ -42,6 +43,7 @@ class AddIncomeExpenseCategories extends Listener $classes = [ 'App\Reports\IncomeExpenseSummary', 'App\Reports\ProfitLoss', + 'App\Reports\DiscountSummary', ]; if (empty($event->class) || !in_array(get_class($event->class), $classes)) { diff --git a/app/Listeners/Report/AddPeriod.php b/app/Listeners/Report/AddPeriod.php index 3bcf3ef12..cf8d0be3c 100644 --- a/app/Listeners/Report/AddPeriod.php +++ b/app/Listeners/Report/AddPeriod.php @@ -13,6 +13,7 @@ class AddPeriod extends Listener 'App\Reports\IncomeExpenseSummary', 'App\Reports\ProfitLoss', 'App\Reports\TaxSummary', + 'App\Reports\DiscountSummary', ]; /** diff --git a/app/Listeners/Report/AddSearchString.php b/app/Listeners/Report/AddSearchString.php index 0620f5376..bbf352a00 100644 --- a/app/Listeners/Report/AddSearchString.php +++ b/app/Listeners/Report/AddSearchString.php @@ -13,6 +13,7 @@ class AddSearchString extends Listener 'App\Reports\IncomeExpenseSummary', 'App\Reports\ProfitLoss', 'App\Reports\TaxSummary', + 'App\Reports\DiscountSummary', ]; /** diff --git a/app/Listeners/Report/AddVendors.php b/app/Listeners/Report/AddVendors.php index 7993ca648..b2651b9d5 100644 --- a/app/Listeners/Report/AddVendors.php +++ b/app/Listeners/Report/AddVendors.php @@ -13,6 +13,7 @@ class AddVendors extends Listener protected $classes = [ 'App\Reports\ExpenseSummary', 'App\Reports\IncomeExpenseSummary', + 'App\Reports\DiscountSummary', ]; /** diff --git a/app/Providers/Event.php b/app/Providers/Event.php index 32e320bdf..121e60378 100644 --- a/app/Providers/Event.php +++ b/app/Providers/Event.php @@ -149,5 +149,6 @@ class Event extends Provider 'App\Listeners\Report\AddBasis', 'App\Listeners\Report\AddPeriod', 'App\Listeners\Report\AddDate', + 'App\Listeners\Report\AddDiscount', ]; } diff --git a/app/Reports/DiscountSummary.php b/app/Reports/DiscountSummary.php new file mode 100644 index 000000000..04d027f91 --- /dev/null +++ b/app/Reports/DiscountSummary.php @@ -0,0 +1,125 @@ + [ + '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(), + ]; + } +} diff --git a/app/Utilities/Reports.php b/app/Utilities/Reports.php index 58a2698c0..353065125 100644 --- a/app/Utilities/Reports.php +++ b/app/Utilities/Reports.php @@ -22,6 +22,7 @@ class Reports 'App\Reports\IncomeExpenseSummary', 'App\Reports\TaxSummary', 'App\Reports\ProfitLoss', + 'App\Reports\DiscountSummary', ]; Module::enabled()->each(function ($module) use (&$list) { diff --git a/database/seeds/Permissions.php b/database/seeds/Permissions.php index ccfbd7a71..5b3c1f1bd 100644 --- a/database/seeds/Permissions.php +++ b/database/seeds/Permissions.php @@ -59,6 +59,7 @@ class Permissions extends Seeder 'reports-income-expense-summary' => 'r', 'reports-profit-loss' => 'r', 'reports-tax-summary' => 'r', + 'reports-discount-summary' => 'r', 'settings-categories' => 'c,r,u,d', 'settings-company' => 'r,u', 'settings-currencies' => 'c,r,u,d', @@ -105,6 +106,7 @@ class Permissions extends Seeder 'reports-income-expense-summary' => 'r', 'reports-profit-loss' => 'r', 'reports-tax-summary' => 'r', + 'reports-discount-summary' => 'r', 'settings-categories' => 'c,r,u,d', 'settings-company' => 'r,u', 'settings-currencies' => 'c,r,u,d', @@ -151,6 +153,7 @@ class Permissions extends Seeder 'reports-income-expense-summary' => 'r', 'reports-profit-loss' => 'r', 'reports-tax-summary' => 'r', + 'reports-discount-summary' => 'r', 'modules-home' => 'r', 'modules-item' => 'r', 'modules-my' => 'r', diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index bfe5c85a2..3d97d5cc8 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -77,6 +77,7 @@ return [ 'contact_persons' => 'Contact Person|Contact Persons', 'bank_feeds' => 'Bank Feed|Bank Feeds', 'receipts' => 'Receipt|Receipts', + 'discounts' => 'Discount|Discounts', 'ofx' => 'OFX', 'mt940' => 'MT940', diff --git a/resources/lang/en-GB/reports.php b/resources/lang/en-GB/reports.php index 171d5ee11..87a1d51a7 100644 --- a/resources/lang/en-GB/reports.php +++ b/resources/lang/en-GB/reports.php @@ -10,6 +10,7 @@ return [ 'expense_summary' => 'Expense Summary', 'income_expense_summary' => 'Income vs Expense', 'tax_summary' => 'Tax Summary', + 'discount_summary' => 'Discount Summary', 'gross_profit' => 'Gross Profit', 'net_profit' => 'Net Profit', 'total_expenses' => 'Total Expenses',