Merge branch 'master' of github.com:akaunting/akaunting
Conflicts: app/Http/Controllers/Auth/Login.php
This commit is contained in:
@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Http\Controllers\Api\Incomes;
|
||||
|
||||
use App\Events\InvoiceCreated;
|
||||
use App\Events\InvoiceUpdated;
|
||||
use App\Http\Controllers\ApiController;
|
||||
use App\Http\Requests\Income\Invoice as Request;
|
||||
use App\Jobs\Income\CreateInvoice;
|
||||
use App\Models\Income\Invoice;
|
||||
use App\Models\Income\InvoiceHistory;
|
||||
use App\Models\Income\InvoiceItem;
|
||||
@ -13,13 +13,13 @@ use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\InvoiceTotal;
|
||||
use App\Models\Common\Item;
|
||||
use App\Models\Setting\Tax;
|
||||
use App\Notifications\Common\Item as ItemNotification;
|
||||
use App\Traits\Incomes;
|
||||
use App\Transformers\Income\Invoice as Transformer;
|
||||
use Dingo\Api\Routing\Helpers;
|
||||
|
||||
class Invoices extends ApiController
|
||||
{
|
||||
use Helpers;
|
||||
use Helpers, Incomes;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
@ -63,114 +63,9 @@ class Invoices extends ApiController
|
||||
$request['amount'] = 0;
|
||||
}
|
||||
|
||||
$invoice = Invoice::create($request->all());
|
||||
$invoice = dispatch(new CreateInvoice($request));
|
||||
|
||||
$taxes = [];
|
||||
$tax_total = 0;
|
||||
$sub_total = 0;
|
||||
|
||||
$invoice_item = array();
|
||||
$invoice_item['company_id'] = $request['company_id'];
|
||||
$invoice_item['invoice_id'] = $invoice->id;
|
||||
|
||||
if ($request['item']) {
|
||||
foreach ($request['item'] as $item) {
|
||||
$item_id = 0;
|
||||
$item_sku = '';
|
||||
|
||||
if (!empty($item['item_id'])) {
|
||||
$item_object = Item::find($item['item_id']);
|
||||
|
||||
$item_id = $item['item_id'];
|
||||
|
||||
$item['name'] = $item_object->name;
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Decrease stock (item sold)
|
||||
$item_object->quantity -= $item['quantity'];
|
||||
$item_object->save();
|
||||
|
||||
// Notify users if out of stock
|
||||
if ($item_object->quantity == 0) {
|
||||
foreach ($item_object->company->users as $user) {
|
||||
if (!$user->can('read-notifications')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$user->notify(new ItemNotification($item_object));
|
||||
}
|
||||
}
|
||||
} elseif (!empty($item['sku'])) {
|
||||
$item_sku = $item['sku'];
|
||||
}
|
||||
|
||||
$tax = $tax_id = 0;
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax_object = Tax::find($item['tax_id']);
|
||||
|
||||
$tax_id = $item['tax_id'];
|
||||
|
||||
$tax = (($item['price'] * $item['quantity']) / 100) * $tax_object->rate;
|
||||
} elseif (!empty($item['tax'])) {
|
||||
$tax = $item['tax'];
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item_id;
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = $item['quantity'];
|
||||
$invoice_item['price'] = $item['price'];
|
||||
$invoice_item['tax'] = $tax;
|
||||
$invoice_item['tax_id'] = $tax_id;
|
||||
$invoice_item['total'] = $item['price'] * $item['quantity'];
|
||||
|
||||
InvoiceItem::create($invoice_item);
|
||||
|
||||
if (isset($tax_object)) {
|
||||
if (array_key_exists($tax_object->id, $taxes)) {
|
||||
$taxes[$tax_object->id]['amount'] += $tax;
|
||||
} else {
|
||||
$taxes[$tax_object->id] = [
|
||||
'name' => $tax_object->name,
|
||||
'amount' => $tax
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$tax_total += $tax;
|
||||
$sub_total += $invoice_item['total'];
|
||||
|
||||
unset($item_object);
|
||||
unset($tax_object);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($request['amount'])) {
|
||||
$request['amount'] = $sub_total + $tax_total;
|
||||
}
|
||||
|
||||
$invoice->update($request->input());
|
||||
|
||||
// Add invoice totals
|
||||
$this->addTotals($invoice, $request, $taxes, $sub_total, $tax_total);
|
||||
|
||||
$request['invoice_id'] = $invoice->id;
|
||||
$request['status_code'] = $request['invoice_status_code'];
|
||||
$request['notify'] = 0;
|
||||
$request['description'] = trans('messages.success.added', ['type' => $request['invoice_number']]);
|
||||
|
||||
InvoiceHistory::create($request->input());
|
||||
|
||||
// Update next invoice number
|
||||
$next = setting('general.invoice_number_next', 1) + 1;
|
||||
setting(['general.invoice_number_next' => $next]);
|
||||
setting()->save();
|
||||
|
||||
// Fire the event to make it extendible
|
||||
event(new InvoiceCreated($invoice));
|
||||
|
||||
return $this->response->created(url('api/invoices/'.$invoice->id));
|
||||
return $this->response->created(url('api/invoices/' . $invoice->id));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,12 +172,9 @@ class Invoices extends ApiController
|
||||
*/
|
||||
public function destroy(Invoice $invoice)
|
||||
{
|
||||
$this->deleteRelationships($invoice, ['items', 'histories', 'payments', 'recurring', 'totals']);
|
||||
$invoice->delete();
|
||||
|
||||
InvoiceItem::where('invoice_id', $invoice->id)->delete();
|
||||
InvoicePayment::where('invoice_id', $invoice->id)->delete();
|
||||
InvoiceHistory::where('invoice_id', $invoice->id)->delete();
|
||||
|
||||
return $this->response->noContent();
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ class Login extends Controller
|
||||
public function store()
|
||||
{
|
||||
// Attempt to login
|
||||
if (!auth()->attempt(request(['email', 'password']))) {
|
||||
if (!auth()->attempt(request(['email', 'password']), request('remember', false))) {
|
||||
flash(trans('auth.failed'))->error();
|
||||
|
||||
return back();
|
||||
@ -79,6 +79,11 @@ class Login extends Controller
|
||||
return redirect($path);
|
||||
}
|
||||
|
||||
// Check wizard
|
||||
if (!setting('general.wizard', false)) {
|
||||
return redirect('wizard');
|
||||
}
|
||||
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,21 @@ class Roles extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$permissions = Permission::all();
|
||||
$names = $permissions = [];
|
||||
$allPermissions = Permission::all();
|
||||
|
||||
return view('auth.roles.create', compact('permissions'));
|
||||
foreach ($allPermissions as $permission) {
|
||||
// permission code explode - and get permission type
|
||||
$n = explode('-', $permission->name);
|
||||
|
||||
if (!in_array($n[0], $names)) {
|
||||
$names[] = $n[0];
|
||||
}
|
||||
|
||||
$permissions[$n[0]][] = $permission;
|
||||
}
|
||||
|
||||
return view('auth.roles.create', compact('names', 'permissions'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,11 +78,23 @@ class Roles extends Controller
|
||||
public function edit(Role $role)
|
||||
{
|
||||
//$permissions = Permission::all()->sortBy('display_name');
|
||||
$permissions = Permission::all();
|
||||
$names = $permissions = [];
|
||||
$allPermissions = Permission::all();
|
||||
|
||||
$rolePermissions = $role->permissions->pluck('id', 'id')->toArray();
|
||||
|
||||
return view('auth.roles.edit', compact('role', 'permissions', 'rolePermissions'));
|
||||
foreach ($allPermissions as $permission) {
|
||||
// permission code explode - and get permission type
|
||||
$n = explode('-', $permission->name);
|
||||
|
||||
if (!in_array($n[0], $names)) {
|
||||
$names[] = $n[0];
|
||||
}
|
||||
|
||||
$permissions[$n[0]][] = $permission;
|
||||
}
|
||||
|
||||
return view('auth.roles.edit', compact('role', 'names', 'permissions', 'rolePermissions'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,8 +98,15 @@ class Accounts extends Controller
|
||||
*/
|
||||
public function update(Account $account, Request $request)
|
||||
{
|
||||
// Check if we can disable it
|
||||
if (!$request['enabled']) {
|
||||
// Check if we can disable or change the code
|
||||
if (!$request['enabled'] || ($account->currency_code != $request['currency_code'])) {
|
||||
$relationships = $this->countRelationships($account, [
|
||||
'invoice_payments' => 'invoices',
|
||||
'revenues' => 'revenues',
|
||||
'bill_payments' => 'bills',
|
||||
'payments' => 'payments',
|
||||
]);
|
||||
|
||||
if ($account->id == setting('general.default_account')) {
|
||||
$relationships[] = strtolower(trans_choice('general.companies', 1));
|
||||
}
|
||||
@ -120,7 +127,7 @@ class Accounts extends Controller
|
||||
|
||||
return redirect('banking/accounts');
|
||||
} else {
|
||||
$message = trans('messages.warning.disabled', ['name' => $account->name, 'text' => implode(', ', $relationships)]);
|
||||
$message = trans('messages.warning.disable_code', ['name' => $account->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
flash($message)->warning();
|
||||
|
||||
|
315
app/Http/Controllers/Banking/Reconciliations.php
Normal file
315
app/Http/Controllers/Banking/Reconciliations.php
Normal file
@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Banking;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Banking\Reconciliation as Request;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Banking\Reconciliation;
|
||||
use App\Models\Setting\Currency;
|
||||
use Date;
|
||||
|
||||
class Reconciliations extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$reconciliations = Reconciliation::collect();
|
||||
|
||||
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
return view('banking.reconciliations.index', compact('reconciliations', 'accounts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
return redirect()->route('reconciliations.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$accounts = Account::enabled()->pluck('name', 'id');
|
||||
|
||||
$account_id = request('account_id', setting('general.default_account'));
|
||||
$started_at = request('started_at', '0000-00-00');
|
||||
$ended_at = request('ended_at', '0000-00-00');
|
||||
|
||||
$account = Account::find($account_id);
|
||||
|
||||
$currency = $account->currency;
|
||||
|
||||
$transactions = $this->getTransactions($account, $started_at, $ended_at);
|
||||
|
||||
$opening_balance = $this->getOpeningBalance($account, $started_at, $ended_at);
|
||||
|
||||
return view('banking.reconciliations.create', compact('accounts', 'account', 'currency', 'opening_balance', 'transactions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$reconcile = $request->get('reconcile');
|
||||
$transactions = $request->get('transactions');
|
||||
|
||||
Reconciliation::create([
|
||||
'company_id' => session('company_id'),
|
||||
'account_id' => $request->get('account_id'),
|
||||
'started_at' => $request->get('started_at'),
|
||||
'ended_at' => $request->get('ended_at'),
|
||||
'closing_balance' => $request->get('closing_balance'),
|
||||
'reconciled' => $reconcile ? 1 : 0,
|
||||
]);
|
||||
|
||||
if ($transactions) {
|
||||
foreach ($transactions as $key => $value) {
|
||||
$t = explode('_', $key);
|
||||
$m = '\\' . $t['1'];
|
||||
|
||||
$transaction = $m::find($t[0]);
|
||||
$transaction->reconciled = 1;
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.reconciliations', 1)]);
|
||||
|
||||
flash($message)->success();
|
||||
|
||||
return redirect()->route('reconciliations.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Reconciliation $reconciliation
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit(Reconciliation $reconciliation)
|
||||
{
|
||||
$account = $reconciliation->account;
|
||||
|
||||
$currency = $account->currency;
|
||||
|
||||
$transactions = $this->getTransactions($account, $reconciliation->started_at, $reconciliation->ended_at);
|
||||
|
||||
$opening_balance = $this->getOpeningBalance($account, $reconciliation->started_at, $reconciliation->ended_at);
|
||||
|
||||
return view('banking.reconciliations.edit', compact('reconciliation', 'account', 'currency', 'opening_balance', 'transactions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Reconciliation $reconciliation
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Reconciliation $reconciliation, Request $request)
|
||||
{
|
||||
$reconcile = $request->get('reconcile');
|
||||
$transactions = $request->get('transactions');
|
||||
|
||||
$reconciliation->reconciled = $reconcile ? 1 : 0;
|
||||
$reconciliation->save();
|
||||
|
||||
if ($transactions) {
|
||||
foreach ($transactions as $key => $value) {
|
||||
$t = explode('_', $key);
|
||||
$m = '\\' . $t['1'];
|
||||
|
||||
$transaction = $m::find($t[0]);
|
||||
$transaction->reconciled = 1;
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.reconciliations', 1)]);
|
||||
|
||||
flash($message)->success();
|
||||
|
||||
return redirect()->route('reconciliations.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Reconciliation $reconciliation
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy(Reconciliation $reconciliation)
|
||||
{
|
||||
$reconciliation->delete();
|
||||
|
||||
$models = [
|
||||
'App\Models\Expense\Payment',
|
||||
'App\Models\Expense\BillPayment',
|
||||
'App\Models\Income\Revenue',
|
||||
'App\Models\Income\InvoicePayment',
|
||||
];
|
||||
|
||||
foreach ($models as $model) {
|
||||
$m = '\\' . $model;
|
||||
|
||||
$m::where('account_id', $reconciliation->account_id)
|
||||
->reconciled()
|
||||
->whereBetween('paid_at', [$reconciliation->started_at, $reconciliation->ended_at])->each(function ($item) {
|
||||
$item->reconciled = 0;
|
||||
$item->save();
|
||||
});
|
||||
}
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.reconciliations', 1)]);
|
||||
|
||||
flash($message)->success();
|
||||
|
||||
return redirect()->route('reconciliations.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add transactions array.
|
||||
*
|
||||
* @param $account_id
|
||||
* @param $started_at
|
||||
* @param $ended_at
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getTransactions($account, $started_at, $ended_at)
|
||||
{
|
||||
$started = explode(' ', $started_at);
|
||||
$ended = explode(' ', $ended_at);
|
||||
|
||||
$models = [
|
||||
'App\Models\Expense\Payment',
|
||||
'App\Models\Expense\BillPayment',
|
||||
'App\Models\Income\Revenue',
|
||||
'App\Models\Income\InvoicePayment',
|
||||
];
|
||||
|
||||
$transactions = [];
|
||||
|
||||
foreach ($models as $model) {
|
||||
$m = '\\' . $model;
|
||||
|
||||
$m::where('account_id', $account->id)->whereBetween('paid_at', [$started[0], $ended[0]])->each(function($item) use(&$transactions, $model) {
|
||||
$item->model = $model;
|
||||
|
||||
if (($model == 'App\Models\Income\Invoice') || ($model == 'App\Models\Income\Revenue')) {
|
||||
if ($item->invoice) {
|
||||
$item->contact = $item->invoice->customer;
|
||||
} else {
|
||||
$item->contact = $item->customer;
|
||||
}
|
||||
} else {
|
||||
if ($item->bill) {
|
||||
$item->contact = $item->bill->vendor;
|
||||
} else {
|
||||
$item->contact = $item->vendor;
|
||||
}
|
||||
}
|
||||
|
||||
$transactions[] = $item;
|
||||
});
|
||||
}
|
||||
|
||||
return collect($transactions)->sortByDesc('paid_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the opening balance
|
||||
*
|
||||
* @param $account
|
||||
* @param $started_at
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOpeningBalance($account, $started_at)
|
||||
{
|
||||
// Opening Balance
|
||||
$total = $account->opening_balance;
|
||||
|
||||
// Sum invoices
|
||||
$invoice_payments = $account->invoice_payments()->whereDate('paid_at', '<', $started_at)->get();
|
||||
foreach ($invoice_payments as $item) {
|
||||
$total += $item->amount;
|
||||
}
|
||||
|
||||
// Sum revenues
|
||||
$revenues = $account->revenues()->whereDate('paid_at', '<', $started_at)->get();
|
||||
foreach ($revenues as $item) {
|
||||
$total += $item->amount;
|
||||
}
|
||||
|
||||
// Subtract bills
|
||||
$bill_payments = $account->bill_payments()->whereDate('paid_at', '<', $started_at)->get();
|
||||
foreach ($bill_payments as $item) {
|
||||
$total -= $item->amount;
|
||||
}
|
||||
|
||||
// Subtract payments
|
||||
$payments = $account->payments()->whereDate('paid_at', '<', $started_at)->get();
|
||||
foreach ($payments as $item) {
|
||||
$total -= $item->amount;
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
public function calculate()
|
||||
{
|
||||
$currency_code = request('currency_code');
|
||||
$closing_balance = request('closing_balance');
|
||||
|
||||
$json = new \stdClass();
|
||||
|
||||
$cleared_amount = $difference = $income_total = $expense_total = 0;
|
||||
|
||||
if ($transactions = request('transactions')) {
|
||||
$opening_balance = request('opening_balance');
|
||||
|
||||
foreach ($transactions as $key => $value) {
|
||||
$model = explode('_', $key);
|
||||
|
||||
if (($model[1] == 'App\Models\Income\Invoice') || ($model[1] == 'App\Models\Income\Revenue')) {
|
||||
$income_total += $value;
|
||||
} else {
|
||||
$expense_total += $value;
|
||||
}
|
||||
}
|
||||
|
||||
$cleared_amount = $opening_balance + ($income_total - $expense_total);
|
||||
}
|
||||
|
||||
$difference = $closing_balance - $cleared_amount;
|
||||
|
||||
$json->closing_balance = money($closing_balance, $currency_code, true)->format();
|
||||
$json->cleared_amount = money($cleared_amount, $currency_code, true)->format();
|
||||
$json->difference = money($difference, $currency_code, true)->format();
|
||||
$json->difference_raw = (int) $difference;
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
}
|
@ -25,25 +25,24 @@ class Transactions extends Controller
|
||||
{
|
||||
$request = request();
|
||||
|
||||
$accounts = collect(Account::enabled()->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
|
||||
$accounts = collect(Account::enabled()->pluck('name', 'id'));
|
||||
|
||||
$types = collect(['expense' => 'Expense', 'income' => 'Income'])
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.types', 2)]), '');
|
||||
|
||||
$categories = collect(Category::enabled()->type('income')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.categories', 2)]), '');
|
||||
|
||||
$type = $request->get('type');
|
||||
|
||||
$type_cats = empty($type) ? ['income', 'expense'] : $type;
|
||||
$categories = collect(Category::enabled()->type($type_cats)->pluck('name', 'id'));
|
||||
|
||||
if ($type != 'income') {
|
||||
$this->addTransactions(Payment::collect(['paid_at'=> 'desc']), trans_choice('general.expenses', 1));
|
||||
$this->addTransactions(BillPayment::collect(['paid_at'=> 'desc']), trans_choice('general.expenses', 1), trans_choice('general.bills', 1));
|
||||
$this->addTransactions(BillPayment::collect(['paid_at'=> 'desc']), trans_choice('general.expenses', 1));
|
||||
}
|
||||
|
||||
if ($type != 'expense') {
|
||||
$this->addTransactions(Revenue::collect(['paid_at'=> 'desc']), trans_choice('general.incomes', 1));
|
||||
$this->addTransactions(InvoicePayment::collect(['paid_at'=> 'desc']), trans_choice('general.incomes', 1), trans_choice('general.invoices', 1));
|
||||
$this->addTransactions(InvoicePayment::collect(['paid_at'=> 'desc']), trans_choice('general.incomes', 1));
|
||||
}
|
||||
|
||||
$transactions = $this->getTransactions($request);
|
||||
@ -56,27 +55,29 @@ class Transactions extends Controller
|
||||
*
|
||||
* @param $items
|
||||
* @param $type
|
||||
* @param $category
|
||||
*/
|
||||
protected function addTransactions($items, $type, $category = null)
|
||||
protected function addTransactions($items, $type)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
$data = [
|
||||
if (!empty($item->category)) {
|
||||
$category_name = ($item->category) ? $item->category->name : trans('general.na');
|
||||
} else {
|
||||
if ($type == trans_choice('general.incomes', 1)) {
|
||||
$category_name = ($item->invoice->category) ? $item->invoice->category->name : trans('general.na');
|
||||
} else {
|
||||
$category_name = ($item->bill->category) ? $item->bill->category->name : trans('general.na');
|
||||
}
|
||||
}
|
||||
|
||||
$this->transactions[] = (object) [
|
||||
'paid_at' => $item->paid_at,
|
||||
'account_name' => $item->account->name,
|
||||
'type' => $type,
|
||||
'description' => $item->description,
|
||||
'amount' => $item->amount,
|
||||
'currency_code' => $item->currency_code,
|
||||
'category_name' => $category_name,
|
||||
];
|
||||
|
||||
if (!is_null($category)) {
|
||||
$data['category_name'] = $category;
|
||||
} else {
|
||||
$data['category_name'] = $item->category->name;
|
||||
}
|
||||
|
||||
$this->transactions[] = (object) $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,11 @@ class Companies extends Controller
|
||||
event(new CompanySwitched($company));
|
||||
}
|
||||
|
||||
// Check wizard
|
||||
if (!setting('general.wizard', false)) {
|
||||
return redirect('wizard');
|
||||
}
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,7 @@ class Dashboard extends Controller
|
||||
$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');
|
||||
$range = request('range', 'custom');
|
||||
|
||||
$start_month = $start->month;
|
||||
$end_month = $end->month;
|
||||
@ -135,6 +136,14 @@ class Dashboard extends Controller
|
||||
|
||||
$s = clone $start;
|
||||
|
||||
if ($range == 'last_12_months') {
|
||||
$end_month = 12;
|
||||
$start_month = 0;
|
||||
} elseif ($range == 'custom') {
|
||||
$end_month = $end->diffInMonths($start);
|
||||
$start_month = 0;
|
||||
}
|
||||
|
||||
for ($j = $end_month; $j >= $start_month; $j--) {
|
||||
$labels[$end_month - $j] = $s->format('M Y');
|
||||
|
||||
|
@ -26,8 +26,7 @@ class Items extends Controller
|
||||
{
|
||||
$items = Item::with('category')->collect();
|
||||
|
||||
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id')
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.categories', 2)]), '');
|
||||
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id');
|
||||
|
||||
return view('common.items.index', compact('items', 'categories'));
|
||||
}
|
||||
@ -51,7 +50,7 @@ class Items extends Controller
|
||||
{
|
||||
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id');
|
||||
|
||||
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$currency = Currency::where('code', '=', setting('general.default_currency', 'USD'))->first();
|
||||
|
||||
@ -132,7 +131,7 @@ class Items extends Controller
|
||||
{
|
||||
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id');
|
||||
|
||||
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$currency = Currency::where('code', '=', setting('general.default_currency', 'USD'))->first();
|
||||
|
||||
@ -323,22 +322,83 @@ class Items extends Controller
|
||||
$price = (double) $item['price'];
|
||||
$quantity = (double) $item['quantity'];
|
||||
|
||||
$item_tax_total= 0;
|
||||
$item_tax_total = 0;
|
||||
$item_tax_amount = 0;
|
||||
|
||||
$item_sub_total = ($price * $quantity);
|
||||
$item_discount_total = $item_sub_total;
|
||||
|
||||
// Apply discount to item
|
||||
if ($discount) {
|
||||
$item_discount_total = $item_sub_total - ($item_sub_total * ($discount / 100));
|
||||
}
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax = Tax::find($item['tax_id']);
|
||||
$inclusives = $compounds = $taxes = [];
|
||||
|
||||
$item_tax_total = (($price * $quantity) / 100) * $tax->rate;
|
||||
foreach ($item['tax_id'] as $tax_id) {
|
||||
$tax = Tax::find($tax_id);
|
||||
|
||||
switch ($tax->type) {
|
||||
case 'inclusive':
|
||||
$inclusives[] = $tax;
|
||||
break;
|
||||
case 'compound':
|
||||
$compounds[] = $tax;
|
||||
break;
|
||||
case 'normal':
|
||||
default:
|
||||
$taxes[] = $tax;
|
||||
|
||||
$item_tax_amount = ($item_discount_total / 100) * $tax->rate;
|
||||
|
||||
$item_tax_total += $item_tax_amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($inclusives) {
|
||||
if ($discount) {
|
||||
$item_tax_total = 0;
|
||||
|
||||
if ($taxes) {
|
||||
foreach ($taxes as $tax) {
|
||||
$item_tax_amount = ($item_sub_total / 100) * $tax->rate;
|
||||
|
||||
$item_tax_total += $item_tax_amount;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($inclusives as $inclusive) {
|
||||
$item_sub_and_tax_total = $item_sub_total + $item_tax_total;
|
||||
|
||||
$item_tax_total = $item_sub_and_tax_total - (($item_sub_and_tax_total * (100 - $inclusive->rate)) / 100);
|
||||
|
||||
$item_sub_total = $item_sub_and_tax_total - $item_tax_total;
|
||||
|
||||
$item_discount_total = $item_sub_total - ($item_sub_total * ($discount / 100));
|
||||
}
|
||||
} else {
|
||||
foreach ($inclusives as $inclusive) {
|
||||
$item_sub_and_tax_total = $item_discount_total + $item_tax_total;
|
||||
|
||||
$item_tax_total = $item_sub_and_tax_total - (($item_sub_and_tax_total * (100 - $inclusive->rate)) / 100);
|
||||
|
||||
$item_sub_total = $item_sub_and_tax_total - $item_tax_total;
|
||||
|
||||
$item_discount_total = $item_sub_total - ($item_sub_total * ($discount / 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($compounds) {
|
||||
foreach ($compounds as $compound) {
|
||||
$item_tax_total += (($item_discount_total + $item_tax_total) / 100) * $compound->rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sub_total += $item_sub_total;
|
||||
|
||||
// Apply discount to tax
|
||||
if ($discount) {
|
||||
$item_tax_total = $item_tax_total - ($item_tax_total * ($discount / 100));
|
||||
}
|
||||
|
||||
$tax_total += $item_tax_total;
|
||||
|
||||
$items[$key] = money($item_sub_total, $currency_code, true)->format();
|
||||
|
70
app/Http/Controllers/Common/Notifications.php
Normal file
70
app/Http/Controllers/Common/Notifications.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Common;
|
||||
|
||||
use Date;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Traits\Modules as RemoteModules;
|
||||
use App\Http\Requests\Common\Notification as Request;
|
||||
|
||||
class Notifications extends Controller
|
||||
{
|
||||
use RemoteModules;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$notifications = setting('notifications');
|
||||
|
||||
return view('common.notifications.index', compact('notifications'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function show($path, $id)
|
||||
{
|
||||
$notification = setting('notifications.' . $path . '.' . $id);
|
||||
|
||||
return view('common.notifications.show', compact('notification'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the specified resource.
|
||||
*
|
||||
* @param Company $company
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function disable(Request $request)
|
||||
{
|
||||
$id = $request['id'];
|
||||
$path = str_replace('#', '/', $request['path']);
|
||||
|
||||
$notifications = $this->getNotifications($path);
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if ($notification->id == $id) {
|
||||
setting()->set('notifications.'. $path . '.' . $id . '.name', $notification->name);
|
||||
setting()->set('notifications.'. $path . '.' . $id . '.message', $notification->message);
|
||||
setting()->set('notifications.'. $path . '.' . $id . '.date', Date::now());
|
||||
setting()->set('notifications.'. $path . '.' . $id . '.status', '0');
|
||||
|
||||
setting()->save();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'data' => null,
|
||||
]);
|
||||
}
|
||||
}
|
@ -91,6 +91,10 @@ class Uploads extends Controller
|
||||
*/
|
||||
protected function getPath($media)
|
||||
{
|
||||
if (!is_object($media)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$path = $media->basename;
|
||||
|
||||
if (!empty($media->directory)) {
|
||||
|
@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Events\InvoicePrinting;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Income\Customer;
|
||||
use App\Models\Income\Revenue;
|
||||
use App\Models\Income\Invoice;
|
||||
use App\Models\Income\InvoiceStatus;
|
||||
use App\Models\Setting\Category;
|
||||
@ -16,8 +17,10 @@ use App\Traits\DateTime;
|
||||
use App\Traits\Uploads;
|
||||
use App\Utilities\Modules;
|
||||
use File;
|
||||
use Illuminate\Http\Request;
|
||||
use Image;
|
||||
use Storage;
|
||||
use SignedUrl;
|
||||
|
||||
class Invoices extends Controller
|
||||
{
|
||||
@ -178,4 +181,52 @@ class Invoices extends Controller
|
||||
|
||||
return $logo;
|
||||
}
|
||||
|
||||
public function link(Invoice $invoice, Request $request)
|
||||
{
|
||||
session(['company_id' => $invoice->company_id]);
|
||||
|
||||
$paid = 0;
|
||||
|
||||
foreach ($invoice->payments as $item) {
|
||||
$amount = $item->amount;
|
||||
|
||||
if ($invoice->currency_code != $item->currency_code) {
|
||||
$item->default_currency_code = $invoice->currency_code;
|
||||
|
||||
$amount = $item->getDynamicConvertedAmount();
|
||||
}
|
||||
|
||||
$paid += $amount;
|
||||
}
|
||||
|
||||
$invoice->paid = $paid;
|
||||
|
||||
$accounts = Account::enabled()->pluck('name', 'id');
|
||||
|
||||
$currencies = Currency::enabled()->pluck('name', 'code')->toArray();
|
||||
|
||||
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
|
||||
|
||||
$customers = Customer::enabled()->pluck('name', 'id');
|
||||
|
||||
$categories = Category::enabled()->type('income')->pluck('name', 'id');
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods();
|
||||
|
||||
$payment_actions = [];
|
||||
|
||||
foreach ($payment_methods as $payment_method_key => $payment_method_value) {
|
||||
$codes = explode('.', $payment_method_key);
|
||||
|
||||
if (!isset($payment_actions[$codes[0]])) {
|
||||
$payment_actions[$codes[0]] = SignedUrl::sign(url('links/invoices/' . $invoice->id . '/' . $codes[0]), 1);
|
||||
}
|
||||
}
|
||||
|
||||
$print_action = SignedUrl::sign(url('links/invoices/' . $invoice->id . '/print'), 1);
|
||||
$pdf_action = SignedUrl::sign(url('links/invoices/' . $invoice->id . '/pdf'), 1);
|
||||
|
||||
return view('customers.invoices.link', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'payment_actions', 'print_action', 'pdf_action'));
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,16 @@ use App\Events\BillUpdated;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Expense\Bill as Request;
|
||||
use App\Http\Requests\Expense\BillPayment as PaymentRequest;
|
||||
use App\Jobs\Expense\CreateBill;
|
||||
use App\Jobs\Expense\UpdateBill;
|
||||
use App\Jobs\Expense\CreateBillPayment;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Common\Media;
|
||||
use App\Models\Expense\BillStatus;
|
||||
use App\Models\Expense\Vendor;
|
||||
use App\Models\Expense\Bill;
|
||||
use App\Models\Expense\BillItem;
|
||||
use App\Models\Expense\BillItemTax;
|
||||
use App\Models\Expense\BillTotal;
|
||||
use App\Models\Expense\BillHistory;
|
||||
use App\Models\Expense\BillPayment;
|
||||
@ -46,13 +50,13 @@ class Bills extends Controller
|
||||
{
|
||||
$bills = Bill::with(['vendor', 'status', 'items', 'payments', 'histories'])->collect(['billed_at'=> 'desc']);
|
||||
|
||||
$vendors = collect(Vendor::enabled()->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.vendors', 2)]), '');
|
||||
$vendors = collect(Vendor::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$statuses = collect(BillStatus::all()->pluck('name', 'code'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.statuses', 2)]), '');
|
||||
$categories = collect(Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
return view('expenses.bills.index', compact('bills', 'vendors', 'statuses'));
|
||||
$statuses = collect(BillStatus::all()->pluck('name', 'code'));
|
||||
|
||||
return view('expenses.bills.index', compact('bills', 'vendors', 'categories', 'statuses'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,43 +68,6 @@ class Bills extends Controller
|
||||
*/
|
||||
public function show(Bill $bill)
|
||||
{
|
||||
$paid = 0;
|
||||
|
||||
// Get Bill Payments
|
||||
if ($bill->payments->count()) {
|
||||
$_currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
|
||||
|
||||
foreach ($bill->payments as $item) {
|
||||
$default_amount = (double) $item->amount;
|
||||
|
||||
if ($bill->currency_code == $item->currency_code) {
|
||||
$amount = $default_amount;
|
||||
} else {
|
||||
$default_amount_model = new BillPayment();
|
||||
|
||||
$default_amount_model->default_currency_code = $bill->currency_code;
|
||||
$default_amount_model->amount = $default_amount;
|
||||
$default_amount_model->currency_code = $item->currency_code;
|
||||
$default_amount_model->currency_rate = $_currencies[$item->currency_code];
|
||||
|
||||
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
|
||||
|
||||
$convert_amount = new BillPayment();
|
||||
|
||||
$convert_amount->default_currency_code = $item->currency_code;
|
||||
$convert_amount->amount = $default_amount;
|
||||
$convert_amount->currency_code = $bill->currency_code;
|
||||
$convert_amount->currency_rate = $_currencies[$bill->currency_code];
|
||||
|
||||
$amount = (double) $convert_amount->getDynamicConvertedAmount();
|
||||
}
|
||||
|
||||
$paid += $amount;
|
||||
}
|
||||
}
|
||||
|
||||
$bill->paid = $paid;
|
||||
|
||||
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
|
||||
@ -131,7 +98,7 @@ class Bills extends Controller
|
||||
|
||||
$items = Item::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -147,120 +114,7 @@ class Bills extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$bill = Bill::create($request->input());
|
||||
|
||||
// Upload attachment
|
||||
if ($request->file('attachment')) {
|
||||
$media = $this->getMedia($request->file('attachment'), 'bills');
|
||||
|
||||
$bill->attachMedia($media, 'attachment');
|
||||
}
|
||||
|
||||
$taxes = [];
|
||||
|
||||
$tax_total = 0;
|
||||
$sub_total = 0;
|
||||
$discount_total = 0;
|
||||
$discount = $request['discount'];
|
||||
|
||||
$bill_item = [];
|
||||
$bill_item['company_id'] = $request['company_id'];
|
||||
$bill_item['bill_id'] = $bill->id;
|
||||
|
||||
if ($request['item']) {
|
||||
foreach ($request['item'] as $item) {
|
||||
unset($tax_object);
|
||||
$item_sku = '';
|
||||
|
||||
if (!empty($item['item_id'])) {
|
||||
$item_object = Item::find($item['item_id']);
|
||||
|
||||
$item['name'] = $item_object->name;
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Increase stock (item bought)
|
||||
$item_object->quantity += $item['quantity'];
|
||||
$item_object->save();
|
||||
}
|
||||
|
||||
$tax = $tax_id = 0;
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax_object = Tax::find($item['tax_id']);
|
||||
|
||||
$tax_id = $item['tax_id'];
|
||||
|
||||
$tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate;
|
||||
|
||||
// Apply discount to tax
|
||||
if ($discount) {
|
||||
$tax = $tax - ($tax * ($discount / 100));
|
||||
}
|
||||
}
|
||||
|
||||
$bill_item['item_id'] = $item['item_id'];
|
||||
$bill_item['name'] = str_limit($item['name'], 180, '');
|
||||
$bill_item['sku'] = $item_sku;
|
||||
$bill_item['quantity'] = (double) $item['quantity'];
|
||||
$bill_item['price'] = (double) $item['price'];
|
||||
$bill_item['tax'] = $tax;
|
||||
$bill_item['tax_id'] = $tax_id;
|
||||
$bill_item['total'] = (double) $item['price'] * (double) $item['quantity'];
|
||||
|
||||
BillItem::create($bill_item);
|
||||
|
||||
// Set taxes
|
||||
if (isset($tax_object)) {
|
||||
if (array_key_exists($tax_object->id, $taxes)) {
|
||||
$taxes[$tax_object->id]['amount'] += $tax;
|
||||
} else {
|
||||
$taxes[$tax_object->id] = [
|
||||
'name' => $tax_object->name,
|
||||
'amount' => $tax
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate totals
|
||||
$tax_total += $tax;
|
||||
$sub_total += $bill_item['total'];
|
||||
|
||||
unset($tax_object);
|
||||
}
|
||||
}
|
||||
|
||||
$s_total = $sub_total;
|
||||
|
||||
// Apply discount to total
|
||||
if ($discount) {
|
||||
$s_discount = $s_total * ($discount / 100);
|
||||
$discount_total += $s_discount;
|
||||
$s_total = $s_total - $s_discount;
|
||||
}
|
||||
|
||||
$amount = $s_total + $tax_total;
|
||||
|
||||
$request['amount'] = money($amount, $request['currency_code'])->getAmount();
|
||||
|
||||
$bill->update($request->input());
|
||||
|
||||
// Add bill totals
|
||||
$this->addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total);
|
||||
|
||||
// Add bill history
|
||||
BillHistory::create([
|
||||
'company_id' => session('company_id'),
|
||||
'bill_id' => $bill->id,
|
||||
'status_code' => 'draft',
|
||||
'notify' => 0,
|
||||
'description' => trans('messages.success.added', ['type' => $bill->bill_number]),
|
||||
]);
|
||||
|
||||
// Recurring
|
||||
$bill->createRecurring();
|
||||
|
||||
// Fire the event to make it extendible
|
||||
event(new BillCreated($bill));
|
||||
$bill = dispatch(new CreateBill($request));
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.bills', 1)]);
|
||||
|
||||
@ -373,105 +227,7 @@ class Bills extends Controller
|
||||
*/
|
||||
public function update(Bill $bill, Request $request)
|
||||
{
|
||||
$taxes = [];
|
||||
$tax_total = 0;
|
||||
$sub_total = 0;
|
||||
$discount_total = 0;
|
||||
$discount = $request['discount'];
|
||||
|
||||
$bill_item = [];
|
||||
$bill_item['company_id'] = $request['company_id'];
|
||||
$bill_item['bill_id'] = $bill->id;
|
||||
|
||||
if ($request['item']) {
|
||||
$this->deleteRelationships($bill, 'items');
|
||||
|
||||
foreach ($request['item'] as $item) {
|
||||
unset($tax_object);
|
||||
$item_sku = '';
|
||||
|
||||
if (!empty($item['item_id'])) {
|
||||
$item_object = Item::find($item['item_id']);
|
||||
|
||||
$item['name'] = $item_object->name;
|
||||
$item_sku = $item_object->sku;
|
||||
}
|
||||
|
||||
$tax = $tax_id = 0;
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax_object = Tax::find($item['tax_id']);
|
||||
|
||||
$tax_id = $item['tax_id'];
|
||||
|
||||
$tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate;
|
||||
|
||||
// Apply discount to tax
|
||||
if ($discount) {
|
||||
$tax = $tax - ($tax * ($discount / 100));
|
||||
}
|
||||
}
|
||||
|
||||
$bill_item['item_id'] = $item['item_id'];
|
||||
$bill_item['name'] = str_limit($item['name'], 180, '');
|
||||
$bill_item['sku'] = $item_sku;
|
||||
$bill_item['quantity'] = (double) $item['quantity'];
|
||||
$bill_item['price'] = (double) $item['price'];
|
||||
$bill_item['tax'] = $tax;
|
||||
$bill_item['tax_id'] = $tax_id;
|
||||
$bill_item['total'] = (double) $item['price'] * (double) $item['quantity'];
|
||||
|
||||
if (isset($tax_object)) {
|
||||
if (array_key_exists($tax_object->id, $taxes)) {
|
||||
$taxes[$tax_object->id]['amount'] += $tax;
|
||||
} else {
|
||||
$taxes[$tax_object->id] = [
|
||||
'name' => $tax_object->name,
|
||||
'amount' => $tax
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$tax_total += $tax;
|
||||
$sub_total += $bill_item['total'];
|
||||
|
||||
BillItem::create($bill_item);
|
||||
}
|
||||
}
|
||||
|
||||
$s_total = $sub_total;
|
||||
|
||||
// Apply discount to total
|
||||
if ($discount) {
|
||||
$s_discount = $s_total * ($discount / 100);
|
||||
$discount_total += $s_discount;
|
||||
$s_total = $s_total - $s_discount;
|
||||
}
|
||||
|
||||
$amount = $s_total + $tax_total;
|
||||
|
||||
$request['amount'] = money($amount, $request['currency_code'])->getAmount();
|
||||
|
||||
$bill->update($request->input());
|
||||
|
||||
// Upload attachment
|
||||
if ($request->file('attachment')) {
|
||||
$media = $this->getMedia($request->file('attachment'), 'bills');
|
||||
|
||||
$bill->attachMedia($media, 'attachment');
|
||||
}
|
||||
|
||||
// Delete previous bill totals
|
||||
$this->deleteRelationships($bill, 'totals');
|
||||
|
||||
// Add bill totals
|
||||
$this->addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total);
|
||||
|
||||
// Recurring
|
||||
$bill->updateRecurring();
|
||||
|
||||
// Fire the event to make it extendible
|
||||
event(new BillUpdated($bill));
|
||||
$bill = dispatch(new UpdateBill($bill, $request));
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.bills', 1)]);
|
||||
|
||||
@ -509,9 +265,9 @@ class Bills extends Controller
|
||||
\Excel::create('bills', function ($excel) {
|
||||
$bills = Bill::with(['items', 'histories', 'payments', 'totals'])->filter(request()->input())->get();
|
||||
|
||||
$excel->sheet('invoices', function ($sheet) use ($bills) {
|
||||
$excel->sheet('bills', function ($sheet) use ($bills) {
|
||||
$sheet->fromModel($bills->makeHidden([
|
||||
'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at', 'attachment', 'discount', 'items', 'histories', 'payments', 'totals', 'media'
|
||||
'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at', 'attachment', 'discount', 'items', 'histories', 'payments', 'totals', 'media', 'paid'
|
||||
]));
|
||||
});
|
||||
|
||||
@ -581,7 +337,9 @@ class Bills extends Controller
|
||||
{
|
||||
$bill = $this->prepareBill($bill);
|
||||
|
||||
$html = view($bill->template_path, compact('bill'))->render();
|
||||
$currency_style = true;
|
||||
|
||||
$html = view($bill->template_path, compact('bill', 'currency_style'))->render();
|
||||
|
||||
$pdf = \App::make('dompdf.wrapper');
|
||||
$pdf->loadHTML($html);
|
||||
@ -652,20 +410,7 @@ class Bills extends Controller
|
||||
|
||||
$bill->save();
|
||||
|
||||
$bill_payment_request = [
|
||||
'company_id' => $request['company_id'],
|
||||
'bill_id' => $request['bill_id'],
|
||||
'account_id' => $request['account_id'],
|
||||
'paid_at' => $request['paid_at'],
|
||||
'amount' => $request['amount'],
|
||||
'currency_code' => $request['currency_code'],
|
||||
'currency_rate' => $request['currency_rate'],
|
||||
'description' => $request['description'],
|
||||
'payment_method' => $request['payment_method'],
|
||||
'reference' => $request['reference']
|
||||
];
|
||||
|
||||
$bill_payment = BillPayment::create($bill_payment_request);
|
||||
$bill_payment = dispatch(new CreateBillPayment($request, $bill));
|
||||
|
||||
// Upload attachment
|
||||
if ($request->file('attachment')) {
|
||||
@ -674,15 +419,6 @@ class Bills extends Controller
|
||||
$bill_payment->attachMedia($media, 'attachment');
|
||||
}
|
||||
|
||||
$request['status_code'] = $bill->bill_status_code;
|
||||
$request['notify'] = 0;
|
||||
|
||||
$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.payments', 1)]);
|
||||
|
||||
return response()->json([
|
||||
@ -791,64 +527,4 @@ class Bills extends Controller
|
||||
|
||||
return $bill;
|
||||
}
|
||||
|
||||
protected function addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total)
|
||||
{
|
||||
$sort_order = 1;
|
||||
|
||||
// Added bill sub total
|
||||
BillTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'bill_id' => $bill->id,
|
||||
'code' => 'sub_total',
|
||||
'name' => 'bills.sub_total',
|
||||
'amount' => $sub_total,
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
|
||||
$sort_order++;
|
||||
|
||||
// Added bill discount
|
||||
if ($discount_total) {
|
||||
BillTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'bill_id' => $bill->id,
|
||||
'code' => 'discount',
|
||||
'name' => 'bills.discount',
|
||||
'amount' => $discount_total,
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
|
||||
// This is for total
|
||||
$sub_total = $sub_total - $discount_total;
|
||||
}
|
||||
|
||||
$sort_order++;
|
||||
|
||||
// Added bill taxes
|
||||
if ($taxes) {
|
||||
foreach ($taxes as $tax) {
|
||||
BillTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'bill_id' => $bill->id,
|
||||
'code' => 'tax',
|
||||
'name' => $tax['name'],
|
||||
'amount' => $tax['amount'],
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
|
||||
$sort_order++;
|
||||
}
|
||||
}
|
||||
|
||||
// Added bill total
|
||||
BillTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'bill_id' => $bill->id,
|
||||
'code' => 'total',
|
||||
'name' => 'bills.total',
|
||||
'amount' => $sub_total + $tax_total,
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,11 @@ class Payments extends Controller
|
||||
{
|
||||
$payments = Payment::with(['vendor', 'account', 'category'])->isNotTransfer()->collect(['paid_at'=> 'desc']);
|
||||
|
||||
$vendors = collect(Vendor::enabled()->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.vendors', 2)]), '');
|
||||
$vendors = collect(Vendor::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$categories = collect(Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.categories', 2)]), '');
|
||||
$categories = collect(Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
|
||||
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$transfer_cat_id = Category::transfer();
|
||||
|
||||
@ -64,7 +61,7 @@ class Payments extends Controller
|
||||
|
||||
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
|
||||
|
||||
$currency = Currency::where('code', '=', $account_currency_code)->first();
|
||||
$currency = Currency::where('code', $account_currency_code)->first();
|
||||
|
||||
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -154,9 +151,7 @@ class Payments extends Controller
|
||||
|
||||
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
|
||||
|
||||
$account_currency_code = Account::where('id', $payment->account_id)->pluck('currency_code')->first();
|
||||
|
||||
$currency = Currency::where('code', '=', $account_currency_code)->first();
|
||||
$currency = Currency::where('code', $payment->currency_code)->first();
|
||||
|
||||
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -164,7 +159,7 @@ class Payments extends Controller
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods();
|
||||
|
||||
return view('expenses.payments.edit', compact('payment', 'accounts', 'currencies', 'account_currency_code', 'currency', 'vendors', 'categories', 'payment_methods'));
|
||||
return view('expenses.payments.edit', compact('payment', 'accounts', 'currencies', 'currency', 'vendors', 'categories', 'payment_methods'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,8 +100,10 @@ class Vendors extends Controller
|
||||
|
||||
$limit = request('limit', setting('general.list_limit', '25'));
|
||||
$transactions = $this->paginate($items->merge($bill_payments)->sortByDesc('paid_at'), $limit);
|
||||
$bills = $this->paginate($bills->sortByDesc('paid_at'), $limit);
|
||||
$payments = $this->paginate($payments->sortByDesc('paid_at'), $limit);
|
||||
|
||||
return view('expenses.vendors.show', compact('vendor', 'counts', 'amounts', 'transactions'));
|
||||
return view('expenses.vendors.show', compact('vendor', 'counts', 'amounts', 'transactions', 'bills', 'payments'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,7 +311,7 @@ class Vendors extends Controller
|
||||
if (empty($vendor_id)) {
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
|
||||
$vendor = Vendor::find($vendor_id);
|
||||
|
||||
if (empty($vendor)) {
|
||||
@ -332,6 +334,12 @@ class Vendors extends Controller
|
||||
$vendor->currency_code = $currency_code;
|
||||
$vendor->currency_rate = $currency->rate;
|
||||
|
||||
$vendor->thousands_separator = $currency->thousands_separator;
|
||||
$vendor->decimal_mark = $currency->decimal_mark;
|
||||
$vendor->precision = (int) $currency->precision;
|
||||
$vendor->symbol_first = $currency->symbol_first;
|
||||
$vendor->symbol = $currency->symbol;
|
||||
|
||||
return response()->json($vendor);
|
||||
}
|
||||
|
||||
|
@ -100,8 +100,10 @@ class Customers extends Controller
|
||||
|
||||
$limit = request('limit', setting('general.list_limit', '25'));
|
||||
$transactions = $this->paginate($items->merge($invoice_payments)->sortByDesc('paid_at'), $limit);
|
||||
$invoices = $this->paginate($invoices->sortByDesc('paid_at'), $limit);
|
||||
$revenues = $this->paginate($revenues->sortByDesc('paid_at'), $limit);
|
||||
|
||||
return view('incomes.customers.show', compact('customer', 'counts', 'amounts', 'transactions'));
|
||||
return view('incomes.customers.show', compact('customer', 'counts', 'amounts', 'transactions', 'invoices', 'revenues'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,21 +8,26 @@ use App\Events\InvoiceUpdated;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Income\Invoice as Request;
|
||||
use App\Http\Requests\Income\InvoicePayment as PaymentRequest;
|
||||
use App\Jobs\Income\CreateInvoice;
|
||||
use App\Jobs\Income\UpdateInvoice;
|
||||
use App\Jobs\Income\CreateInvoicePayment;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Common\Item;
|
||||
use App\Models\Common\Media;
|
||||
use App\Models\Income\Customer;
|
||||
use App\Models\Income\Invoice;
|
||||
use App\Models\Income\InvoiceHistory;
|
||||
use App\Models\Income\InvoiceItem;
|
||||
use App\Models\Income\InvoiceItemTax;
|
||||
use App\Models\Income\InvoiceTotal;
|
||||
use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\InvoiceStatus;
|
||||
use App\Models\Common\Item;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Models\Setting\Currency;
|
||||
use App\Models\Setting\Tax;
|
||||
use App\Notifications\Income\Invoice as Notification;
|
||||
use App\Notifications\Common\Item as ItemNotification;
|
||||
use App\Notifications\Common\ItemReminder as ItemReminderNotification;
|
||||
use App\Traits\Currencies;
|
||||
use App\Traits\DateTime;
|
||||
use App\Traits\Incomes;
|
||||
@ -35,6 +40,7 @@ use File;
|
||||
use Illuminate\Http\Request as ItemRequest;
|
||||
use Image;
|
||||
use Storage;
|
||||
use SignedUrl;
|
||||
|
||||
class Invoices extends Controller
|
||||
{
|
||||
@ -49,13 +55,13 @@ class Invoices extends Controller
|
||||
{
|
||||
$invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories'])->collect(['invoice_number'=> 'desc']);
|
||||
|
||||
$customers = collect(Customer::enabled()->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.customers', 2)]), '');
|
||||
$customers = collect(Customer::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$status = collect(InvoiceStatus::all()->pluck('name', 'code'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.statuses', 2)]), '');
|
||||
$categories = collect(Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
return view('incomes.invoices.index', compact('invoices', 'customers', 'status'));
|
||||
$statuses = collect(InvoiceStatus::all()->pluck('name', 'code'));
|
||||
|
||||
return view('incomes.invoices.index', compact('invoices', 'customers', 'categories', 'statuses'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,43 +73,6 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function show(Invoice $invoice)
|
||||
{
|
||||
$paid = 0;
|
||||
|
||||
// Get Invoice Payments
|
||||
if ($invoice->payments->count()) {
|
||||
$_currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
|
||||
|
||||
foreach ($invoice->payments as $item) {
|
||||
$default_amount = $item->amount;
|
||||
|
||||
if ($invoice->currency_code == $item->currency_code) {
|
||||
$amount = (double)$default_amount;
|
||||
} else {
|
||||
$default_amount_model = new InvoicePayment();
|
||||
|
||||
$default_amount_model->default_currency_code = $invoice->currency_code;
|
||||
$default_amount_model->amount = $default_amount;
|
||||
$default_amount_model->currency_code = $item->currency_code;
|
||||
$default_amount_model->currency_rate = $_currencies[$item->currency_code];
|
||||
|
||||
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
|
||||
|
||||
$convert_amount = new InvoicePayment();
|
||||
|
||||
$convert_amount->default_currency_code = $item->currency_code;
|
||||
$convert_amount->amount = $default_amount;
|
||||
$convert_amount->currency_code = $invoice->currency_code;
|
||||
$convert_amount->currency_rate = $_currencies[$invoice->currency_code];
|
||||
|
||||
$amount = (double) $convert_amount->getDynamicConvertedAmount();
|
||||
}
|
||||
|
||||
$paid += $amount;
|
||||
}
|
||||
}
|
||||
|
||||
$invoice->paid = $paid;
|
||||
|
||||
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
|
||||
@ -116,7 +85,9 @@ class Invoices extends Controller
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods();
|
||||
|
||||
return view('incomes.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods'));
|
||||
$customer_share = SignedUrl::sign(url('links/invoices/' . $invoice->id));
|
||||
|
||||
return view('incomes.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'customer_share'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +105,7 @@ class Invoices extends Controller
|
||||
|
||||
$items = Item::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -152,133 +123,7 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$invoice = Invoice::create($request->input());
|
||||
|
||||
// Upload attachment
|
||||
if ($request->file('attachment')) {
|
||||
$media = $this->getMedia($request->file('attachment'), 'invoices');
|
||||
|
||||
$invoice->attachMedia($media, 'attachment');
|
||||
}
|
||||
|
||||
$taxes = [];
|
||||
|
||||
$tax_total = 0;
|
||||
$sub_total = 0;
|
||||
$discount_total = 0;
|
||||
$discount = $request['discount'];
|
||||
|
||||
$invoice_item = [];
|
||||
$invoice_item['company_id'] = $request['company_id'];
|
||||
$invoice_item['invoice_id'] = $invoice->id;
|
||||
|
||||
if ($request['item']) {
|
||||
foreach ($request['item'] as $item) {
|
||||
$item_sku = '';
|
||||
|
||||
if (!empty($item['item_id'])) {
|
||||
$item_object = Item::find($item['item_id']);
|
||||
|
||||
$item['name'] = $item_object->name;
|
||||
$item_sku = $item_object->sku;
|
||||
|
||||
// Decrease stock (item sold)
|
||||
$item_object->quantity -= $item['quantity'];
|
||||
$item_object->save();
|
||||
|
||||
// Notify users if out of stock
|
||||
if ($item_object->quantity == 0) {
|
||||
foreach ($item_object->company->users as $user) {
|
||||
if (!$user->can('read-notifications')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$user->notify(new ItemNotification($item_object));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tax = $tax_id = 0;
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax_object = Tax::find($item['tax_id']);
|
||||
|
||||
$tax_id = $item['tax_id'];
|
||||
|
||||
$tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate;
|
||||
|
||||
// Apply discount to tax
|
||||
if ($discount) {
|
||||
$tax = $tax - ($tax * ($discount / 100));
|
||||
}
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item['item_id'];
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = (double) $item['quantity'];
|
||||
$invoice_item['price'] = (double) $item['price'];
|
||||
$invoice_item['tax'] = $tax;
|
||||
$invoice_item['tax_id'] = $tax_id;
|
||||
$invoice_item['total'] = (double) $item['price'] * (double) $item['quantity'];
|
||||
|
||||
InvoiceItem::create($invoice_item);
|
||||
|
||||
// Set taxes
|
||||
if (isset($tax_object)) {
|
||||
if (array_key_exists($tax_object->id, $taxes)) {
|
||||
$taxes[$tax_object->id]['amount'] += $tax;
|
||||
} else {
|
||||
$taxes[$tax_object->id] = [
|
||||
'name' => $tax_object->name,
|
||||
'amount' => $tax
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate totals
|
||||
$tax_total += $tax;
|
||||
$sub_total += $invoice_item['total'];
|
||||
|
||||
unset($tax_object);
|
||||
}
|
||||
}
|
||||
|
||||
$s_total = $sub_total;
|
||||
|
||||
// Apply discount to total
|
||||
if ($discount) {
|
||||
$s_discount = $s_total * ($discount / 100);
|
||||
$discount_total += $s_discount;
|
||||
$s_total = $s_total - $s_discount;
|
||||
}
|
||||
|
||||
$amount = $s_total + $tax_total;
|
||||
|
||||
$request['amount'] = money($amount, $request['currency_code'])->getAmount();
|
||||
|
||||
$invoice->update($request->input());
|
||||
|
||||
// Add invoice totals
|
||||
$this->addTotals($invoice, $request, $taxes, $sub_total, $discount_total, $tax_total);
|
||||
|
||||
// Add invoice history
|
||||
InvoiceHistory::create([
|
||||
'company_id' => session('company_id'),
|
||||
'invoice_id' => $invoice->id,
|
||||
'status_code' => 'draft',
|
||||
'notify' => 0,
|
||||
'description' => trans('messages.success.added', ['type' => $invoice->invoice_number]),
|
||||
]);
|
||||
|
||||
// Update next invoice number
|
||||
$this->increaseNextInvoiceNumber();
|
||||
|
||||
// Recurring
|
||||
$invoice->createRecurring();
|
||||
|
||||
// Fire the event to make it extendible
|
||||
event(new InvoiceCreated($invoice));
|
||||
$invoice = dispatch(new CreateInvoice($request));
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.invoices', 1)]);
|
||||
|
||||
@ -377,7 +222,7 @@ class Invoices extends Controller
|
||||
|
||||
$items = Item::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -394,105 +239,7 @@ class Invoices extends Controller
|
||||
*/
|
||||
public function update(Invoice $invoice, Request $request)
|
||||
{
|
||||
$taxes = [];
|
||||
$tax_total = 0;
|
||||
$sub_total = 0;
|
||||
$discount_total = 0;
|
||||
$discount = $request['discount'];
|
||||
|
||||
$invoice_item = [];
|
||||
$invoice_item['company_id'] = $request['company_id'];
|
||||
$invoice_item['invoice_id'] = $invoice->id;
|
||||
|
||||
if ($request['item']) {
|
||||
$this->deleteRelationships($invoice, 'items');
|
||||
|
||||
foreach ($request['item'] as $item) {
|
||||
unset($tax_object);
|
||||
$item_sku = '';
|
||||
|
||||
if (!empty($item['item_id'])) {
|
||||
$item_object = Item::find($item['item_id']);
|
||||
|
||||
$item['name'] = $item_object->name;
|
||||
$item_sku = $item_object->sku;
|
||||
}
|
||||
|
||||
$tax = $tax_id = 0;
|
||||
|
||||
if (!empty($item['tax_id'])) {
|
||||
$tax_object = Tax::find($item['tax_id']);
|
||||
|
||||
$tax_id = $item['tax_id'];
|
||||
|
||||
$tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate;
|
||||
|
||||
// Apply discount to tax
|
||||
if ($discount) {
|
||||
$tax = $tax - ($tax * ($discount / 100));
|
||||
}
|
||||
}
|
||||
|
||||
$invoice_item['item_id'] = $item['item_id'];
|
||||
$invoice_item['name'] = str_limit($item['name'], 180, '');
|
||||
$invoice_item['sku'] = $item_sku;
|
||||
$invoice_item['quantity'] = (double) $item['quantity'];
|
||||
$invoice_item['price'] = (double) $item['price'];
|
||||
$invoice_item['tax'] = $tax;
|
||||
$invoice_item['tax_id'] = $tax_id;
|
||||
$invoice_item['total'] = (double) $item['price'] * (double) $item['quantity'];
|
||||
|
||||
if (isset($tax_object)) {
|
||||
if (array_key_exists($tax_object->id, $taxes)) {
|
||||
$taxes[$tax_object->id]['amount'] += $tax;
|
||||
} else {
|
||||
$taxes[$tax_object->id] = [
|
||||
'name' => $tax_object->name,
|
||||
'amount' => $tax
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$tax_total += $tax;
|
||||
$sub_total += $invoice_item['total'];
|
||||
|
||||
InvoiceItem::create($invoice_item);
|
||||
}
|
||||
}
|
||||
|
||||
$s_total = $sub_total;
|
||||
|
||||
// Apply discount to total
|
||||
if ($discount) {
|
||||
$s_discount = $s_total * ($discount / 100);
|
||||
$discount_total += $s_discount;
|
||||
$s_total = $s_total - $s_discount;
|
||||
}
|
||||
|
||||
$amount = $s_total + $tax_total;
|
||||
|
||||
$request['amount'] = money($amount, $request['currency_code'])->getAmount();
|
||||
|
||||
$invoice->update($request->input());
|
||||
|
||||
// Upload attachment
|
||||
if ($request->file('attachment')) {
|
||||
$media = $this->getMedia($request->file('attachment'), 'invoices');
|
||||
|
||||
$invoice->attachMedia($media, 'attachment');
|
||||
}
|
||||
|
||||
// Delete previous invoice totals
|
||||
$this->deleteRelationships($invoice, 'totals');
|
||||
|
||||
// Add invoice totals
|
||||
$this->addTotals($invoice, $request, $taxes, $sub_total, $discount_total, $tax_total);
|
||||
|
||||
// Recurring
|
||||
$invoice->updateRecurring();
|
||||
|
||||
// Fire the event to make it extendible
|
||||
event(new InvoiceUpdated($invoice));
|
||||
$invoice = dispatch(new UpdateInvoice($invoice, $request));
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.invoices', 1)]);
|
||||
|
||||
@ -532,7 +279,7 @@ class Invoices extends Controller
|
||||
|
||||
$excel->sheet('invoices', function ($sheet) use ($invoices) {
|
||||
$sheet->fromModel($invoices->makeHidden([
|
||||
'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at', 'attachment', 'discount', 'items', 'histories', 'payments', 'totals', 'media'
|
||||
'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at', 'attachment', 'discount', 'items', 'histories', 'payments', 'totals', 'media', 'paid'
|
||||
]));
|
||||
});
|
||||
|
||||
@ -623,6 +370,7 @@ class Invoices extends Controller
|
||||
unset($invoice->paid);
|
||||
unset($invoice->template_path);
|
||||
unset($invoice->pdf_path);
|
||||
unset($invoice->reconciled);
|
||||
|
||||
// Mark invoice as sent
|
||||
if ($invoice->invoice_status_code != 'partial') {
|
||||
@ -670,7 +418,9 @@ class Invoices extends Controller
|
||||
{
|
||||
$invoice = $this->prepareInvoice($invoice);
|
||||
|
||||
$html = view($invoice->template_path, compact('invoice'))->render();
|
||||
$currency_style = true;
|
||||
|
||||
$html = view($invoice->template_path, compact('invoice', 'currency_style'))->render();
|
||||
|
||||
$pdf = app('dompdf.wrapper');
|
||||
$pdf->loadHTML($html);
|
||||
@ -789,20 +539,7 @@ class Invoices extends Controller
|
||||
|
||||
$invoice->save();
|
||||
|
||||
$invoice_payment_request = [
|
||||
'company_id' => $request['company_id'],
|
||||
'invoice_id' => $request['invoice_id'],
|
||||
'account_id' => $request['account_id'],
|
||||
'paid_at' => $request['paid_at'],
|
||||
'amount' => $request['amount'],
|
||||
'currency_code' => $request['currency_code'],
|
||||
'currency_rate' => $request['currency_rate'],
|
||||
'description' => $request['description'],
|
||||
'payment_method' => $request['payment_method'],
|
||||
'reference' => $request['reference']
|
||||
];
|
||||
|
||||
$invoice_payment = InvoicePayment::create($invoice_payment_request);
|
||||
$invoice_payment = dispatch(new CreateInvoicePayment($request, $invoice));
|
||||
|
||||
// Upload attachment
|
||||
if ($request->file('attachment')) {
|
||||
@ -811,15 +548,6 @@ class Invoices extends Controller
|
||||
$invoice_payment->attachMedia($media, 'attachment');
|
||||
}
|
||||
|
||||
$request['status_code'] = $invoice->invoice_status_code;
|
||||
$request['notify'] = 0;
|
||||
|
||||
$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.payments', 1)]);
|
||||
|
||||
return response()->json([
|
||||
@ -928,64 +656,4 @@ class Invoices extends Controller
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
protected function addTotals($invoice, $request, $taxes, $sub_total, $discount_total, $tax_total)
|
||||
{
|
||||
$sort_order = 1;
|
||||
|
||||
// Added invoice sub total
|
||||
InvoiceTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'invoice_id' => $invoice->id,
|
||||
'code' => 'sub_total',
|
||||
'name' => 'invoices.sub_total',
|
||||
'amount' => $sub_total,
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
|
||||
$sort_order++;
|
||||
|
||||
// Added invoice discount
|
||||
if ($discount_total) {
|
||||
InvoiceTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'invoice_id' => $invoice->id,
|
||||
'code' => 'discount',
|
||||
'name' => 'invoices.discount',
|
||||
'amount' => $discount_total,
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
|
||||
// This is for total
|
||||
$sub_total = $sub_total - $discount_total;
|
||||
}
|
||||
|
||||
$sort_order++;
|
||||
|
||||
// Added invoice taxes
|
||||
if ($taxes) {
|
||||
foreach ($taxes as $tax) {
|
||||
InvoiceTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'invoice_id' => $invoice->id,
|
||||
'code' => 'tax',
|
||||
'name' => $tax['name'],
|
||||
'amount' => $tax['amount'],
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
|
||||
$sort_order++;
|
||||
}
|
||||
}
|
||||
|
||||
// Added invoice total
|
||||
InvoiceTotal::create([
|
||||
'company_id' => $request['company_id'],
|
||||
'invoice_id' => $invoice->id,
|
||||
'code' => 'total',
|
||||
'name' => 'invoices.total',
|
||||
'amount' => $sub_total + $tax_total,
|
||||
'sort_order' => $sort_order,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -29,14 +29,11 @@ class Revenues extends Controller
|
||||
{
|
||||
$revenues = Revenue::with(['account', 'category', 'customer'])->isNotTransfer()->collect(['paid_at'=> 'desc']);
|
||||
|
||||
$customers = collect(Customer::enabled()->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.customers', 2)]), '');
|
||||
$customers = collect(Customer::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$categories = collect(Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.categories', 2)]), '');
|
||||
$categories = collect(Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'))
|
||||
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
|
||||
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'));
|
||||
|
||||
$transfer_cat_id = Category::transfer();
|
||||
|
||||
@ -66,7 +63,7 @@ class Revenues extends Controller
|
||||
|
||||
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
|
||||
|
||||
$currency = Currency::where('code', '=', $account_currency_code)->first();
|
||||
$currency = Currency::where('code', $account_currency_code)->first();
|
||||
|
||||
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -156,9 +153,7 @@ class Revenues extends Controller
|
||||
|
||||
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
|
||||
|
||||
$account_currency_code = Account::where('id', $revenue->account_id)->pluck('currency_code')->first();
|
||||
|
||||
$currency = Currency::where('code', '=', $account_currency_code)->first();
|
||||
$currency = Currency::where('code', $revenue->currency_code)->first();
|
||||
|
||||
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
|
||||
|
||||
@ -166,7 +161,7 @@ class Revenues extends Controller
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods();
|
||||
|
||||
return view('incomes.revenues.edit', compact('revenue', 'accounts', 'currencies', 'account_currency_code', 'currency', 'customers', 'categories', 'payment_methods'));
|
||||
return view('incomes.revenues.edit', compact('revenue', 'accounts', 'currencies', 'currency', 'customers', 'categories', 'payment_methods'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,8 +6,10 @@ use App\Http\Controllers\Controller;
|
||||
use App\Events\UpdateFinished;
|
||||
use App\Utilities\Updater;
|
||||
use App\Utilities\Versions;
|
||||
use Illuminate\Http\Request;
|
||||
use Artisan;
|
||||
use Module;
|
||||
use File;
|
||||
|
||||
class Updates extends Controller
|
||||
{
|
||||
@ -80,15 +82,20 @@ class Updates extends Controller
|
||||
*/
|
||||
public function update($alias, $version)
|
||||
{
|
||||
set_time_limit(600); // 10 minutes
|
||||
if ($alias == 'core') {
|
||||
$name = 'Akaunting v' . $version;
|
||||
|
||||
if (Updater::update($alias, $version)) {
|
||||
return redirect('install/updates/post/' . $alias . '/' . version('short') . '/' . $version);
|
||||
$installed = version('short');
|
||||
} else {
|
||||
// Get module instance
|
||||
$module = Module::findByAlias($alias);
|
||||
|
||||
$name = $module->get('name');
|
||||
|
||||
$installed = $module->get('version');
|
||||
}
|
||||
|
||||
flash(trans('updates.error'))->error()->important();
|
||||
|
||||
return redirect()->back();
|
||||
return view('install.updates.edit', compact('alias', 'name', 'installed', 'version'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,4 +124,229 @@ class Updates extends Controller
|
||||
|
||||
return redirect('install/updates');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function steps(Request $request)
|
||||
{
|
||||
$json = [];
|
||||
$json['step'] = [];
|
||||
|
||||
$name = $request['name'];
|
||||
$version = $request['version'];
|
||||
|
||||
// Download
|
||||
$json['step'][] = [
|
||||
'text' => trans('modules.installation.download', ['module' => $name]),
|
||||
'url' => url('install/updates/download')
|
||||
];
|
||||
|
||||
// Unzip
|
||||
$json['step'][] = [
|
||||
'text' => trans('modules.installation.unzip', ['module' => $name]),
|
||||
'url' => url('install/updates/unzip')
|
||||
];
|
||||
|
||||
// File Copy
|
||||
$json['step'][] = [
|
||||
'text' => trans('modules.installation.file_copy', ['module' => $name]),
|
||||
'url' => url('install/updates/file-copy')
|
||||
];
|
||||
|
||||
// Migrate DB and trigger event UpdateFinish event
|
||||
$json['step'][] = [
|
||||
'text' => trans('modules.installation.migrate', ['module' => $name]),
|
||||
'url' => url('install/updates/migrate')
|
||||
];
|
||||
|
||||
// redirect update page
|
||||
$json['step'][] = [
|
||||
'text' => trans('modules.installation.finish'),
|
||||
'url' => url('install/updates/finish')
|
||||
];
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function download(Request $request)
|
||||
{
|
||||
set_time_limit(600); // 10 minutes
|
||||
|
||||
$status = true;
|
||||
|
||||
if ($request['alias'] != 'core') {
|
||||
$this->checkApiToken();
|
||||
}
|
||||
|
||||
// Download file
|
||||
if (!$data = Updater::download($request['alias'], $request['version'])) {
|
||||
$status = false;
|
||||
|
||||
$message = trans('modules.errors.download', ['module' => $request['name']]);
|
||||
}
|
||||
|
||||
// Create temp directory
|
||||
$path = 'temp-' . md5(mt_rand());
|
||||
$temp_path = storage_path('app/temp') . '/' . $path;
|
||||
|
||||
if (!File::isDirectory($temp_path)) {
|
||||
File::makeDirectory($temp_path);
|
||||
}
|
||||
|
||||
$file = $temp_path . '/upload.zip';
|
||||
|
||||
// Add content to the Zip file
|
||||
$uploaded = is_int(file_put_contents($file, $data)) ? true : false;
|
||||
|
||||
if (!$uploaded) {
|
||||
$status = false;
|
||||
|
||||
$message = trans('modules.errors.upload', ['module' => $request['name']]);
|
||||
}
|
||||
|
||||
$json = [
|
||||
'success' => ($status) ? true : false,
|
||||
'errors' => (!$status) ? $message : false,
|
||||
'data' => [
|
||||
'path' => $path
|
||||
]
|
||||
];
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function unzip(Request $request)
|
||||
{
|
||||
set_time_limit(600); // 10 minutes
|
||||
|
||||
if ($request['alias'] != 'core') {
|
||||
$this->checkApiToken();
|
||||
}
|
||||
|
||||
$path = storage_path('app/temp') . '/' . $request['path'];
|
||||
|
||||
$file = $path . '/upload.zip';
|
||||
|
||||
$result = Updater::unzip($file, $path);
|
||||
|
||||
$json = [
|
||||
'success' => ($result) ? true : false,
|
||||
'errors' => (!$result) ? trans('modules.errors.unzip', ['module' => $request['name']]) : false,
|
||||
'data' => [
|
||||
'path' => $request['path']
|
||||
]
|
||||
];
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function fileCopy(Request $request)
|
||||
{
|
||||
set_time_limit(600); // 10 minutes
|
||||
|
||||
if ($request['alias'] != 'core') {
|
||||
$this->checkApiToken();
|
||||
}
|
||||
|
||||
$path = storage_path('app/temp') . '/' . $request['path'];
|
||||
|
||||
$result = Updater::fileCopy($request['alias'], $path, $request['version']);
|
||||
|
||||
$json = [
|
||||
'success' => ($result) ? true : false,
|
||||
'errors' => (!$result) ? trans('modules.errors.file_copy', ['module' => $request['name']]) : false,
|
||||
'data' => [
|
||||
'path' => $request['path']
|
||||
]
|
||||
];
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function migrate(Request $request)
|
||||
{
|
||||
// Check if the file mirror was successful
|
||||
if (($request['alias'] == 'core') && (version('short') != $request['version'])) {
|
||||
$json = [
|
||||
'success' => false,
|
||||
'errors' => trans('modules.errors.migrate core', ['module' => $request['name']]),
|
||||
'data' => []
|
||||
];
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
// Clear cache after update
|
||||
Artisan::call('cache:clear');
|
||||
|
||||
try {
|
||||
event(new UpdateFinished($request['alias'], $request['installed'], $request['version']));
|
||||
|
||||
$json = [
|
||||
'success' => true,
|
||||
'errors' => false,
|
||||
'data' => []
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
$json = [
|
||||
'success' => false,
|
||||
'errors' => trans('modules.errors.migrate', ['module' => $request['name']]),
|
||||
'data' => []
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function finish(Request $request)
|
||||
{
|
||||
$json = [
|
||||
'success' => true,
|
||||
'errors' => false,
|
||||
'redirect' => url("install/updates"),
|
||||
'data' => [],
|
||||
];
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ class BillPayments extends Controller
|
||||
|
||||
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
|
||||
|
||||
$currency = Currency::where('code', setting('general.default_currency'))->first();
|
||||
|
||||
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
|
||||
|
||||
$currency = Currency::where('code', $account_currency_code)->first();
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods();
|
||||
|
||||
$bill->paid = $this->getPaid($bill);
|
||||
@ -52,7 +52,9 @@ class BillPayments extends Controller
|
||||
$bill->{$bill_total->code} = $bill_total->amount;
|
||||
}
|
||||
|
||||
$bill->grand_total = $bill->total;
|
||||
$total = money($bill->total, $currency->code, true)->format();
|
||||
|
||||
$bill->grand_total = money($total, $currency->code)->getAmount();
|
||||
|
||||
if (!empty($paid)) {
|
||||
$bill->grand_total = $bill->total - $paid;
|
||||
|
@ -52,7 +52,9 @@ class InvoicePayments extends Controller
|
||||
$invoice->{$invoice_total->code} = $invoice_total->amount;
|
||||
}
|
||||
|
||||
$invoice->grand_total = $invoice->total;
|
||||
$total = money($invoice->total, $currency->code, true)->format();
|
||||
|
||||
$invoice->grand_total = money($total, $currency->code)->getAmount();
|
||||
|
||||
if (!empty($paid)) {
|
||||
$invoice->grand_total = $invoice->total - $paid;
|
||||
@ -147,7 +149,7 @@ class InvoicePayments extends Controller
|
||||
$error_amount = (double) $convert_amount->getDynamicConvertedAmount();
|
||||
}
|
||||
|
||||
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $request['currency_code'],true)]);
|
||||
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $request['currency_code'], true)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
|
69
app/Http/Controllers/Modals/Taxes.php
Normal file
69
app/Http/Controllers/Modals/Taxes.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Modals;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Setting\Tax as Request;
|
||||
use App\Models\Setting\Tax;
|
||||
|
||||
class Taxes extends Controller
|
||||
{
|
||||
/**
|
||||
* Instantiate a new controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Add CRUD permission check
|
||||
$this->middleware('permission:create-settings-taxes')->only(['create', 'store']);
|
||||
$this->middleware('permission:read-settings-taxes')->only(['index', 'edit']);
|
||||
$this->middleware('permission:update-settings-taxes')->only(['update', 'enable', 'disable']);
|
||||
$this->middleware('permission:delete-settings-taxes')->only('destroy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$types = [
|
||||
'normal' => trans('taxes.normal'),
|
||||
'inclusive' => trans('taxes.inclusive'),
|
||||
'compound' => trans('taxes.compound'),
|
||||
];
|
||||
|
||||
$html = view('modals.taxes.create', compact('types'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => 'null',
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request['enabled'] = 1;
|
||||
|
||||
$tax = Tax::create($request->all());
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.taxes', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'data' => $tax,
|
||||
'message' => $message,
|
||||
'html' => 'null',
|
||||
]);
|
||||
}
|
||||
}
|
@ -67,7 +67,7 @@ class Item extends Controller
|
||||
$module->action_url .= $character . http_build_query($parameters);
|
||||
}
|
||||
|
||||
return view('modules.item.show', compact('module', 'about', 'installed', 'enable'));
|
||||
return view('modules.item.show', compact('module', 'installed', 'enable'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,4 +302,42 @@ class Item extends Controller
|
||||
|
||||
return redirect('apps/' . $alias);
|
||||
}
|
||||
|
||||
public function reviews($alias, Request $request)
|
||||
{
|
||||
$page = $request['page'];
|
||||
|
||||
$data = [
|
||||
'query' => [
|
||||
'page' => ($page) ? $page : 1,
|
||||
]
|
||||
];
|
||||
|
||||
$reviews = $this->getModuleReviews($alias, $data);
|
||||
|
||||
$html = view('partials.modules.reviews', compact('reviews'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'data' => null,
|
||||
'message' => null,
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
public function documentation($alias)
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$documentation = $this->getDocumentation($alias);
|
||||
|
||||
if (empty($documentation)) {
|
||||
return redirect('apps/' . $alias)->send();
|
||||
}
|
||||
|
||||
$back = 'apps/' . $alias;
|
||||
|
||||
return view('modules.item.documentation', compact('documentation', 'back'));
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,15 @@ class Tiles extends Controller
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$data = $this->getModulesByCategory($alias);
|
||||
$page = request('page', 1);
|
||||
|
||||
$request = [
|
||||
'query' => [
|
||||
'page' => $page,
|
||||
]
|
||||
];
|
||||
|
||||
$data = $this->getModulesByCategory($alias, $request);
|
||||
|
||||
$title = $data->category->name;
|
||||
$modules = $data->modules;
|
||||
@ -32,6 +40,34 @@ class Tiles extends Controller
|
||||
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
* @param $alias
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function vendorModules($alias)
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$page = request('page', 1);
|
||||
|
||||
$request = [
|
||||
'query' => [
|
||||
'page' => $page,
|
||||
]
|
||||
];
|
||||
|
||||
$data = $this->getModulesByVendor($alias, $request);
|
||||
|
||||
$title = $data->vendor->name;
|
||||
$modules = $data->modules;
|
||||
$installed = Module::all()->pluck('status', 'alias')->toArray();
|
||||
|
||||
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for viewing the specified resource.
|
||||
*
|
||||
@ -41,8 +77,16 @@ class Tiles extends Controller
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$page = request('page', 1);
|
||||
|
||||
$data = [
|
||||
'query' => [
|
||||
'page' => $page,
|
||||
]
|
||||
];
|
||||
|
||||
$title = trans('modules.top_paid');
|
||||
$modules = $this->getPaidModules();
|
||||
$modules = $this->getPaidModules($data);
|
||||
$installed = Module::all()->pluck('status', 'alias')->toArray();
|
||||
|
||||
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
|
||||
@ -57,8 +101,16 @@ class Tiles extends Controller
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$page = request('page', 1);
|
||||
|
||||
$data = [
|
||||
'query' => [
|
||||
'page' => $page,
|
||||
]
|
||||
];
|
||||
|
||||
$title = trans('modules.new');
|
||||
$modules = $this->getNewModules();
|
||||
$modules = $this->getNewModules($data);
|
||||
$installed = Module::all()->pluck('status', 'alias')->toArray();
|
||||
|
||||
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
|
||||
@ -73,8 +125,16 @@ class Tiles extends Controller
|
||||
{
|
||||
$this->checkApiToken();
|
||||
|
||||
$page = request('page', 1);
|
||||
|
||||
$data = [
|
||||
'query' => [
|
||||
'page' => $page,
|
||||
]
|
||||
];
|
||||
|
||||
$title = trans('modules.top_free');
|
||||
$modules = $this->getFreeModules();
|
||||
$modules = $this->getFreeModules($data);
|
||||
$installed = Module::all()->pluck('status', 'alias')->toArray();
|
||||
|
||||
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
|
||||
@ -90,10 +150,12 @@ class Tiles extends Controller
|
||||
$this->checkApiToken();
|
||||
|
||||
$keyword = $request['keyword'];
|
||||
$page = request('page', 1);
|
||||
|
||||
$data = [
|
||||
'query' => [
|
||||
'keyword' => $keyword,
|
||||
'page' => $page,
|
||||
]
|
||||
];
|
||||
|
||||
|
@ -3,10 +3,13 @@
|
||||
namespace App\Http\Controllers\Reports;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Expense\Bill;
|
||||
use App\Models\Expense\BillPayment;
|
||||
use App\Models\Expense\Payment;
|
||||
use App\Models\Expense\Vendor;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Utilities\Recurring;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
@ -22,13 +25,16 @@ class ExpenseSummary extends Controller
|
||||
$dates = $totals = $expenses = $expenses_graph = $categories = [];
|
||||
|
||||
$status = request('status');
|
||||
$year = request('year', Date::now()->year);
|
||||
|
||||
$categories = Category::enabled()->type('expense')->pluck('name', 'id')->toArray();
|
||||
$categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
|
||||
// Get year
|
||||
$year = request('year');
|
||||
if (empty($year)) {
|
||||
$year = Date::now()->year;
|
||||
if ($categories_filter = request('categories')) {
|
||||
$cats = collect($categories)->filter(function ($value, $key) use ($categories_filter) {
|
||||
return in_array($key, $categories_filter);
|
||||
});
|
||||
} else {
|
||||
$cats = $categories;
|
||||
}
|
||||
|
||||
// Dates
|
||||
@ -44,7 +50,7 @@ class ExpenseSummary extends Controller
|
||||
'currency_rate' => 1
|
||||
);
|
||||
|
||||
foreach ($categories as $category_id => $category_name) {
|
||||
foreach ($cats as $category_id => $category_name) {
|
||||
$expenses[$category_id][$dates[$j]] = array(
|
||||
'category_id' => $category_id,
|
||||
'name' => $category_name,
|
||||
@ -55,27 +61,47 @@ class ExpenseSummary extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Bills
|
||||
$payments = Payment::monthsOfYear('paid_at')->account(request('accounts'))->vendor(request('vendors'))->isNotTransfer()->get();
|
||||
|
||||
switch ($status) {
|
||||
case 'paid':
|
||||
$bills = BillPayment::monthsOfYear('paid_at')->get();
|
||||
// Bills
|
||||
$bills = BillPayment::monthsOfYear('paid_at')->account(request('accounts'))->get();
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'paid_at');
|
||||
|
||||
// Payments
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $payments, 'payment', 'paid_at');
|
||||
break;
|
||||
case 'upcoming':
|
||||
$bills = Bill::accrued()->monthsOfYear('due_at')->get();
|
||||
// Bills
|
||||
$bills = Bill::accrued()->monthsOfYear('due_at')->vendor(request('vendors'))->get();
|
||||
Recurring::reflect($bills, 'bill', 'billed_at', $status);
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'due_at');
|
||||
|
||||
// Payments
|
||||
Recurring::reflect($payments, 'payment', 'paid_at', $status);
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $payments, 'payment', 'paid_at');
|
||||
break;
|
||||
default:
|
||||
$bills = Bill::accrued()->monthsOfYear('billed_at')->get();
|
||||
// Bills
|
||||
$bills = Bill::accrued()->monthsOfYear('billed_at')->vendor(request('vendors'))->get();
|
||||
Recurring::reflect($bills, 'bill', 'billed_at', $status);
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $bills, 'bill', 'billed_at');
|
||||
|
||||
// Payments
|
||||
Recurring::reflect($payments, 'payment', 'paid_at', $status);
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $payments, 'payment', 'paid_at');
|
||||
break;
|
||||
}
|
||||
|
||||
// Payments
|
||||
if ($status != 'upcoming') {
|
||||
$payments = Payment::monthsOfYear('paid_at')->isNotTransfer()->get();
|
||||
$this->setAmount($expenses_graph, $totals, $expenses, $payments, 'payment', 'paid_at');
|
||||
}
|
||||
$statuses = collect([
|
||||
'all' => trans('general.all'),
|
||||
'paid' => trans('invoices.paid'),
|
||||
'upcoming' => trans('dashboard.payables'),
|
||||
]);
|
||||
|
||||
$accounts = Account::enabled()->pluck('name', 'id')->toArray();
|
||||
$vendors = Vendor::enabled()->pluck('name', 'id')->toArray();
|
||||
|
||||
// Check if it's a print or normal request
|
||||
if (request('print')) {
|
||||
@ -86,6 +112,8 @@ class ExpenseSummary extends Controller
|
||||
$view_template = 'reports.expense_summary.index';
|
||||
}
|
||||
|
||||
$print_url = $this->getPrintUrl($year);
|
||||
|
||||
// Expenses chart
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
@ -95,21 +123,49 @@ class ExpenseSummary extends Controller
|
||||
->credits(false)
|
||||
->view($chart_template);
|
||||
|
||||
return view($view_template, compact('chart', 'dates', 'categories', 'expenses', 'totals'));
|
||||
return view($view_template, compact(
|
||||
'chart',
|
||||
'dates',
|
||||
'categories',
|
||||
'statuses',
|
||||
'accounts',
|
||||
'vendors',
|
||||
'expenses',
|
||||
'totals',
|
||||
'print_url'
|
||||
));
|
||||
}
|
||||
|
||||
private function setAmount(&$graph, &$totals, &$expenses, $items, $type, $date_field)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($item['table'] == 'bill_payments') {
|
||||
$bill = $item->bill;
|
||||
switch ($item->getTable()) {
|
||||
case 'bill_payments':
|
||||
$bill = $item->bill;
|
||||
|
||||
$item->category_id = $bill->category_id;
|
||||
if ($vendors = request('vendors')) {
|
||||
if (!in_array($bill->vendor_id, $vendors)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$item->category_id = $bill->category_id;
|
||||
break;
|
||||
case 'bills':
|
||||
if ($accounts = request('accounts')) {
|
||||
foreach ($item->payments as $payment) {
|
||||
if (!in_array($payment->account_id, $accounts)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$date = Date::parse($item->$date_field)->format('F');
|
||||
$month = Date::parse($item->$date_field)->format('F');
|
||||
$month_year = Date::parse($item->$date_field)->format('F-Y');
|
||||
|
||||
if (!isset($expenses[$item->category_id])) {
|
||||
if (!isset($expenses[$item->category_id]) || !isset($expenses[$item->category_id][$month]) || !isset($graph[$month_year])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -122,13 +178,34 @@ class ExpenseSummary extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$expenses[$item->category_id][$date]['amount'] += $amount;
|
||||
$expenses[$item->category_id][$date]['currency_code'] = $item->currency_code;
|
||||
$expenses[$item->category_id][$date]['currency_rate'] = $item->currency_rate;
|
||||
$expenses[$item->category_id][$month]['amount'] += $amount;
|
||||
$expenses[$item->category_id][$month]['currency_code'] = $item->currency_code;
|
||||
$expenses[$item->category_id][$month]['currency_rate'] = $item->currency_rate;
|
||||
|
||||
$graph[Date::parse($item->$date_field)->format('F-Y')] += $amount;
|
||||
$graph[$month_year] += $amount;
|
||||
|
||||
$totals[$date]['amount'] += $amount;
|
||||
$totals[$month]['amount'] += $amount;
|
||||
}
|
||||
}
|
||||
|
||||
private function getPrintUrl($year)
|
||||
{
|
||||
$print_url = 'reports/expense-summary?print=1'
|
||||
. '&status=' . request('status')
|
||||
. '&year='. request('year', $year);
|
||||
|
||||
collect(request('accounts'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&accounts[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('vendors'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&vendors[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('categories'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&categories[]=' . $item;
|
||||
});
|
||||
|
||||
return $print_url;
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,17 @@
|
||||
namespace App\Http\Controllers\Reports;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Income\Customer;
|
||||
use App\Models\Income\Invoice;
|
||||
use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\Revenue;
|
||||
use App\Models\Expense\Bill;
|
||||
use App\Models\Expense\BillPayment;
|
||||
use App\Models\Expense\Payment;
|
||||
use App\Models\Expense\Vendor;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Utilities\Recurring;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
@ -25,16 +29,16 @@ class IncomeExpenseSummary extends Controller
|
||||
$dates = $totals = $compares = $profit_graph = $categories = [];
|
||||
|
||||
$status = request('status');
|
||||
$year = request('year', Date::now()->year);
|
||||
$categories_filter = request('categories');
|
||||
|
||||
$income_categories = Category::enabled()->type('income')->pluck('name', 'id')->toArray();
|
||||
$income_categories = Category::enabled()->type('income')->when($categories_filter, function ($query) use ($categories_filter) {
|
||||
return $query->whereIn('id', $categories_filter);
|
||||
})->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
|
||||
$expense_categories = Category::enabled()->type('expense')->pluck('name', 'id')->toArray();
|
||||
|
||||
// Get year
|
||||
$year = request('year');
|
||||
if (empty($year)) {
|
||||
$year = Date::now()->year;
|
||||
}
|
||||
$expense_categories = Category::enabled()->type('expense')->when($categories_filter, function ($query) use ($categories_filter) {
|
||||
return $query->whereIn('id', $categories_filter);
|
||||
})->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
|
||||
// Dates
|
||||
for ($j = 1; $j <= 12; $j++) {
|
||||
@ -70,49 +74,75 @@ class IncomeExpenseSummary extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Invoices
|
||||
$revenues = Revenue::monthsOfYear('paid_at')->account(request('accounts'))->customer(request('customers'))->isNotTransfer()->get();
|
||||
$payments = Payment::monthsOfYear('paid_at')->account(request('accounts'))->vendor(request('vendors'))->isNotTransfer()->get();
|
||||
|
||||
switch ($status) {
|
||||
case 'paid':
|
||||
$invoices = InvoicePayment::monthsOfYear('paid_at')->get();
|
||||
// Invoices
|
||||
$invoices = InvoicePayment::monthsOfYear('paid_at')->account(request('accounts'))->get();
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'paid_at');
|
||||
break;
|
||||
case 'upcoming':
|
||||
$invoices = Invoice::accrued()->monthsOfYear('due_at')->get();
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'due_at');
|
||||
break;
|
||||
default:
|
||||
$invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->get();
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'invoiced_at');
|
||||
break;
|
||||
}
|
||||
|
||||
// Revenues
|
||||
if ($status != 'upcoming') {
|
||||
$revenues = Revenue::monthsOfYear('paid_at')->isNotTransfer()->get();
|
||||
$this->setAmount($profit_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
|
||||
}
|
||||
// Revenues
|
||||
$this->setAmount($profit_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
|
||||
|
||||
// Bills
|
||||
switch ($status) {
|
||||
case 'paid':
|
||||
$bills = BillPayment::monthsOfYear('paid_at')->get();
|
||||
// Bills
|
||||
$bills = BillPayment::monthsOfYear('paid_at')->account(request('accounts'))->get();
|
||||
$this->setAmount($profit_graph, $totals, $compares, $bills, 'bill', 'paid_at');
|
||||
|
||||
// Payments
|
||||
$this->setAmount($profit_graph, $totals, $compares, $payments, 'payment', 'paid_at');
|
||||
break;
|
||||
case 'upcoming':
|
||||
$bills = Bill::accrued()->monthsOfYear('due_at')->get();
|
||||
// Invoices
|
||||
$invoices = Invoice::accrued()->monthsOfYear('due_at')->customer(request('customers'))->get();
|
||||
Recurring::reflect($invoices, 'invoice', 'due_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'due_at');
|
||||
|
||||
// Revenues
|
||||
Recurring::reflect($revenues, 'revenue', 'paid_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
|
||||
|
||||
// Bills
|
||||
$bills = Bill::accrued()->monthsOfYear('due_at')->vendor(request('vendors'))->get();
|
||||
Recurring::reflect($bills, 'bill', 'billed_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $bills, 'bill', 'due_at');
|
||||
|
||||
// Payments
|
||||
Recurring::reflect($payments, 'payment', 'paid_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $payments, 'payment', 'paid_at');
|
||||
break;
|
||||
default:
|
||||
$bills = Bill::accrued()->monthsOfYear('billed_at')->get();
|
||||
// Invoices
|
||||
$invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->customer(request('customers'))->get();
|
||||
Recurring::reflect($invoices, 'invoice', 'invoiced_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'invoiced_at');
|
||||
|
||||
// Revenues
|
||||
Recurring::reflect($revenues, 'revenue', 'paid_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
|
||||
|
||||
// Bills
|
||||
$bills = Bill::accrued()->monthsOfYear('billed_at')->vendor(request('vendors'))->get();
|
||||
Recurring::reflect($bills, 'bill', 'billed_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $bills, 'bill', 'billed_at');
|
||||
|
||||
// Payments
|
||||
Recurring::reflect($payments, 'payment', 'paid_at', $status);
|
||||
$this->setAmount($profit_graph, $totals, $compares, $payments, 'payment', 'paid_at');
|
||||
break;
|
||||
}
|
||||
|
||||
// Payments
|
||||
if ($status != 'upcoming') {
|
||||
$payments = Payment::monthsOfYear('paid_at')->isNotTransfer()->get();
|
||||
$this->setAmount($profit_graph, $totals, $compares, $payments, 'payment', 'paid_at');
|
||||
}
|
||||
|
||||
$statuses = collect([
|
||||
'all' => trans('general.all'),
|
||||
'paid' => trans('invoices.paid'),
|
||||
'upcoming' => trans('general.upcoming'),
|
||||
]);
|
||||
|
||||
$accounts = Account::enabled()->pluck('name', 'id')->toArray();
|
||||
$customers = Customer::enabled()->pluck('name', 'id')->toArray();
|
||||
$vendors = Vendor::enabled()->pluck('name', 'id')->toArray();
|
||||
$categories = Category::enabled()->type(['income', 'expense'])->pluck('name', 'id')->toArray();
|
||||
|
||||
// Check if it's a print or normal request
|
||||
if (request('print')) {
|
||||
@ -123,6 +153,8 @@ class IncomeExpenseSummary extends Controller
|
||||
$view_template = 'reports.income_expense_summary.index';
|
||||
}
|
||||
|
||||
$print_url = $this->getPrintUrl($year);
|
||||
|
||||
// Profit chart
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
@ -132,23 +164,72 @@ class IncomeExpenseSummary extends Controller
|
||||
->credits(false)
|
||||
->view($chart_template);
|
||||
|
||||
return view($view_template, compact('chart', 'dates', 'income_categories', 'expense_categories', 'compares', 'totals'));
|
||||
return view($view_template, compact(
|
||||
'chart',
|
||||
'dates',
|
||||
'income_categories',
|
||||
'expense_categories',
|
||||
'categories',
|
||||
'statuses',
|
||||
'accounts',
|
||||
'customers',
|
||||
'vendors',
|
||||
'compares',
|
||||
'totals',
|
||||
'print_url'
|
||||
));
|
||||
}
|
||||
|
||||
private function setAmount(&$graph, &$totals, &$compares, $items, $type, $date_field)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($item['table'] == 'bill_payments' || $item['table'] == 'invoice_payments') {
|
||||
if ($item->getTable() == 'bill_payments' || $item->getTable() == 'invoice_payments') {
|
||||
$type_item = $item->$type;
|
||||
|
||||
$item->category_id = $type_item->category_id;
|
||||
}
|
||||
|
||||
$date = Date::parse($item->$date_field)->format('F');
|
||||
switch ($item->getTable()) {
|
||||
case 'invoice_payments':
|
||||
$invoice = $item->invoice;
|
||||
|
||||
if ($customers = request('customers')) {
|
||||
if (!in_array($invoice->customer_id, $customers)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$item->category_id = $invoice->category_id;
|
||||
break;
|
||||
case 'bill_payments':
|
||||
$bill = $item->bill;
|
||||
|
||||
if ($vendors = request('vendors')) {
|
||||
if (!in_array($bill->vendor_id, $vendors)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$item->category_id = $bill->category_id;
|
||||
break;
|
||||
case 'invoices':
|
||||
case 'bills':
|
||||
if ($accounts = request('accounts')) {
|
||||
foreach ($item->payments as $payment) {
|
||||
if (!in_array($payment->account_id, $accounts)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$month = Date::parse($item->$date_field)->format('F');
|
||||
$month_year = Date::parse($item->$date_field)->format('F-Y');
|
||||
|
||||
$group = (($type == 'invoice') || ($type == 'revenue')) ? 'income' : 'expense';
|
||||
|
||||
if (!isset($compares[$group][$item->category_id])) {
|
||||
if (!isset($compares[$group][$item->category_id]) || !isset($compares[$group][$item->category_id][$month]) || !isset($graph[$month_year])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -161,19 +242,44 @@ class IncomeExpenseSummary extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$compares[$group][$item->category_id][$date]['amount'] += $amount;
|
||||
$compares[$group][$item->category_id][$date]['currency_code'] = $item->currency_code;
|
||||
$compares[$group][$item->category_id][$date]['currency_rate'] = $item->currency_rate;
|
||||
$compares[$group][$item->category_id][$month]['amount'] += $amount;
|
||||
$compares[$group][$item->category_id][$month]['currency_code'] = $item->currency_code;
|
||||
$compares[$group][$item->category_id][$month]['currency_rate'] = $item->currency_rate;
|
||||
|
||||
if ($group == 'income') {
|
||||
$graph[Date::parse($item->$date_field)->format('F-Y')] += $amount;
|
||||
$graph[$month_year] += $amount;
|
||||
|
||||
$totals[$date]['amount'] += $amount;
|
||||
$totals[$month]['amount'] += $amount;
|
||||
} else {
|
||||
$graph[Date::parse($item->$date_field)->format('F-Y')] -= $amount;
|
||||
$graph[$month_year] -= $amount;
|
||||
|
||||
$totals[$date]['amount'] -= $amount;
|
||||
$totals[$month]['amount'] -= $amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getPrintUrl($year)
|
||||
{
|
||||
$print_url = 'reports/income-expense-summary?print=1'
|
||||
. '&status=' . request('status')
|
||||
. '&year='. request('year', $year);
|
||||
|
||||
collect(request('accounts'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&accounts[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('customers'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&customers[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('vendors'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&vendors[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('categories'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&categories[]=' . $item;
|
||||
});
|
||||
|
||||
return $print_url;
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,13 @@
|
||||
namespace App\Http\Controllers\Reports;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Income\Customer;
|
||||
use App\Models\Income\Invoice;
|
||||
use App\Models\Income\InvoicePayment;
|
||||
use App\Models\Income\Revenue;
|
||||
use App\Models\Setting\Category;
|
||||
use App\Utilities\Recurring;
|
||||
use Charts;
|
||||
use Date;
|
||||
|
||||
@ -22,13 +25,16 @@ class IncomeSummary extends Controller
|
||||
$dates = $totals = $incomes = $incomes_graph = $categories = [];
|
||||
|
||||
$status = request('status');
|
||||
$year = request('year', Date::now()->year);
|
||||
|
||||
$categories = Category::enabled()->type('income')->pluck('name', 'id')->toArray();
|
||||
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
|
||||
// Get year
|
||||
$year = request('year');
|
||||
if (empty($year)) {
|
||||
$year = Date::now()->year;
|
||||
if ($categories_filter = request('categories')) {
|
||||
$cats = collect($categories)->filter(function ($value, $key) use ($categories_filter) {
|
||||
return in_array($key, $categories_filter);
|
||||
});
|
||||
} else {
|
||||
$cats = $categories;
|
||||
}
|
||||
|
||||
// Dates
|
||||
@ -44,38 +50,58 @@ class IncomeSummary extends Controller
|
||||
'currency_rate' => 1
|
||||
);
|
||||
|
||||
foreach ($categories as $category_id => $category_name) {
|
||||
$incomes[$category_id][$dates[$j]] = array(
|
||||
foreach ($cats as $category_id => $category_name) {
|
||||
$incomes[$category_id][$dates[$j]] = [
|
||||
'category_id' => $category_id,
|
||||
'name' => $category_name,
|
||||
'amount' => 0,
|
||||
'currency_code' => setting('general.default_currency'),
|
||||
'currency_rate' => 1
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Invoices
|
||||
$revenues = Revenue::monthsOfYear('paid_at')->account(request('accounts'))->customer(request('customers'))->isNotTransfer()->get();
|
||||
|
||||
switch ($status) {
|
||||
case 'paid':
|
||||
$invoices = InvoicePayment::monthsOfYear('paid_at')->get();
|
||||
// Invoices
|
||||
$invoices = InvoicePayment::monthsOfYear('paid_at')->account(request('accounts'))->get();
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'paid_at');
|
||||
|
||||
// Revenues
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $revenues, 'revenue', 'paid_at');
|
||||
break;
|
||||
case 'upcoming':
|
||||
$invoices = Invoice::accrued()->monthsOfYear('due_at')->get();
|
||||
// Invoices
|
||||
$invoices = Invoice::accrued()->monthsOfYear('due_at')->customer(request('customers'))->get();
|
||||
Recurring::reflect($invoices, 'invoice', 'invoiced_at', $status);
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'due_at');
|
||||
|
||||
// Revenues
|
||||
Recurring::reflect($revenues, 'revenue', 'paid_at', $status);
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $revenues, 'revenue', 'paid_at');
|
||||
break;
|
||||
default:
|
||||
$invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->get();
|
||||
// Invoices
|
||||
$invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->customer(request('customers'))->get();
|
||||
Recurring::reflect($invoices, 'invoice', 'invoiced_at', $status);
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $invoices, 'invoice', 'invoiced_at');
|
||||
|
||||
// Revenues
|
||||
Recurring::reflect($revenues, 'revenue', 'paid_at', $status);
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $revenues, 'revenue', 'paid_at');
|
||||
break;
|
||||
}
|
||||
|
||||
// Revenues
|
||||
if ($status != 'upcoming') {
|
||||
$revenues = Revenue::monthsOfYear('paid_at')->isNotTransfer()->get();
|
||||
$this->setAmount($incomes_graph, $totals, $incomes, $revenues, 'revenue', 'paid_at');
|
||||
}
|
||||
$statuses = collect([
|
||||
'all' => trans('general.all'),
|
||||
'paid' => trans('invoices.paid'),
|
||||
'upcoming' => trans('dashboard.receivables'),
|
||||
]);
|
||||
|
||||
$accounts = Account::enabled()->pluck('name', 'id')->toArray();
|
||||
$customers = Customer::enabled()->pluck('name', 'id')->toArray();
|
||||
|
||||
// Check if it's a print or normal request
|
||||
if (request('print')) {
|
||||
@ -86,6 +112,8 @@ class IncomeSummary extends Controller
|
||||
$view_template = 'reports.income_summary.index';
|
||||
}
|
||||
|
||||
$print_url = $this->getPrintUrl($year);
|
||||
|
||||
// Incomes chart
|
||||
$chart = Charts::multi('line', 'chartjs')
|
||||
->dimensions(0, 300)
|
||||
@ -95,21 +123,49 @@ class IncomeSummary extends Controller
|
||||
->credits(false)
|
||||
->view($chart_template);
|
||||
|
||||
return view($view_template, compact('chart', 'dates', 'categories', 'incomes', 'totals'));
|
||||
return view($view_template, compact(
|
||||
'chart',
|
||||
'dates',
|
||||
'categories',
|
||||
'statuses',
|
||||
'accounts',
|
||||
'customers',
|
||||
'incomes',
|
||||
'totals',
|
||||
'print_url'
|
||||
));
|
||||
}
|
||||
|
||||
private function setAmount(&$graph, &$totals, &$incomes, $items, $type, $date_field)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($item['table'] == 'invoice_payments') {
|
||||
$invoice = $item->invoice;
|
||||
switch ($item->getTable()) {
|
||||
case 'invoice_payments':
|
||||
$invoice = $item->invoice;
|
||||
|
||||
$item->category_id = $invoice->category_id;
|
||||
if ($customers = request('customers')) {
|
||||
if (!in_array($invoice->customer_id, $customers)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$item->category_id = $invoice->category_id;
|
||||
break;
|
||||
case 'invoices':
|
||||
if ($accounts = request('accounts')) {
|
||||
foreach ($item->payments as $payment) {
|
||||
if (!in_array($payment->account_id, $accounts)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$date = Date::parse($item->$date_field)->format('F');
|
||||
$month = Date::parse($item->$date_field)->format('F');
|
||||
$month_year = Date::parse($item->$date_field)->format('F-Y');
|
||||
|
||||
if (!isset($incomes[$item->category_id])) {
|
||||
if (!isset($incomes[$item->category_id]) || !isset($incomes[$item->category_id][$month]) || !isset($graph[$month_year])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -122,13 +178,34 @@ class IncomeSummary extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$incomes[$item->category_id][$date]['amount'] += $amount;
|
||||
$incomes[$item->category_id][$date]['currency_code'] = $item->currency_code;
|
||||
$incomes[$item->category_id][$date]['currency_rate'] = $item->currency_rate;
|
||||
$incomes[$item->category_id][$month]['amount'] += $amount;
|
||||
$incomes[$item->category_id][$month]['currency_code'] = $item->currency_code;
|
||||
$incomes[$item->category_id][$month]['currency_rate'] = $item->currency_rate;
|
||||
|
||||
$graph[Date::parse($item->$date_field)->format('F-Y')] += $amount;
|
||||
$graph[$month_year] += $amount;
|
||||
|
||||
$totals[$date]['amount'] += $amount;
|
||||
$totals[$month]['amount'] += $amount;
|
||||
}
|
||||
}
|
||||
|
||||
private function getPrintUrl($year)
|
||||
{
|
||||
$print_url = 'reports/income-summary?print=1'
|
||||
. '&status=' . request('status')
|
||||
. '&year='. request('year', $year);
|
||||
|
||||
collect(request('accounts'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&accounts[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('customers'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&customers[]=' . $item;
|
||||
});
|
||||
|
||||
collect(request('categories'))->each(function($item) use(&$print_url) {
|
||||
$print_url .= '&categories[]=' . $item;
|
||||
});
|
||||
|
||||
return $print_url;
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,11 @@ class ProfitLoss extends Controller
|
||||
$dates = $totals = $compares = $categories = [];
|
||||
|
||||
$status = request('status');
|
||||
$year = request('year', Date::now()->year);
|
||||
|
||||
$income_categories = Category::enabled()->type('income')->pluck('name', 'id')->toArray();
|
||||
$income_categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
|
||||
$expense_categories = Category::enabled()->type('expense')->pluck('name', 'id')->toArray();
|
||||
|
||||
// Get year
|
||||
$year = request('year');
|
||||
if (empty($year)) {
|
||||
$year = Date::now()->year;
|
||||
}
|
||||
$expense_categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
|
||||
// Dates
|
||||
for ($j = 1; $j <= 12; $j++) {
|
||||
@ -142,6 +137,12 @@ class ProfitLoss extends Controller
|
||||
$this->setAmount($totals, $compares, $payments, 'payment', 'paid_at');
|
||||
}
|
||||
|
||||
$statuses = collect([
|
||||
'all' => trans('general.all'),
|
||||
'paid' => trans('invoices.paid'),
|
||||
'upcoming' => trans('general.upcoming'),
|
||||
]);
|
||||
|
||||
// Check if it's a print or normal request
|
||||
if (request('print')) {
|
||||
$view_template = 'reports.profit_loss.print';
|
||||
@ -149,7 +150,7 @@ class ProfitLoss extends Controller
|
||||
$view_template = 'reports.profit_loss.index';
|
||||
}
|
||||
|
||||
return view($view_template, compact('dates', 'income_categories', 'expense_categories', 'compares', 'totals', 'gross'));
|
||||
return view($view_template, compact('dates', 'income_categories', 'expense_categories', 'compares', 'totals', 'gross', 'statuses'));
|
||||
}
|
||||
|
||||
private function setAmount(&$totals, &$compares, $items, $type, $date_field)
|
||||
|
@ -27,17 +27,12 @@ class TaxSummary extends Controller
|
||||
$dates = $incomes = $expenses = $totals = [];
|
||||
|
||||
$status = request('status');
|
||||
$year = request('year', Date::now()->year);
|
||||
|
||||
$t = Tax::enabled()->where('rate', '<>', '0')->pluck('name')->toArray();
|
||||
|
||||
$taxes = array_combine($t, $t);
|
||||
|
||||
// Get year
|
||||
$year = request('year');
|
||||
if (empty($year)) {
|
||||
$year = Date::now()->year;
|
||||
}
|
||||
|
||||
// Dates
|
||||
for ($j = 1; $j <= 12; $j++) {
|
||||
$dates[$j] = Date::parse($year . '-' . $j)->format('M');
|
||||
@ -90,6 +85,12 @@ class TaxSummary extends Controller
|
||||
break;
|
||||
}
|
||||
|
||||
$statuses = collect([
|
||||
'all' => trans('general.all'),
|
||||
'paid' => trans('invoices.paid'),
|
||||
'upcoming' => trans('general.upcoming'),
|
||||
]);
|
||||
|
||||
// Check if it's a print or normal request
|
||||
if (request('print')) {
|
||||
$view_template = 'reports.tax_summary.print';
|
||||
@ -97,13 +98,13 @@ class TaxSummary extends Controller
|
||||
$view_template = 'reports.tax_summary.index';
|
||||
}
|
||||
|
||||
return view($view_template, compact('dates', 'taxes', 'incomes', 'expenses', 'totals'));
|
||||
return view($view_template, compact('dates', 'taxes', 'incomes', 'expenses', 'totals', 'statuses'));
|
||||
}
|
||||
|
||||
private function setAmount(&$items, &$totals, $rows, $type, $date_field)
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
if ($row['table'] == 'bill_payments' || $row['table'] == 'invoice_payments') {
|
||||
if ($row->getTable() == 'bill_payments' || $row->getTable() == 'invoice_payments') {
|
||||
$type_row = $row->$type;
|
||||
|
||||
$row->category_id = $type_row->category_id;
|
||||
@ -126,7 +127,14 @@ class TaxSummary extends Controller
|
||||
continue;
|
||||
}
|
||||
|
||||
$amount = $this->convert($row_total->amount, $row->currency_code, $row->currency_rate);
|
||||
if ($date_field == 'paid_at') {
|
||||
$rate = ($row->amount * 100) / $type_row->amount;
|
||||
$row_amount = ($row_total->amount / 100) * $rate;
|
||||
} else {
|
||||
$row_amount = $row_total->amount;
|
||||
}
|
||||
|
||||
$amount = $this->convert($row_amount, $row->currency_code, $row->currency_rate);
|
||||
|
||||
$items[$row_total->name][$date]['amount'] += $amount;
|
||||
|
||||
|
@ -25,7 +25,7 @@ class Categories extends Controller
|
||||
'income' => trans_choice('general.incomes', 1),
|
||||
'item' => trans_choice('general.items', 1),
|
||||
'other' => trans_choice('general.others', 1),
|
||||
])->prepend(trans('general.all_type', ['type' => trans_choice('general.types', 2)]), '');
|
||||
]);
|
||||
|
||||
return view('settings.categories.index', compact('categories', 'types', 'transfer_id'));
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ class Currencies extends Controller
|
||||
|
||||
return redirect('settings/currencies');
|
||||
} else {
|
||||
$message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
|
||||
$message = trans('messages.warning.disable_code', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
flash($message)->warning();
|
||||
|
||||
|
@ -47,7 +47,7 @@ class Settings extends Controller
|
||||
|
||||
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
|
||||
|
||||
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
|
||||
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
|
||||
|
||||
$payment_methods = Modules::getPaymentMethods();
|
||||
|
||||
@ -67,6 +67,24 @@ class Settings extends Controller
|
||||
'space' => trans('settings.localisation.date.space'),
|
||||
];
|
||||
|
||||
$item_names = [
|
||||
'settings.invoice.item' => trans('settings.invoice.item'),
|
||||
'settings.invoice.product' => trans('settings.invoice.product'),
|
||||
'settings.invoice.service' => trans('settings.invoice.service'),
|
||||
'custom' => trans('settings.invoice.custom'),
|
||||
];
|
||||
|
||||
$price_names = [
|
||||
'settings.invoice.price' => trans('settings.invoice.price'),
|
||||
'settings.invoice.rate' => trans('settings.invoice.rate'),
|
||||
'custom' => trans('settings.invoice.custom'),
|
||||
];
|
||||
|
||||
$quantity_names = [
|
||||
'settings.invoice.quantity' => trans('settings.invoice.quantity'),
|
||||
'custom' => trans('settings.invoice.custom'),
|
||||
];
|
||||
|
||||
$email_protocols = [
|
||||
'mail' => trans('settings.email.php'),
|
||||
'smtp' => trans('settings.email.smtp.name'),
|
||||
@ -88,6 +106,9 @@ class Settings extends Controller
|
||||
'payment_methods',
|
||||
'date_formats',
|
||||
'date_separators',
|
||||
'item_names',
|
||||
'price_names',
|
||||
'quantity_names',
|
||||
'email_protocols',
|
||||
'percent_positions'
|
||||
));
|
||||
@ -160,17 +181,17 @@ class Settings extends Controller
|
||||
protected function oneCompany($key, $value)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'company_name':
|
||||
Installer::updateEnv(['MAIL_FROM_NAME' => '"' . $value . '"']);
|
||||
break;
|
||||
case 'company_email':
|
||||
Installer::updateEnv(['MAIL_FROM_ADDRESS' => $value]);
|
||||
break;
|
||||
case 'default_locale':
|
||||
// Change default locale
|
||||
Installer::updateEnv([
|
||||
'APP_LOCALE' => $value
|
||||
]);
|
||||
Installer::updateEnv(['APP_LOCALE' => $value]);
|
||||
break;
|
||||
case 'session_handler':
|
||||
// Change session handler
|
||||
Installer::updateEnv([
|
||||
'SESSION_DRIVER' => $value
|
||||
]);
|
||||
Installer::updateEnv(['SESSION_DRIVER' => $value]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,13 @@ class Taxes extends Controller
|
||||
{
|
||||
$taxes = Tax::collect();
|
||||
|
||||
return view('settings.taxes.index', compact('taxes', 'rates'));
|
||||
$types = [
|
||||
'normal' => trans('taxes.normal'),
|
||||
'inclusive' => trans('taxes.inclusive'),
|
||||
'compound' => trans('taxes.compound'),
|
||||
];
|
||||
|
||||
return view('settings.taxes.index', compact('taxes', 'types'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,7 +44,13 @@ class Taxes extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('settings.taxes.create');
|
||||
$types = [
|
||||
'normal' => trans('taxes.normal'),
|
||||
'inclusive' => trans('taxes.inclusive'),
|
||||
'compound' => trans('taxes.compound'),
|
||||
];
|
||||
|
||||
return view('settings.taxes.create', compact('types'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +80,13 @@ class Taxes extends Controller
|
||||
*/
|
||||
public function edit(Tax $tax)
|
||||
{
|
||||
return view('settings.taxes.edit', compact('tax'));
|
||||
$types = [
|
||||
'normal' => trans('taxes.normal'),
|
||||
'inclusive' => trans('taxes.inclusive'),
|
||||
'compound' => trans('taxes.compound'),
|
||||
];
|
||||
|
||||
return view('settings.taxes.edit', compact('tax', 'types'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
81
app/Http/Controllers/Wizard/Companies.php
Normal file
81
app/Http/Controllers/Wizard/Companies.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Wizard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Wizard\Company as Request;
|
||||
use App\Models\Common\Company;
|
||||
use App\Traits\Uploads;
|
||||
|
||||
class Companies extends Controller
|
||||
{
|
||||
use Uploads;
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
if (setting('general.wizard', false)) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
$company = Company::find(session('company_id'));
|
||||
|
||||
$company->setSettings();
|
||||
|
||||
return view('wizard.companies.edit', compact('company'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Company $company
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
// Company
|
||||
$company = Company::find(session('company_id'));
|
||||
|
||||
$fields = $request->all();
|
||||
|
||||
$skip_keys = ['company_id', '_method', '_token'];
|
||||
$file_keys = ['company_logo', 'invoice_logo'];
|
||||
|
||||
foreach ($fields as $key => $value) {
|
||||
// Don't process unwanted keys
|
||||
if (in_array($key, $skip_keys)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Process file uploads
|
||||
if (in_array($key, $file_keys)) {
|
||||
// Upload attachment
|
||||
if ($request->file($key)) {
|
||||
$media = $this->getMedia($request->file($key), 'settings');
|
||||
|
||||
$company->attachMedia($media, $key);
|
||||
|
||||
$value = $media->id;
|
||||
}
|
||||
|
||||
// Prevent reset
|
||||
if (empty($value)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
setting()->set('general.' . $key, $value);
|
||||
}
|
||||
|
||||
// Save all settings
|
||||
setting()->save();
|
||||
|
||||
return redirect('wizard/currencies');
|
||||
}
|
||||
}
|
311
app/Http/Controllers/Wizard/Currencies.php
Normal file
311
app/Http/Controllers/Wizard/Currencies.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Wizard;
|
||||
|
||||
use Akaunting\Money\Currency as MoneyCurrency;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Setting\Currency as Request;
|
||||
use App\Models\Banking\Account;
|
||||
use App\Models\Setting\Currency;
|
||||
|
||||
class Currencies extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Currency $currency
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (setting('general.wizard', false)) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
$currencies = Currency::all();
|
||||
|
||||
return view('wizard.currencies.index', compact('currencies'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if (setting(setting('general.wizard', false))) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
// Get current currencies
|
||||
$current = Currency::pluck('code')->toArray();
|
||||
|
||||
// Prepare codes
|
||||
$codes = array();
|
||||
$currencies = MoneyCurrency::getCurrencies();
|
||||
foreach ($currencies as $key => $item) {
|
||||
// Don't show if already available
|
||||
if (in_array($key, $current)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$codes[$key] = $key;
|
||||
}
|
||||
|
||||
$html = view('wizard.currencies.create', compact('codes'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => 'null',
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
// Force the rate to be 1 for default currency
|
||||
if ($request['default_currency']) {
|
||||
$request['rate'] = '1';
|
||||
}
|
||||
|
||||
$currency = Currency::create($request->all());
|
||||
|
||||
// Update default currency setting
|
||||
if ($request['default_currency']) {
|
||||
setting()->set('general.default_currency', $request['code']);
|
||||
setting()->save();
|
||||
}
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.currencies', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Currency $currency
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit(Currency $currency)
|
||||
{
|
||||
if (setting('general.wizard', false)) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
// Get current currencies
|
||||
$current = Currency::pluck('code')->toArray();
|
||||
|
||||
// Prepare codes
|
||||
$codes = array();
|
||||
$currencies = MoneyCurrency::getCurrencies();
|
||||
foreach ($currencies as $key => $item) {
|
||||
// Don't show if already available
|
||||
if (($key != $currency->code) && in_array($key, $current)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$codes[$key] = $key;
|
||||
}
|
||||
|
||||
$item = $currency;
|
||||
|
||||
$html = view('wizard.currencies.edit', compact('item', 'codes'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => 'null',
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Currency $currency
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Currency $currency, Request $request)
|
||||
{
|
||||
// Check if we can disable or change the code
|
||||
if (!$request['enabled'] || ($currency->code != $request['code'])) {
|
||||
$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 (empty($relationships)) {
|
||||
// Force the rate to be 1 for default currency
|
||||
if ($request['default_currency']) {
|
||||
$request['rate'] = '1';
|
||||
}
|
||||
|
||||
$currency->update($request->all());
|
||||
|
||||
// Update default currency setting
|
||||
if ($request['default_currency']) {
|
||||
setting()->set('general.default_currency', $request['code']);
|
||||
setting()->save();
|
||||
}
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.currencies', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
} else {
|
||||
$message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the specified resource.
|
||||
*
|
||||
* @param Currency $currency
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function enable(Currency $currency)
|
||||
{
|
||||
$currency->enabled = 1;
|
||||
$currency->save();
|
||||
|
||||
$message = trans('messages.success.enabled', ['type' => trans_choice('general.currencies', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the specified resource.
|
||||
*
|
||||
* @param Currency $currency
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function disable(Currency $currency)
|
||||
{
|
||||
$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 (empty($relationships)) {
|
||||
$currency->enabled = 0;
|
||||
$currency->save();
|
||||
|
||||
$message = trans('messages.success.disabled', ['type' => trans_choice('general.currencies', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
} else {
|
||||
$message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Currency $currency
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy(Currency $currency)
|
||||
{
|
||||
$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 (empty($relationships)) {
|
||||
$currency->delete();
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.currencies', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
} else {
|
||||
$message = trans('messages.warning.deleted', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'message' => $message,
|
||||
'data' => $currency,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
39
app/Http/Controllers/Wizard/Finish.php
Normal file
39
app/Http/Controllers/Wizard/Finish.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Wizard;
|
||||
|
||||
use Illuminate\Routing\Controller;
|
||||
use App\Traits\Modules;
|
||||
use App\Models\Module\Module;
|
||||
|
||||
class Finish extends Controller
|
||||
{
|
||||
use Modules;
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (setting(setting('general.wizard', false))) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
setting()->set('general.wizard', true);
|
||||
|
||||
// Save all settings
|
||||
setting()->save();
|
||||
|
||||
$data = [
|
||||
'query' => [
|
||||
'limit' => 4
|
||||
]
|
||||
];
|
||||
|
||||
$modules = $this->getFeaturedModules($data);
|
||||
|
||||
return view('wizard.finish.index', compact('modules'));
|
||||
}
|
||||
}
|
231
app/Http/Controllers/Wizard/Taxes.php
Normal file
231
app/Http/Controllers/Wizard/Taxes.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Wizard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Setting\Tax as Request;
|
||||
use App\Models\Setting\Tax;
|
||||
|
||||
class Taxes extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (setting(setting('general.wizard', false))) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
$taxes = Tax::all();
|
||||
|
||||
return view('wizard.taxes.index', compact('taxes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if (setting(setting('general.wizard', false))) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
$html = view('wizard.taxes.create', compact('codes'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => 'null',
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$tax = Tax::create($request->all());
|
||||
|
||||
$message = trans('messages.success.added', ['type' => trans_choice('general.tax_rates', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param Tax $tax
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit(Tax $tax)
|
||||
{
|
||||
if (setting(setting('general.wizard', false))) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
$item = $tax;
|
||||
|
||||
$html = view('wizard.taxes.edit', compact('item'))->render();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => 'null',
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Tax $tax
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Tax $tax, Request $request)
|
||||
{
|
||||
$relationships = $this->countRelationships($tax, [
|
||||
'items' => 'items',
|
||||
'invoice_items' => 'invoices',
|
||||
'bill_items' => 'bills',
|
||||
]);
|
||||
|
||||
if (empty($relationships) || $request['enabled']) {
|
||||
$tax->update($request->all());
|
||||
|
||||
$message = trans('messages.success.updated', ['type' => trans_choice('general.tax_rates', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
} else {
|
||||
$message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the specified resource.
|
||||
*
|
||||
* @param Tax $tax
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function enable(Tax $tax)
|
||||
{
|
||||
$tax->enabled = 1;
|
||||
$tax->save();
|
||||
|
||||
$message = trans('messages.success.enabled', ['type' => trans_choice('general.tax_rates', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the specified resource.
|
||||
*
|
||||
* @param Tax $tax
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function disable(Tax $tax)
|
||||
{
|
||||
$relationships = $this->countRelationships($tax, [
|
||||
'items' => 'items',
|
||||
'invoice_items' => 'invoices',
|
||||
'bill_items' => 'bills',
|
||||
]);
|
||||
|
||||
if (empty($relationships)) {
|
||||
$tax->enabled = 0;
|
||||
$tax->save();
|
||||
|
||||
$message = trans('messages.success.disabled', ['type' => trans_choice('general.tax_rates', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
} else {
|
||||
$message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param Tax $tax
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy(Tax $tax)
|
||||
{
|
||||
$relationships = $this->countRelationships($tax, [
|
||||
'items' => 'items',
|
||||
'invoice_items' => 'invoices',
|
||||
'bill_items' => 'bills',
|
||||
]);
|
||||
|
||||
if (empty($relationships)) {
|
||||
$tax->delete();
|
||||
|
||||
$message = trans('messages.success.deleted', ['type' => trans_choice('general.taxes', 1)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'error' => false,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
} else {
|
||||
$message = trans('messages.warning.deleted', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error' => true,
|
||||
'message' => $message,
|
||||
'data' => $tax,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user