This commit is contained in:
@ -70,7 +70,7 @@ class Bills extends ApiController
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Increase stock (item bought)
|
||||
$item_object->quantity++;
|
||||
$item_object->quantity += $item['quantity'];
|
||||
$item_object->save();
|
||||
} elseif (!empty($item['sku'])) {
|
||||
$item_sku = $item['sku'];
|
||||
@ -89,7 +89,7 @@ class Bills extends ApiController
|
||||
}
|
||||
|
||||
$bill_item['item_id'] = $item_id;
|
||||
$bill_item['name'] = $item['name'];
|
||||
$bill_item['name'] = str_limit($item['name'], 180, '');
|
||||
$bill_item['sku'] = $item_sku;
|
||||
$bill_item['quantity'] = $item['quantity'];
|
||||
$bill_item['price'] = $item['price'];
|
||||
@ -161,7 +161,7 @@ class Bills extends ApiController
|
||||
}
|
||||
|
||||
$bill_item['item_id'] = $item_id;
|
||||
$bill_item['name'] = $item['name'];
|
||||
$bill_item['name'] = str_limit($item['name'], 180, '');
|
||||
$bill_item['sku'] = $item_sku;
|
||||
$bill_item['quantity'] = $item['quantity'];
|
||||
$bill_item['price'] = $item['price'];
|
||||
|
@ -79,7 +79,7 @@ class Invoices extends ApiController
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Decrease stock (item sold)
|
||||
$item_object->quantity--;
|
||||
$item_object->quantity -= $item['quantity'];
|
||||
$item_object->save();
|
||||
|
||||
// Notify users if out of stock
|
||||
@ -109,7 +109,7 @@ class Invoices extends ApiController
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item_id;
|
||||
$invoice_item['name'] = $item['name'];
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = $item['quantity'];
|
||||
$invoice_item['price'] = $item['price'];
|
||||
@ -212,7 +212,7 @@ class Invoices extends ApiController
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item_id;
|
||||
$invoice_item['name'] = $item['name'];
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = $item['quantity'];
|
||||
$invoice_item['price'] = $item['price'];
|
||||
|
@ -243,6 +243,7 @@ class Users extends Controller
|
||||
public function autocomplete(ARequest $request)
|
||||
{
|
||||
$user = false;
|
||||
$data = false;
|
||||
|
||||
$column = $request['column'];
|
||||
$value = $request['value'];
|
||||
@ -250,7 +251,7 @@ class Users extends Controller
|
||||
if (!empty($column) && !empty($value)) {
|
||||
switch ($column) {
|
||||
case 'id':
|
||||
$user = User::find();
|
||||
$user = User::find((int) $value);
|
||||
break;
|
||||
case 'email':
|
||||
$user = User::where('email', $value)->first();
|
||||
@ -258,12 +259,16 @@ class Users extends Controller
|
||||
default:
|
||||
$user = User::where($column, $value)->first();
|
||||
}
|
||||
|
||||
$data = $user;
|
||||
} elseif (!empty($column) && empty($value)) {
|
||||
$data = trans('validation.required', ['attribute' => $column]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'errors' => ($user) ? false: true,
|
||||
'success' => ($user) ? true: false,
|
||||
'data' => $user
|
||||
'errors' => ($user) ? false : true,
|
||||
'success' => ($user) ? true : false,
|
||||
'data' => $data
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,17 @@ namespace App\Http\Controllers\Banking;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Banking\Transaction;
|
||||
use App\Models\Expense\BillPayment;
|
||||
use App\Models\Expense\Payment;
|
||||
use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\Revenue;
|
||||
use App\Models\Setting\Category;
|
||||
|
||||
class Transactions extends Controller
|
||||
{
|
||||
|
||||
public $transactions = [];
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
@ -21,8 +25,6 @@ class Transactions extends Controller
|
||||
{
|
||||
$request = request();
|
||||
|
||||
$transactions = array();
|
||||
|
||||
$accounts = collect(Account::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
|
||||
|
||||
@ -35,62 +37,64 @@ class Transactions extends Controller
|
||||
$type = $request->get('type');
|
||||
|
||||
if ($type != 'income') {
|
||||
$payments = Payment::collect('paid_at');
|
||||
|
||||
foreach ($payments as $payment) {
|
||||
$transactions[] = (object)[
|
||||
'paid_at' => $payment->paid_at,
|
||||
'account_name' => $payment->account->name,
|
||||
'type' => trans_choice('general.expenses', 1),
|
||||
'category_name' => $payment->category->name,
|
||||
'description' => $payment->description,
|
||||
'amount' => $payment->amount,
|
||||
'currency_code' => $payment->currency_code,
|
||||
];
|
||||
}
|
||||
$this->addTransactions(Payment::collect('paid_at'), trans_choice('general.expenses', 1));
|
||||
$this->addTransactions(BillPayment::collect('paid_at'), trans_choice('general.expenses', 1), trans_choice('general.bills', 1));
|
||||
}
|
||||
|
||||
if ($type != 'expense') {
|
||||
$revenues = Revenue::collect('paid_at');
|
||||
|
||||
foreach ($revenues as $revenue) {
|
||||
$transactions[] = (object)[
|
||||
'paid_at' => $revenue->paid_at,
|
||||
'account_name' => $revenue->account->name,
|
||||
'type' => trans_choice('general.incomes', 1),
|
||||
'category_name' => $revenue->category->name,
|
||||
'description' => $revenue->description,
|
||||
'amount' => $revenue->amount,
|
||||
'currency_code' => $revenue->currency_code,
|
||||
];
|
||||
}
|
||||
$this->addTransactions(Revenue::collect('paid_at'), trans_choice('general.incomes', 1));
|
||||
$this->addTransactions(InvoicePayment::collect('paid_at'), trans_choice('general.incomes', 1), trans_choice('general.invoices', 1));
|
||||
}
|
||||
|
||||
$special_key = array(
|
||||
'account.name' => 'account_name',
|
||||
'category.name' => 'category_name',
|
||||
);
|
||||
|
||||
if (isset($request['sort']) && array_key_exists($request['sort'], $special_key)) {
|
||||
$sort_order = array();
|
||||
|
||||
foreach ($transactions as $key => $value) {
|
||||
$sort = $request['sort'];
|
||||
|
||||
if (array_key_exists($request['sort'], $special_key)) {
|
||||
$sort = $special_key[$request['sort']];
|
||||
}
|
||||
|
||||
$sort_order[$key] = $value->{$sort};
|
||||
}
|
||||
|
||||
$sort_type = (isset($request['order']) && $request['order'] == 'asc') ? SORT_ASC : SORT_DESC;
|
||||
|
||||
array_multisort($sort_order, $sort_type, $transactions);
|
||||
}
|
||||
|
||||
$transactions = (object) $transactions;
|
||||
$transactions = $this->getTransactions($request);
|
||||
|
||||
return view('banking.transactions.index', compact('transactions', 'accounts', 'types', 'categories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add items to transactions array.
|
||||
*
|
||||
* @param $items
|
||||
* @param $type
|
||||
* @param $category
|
||||
*/
|
||||
protected function addTransactions($items, $type, $category = null)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
$data = [
|
||||
'paid_at' => $item->paid_at,
|
||||
'account_name' => $item->account->name,
|
||||
'type' => $type,
|
||||
'description' => $item->description,
|
||||
'amount' => $item->amount,
|
||||
'currency_code' => $item->currency_code,
|
||||
];
|
||||
|
||||
if (!is_null($category)) {
|
||||
$data['category_name'] = $category;
|
||||
} else {
|
||||
$data['category_name'] = $item->category->name;
|
||||
}
|
||||
|
||||
$this->transactions[] = (object) $data;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTransactions($request)
|
||||
{
|
||||
// Sort items
|
||||
if (isset($request['sort'])) {
|
||||
if ($request['order'] == 'asc') {
|
||||
$f = 'sortBy';
|
||||
} else {
|
||||
$f = 'sortByDesc';
|
||||
}
|
||||
|
||||
$transactions = collect($this->transactions)->$f($request['sort']);
|
||||
} else {
|
||||
$transactions = collect($this->transactions)->sortByDesc('paid_at');
|
||||
}
|
||||
|
||||
return $transactions;
|
||||
}
|
||||
}
|
||||
|
@ -102,14 +102,10 @@ class Transfers extends Controller
|
||||
|
||||
$request['account_id'] = $request['from_account_id'];
|
||||
$request['paid_at'] = $request['transferred_at'];
|
||||
// amount
|
||||
$request['currency_code'] = $payment_currency_code;
|
||||
$request['currency_rate'] = $currencies[$payment_currency_code];
|
||||
$request['vendor_id'] = '0';
|
||||
// description
|
||||
$request['category_id'] = Category::enabled()->type('other')->pluck('id')->first(); // Transfer Category ID
|
||||
// payment_method
|
||||
// reference
|
||||
$request['category_id'] = Category::transfer(); // Transfer Category ID
|
||||
$request['attachment'] = '';
|
||||
|
||||
$payment = Payment::create($request->all());
|
||||
@ -195,14 +191,10 @@ class Transfers extends Controller
|
||||
|
||||
$request['account_id'] = $request['from_account_id'];
|
||||
$request['paid_at'] = $request['transferred_at'];
|
||||
// amount
|
||||
$request['currency_code'] = $payment_currency_code;
|
||||
$request['currency_rate'] = $currencies[$payment_currency_code];
|
||||
$request['vendor_id'] = '0';
|
||||
// description
|
||||
$request['category_id'] = Category::enabled()->type('other')->pluck('id')->first(); // Transfer Category ID
|
||||
// payment_method
|
||||
// reference
|
||||
$request['category_id'] = Category::transfer(); // Transfer Category ID
|
||||
$request['attachment'] = '';
|
||||
|
||||
$payment->update($request->all());
|
||||
|
@ -2,14 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
use App\Events\CompanySwitched;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Company\Company as Request;
|
||||
use App\Models\Company\Company;
|
||||
use App\Models\Setting\Currency;
|
||||
use App\Traits\Uploads;
|
||||
use Auth;
|
||||
use Redirect;
|
||||
use Setting;
|
||||
|
||||
class Companies extends Controller
|
||||
{
|
||||
@ -51,26 +49,26 @@ class Companies extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
Setting::forgetAll();
|
||||
setting()->forgetAll();
|
||||
|
||||
// Create company
|
||||
$company = Company::create($request->input());
|
||||
|
||||
// Create settings
|
||||
Setting::set('general.company_name', $request->get('company_name'));
|
||||
Setting::set('general.company_email', $request->get('company_email'));
|
||||
Setting::set('general.company_address', $request->get('company_address'));
|
||||
setting()->set('general.company_name', $request->get('company_name'));
|
||||
setting()->set('general.company_email', $request->get('company_email'));
|
||||
setting()->set('general.company_address', $request->get('company_address'));
|
||||
|
||||
$logo_path = $this->getUploadedFilePath($request->file('company_logo'), 'settings', $company->id);
|
||||
if ($logo_path) {
|
||||
Setting::set('general.company_logo', $logo_path);
|
||||
setting()->set('general.company_logo', $logo_path);
|
||||
}
|
||||
|
||||
Setting::set('general.default_currency', $request->get('default_currency'));
|
||||
Setting::set('general.default_locale', session('locale'));
|
||||
setting()->set('general.default_currency', $request->get('default_currency'));
|
||||
setting()->set('general.default_locale', session('locale'));
|
||||
|
||||
Setting::setExtraColumns(['company_id' => $company->id]);
|
||||
Setting::save();
|
||||
setting()->setExtraColumns(['company_id' => $company->id]);
|
||||
setting()->save();
|
||||
|
||||
// Redirect
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.companies', 1)]);
|
||||
@ -90,7 +88,13 @@ class Companies extends Controller
|
||||
public function edit(Company $company)
|
||||
{
|
||||
// Check if user can edit company
|
||||
$this->authorizeUserOrRedirect($company);
|
||||
if (!$this->isUserCompany($company)) {
|
||||
$message = trans('companies.error.not_user_company');
|
||||
|
||||
flash($message)->error();
|
||||
|
||||
return redirect('companies/companies');
|
||||
}
|
||||
|
||||
$company->setSettings();
|
||||
|
||||
@ -110,30 +114,36 @@ class Companies extends Controller
|
||||
public function update(Company $company, Request $request)
|
||||
{
|
||||
// Check if user can update company
|
||||
$this->authorizeUserOrRedirect($company);
|
||||
if (!$this->isUserCompany($company)) {
|
||||
$message = trans('companies.error.not_user_company');
|
||||
|
||||
flash($message)->error();
|
||||
|
||||
return redirect('companies/companies');
|
||||
}
|
||||
|
||||
// Update company
|
||||
$company->update($request->input());
|
||||
|
||||
// Get the company settings
|
||||
Setting::forgetAll();
|
||||
Setting::setExtraColumns(['company_id' => $company->id]);
|
||||
Setting::load(true);
|
||||
setting()->forgetAll();
|
||||
setting()->setExtraColumns(['company_id' => $company->id]);
|
||||
setting()->load(true);
|
||||
|
||||
// Update settings
|
||||
Setting::set('general.company_name', $request->get('company_name'));
|
||||
Setting::set('general.company_email', $request->get('company_email'));
|
||||
Setting::set('general.company_address', $request->get('company_address'));
|
||||
setting()->set('general.company_name', $request->get('company_name'));
|
||||
setting()->set('general.company_email', $request->get('company_email'));
|
||||
setting()->set('general.company_address', $request->get('company_address'));
|
||||
|
||||
$logo_path = $this->getUploadedFilePath($request->file('company_logo'), 'settings', $company->id);
|
||||
if ($logo_path) {
|
||||
Setting::set('general.company_logo', $logo_path);
|
||||
setting()->set('general.company_logo', $logo_path);
|
||||
}
|
||||
|
||||
Setting::set('general.default_payment_method', 'offlinepayment.cash.1');
|
||||
Setting::set('general.default_currency', $request->get('default_currency'));
|
||||
setting()->set('general.default_payment_method', 'offlinepayment.cash.1');
|
||||
setting()->set('general.default_currency', $request->get('default_currency'));
|
||||
|
||||
Setting::save();
|
||||
setting()->save();
|
||||
|
||||
// Redirect
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.companies', 1)]);
|
||||
@ -182,9 +192,10 @@ class Companies extends Controller
|
||||
// Check if user can manage company
|
||||
if ($this->isUserCompany($company)) {
|
||||
session(['company_id' => $company->id]);
|
||||
|
||||
event(new CompanySwitched($company));
|
||||
}
|
||||
|
||||
//return redirect('/');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
@ -197,7 +208,7 @@ class Companies extends Controller
|
||||
*/
|
||||
public function isUserCompany(Company $company)
|
||||
{
|
||||
$companies = Auth::user()->companies()->pluck('id')->toArray();
|
||||
$companies = auth()->user()->companies()->pluck('id')->toArray();
|
||||
|
||||
if (in_array($company->id, $companies)) {
|
||||
return true;
|
||||
@ -205,24 +216,4 @@ class Companies extends Controller
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user company permission and redirect if not
|
||||
*
|
||||
* @param Company $company
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorizeUserOrRedirect(Company $company)
|
||||
{
|
||||
if ($this->isUserCompany($company)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$message = trans('companies.error.not_user_company');
|
||||
|
||||
flash($message)->error();
|
||||
|
||||
Redirect::away(url('companies/companies'))->send();
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
namespace App\Http\Controllers\Customers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use Auth;
|
||||
use App\Models\Income\Invoice;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
class Dashboard extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
@ -16,8 +16,110 @@ class Dashboard extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$user = Auth::user()->customer;
|
||||
$customer = auth()->user()->customer;
|
||||
|
||||
return view('customers.dashboard.index', compact('user'));
|
||||
$invoices = Invoice::with('status')->accrued()->where('customer_id', $customer->id)->get();
|
||||
|
||||
$start = Date::parse(request('start', Date::today()->startOfYear()->format('Y-m-d')));
|
||||
$end = Date::parse(request('end', Date::today()->endOfYear()->format('Y-m-d')));
|
||||
|
||||
$start_month = $start->month;
|
||||
$end_month = $end->month;
|
||||
|
||||
// Monthly
|
||||
$labels = [];
|
||||
|
||||
$s = clone $start;
|
||||
|
||||
for ($j = $end_month; $j >= $start_month; $j--) {
|
||||
$labels[$end_month - $j] = $s->format('M Y');
|
||||
|
||||
$s->addMonth();
|
||||
}
|
||||
|
||||
$unpaid = $paid = $overdue = $partial_paid = [];
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
switch ($invoice->invoice_status_code) {
|
||||
case 'paid':
|
||||
$paid[] = $invoice;
|
||||
break;
|
||||
case 'partial':
|
||||
$partial_paid[] = $invoice;
|
||||
break;
|
||||
case 'sent':
|
||||
default:
|
||||
if (Date::today()->format('Y-m-d') > $invoice->due_at->format('Y-m-d')) {
|
||||
$overdue[] = $invoice;
|
||||
} else {
|
||||
$unpaid[] = $invoice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$total = count($unpaid) + count($paid) + count($partial_paid) + count($overdue);
|
||||
|
||||
$progress = [
|
||||
'unpaid' => count($unpaid),
|
||||
'paid' => count($paid),
|
||||
'overdue' => count($overdue),
|
||||
'partially_paid' => count($partial_paid),
|
||||
'total' => $total,
|
||||
];
|
||||
|
||||
$unpaid = $this->calculateTotals($unpaid, $start, $end, 'unpaid');
|
||||
$paid = $this->calculateTotals($paid, $start, $end, 'paid');
|
||||
$partial_paid = $this->calculateTotals($partial_paid, $start, $end, 'partial');
|
||||
$overdue = $this->calculateTotals($overdue, $start, $end, 'overdue');
|
||||
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
->colors(['#dd4b39', '#6da252', '#f39c12', '#00c0ef'])
|
||||
->dataset(trans('general.unpaid'), $unpaid)
|
||||
->dataset(trans('general.paid'), $paid)
|
||||
->dataset(trans('general.overdue'), $overdue)
|
||||
->dataset(trans('general.partially_paid'), $partial_paid)
|
||||
->labels($labels)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.multi.line');
|
||||
|
||||
return view('customers.dashboard.index', compact('customer', 'invoices', 'progress', 'chart'));
|
||||
}
|
||||
|
||||
private function calculateTotals($items, $start, $end, $type)
|
||||
{
|
||||
$totals = [];
|
||||
|
||||
$date_format = 'Y-m';
|
||||
|
||||
$n = 1;
|
||||
$start_date = $start->format($date_format);
|
||||
$end_date = $end->format($date_format);
|
||||
$next_date = $start_date;
|
||||
|
||||
$s = clone $start;
|
||||
|
||||
while ($next_date <= $end_date) {
|
||||
$totals[$next_date] = 0;
|
||||
|
||||
$next_date = $s->addMonths($n)->format($date_format);
|
||||
}
|
||||
|
||||
$this->setTotals($totals, $items, $date_format, $type);
|
||||
|
||||
return $totals;
|
||||
}
|
||||
|
||||
private function setTotals(&$totals, $items, $date_format, $type)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($type == 'partial') {
|
||||
$item->amount = $item->payments()->paid();
|
||||
}
|
||||
|
||||
$i = Date::parse($item->paid_at)->format($date_format);
|
||||
|
||||
$totals[$i] += $item->getConvertedAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,6 @@ use App\Models\Setting\Currency;
|
||||
use App\Traits\Currencies;
|
||||
use App\Traits\DateTime;
|
||||
use App\Traits\Uploads;
|
||||
use Auth;
|
||||
|
||||
use App\Utilities\Modules;
|
||||
|
||||
class Invoices extends Controller
|
||||
@ -27,19 +25,7 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$invoices = Invoice::with('status')->where('customer_id', '=', Auth::user()->customer->id)->paginate();
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
$paid = 0;
|
||||
|
||||
foreach ($invoice->payments as $item) {
|
||||
$item->default_currency_code = $invoice->currency_code;
|
||||
|
||||
$paid += $item->getDynamicConvertedAmount();
|
||||
}
|
||||
|
||||
$invoice->amount = $invoice->amount - $paid;
|
||||
}
|
||||
$invoices = Invoice::with('status')->accrued()->where('customer_id', auth()->user()->customer->id)->paginate();
|
||||
|
||||
$status = collect(InvoiceStatus::all()->pluck('name', 'code'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.statuses', 2)]), '');
|
||||
@ -94,7 +80,7 @@ class Invoices extends Controller
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param int $invoice_id
|
||||
* @param Invoice $invoice
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
@ -126,7 +112,7 @@ class Invoices extends Controller
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param int $invoice_id
|
||||
* @param Invoice $invoice
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
|
92
app/Http/Controllers/Customers/Profile.php
Normal file
92
app/Http/Controllers/Customers/Profile.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Customers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Customer\Profile as Request;
|
||||
use App\Models\Auth\User;
|
||||
|
||||
class Profile extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
return $this->edit();
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
return $this->edit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
return view('customers.profile.edit', compact('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
// Upload picture
|
||||
$picture = $request->file('picture');
|
||||
if ($picture && $picture->isValid()) {
|
||||
$request['picture'] = $picture->store('users');
|
||||
}
|
||||
|
||||
// Do not reset password if not entered/changed
|
||||
if (empty($request['password'])) {
|
||||
unset($request['password']);
|
||||
unset($request['password_confirmation']);
|
||||
}
|
||||
|
||||
// Update user
|
||||
$user->update($request->input());
|
||||
|
||||
// Update customer
|
||||
$user->customer->update($request->input());
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans('auth.profile')]);
|
||||
|
||||
flash($message)->success();
|
||||
|
||||
return redirect('customers/profile/edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark overdue invoices notifications are read and redirect to invoices page.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function readOverdueInvoices()
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
// Mark invoice notifications as read
|
||||
foreach ($user->unreadNotifications as $notification) {
|
||||
// Not an invoice notification
|
||||
if ($notification->getAttribute('type') != 'App\Notifications\Income\Invoice') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$notification->markAsRead();
|
||||
}
|
||||
|
||||
// Redirect to invoices
|
||||
return redirect('customers/invoices');
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\Revenue;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Traits\Currencies;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
class Dashboard extends Controller
|
||||
@ -20,6 +21,10 @@ class Dashboard extends Controller
|
||||
|
||||
public $today;
|
||||
|
||||
public $income_donut = ['colors' => [], 'labels' => [], 'values' => []];
|
||||
|
||||
public $expense_donut = ['colors' => [], 'labels' => [], 'values' => []];
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
@ -28,174 +33,46 @@ class Dashboard extends Controller
|
||||
public function index()
|
||||
{
|
||||
$this->today = Date::today();
|
||||
$month_days = $this->today->daysInMonth;
|
||||
|
||||
/*
|
||||
* Cash Flow
|
||||
*/
|
||||
list($total_incomes, $total_expenses, $total_profit) = $this->getTotals();
|
||||
|
||||
// Daily
|
||||
$day = array();
|
||||
$cashflow = $this->getCashFlow();
|
||||
|
||||
for ($j = $month_days; $j > -1; $j--) {
|
||||
$day[$month_days - $j] = date("d M", strtotime("-$j day"));
|
||||
}
|
||||
list($donut_incomes, $donut_expenses) = $this->getDonuts();
|
||||
|
||||
$daily_income = $this->getCashFlow('income', 'daily');
|
||||
$daily_expense = $this->getCashFlow('expense', 'daily');
|
||||
$accounts = Account::enabled()->take(6)->get();
|
||||
|
||||
$daily_profit = $this->getProfit($daily_income, $daily_expense);
|
||||
$latest_incomes = $this->getLatestIncomes();
|
||||
|
||||
// Monthly
|
||||
$month = array();
|
||||
$latest_expenses = $this->getLatestExpenses();
|
||||
|
||||
for ($j = 12; $j >= 0; $j--) {
|
||||
$month[12 - $j] = date("F-Y", strtotime(" -$j month"));
|
||||
}
|
||||
return view('dashboard.dashboard.index', compact(
|
||||
'total_incomes',
|
||||
'total_expenses',
|
||||
'total_profit',
|
||||
'cashflow',
|
||||
'donut_incomes',
|
||||
'donut_expenses',
|
||||
'accounts',
|
||||
'latest_incomes',
|
||||
'latest_expenses'
|
||||
));
|
||||
}
|
||||
|
||||
$monthly_income = $this->getCashFlow('income', 'monthly');
|
||||
$monthly_expense = $this->getCashFlow('expense', 'monthly');
|
||||
public function cashFlow()
|
||||
{
|
||||
$this->today = Date::today();
|
||||
|
||||
$monthly_profit = $this->getProfit($monthly_income, $monthly_expense);
|
||||
$content = $this->getCashFlow()->render();
|
||||
|
||||
$cash_flow = [
|
||||
'daily' => [
|
||||
'date' => json_encode($day),
|
||||
'income' => json_encode(array_values($daily_income)),
|
||||
'expense' => json_encode(array_values($daily_expense)),
|
||||
'profit' => json_encode(array_values($daily_profit))
|
||||
],
|
||||
'monthly' => [
|
||||
'date' => json_encode($month),
|
||||
'income' => json_encode(array_values($monthly_income)),
|
||||
'expense' => json_encode(array_values($monthly_expense)),
|
||||
'profit' => json_encode(array_values($monthly_profit))
|
||||
],
|
||||
];
|
||||
//return response()->setContent($content)->send();
|
||||
|
||||
/*
|
||||
* Totals & Pie Charts
|
||||
*/
|
||||
echo $content;
|
||||
}
|
||||
|
||||
$incomes = $expenses = array();
|
||||
|
||||
$incomes_amount = $expenses_amount = 0;
|
||||
|
||||
// Invoices
|
||||
$invoices = Invoice::with('payments')->accrued()->get();
|
||||
list($invoice_paid_amount, $open_invoice, $overdue_invoice) = $this->getTotals($invoices, 'invoice');
|
||||
|
||||
$incomes_amount += $invoice_paid_amount;
|
||||
|
||||
// Bills
|
||||
$bills = Bill::with('payments')->accrued()->get();
|
||||
list($bill_paid_amount, $open_bill, $overdue_bill) = $this->getTotals($bills, 'bill');
|
||||
|
||||
$expenses_amount += $bill_paid_amount;
|
||||
|
||||
// Add to Incomes By Category
|
||||
$incomes[] = array(
|
||||
'amount' => money($invoice_paid_amount, setting('general.default_currency'), true)->format(),
|
||||
'value' => (int) $invoice_paid_amount,
|
||||
'color' => '#00c0ef',
|
||||
'highlight' => '#00c0ef',
|
||||
'label' => trans_choice('general.invoices', 2)
|
||||
);
|
||||
|
||||
// Add to Expenses By Category
|
||||
$expenses[] = array(
|
||||
'amount' => money($bill_paid_amount, setting('general.default_currency'), true)->format(),
|
||||
'value' => (int) $bill_paid_amount,
|
||||
'color' => '#dd4b39',
|
||||
'highlight' => '#dd4b39',
|
||||
'label' => trans_choice('general.bills', 2)
|
||||
);
|
||||
|
||||
// Revenues & Payments
|
||||
$categories = Category::orWhere('type', 'income')->orWhere('type', 'expense')->enabled()->get();
|
||||
|
||||
foreach ($categories as $category) {
|
||||
switch ($category->type) {
|
||||
case 'income':
|
||||
$revenues = $category->revenues;
|
||||
|
||||
$amount = 0;
|
||||
|
||||
if ($revenues) {
|
||||
foreach ($revenues as $revenue) {
|
||||
$amount += $revenue->getConvertedAmount();
|
||||
}
|
||||
|
||||
$incomes[] = array(
|
||||
'amount' => money($amount, setting('general.default_currency'), true)->format(),
|
||||
'value' => (int) $amount,
|
||||
'color' => $category->color,
|
||||
'highlight' => $category->color,
|
||||
'label' => $category->name
|
||||
);
|
||||
} else {
|
||||
$incomes[] = array(
|
||||
'amount' => money(0, setting('general.default_currency'), true)->format(),
|
||||
'value' => (int) 0,
|
||||
'color' => $category->color,
|
||||
'highlight' => $category->color,
|
||||
'label' => $category->name
|
||||
);
|
||||
}
|
||||
|
||||
$incomes_amount += $amount;
|
||||
break;
|
||||
case 'expense':
|
||||
$payments = $category->payments;
|
||||
|
||||
$amount = 0;
|
||||
|
||||
if ($payments) {
|
||||
foreach ($payments as $payment) {
|
||||
$amount += $payment->getConvertedAmount();
|
||||
}
|
||||
|
||||
$expenses[] = array(
|
||||
'amount' => money($amount, setting('general.default_currency'), true)->format(),
|
||||
'value' => (int) $amount,
|
||||
'color' => $category->color,
|
||||
'highlight' => $category->color,
|
||||
'label' => $category->name
|
||||
);
|
||||
} else {
|
||||
$expenses[] = array(
|
||||
'amount' => money(0, setting('general.default_currency'), true)->format(),
|
||||
'value' => (int) 0,
|
||||
'color' => $category->color,
|
||||
'highlight' => $category->color,
|
||||
'label' => $category->name
|
||||
);
|
||||
}
|
||||
|
||||
$expenses_amount += $amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($incomes_amount)) {
|
||||
foreach ($incomes as $key => $income) {
|
||||
$incomes[$key]['amount'] = money(0, setting('general.default_currency'), true)->format();
|
||||
$incomes[$key]['value'] = (int) 100 / count($incomes);
|
||||
}
|
||||
}
|
||||
|
||||
// Incomes Pie Chart
|
||||
$income_graph = json_encode($incomes);
|
||||
|
||||
if (empty($expenses_amount)) {
|
||||
foreach ($expenses as $key => $expense) {
|
||||
$expenses[$key]['amount'] = money(0, setting('general.default_currency'), true)->format();
|
||||
$expenses[$key]['value'] = (int) 100 / count($expenses);
|
||||
}
|
||||
}
|
||||
|
||||
// Expenses Pie Chart
|
||||
$expense_graph = json_encode($expenses);
|
||||
private function getTotals()
|
||||
{
|
||||
list($incomes_amount, $open_invoice, $overdue_invoice, $expenses_amount, $open_bill, $overdue_bill) = $this->calculateAmounts();
|
||||
|
||||
$incomes_progress = 100;
|
||||
|
||||
@ -241,44 +118,175 @@ class Dashboard extends Controller
|
||||
'progress' => $total_progress
|
||||
);
|
||||
|
||||
/*
|
||||
* Accounts
|
||||
*/
|
||||
|
||||
$accounts = Account::enabled()->get();
|
||||
|
||||
/*
|
||||
* Latest Incomes
|
||||
*/
|
||||
|
||||
$latest_incomes = collect(Invoice::accrued()->latest()->take(10)->get());
|
||||
$latest_incomes = $latest_incomes->merge(Revenue::latest()->take(10)->get())->take(5)->sortByDesc('invoiced_at');
|
||||
|
||||
/*
|
||||
* Latest Expenses
|
||||
*/
|
||||
|
||||
$latest_expenses = collect(Bill::accrued()->latest()->take(10)->get());
|
||||
$latest_expenses = $latest_expenses->merge(Payment::latest()->take(10)->get())->take(5)->sortByDesc('billed_at');
|
||||
|
||||
return view('dashboard.dashboard.index', compact(
|
||||
'total_incomes',
|
||||
'total_expenses',
|
||||
'total_profit',
|
||||
'cash_flow',
|
||||
'incomes',
|
||||
'incomes_amount',
|
||||
'income_graph',
|
||||
'expenses',
|
||||
'expenses_amount',
|
||||
'expense_graph',
|
||||
'accounts',
|
||||
'latest_incomes',
|
||||
'latest_expenses'
|
||||
));
|
||||
return array($total_incomes, $total_expenses, $total_profit);
|
||||
}
|
||||
|
||||
private function getCashFlow($type, $period)
|
||||
private function getCashFlow()
|
||||
{
|
||||
$start = Date::parse(request('start', $this->today->startOfYear()->format('Y-m-d')));
|
||||
$end = Date::parse(request('end', $this->today->endOfYear()->format('Y-m-d')));
|
||||
$period = request('period', 'month');
|
||||
|
||||
$start_month = $start->month;
|
||||
$end_month = $end->month;
|
||||
|
||||
// Monthly
|
||||
$labels = array();
|
||||
|
||||
$s = clone $start;
|
||||
|
||||
for ($j = $end_month; $j >= $start_month; $j--) {
|
||||
$labels[$end_month - $j] = $s->format('M Y');
|
||||
|
||||
if ($period == 'month') {
|
||||
$s->addMonth();
|
||||
} else {
|
||||
$s->addMonths(3);
|
||||
$j -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
$income = $this->calculateCashFlowTotals('income', $start, $end, $period);
|
||||
$expense = $this->calculateCashFlowTotals('expense', $start, $end, $period);
|
||||
|
||||
$profit = $this->calculateCashFlowProfit($income, $expense);
|
||||
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
->colors(['#6da252', '#00c0ef', '#F56954'])
|
||||
->dataset(trans_choice('general.profits', 1), $profit)
|
||||
->dataset(trans_choice('general.incomes', 1), $income)
|
||||
->dataset(trans_choice('general.expenses', 1), $expense)
|
||||
->labels($labels)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.multi.line');
|
||||
|
||||
return $chart;
|
||||
}
|
||||
|
||||
private function getDonuts()
|
||||
{
|
||||
// Show donut prorated if there is no income
|
||||
if (array_sum($this->income_donut['values']) == 0) {
|
||||
foreach ($this->income_donut['values'] as $key => $value) {
|
||||
$this->income_donut['values'][$key] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Get 6 categories by amount
|
||||
$colors = $labels = [];
|
||||
$values = collect($this->income_donut['values'])->sort()->reverse()->take(6)->all();
|
||||
foreach ($values as $id => $val) {
|
||||
$colors[$id] = $this->income_donut['colors'][$id];
|
||||
$labels[$id] = $this->income_donut['labels'][$id];
|
||||
}
|
||||
|
||||
$donut_incomes = Charts::create('donut', 'chartjs')
|
||||
->colors($colors)
|
||||
->labels($labels)
|
||||
->values($values)
|
||||
->dimensions(0, 160)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.donut');
|
||||
|
||||
// Show donut prorated if there is no expense
|
||||
if (array_sum($this->expense_donut['values']) == 0) {
|
||||
foreach ($this->expense_donut['values'] as $key => $value) {
|
||||
$this->expense_donut['values'][$key] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Get 6 categories by amount
|
||||
$colors = $labels = [];
|
||||
$values = collect($this->expense_donut['values'])->sort()->reverse()->take(6)->all();
|
||||
foreach ($values as $id => $val) {
|
||||
$colors[$id] = $this->expense_donut['colors'][$id];
|
||||
$labels[$id] = $this->expense_donut['labels'][$id];
|
||||
}
|
||||
|
||||
$donut_expenses = Charts::create('donut', 'chartjs')
|
||||
->colors($colors)
|
||||
->labels($labels)
|
||||
->values($values)
|
||||
->dimensions(0, 160)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.donut');
|
||||
|
||||
return array($donut_incomes, $donut_expenses);
|
||||
}
|
||||
|
||||
private function getLatestIncomes()
|
||||
{
|
||||
$latest = collect(Invoice::accrued()->latest()->take(10)->get());
|
||||
$latest = $latest->merge(Revenue::latest()->take(10)->get())->take(5)->sortByDesc('invoiced_at');
|
||||
|
||||
return $latest;
|
||||
}
|
||||
|
||||
private function getLatestExpenses()
|
||||
{
|
||||
$latest = collect(Bill::accrued()->latest()->take(10)->get());
|
||||
$latest = $latest->merge(Payment::latest()->take(10)->get())->take(5)->sortByDesc('billed_at');
|
||||
|
||||
return $latest;
|
||||
}
|
||||
|
||||
private function calculateAmounts()
|
||||
{
|
||||
$incomes_amount = $expenses_amount = 0;
|
||||
|
||||
// Invoices
|
||||
$invoices = Invoice::with('payments')->accrued()->get();
|
||||
list($invoice_paid_amount, $open_invoice, $overdue_invoice) = $this->calculateTotals($invoices, 'invoice');
|
||||
|
||||
$incomes_amount += $invoice_paid_amount;
|
||||
|
||||
// Add to Incomes By Category
|
||||
$this->addToIncomeDonut('#00c0ef', $invoice_paid_amount, trans_choice('general.invoices', 2));
|
||||
|
||||
// Bills
|
||||
$bills = Bill::with('payments')->accrued()->get();
|
||||
list($bill_paid_amount, $open_bill, $overdue_bill) = $this->calculateTotals($bills, 'bill');
|
||||
|
||||
$expenses_amount += $bill_paid_amount;
|
||||
|
||||
// Add to Expenses By Category
|
||||
$this->addToExpenseDonut('#dd4b39', $bill_paid_amount, trans_choice('general.bills', 2));
|
||||
|
||||
// Revenues & Payments
|
||||
$categories = Category::orWhere('type', 'income')->orWhere('type', 'expense')->enabled()->get();
|
||||
|
||||
foreach ($categories as $category) {
|
||||
switch ($category->type) {
|
||||
case 'income':
|
||||
$amount = 0;
|
||||
|
||||
foreach ($category->revenues as $revenue) {
|
||||
$amount += $revenue->getConvertedAmount();
|
||||
}
|
||||
|
||||
$this->addToIncomeDonut($category->color, $amount, $category->name);
|
||||
|
||||
$incomes_amount += $amount;
|
||||
break;
|
||||
case 'expense':
|
||||
$amount = 0;
|
||||
|
||||
foreach ($category->payments as $payment) {
|
||||
$amount += $payment->getConvertedAmount();
|
||||
}
|
||||
|
||||
$this->addToExpenseDonut($category->color, $amount, $category->name);
|
||||
|
||||
$expenses_amount += $amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array($incomes_amount, $open_invoice, $overdue_invoice, $expenses_amount, $open_bill, $overdue_bill);
|
||||
}
|
||||
|
||||
private function calculateCashFlowTotals($type, $start, $end, $period)
|
||||
{
|
||||
$totals = array();
|
||||
|
||||
@ -290,64 +298,77 @@ class Dashboard extends Controller
|
||||
$m2 = '\App\Models\Expense\BillPayment';
|
||||
}
|
||||
|
||||
switch ($period) {
|
||||
case 'yearly':
|
||||
$f1 = 'subYear';
|
||||
$f2 = 'addYear';
|
||||
$date_format = 'Y-m';
|
||||
|
||||
$date_format = 'Y';
|
||||
break;
|
||||
case 'monthly':
|
||||
$f1 = 'subYear';
|
||||
$f2 = 'addMonth';
|
||||
|
||||
$date_format = 'Y-m';
|
||||
break;
|
||||
default:
|
||||
case 'daily':
|
||||
$f1 = 'subMonth';
|
||||
$f2 = 'addDay';
|
||||
|
||||
$date_format = 'Y-m-d';
|
||||
break;
|
||||
if ($period == 'month') {
|
||||
$n = 1;
|
||||
$start_date = $start->format($date_format);
|
||||
$end_date = $end->format($date_format);
|
||||
$next_date = $start_date;
|
||||
} else {
|
||||
$n = 3;
|
||||
$start_date = $start->quarter;
|
||||
$end_date = $end->quarter;
|
||||
$next_date = $start_date;
|
||||
}
|
||||
|
||||
$now = Date::now();
|
||||
$sub = Date::now()->$f1();
|
||||
|
||||
$start_date = $sub->format($date_format);
|
||||
$end_date = $now->format($date_format);
|
||||
$next_date = $start_date;
|
||||
|
||||
$totals[$start_date] = 0;
|
||||
|
||||
do {
|
||||
$next_date = Date::parse($next_date)->$f2()->format($date_format);
|
||||
$s = clone $start;
|
||||
|
||||
//$totals[$start_date] = 0;
|
||||
while ($next_date <= $end_date) {
|
||||
$totals[$next_date] = 0;
|
||||
} while ($next_date < $end_date);
|
||||
|
||||
$items_1 = $m1::whereBetween('paid_at', [$sub, $now])->get();
|
||||
if ($period == 'month') {
|
||||
$next_date = $s->addMonths($n)->format($date_format);
|
||||
} else {
|
||||
if (isset($totals[4])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->setCashFlowTotals($totals, $items_1, $date_format);
|
||||
$next_date = $s->addMonths($n)->quarter;
|
||||
}
|
||||
}
|
||||
|
||||
$items_2 = $m2::whereBetween('paid_at', [$sub, $now])->get();
|
||||
$items_1 = $m1::whereBetween('paid_at', [$start, $end])->get();
|
||||
|
||||
$this->setCashFlowTotals($totals, $items_2, $date_format);
|
||||
$this->setCashFlowTotals($totals, $items_1, $date_format, $period);
|
||||
|
||||
$items_2 = $m2::whereBetween('paid_at', [$start, $end])->get();
|
||||
|
||||
$this->setCashFlowTotals($totals, $items_2, $date_format, $period);
|
||||
|
||||
return $totals;
|
||||
}
|
||||
|
||||
private function setCashFlowTotals(&$totals, $items, $date_format)
|
||||
private function setCashFlowTotals(&$totals, $items, $date_format, $period)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
$i = Date::parse($item->paid_at)->format($date_format);
|
||||
if ($period == 'month') {
|
||||
$i = Date::parse($item->paid_at)->format($date_format);
|
||||
} else {
|
||||
$i = Date::parse($item->paid_at)->quarter;
|
||||
}
|
||||
|
||||
$totals[$i] += $item->getConvertedAmount();
|
||||
}
|
||||
}
|
||||
|
||||
private function getTotals($items, $type)
|
||||
private function calculateCashFlowProfit($incomes, $expenses)
|
||||
{
|
||||
$profit = [];
|
||||
|
||||
foreach ($incomes as $key => $income) {
|
||||
if ($income > 0 && $income > $expenses[$key]) {
|
||||
$profit[$key] = $income - $expenses[$key];
|
||||
} else {
|
||||
$profit[$key] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $profit;
|
||||
}
|
||||
|
||||
private function calculateTotals($items, $type)
|
||||
{
|
||||
$paid = $open = $overdue = 0;
|
||||
|
||||
@ -380,18 +401,17 @@ class Dashboard extends Controller
|
||||
return array($paid, $open, $overdue);
|
||||
}
|
||||
|
||||
private function getProfit($incomes, $expenses)
|
||||
private function addToIncomeDonut($color, $amount, $text)
|
||||
{
|
||||
$profit = [];
|
||||
$this->income_donut['colors'][] = $color;
|
||||
$this->income_donut['labels'][] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $text;
|
||||
$this->income_donut['values'][] = (int) $amount;
|
||||
}
|
||||
|
||||
foreach ($incomes as $key => $income) {
|
||||
if ($income > 0 && $income > $expenses[$key]) {
|
||||
$profit[$key] = $income - $expenses[$key];
|
||||
} else {
|
||||
$profit[$key] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $profit;
|
||||
private function addToExpenseDonut($color, $amount, $text)
|
||||
{
|
||||
$this->expense_donut['colors'][] = $color;
|
||||
$this->expense_donut['labels'][] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $text;
|
||||
$this->expense_donut['values'][] = (int) $amount;
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class Bills extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$bills = Bill::with(['vendor', 'status', 'items', 'payments', 'histories'])->collect();
|
||||
$bills = Bill::with(['vendor', 'status', 'items', 'payments', 'histories'])->collect(['billed_at'=> 'desc']);
|
||||
|
||||
$vendors = collect(Vendor::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.vendors', 2)]), '');
|
||||
@ -156,7 +156,7 @@ class Bills extends Controller
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Increase stock (item bought)
|
||||
$item_object->quantity++;
|
||||
$item_object->quantity += $item['quantity'];
|
||||
$item_object->save();
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ class Bills extends Controller
|
||||
}
|
||||
|
||||
$bill_item['item_id'] = $item['item_id'];
|
||||
$bill_item['name'] = $item['name'];
|
||||
$bill_item['name'] = str_limit($item['name'], 180, '');
|
||||
$bill_item['sku'] = $item_sku;
|
||||
$bill_item['quantity'] = $item['quantity'];
|
||||
$bill_item['price'] = $item['price'];
|
||||
@ -396,7 +396,7 @@ class Bills extends Controller
|
||||
}
|
||||
|
||||
$bill_item['item_id'] = $item['item_id'];
|
||||
$bill_item['name'] = $item['name'];
|
||||
$bill_item['name'] = str_limit($item['name'], 180, '');
|
||||
$bill_item['sku'] = $item_sku;
|
||||
$bill_item['quantity'] = $item['quantity'];
|
||||
$bill_item['price'] = $item['price'];
|
||||
@ -603,17 +603,11 @@ class Bills extends Controller
|
||||
|
||||
$bill = Bill::find($request['bill_id']);
|
||||
|
||||
if ($request['currency_code'] == $bill->currency_code) {
|
||||
if ($request['amount'] > $bill->amount) {
|
||||
$message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]);
|
||||
$total_amount = $bill->amount;
|
||||
|
||||
return response()->json($message);
|
||||
} elseif ($request['amount'] == $bill->amount) {
|
||||
$bill->bill_status_code = 'paid';
|
||||
} else {
|
||||
$bill->bill_status_code = 'partial';
|
||||
}
|
||||
} else {
|
||||
$amount = (double) $request['amount'];
|
||||
|
||||
if ($request['currency_code'] != $bill->currency_code) {
|
||||
$request_bill = new Bill();
|
||||
|
||||
$request_bill->amount = (float) $request['amount'];
|
||||
@ -621,16 +615,24 @@ class Bills extends Controller
|
||||
$request_bill->currency_rate = $currency->rate;
|
||||
|
||||
$amount = $request_bill->getConvertedAmount();
|
||||
}
|
||||
|
||||
if ($amount > $bill->amount) {
|
||||
$message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]);
|
||||
if ($bill->payments()->count()) {
|
||||
$total_amount -= $bill->payments()->paid();
|
||||
}
|
||||
|
||||
return response()->json($message);
|
||||
} elseif ($amount == $bill->amount) {
|
||||
$bill->bill_status_code = 'paid';
|
||||
} else {
|
||||
$bill->bill_status_code = 'partial';
|
||||
}
|
||||
if ($amount > $total_amount) {
|
||||
$message = trans('messages.error.payment_add');
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'message' => $message,
|
||||
]);
|
||||
} elseif ($amount == $total_amount) {
|
||||
$bill->bill_status_code = 'paid';
|
||||
} else {
|
||||
$bill->bill_status_code = 'partial';
|
||||
}
|
||||
|
||||
$bill->save();
|
||||
@ -640,15 +642,19 @@ class Bills extends Controller
|
||||
$request['status_code'] = $bill->bill_status_code;
|
||||
$request['notify'] = 0;
|
||||
|
||||
$desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat());
|
||||
$desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format();
|
||||
$request['description'] = $desc_date . ' ' . $desc_amount;
|
||||
$desc_amount = money((float) $request['amount'], (string) $request['currency_code'], true)->format();
|
||||
|
||||
$request['description'] = $desc_amount . ' ' . trans_choice('general.payments', 1);
|
||||
|
||||
BillHistory::create($request->input());
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]);
|
||||
|
||||
return response()->json($message);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -660,12 +666,22 @@ class Bills extends Controller
|
||||
*/
|
||||
public function paymentDestroy(BillPayment $payment)
|
||||
{
|
||||
$bill = Bill::find($payment->bill_id);
|
||||
|
||||
if ($bill->payments()->count() > 1) {
|
||||
$bill->bill_status_code = 'partial';
|
||||
} else {
|
||||
$bill->bill_status_code = 'draft';
|
||||
}
|
||||
|
||||
$bill->save();
|
||||
|
||||
$payment->delete();
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.bills', 1)]);
|
||||
|
||||
flash($message)->success();
|
||||
|
||||
return redirect('expenses/bills');
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class Payments extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$payments = Payment::with(['vendor', 'account', 'category'])->collect();
|
||||
$payments = Payment::with(['vendor', 'account', 'category'])->collect(['paid_at'=> 'desc']);
|
||||
|
||||
$vendors = collect(Vendor::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.vendors', 2)]), '');
|
||||
@ -35,7 +35,9 @@ class Payments extends Controller
|
||||
$accounts = collect(Account::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
|
||||
|
||||
return view('expenses.payments.index', compact('payments', 'vendors', 'categories', 'accounts'));
|
||||
$transfer_cat_id = Category::transfer();
|
||||
|
||||
return view('expenses.payments.index', compact('payments', 'vendors', 'categories', 'accounts', 'transfer_cat_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,6 +199,11 @@ class Payments extends Controller
|
||||
*/
|
||||
public function destroy(Payment $payment)
|
||||
{
|
||||
// Can't delete transfer payment
|
||||
if ($payment->category->id == Category::transfer()) {
|
||||
return redirect('expenses/payments');
|
||||
}
|
||||
|
||||
$payment->delete();
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.payments', 1)]);
|
||||
|
@ -44,6 +44,10 @@ class Vendors extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if (empty($request['email'])) {
|
||||
$request['email'] = '';
|
||||
}
|
||||
|
||||
Vendor::create($request->all());
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.vendors', 1)]);
|
||||
@ -84,6 +88,11 @@ class Vendors extends Controller
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$data = $row->toArray();
|
||||
|
||||
if (empty($data['email'])) {
|
||||
$data['email'] = '';
|
||||
}
|
||||
|
||||
$data['company_id'] = session('company_id');
|
||||
|
||||
Vendor::create($data);
|
||||
@ -120,6 +129,10 @@ class Vendors extends Controller
|
||||
*/
|
||||
public function update(Vendor $vendor, Request $request)
|
||||
{
|
||||
if (empty($request['email'])) {
|
||||
$request['email'] = '';
|
||||
}
|
||||
|
||||
$vendor->update($request->all());
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.vendors', 1)]);
|
||||
@ -169,6 +182,10 @@ class Vendors extends Controller
|
||||
|
||||
public function vendor(Request $request)
|
||||
{
|
||||
if (empty($request['email'])) {
|
||||
$request['email'] = '';
|
||||
}
|
||||
|
||||
$vendor = Vendor::create($request->all());
|
||||
|
||||
return response()->json($vendor);
|
||||
|
@ -46,6 +46,10 @@ class Customers extends Controller
|
||||
public function store(Request $request)
|
||||
{
|
||||
if (empty($request->input('create_user'))) {
|
||||
if (empty($request['email'])) {
|
||||
$request['email'] = '';
|
||||
}
|
||||
|
||||
Customer::create($request->all());
|
||||
} else {
|
||||
// Check if user exist
|
||||
@ -61,10 +65,14 @@ class Customers extends Controller
|
||||
}
|
||||
|
||||
// Create user first
|
||||
$user = User::create($request->all());
|
||||
$data = $request->all();
|
||||
$data['locale'] = setting('general.default_locale', 'en-GB');
|
||||
|
||||
$user = User::create($data);
|
||||
$user->roles()->attach(['3']);
|
||||
$user->companies()->attach([session('company_id')]);
|
||||
|
||||
// Finally create customer
|
||||
$request['user_id'] = $user->id;
|
||||
|
||||
Customer::create($request->all());
|
||||
@ -108,6 +116,11 @@ class Customers extends Controller
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$data = $row->toArray();
|
||||
|
||||
if (empty($data['email'])) {
|
||||
$data['email'] = '';
|
||||
}
|
||||
|
||||
$data['company_id'] = session('company_id');
|
||||
|
||||
Customer::create($data);
|
||||
@ -145,6 +158,10 @@ class Customers extends Controller
|
||||
public function update(Customer $customer, Request $request)
|
||||
{
|
||||
if (empty($request->input('create_user'))) {
|
||||
if (empty($request['email'])) {
|
||||
$request['email'] = '';
|
||||
}
|
||||
|
||||
$customer->update($request->all());
|
||||
} else {
|
||||
// Check if user exist
|
||||
@ -216,6 +233,10 @@ class Customers extends Controller
|
||||
|
||||
public function customer(Request $request)
|
||||
{
|
||||
if (empty($request['email'])) {
|
||||
$request['email'] = '';
|
||||
}
|
||||
|
||||
$customer = Customer::create($request->all());
|
||||
|
||||
return response()->json($customer);
|
||||
|
@ -30,6 +30,8 @@ use App\Utilities\ImportFile;
|
||||
use App\Utilities\Modules;
|
||||
use Date;
|
||||
use File;
|
||||
use Image;
|
||||
use Storage;
|
||||
|
||||
class Invoices extends Controller
|
||||
{
|
||||
@ -42,7 +44,7 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories'])->collect();
|
||||
$invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories'])->collect(['invoice_number'=> 'desc']);
|
||||
|
||||
$customers = collect(Customer::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.customers', 2)]), '');
|
||||
@ -162,7 +164,7 @@ class Invoices extends Controller
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Decrease stock (item sold)
|
||||
$item_object->quantity--;
|
||||
$item_object->quantity -= $item['quantity'];
|
||||
$item_object->save();
|
||||
|
||||
// Notify users if out of stock
|
||||
@ -188,7 +190,7 @@ class Invoices extends Controller
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item['item_id'];
|
||||
$invoice_item['name'] = $item['name'];
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = $item['quantity'];
|
||||
$invoice_item['price'] = $item['price'];
|
||||
@ -386,7 +388,7 @@ class Invoices extends Controller
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item['item_id'];
|
||||
$invoice_item['name'] = $item['name'];
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = $item['quantity'];
|
||||
$invoice_item['price'] = $item['price'];
|
||||
@ -487,9 +489,15 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function emailInvoice(Invoice $invoice)
|
||||
{
|
||||
if (empty($invoice->customer_email)) {
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$invoice = $this->prepareInvoice($invoice);
|
||||
|
||||
$html = view($invoice->template_path, compact('invoice'))->render();
|
||||
$logo = $this->getLogo();
|
||||
|
||||
$html = view($invoice->template_path, compact('invoice', 'logo'))->render();
|
||||
|
||||
$pdf = \App::make('dompdf.wrapper');
|
||||
$pdf->loadHTML($html);
|
||||
@ -531,7 +539,9 @@ class Invoices extends Controller
|
||||
{
|
||||
$invoice = $this->prepareInvoice($invoice);
|
||||
|
||||
return view($invoice->template_path, compact('invoice'));
|
||||
$logo = $this->getLogo();
|
||||
|
||||
return view($invoice->template_path, compact('invoice', 'logo'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -545,7 +555,9 @@ class Invoices extends Controller
|
||||
{
|
||||
$invoice = $this->prepareInvoice($invoice);
|
||||
|
||||
$html = view($invoice->template_path, compact('invoice'))->render();
|
||||
$logo = $this->getLogo();
|
||||
|
||||
$html = view($invoice->template_path, compact('invoice', 'logo'))->render();
|
||||
|
||||
$pdf = \App::make('dompdf.wrapper');
|
||||
$pdf->loadHTML($html);
|
||||
@ -576,18 +588,23 @@ class Invoices extends Controller
|
||||
|
||||
$amount = $invoice->amount - $paid;
|
||||
|
||||
$request = new PaymentRequest();
|
||||
if (!empty($amount)) {
|
||||
$request = new PaymentRequest();
|
||||
|
||||
$request['company_id'] = $invoice->company_id;
|
||||
$request['invoice_id'] = $invoice->id;
|
||||
$request['account_id'] = setting('general.default_account');
|
||||
$request['payment_method'] = setting('general.default_payment_method');
|
||||
$request['currency_code'] = $invoice->currency_code;
|
||||
$request['amount'] = $amount;
|
||||
$request['paid_at'] = Date::now();
|
||||
$request['_token'] = csrf_token();
|
||||
$request['company_id'] = $invoice->company_id;
|
||||
$request['invoice_id'] = $invoice->id;
|
||||
$request['account_id'] = setting('general.default_account');
|
||||
$request['payment_method'] = setting('general.default_payment_method', 'offlinepayment.cash.1');
|
||||
$request['currency_code'] = $invoice->currency_code;
|
||||
$request['amount'] = $amount;
|
||||
$request['paid_at'] = Date::now();
|
||||
$request['_token'] = csrf_token();
|
||||
|
||||
$this->payment($request);
|
||||
$this->payment($request);
|
||||
} else {
|
||||
$invoice->invoice_status_code = 'paid';
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
@ -616,17 +633,11 @@ class Invoices extends Controller
|
||||
|
||||
$invoice = Invoice::find($request['invoice_id']);
|
||||
|
||||
if ($request['currency_code'] == $invoice->currency_code) {
|
||||
if ($request['amount'] > $invoice->amount) {
|
||||
$message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]);
|
||||
$total_amount = $invoice->amount;
|
||||
|
||||
return response()->json($message);
|
||||
} elseif ($request['amount'] == $invoice->amount) {
|
||||
$invoice->invoice_status_code = 'paid';
|
||||
} else {
|
||||
$invoice->invoice_status_code = 'partial';
|
||||
}
|
||||
} else {
|
||||
$amount = (double) $request['amount'];
|
||||
|
||||
if ($request['currency_code'] != $invoice->currency_code) {
|
||||
$request_invoice = new Invoice();
|
||||
|
||||
$request_invoice->amount = (float) $request['amount'];
|
||||
@ -634,16 +645,24 @@ class Invoices extends Controller
|
||||
$request_invoice->currency_rate = $currency->rate;
|
||||
|
||||
$amount = $request_invoice->getConvertedAmount();
|
||||
}
|
||||
|
||||
if ($amount > $invoice->amount) {
|
||||
$message = trans('messages.error.added', ['type' => trans_choice('general.payment', 1)]);
|
||||
if ($invoice->payments()->count()) {
|
||||
$total_amount -= $invoice->payments()->paid();
|
||||
}
|
||||
|
||||
return response()->json($message);
|
||||
} elseif ($amount == $invoice->amount) {
|
||||
$invoice->invoice_status_code = 'paid';
|
||||
} else {
|
||||
$invoice->invoice_status_code = 'partial';
|
||||
}
|
||||
if ($amount > $total_amount) {
|
||||
$message = trans('messages.error.payment_add');
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'message' => $message,
|
||||
]);
|
||||
} elseif ($amount == $total_amount) {
|
||||
$invoice->invoice_status_code = 'paid';
|
||||
} else {
|
||||
$invoice->invoice_status_code = 'partial';
|
||||
}
|
||||
|
||||
$invoice->save();
|
||||
@ -653,15 +672,19 @@ class Invoices extends Controller
|
||||
$request['status_code'] = $invoice->invoice_status_code;
|
||||
$request['notify'] = 0;
|
||||
|
||||
$desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat());
|
||||
$desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format();
|
||||
$request['description'] = $desc_date . ' ' . $desc_amount;
|
||||
$desc_amount = money((float) $request['amount'], (string) $request['currency_code'], true)->format();
|
||||
|
||||
$request['description'] = $desc_amount . ' ' . trans_choice('general.payments', 1);
|
||||
|
||||
InvoiceHistory::create($request->input());
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]);
|
||||
|
||||
return response()->json($message);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -673,13 +696,25 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function paymentDestroy(InvoicePayment $payment)
|
||||
{
|
||||
$invoice = Invoice::find($payment->invoice_id);
|
||||
|
||||
if ($invoice->payments()->paid() == $invoice->amount) {
|
||||
$invoice->invoice_status_code = 'paid';
|
||||
} elseif ($invoice->payments()->count() > 1) {
|
||||
$invoice->invoice_status_code = 'partial';
|
||||
} else {
|
||||
$invoice->invoice_status_code = 'draft';
|
||||
}
|
||||
|
||||
$invoice->save();
|
||||
|
||||
$payment->delete();
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.invoices', 1)]);
|
||||
|
||||
flash($message)->success();
|
||||
|
||||
return redirect('incomes/invoices');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
protected function prepareInvoice(Invoice $invoice)
|
||||
@ -743,4 +778,31 @@ class Invoices extends Controller
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getLogo()
|
||||
{
|
||||
$logo = '';
|
||||
|
||||
if (setting('general.invoice_logo')) {
|
||||
$file = session('company_id') . '/' . setting('general.invoice_logo');
|
||||
} else {
|
||||
$file = session('company_id') . '/' . setting('general.company_logo');
|
||||
}
|
||||
|
||||
$path = Storage::path($file);
|
||||
if (!is_file($path)) {
|
||||
return $logo;
|
||||
}
|
||||
|
||||
$image = Image::make($path)->encode()->getEncoded();
|
||||
if (empty($image)) {
|
||||
return $logo;
|
||||
}
|
||||
|
||||
$extension = File::extension($path);
|
||||
|
||||
$logo = 'data:image/' . $extension . ';base64,' . base64_encode($image);
|
||||
|
||||
return $logo;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class Revenues extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$revenues = Revenue::with(['account', 'category', 'customer'])->collect();
|
||||
$revenues = Revenue::with(['account', 'category', 'customer'])->collect(['paid_at'=> 'desc']);
|
||||
|
||||
$customers = collect(Customer::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.customers', 2)]), '');
|
||||
@ -37,7 +37,9 @@ class Revenues extends Controller
|
||||
$accounts = collect(Account::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
|
||||
|
||||
return view('incomes.revenues.index', compact('revenues', 'customers', 'categories', 'accounts'));
|
||||
$transfer_cat_id = Category::transfer();
|
||||
|
||||
return view('incomes.revenues.index', compact('revenues', 'customers', 'categories', 'accounts', 'transfer_cat_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,6 +201,11 @@ class Revenues extends Controller
|
||||
*/
|
||||
public function destroy(Revenue $revenue)
|
||||
{
|
||||
// Can't delete transfer revenue
|
||||
if ($revenue->category->id == Category::transfer()) {
|
||||
return redirect('incomes/revenues');
|
||||
}
|
||||
|
||||
$revenue->delete();
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.revenues', 1)]);
|
||||
|
@ -247,13 +247,16 @@ class Items extends Controller
|
||||
|
||||
if ($input_items) {
|
||||
foreach ($input_items as $key => $item) {
|
||||
$price = (double) $item['price'];
|
||||
$quantity = (int) $item['quantity'];
|
||||
|
||||
$item_tax_total= 0;
|
||||
$item_sub_total = ($item['price'] * $item['quantity']);
|
||||
$item_sub_total = ($price * $quantity);
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax = Tax::find($item['tax_id']);
|
||||
|
||||
$item_tax_total = (($item['price'] * $item['quantity']) / 100) * $tax->rate;
|
||||
$item_tax_total = (($price * $quantity) / 100) * $tax->rate;
|
||||
}
|
||||
|
||||
$sub_total += $item_sub_total;
|
||||
|
@ -19,9 +19,15 @@ class Home extends Controller
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$paid = $this->getPaidModules();
|
||||
$new = $this->getNewModules();
|
||||
$free = $this->getFreeModules();
|
||||
$data = [
|
||||
'query' => [
|
||||
'limit' => 4
|
||||
]
|
||||
];
|
||||
|
||||
$paid = $this->getPaidModules($data);
|
||||
$new = $this->getNewModules($data);
|
||||
$free = $this->getFreeModules($data);
|
||||
|
||||
return view('modules.home.index', compact('paid', 'new', 'free'));
|
||||
}
|
||||
|
@ -2,19 +2,33 @@
|
||||
|
||||
namespace App\Http\Controllers\Modules;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Module\Module;
|
||||
use App\Models\Module\ModuleHistory;
|
||||
use App\Traits\Modules;
|
||||
use Artisan;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Route;
|
||||
|
||||
class Item extends Controller
|
||||
{
|
||||
use Modules;
|
||||
|
||||
/**
|
||||
* Instantiate a new controller instance.
|
||||
*
|
||||
* @param Route $route
|
||||
*/
|
||||
public function __construct(Route $route)
|
||||
{
|
||||
parent::__construct($route);
|
||||
|
||||
// Add CRUD permission check
|
||||
$this->middleware('permission:create-modules-item')->only(['install']);
|
||||
$this->middleware('permission:update-modules-item')->only(['update', 'enable', 'disable']);
|
||||
$this->middleware('permission:delete-modules-item')->only(['uninstall']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
@ -31,7 +45,7 @@ class Item extends Controller
|
||||
|
||||
$module = $this->getModule($alias);
|
||||
|
||||
$check = Module::where('alias', $alias)->first();
|
||||
$check = Module::alias($alias)->first();
|
||||
|
||||
if ($check) {
|
||||
$installed = true;
|
||||
@ -154,7 +168,7 @@ class Item extends Controller
|
||||
|
||||
$json = $this->uninstallModule($alias);
|
||||
|
||||
$module = Module::where('alias', $alias)->first();
|
||||
$module = Module::alias($alias)->first();
|
||||
|
||||
$data = array(
|
||||
'company_id' => session('company_id'),
|
||||
@ -181,7 +195,7 @@ class Item extends Controller
|
||||
|
||||
$json = $this->updateModule($alias);
|
||||
|
||||
$module = Module::where('alias', $alias)->first();
|
||||
$module = Module::alias($alias)->first();
|
||||
|
||||
$data = array(
|
||||
'company_id' => session('company_id'),
|
||||
@ -206,7 +220,7 @@ class Item extends Controller
|
||||
|
||||
$json = $this->enableModule($alias);
|
||||
|
||||
$module = Module::where('alias', $alias)->first();
|
||||
$module = Module::alias($alias)->first();
|
||||
|
||||
$data = array(
|
||||
'company_id' => session('company_id'),
|
||||
@ -235,7 +249,7 @@ class Item extends Controller
|
||||
|
||||
$json = $this->disableModule($alias);
|
||||
|
||||
$module = Module::where('alias', $alias)->first();
|
||||
$module = Module::alias($alias)->first();
|
||||
|
||||
$data = array(
|
||||
'company_id' => session('company_id'),
|
||||
|
@ -7,6 +7,7 @@ use App\Models\Expense\Bill;
|
||||
use App\Models\Expense\BillPayment;
|
||||
use App\Models\Expense\Payment;
|
||||
use App\Models\Setting\Category;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
class ExpenseSummary extends Controller
|
||||
@ -90,10 +91,19 @@ class ExpenseSummary extends Controller
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $payments, 'payment', 'paid_at');
|
||||
}
|
||||
|
||||
// Expenses chart
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
->colors(['#F56954'])
|
||||
->dataset(trans_choice('general.expenses', 1), $expenses_graph)
|
||||
->labels($dates)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.multi.line');
|
||||
|
||||
// Expenses Graph
|
||||
$expenses_graph = json_encode($expenses_graph);
|
||||
|
||||
return view('reports.expense_summary.index', compact('dates', 'categories', 'expenses', 'expenses_graph', 'totals'));
|
||||
return view('reports.expense_summary.index', compact('chart', 'dates', 'categories', 'expenses', 'totals'));
|
||||
}
|
||||
|
||||
private function setAmount(&$graph, &$totals, &$expenses, $items, $type, $date_field)
|
||||
|
@ -10,6 +10,7 @@ use App\Models\Expense\Bill;
|
||||
use App\Models\Expense\BillPayment;
|
||||
use App\Models\Expense\Payment;
|
||||
use App\Models\Setting\Category;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
class IncomeExpenseSummary extends Controller
|
||||
@ -21,7 +22,7 @@ class IncomeExpenseSummary extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$dates = $totals = $compares = $compares_graph = $categories = [];
|
||||
$dates = $totals = $compares = $profit_graph = $categories = [];
|
||||
|
||||
$status = request('status');
|
||||
|
||||
@ -49,7 +50,7 @@ class IncomeExpenseSummary extends Controller
|
||||
for ($j = 1; $j <= 12; $j++) {
|
||||
$dates[$j] = Date::parse($year . '-' . $j)->format('F');
|
||||
|
||||
$compares_graph[Date::parse($year . '-' . $j)->format('F-Y')] = 0;
|
||||
$profit_graph[Date::parse($year . '-' . $j)->format('F-Y')] = 0;
|
||||
|
||||
// Totals
|
||||
$totals[$dates[$j]] = array(
|
||||
@ -100,50 +101,56 @@ class IncomeExpenseSummary extends Controller
|
||||
switch ($status) {
|
||||
case 'paid':
|
||||
$invoices = InvoicePayment::monthsOfYear('paid_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'paid_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'paid_at');
|
||||
break;
|
||||
case 'upcoming':
|
||||
$invoices = Invoice::accrued()->monthsOfYear('due_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'due_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'due_at');
|
||||
break;
|
||||
default:
|
||||
$invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $invoices, 'invoice', 'invoiced_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'invoiced_at');
|
||||
break;
|
||||
}
|
||||
|
||||
// Revenues
|
||||
if ($status != 'upcoming') {
|
||||
$revenues = Revenue::monthsOfYear('paid_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
|
||||
}
|
||||
|
||||
// Bills
|
||||
switch ($status) {
|
||||
case 'paid':
|
||||
$bills = BillPayment::monthsOfYear('paid_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'paid_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $bills, 'bill', 'paid_at');
|
||||
break;
|
||||
case 'upcoming':
|
||||
$bills = Bill::accrued()->monthsOfYear('due_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'due_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $bills, 'bill', 'due_at');
|
||||
break;
|
||||
default:
|
||||
$bills = Bill::accrued()->monthsOfYear('billed_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $bills, 'bill', 'billed_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $bills, 'bill', 'billed_at');
|
||||
break;
|
||||
}
|
||||
|
||||
// Payments
|
||||
if ($status != 'upcoming') {
|
||||
$payments = Payment::monthsOfYear('paid_at')->get();
|
||||
$this->setAmount($compares_graph, $totals, $compares, $payments, 'payment', 'paid_at');
|
||||
$this->setAmount($profit_graph, $totals, $compares, $payments, 'payment', 'paid_at');
|
||||
}
|
||||
|
||||
// Incomes Graph
|
||||
$compares_graph = json_encode($compares_graph);
|
||||
// Profit chart
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
->colors(['#6da252'])
|
||||
->dataset(trans_choice('general.profits', 1), $profit_graph)
|
||||
->labels($dates)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.multi.line');
|
||||
|
||||
return view('reports.income_expense_summary.index', compact('dates', 'income_categories', 'expense_categories', 'compares', 'compares_graph', 'totals'));
|
||||
return view('reports.income_expense_summary.index', compact('chart', 'dates', 'income_categories', 'expense_categories', 'compares', 'totals'));
|
||||
}
|
||||
|
||||
private function setAmount(&$graph, &$totals, &$compares, $items, $type, $date_field)
|
||||
|
@ -7,6 +7,7 @@ use App\Models\Income\Invoice;
|
||||
use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\Revenue;
|
||||
use App\Models\Setting\Category;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
class IncomeSummary extends Controller
|
||||
@ -90,10 +91,16 @@ class IncomeSummary extends Controller
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $revenues, 'revenue', 'paid_at');
|
||||
}
|
||||
|
||||
// Incomes Graph
|
||||
$incomes_graph = json_encode($incomes_graph);
|
||||
// Incomes chart
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
->colors(['#00c0ef'])
|
||||
->dataset(trans_choice('general.incomes', 1), $incomes_graph)
|
||||
->labels($dates)
|
||||
->credits(false)
|
||||
->view('vendor.consoletvs.charts.chartjs.multi.line');
|
||||
|
||||
return view('reports.income_summary.index', compact('dates', 'categories', 'incomes', 'incomes_graph', 'totals'));
|
||||
return view('reports.income_summary.index', compact('chart', 'dates', 'categories', 'incomes', 'totals'));
|
||||
}
|
||||
|
||||
private function setAmount(&$graph, &$totals, &$incomes, $items, $type, $date_field)
|
||||
|
@ -18,10 +18,12 @@ class Categories extends Controller
|
||||
{
|
||||
$categories = Category::collect();
|
||||
|
||||
$transfer_id = Category::transfer();
|
||||
|
||||
$types = collect(['expense' => 'Expense', 'income' => 'Income', 'item' => 'Item', 'other' => 'Other'])
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.types', 2)]), '');
|
||||
|
||||
return view('settings.categories.index', compact('categories', 'types'));
|
||||
return view('settings.categories.index', compact('categories', 'types', 'transfer_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,6 +114,11 @@ class Categories extends Controller
|
||||
'payments' => 'payments',
|
||||
]);
|
||||
|
||||
// Can't delete transfer category
|
||||
if ($category->id == Category::transfer()) {
|
||||
return redirect('settings/categories');
|
||||
}
|
||||
|
||||
if (empty($relationships)) {
|
||||
$category->delete();
|
||||
|
||||
|
@ -19,7 +19,7 @@ class Currencies extends Controller
|
||||
{
|
||||
$currencies = Currency::collect();
|
||||
|
||||
return view('settings.currencies.index', compact('currencies', 'codes', 'rates'));
|
||||
return view('settings.currencies.index', compact('currencies'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,20 +116,23 @@ class Currencies extends Controller
|
||||
*/
|
||||
public function update(Currency $currency, Request $request)
|
||||
{
|
||||
$relationships = $this->countRelationships($currency, [
|
||||
'accounts' => 'accounts',
|
||||
'customers' => 'customers',
|
||||
'invoices' => 'invoices',
|
||||
'revenues' => 'revenues',
|
||||
'bills' => 'bills',
|
||||
'payments' => 'payments',
|
||||
]);
|
||||
// Check if we can disable it
|
||||
if (!$request['enabled']) {
|
||||
$relationships = $this->countRelationships($currency, [
|
||||
'accounts' => 'accounts',
|
||||
'customers' => 'customers',
|
||||
'invoices' => 'invoices',
|
||||
'revenues' => 'revenues',
|
||||
'bills' => 'bills',
|
||||
'payments' => 'payments',
|
||||
]);
|
||||
|
||||
if ($currency->code == setting('general.default_currency')) {
|
||||
$relationships[] = strtolower(trans_choice('general.companies', 1));
|
||||
if ($currency->code == setting('general.default_currency')) {
|
||||
$relationships[] = strtolower(trans_choice('general.companies', 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($relationships) || $request['enabled']) {
|
||||
if (empty($relationships)) {
|
||||
// Force the rate to be 1 for default currency
|
||||
if ($request['default_currency']) {
|
||||
$request['rate'] = '1';
|
||||
@ -209,4 +212,20 @@ class Currencies extends Controller
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
public function config()
|
||||
{
|
||||
$json = new \stdClass();
|
||||
|
||||
$code = request('code');
|
||||
|
||||
if ($code) {
|
||||
$currency = config('money.' . $code);
|
||||
$currency['symbol_first'] = $currency['symbol_first'] ? 1 : 0;
|
||||
|
||||
$json = (object) $currency;
|
||||
}
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,14 @@ namespace App\Http\Controllers\Settings;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Setting\Setting as Request;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Company\Company;
|
||||
use App\Models\Setting\Currency;
|
||||
use App\Models\Setting\Tax;
|
||||
use App\Models\Setting\Setting;
|
||||
use App\Models\Setting\Tax;
|
||||
use App\Traits\DateTime;
|
||||
use App\Traits\Uploads;
|
||||
|
||||
use App\Utilities\Modules;
|
||||
use DotenvEditor;
|
||||
|
||||
class Settings extends Controller
|
||||
{
|
||||
@ -90,6 +91,8 @@ class Settings extends Controller
|
||||
|
||||
$skip_keys = ['company_id', '_method', '_token'];
|
||||
$file_keys = ['company_logo', 'invoice_logo'];
|
||||
|
||||
$companies = Company::all()->count();
|
||||
|
||||
foreach ($fields as $key => $value) {
|
||||
// Don't process unwanted keys
|
||||
@ -107,6 +110,17 @@ class Settings extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Change default locale if only 1 company
|
||||
if (($key == 'default_locale') && ($companies == 1)) {
|
||||
// Update .env file
|
||||
DotenvEditor::setKeys([
|
||||
[
|
||||
'key' => 'APP_LOCALE',
|
||||
'value' => $value,
|
||||
],
|
||||
])->save();
|
||||
}
|
||||
|
||||
setting()->set('general.' . $key, $value);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user