v2 first commit

This commit is contained in:
denisdulici
2019-11-16 10:21:14 +03:00
parent 5b23e9c2c4
commit 6d50fa8442
3075 changed files with 3451681 additions and 65594 deletions

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Auth;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Auth\Permission as Request;
use App\Models\Auth\Permission;
use App\Jobs\Auth\CreatePermission;
use App\Jobs\Auth\DeletePermission;
use App\Jobs\Auth\UpdatePermission;
use App\Transformers\Auth\Permission as Transformer;
use Dingo\Api\Routing\Helpers;
class Permissions extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -43,9 +43,9 @@ class Permissions extends ApiController
*/
public function store(Request $request)
{
$permission = Permission::create($request->all());
$permission = $this->dispatch(new CreatePermission($request));
return $this->response->created(url('api/permissions/'.$permission->id));
return $this->response->created(url('api/permissions/' . $permission->id));
}
/**
@ -57,9 +57,9 @@ class Permissions extends ApiController
*/
public function update(Permission $permission, Request $request)
{
$permission->update($request->all());
$permission = $this->dispatch(new UpdatePermission($permission, $request));
return $this->response->item($permission->fresh(), new Transformer());
return $this->item($permission->fresh(), new Transformer());
}
/**
@ -70,8 +70,12 @@ class Permissions extends ApiController
*/
public function destroy(Permission $permission)
{
$permission->delete();
try {
$this->dispatch(new DeletePermission($permission));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Auth;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Auth\Role as Request;
use App\Models\Auth\Role;
use App\Jobs\Auth\CreateRole;
use App\Jobs\Auth\DeleteRole;
use App\Jobs\Auth\UpdateRole;
use App\Transformers\Auth\Role as Transformer;
use Dingo\Api\Routing\Helpers;
class Roles extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -43,13 +43,9 @@ class Roles extends ApiController
*/
public function store(Request $request)
{
$role = Role::create($request->input());
$role = $this->dispatch(new CreateRole($request));
if ($request->has('permissions')) {
$role->permissions()->attach($request->get('permissions'));
}
return $this->response->created(url('api/roles/'.$role->id));
return $this->response->created(url('api/roles/' . $role->id));
}
/**
@ -61,13 +57,9 @@ class Roles extends ApiController
*/
public function update(Role $role, Request $request)
{
$role->update($request->all());
$role = $this->dispatch(new UpdateRole($role, $request));
if ($request->has('permissions')) {
$role->permissions()->attach($request->get('permissions'));
}
return $this->response->item($role->fresh(), new Transformer());
return $this->item($role->fresh(), new Transformer());
}
/**
@ -78,8 +70,12 @@ class Roles extends ApiController
*/
public function destroy(Role $role)
{
$role->delete();
try {
$this->dispatch(new DeleteRole($role));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Auth;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Auth\User as Request;
use App\Jobs\Auth\CreateUser;
use App\Jobs\Auth\DeleteUser;
use App\Jobs\Auth\UpdateUser;
use App\Models\Auth\User;
use App\Transformers\Auth\User as Transformer;
use Dingo\Api\Routing\Helpers;
class Users extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -50,15 +50,9 @@ class Users extends ApiController
*/
public function store(Request $request)
{
$user = User::create($request->input());
$user = $this->dispatch(new CreateUser($request));
// Attach roles
$user->roles()->attach($request->get('roles'));
// Attach companies
$user->companies()->attach($request->get('companies'));
return $this->response->created(url('api/users/'.$user->id));
return $this->response->created(url('api/users/' . $user->id));
}
/**
@ -70,16 +64,35 @@ class Users extends ApiController
*/
public function update(User $user, Request $request)
{
// Except password as we don't want to let the users change a password from this endpoint
$user->update($request->except('password'));
$user = $this->dispatch(new UpdateUser($user, $request));
// Sync roles
$user->roles()->sync($request->get('roles'));
return $this->item($user->fresh(), new Transformer());
}
// Sync companies
$user->companies()->sync($request->get('companies'));
/**
* Enable the specified resource in storage.
*
* @param User $user
* @return \Dingo\Api\Http\Response
*/
public function enable(User $user)
{
$user = $this->dispatch(new UpdateUser($user, request()->merge(['enabled' => 1])));
return $this->response->item($user->fresh(), new Transformer());
return $this->item($user->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param User $user
* @return \Dingo\Api\Http\Response
*/
public function disable(User $user)
{
$user = $this->dispatch(new UpdateUser($user, request()->merge(['enabled' => 0])));
return $this->item($user->fresh(), new Transformer());
}
/**
@ -90,8 +103,12 @@ class Users extends ApiController
*/
public function destroy(User $user)
{
$user->delete();
try {
$this->dispatch(new DeleteUser($user));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Banking;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Banking\Account as Request;
use App\Jobs\Banking\CreateAccount;
use App\Jobs\Banking\DeleteAccount;
use App\Jobs\Banking\UpdateAccount;
use App\Models\Banking\Account;
use App\Transformers\Banking\Account as Transformer;
use Dingo\Api\Routing\Helpers;
class Accounts extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -27,11 +27,18 @@ class Accounts extends ApiController
/**
* Display the specified resource.
*
* @param Account $account
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function show(Account $account)
public function show($id)
{
// Check if we're querying by id or number
if (is_numeric($id)) {
$account = Account::find($id);
} else {
$account = Account::where('number', $id)->first();
}
return $this->response->item($account, new Transformer());
}
@ -43,9 +50,9 @@ class Accounts extends ApiController
*/
public function store(Request $request)
{
$account = Account::create($request->all());
$account = $this->dispatch(new CreateAccount($request));
return $this->response->created(url('api/accounts/'.$account->id));
return $this->response->created(url('api/accounts/' . $account->id));
}
/**
@ -57,9 +64,43 @@ class Accounts extends ApiController
*/
public function update(Account $account, Request $request)
{
$account->update($request->all());
try {
$account = $this->dispatch(new UpdateAccount($account, $request));
return $this->response->item($account->fresh(), new Transformer());
return $this->item($account->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
* Enable the specified resource in storage.
*
* @param Account $account
* @return \Dingo\Api\Http\Response
*/
public function enable(Account $account)
{
$account = $this->dispatch(new UpdateAccount($account, request()->merge(['enabled' => 1])));
return $this->item($account->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Account $account
* @return \Dingo\Api\Http\Response
*/
public function disable(Account $account)
{
try {
$account = $this->dispatch(new UpdateAccount($account, request()->merge(['enabled' => 0])));
return $this->item($account->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
@ -70,8 +111,12 @@ class Accounts extends ApiController
*/
public function destroy(Account $account)
{
$account->delete();
try {
$this->dispatch(new DeleteAccount($account));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace App\Http\Controllers\Api\Banking;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Banking\Reconciliation as Request;
use App\Jobs\Banking\CreateReconciliation;
use App\Jobs\Banking\DeleteReconciliation;
use App\Jobs\Banking\UpdateReconciliation;
use App\Models\Banking\Reconciliation;
use App\Transformers\Banking\Reconciliation as Transformer;
class Reconciliations extends ApiController
{
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$items = Reconciliation::with(['account'])->collect();
return $this->response->paginator($items, new Transformer());
}
/**
* Display the specified resource.
*
* @param $reconciliation
* @return \Dingo\Api\Http\Response
*/
public function show(Reconciliation $reconciliation)
{
return $this->response->item($reconciliation, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$reconciliation = $this->dispatch(new CreateReconciliation($request));
return $this->response->created(url('api/reconciliations/' . $reconciliation->id));
}
/**
* Update the specified resource in storage.
*
* @param $reconciliation
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Reconciliation $reconciliation, Request $request)
{
$reconciliation = $this->dispatch(new UpdateReconciliation($reconciliation, $request));
return $this->item($reconciliation->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Reconciliation $reconciliation
* @return \Dingo\Api\Http\Response
*/
public function destroy(Reconciliation $reconciliation)
{
try {
$this->dispatch(new DeleteReconciliation($reconciliation));
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace App\Http\Controllers\Api\Banking;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Banking\Transaction as Request;
use App\Jobs\Banking\CreateTransaction;
use App\Jobs\Banking\DeleteTransaction;
use App\Jobs\Banking\UpdateTransaction;
use App\Models\Banking\Transaction;
use App\Transformers\Banking\Transaction as Transformer;
class Transactions extends ApiController
{
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$transactions = Transaction::with(['account', 'category', 'contact'])->collect(['paid_at'=> 'desc']);
return $this->response->paginator($transactions, new Transformer());
}
/**
* Display the specified resource.
*
* @param Transaction $transaction
* @return \Dingo\Api\Http\Response
*/
public function show(Transaction $transaction)
{
return $this->response->item($transaction, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$transaction = $this->dispatch(new CreateTransaction($request));
return $this->response->created(url('api/transactions/' . $transaction->id));
}
/**
* Update the specified resource in storage.
*
* @param $transaction
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Transaction $transaction, Request $request)
{
$transaction = $this->dispatch(new UpdateTransaction($transaction, $request));
return $this->item($transaction->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Transaction $transaction
* @return \Dingo\Api\Http\Response
*/
public function destroy(Transaction $transaction)
{
try {
$this->dispatch(new DeleteTransaction($transaction));
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,18 +2,16 @@
namespace App\Http\Controllers\Api\Banking;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Banking\Transfer as Request;
use App\Jobs\Banking\CreateTransfer;
use App\Jobs\Banking\UpdateTransfer;
use App\Jobs\Banking\DeleteTransfer;
use App\Models\Banking\Transfer;
use App\Models\Expense\Payment;
use App\Models\Income\Revenue;
use App\Transformers\Banking\Transfer as Transformer;
use Dingo\Api\Routing\Helpers;
class Transfers extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -21,7 +19,37 @@ class Transfers extends ApiController
*/
public function index()
{
$transfers = Transfer::with(['payment', 'revenue'])->collect('payment.paid_at');
$transfers = Transfer::with([
'expense_transaction', 'expense_transaction.account', 'income_transaction', 'income_transaction.account'
])->collect('expense_transaction.paid_at');
$special_key = [
'expense_transaction.name' => 'from_account',
'income_transaction.name' => 'to_account',
];
$request = request();
if (isset($request['sort']) && array_key_exists($request['sort'], $special_key)) {
$items = $transfers->items();
$sort_order = [];
foreach ($items as $key => $value) {
$sort = $request['sort'];
if (array_key_exists($request['sort'], $special_key)) {
$sort = $special_key[$request['sort']];
}
$sort_order[$key] = $value->{$sort};
}
$sort_type = (isset($request['order']) && $request['order'] == 'asc') ? SORT_ASC : SORT_DESC;
array_multisort($sort_order, $sort_type, $items);
$transfers->setCollection(collect($items));
}
return $this->response->paginator($transfers, new Transformer());
}
@ -45,9 +73,9 @@ class Transfers extends ApiController
*/
public function store(Request $request)
{
$transfer = Transfer::create($request->all());
$transfer = $this->dispatch(new CreateTransfer($request));
return $this->response->created(url('api/transfers/'.$transfer->id));
return $this->response->created(url('api/transfers/' . $transfer->id));
}
/**
@ -59,9 +87,9 @@ class Transfers extends ApiController
*/
public function update(Transfer $transfer, Request $request)
{
$transfer->update($request->all());
$transfer = $this->dispatch(new UpdateTransfer($transfer, $request));
return $this->response->item($transfer->fresh(), new Transformer());
return $this->item($transfer->fresh(), new Transformer());
}
/**
@ -72,13 +100,12 @@ class Transfers extends ApiController
*/
public function destroy(Transfer $transfer)
{
$payment = Payment::findOrFail($transfer['payment_id']);
$revenue = Revenue::findOrFail($transfer['revenue_id']);
try {
$this->dispatch(new DeleteTransfer($transfer));
$transfer->delete();
$payment->delete();
$revenue->delete();
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,15 +2,19 @@
namespace App\Http\Controllers\Api\Common;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Common\Company as Request;
use App\Jobs\Common\CreateCompany;
use App\Jobs\Common\DeleteCompany;
use App\Jobs\Common\UpdateCompany;
use App\Models\Common\Company;
use App\Transformers\Common\Company as Transformer;
use Dingo\Api\Routing\Helpers;
use App\Traits\Users;
use Dingo\Api\Http\Response;
class Companies extends ApiController
{
use Helpers;
use Users;
/**
* Display a listing of the resource.
@ -19,13 +23,9 @@ class Companies extends ApiController
*/
public function index()
{
$companies = app('Dingo\Api\Auth\Auth')->user()->companies()->get()->sortBy('name');
$companies = user()->companies()->collect();
foreach ($companies as $company) {
$company->setSettings();
}
return $this->response->collection($companies, new Transformer());
return $this->response->paginator($companies, new Transformer());
}
/**
@ -36,15 +36,14 @@ class Companies extends ApiController
*/
public function show(Company $company)
{
// Check if user can access company
$companies = app('Dingo\Api\Auth\Auth')->user()->companies()->pluck('id')->toArray();
if (!in_array($company->id, $companies)) {
$this->response->errorUnauthorized();
try {
// Check if user can access company
$this->owner($company);
return $this->response->item($company, new Transformer());
} catch (\HttpException $e) {
$this->response->errorUnauthorized($e->getMessage());
}
$company->setSettings();
return $this->response->item($company, new Transformer());
}
/**
@ -55,22 +54,7 @@ class Companies extends ApiController
*/
public function store(Request $request)
{
$company = Company::create($request->all());
// Clear settings
setting()->forgetAll();
setting()->setExtraColumns(['company_id' => $company->id]);
// Create settings
setting()->set([
'general.company_name' => $request->get('company_name'),
'general.company_email' => $request->get('company_email'),
'general.company_address' => $request->get('company_address'),
'general.default_currency' => $request->get('default_currency'),
'general.default_locale' => $request->get('default_locale', 'en-GB'),
]);
setting()->save();
$company = $this->dispatch(new CreateCompany($request));
return $this->response->created(url('api/companies/' . $company->id));
}
@ -84,31 +68,47 @@ class Companies extends ApiController
*/
public function update(Company $company, Request $request)
{
// Check if user can access company
$companies = app('Dingo\Api\Auth\Auth')->user()->companies()->pluck('id')->toArray();
if (!in_array($company->id, $companies)) {
$this->response->errorUnauthorized();
try {
$company = $this->dispatch(new UpdateCompany($company, $request));
return $this->item($company->fresh(), new Transformer());
} catch (\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
// Update company
$company->update(['domain' => $request->get('domain')]);
/**
* Enable the specified resource in storage.
*
* @param Company $company
* @return \Dingo\Api\Http\Response
*/
public function enable(Company $company)
{
try {
$company = $this->dispatch(new UpdateCompany($company, request()->merge(['enabled' => 1])));
// Update settings
setting()->forgetAll();
setting()->setExtraColumns(['company_id' => $company->id]);
setting()->load(true);
return $this->item($company->fresh(), new Transformer());
} catch (\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
setting()->set([
'general.company_name' => $request->get('company_name'),
'general.company_email' => $request->get('company_email'),
'general.company_address' => $request->get('company_address'),
'general.default_currency' => $request->get('default_currency'),
'general.default_locale' => $request->get('default_locale', 'en-GB'),
]);
/**
* Disable the specified resource in storage.
*
* @param Company $company
* @return \Dingo\Api\Http\Response
*/
public function disable(Company $company)
{
try {
$company = $this->dispatch(new UpdateCompany($company, request()->merge(['enabled' => 0])));
setting()->save();
return $this->response->item($company->fresh(), new Transformer());
return $this->item($company->fresh(), new Transformer());
} catch (\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
@ -119,14 +119,30 @@ class Companies extends ApiController
*/
public function destroy(Company $company)
{
// Check if user can access company
$companies = app('Dingo\Api\Auth\Auth')->user()->companies()->pluck('id')->toArray();
if (!in_array($company->id, $companies)) {
$this->response->errorUnauthorized();
try {
$this->dispatch(new DeleteCompany($company));
return $this->response->noContent();
} catch (\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
* Check user company assignment
*
* @param Company $company
*
* @return \Dingo\Api\Http\Response
*/
public function owner(Company $company)
{
if ($this->isUserCompany($company->id)) {
return new Response('');
}
$company->delete();
$message = trans('companies.error.not_user_company');
return $this->response->noContent();
$this->response->errorUnauthorized($message);
}
}

View File

@ -0,0 +1,133 @@
<?php
namespace App\Http\Controllers\Api\Common;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Common\Contact as Request;
use App\Jobs\Common\CreateContact;
use App\Jobs\Common\DeleteContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Common\Contact;
use App\Traits\Uploads;
use App\Transformers\Common\Contact as Transformer;
class Contacts extends ApiController
{
use Uploads;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:create-incomes-customers')->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-incomes-customers')->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-incomes-customers')->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-incomes-customers')->only('destroy');
}
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$contacts = Contact::collect();
return $this->response->paginator($contacts, new Transformer());
}
/**
* Display the specified resource.
*
* @param int|string $id
* @return \Dingo\Api\Http\Response
*/
public function show($id)
{
// Check if we're querying by id or email
if (is_numeric($id)) {
$contact = Contact::find($id);
} else {
$contact = Contact::where('email', $id)->first();
}
return $this->response->item($contact, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$contact = $this->dispatch(new CreateContact($request));
return $this->response->created(url('api/contacts/' . $contact->id));
}
/**
* Update the specified resource in storage.
*
* @param $contact
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Contact $contact, Request $request)
{
$contact = $this->dispatch(new UpdateContact($contact, $request));
return $this->item($contact->fresh(), new Transformer());
}
/**
* Enable the specified resource in storage.
*
* @param Contact $contact
* @return \Dingo\Api\Http\Response
*/
public function enable(Contact $contact)
{
$contact = $this->dispatch(new UpdateContact($contact, request()->merge(['enabled' => 1])));
return $this->item($contact->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Contact $contact
* @return \Dingo\Api\Http\Response
*/
public function disable(Contact $contact)
{
try {
$contact = $this->dispatch(new UpdateContact($contact, request()->merge(['enabled' => 0])));
return $this->item($contact->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
* Remove the specified resource from storage.
*
* @param Contact $contact
* @return \Dingo\Api\Http\Response
*/
public function destroy(Contact $contact)
{
try {
$this->dispatch(new DeleteContact($contact));
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,15 +2,18 @@
namespace App\Http\Controllers\Api\Common;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Common\Item as Request;
use App\Jobs\Common\CreateItem;
use App\Jobs\Common\DeleteItem;
use App\Jobs\Common\UpdateItem;
use App\Models\Common\Item;
use App\Transformers\Common\Item as Transformer;
use Dingo\Api\Routing\Helpers;
use App\Traits\Uploads;
class Items extends ApiController
{
use Helpers;
use Uploads;
/**
* Display a listing of the resource.
@ -32,12 +35,7 @@ class Items extends ApiController
*/
public function show($id)
{
// Check if we're querying by id or sku
if (is_numeric($id)) {
$item = Item::with(['category', 'tax'])->find($id);
} else {
$item = Item::with(['category', 'tax'])->where('sku', $id)->first();
}
$item = Item::with(['category', 'tax'])->find($id);
return $this->response->item($item, new Transformer());
}
@ -50,9 +48,9 @@ class Items extends ApiController
*/
public function store(Request $request)
{
$item = Item::create($request->all());
$item = $this->dispatch(new CreateItem($request));
return $this->response->created(url('api/items/'.$item->id));
return $this->response->created(url('api/items/' . $item->id));
}
/**
@ -64,9 +62,35 @@ class Items extends ApiController
*/
public function update(Item $item, Request $request)
{
$item->update($request->all());
$item = $this->dispatch(new UpdateItem($item, $request));
return $this->response->item($item->fresh(), new Transformer());
return $this->item($item->fresh(), new Transformer());
}
/**
* Enable the specified resource in storage.
*
* @param Item $item
* @return \Dingo\Api\Http\Response
*/
public function enable(Item $item)
{
$item = $this->dispatch(new UpdateItem($item, request()->merge(['enabled' => 1])));
return $this->item($item->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Item $item
* @return \Dingo\Api\Http\Response
*/
public function disable(Item $item)
{
$item = $this->dispatch(new UpdateItem($item, request()->merge(['enabled' => 0])));
return $this->item($item->fresh(), new Transformer());
}
/**
@ -77,8 +101,12 @@ class Items extends ApiController
*/
public function destroy(Item $item)
{
$item->delete();
try {
$this->dispatch(new DeleteItem($item));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Api\Common;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use Date;
use Dingo\Api\Routing\Helpers;

View File

@ -0,0 +1,107 @@
<?php
namespace App\Http\Controllers\Api\Common;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Common\Report as Request;
use App\Jobs\Common\CreateReport;
use App\Jobs\Common\DeleteReport;
use App\Jobs\Common\UpdateReport;
use App\Models\Common\Report;
use App\Transformers\Common\Report as Transformer;
class Reports extends ApiController
{
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$reports = Report::collect();
return $this->response->paginator($reports, new Transformer());
}
/**
* Display the specified resource.
*
* @param Report $report
* @return \Dingo\Api\Http\Response
*/
public function show(Report $report)
{
return $this->response->item($report, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$report = $this->dispatch(new CreateReport($request));
return $this->response->created(url('api/reports/' . $report->id));
}
/**
* Update the specified resource in storage.
*
* @param $report
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Report $report, Request $request)
{
$report = $this->dispatch(new UpdateReport($report, $request));
return $this->item($report->fresh(), new Transformer());
}
/**
* Enable the specified resource in storage.
*
* @param Report $report
* @return \Dingo\Api\Http\Response
*/
public function enable(Report $report)
{
$report = $this->dispatch(new UpdateReport($report, request()->merge(['enabled' => 1])));
return $this->item($report->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Report $report
* @return \Dingo\Api\Http\Response
*/
public function disable(Report $report)
{
$report = $this->dispatch(new UpdateReport($report, request()->merge(['enabled' => 0])));
return $this->item($report->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Report $report
* @return \Dingo\Api\Http\Response
*/
public function destroy(Report $report)
{
try {
$this->dispatch(new DeleteReport($report));
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,24 +2,16 @@
namespace App\Http\Controllers\Api\Expenses;
use App\Events\BillCreated;
use App\Events\BillUpdated;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Expense\Bill as Request;
use App\Jobs\Expense\CreateBill;
use App\Jobs\Expense\DeleteBill;
use App\Jobs\Expense\UpdateBill;
use App\Models\Expense\Bill;
use App\Models\Expense\BillHistory;
use App\Models\Expense\BillItem;
use App\Models\Expense\BillPayment;
use App\Models\Expense\BillStatus;
use App\Models\Common\Item;
use App\Models\Setting\Tax;
use App\Transformers\Expense\Bill as Transformer;
use Dingo\Api\Routing\Helpers;
class Bills extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -27,7 +19,7 @@ class Bills extends ApiController
*/
public function index()
{
$bills = Bill::with(['vendor', 'status', 'items', 'payments', 'histories'])->collect();
$bills = Bill::with(['contact', 'status', 'items', 'transactions', 'histories'])->collect(['billed_at'=> 'desc']);
return $this->response->paginator($bills, new Transformer());
}
@ -51,72 +43,9 @@ class Bills extends ApiController
*/
public function store(Request $request)
{
$bill = Bill::create($request->all());
$bill = $this->dispatch(new CreateBill($request));
$bill_item = array();
$bill_item['company_id'] = $request['company_id'];
$bill_item['bill_id'] = $bill->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;
// Increase stock (item bought)
$item_object->quantity += $item['quantity'];
$item_object->save();
} 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'];
}
$bill_item['item_id'] = $item_id;
$bill_item['name'] = str_limit($item['name'], 180, '');
$bill_item['sku'] = $item_sku;
$bill_item['quantity'] = $item['quantity'];
$bill_item['price'] = $item['price'];
$bill_item['tax'] = $tax;
$bill_item['tax_id'] = $tax_id;
$bill_item['total'] = ($item['price'] + $bill_item['tax']) * $item['quantity'];
$request['amount'] += $bill_item['total'];
BillItem::create($bill_item);
}
}
$bill->update($request->input());
$request['bill_id'] = $bill->id;
$request['status_code'] = $request['bill_status_code'];
$request['notify'] = 0;
$request['description'] = trans('messages.success.added', ['type' => $request['bill_number']]);
BillHistory::create($request->input());
// Fire the event to make it extendible
event(new BillCreated($bill));
return $this->response->created(url('api/bills/'.$bill->id));
return $this->response->created(url('api/bills/' . $bill->id));
}
/**
@ -128,61 +57,9 @@ class Bills extends ApiController
*/
public function update(Bill $bill, Request $request)
{
$bill_item = array();
$bill_item['company_id'] = $request['company_id'];
$bill_item['bill_id'] = $bill->id;
$bill = $this->dispatch(new UpdateBill($bill, $request));
if ($request['item']) {
BillItem::where('bill_id', $bill->id)->delete();
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;
} 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'];
}
$bill_item['item_id'] = $item_id;
$bill_item['name'] = str_limit($item['name'], 180, '');
$bill_item['sku'] = $item_sku;
$bill_item['quantity'] = $item['quantity'];
$bill_item['price'] = $item['price'];
$bill_item['tax'] = $tax;
$bill_item['tax_id'] = $tax_id;
$bill_item['total'] = ($item['price'] + $bill_item['tax']) * $item['quantity'];
$request['amount'] += $bill_item['total'];
BillItem::create($bill_item);
}
}
$bill->update($request->input());
// Fire the event to make it extendible
event(new BillUpdated($bill));
return $this->response->item($bill->fresh(), new Transformer());
return $this->item($bill->fresh(), new Transformer());
}
/**
@ -193,12 +70,12 @@ class Bills extends ApiController
*/
public function destroy(Bill $bill)
{
$bill->delete();
try {
$this->dispatch(new DeleteBill($bill));
BillItem::where('bill_id', $bill->id)->delete();
BillPayment::where('bill_id', $bill->id)->delete();
BillHistory::where('bill_id', $bill->id)->delete();
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace App\Http\Controllers\Api\Expenses;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Expense\Payment as Request;
use App\Models\Expense\Payment;
use App\Transformers\Expense\Payment as Transformer;
use Dingo\Api\Routing\Helpers;
class Payments extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$payments = Payment::with(['account', 'vendor', 'category'])->collect();
return $this->response->paginator($payments, new Transformer());
}
/**
* Display the specified resource.
*
* @param Payment $payment
* @return \Dingo\Api\Http\Response
*/
public function show(Payment $payment)
{
return $this->response->item($payment, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$payment = Payment::create($request->all());
return $this->response->created(url('api/payments/'.$payment->id));
}
/**
* Update the specified resource in storage.
*
* @param $payment
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Payment $payment, Request $request)
{
$payment->update($request->all());
return $this->response->item($payment->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Payment $payment
* @return \Dingo\Api\Http\Response
*/
public function destroy(Payment $payment)
{
$payment->delete();
return $this->response->noContent();
}
}

View File

@ -1,84 +0,0 @@
<?php
namespace App\Http\Controllers\Api\Expenses;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Expense\Vendor as Request;
use App\Models\Expense\Vendor;
use App\Transformers\Expense\Vendor as Transformer;
use Dingo\Api\Routing\Helpers;
class Vendors extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$vendors = Vendor::collect();
return $this->response->paginator($vendors, new Transformer());
}
/**
* Display the specified resource.
*
* @param int|string $id
* @return \Dingo\Api\Http\Response
*/
public function show($id)
{
// Check if we're querying by id or email
if (is_numeric($id)) {
$vendor = Vendor::find($id);
} else {
$vendor = Vendor::where('email', $id)->first();
}
return $this->response->item($vendor, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$vendor = Vendor::create($request->all());
return $this->response->created(url('api/vendors/'.$vendor->id));
}
/**
* Update the specified resource in storage.
*
* @param $vendor
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Vendor $vendor, Request $request)
{
$vendor->update($request->all());
return $this->response->item($vendor->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Vendor $vendor
* @return \Dingo\Api\Http\Response
*/
public function destroy(Vendor $vendor)
{
$vendor->delete();
return $this->response->noContent();
}
}

View File

@ -1,84 +0,0 @@
<?php
namespace App\Http\Controllers\Api\Incomes;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Income\Customer as Request;
use App\Models\Income\Customer;
use App\Transformers\Income\Customer as Transformer;
use Dingo\Api\Routing\Helpers;
class Customers extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$customers = Customer::collect();
return $this->response->paginator($customers, new Transformer());
}
/**
* Display the specified resource.
*
* @param int|string $id
* @return \Dingo\Api\Http\Response
*/
public function show($id)
{
// Check if we're querying by id or email
if (is_numeric($id)) {
$customer = Customer::find($id);
} else {
$customer = Customer::where('email', $id)->first();
}
return $this->response->item($customer, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$customer = Customer::create($request->all());
return $this->response->created(url('api/customers/'.$customer->id));
}
/**
* Update the specified resource in storage.
*
* @param $customer
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Customer $customer, Request $request)
{
$customer->update($request->all());
return $this->response->item($customer->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Customer $customer
* @return \Dingo\Api\Http\Response
*/
public function destroy(Customer $customer)
{
$customer->delete();
return $this->response->noContent();
}
}

View File

@ -1,126 +0,0 @@
<?php
namespace App\Http\Controllers\Api\Incomes;
use App\Http\Requests\Income\InvoicePayment as Request;
use App\Models\Income\Invoice;
use App\Models\Income\InvoiceHistory;
use App\Models\Income\InvoicePayment;
use App\Models\Setting\Currency;
use App\Traits\DateTime;
use App\Transformers\Income\InvoicePayments as Transformer;
use Date;
use Dingo\Api\Routing\Helpers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class InvoicePayments extends BaseController
{
use DateTime, Helpers, AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* Display a listing of the resource.
*
* @param $invoice_id
* @return \Dingo\Api\Http\Response
*/
public function index($invoice_id)
{
$invoice_payments = InvoicePayment::where('invoice_id', $invoice_id)->get();
return $this->response->collection($invoice_payments, new Transformer());
}
/**
* Display the specified resource.
*
* @param $invoice_id
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function show($invoice_id, $id)
{
$invoice_payment = InvoicePayment::find($id);
return $this->response->item($invoice_payment, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $invoice_id
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store($invoice_id, Request $request)
{
// Get currency object
$currency = Currency::where('code', $request['currency_code'])->first();
$request['currency_code'] = $currency->code;
$request['currency_rate'] = $currency->rate;
$request['invoice_id'] = $invoice_id;
$invoice = Invoice::find($invoice_id);
if ($request['currency_code'] == $invoice->currency_code) {
if ($request['amount'] > $invoice->amount) {
return $this->response->noContent();
} elseif ($request['amount'] == $invoice->amount) {
$invoice->invoice_status_code = 'paid';
} else {
$invoice->invoice_status_code = 'partial';
}
} else {
$request_invoice = new Invoice();
$request_invoice->amount = (float) $request['amount'];
$request_invoice->currency_code = $currency->code;
$request_invoice->currency_rate = $currency->rate;
$amount = $request_invoice->getConvertedAmount();
if ($amount > $invoice->amount) {
return $this->response->noContent();
} elseif ($amount == $invoice->amount) {
$invoice->invoice_status_code = 'paid';
} else {
$invoice->invoice_status_code = 'partial';
}
}
$invoice->save();
$invoice_payment = InvoicePayment::create($request->input());
$request['status_code'] = $invoice->invoice_status_code;
$request['notify'] = 0;
$desc_date = Date::parse($request['paid_at'])->format($this->getCompanyDateFormat());
$desc_amount = money((float) $request['amount'], $request['currency_code'], true)->format();
$request['description'] = $desc_date . ' ' . $desc_amount;
InvoiceHistory::create($request->input());
return $this->response->created(url('api/invoices/' . $invoice_id . '/payments' . $invoice_payment->id));
}
/**
* Remove the specified resource from storage.
*
* @param $invoice_id
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function destroy($invoice_id, $id)
{
$invoice_payment = InvoicePayment::find($id);
$invoice_payment->delete();
return $this->response->noContent();
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace App\Http\Controllers\Api\Incomes;
use App\Http\Requests\Banking\Transaction as Request;
use App\Jobs\Banking\CreateDocumentTransaction;
use App\Jobs\Banking\DeleteTransaction;
use App\Models\Banking\Transaction;
use App\Models\Income\Invoice;
use App\Transformers\Banking\Transaction as Transformer;
use Dingo\Api\Routing\Helpers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class InvoiceTransactions extends BaseController
{
use Helpers, AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* Display a listing of the resource.
*
* @param $invoice_id
* @return \Dingo\Api\Http\Response
*/
public function index($invoice_id)
{
$transactions = Transaction::document($invoice_id)->get();
return $this->response->collection($transactions, new Transformer());
}
/**
* Display the specified resource.
*
* @param $invoice_id
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function show($invoice_id, $id)
{
$transaction = Transaction::document($invoice_id)->find($id);
return $this->response->item($transaction, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $invoice_id
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store($invoice_id, Request $request)
{
$invoice = Invoice::find($invoice_id);
$transaction = $this->dispatch(new CreateDocumentTransaction($invoice, $request));
return $this->response->created(url('api/invoices/' . $invoice_id . '/transactions/' . $transaction->id));
}
/**
* Remove the specified resource from storage.
*
* @param $invoice_id
* @param $id
* @return \Dingo\Api\Http\Response
*/
public function destroy($invoice_id, $id)
{
$transaction = Transaction::document($invoice_id)->find($id);
$this->dispatch(new DeleteTransaction($transaction));
return $this->response->noContent();
}
}

View File

@ -2,25 +2,16 @@
namespace App\Http\Controllers\Api\Incomes;
use App\Events\InvoiceUpdated;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Income\Invoice as Request;
use App\Jobs\Income\CreateInvoice;
use App\Jobs\Income\DeleteInvoice;
use App\Jobs\Income\UpdateInvoice;
use App\Models\Income\Invoice;
use App\Models\Income\InvoiceHistory;
use App\Models\Income\InvoiceItem;
use App\Models\Income\InvoicePayment;
use App\Models\Income\InvoiceTotal;
use App\Models\Common\Item;
use App\Models\Setting\Tax;
use App\Traits\Incomes;
use App\Transformers\Income\Invoice as Transformer;
use Dingo\Api\Routing\Helpers;
class Invoices extends ApiController
{
use Helpers, Incomes;
/**
* Display a listing of the resource.
*
@ -28,7 +19,7 @@ class Invoices extends ApiController
*/
public function index()
{
$invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories'])->collect();
$invoices = Invoice::with(['contact', 'status', 'items', 'transactions', 'histories'])->collect(['invoiced_at'=> 'desc']);
return $this->response->paginator($invoices, new Transformer());
}
@ -59,11 +50,7 @@ class Invoices extends ApiController
*/
public function store(Request $request)
{
if (empty($request['amount'])) {
$request['amount'] = 0;
}
$invoice = dispatch(new CreateInvoice($request));
$invoice = $this->dispatch(new CreateInvoice($request));
return $this->response->created(url('api/invoices/' . $invoice->id));
}
@ -77,89 +64,7 @@ class Invoices extends ApiController
*/
public function update(Invoice $invoice, Request $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']) {
InvoiceItem::where('invoice_id', $invoice->id)->delete();
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;
} 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'];
$request['amount'] += $invoice_item['total'];
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());
// Delete previous invoice totals
InvoiceTotal::where('invoice_id', $invoice->id)->delete();
$this->addTotals($invoice, $request, $taxes, $sub_total, $tax_total);
// Fire the event to make it extendible
event(new InvoiceUpdated($invoice));
$invoice = $this->dispatch(new UpdateInvoice($invoice, $request));
return $this->response->item($invoice->fresh(), new Transformer());
}
@ -172,81 +77,12 @@ class Invoices extends ApiController
*/
public function destroy(Invoice $invoice)
{
$this->deleteRelationships($invoice, ['items', 'histories', 'payments', 'recurring', 'totals']);
$invoice->delete();
try {
$this->dispatch(new DeleteInvoice($invoice));
return $this->response->noContent();
}
protected function addTotals($invoice, $request, $taxes, $sub_total, $tax_total) {
// Add invoice total taxes
if ($request['totals']) {
$sort_order = 1;
foreach ($request['totals'] as $total) {
if (!empty($total['sort_order'])) {
$sort_order = $total['sort_order'];
}
$invoice_total = [
'company_id' => $request['company_id'],
'invoice_id' => $invoice->id,
'code' => $total['code'],
'name' => $total['name'],
'amount' => $total['amount'],
'sort_order' => $sort_order,
];
InvoiceTotal::create($invoice_total);
if (empty($total['sort_order'])) {
$sort_order++;
}
}
} else {
// Added invoice total sub total
$invoice_sub_total = [
'company_id' => $request['company_id'],
'invoice_id' => $invoice->id,
'code' => 'sub_total',
'name' => 'invoices.sub_total',
'amount' => $sub_total,
'sort_order' => 1,
];
InvoiceTotal::create($invoice_sub_total);
$sort_order = 2;
// Added invoice total taxes
if ($taxes) {
foreach ($taxes as $tax) {
$invoice_tax_total = [
'company_id' => $request['company_id'],
'invoice_id' => $invoice->id,
'code' => 'tax',
'name' => $tax['name'],
'amount' => $tax['amount'],
'sort_order' => $sort_order,
];
InvoiceTotal::create($invoice_tax_total);
$sort_order++;
}
}
// Added invoice total total
$invoice_total = [
'company_id' => $request['company_id'],
'invoice_id' => $invoice->id,
'code' => 'total',
'name' => 'invoices.total',
'amount' => $sub_total + $tax_total,
'sort_order' => $sort_order,
];
InvoiceTotal::create($invoice_total);
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace App\Http\Controllers\Api\Incomes;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Income\Revenue as Request;
use App\Models\Income\Revenue;
use App\Transformers\Income\Revenue as Transformer;
use Dingo\Api\Routing\Helpers;
class Revenues extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
* @return \Dingo\Api\Http\Response
*/
public function index()
{
$revenues = Revenue::with(['account', 'customer', 'category'])->collect();
return $this->response->paginator($revenues, new Transformer());
}
/**
* Display the specified resource.
*
* @param Revenue $revenue
* @return \Dingo\Api\Http\Response
*/
public function show(Revenue $revenue)
{
return $this->response->item($revenue, new Transformer());
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function store(Request $request)
{
$revenue = Revenue::create($request->all());
return $this->response->created(url('api/revenues/'.$revenue->id));
}
/**
* Update the specified resource in storage.
*
* @param $revenue
* @param $request
* @return \Dingo\Api\Http\Response
*/
public function update(Revenue $revenue, Request $request)
{
$revenue->update($request->all());
return $this->response->item($revenue->fresh(), new Transformer());
}
/**
* Remove the specified resource from storage.
*
* @param Revenue $revenue
* @return \Dingo\Api\Http\Response
*/
public function destroy(Revenue $revenue)
{
$revenue->delete();
return $this->response->noContent();
}
}

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Settings;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Setting\Category as Request;
use App\Jobs\Setting\CreateCategory;
use App\Jobs\Setting\DeleteCategory;
use App\Jobs\Setting\UpdateCategory;
use App\Models\Setting\Category;
use App\Transformers\Setting\Category as Transformer;
use Dingo\Api\Routing\Helpers;
class Categories extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -43,9 +43,9 @@ class Categories extends ApiController
*/
public function store(Request $request)
{
$category = Category::create($request->all());
$category = $this->dispatch(new CreateCategory($request));
return $this->response->created(url('api/categories/'.$category->id));
return $this->response->created(url('api/categories/' . $category->id));
}
/**
@ -57,9 +57,43 @@ class Categories extends ApiController
*/
public function update(Category $category, Request $request)
{
$category->update($request->all());
try {
$category = $this->dispatch(new UpdateCategory($category, $request));
return $this->response->item($category->fresh(), new Transformer());
return $this->item($category->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
* Enable the specified resource in storage.
*
* @param Category $category
* @return \Dingo\Api\Http\Response
*/
public function enable(Category $category)
{
$category = $this->dispatch(new UpdateCategory($category, request()->merge(['enabled' => 1])));
return $this->item($category->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Category $category
* @return \Dingo\Api\Http\Response
*/
public function disable(Category $category)
{
try {
$category = $this->dispatch(new UpdateCategory($category, request()->merge(['enabled' => 0])));
return $this->item($category->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
@ -70,8 +104,12 @@ class Categories extends ApiController
*/
public function destroy(Category $category)
{
$category->delete();
try {
$this->dispatch(new DeleteCategory($category));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Settings;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Setting\Currency as Request;
use App\Jobs\Setting\CreateCurrency;
use App\Jobs\Setting\DeleteCurrency;
use App\Jobs\Setting\UpdateCurrency;
use App\Models\Setting\Currency;
use App\Transformers\Setting\Currency as Transformer;
use Dingo\Api\Routing\Helpers;
class Currencies extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -27,11 +27,18 @@ class Currencies extends ApiController
/**
* Display the specified resource.
*
* @param Currency $currency
* @param int|string $id
* @return \Dingo\Api\Http\Response
*/
public function show(Currency $currency)
public function show($id)
{
// Check if we're querying by id or code
if (is_numeric($id)) {
$currency = Currency::find($id);
} else {
$currency = Currency::where('code', $id)->first();
}
return $this->response->item($currency, new Transformer());
}
@ -43,9 +50,9 @@ class Currencies extends ApiController
*/
public function store(Request $request)
{
$currency = Currency::create($request->all());
$currency = $this->dispatch(new CreateCurrency($request));
return $this->response->created(url('api/currencies/'.$currency->id));
return $this->response->created(url('api/currencies/' . $currency->id));
}
/**
@ -57,9 +64,43 @@ class Currencies extends ApiController
*/
public function update(Currency $currency, Request $request)
{
$currency->update($request->all());
try {
$currency = $this->dispatch(new UpdateCurrency($currency, $request));
return $this->response->item($currency->fresh(), new Transformer());
return $this->item($currency->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
* Enable the specified resource in storage.
*
* @param Currency $currency
* @return \Dingo\Api\Http\Response
*/
public function enable(Currency $currency)
{
$currency = $this->dispatch(new UpdateCurrency($currency, request()->merge(['enabled' => 1])));
return $this->item($currency->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Currency $currency
* @return \Dingo\Api\Http\Response
*/
public function disable(Currency $currency)
{
try {
$currency = $this->dispatch(new UpdateCurrency($currency, request()->merge(['enabled' => 0])));
return $this->item($currency->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
@ -70,8 +111,12 @@ class Currencies extends ApiController
*/
public function destroy(Currency $currency)
{
$currency->delete();
try {
$this->dispatch(new DeleteCurrency($currency));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Api\Settings;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Setting\Setting as Request;
use App\Models\Setting\Setting;
use App\Transformers\Setting\Setting as Transformer;

View File

@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\Settings;
use App\Http\Controllers\ApiController;
use App\Abstracts\Http\ApiController;
use App\Http\Requests\Setting\Tax as Request;
use App\Jobs\Setting\CreateTax;
use App\Jobs\Setting\DeleteTax;
use App\Jobs\Setting\UpdateTax;
use App\Models\Setting\Tax;
use App\Transformers\Setting\Tax as Transformer;
use Dingo\Api\Routing\Helpers;
class Taxes extends ApiController
{
use Helpers;
/**
* Display a listing of the resource.
*
@ -43,9 +43,9 @@ class Taxes extends ApiController
*/
public function store(Request $request)
{
$tax = Tax::create($request->all());
$tax = $this->dispatch(new CreateTax($request));
return $this->response->created(url('api/taxes/'.$tax->id));
return $this->response->created(url('api/taxes/' . $tax->id));
}
/**
@ -57,9 +57,43 @@ class Taxes extends ApiController
*/
public function update(Tax $tax, Request $request)
{
$tax->update($request->all());
try {
$tax = $this->dispatch(new UpdateTax($tax, $request));
return $this->response->item($tax->fresh(), new Transformer());
return $this->item($tax->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
* Enable the specified resource in storage.
*
* @param Tax $tax
* @return \Dingo\Api\Http\Response
*/
public function enable(Tax $tax)
{
$tax = $this->dispatch(new UpdateTax($tax, request()->merge(['enabled' => 1])));
return $this->item($tax->fresh(), new Transformer());
}
/**
* Disable the specified resource in storage.
*
* @param Tax $tax
* @return \Dingo\Api\Http\Response
*/
public function disable(Tax $tax)
{
try {
$tax = $this->dispatch(new UpdateTax($tax, request()->merge(['enabled' => 0])));
return $this->item($tax->fresh(), new Transformer());
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
/**
@ -70,8 +104,12 @@ class Taxes extends ApiController
*/
public function destroy(Tax $tax)
{
$tax->delete();
try {
$this->dispatch(new DeleteTax($tax));
return $this->response->noContent();
return $this->response->noContent();
} catch(\Exception $e) {
$this->response->errorUnauthorized($e->getMessage());
}
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace App\Http\Controllers;
use Dingo\Api\Exception\ResourceException;
use Illuminate\Http\Request;
class ApiController extends Controller
{
/**
* Create the response for when a request fails validation.
*
* @param \Illuminate\Http\Request $request
* @param array $errors
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function buildFailedValidationResponse(Request $request, array $errors)
{
if ($request->expectsJson()) {
throw new ResourceException('Validation Error', $errors);
}
return redirect()->to($this->getRedirectUrl())->withInput($request->input())->withErrors($errors, $this->errorBag());
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;

View File

@ -2,8 +2,10 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Auth\Login as Request;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Str;
class Login extends Controller
{
@ -46,47 +48,81 @@ class Login extends Controller
return view('auth.login.create');
}
public function store()
public function store(Request $request)
{
// Attempt to login
if (!auth()->attempt(request(['email', 'password']), request('remember', false))) {
flash(trans('auth.failed'))->error();
if (!auth()->attempt($request->only('email', 'password'), $request->get('remember', false))) {
$response = [
'status' => null,
'success' => false,
'error' => true,
'message' => trans('auth.failed'),
'data' => null,
'redirect' => null,
];
return back();
return response()->json($response);
}
// Get user object
$user = auth()->user();
$user = user();
// Check if user is enabled
if (!$user->enabled) {
$this->logout();
flash(trans('auth.disabled'))->error();
$response = [
'status' => null,
'success' => false,
'error' => true,
'message' => trans('auth.disabled'),
'data' => null,
'redirect' => null,
];
return redirect('auth/login');
return response()->json($response);
}
// Check if is customer
if ($user->customer) {
$path = session('url.intended', 'customers');
if ($user->contact) {
$path = session('url.intended', 'portal');
// Path must start with 'customers' prefix
if (!str_contains($path, 'customers')) {
$path = 'customers';
// Path must start with 'portal' prefix
if (!Str::startsWith($path, 'portal')) {
$path = 'portal';
}
return redirect($path);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => null,
'data' => null,
'redirect' => url($path),
];
return response()->json($response);
}
return redirect()->intended('wizard');
session(['dashboard_id' => $user->dashboards()->pluck('id')->first()]);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => null,
'data' => null,
'redirect' => redirect()->intended('wizard')->getTargetUrl(),
];
return response()->json($response);
}
public function destroy()
{
$this->logout();
return redirect('auth/login');
return redirect()->route('login');
}
public function logout()

View File

@ -2,13 +2,15 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Auth\Permission as Request;
use App\Jobs\Auth\CreatePermission;
use App\Jobs\Auth\DeletePermission;
use App\Jobs\Auth\UpdatePermission;
use App\Models\Auth\Permission;
class Permissions extends Controller
{
/**
* Display a listing of the resource.
*
@ -40,14 +42,23 @@ class Permissions extends Controller
*/
public function store(Request $request)
{
// Create permission
$permission = Permission::create($request->all());
$response = $this->ajaxDispatch(new CreatePermission($request));
$message = trans('messages.success.added', ['type' => trans_choice('general.permissions', 1)]);
if ($response['success']) {
$response['redirect'] = route('permissions.index');
flash($message)->success();
$message = trans('messages.success.added', ['type' => trans_choice('general.permissions', 1)]);
return redirect('auth/permissions');
flash($message)->success();
} else {
$response['redirect'] = route('permissions.create');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
@ -65,38 +76,55 @@ class Permissions extends Controller
/**
* Update the specified resource in storage.
*
* @param Permission $permission
* @param Request $request
* @param Permission $permission
* @param Request $request
*
* @return Response
*/
public function update(Permission $permission, Request $request)
{
// Update permission
$permission->update($request->all());
$response = $this->ajaxDispatch(new UpdatePermission($permission, $request));
$message = trans('messages.success.updated', ['type' => trans_choice('general.permissions', 1)]);
if ($response['success']) {
$response['redirect'] = route('permissions.index');
flash($message)->success();
$message = trans('messages.success.updated', ['type' => $permission->display_name]);
return redirect('auth/permissions');
flash($message)->success();
} else {
$response['redirect'] = route('permissions.edit', $permission->id);
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Permission $permission
* @param Permission $permission
*
* @return Response
*/
public function destroy(Permission $permission)
{
$permission->delete();
$response = $this->ajaxDispatch(new DeletePermission($permission));
$message = trans('messages.success.deleted', ['type' => trans_choice('general.permissions', 1)]);
$response['redirect'] = route('permissions.index');
flash($message)->success();
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $permission->display_name]);
return redirect('auth/permissions');
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;

View File

@ -2,14 +2,16 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Auth\Role as Request;
use App\Jobs\Auth\CreateRole;
use App\Jobs\Auth\DeleteRole;
use App\Jobs\Auth\UpdateRole;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
class Roles extends Controller
{
/**
* Display a listing of the resource.
*
@ -55,17 +57,23 @@ class Roles extends Controller
*/
public function store(Request $request)
{
// Create role
$role = Role::create($request->all());
$response = $this->ajaxDispatch(new CreateRole($request));
// Attach permissions
$role->permissions()->attach($request['permissions']);
if ($response['success']) {
$response['redirect'] = route('roles.index');
$message = trans('messages.success.added', ['type' => trans_choice('general.roles', 1)]);
$message = trans('messages.success.added', ['type' => trans_choice('general.roles', 1)]);
flash($message)->success();
flash($message)->success();
} else {
$response['redirect'] = route('roles.create');
return redirect('auth/roles');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
@ -100,41 +108,55 @@ class Roles extends Controller
/**
* Update the specified resource in storage.
*
* @param Role $role
* @param Role $role
* @param Request $request
*
* @return Response
*/
public function update(Role $role, Request $request)
{
// Update role
$role->update($request->all());
$response = $this->ajaxDispatch(new UpdateRole($role, $request));
// Sync permissions
$role->permissions()->sync($request['permissions']);
if ($response['success']) {
$response['redirect'] = route('roles.index');
$message = trans('messages.success.updated', ['type' => trans_choice('general.roles', 1)]);
$message = trans('messages.success.updated', ['type' => $role->display_name]);
flash($message)->success();
flash($message)->success();
} else {
$response['redirect'] = route('roles.edit', $role->id);
return redirect('auth/roles');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Role $role
* @param Role $role
*
* @return Response
*/
public function destroy(Role $role)
{
$role->delete();
$response = $this->ajaxDispatch(new DeleteRole($role));
$message = trans('messages.success.deleted', ['type' => trans_choice('general.roles', 1)]);
$response['redirect'] = route('roles.index');
flash($message)->success();
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $role->display_name]);
return redirect('auth/roles');
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
}

View File

@ -2,14 +2,15 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Auth\User as Request;
use Illuminate\Http\Request as ARequest;
use App\Jobs\Auth\CreateUser;
use App\Jobs\Auth\DeleteUser;
use App\Jobs\Auth\UpdateUser;
use App\Models\Auth\User;
use App\Models\Auth\Role;
use App\Traits\Uploads;
use Auth;
use Illuminate\Http\Request as BaseRequest;
class Users extends Controller
{
@ -24,10 +25,7 @@ class Users extends Controller
{
$users = User::with('roles')->collect();
$roles = collect(Role::all()->pluck('display_name', 'id'))
->prepend(trans('general.all_type', ['type' => trans_choice('general.roles', 2)]), '');
return view('auth.users.index', compact('users', 'roles'));
return view('auth.users.index', compact('users'));
}
/**
@ -38,14 +36,10 @@ class Users extends Controller
public function create()
{
$roles = Role::all()->reject(function ($r) {
return $r->hasPermission('read-customer-panel');
return $r->hasPermission('read-client-portal');
});
$companies = Auth::user()->companies()->get()->sortBy('name');
foreach ($companies as $company) {
$company->setSettings();
}
$companies = user()->companies()->get()->sortBy('name');
return view('auth.users.create', compact('roles', 'companies'));
}
@ -59,27 +53,23 @@ class Users extends Controller
*/
public function store(Request $request)
{
// Create user
$user = User::create($request->input());
$response = $this->ajaxDispatch(new CreateUser($request));
// Upload picture
if ($request->file('picture')) {
$media = $this->getMedia($request->file('picture'), 'users');
if ($response['success']) {
$response['redirect'] = route('users.index');
$user->attachMedia($media, 'picture');
$message = trans('messages.success.added', ['type' => trans_choice('general.users', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('users.create');
$message = $response['message'];
flash($message)->error();
}
// Attach roles
$user->roles()->attach($request['roles']);
// Attach companies
$user->companies()->attach($request['companies']);
$message = trans('messages.success.added', ['type' => trans_choice('general.users', 1)]);
flash($message)->success();
return redirect('auth/users');
return response()->json($response);
}
/**
@ -91,23 +81,19 @@ class Users extends Controller
*/
public function edit(User $user)
{
if ($user->customer) {
if ($user->contact) {
// Show only roles with customer permission
$roles = Role::all()->reject(function ($r) {
return !$r->hasPermission('read-customer-panel');
return !$r->hasPermission('read-client-portal');
});
} else {
// Don't show roles with customer permission
$roles = Role::all()->reject(function ($r) {
return $r->hasPermission('read-customer-panel');
return $r->hasPermission('read-client-portal');
});
}
$companies = Auth::user()->companies()->get()->sortBy('name');
foreach ($companies as $company) {
$company->setSettings();
}
$companies = user()->companies()->get()->sortBy('name');
return view('auth.users.edit', compact('user', 'companies', 'roles'));
}
@ -115,111 +101,98 @@ class Users extends Controller
/**
* Update the specified resource in storage.
*
* @param User $user
* @param Request $request
* @param User $user
* @param Request $request
*
* @return Response
*/
public function update(User $user, Request $request)
{
// Do not reset password if not entered/changed
if (empty($request['password'])) {
unset($request['password']);
unset($request['password_confirmation']);
$response = $this->ajaxDispatch(new UpdateUser($user, $request));
if ($response['success']) {
$response['redirect'] = route('users.index');
$message = trans('messages.success.updated', ['type' => $user->name]);
flash($message)->success();
} else {
$response['redirect'] = route('users.edit', $user->id);
$message = $response['message'];
flash($message)->error();
}
// Update user
$user->update($request->input());
// Upload picture
if ($request->file('picture')) {
$media = $this->getMedia($request->file('picture'), 'users');
$user->attachMedia($media, 'picture');
}
// Sync roles
$user->roles()->sync($request['roles']);
// Sync companies
$user->companies()->sync($request['companies']);
$message = trans('messages.success.updated', ['type' => trans_choice('general.users', 1)]);
flash($message)->success();
return redirect('auth/users');
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param User $user
* @param User $user
*
* @return Response
*/
public function enable(User $user)
{
$user->enabled = 1;
$user->save();
$response = $this->ajaxDispatch(new UpdateUser($user, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.users', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $user->name]);
}
flash($message)->success();
return redirect()->route('users.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param User $user
* @param User $user
*
* @return Response
*/
public function disable(User $user)
{
$user->enabled = 0;
$user->save();
$response = $this->ajaxDispatch(new UpdateUser($user, request()->merge(['enabled' => 0])));
$message = trans('messages.success.disabled', ['type' => trans_choice('general.users', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $user->name]);
}
flash($message)->success();
return redirect()->route('users.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param User $user
* @param User $user
*
* @return Response
*/
public function destroy(User $user)
{
// Can't delete yourself
if ($user->id == \Auth::user()->id) {
$message = trans('auth.error.self_delete');
$response = $this->ajaxDispatch(new DeleteUser($user));
$response['redirect'] = route('users.index');
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $user->name]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
return redirect('auth/users');
}
$user->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.users', 1)]);
flash($message)->success();
return redirect('auth/users');
return response()->json($response);
}
/**
* Mark upcoming bills notifications are read and redirect to bills page.
*
* @param User $user
* @param User $user
*
* @return Response
*/
@ -235,14 +208,13 @@ class Users extends Controller
$notification->markAsRead();
}
// Redirect to bills
return redirect('expenses/bills');
return redirect()->route('bills.index');
}
/**
* Mark overdue invoices notifications are read and redirect to invoices page.
*
* @param User $user
* @param User $user
*
* @return Response
*/
@ -258,34 +230,10 @@ class Users extends Controller
$notification->markAsRead();
}
// Redirect to invoices
return redirect('incomes/invoices');
return redirect()->route('invoices.index');
}
/**
* Mark items out of stock notifications are read and redirect to items page.
*
* @param User $user
*
* @return Response
*/
public function readItemsOutOfStock(User $user)
{
// Mark item notifications as read
foreach ($user->unreadNotifications as $notification) {
// Not an item notification
if ($notification->getAttribute('type') != 'App\Notifications\Common\Item') {
continue;
}
$notification->markAsRead();
}
// Redirect to items
return redirect('common/items');
}
public function autocomplete(ARequest $request)
public function autocomplete(BaseRequest $request)
{
$user = false;
$data = false;

View File

@ -2,14 +2,16 @@
namespace App\Http\Controllers\Banking;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Account as Request;
use App\Jobs\Banking\CreateAccount;
use App\Jobs\Banking\DeleteAccount;
use App\Jobs\Banking\UpdateAccount;
use App\Models\Banking\Account;
use App\Models\Setting\Currency;
class Accounts extends Controller
{
/**
* Display a listing of the resource.
*
@ -29,7 +31,7 @@ class Accounts extends Controller
*/
public function show()
{
return redirect('banking/accounts');
return redirect()->route('accounts.index');
}
/**
@ -41,7 +43,7 @@ class Accounts extends Controller
{
$currencies = Currency::enabled()->pluck('name', 'code');
$currency = Currency::where('code', '=', setting('general.default_currency', 'USD'))->first();
$currency = Currency::where('code', '=', setting('default.currency'))->first();
return view('banking.accounts.create', compact('currencies', 'currency'));
}
@ -55,19 +57,23 @@ class Accounts extends Controller
*/
public function store(Request $request)
{
$account = Account::create($request->all());
$response = $this->ajaxDispatch(new CreateAccount($request));
// Set default account
if ($request['default_account']) {
setting()->set('general.default_account', $account->id);
setting()->save();
if ($response['success']) {
$response['redirect'] = route('accounts.index');
$message = trans('messages.success.added', ['type' => trans_choice('general.accounts', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('accounts.create');
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.added', ['type' => trans_choice('general.accounts', 1)]);
flash($message)->success();
return redirect('banking/accounts');
return response()->json($response);
}
/**
@ -81,7 +87,7 @@ class Accounts extends Controller
{
$currencies = Currency::enabled()->pluck('name', 'code');
$account->default_account = ($account->id == setting('general.default_account')) ? 1 : 0;
$account->default_account = ($account->id == setting('default.account')) ? 1 : 0;
$currency = Currency::where('code', '=', $account->currency_code)->first();
@ -91,131 +97,92 @@ class Accounts extends Controller
/**
* Update the specified resource in storage.
*
* @param Account $account
* @param Request $request
* @param Account $account
* @param Request $request
*
* @return Response
*/
public function update(Account $account, Request $request)
{
// 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',
]);
$response = $this->ajaxDispatch(new UpdateAccount($account, $request));
if (!$request['enabled'] && $account->id == setting('general.default_account')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
}
if ($response['success']) {
$response['redirect'] = route('accounts.index');
if (empty($relationships)) {
$account->update($request->all());
// Set default account
if ($request['default_account']) {
setting()->set('general.default_account', $account->id);
setting()->save();
}
$message = trans('messages.success.updated', ['type' => trans_choice('general.accounts', 1)]);
$message = trans('messages.success.updated', ['type' => $account->name]);
flash($message)->success();
return redirect('banking/accounts');
} else {
$message = trans('messages.warning.disable_code', ['name' => $account->name, 'text' => implode(', ', $relationships)]);
$response['redirect'] = route('accounts.edit', $account->id);
flash($message)->warning();
$message = $response['message'];
return redirect('banking/accounts/' . $account->id . '/edit');
flash($message)->error();
}
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Account $account
* @param Account $account
*
* @return Response
*/
public function enable(Account $account)
{
$account->enabled = 1;
$account->save();
$response = $this->ajaxDispatch(new UpdateAccount($account, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.accounts', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $account->name]);
}
flash($message)->success();
return redirect()->route('accounts.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Account $account
* @param Account $account
*
* @return Response
*/
public function disable(Account $account)
{
if ($account->id == setting('general.default_account')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
$response = $this->ajaxDispatch(new UpdateAccount($account, request()->merge(['enabled' => 0])));
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $account->name]);
}
if (empty($relationships)) {
$account->enabled = 0;
$account->save();
$message = trans('messages.success.disabled', ['type' => trans_choice('general.accounts', 1)]);
flash($message)->success();
} else {
$message = trans('messages.warning.disabled', ['name' => $account->name, 'text' => implode(', ', $relationships)]);
flash($message)->warning();
}
return redirect()->route('accounts.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Account $account
* @param Account $account
*
* @return Response
*/
public function destroy(Account $account)
{
$relationships = $this->countRelationships($account, [
'bill_payments' => 'bills',
'payments' => 'payments',
'invoice_payments' => 'invoices',
'revenues' => 'revenues',
]);
$response = $this->ajaxDispatch(new DeleteAccount($account));
if ($account->id == setting('general.default_account')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
$response['redirect'] = route('accounts.index');
if (empty($relationships)) {
$account->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.accounts', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $account->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $account->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect('banking/accounts');
return response()->json($response);
}
public function currency()
@ -232,7 +199,7 @@ class Accounts extends Controller
return response()->json([]);
}
$currency_code = setting('general.default_currency');
$currency_code = setting('default.currency');
if (isset($account->currency_code)) {
$currencies = Currency::enabled()->pluck('name', 'code')->toArray();

View File

@ -2,13 +2,15 @@
namespace App\Http\Controllers\Banking;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Reconciliation as Request;
use App\Http\Requests\Banking\ReconciliationCalculate as CalculateRequest;
use App\Jobs\Banking\CreateReconciliation;
use App\Jobs\Banking\DeleteReconciliation;
use App\Jobs\Banking\UpdateReconciliation;
use App\Models\Banking\Account;
use App\Models\Banking\Reconciliation;
use App\Models\Setting\Currency;
use Date;
use App\Models\Banking\Transaction;
class Reconciliations extends Controller
{
@ -45,7 +47,7 @@ class Reconciliations extends Controller
{
$accounts = Account::enabled()->pluck('name', 'id');
$account_id = request('account_id', setting('general.default_account'));
$account_id = request('account_id', setting('default.account'));
$started_at = request('started_at', '0000-00-00');
$ended_at = request('ended_at', '0000-00-00');
@ -55,7 +57,7 @@ class Reconciliations extends Controller
$transactions = $this->getTransactions($account, $started_at, $ended_at);
$opening_balance = $this->getOpeningBalance($account, $started_at, $ended_at);
$opening_balance = $this->getOpeningBalance($account, $started_at);
return view('banking.reconciliations.create', compact('accounts', 'account', 'currency', 'opening_balance', 'transactions'));
}
@ -69,34 +71,23 @@ class Reconciliations extends Controller
*/
public function store(Request $request)
{
$reconcile = $request->get('reconcile');
$transactions = $request->get('transactions');
$response = $this->ajaxDispatch(new CreateReconciliation($request));
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 ($response['success']) {
$response['redirect'] = route('reconciliations.index');
if ($transactions) {
foreach ($transactions as $key => $value) {
$t = explode('_', $key);
$m = '\\' . $t['1'];
$message = trans('messages.success.added', ['type' => trans_choice('general.reconciliations', 1)]);
$transaction = $m::find($t[0]);
$transaction->reconciled = 1;
$transaction->save();
}
flash($message)->success();
} else {
$response['redirect'] = route('reconciliations.create');
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.added', ['type' => trans_choice('general.reconciliations', 1)]);
flash($message)->success();
return redirect()->route('reconciliations.index');
return response()->json($response);
}
/**
@ -122,119 +113,73 @@ class Reconciliations extends Controller
/**
* Update the specified resource in storage.
*
* @param Reconciliation $reconciliation
* @param Request $request
* @param Reconciliation $reconciliation
* @param Request $request
*
* @return Response
*/
public function update(Reconciliation $reconciliation, Request $request)
{
$reconcile = $request->get('reconcile');
$transactions = $request->get('transactions');
$response = $this->ajaxDispatch(new UpdateReconciliation($reconciliation, $request));
$reconciliation->reconciled = $reconcile ? 1 : 0;
$reconciliation->save();
if ($response['success']) {
$response['redirect'] = route('reconciliations.index');
if ($transactions) {
foreach ($transactions as $key => $value) {
$t = explode('_', $key);
$m = '\\' . $t['1'];
$message = trans('messages.success.updated', ['type' => trans_choice('general.reconciliations', 1)]);
$transaction = $m::find($t[0]);
$transaction->reconciled = 1;
$transaction->save();
}
flash($message)->success();
} else {
$response['redirect'] = route('reconciliations.edit', $reconciliation->id);
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.updated', ['type' => trans_choice('general.reconciliations', 1)]);
flash($message)->success();
return redirect()->route('reconciliations.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Reconciliation $reconciliation
* @param Reconciliation $reconciliation
*
* @return Response
*/
public function destroy(Reconciliation $reconciliation)
{
$reconciliation->delete();
$response = $this->ajaxDispatch(new DeleteReconciliation($reconciliation));
$models = [
'App\Models\Expense\Payment',
'App\Models\Expense\BillPayment',
'App\Models\Income\Revenue',
'App\Models\Income\InvoicePayment',
];
$response['redirect'] = route('reconciliations.index');
foreach ($models as $model) {
$m = '\\' . $model;
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.reconciliations', 1)]);
$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();
});
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.deleted', ['type' => trans_choice('general.reconciliations', 1)]);
flash($message)->success();
return redirect()->route('reconciliations.index');
return response()->json($response);
}
/**
* Add transactions array.
*
* @param $account_id
* @param $account
* @param $started_at
* @param $ended_at
*
* @return array
* @return mixed
*/
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\InvoicePayment') || ($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;
});
}
$transactions = Transaction::where('account_id', $account->id)->whereBetween('paid_at', [$started[0], $ended[0]])->get();
return collect($transactions)->sortByDesc('paid_at');
}
@ -252,24 +197,12 @@ class Reconciliations extends Controller
// 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) {
@ -292,9 +225,9 @@ class Reconciliations extends Controller
$opening_balance = $request['opening_balance'];
foreach ($transactions as $key => $value) {
$model = explode('_', $key);
$k = explode('_', $key);
if (($model[1] == 'App\Models\Income\InvoicePayment') || ($model[1] == 'App\Models\Income\Revenue')) {
if ($k[1] == 'income') {
$income_total += $value;
} else {
$expense_total += $value;

View File

@ -2,20 +2,17 @@
namespace App\Http\Controllers\Banking;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Exports\Banking\Transactions as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Imports\Banking\Transactions as Import;
use App\Jobs\Banking\DeleteTransaction;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Expense\BillPayment;
use App\Models\Expense\Payment;
use App\Models\Income\InvoicePayment;
use App\Models\Income\Revenue;
use App\Models\Setting\Category;
class Transactions extends Controller
{
public $transactions = [];
/**
* Display a listing of the resource.
*
@ -23,79 +20,70 @@ class Transactions extends Controller
*/
public function index()
{
$request = request();
$accounts = collect(Account::enabled()->pluck('name', 'id'));
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$types = collect(['expense' => 'Expense', 'income' => 'Income'])
->prepend(trans('general.all_type', ['type' => trans_choice('general.types', 2)]), '');
$type = $request->get('type');
$request_type = !request()->has('type') ? ['income', 'expense'] : request('type');
$categories = Category::enabled()->type($request_type)->orderBy('name')->pluck('name', 'id');
$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));
}
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));
}
$transactions = $this->getTransactions($request);
$transactions = Transaction::with(['account', 'category', 'contact'])->collect(['paid_at'=> 'desc']);
return view('banking.transactions.index', compact('transactions', 'accounts', 'types', 'categories'));
}
/**
* Add items to transactions array.
* Import the specified resource.
*
* @param $items
* @param $type
* @param ImportRequest $request
*
* @return Response
*/
protected function addTransactions($items, $type)
public function import(ImportRequest $request)
{
foreach ($items as $item) {
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');
}
}
\Excel::import(new Import(), $request->file('import'));
$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,
];
}
$message = trans('messages.success.imported', ['type' => trans_choice('general.transactions', 2)]);
flash($message)->success();
return redirect()->route('transactions.index');
}
protected function getTransactions($request)
/**
* Remove the specified resource from storage.
*
* @param Transaction $transaction
*
* @return Response
*/
public function destroy(Transaction $transaction)
{
// Sort items
if (isset($request['sort'])) {
if ($request['order'] == 'asc') {
$f = 'sortBy';
} else {
$f = 'sortByDesc';
}
$response = $this->ajaxDispatch(new DeleteTransaction($transaction));
$transactions = collect($this->transactions)->$f($request['sort']);
$response['redirect'] = url()->previous();
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.transactions', 1)]);
flash($message)->success();
} else {
$transactions = collect($this->transactions)->sortByDesc('paid_at');
$message = $response['message'];
flash($message)->error();
}
return $transactions;
return response()->json($response);
}
/**
* Export the specified resource.
*
* @return Response
*/
public function export()
{
return \Excel::download(new Export(), trans_choice('general.transactions', 2) . '.xlsx');
}
}

View File

@ -2,22 +2,19 @@
namespace App\Http\Controllers\Banking;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Transfer as Request;
use App\Jobs\Banking\CreateTransfer;
use App\Jobs\Banking\UpdateTransfer;
use App\Jobs\Banking\DeleteTransfer;
use App\Models\Banking\Account;
use App\Models\Banking\Transfer;
use App\Models\Expense\Payment;
use App\Models\Income\Revenue;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use Date;
use App\Utilities\Modules;
use Date;
class Transfers extends Controller
{
/**
* Display a listing of the resource.
*
@ -25,45 +22,43 @@ class Transfers extends Controller
*/
public function index()
{
$request = request();
$data = [];
$items = Transfer::with(['payment', 'payment.account', 'revenue', 'revenue.account'])->collect(['payment.paid_at' => 'desc']);
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'))
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
$transfers = array();
$items = Transfer::with([
'expense_transaction', 'expense_transaction.account', 'income_transaction', 'income_transaction.account'
])->collect(['expense_transaction.paid_at' => 'desc']);
foreach ($items as $item) {
$revenue = $item->revenue;
$payment = $item->payment;
$income_transaction = $item->income_transaction;
$expense_transaction = $item->expense_transaction;
$name = trans('transfers.messages.delete', [
'from' => $payment->account->name,
'to' => $revenue->account->name,
'amount' => money($payment->amount, $payment->currency_code, true)
'from' => $expense_transaction->account->name,
'to' => $income_transaction->account->name,
'amount' => money($expense_transaction->amount, $expense_transaction->currency_code, true)
]);
$transfers[] = (object)[
$data[] = (object) [
'id' => $item->id,
'name' => $name,
'from_account' => $payment->account->name,
'to_account' => $revenue->account->name,
'amount' => $payment->amount,
'currency_code' => $payment->currency_code,
'paid_at' => $payment->paid_at,
'from_account' => $expense_transaction->account->name,
'to_account' => $income_transaction->account->name,
'amount' => $expense_transaction->amount,
'currency_code' => $expense_transaction->currency_code,
'paid_at' => $expense_transaction->paid_at,
];
}
$special_key = array(
'payment.name' => 'from_account',
'revenue.name' => 'to_account',
'expense_transaction.name' => 'from_account',
'income_transaction.name' => 'to_account',
);
$request = request();
if (isset($request['sort']) && array_key_exists($request['sort'], $special_key)) {
$sort_order = array();
foreach ($transfers as $key => $value) {
foreach ($data as $key => $value) {
$sort = $request['sort'];
if (array_key_exists($request['sort'], $special_key)) {
@ -75,10 +70,15 @@ class Transfers extends Controller
$sort_type = (isset($request['order']) && $request['order'] == 'asc') ? SORT_ASC : SORT_DESC;
array_multisort($sort_order, $sort_type, $transfers);
array_multisort($sort_order, $sort_type, $data);
}
return view('banking.transfers.index', compact('transfers', 'items', 'accounts'));
$transfers = $this->paginate($data);
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'))
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
return view('banking.transfers.index', compact('transfers', 'accounts'));
}
/**
@ -88,7 +88,7 @@ class Transfers extends Controller
*/
public function show()
{
return redirect('banking/transfers');
return redirect()->route('transfers.index');
}
/**
@ -102,7 +102,7 @@ class Transfers extends Controller
$payment_methods = Modules::getPaymentMethods();
$currency = Currency::where('code', '=', setting('general.default_currency', 'USD'))->first();
$currency = Currency::where('code', setting('default.currency'))->first();
return view('banking.transfers.create', compact('accounts', 'payment_methods', 'currency'));
}
@ -116,113 +116,49 @@ class Transfers extends Controller
*/
public function store(Request $request)
{
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$response = $this->ajaxDispatch(new CreateTransfer($request));
$payment_currency_code = Account::where('id', $request['from_account_id'])->pluck('currency_code')->first();
$revenue_currency_code = Account::where('id', $request['to_account_id'])->pluck('currency_code')->first();
if ($response['success']) {
$response['redirect'] = route('transfers.index');
$payment_request = [
'company_id' => $request['company_id'],
'account_id' => $request['from_account_id'],
'paid_at' => $request['transferred_at'],
'currency_code' => $payment_currency_code,
'currency_rate' => $currencies[$payment_currency_code],
'amount' => $request['amount'],
'vendor_id' => 0,
'description' => $request['description'],
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $request['payment_method'],
'reference' => $request['reference'],
];
$message = trans('messages.success.added', ['type' => trans_choice('general.transfers', 1)]);
$payment = Payment::create($payment_request);
// Convert amount if not same currency
if ($payment_currency_code != $revenue_currency_code) {
$default_currency = setting('general.default_currency', 'USD');
$default_amount = $request['amount'];
if ($default_currency != $payment_currency_code) {
$default_amount_model = new Transfer();
$default_amount_model->default_currency_code = $default_currency;
$default_amount_model->amount = $request['amount'];
$default_amount_model->currency_code = $payment_currency_code;
$default_amount_model->currency_rate = $currencies[$payment_currency_code];
$default_amount = $default_amount_model->getDivideConvertedAmount();
}
$transfer_amount = new Transfer();
$transfer_amount->default_currency_code = $payment_currency_code;
$transfer_amount->amount = $default_amount;
$transfer_amount->currency_code = $revenue_currency_code;
$transfer_amount->currency_rate = $currencies[$revenue_currency_code];
$amount = $transfer_amount->getDynamicConvertedAmount();
flash($message)->success();
} else {
$amount = $request['amount'];
$response['redirect'] = route('transfers.create');
$message = $response['message'];
flash($message)->error();
}
$revenue_request = [
'company_id' => $request['company_id'],
'account_id' => $request['to_account_id'],
'paid_at' => $request['transferred_at'],
'currency_code' => $revenue_currency_code,
'currency_rate' => $currencies[$revenue_currency_code],
'amount' => $amount,
'customer_id' => 0,
'description' => $request['description'],
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $request['payment_method'],
'reference' => $request['reference'],
];
$revenue = Revenue::create($revenue_request);
$transfer_request = [
'company_id' => $request['company_id'],
'payment_id' => $payment->id,
'revenue_id' => $revenue->id,
];
Transfer::create($transfer_request);
$message = trans('messages.success.added', ['type' => trans_choice('general.transfers', 1)]);
flash($message)->success();
return redirect('banking/transfers');
return response()->json($response);
}
/**
* Show the form for editing the specified resource.
*
* @param Request $request
* @param Transfer $transfer
*
* @return Response
*/
public function edit(Transfer $transfer)
{
$payment = Payment::findOrFail($transfer->payment_id);
$revenue = Revenue::findOrFail($transfer->revenue_id);
$transfer['from_account_id'] = $transfer->expense_transaction->account_id;
$transfer['to_account_id'] = $transfer->income_transaction->account_id;
$transfer['transferred_at'] = Date::parse($transfer->expense_transaction->paid_at)->format('Y-m-d');
$transfer['description'] = $transfer->expense_transaction->description;
$transfer['amount'] = $transfer->expense_transaction->amount;
$transfer['payment_method'] = $transfer->expense_transaction->payment_method;
$transfer['reference'] = $transfer->expense_transaction->reference;
$transfer['from_account_id'] = $payment->account_id;
$transfer['to_account_id'] = $revenue->account_id;
$transfer['transferred_at'] = Date::parse($payment->paid_at)->format('Y-m-d');
$transfer['description'] = $payment->description;
$transfer['amount'] = $payment->amount;
$transfer['payment_method'] = $payment->payment_method;
$transfer['reference'] = $payment->reference;
$account = Account::find($payment->account_id);
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
$currency = Currency::where('code', '=', $account->currency_code)->first();
$account = $transfer->expense_transaction->account;
$currency = Currency::where('code', $account->currency_code)->first();
return view('banking.transfers.edit', compact('transfer', 'accounts', 'payment_methods', 'currency'));
}
@ -230,117 +166,55 @@ class Transfers extends Controller
/**
* Update the specified resource in storage.
*
* @param Transfer $transfer
* @param $id
* @param Request $request
*
* @return Response
*/
public function update(Transfer $transfer, Request $request)
{
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$response = $this->ajaxDispatch(new UpdateTransfer($transfer, $request));
$payment_currency_code = Account::where('id', $request['from_account_id'])->pluck('currency_code')->first();
$revenue_currency_code = Account::where('id', $request['to_account_id'])->pluck('currency_code')->first();
if ($response['success']) {
$response['redirect'] = route('transfers.index');
$payment = Payment::findOrFail($transfer->payment_id);
$revenue = Revenue::findOrFail($transfer->revenue_id);
$message = trans('messages.success.updated', ['type' => trans_choice('general.transfers', 1)]);
$payment_request = [
'company_id' => $request['company_id'],
'account_id' => $request['from_account_id'],
'paid_at' => $request['transferred_at'],
'currency_code' => $payment_currency_code,
'currency_rate' => $currencies[$payment_currency_code],
'amount' => $request['amount'],
'vendor_id' => 0,
'description' => $request['description'],
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $request['payment_method'],
'reference' => $request['reference'],
];
$payment->update($payment_request);
// Convert amount if not same currency
if ($payment_currency_code != $revenue_currency_code) {
$default_currency = setting('general.default_currency', 'USD');
$default_amount = $request['amount'];
if ($default_currency != $payment_currency_code) {
$default_amount_model = new Transfer();
$default_amount_model->default_currency_code = $default_currency;
$default_amount_model->amount = $request['amount'];
$default_amount_model->currency_code = $payment_currency_code;
$default_amount_model->currency_rate = $currencies[$payment_currency_code];
$default_amount = $default_amount_model->getDivideConvertedAmount();
}
$transfer_amount = new Transfer();
$transfer_amount->default_currency_code = $payment_currency_code;
$transfer_amount->amount = $default_amount;
$transfer_amount->currency_code = $revenue_currency_code;
$transfer_amount->currency_rate = $currencies[$revenue_currency_code];
$amount = $transfer_amount->getDynamicConvertedAmount();
flash($message)->success();
} else {
$amount = $request['amount'];
$response['redirect'] = route('transfers.edit', $transfer->id);
$message = $response['message'];
flash($message)->error();
}
$revenue_request = [
'company_id' => $request['company_id'],
'account_id' => $request['to_account_id'],
'paid_at' => $request['transferred_at'],
'currency_code' => $revenue_currency_code,
'currency_rate' => $currencies[$revenue_currency_code],
'amount' => $amount,
'customer_id' => 0,
'description' => $request['description'],
'category_id' => Category::transfer(), // Transfer Category ID
'payment_method' => $request['payment_method'],
'reference' => $request['reference'],
];
$revenue->update($revenue_request);
$transfer_request = [
'company_id' => $request['company_id'],
'payment_id' => $payment->id,
'revenue_id' => $revenue->id,
];
$transfer->update($transfer_request);
$message = trans('messages.success.updated', ['type' => trans_choice('general.transfers', 1)]);
flash($message)->success();
return redirect('banking/transfers');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Transfer $transfer
* @param $id
*
* @return Response
*/
public function destroy(Transfer $transfer)
{
$payment = Payment::findOrFail($transfer->payment_id);
$revenue = Revenue::findOrFail($transfer->revenue_id);
$response = $this->ajaxDispatch(new DeleteTransfer($transfer));
$payment->delete();
$revenue->delete();
$transfer->delete();
$response['redirect'] = route('transfers.index');
$message = trans('messages.success.deleted', ['type' => trans_choice('general.transfers', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.transfers', 1)]);
flash($message)->success();
flash($message)->success();
} else {
$message = $response['message'];
return redirect('banking/transfers');
flash($message)->error();
}
return response()->json($response);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\Http\Controllers\Common;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\BulkAction as Request;
class
BulkActions extends Controller
{
/**
* Show the form for creating a new resource.
*
* @param $group
* @param $type
* @param Request $request
* @return Response
*/
public function action($group, $type, Request $request)
{
// Check is module
$module = module($group);
if ($module instanceof \Akaunting\Module\Module) {
$bulk_actions = app('Modules\\' . $module->getStudlyName() . '\BulkActions\\' . ucfirst($type));
} else {
$bulk_actions = app('App\BulkActions\\' . ucfirst($group) . '\\' . ucfirst($type));
}
$bulk_actions->{$request->get('handle')}($request);
return view('common.import.create', compact('group', 'type', 'path', 'namespace'));
}
}

View File

@ -2,17 +2,20 @@
namespace App\Http\Controllers\Common;
use App\Events\CompanySwitched;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\Company as Request;
use App\Jobs\Common\CreateCompany;
use App\Jobs\Common\DeleteCompany;
use App\Jobs\Common\UpdateCompany;
use App\Models\Common\Company;
use App\Models\Setting\Currency;
use App\Traits\Uploads;
use App\Traits\Users;
use App\Utilities\Overrider;
class Companies extends Controller
{
use Uploads;
use Uploads, Users;
/**
* Display a listing of the resource.
@ -23,10 +26,6 @@ class Companies extends Controller
{
$companies = Company::collect();
foreach ($companies as $company) {
$company->setSettings();
}
return view('common.companies.index', compact('companies'));
}
@ -37,7 +36,7 @@ class Companies extends Controller
*/
public function show()
{
return redirect('common/companies');
return redirect()->route('companies.index');
}
/**
@ -63,40 +62,27 @@ class Companies extends Controller
{
$company_id = session('company_id');
// Create company
$company = Company::create($request->input());
// Create settings
setting()->set('general.company_name', $request->get('company_name'));
setting()->set('general.company_email', $request->get('company_email'));
setting()->set('general.company_address', $request->get('company_address'));
$response = $this->ajaxDispatch(new CreateCompany($request));
if ($request->file('company_logo')) {
$company_logo = $this->getMedia($request->file('company_logo'), 'settings', $company->id);
if ($response['success']) {
$response['redirect'] = route('companies.index');
if ($company_logo) {
$company->attachMedia($company_logo, 'company_logo');
$message = trans('messages.success.added', ['type' => trans_choice('general.companies', 1)]);
setting()->set('general.company_logo', $company_logo->id);
}
flash($message)->success();
} else {
$response['redirect'] = route('companies.create');
$message = $response['message'];
flash($message)->error();
}
setting()->set('general.default_currency', $request->get('default_currency'));
setting()->set('general.default_locale', session('locale'));
setting()->save();
setting()->forgetAll();
session(['company_id' => $company_id]);
Overrider::load('settings');
// Redirect
$message = trans('messages.success.added', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
return redirect('common/companies');
return response()->json($response);
}
/**
@ -108,17 +94,10 @@ class Companies extends Controller
*/
public function edit(Company $company)
{
// Check if user can edit company
if (!$this->isUserCompany($company)) {
$message = trans('companies.error.not_user_company');
flash($message)->error();
return redirect('common/companies');
if (!$this->isUserCompany($company->id)) {
return redirect()->route('companies.index');
}
$company->setSettings();
$currencies = Currency::enabled()->pluck('name', 'code');
return view('common.companies.edit', compact('company', 'currencies'));
@ -127,8 +106,8 @@ class Companies extends Controller
/**
* Update the specified resource in storage.
*
* @param Company $company
* @param Request $request
* @param Company $company
* @param Request $request
*
* @return Response
*/
@ -136,132 +115,89 @@ class Companies extends Controller
{
$company_id = session('company_id');
// Check if user can update company
if (!$this->isUserCompany($company)) {
$message = trans('companies.error.not_user_company');
$response = $this->ajaxDispatch(new UpdateCompany($company, $request));
if ($response['success']) {
$response['redirect'] = route('companies.index');
$message = trans('messages.success.updated', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('companies.edit', $company->id);
$message = $response['message'];
flash($message)->error();
return redirect('common/companies');
}
// Update company
$company->update($request->input());
// Get the company settings
setting()->forgetAll();
setting()->setExtraColumns(['company_id' => $company->id]);
setting()->load(true);
// Update settings
setting()->set('general.company_name', $request->get('company_name'));
setting()->set('general.company_email', $request->get('company_email'));
setting()->set('general.company_address', $request->get('company_address'));
if ($request->file('company_logo')) {
$company_logo = $this->getMedia($request->file('company_logo'), 'settings', $company->id);
if ($company_logo) {
$company->attachMedia($company_logo, 'company_logo');
setting()->set('general.company_logo', $company_logo->id);
}
}
setting()->set('general.default_payment_method', 'offlinepayment.cash.1');
setting()->set('general.default_currency', $request->get('default_currency'));
setting()->save();
setting()->forgetAll();
session(['company_id' => $company_id]);
Overrider::load('settings');
// Redirect
$message = trans('messages.success.updated', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
return redirect('common/companies');
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Company $company
* @param Company $company
*
* @return Response
*/
public function enable(Company $company)
{
$company->enabled = 1;
$company->save();
$response = $this->ajaxDispatch(new UpdateCompany($company, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
return redirect()->route('companies.index');
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => trans_choice('general.companies', 1)]);
}
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Company $company
* @param Company $company
*
* @return Response
*/
public function disable(Company $company)
{
// Check if user can update company
if (!$this->isUserCompany($company)) {
$message = trans('companies.error.not_user_company');
$response = $this->ajaxDispatch(new UpdateCompany($company, request()->merge(['enabled' => 0])));
Overrider::load('settings');
flash($message)->error();
return redirect()->route('companies.index');
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => trans_choice('general.companies', 1)]);
}
$company->enabled = 0;
$company->save();
$message = trans('messages.success.disabled', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
return redirect()->route('companies.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Company $company
* @param Company $company
*
* @return Response
*/
public function destroy(Company $company)
{
// Can't delete active company
if ($company->id == session('company_id')) {
$message = trans('companies.error.delete_active');
$response = $this->ajaxDispatch(new DeleteCompany($company));
$response['redirect'] = route('companies.index');
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
return redirect('common/companies');
}
$company->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.companies', 1)]);
flash($message)->success();
return redirect('common/companies');
return response()->json($response);
}
/**
@ -271,40 +207,24 @@ class Companies extends Controller
*
* @return Response
*/
public function set(Company $company)
public function switch(Company $company)
{
// Check if user can manage company
if ($this->isUserCompany($company)) {
if ($this->isUserCompany($company->id)) {
$old_company_id = session('company_id');
session(['company_id' => $company->id]);
session(['dashboard_id' => $company->dashboards()->pluck('id')->first()]);
Overrider::load('settings');
event(new CompanySwitched($company));
}
event(new \App\Events\Common\CompanySwitched($company, $old_company_id));
// Check wizard
if (!setting('general.wizard', false)) {
return redirect('wizard');
// Check wizard
if (!setting('wizard.completed', false)) {
return redirect()->route('wizard.edit');
}
}
return redirect('/');
}
/**
* Check user company assignment
*
* @param Company $company
*
* @return boolean
*/
public function isUserCompany(Company $company)
{
$companies = auth()->user()->companies()->pluck('id')->toArray();
if (in_array($company->id, $companies)) {
return true;
}
return false;
}
}

View File

@ -2,33 +2,14 @@
namespace App\Http\Controllers\Common;
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\Income\Invoice;
use App\Models\Income\InvoicePayment;
use App\Models\Income\Revenue;
use App\Models\Setting\Category;
use App\Traits\Currencies;
use App\Traits\DateTime;
use Charts;
use Date;
use App\Abstracts\Http\Controller;
use App\Models\Common\Dashboard as Model;
use App\Models\Common\DashboardWidget;
use App\Http\Requests\Common\Dashboard as Request;
class Dashboard extends Controller
{
use Currencies, DateTime;
public $today;
// get any custom financial year beginning
public $financial_start;
public $income_donut = ['colors' => [], 'labels' => [], 'values' => []];
public $expense_donut = ['colors' => [], 'labels' => [], 'values' => []];
/**
* Display a listing of the resource.
*
@ -36,424 +17,98 @@ class Dashboard extends Controller
*/
public function index()
{
$this->today = Date::today();
$this->financial_start = $financial_start = $this->getFinancialStart()->format('Y-m-d');
$dashboard_id = session('dashboard_id', 0);
list($total_incomes, $total_expenses, $total_profit) = $this->getTotals();
// Change Dashboard
if (request()->get('dashboard_id', 0)) {
$dashboard_id = request()->get('dashboard_id');
$cashflow = $this->getCashFlow();
session(['dashboard_id' => $dashboard_id]);
}
list($donut_incomes, $donut_expenses) = $this->getDonuts();
$user_id = user()->id;
$accounts = Account::enabled()->take(6)->get();
$dashboards = Model::where('user_id', $user_id)->enabled()->get();
$latest_incomes = $this->getLatestIncomes();
if (!$dashboard_id) {
$dashboard_id = $dashboards->first()->id;
}
$latest_expenses = $this->getLatestExpenses();
// Dashboard
$dashboard = Model::find($dashboard_id);
return view('common.dashboard.index', compact(
'total_incomes',
'total_expenses',
'total_profit',
'cashflow',
'donut_incomes',
'donut_expenses',
'accounts',
'latest_incomes',
'latest_expenses',
'financial_start'
));
// Dashboard Widgets
$widgets = DashboardWidget::where('dashboard_id', $dashboard->id)
->where('user_id', $user_id)
->orderBy('sort', 'asc')->get();
return view('common.dashboard.index', compact('dashboards','dashboard', 'widgets'));
}
public function cashFlow()
/**
* Store a newly created resource in storage.
*
* @param $request
* @return Response
*/
public function store(Request $request)
{
$this->today = Date::today();
$request['enabled'] = 1;
$request['user_id'] = user()->id;
$content = $this->getCashFlow()->render();
$dashboard = Model::create($request->input());
//return response()->setContent($content)->send();
$response['data'] = $dashboard;
$response['redirect'] = route('dashboard');
echo $content;
return response()->json($response);
}
private function getTotals()
/**
* Show the form for editing the specified resource.
*
* @param Model $dashboard
*
* @return Response
*/
public function edit(Model $dashboard)
{
list($incomes_amount, $open_invoice, $overdue_invoice, $expenses_amount, $open_bill, $overdue_bill) = $this->calculateAmounts();
$incomes_progress = 100;
if (!empty($open_invoice) && !empty($overdue_invoice)) {
$incomes_progress = (int) ($open_invoice * 100) / ($open_invoice + $overdue_invoice);
}
// Totals
$total_incomes = array(
'total' => $incomes_amount,
'open_invoice' => money($open_invoice, setting('general.default_currency'), true),
'overdue_invoice' => money($overdue_invoice, setting('general.default_currency'), true),
'progress' => $incomes_progress
);
$expenses_progress = 100;
if (!empty($open_bill) && !empty($overdue_bill)) {
$expenses_progress = (int) ($open_bill * 100) / ($open_bill + $overdue_bill);
}
$total_expenses = array(
'total' => $expenses_amount,
'open_bill' => money($open_bill, setting('general.default_currency'), true),
'overdue_bill' => money($overdue_bill, setting('general.default_currency'), true),
'progress' => $expenses_progress
);
$amount_profit = $incomes_amount - $expenses_amount;
$open_profit = $open_invoice - $open_bill;
$overdue_profit = $overdue_invoice - $overdue_bill;
$total_progress = 100;
if (!empty($open_profit) && !empty($overdue_profit)) {
$total_progress = (int) ($open_profit * 100) / ($open_profit + $overdue_profit);
}
$total_profit = array(
'total' => $amount_profit,
'open' => money($open_profit, setting('general.default_currency'), true),
'overdue' => money($overdue_profit, setting('general.default_currency'), true),
'progress' => $total_progress
);
return array($total_incomes, $total_expenses, $total_profit);
return response()->json($dashboard);
}
private function getCashFlow()
/**
* Update the specified resource in storage.
*
* @param Model $dashboard
* @param $request
* @return Response
*/
public function update(Model $dashboard, Request $request)
{
// check and assign year start
if (($year_start = $this->today->startOfYear()->format('Y-m-d')) !== $this->financial_start) {
$year_start = $this->financial_start;
}
$request['enabled'] = 1;
$dashboard->update($request->input());
$start = Date::parse(request('start', $year_start));
$end = Date::parse(request('end', Date::parse($year_start)->addYear(1)->subDays(1)->format('Y-m-d')));
$period = request('period', 'month');
$range = request('range', 'custom');
$response['data'] = $dashboard;
$response['redirect'] = route('dashboard');
$start_month = $start->month;
$end_month = $end->month;
// Monthly
$labels = array();
$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');
if ($period == 'month') {
$s->addMonth();
} else {
$s->addMonths(3);
$j -= 2;
}
}
$income = $this->calculateCashFlowTotals('income', $start, $end, $period);
$expense = $this->calculateCashFlowTotals('expense', $start, $end, $period);
$profit = $this->calculateCashFlowProfit($income, $expense);
$chart = Charts::multi('line', 'chartjs')
->dimensions(0, 300)
->colors(['#6da252', '#00c0ef', '#F56954'])
->dataset(trans_choice('general.profits', 1), $profit)
->dataset(trans_choice('general.incomes', 1), $income)
->dataset(trans_choice('general.expenses', 1), $expense)
->labels($labels)
->credits(false)
->view('vendor.consoletvs.charts.chartjs.multi.line');
return $chart;
return response()->json($response);
}
private function getDonuts()
/**
* Remove the specified resource from storage.
*
* @param Model $dashboard
*
* @return Response
*/
public function destroy(Model $dashboard)
{
// Show donut prorated if there is no income
if (array_sum($this->income_donut['values']) == 0) {
foreach ($this->income_donut['values'] as $key => $value) {
$this->income_donut['values'][$key] = 1;
}
}
$dashboard->delete();
// Get 6 categories by amount
$colors = $labels = [];
$values = collect($this->income_donut['values'])->sort()->reverse()->take(6)->all();
foreach ($values as $id => $val) {
$colors[$id] = $this->income_donut['colors'][$id];
$labels[$id] = $this->income_donut['labels'][$id];
}
session(['dashboard_id' => user()->dashboards()->pluck('id')->first()]);
$donut_incomes = Charts::create('donut', 'chartjs')
->colors($colors)
->labels($labels)
->values($values)
->dimensions(0, 160)
->credits(false)
->view('vendor.consoletvs.charts.chartjs.donut');
$response['redirect'] = route('dashboard');
// Show donut prorated if there is no expense
if (array_sum($this->expense_donut['values']) == 0) {
foreach ($this->expense_donut['values'] as $key => $value) {
$this->expense_donut['values'][$key] = 1;
}
}
// Get 6 categories by amount
$colors = $labels = [];
$values = collect($this->expense_donut['values'])->sort()->reverse()->take(6)->all();
foreach ($values as $id => $val) {
$colors[$id] = $this->expense_donut['colors'][$id];
$labels[$id] = $this->expense_donut['labels'][$id];
}
$donut_expenses = Charts::create('donut', 'chartjs')
->colors($colors)
->labels($labels)
->values($values)
->dimensions(0, 160)
->credits(false)
->view('vendor.consoletvs.charts.chartjs.donut');
return array($donut_incomes, $donut_expenses);
}
private function getLatestIncomes()
{
$invoices = collect(Invoice::orderBy('invoiced_at', 'desc')->accrued()->take(10)->get())->each(function ($item) {
$item->paid_at = $item->invoiced_at;
});
$revenues = collect(Revenue::orderBy('paid_at', 'desc')->isNotTransfer()->take(10)->get());
$latest = $revenues->merge($invoices)->take(5)->sortByDesc('paid_at');
return $latest;
}
private function getLatestExpenses()
{
$bills = collect(Bill::orderBy('billed_at', 'desc')->accrued()->take(10)->get())->each(function ($item) {
$item->paid_at = $item->billed_at;
});
$payments = collect(Payment::orderBy('paid_at', 'desc')->isNotTransfer()->take(10)->get());
$latest = $payments->merge($bills)->take(5)->sortByDesc('paid_at');
return $latest;
}
private function calculateAmounts()
{
$incomes_amount = $open_invoice = $overdue_invoice = 0;
$expenses_amount = $open_bill = $overdue_bill = 0;
// Get categories
$categories = Category::with(['bills', 'invoices', 'payments', 'revenues'])->orWhere('type', 'income')->orWhere('type', 'expense')->enabled()->get();
foreach ($categories as $category) {
switch ($category->type) {
case 'income':
$amount = 0;
// Revenues
foreach ($category->revenues as $revenue) {
$amount += $revenue->getConvertedAmount();
}
$incomes_amount += $amount;
// Invoices
$invoices = $category->invoices()->accrued()->get();
foreach ($invoices as $invoice) {
list($paid, $open, $overdue) = $this->calculateInvoiceBillTotals($invoice, 'invoice');
$incomes_amount += $paid;
$open_invoice += $open;
$overdue_invoice += $overdue;
$amount += $paid;
}
$this->addToIncomeDonut($category->color, $amount, $category->name);
break;
case 'expense':
$amount = 0;
// Payments
foreach ($category->payments as $payment) {
$amount += $payment->getConvertedAmount();
}
$expenses_amount += $amount;
// Bills
$bills = $category->bills()->accrued()->get();
foreach ($bills as $bill) {
list($paid, $open, $overdue) = $this->calculateInvoiceBillTotals($bill, 'bill');
$expenses_amount += $paid;
$open_bill += $open;
$overdue_bill += $overdue;
$amount += $paid;
}
$this->addToExpenseDonut($category->color, $amount, $category->name);
break;
}
}
return array($incomes_amount, $open_invoice, $overdue_invoice, $expenses_amount, $open_bill, $overdue_bill);
}
private function calculateCashFlowTotals($type, $start, $end, $period)
{
$totals = array();
if ($type == 'income') {
$m1 = '\App\Models\Income\Revenue';
$m2 = '\App\Models\Income\InvoicePayment';
} else {
$m1 = '\App\Models\Expense\Payment';
$m2 = '\App\Models\Expense\BillPayment';
}
$date_format = 'Y-m';
if ($period == 'month') {
$n = 1;
$start_date = $start->format($date_format);
$end_date = $end->format($date_format);
$next_date = $start_date;
} else {
$n = 3;
$start_date = $start->quarter;
$end_date = $end->quarter;
$next_date = $start_date;
}
$s = clone $start;
//$totals[$start_date] = 0;
while ($next_date <= $end_date) {
$totals[$next_date] = 0;
if ($period == 'month') {
$next_date = $s->addMonths($n)->format($date_format);
} else {
if (isset($totals[4])) {
break;
}
$next_date = $s->addMonths($n)->quarter;
}
}
$items_1 = $m1::whereBetween('paid_at', [$start, $end])->isNotTransfer()->get();
$this->setCashFlowTotals($totals, $items_1, $date_format, $period);
$items_2 = $m2::whereBetween('paid_at', [$start, $end])->get();
$this->setCashFlowTotals($totals, $items_2, $date_format, $period);
return $totals;
}
private function setCashFlowTotals(&$totals, $items, $date_format, $period)
{
foreach ($items as $item) {
if ($period == 'month') {
$i = Date::parse($item->paid_at)->format($date_format);
} else {
$i = Date::parse($item->paid_at)->quarter;
}
if (!isset($totals[$i])) {
continue;
}
$totals[$i] += $item->getConvertedAmount();
}
}
private function calculateCashFlowProfit($incomes, $expenses)
{
$profit = [];
foreach ($incomes as $key => $income) {
if ($income > 0 && $income > $expenses[$key]) {
$profit[$key] = $income - $expenses[$key];
} else {
$profit[$key] = 0;
}
}
return $profit;
}
private function calculateInvoiceBillTotals($item, $type)
{
$paid = $open = $overdue = 0;
$today = $this->today->toDateString();
$paid += $item->getConvertedAmount();
$code_field = $type . '_status_code';
if ($item->$code_field != 'paid') {
$payments = 0;
if ($item->$code_field == 'partial') {
foreach ($item->payments as $payment) {
$payments += $payment->getConvertedAmount();
}
}
// Check if it's open or overdue invoice
if ($item->due_at > $today) {
$open += $item->getConvertedAmount() - $payments;
} else {
$overdue += $item->getConvertedAmount() - $payments;
}
}
return array($paid, $open, $overdue);
}
private function addToIncomeDonut($color, $amount, $text)
{
$this->income_donut['colors'][] = $color;
$this->income_donut['labels'][] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $text;
$this->income_donut['values'][] = (int) $amount;
}
private function addToExpenseDonut($color, $amount, $text)
{
$this->expense_donut['colors'][] = $color;
$this->expense_donut['labels'][] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $text;
$this->expense_donut['values'][] = (int) $amount;
return response()->json($response);
}
}

View File

@ -2,8 +2,7 @@
namespace App\Http\Controllers\Common;
use App\Http\Controllers\Controller;
use Module;
use App\Abstracts\Http\Controller;
class Import extends Controller
{
@ -18,7 +17,7 @@ class Import extends Controller
{
$path = $group . '/' . $type;
if (Module::findByAlias($group) instanceof \Nwidart\Modules\Module) {
if (module($group) instanceof \Akaunting\Module\Module) {
$namespace = $group . '::';
} else {
$namespace = '';

View File

@ -2,16 +2,20 @@
namespace App\Http\Controllers\Common;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Exports\Common\Items as Export;
use App\Http\Requests\Common\Item as Request;
use App\Http\Requests\Common\TotalItem as TRequest;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Common\TotalItem as TotalRequest;
use App\Imports\Common\Items as Import;
use App\Jobs\Common\CreateItem;
use App\Jobs\Common\DeleteItem;
use App\Jobs\Common\UpdateItem;
use App\Models\Common\Item;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Models\Setting\Tax;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
class Items extends Controller
{
@ -24,11 +28,9 @@ class Items extends Controller
*/
public function index()
{
$items = Item::with('category')->collect();
$items = Item::with(['category', 'tax'])->collect();
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id');
return view('common.items.index', compact('items', 'categories'));
return view('common.items.index', compact('items'));
}
/**
@ -48,11 +50,11 @@ class Items extends Controller
*/
public function create()
{
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id');
$categories = Category::type('item')->enabled()->orderBy('name')->pluck('name', 'id');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$currency = Currency::where('code', '=', setting('general.default_currency', 'USD'))->first();
$currency = Currency::where('code', setting('default.currency', 'USD'))->first();
return view('common.items.create', compact('categories', 'taxes', 'currency'));
}
@ -60,26 +62,28 @@ class Items extends Controller
/**
* Store a newly created resource in storage.
*
* @param Request $request
*
* @param $request
* @return Response
*/
public function store(Request $request)
{
$item = Item::create($request->input());
$response = $this->ajaxDispatch(new CreateItem($request));
// Upload picture
if ($request->file('picture')) {
$media = $this->getMedia($request->file('picture'), 'items');
if ($response['success']) {
$response['redirect'] = route('items.index');
$item->attachMedia($media, 'picture');
$message = trans('messages.success.added', ['type' => trans_choice('general.items', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('items.create');
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.added', ['type' => trans_choice('general.items', 1)]);
flash($message)->success();
return redirect()->route('items.index');
return response()->json($response);
}
/**
@ -103,15 +107,13 @@ class Items extends Controller
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
if (!Import::createFromFile($import, 'Common\Item')) {
return redirect('common/import/common/items');
}
\Excel::import(new Import(), $request->file('import'));
$message = trans('messages.success.imported', ['type' => trans_choice('general.items', 2)]);
@ -129,106 +131,101 @@ class Items extends Controller
*/
public function edit(Item $item)
{
$categories = Category::enabled()->orderBy('name')->type('item')->pluck('name', 'id');
$categories = Category::type('item')->enabled()->orderBy('name')->pluck('name', 'id');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$currency = Currency::where('code', '=', setting('general.default_currency', 'USD'))->first();
return view('common.items.edit', compact('item', 'categories', 'taxes', 'currency'));
return view('common.items.edit', compact('item', 'categories', 'taxes'));
}
/**
* Update the specified resource in storage.
*
* @param Item $item
* @param Request $request
*
* @param $item
* @param $request
* @return Response
*/
public function update(Item $item, Request $request)
{
$item->update($request->input());
$response = $this->ajaxDispatch(new UpdateItem($item, $request));
// Upload picture
if ($request->file('picture')) {
$media = $this->getMedia($request->file('picture'), 'items');
if ($response['success']) {
$response['redirect'] = route('items.index');
$item->attachMedia($media, 'picture');
$message = trans('messages.success.updated', ['type' => $item->name]);
flash($message)->success();
} else {
$response['redirect'] = route('items.edit', $item->id);
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.updated', ['type' => trans_choice('general.items', 1)]);
flash($message)->success();
return redirect()->route('items.index');
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Item $item
* @param Item $item
*
* @return Response
*/
public function enable(Item $item)
{
$item->enabled = 1;
$item->save();
$response = $this->ajaxDispatch(new UpdateItem($item, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.items', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $item->name]);
}
flash($message)->success();
return redirect()->route('items.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Item $item
* @param Item $item
*
* @return Response
*/
public function disable(Item $item)
{
$item->enabled = 0;
$item->save();
$response = $this->ajaxDispatch(new UpdateItem($item, request()->merge(['enabled' => 0])));
$message = trans('messages.success.disabled', ['type' => trans_choice('general.items', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $item->name]);
}
flash($message)->success();
return redirect()->route('items.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Item $item
* @param Item $item
*
* @return Response
*/
public function destroy(Item $item)
{
$relationships = $this->countRelationships($item, [
'invoice_items' => 'invoices',
'bill_items' => 'bills',
]);
$response = $this->ajaxDispatch(new DeleteItem($item));
if (empty($relationships)) {
$item->delete();
$response['redirect'] = route('items.index');
$message = trans('messages.success.deleted', ['type' => trans_choice('general.items', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $item->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $item->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect()->route('items.index');
return response()->json($response);
}
/**
@ -238,13 +235,7 @@ class Items extends Controller
*/
public function export()
{
\Excel::create('items', function($excel) {
$excel->sheet('items', function($sheet) {
$sheet->fromModel(Item::filter(request()->input())->get()->makeHidden([
'id', 'company_id', 'item_id', 'created_at', 'updated_at', 'deleted_at'
]));
});
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.items', 2) . '.xlsx');
}
public function autocomplete()
@ -254,20 +245,13 @@ class Items extends Controller
$currency_code = request('currency_code');
if (empty($currency_code) || (strtolower($currency_code) == 'null')) {
$currency_code = setting('general.default_currency');
$currency_code = setting('default.currency');
}
$currency = Currency::where('code', $currency_code)->first();
$autocomplete = Item::autocomplete([
'name' => $query,
'sku' => $query,
'name' => $query
]);
if ($type == 'invoice') {
$autocomplete->quantity();
}
$items = $autocomplete->get();
if ($items) {
@ -280,9 +264,6 @@ class Items extends Controller
$item_tax_price = ($item->sale_price / 100) * $tax->rate;
}
//$item->sale_price = $this->convertPrice($item->sale_price, $currency_code, $currency->rate);
//$item->purchase_price = $this->convertPrice($item->purchase_price, $currency_code, $currency->rate);
switch ($type) {
case 'bill':
$total = $item->purchase_price + $item_tax_price;
@ -300,14 +281,14 @@ class Items extends Controller
return response()->json($items);
}
public function totalItem(TRequest $request)
public function total(TotalRequest $request)
{
$input_items = $request->input('item');
$input_items = $request->input('items');
$currency_code = $request->input('currency_code');
$discount = $request->input('discount');
if (empty($currency_code)) {
$currency_code = setting('general.default_currency');
$currency_code = setting('default.currency');
}
$json = new \stdClass;
@ -334,7 +315,7 @@ class Items extends Controller
}
if (!empty($item['tax_id'])) {
$inclusives = $compounds = $taxes = [];
$inclusives = $compounds = $taxes = $fixed_taxes = [];
foreach ($item['tax_id'] as $tax_id) {
$tax = Tax::find($tax_id);
@ -346,6 +327,11 @@ class Items extends Controller
case 'compound':
$compounds[] = $tax;
break;
case 'fixed':
$fixed_taxes[] = $tax;
$item_tax_total += $tax->rate;
break;
case 'normal':
default:
$taxes[] = $tax;
@ -416,19 +402,4 @@ class Items extends Controller
return response()->json($json);
}
protected function convertPrice($amount, $currency_code, $currency_rate, $format = false, $reverse = false)
{
$item = new Item();
$item->amount = $amount;
$item->currency_code = $currency_code;
$item->currency_rate = $currency_rate;
if ($reverse) {
return $item->getReverseConvertedAmount($format);
}
return $item->getConvertedAmount($format);
}
}

View File

@ -3,7 +3,7 @@
namespace App\Http\Controllers\Common;
use Date;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Traits\Modules as RemoteModules;
use App\Http\Requests\Common\Notification as Request;

View File

@ -0,0 +1,277 @@
<?php
namespace App\Http\Controllers\Common;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\Report as Request;
use App\Jobs\Common\CreateReport;
use App\Jobs\Common\DeleteReport;
use App\Jobs\Common\UpdateReport;
use App\Models\Common\Report;
use App\Utilities\Reports as Utility;
class Reports extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$classes = [];
$reports = ['income-expense' => [], 'accounting' => []];
$items = Report::collect();
foreach ($items as $item) {
$class = Utility::getClassInstance($item);
if (!$class->canRead()) {
continue;
}
$reports[$class->getCategory()][] = $item;
$classes[$item->id] = $class;
}
return view('common.reports.index', compact('reports', 'classes'));
}
/**
* Show the form for viewing the specified resource.
*
* @param Report $report
* @return Response
*/
public function show(Report $report)
{
$class = Utility::getClassInstance($report);
if (!$class->canRead()) {
abort(403);
}
return $class->show();
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
$classes = Utility::getClasses();
$groups = Utility::getGroups();
$periods = Utility::getPeriods();
$basises = Utility::getBasises();
$charts = Utility::getCharts();
return view('common.reports.create', compact('classes', 'groups', 'periods', 'basises', 'charts'));
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return Response
*/
public function store(Request $request)
{
$response = $this->ajaxDispatch(new CreateReport($request));
if ($response['success']) {
$response['redirect'] = route('reports.index');
$message = trans('messages.success.added', ['type' => trans_choice('general.reports', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('reports.create');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Show the form for editing the specified resource.
*
* @param Report $report
*
* @return Response
*/
public function edit(Report $report)
{
$classes = Utility::getClasses();
$groups = Utility::getGroups();
$periods = Utility::getPeriods();
$basises = Utility::getBasises();
$charts = Utility::getCharts();
return view('common.reports.edit', compact('report', 'classes', 'groups', 'periods', 'basises', 'charts'));
}
/**
* Update the specified resource in storage.
*
* @param Report $report
* @param $request
* @return Response
*/
public function update(Report $report, Request $request)
{
$response = $this->ajaxDispatch(new UpdateReport($report, $request));
if ($response['success']) {
$response['redirect'] = route('reports.index');
$message = trans('messages.success.updated', ['type' => $report->name]);
flash($message)->success();
} else {
$response['redirect'] = route('reports.edit', $report->id);
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Report $report
*
* @return Response
*/
public function enable(Report $report)
{
$response = $this->ajaxDispatch(new UpdateReport($report, request()->merge(['enabled' => 1])));
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $report->name]);
}
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Report $report
*
* @return Response
*/
public function disable(Report $report)
{
$response = $this->ajaxDispatch(new UpdateReport($report, request()->merge(['enabled' => 0])));
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $report->name]);
}
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Report $report
*
* @return Response
*/
public function destroy(Report $report)
{
$response = $this->ajaxDispatch(new DeleteReport($report));
$response['redirect'] = route('reports.index');
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $report->name]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Print the report.
*
* @param Report $report
* @return Response
*/
public function print(Report $report)
{
$class = Utility::getClassInstance($report);
if (!$class->canRead()) {
abort(403);
}
return $class->print();
}
/**
* Export the report.
*
* @param Report $report
* @return Response
*/
public function export(Report $report)
{
$class = Utility::getClassInstance($report);
if (!$class->canRead()) {
abort(403);
}
return $class->export();
}
/**
* Get groups of the specified resource.
*
* @return Response
*/
public function groups()
{
$class = request('class');
if (!class_exists($class)) {
return response()->json([
'success' => false,
'error' => true,
'data' => false,
'message' => "Class doesn't exist",
]);
}
return response()->json([
'success' => true,
'error' => false,
'data' => (new $class())->groups,
'message' => '',
]);
}
}

View File

@ -2,42 +2,31 @@
namespace App\Http\Controllers\Common;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Expense\Bill;
use App\Models\Expense\Payment;
use App\Models\Expense\Vendor;
use App\Models\Income\Invoice;
use App\Models\Income\Revenue;
use App\Models\Income\Customer;
use App\Models\Common\Item;
use App\Traits\Contacts;
class Search extends Controller
{
use Contacts;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$items = Item::enabled()->with('category')->get()->sortBy('name');
return view('items.items.index', compact('items'));
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function search()
{
$results = array();
$keyword = request('keyword');
$accounts = Account::enabled()->search($keyword)->get();
$accounts = Account::enabled()->usingSearchString($keyword)->get();
if ($accounts->count()) {
foreach ($accounts as $account) {
@ -45,13 +34,13 @@ class Search extends Controller
'id' => $account->id,
'name' => $account->name,
'type' => trans_choice('general.accounts', 1),
'color' => '#337ab7',
'color' => '#55588b',
'href' => url('banking/accounts/' . $account->id . '/edit'),
];
}
}
$items = Item::enabled()->search($keyword)->get();
$items = Item::enabled()->usingSearchString($keyword)->get();
if ($items->count()) {
foreach ($items as $item) {
@ -59,29 +48,41 @@ class Search extends Controller
'id' => $item->id,
'name' => $item->name,
'type' => trans_choice('general.items', 1),
'color' => '#f5bd65',
'color' => '#efad32',
'href' => url('common/items/' . $item->id . '/edit'),
];
}
}
$invoices = Invoice::search($keyword)->get();
$invoices = Invoice::usingSearchString($keyword)->get();
if ($invoices->count()) {
foreach ($invoices as $invoice) {
$results[] = (object)[
'id' => $invoice->id,
'name' => $invoice->invoice_number . ' - ' . $invoice->customer_name,
'name' => $invoice->invoice_number . ' - ' . $invoice->contact_name,
'type' => trans_choice('general.invoices', 1),
'color' => '#00c0ef',
'color' => '#6da252',
'href' => url('incomes/invoices/' . $invoice->id),
];
}
}
}/*
//$revenues = Revenue::search($keyword)->get();
$revenues = Transaction::type('income')->usingSearchString($keyword)->get();
$customers = Customer::enabled()->search($keyword)->get();
if ($revenues->count()) {
foreach ($revenues as $revenue) {
$results[] = (object)[
'id' => $revenue->id,
'name' => $revenue->contact_name,
'type' => trans_choice('general.revenues', 1),
'color' => '#00c0ef',
'href' => url('incomes/revenues/' . $revenue->id),
];
}
}*/
$customers = Contact::type($this->getCustomerTypes())->enabled()->usingSearchString($keyword)->get();
if ($customers->count()) {
foreach ($customers as $customer) {
@ -89,29 +90,41 @@ class Search extends Controller
'id' => $customer->id,
'name' => $customer->name,
'type' => trans_choice('general.customers', 1),
'color' => '#03d876',
'color' => '#328aef',
'href' => url('incomes/customers/' . $customer->id),
];
}
}
$bills = Bill::search($keyword)->get();
$bills = Bill::usingSearchString($keyword)->get();
if ($bills->count()) {
foreach ($bills as $bill) {
$results[] = (object)[
'id' => $bill->id,
'name' => $bill->bill_number . ' - ' . $bill->vendor_name,
'name' => $bill->bill_number . ' - ' . $bill->contact_name,
'type' => trans_choice('general.bills', 1),
'color' => '#dd4b39',
'color' => '#ef3232',
'href' => url('expenses/bills/' . $bill->id),
];
}
}
/*
$payments = Transaction::type('expense')->usingSearchString($keyword)->get();
//$payments = Payment::search($keyword)->get();
if ($revenues->count()) {
foreach ($revenues as $revenue) {
$results[] = (object)[
'id' => $revenue->id,
'name' => $revenue->contact_name,
'type' => trans_choice('general.revenues', 1),
'color' => '#00c0ef',
'href' => url('incomes/revenues/' . $revenue->id),
];
}
}*/
$vendors = Vendor::enabled()->search($keyword)->get();
$vendors = Contact::type($this->getVendorTypes())->enabled()->usingSearchString($keyword)->get();
if ($vendors->count()) {
foreach ($vendors as $vendor) {
@ -119,7 +132,7 @@ class Search extends Controller
'id' => $vendor->id,
'name' => $vendor->name,
'type' => trans_choice('general.vendors', 1),
'color' => '#ff8373',
'color' => '#efef32',
'href' => url('expenses/vendors/' . $vendor->id),
];
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Common;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use Illuminate\Http\Request;
use App\Models\Common\Media;
use File;
@ -21,12 +21,12 @@ class Uploads extends Controller
try {
$media = Media::find($id);
} catch (\Exception $e) {
return false;
return response(null, 204);
}
// Get file path
if (!$path = $this->getPath($media)) {
return false;
return response(null, 204);
}
return response()->file($path);

View File

@ -0,0 +1,152 @@
<?php
namespace App\Http\Controllers\Common;
use App\Abstracts\Http\Controller;
use App\Models\Common\DashboardWidget as Model;
use App\Models\Common\Widget;
use App\Http\Requests\Common\Widget as Request;
class Widgets extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$dashboard_widgets = Widget::enabled()->get();
return response()->json($dashboard_widgets);
}
/**
* Store a newly created resource in storage.
*
* @param $request
* @return Response
*/
public function store(Request $request)
{
$request['user_id'] = user()->id;
$request['settings'] = [
'width' => $request->get('width')
];
$widget = Model::create($request->input());
$settings = $widget->settings;
unset($settings['widget']);
return response()->json([
'status' => 200,
'success' => true,
'error' => false,
'message' => trans('messages.success.added', ['type' => $widget->name]),
'data' => [
'widget_id' => $widget->widget_id,
'name' => $widget->name,
'settings' => $settings,
'sort' => $widget->sort,
],
'redirect' => route('dashboard')
]);
}
/**
* Show the form for editing the specified resource.
*
* @param Model $dashboard
*
* @return Response
*/
public function edit(Model $widget)
{
$settings = $widget->settings;
unset($settings['widget']);
return response()->json([
'widget_id' => $widget->widget_id,
'name' => $widget->name,
'settings' => $settings,
'sort' => $widget->sort,
]);
}
/**
* Update the specified resource in storage.
*
* @param Model $dashboard
* @param $request
* @return Response
*/
public function update(Model $widget, Request $request)
{
$request['user_id'] = user()->id;
$request['settings'] = [
'width' => $request->get('width')
];
$widget->update($request->input());
$settings = $widget->settings;
unset($settings['widget']);
return response()->json([
'status' => 200,
'success' => true,
'error' => false,
'message' => trans('messages.success.added', ['type' => $widget->name]),
'data' => [
'widget_id' => $widget->widget_id,
'name' => $widget->name,
'settings' => $settings,
'sort' => $widget->sort,
],
'redirect' => route('dashboard')
]);
}
/**
* Remove the specified resource from storage.
*
* @param Model $dashboard
*
* @return Response
*/
public function destroy(Model $widget)
{
$message = trans('messages.success.deleted', ['type' => $widget->name]);
$widget->delete();
return response()->json([
'status' => 200,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => route('dashboard')
]);
}
public function getData(Request $request)
{
// Check is module
$module = module($request->get('widget'));
if ($module instanceof \Akaunting\Module\Module) {
$widget = app('Modules\\' . $module->getStudlyName() . '\Widgets\\' . ucfirst($request->get('widget')));
} else {
$widget = app('App\Widgets\\' . ucfirst($request->get('widget')));
}
$response = $widget->{$request->get('method')}($request);
return response()->json($response);
}
}

View File

@ -1,112 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Routing\Route;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// No need to check for permission in console
if (app()->runningInConsole()) {
return;
}
$route = app(Route::class);
// Get the controller array
$arr = array_reverse(explode('\\', explode('@', $route->getAction()['uses'])[0]));
$controller = '';
// Add folder
if (strtolower($arr[1]) != 'controllers') {
$controller .= kebab_case($arr[1]) . '-';
}
// Add module
if (isset($arr[3]) && isset($arr[4]) && (strtolower($arr[4]) == 'modules')) {
$controller .= kebab_case($arr[3]) . '-';
}
// Add file
$controller .= kebab_case($arr[0]);
// Skip ACL
$skip = ['common-dashboard', 'customers-dashboard'];
if (in_array($controller, $skip)) {
return;
}
// Add CRUD permission check
$this->middleware('permission:create-' . $controller)->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-' . $controller)->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-' . $controller)->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-' . $controller)->only('destroy');
}
public function countRelationships($model, $relationships)
{
$counter = array();
foreach ($relationships as $relationship => $text) {
if ($c = $model->$relationship()->count()) {
$counter[] = $c . ' ' . strtolower(trans_choice('general.' . $text, ($c > 1) ? 2 : 1));
}
}
return $counter;
}
/**
* Check for api token and redirect if empty.
*
* @return mixed
*/
public function checkApiToken()
{
if (setting('general.api_token')) {
return;
}
redirect('apps/token/create')->send();
}
/**
* Mass delete relationships with events being fired.
*
* @param $model
* @param $relationships
*
* @return void
*/
public function deleteRelationships($model, $relationships)
{
foreach ((array) $relationships as $relationship) {
if (empty($model->$relationship)) {
continue;
}
$items = $model->$relationship->all();
if ($items instanceof Collection) {
$items = $items->all();
}
foreach ((array) $items as $item) {
$item->delete();
}
}
}
}

View File

@ -1,125 +0,0 @@
<?php
namespace App\Http\Controllers\Customers;
use App\Http\Controllers\Controller;
use App\Models\Income\Invoice;
use Charts;
use Date;
class Dashboard extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$customer = auth()->user()->customer;
$invoices = Invoice::with('status')->accrued()->where('customer_id', $customer->id)->get();
$start = Date::parse(request('start', Date::today()->startOfYear()->format('Y-m-d')));
$end = Date::parse(request('end', Date::today()->endOfYear()->format('Y-m-d')));
$start_month = $start->month;
$end_month = $end->month;
// Monthly
$labels = [];
$s = clone $start;
for ($j = $end_month; $j >= $start_month; $j--) {
$labels[$end_month - $j] = $s->format('M Y');
$s->addMonth();
}
$unpaid = $paid = $overdue = $partial_paid = [];
foreach ($invoices as $invoice) {
switch ($invoice->invoice_status_code) {
case 'paid':
$paid[] = $invoice;
break;
case 'partial':
$partial_paid[] = $invoice;
break;
case 'sent':
default:
if (Date::today()->format('Y-m-d') > $invoice->due_at->format('Y-m-d')) {
$overdue[] = $invoice;
} else {
$unpaid[] = $invoice;
}
}
}
$total = count($unpaid) + count($paid) + count($partial_paid) + count($overdue);
$progress = [
'unpaid' => count($unpaid),
'paid' => count($paid),
'overdue' => count($overdue),
'partially_paid' => count($partial_paid),
'total' => $total,
];
$unpaid = $this->calculateTotals($unpaid, $start, $end, 'unpaid');
$paid = $this->calculateTotals($paid, $start, $end, 'paid');
$partial_paid = $this->calculateTotals($partial_paid, $start, $end, 'partial');
$overdue = $this->calculateTotals($overdue, $start, $end, 'overdue');
$chart = Charts::multi('line', 'chartjs')
->dimensions(0, 300)
->colors(['#dd4b39', '#6da252', '#f39c12', '#00c0ef'])
->dataset(trans('general.unpaid'), $unpaid)
->dataset(trans('general.paid'), $paid)
->dataset(trans('general.overdue'), $overdue)
->dataset(trans('general.partially_paid'), $partial_paid)
->labels($labels)
->credits(false)
->view('vendor.consoletvs.charts.chartjs.multi.line');
return view('customers.dashboard.index', compact('customer', 'invoices', 'progress', 'chart'));
}
private function calculateTotals($items, $start, $end, $type)
{
$totals = [];
$date_format = 'Y-m';
$n = 1;
$start_date = $start->format($date_format);
$end_date = $end->format($date_format);
$next_date = $start_date;
$s = clone $start;
while ($next_date <= $end_date) {
$totals[$next_date] = 0;
$next_date = $s->addMonths($n)->format($date_format);
}
$this->setTotals($totals, $items, $date_format, $type);
return $totals;
}
private function setTotals(&$totals, $items, $date_format, $type)
{
foreach ($items as $item) {
if ($type == 'partial') {
$item->amount = $item->payments()->paid();
}
$i = Date::parse($item->paid_at)->format($date_format);
$totals[$i] += $item->getConvertedAmount();
}
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace App\Http\Controllers\Customers;
use App\Http\Controllers\Controller;
use App\Models\Banking\Transaction;
use Auth;
class Transactions extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$transactions = Transaction::getUserTransactions(Auth::user()->customer->id, 'revenues');
return view('customers.transactions.index', compact('transactions'));
}
}

View File

@ -2,44 +2,33 @@
namespace App\Http\Controllers\Expenses;
use App\Events\BillCreated;
//use App\Events\BillPrinting;
use App\Events\BillUpdated;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Exports\Expenses\Bills as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Expense\Bill as Request;
use App\Http\Requests\Expense\BillAddItem as ItemRequest;
use App\Http\Requests\Expense\BillPayment as PaymentRequest;
use App\Imports\Expenses\Bills as Import;
use App\Jobs\Expense\CreateBill;
use App\Jobs\Expense\DuplicateBill;
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;
use App\Models\Common\Contact;
use App\Models\Common\Item;
use App\Models\Expense\BillStatus;
use App\Models\Expense\Bill;
use App\Models\Expense\BillHistory;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Models\Setting\Tax;
use App\Traits\Contacts;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use App\Utilities\Modules;
use Date;
use File;
use Image;
use Storage;
class Bills extends Controller
{
use DateTime, Currencies, Uploads;
use Contacts, Currencies, DateTime, Uploads;
/**
* Display a listing of the resource.
@ -48,13 +37,13 @@ class Bills extends Controller
*/
public function index()
{
$bills = Bill::with(['vendor', 'status', 'items', 'payments', 'histories'])->collect(['billed_at'=> 'desc']);
$bills = Bill::with(['contact', 'items', 'histories', 'status', 'transactions'])->collect(['billed_at'=> 'desc']);
$vendors = collect(Vendor::enabled()->orderBy('name')->pluck('name', 'id'));
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = collect(Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id'));
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
$statuses = collect(BillStatus::get()->each(function($item) {
$statuses = collect(BillStatus::get()->each(function ($item) {
$item->name = trans('bills.status.' . $item->code);
return $item;
})->pluck('name', 'code'));
@ -75,15 +64,19 @@ class Bills extends Controller
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
$currency = Currency::where('code', $invoice->currency_code)->first();
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
return view('expenses.bills.show', compact('bill', 'accounts', 'currencies', 'account_currency_code', 'vendors', 'categories', 'payment_methods'));
$date_format = $this->getCompanyDateFormat();
return view('expenses.bills.show', compact('bill', 'accounts', 'currencies', 'currency', 'account_currency_code', 'vendors', 'categories', 'payment_methods', 'date_format'));
}
/**
@ -93,17 +86,17 @@ class Bills extends Controller
*/
public function create()
{
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', '=', setting('general.default_currency'))->first();
$currency = Currency::where('code', setting('default.currency'))->first();
$items = Item::enabled()->orderBy('name')->pluck('name', 'id');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
return view('expenses.bills.create', compact('vendors', 'currencies', 'currency', 'items', 'taxes', 'categories'));
}
@ -117,83 +110,65 @@ class Bills extends Controller
*/
public function store(Request $request)
{
$bill = dispatch(new CreateBill($request));
$response = $this->ajaxDispatch(new CreateBill($request));
$message = trans('messages.success.added', ['type' => trans_choice('general.bills', 1)]);
if ($response['success']) {
$response['redirect'] = route('bills.index');
flash($message)->success();
$message = trans('messages.success.added', ['type' => trans_choice('general.bills', 1)]);
return redirect('expenses/bills/' . $bill->id);
flash($message)->success();
} else {
$response['redirect'] = route('bills.create');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Duplicate the specified resource.
*
* @param Bill $bill
* @param Bill $bill
*
* @return Response
*/
public function duplicate(Bill $bill)
{
$clone = $bill->duplicate();
// Add bill history
BillHistory::create([
'company_id' => session('company_id'),
'bill_id' => $clone->id,
'status_code' => 'draft',
'notify' => 0,
'description' => trans('messages.success.added', ['type' => $clone->bill_number]),
]);
$clone = $this->dispatch(new DuplicateBill($bill));
$message = trans('messages.success.duplicated', ['type' => trans_choice('general.bills', 1)]);
flash($message)->success();
return redirect('expenses/bills/' . $clone->id . '/edit');
return redirect()->route('bills.edit', $clone->id);
}
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
$success = true;
$allowed_sheets = ['bills', 'bill_items', 'bill_item_taxes', 'bill_histories', 'bill_payments', 'bill_totals'];
// Loop through all sheets
$import->each(function ($sheet) use (&$success, $allowed_sheets) {
$sheet_title = $sheet->getTitle();
if (!in_array($sheet_title, $allowed_sheets)) {
$message = trans('messages.error.import_sheet');
flash($message)->error()->important();
return false;
}
$slug = 'Expense\\' . str_singular(studly_case($sheet_title));
if (!$success = Import::createFromSheet($sheet, $slug)) {
return false;
}
});
\Excel::import(new Import(), $request->file('import'));
if (!$success) {
return redirect('common/import/expenses/bills');
return redirect()->route('import.create', ['expenses', 'bills']);
}
$message = trans('messages.success.imported', ['type' => trans_choice('general.bills', 2)]);
flash($message)->success();
return redirect('expenses/bills');
return redirect()->route('bills.index');
}
/**
@ -205,17 +180,17 @@ class Bills extends Controller
*/
public function edit(Bill $bill)
{
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', '=', $bill->currency_code)->first();
$currency = Currency::where('code', $bill->currency_code)->first();
$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');
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
return view('expenses.bills.edit', compact('bill', 'vendors', 'currencies', 'currency', 'items', 'taxes', 'categories'));
}
@ -223,51 +198,56 @@ class Bills extends Controller
/**
* Update the specified resource in storage.
*
* @param Bill $bill
* @param Request $request
* @param Bill $bill
* @param Request $request
*
* @return Response
*/
public function update(Bill $bill, Request $request)
{
$bill = dispatch(new UpdateBill($bill, $request));
$response = $this->ajaxDispatch(new UpdateBill($bill, $request));
$message = trans('messages.success.updated', ['type' => trans_choice('general.bills', 1)]);
if ($response['success']) {
$response['redirect'] = route('bills.index');
flash($message)->success();
$message = trans('messages.success.updated', ['type' => trans_choice('general.bills', 1)]);
return redirect('expenses/bills/' . $bill->id);
flash($message)->success();
} else {
$response['redirect'] = route('bills.edit', $bill->id);
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Bill $bill
* @param $id
*
* @return Response
*/
public function destroy(Bill $bill)
{
// Decrease stock
$bill->items()->each(function ($bill_item) {
$item = Item::find($bill_item->item_id);
$response = $this->ajaxDispatch(new DeleteBill($bill));
if (empty($item)) {
return;
}
$response['redirect'] = route('bills.index');
$item->quantity += (double) $bill_item->quantity;
$item->save();
});
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.bills', 1)]);
$this->deleteRelationships($bill, ['items', 'item_taxes', 'histories', 'payments', 'recurring', 'totals']);
$bill->delete();
flash($message)->success();
} else {
$message = $response['message'];
$message = trans('messages.success.deleted', ['type' => trans_choice('general.bills', 1)]);
flash($message)->error();
}
flash($message)->success();
return redirect('expenses/bills');
return response()->json($response);
}
/**
@ -277,37 +257,7 @@ class Bills extends Controller
*/
public function export()
{
\Excel::create('bills', function ($excel) {
$bills = Bill::with(['items', 'item_taxes', 'histories', 'payments', 'totals'])->filter(request()->input())->get();
$excel->sheet('bills', function ($sheet) use ($bills) {
$sheet->fromModel($bills->makeHidden([
'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at', 'attachment', 'discount', 'items', 'item_taxes', 'histories', 'payments', 'totals', 'media', 'paid', 'amount_without_tax'
]));
});
$tables = ['items', 'item_taxes', 'histories', 'payments', 'totals'];
foreach ($tables as $table) {
$excel->sheet('bill_' . $table, function ($sheet) use ($bills, $table) {
$hidden_fields = ['id', 'company_id', 'created_at', 'updated_at', 'deleted_at', 'title'];
$i = 1;
foreach ($bills as $bill) {
$model = $bill->$table->makeHidden($hidden_fields);
if ($i == 1) {
$sheet->fromModel($model, null, 'A1', false);
} else {
// Don't put multiple heading columns
$sheet->fromModel($model, null, 'A1', false, false);
}
$i++;
}
});
}
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.bills', 2) . '.xlsx');
}
/**
@ -328,10 +278,12 @@ class Bills extends Controller
'bill_id' => $bill->id,
'status_code' => 'received',
'notify' => 0,
'description' => trans('bills.mark_recevied'),
'description' => trans('bills.mark_received'),
]);
flash(trans('bills.messages.received'))->success();
$message = trans('bills.messages.received');
flash($message)->success();
return redirect()->back();
}
@ -366,7 +318,7 @@ class Bills extends Controller
$view = view($bill->template_path, compact('bill', 'currency_style'))->render();
$html = mb_convert_encoding($view, 'HTML-ENTITIES');
$pdf = \App::make('dompdf.wrapper');
$pdf = app('dompdf.wrapper');
$pdf->loadHTML($html);
$file_name = 'bill_' . time() . '.pdf';
@ -374,165 +326,6 @@ class Bills extends Controller
return $pdf->download($file_name);
}
/**
* Add payment to the bill.
*
* @param PaymentRequest $request
*
* @return Response
*/
public function payment(PaymentRequest $request)
{
// Get currency object
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$currency = Currency::where('code', $request['currency_code'])->first();
$request['currency_code'] = $currency->code;
$request['currency_rate'] = $currency->rate;
$bill = Bill::find($request['bill_id']);
$total_amount = $bill->amount;
$default_amount = (double) $request['amount'];
if ($bill->currency_code == $request['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 = $request['currency_code'];
$default_amount_model->currency_rate = $currencies[$request['currency_code']];
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
$convert_amount = new BillPayment();
$convert_amount->default_currency_code = $request['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();
}
if ($bill->payments()->count()) {
$total_amount -= $bill->payments()->paid();
}
// For amount cover integer
$multiplier = 1;
for ($i = 0; $i < $currency->precision; $i++) {
$multiplier *= 10;
}
$amount_check = (int) ($amount * $multiplier);
$total_amount_check = (int) (round($total_amount, $currency->precision) * $multiplier);
if ($amount_check > $total_amount_check) {
$error_amount = $total_amount;
if ($bill->currency_code != $request['currency_code']) {
$error_amount_model = new BillPayment();
$error_amount_model->default_currency_code = $request['currency_code'];
$error_amount_model->amount = $error_amount;
$error_amount_model->currency_code = $bill->currency_code;
$error_amount_model->currency_rate = $currencies[$bill->currency_code];
$error_amount = (double) $error_amount_model->getDivideConvertedAmount();
$convert_amount = new BillPayment();
$convert_amount->default_currency_code = $bill->currency_code;
$convert_amount->amount = $error_amount;
$convert_amount->currency_code = $request['currency_code'];
$convert_amount->currency_rate = $currencies[$request['currency_code']];
$error_amount = (double) $convert_amount->getDynamicConvertedAmount();
}
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $request['currency_code'], true)]);
return response()->json([
'success' => false,
'error' => true,
'data' => [
'amount' => $error_amount
],
'message' => $message,
'html' => 'null',
]);
} elseif ($amount_check == $total_amount_check) {
$bill->bill_status_code = 'paid';
} else {
$bill->bill_status_code = 'partial';
}
$bill->save();
$bill_payment = dispatch(new CreateBillPayment($request, $bill));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'bills');
$bill_payment->attachMedia($media, 'attachment');
}
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
]);
}
/**
* Remove the specified resource from storage.
*
* @param BillPayment $payment
*
* @return Response
*/
public function paymentDestroy(BillPayment $payment)
{
$bill = Bill::find($payment->bill_id);
if ($bill->payments()->count() > 1) {
$bill->bill_status_code = 'partial';
} else {
$bill->bill_status_code = 'received';
}
$bill->save();
$desc_amount = money((float) $payment->amount, (string) $payment->currency_code, true)->format();
$description = $desc_amount . ' ' . trans_choice('general.payments', 1);
// Add bill history
BillHistory::create([
'company_id' => $bill->company_id,
'bill_id' => $bill->id,
'status_code' => $bill->bill_status_code,
'notify' => 0,
'description' => trans('messages.success.deleted', ['type' => $description]),
]);
$payment->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.bills', 1)]);
flash($message)->success();
return redirect()->back();
}
public function addItem(ItemRequest $request)
{
$item_row = $request['item_row'];
@ -543,7 +336,7 @@ class Bills extends Controller
$currency = Currency::where('code', '=', $currency_code)->first();
if (empty($currency)) {
$currency = Currency::where('code', '=', setting('general.default_currency'))->first();
$currency = Currency::where('code', '=', setting('default.currency'))->first();
}
if ($currency) {
@ -574,7 +367,7 @@ class Bills extends Controller
if ($bill->currency_code != $item->currency_code) {
$item->default_currency_code = $bill->currency_code;
$amount = $item->getDynamicConvertedAmount();
$amount = $item->getAmountConvertedFromCustomDefault();
}
$paid += $amount;

View File

@ -2,21 +2,27 @@
namespace App\Http\Controllers\Expenses;
use App\Http\Controllers\Controller;
use App\Http\Requests\Expense\Payment as Request;
use App\Abstracts\Http\Controller;
use App\Exports\Expenses\Payments as Export;
use App\Http\Requests\Banking\Transaction as Request;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Imports\Expenses\Payments as Import;
use App\Jobs\Banking\CreateTransaction;
use App\Jobs\Banking\DeleteTransaction;
use App\Jobs\Banking\UpdateTransaction;
use App\Models\Banking\Account;
use App\Models\Expense\Payment;
use App\Models\Expense\Vendor;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use App\Traits\Contacts;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Utilities\Modules;
class Payments extends Controller
{
use Uploads;
use Contacts, Currencies, DateTime;
/**
* Display a listing of the resource.
@ -25,13 +31,13 @@ class Payments extends Controller
*/
public function index()
{
$payments = Payment::with(['vendor', 'account', 'category'])->isNotTransfer()->collect(['paid_at'=> 'desc']);
$payments = Transaction::type('expense')->with(['account', 'category', 'contact'])->isNotTransfer()->collect(['paid_at'=> 'desc']);
$vendors = collect(Vendor::enabled()->orderBy('name')->pluck('name', 'id'));
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = collect(Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id'));
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'));
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$transfer_cat_id = Category::transfer();
@ -45,7 +51,7 @@ class Payments extends Controller
*/
public function show()
{
return redirect('expenses/payments');
return redirect()->route('payments.index');
}
/**
@ -59,13 +65,13 @@ class Payments extends Controller
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$currency = Currency::where('code', $account_currency_code)->first();
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
@ -81,33 +87,33 @@ class Payments extends Controller
*/
public function store(Request $request)
{
$payment = Payment::create($request->input());
$response = $this->ajaxDispatch(new CreateTransaction($request));
// Upload attachment
$media = $this->getMedia($request->file('attachment'), 'payments');
if ($response['success']) {
$response['redirect'] = route('payments.index');
if ($media) {
$payment->attachMedia($media, 'attachment');
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('payments.create');
$message = $response['message'];
flash($message)->error();
}
// Recurring
$payment->createRecurring();
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
return redirect('expenses/payments');
return response()->json($response);
}
/**
* Duplicate the specified resource.
*
* @param Payment $payment
* @param Transaction $payment
*
* @return Response
*/
public function duplicate(Payment $payment)
public function duplicate(Transaction $payment)
{
$clone = $payment->duplicate();
@ -115,37 +121,35 @@ class Payments extends Controller
flash($message)->success();
return redirect('expenses/payments/' . $clone->id . '/edit');
return redirect()->route('payments.edit', $clone->id);
}
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
if (!Import::createFromFile($import, 'Expense\Payment')) {
return redirect('common/import/expenses/payments');
}
\Excel::import(new Import(), $request->file('import'));
$message = trans('messages.success.imported', ['type' => trans_choice('general.payments', 2)]);
flash($message)->success();
return redirect('expenses/payments');
return redirect()->route('payments.index');
}
/**
* Show the form for editing the specified resource.
*
* @param Payment $payment
* @param Transaction $payment
*
* @return Response
*/
public function edit(Payment $payment)
public function edit(Transaction $payment)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
@ -153,66 +157,70 @@ class Payments extends Controller
$currency = Currency::where('code', $payment->currency_code)->first();
$vendors = Vendor::enabled()->orderBy('name')->pluck('name', 'id');
$vendors = Contact::type($this->getVendorTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('expense')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
return view('expenses.payments.edit', compact('payment', 'accounts', 'currencies', 'currency', 'vendors', 'categories', 'payment_methods'));
$date_format = $this->getCompanyDateFormat();
return view('expenses.payments.edit', compact('payment', 'accounts', 'currencies', 'currency', 'vendors', 'categories', 'payment_methods', 'date_format'));
}
/**
* Update the specified resource in storage.
*
* @param Payment $payment
* @param Request $request
* @param Transaction $payment
* @param Request $request
*
* @return Response
*/
public function update(Payment $payment, Request $request)
public function update(Transaction $payment, Request $request)
{
$payment->update($request->input());
$response = $this->ajaxDispatch(new UpdateTransaction($payment, $request));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'payments');
if ($response['success']) {
$response['redirect'] = route('payments.index');
$payment->attachMedia($media, 'attachment');
$message = trans('messages.success.updated', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('payments.edit', $payment->id);
$message = $response['message'];
flash($message)->error();
}
// Recurring
$payment->updateRecurring();
$message = trans('messages.success.updated', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
return redirect('expenses/payments');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Payment $payment
* @param Transaction $payment
*
* @return Response
*/
public function destroy(Payment $payment)
public function destroy(Transaction $payment)
{
// Can't delete transfer payment
if ($payment->category->id == Category::transfer()) {
return redirect('expenses/payments');
$response = $this->ajaxDispatch(new DeleteTransaction($payment));
$response['redirect'] = route('payments.index');
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
$payment->recurring()->delete();
$payment->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
return redirect('expenses/payments');
return response()->json($response);
}
/**
@ -222,12 +230,6 @@ class Payments extends Controller
*/
public function export()
{
\Excel::create('payments', function($excel) {
$excel->sheet('payments', function($sheet) {
$sheet->fromModel(Payment::filter(request()->input())->get()->makeHidden([
'id', 'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at'
]));
});
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.payments', 2) . '.xlsx');
}
}

View File

@ -2,23 +2,24 @@
namespace App\Http\Controllers\Expenses;
use App\Http\Controllers\Controller;
use App\Http\Requests\Expense\Vendor as Request;
use App\Abstracts\Http\Controller;
use App\Exports\Expenses\Vendors as Export;
use App\Http\Requests\Common\Contact as Request;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Imports\Expenses\Vendors as Import;
use App\Jobs\Common\CreateContact;
use App\Jobs\Common\DeleteContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Expense\Bill;
use App\Models\Expense\Payment;
use App\Models\Expense\Vendor;
use App\Models\Setting\Currency;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use App\Traits\Contacts;
use Date;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
class Vendors extends Controller
{
use Uploads;
use Contacts;
/**
* Display a listing of the resource.
@ -27,7 +28,7 @@ class Vendors extends Controller
*/
public function index()
{
$vendors = Vendor::collect();
$vendors = Contact::type($this->getVendorTypes())->collect();
return view('expenses.vendors.index', compact('vendors'));
}
@ -35,11 +36,11 @@ class Vendors extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Vendor $vendor
* @param Contact $vendor
*
* @return Response
*/
public function show(Vendor $vendor)
public function show(Contact $vendor)
{
$amounts = [
'paid' => 0,
@ -53,57 +54,42 @@ class Vendors extends Controller
];
// Handle bills
$bills = Bill::with(['status', 'payments'])->where('vendor_id', $vendor->id)->get();
$bills = Bill::where('contact_id', $vendor->id)->get();
$counts['bills'] = $bills->count();
$bill_payments = [];
$today = Date::today()->toDateString();
foreach ($bills as $item) {
$payments = 0;
foreach ($item->payments as $payment) {
$payment->category = $item->category;
$bill_payments[] = $payment;
$amount = $payment->getConvertedAmount();
$amounts['paid'] += $amount;
$payments += $amount;
}
// Already in payments
if ($item->bill_status_code == 'paid') {
continue;
}
$transactions = 0;
foreach ($item->transactions as $transaction) {
$transactions += $transaction->getAmountConvertedToDefault();
}
// Check if it's open or overdue invoice
if ($item->due_at > $today) {
$amounts['open'] += $item->getConvertedAmount() - $payments;
$amounts['open'] += $item->getAmountConvertedToDefault() - $transactions;
} else {
$amounts['overdue'] += $item->getConvertedAmount() - $payments;
$amounts['overdue'] += $item->getAmountConvertedToDefault() - $transactions;
}
}
// Handle payments
$payments = Payment::with(['account', 'category'])->where('vendor_id', $vendor->id)->get();
$transactions = Transaction::where('contact_id', $vendor->id)->type('expense')->get();
$counts['payments'] = $payments->count();
$counts['transactions'] = $transactions->count();
// Prepare data
$items = collect($payments)->each(function ($item) use (&$amounts) {
$amounts['paid'] += $item->getConvertedAmount();
});
$limit = request('limit', setting('general.list_limit', '25'));
$transactions = $this->paginate($items->merge($bill_payments)->sortByDesc('paid_at'), $limit);
$limit = request('limit', setting('default.list_limit', '25'));
$transactions = $this->paginate($transactions->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', 'bills', 'payments'));
return view('expenses.vendors.show', compact('vendor', 'counts', 'amounts', 'transactions', 'bills'));
}
/**
@ -127,30 +113,33 @@ class Vendors extends Controller
*/
public function store(Request $request)
{
$vendor = Vendor::create($request->all());
$response = $this->ajaxDispatch(new CreateContact($request));
// Upload logo
if ($request->file('logo')) {
$media = $this->getMedia($request->file('logo'), 'vendors');
if ($response['success']) {
$response['redirect'] = route('vendors.index');
$vendor->attachMedia($media, 'logo');
$message = trans('messages.success.added', ['type' => trans_choice('general.vendors', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('vendors.create');
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.added', ['type' => trans_choice('general.vendors', 1)]);
flash($message)->success();
return redirect('expenses/vendors');
return response()->json($response);
}
/**
* Duplicate the specified resource.
*
* @param Vendor $vendor
* @param Contact $vendor
*
* @return Response
*/
public function duplicate(Vendor $vendor)
public function duplicate(Contact $vendor)
{
$clone = $vendor->duplicate();
@ -158,37 +147,35 @@ class Vendors extends Controller
flash($message)->success();
return redirect('expenses/vendors/' . $clone->id . '/edit');
return redirect()->route('vendors.edit', $clone->id);
}
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
if (!Import::createFromFile($import, 'Expense\Vendor')) {
return redirect('common/import/expenses/vendors');
}
\Excel::import(new Import(), $request->file('import'));
$message = trans('messages.success.imported', ['type' => trans_choice('general.vendors', 2)]);
flash($message)->success();
return redirect('expenses/vendors');
return redirect()->route('vendors.index');
}
/**
* Show the form for editing the specified resource.
*
* @param Vendor $vendor
* @param Contact $vendor
*
* @return Response
*/
public function edit(Vendor $vendor)
public function edit(Contact $vendor)
{
$currencies = Currency::enabled()->pluck('name', 'code');
@ -198,94 +185,92 @@ class Vendors extends Controller
/**
* Update the specified resource in storage.
*
* @param Vendor $vendor
* @param Request $request
* @param Contact $vendor
* @param Request $request
*
* @return Response
*/
public function update(Vendor $vendor, Request $request)
public function update(Contact $vendor, Request $request)
{
$vendor->update($request->all());
$response = $this->ajaxDispatch(new UpdateContact($vendor, $request));
// Upload logo
if ($request->file('logo')) {
$media = $this->getMedia($request->file('logo'), 'vendors');
if ($response['success']) {
$response['redirect'] = route('vendors.index');
$vendor->attachMedia($media, 'logo');
$message = trans('messages.success.updated', ['type' => $vendor->name]);
flash($message)->success();
} else {
$response['redirect'] = route('vendors.edit', $vendor->id);
$message = $response['message'];
flash($message)->error();
}
$message = trans('messages.success.updated', ['type' => trans_choice('general.vendors', 1)]);
flash($message)->success();
return redirect('expenses/vendors');
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Vendor $vendor
* @param Contact $vendor
*
* @return Response
*/
public function enable(Vendor $vendor)
public function enable(Contact $vendor)
{
$vendor->enabled = 1;
$vendor->save();
$response = $this->ajaxDispatch(new UpdateContact($vendor, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.vendors', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $vendor->name]);
}
flash($message)->success();
return redirect()->route('vendors.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Vendor $vendor
* @param Contact $vendor
*
* @return Response
*/
public function disable(Vendor $vendor)
public function disable(Contact $vendor)
{
$vendor->enabled = 0;
$vendor->save();
$response = $this->ajaxDispatch(new UpdateContact($vendor, request()->merge(['enabled' => 0])));
$message = trans('messages.success.disabled', ['type' => trans_choice('general.vendors', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $vendor->name]);
}
flash($message)->success();
return redirect()->route('vendors.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Vendor $vendor
* @param Contact $vendor
*
* @return Response
*/
public function destroy(Vendor $vendor)
public function destroy(Contact $vendor)
{
$relationships = $this->countRelationships($vendor, [
'bills' => 'bills',
'payments' => 'payments',
]);
$response = $this->ajaxDispatch(new DeleteContact($vendor));
if (empty($relationships)) {
$vendor->delete();
$response['redirect'] = route('vendors.index');
$message = trans('messages.success.deleted', ['type' => trans_choice('general.vendors', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $vendor->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $vendor->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect('expenses/vendors');
return response()->json($response);
}
/**
@ -295,30 +280,16 @@ class Vendors extends Controller
*/
public function export()
{
\Excel::create('vendors', function($excel) {
$excel->sheet('vendors', function($sheet) {
$sheet->fromModel(Vendor::filter(request()->input())->get()->makeHidden([
'id', 'company_id', 'created_at', 'updated_at', 'deleted_at'
]));
});
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.vendors', 2) . '.xlsx');
}
public function currency()
public function currency(Contact $vendor)
{
$vendor_id = (int) request('vendor_id');
if (empty($vendor_id)) {
return response()->json([]);
}
$vendor = Vendor::find($vendor_id);
if (empty($vendor)) {
return response()->json([]);
}
$currency_code = setting('general.default_currency');
$currency_code = setting('default.currency');
if (isset($vendor->currency_code)) {
$currencies = Currency::enabled()->pluck('name', 'code')->toArray();
@ -331,6 +302,7 @@ class Vendors extends Controller
// Get currency object
$currency = Currency::where('code', $currency_code)->first();
$vendor->currency_name = $currency->name;
$vendor->currency_code = $currency_code;
$vendor->currency_rate = $currency->rate;
@ -342,30 +314,4 @@ class Vendors extends Controller
return response()->json($vendor);
}
public function vendor(Request $request)
{
$vendor = Vendor::create($request->all());
return response()->json($vendor);
}
/**
* Generate a pagination collection.
*
* @param array|Collection $items
* @param int $perPage
* @param int $page
* @param array $options
*
* @return LengthAwarePaginator
*/
public function paginate($items, $perPage = 15, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
}

View File

@ -2,23 +2,25 @@
namespace App\Http\Controllers\Incomes;
use App\Http\Controllers\Controller;
use App\Http\Requests\Income\Customer as Request;
use App\Models\Auth\User;
use App\Models\Income\Customer;
use App\Abstracts\Http\Controller;
use App\Exports\Incomes\Customers as Export;
use App\Http\Requests\Common\Contact as Request;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Imports\Incomes\Customers as Import;
use App\Jobs\Common\CreateContact;
use App\Jobs\Common\DeleteContact;
use App\Jobs\Common\UpdateContact;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Income\Invoice;
use App\Models\Income\Revenue;
use App\Models\Setting\Currency;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use App\Traits\Contacts;
use Date;
use Illuminate\Http\Request as FRequest;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Http\Request as BaseRequest;
class Customers extends Controller
{
use Contacts;
/**
* Display a listing of the resource.
@ -27,7 +29,7 @@ class Customers extends Controller
*/
public function index()
{
$customers = Customer::collect();
$customers = Contact::type($this->getCustomerTypes())->collect();
return view('incomes.customers.index', compact('customers'));
}
@ -35,11 +37,11 @@ class Customers extends Controller
/**
* Show the form for viewing the specified resource.
*
* @param Customer $customer
* @param Contact $customer
*
* @return Response
*/
public function show(Customer $customer)
public function show(Contact $customer)
{
$amounts = [
'paid' => 0,
@ -53,57 +55,47 @@ class Customers extends Controller
];
// Handle invoices
$invoices = Invoice::with(['status', 'payments'])->where('customer_id', $customer->id)->get();
$invoices = Invoice::where('contact_id', $customer->id)->get();
$counts['invoices'] = $invoices->count();
$invoice_payments = [];
$today = Date::today()->toDateString();
foreach ($invoices as $item) {
$payments = 0;
foreach ($item->payments as $payment) {
$payment->category = $item->category;
$invoice_payments[] = $payment;
$amount = $payment->getConvertedAmount();
$amounts['paid'] += $amount;
$payments += $amount;
}
// Already in revenues
if ($item->invoice_status_code == 'paid') {
continue;
}
$transactions = 0;
foreach ($item->transactions as $transaction) {
$transactions += $transaction->getAmountConvertedToDefault();
}
// Check if it's open or overdue invoice
if ($item->due_at > $today) {
$amounts['open'] += $item->getConvertedAmount() - $payments;
$amounts['open'] += $item->getAmountConvertedToDefault() - $transactions;
} else {
$amounts['overdue'] += $item->getConvertedAmount() - $payments;
$amounts['overdue'] += $item->getAmountConvertedToDefault() - $transactions;
}
}
// Handle revenues
$revenues = Revenue::with(['account', 'category'])->where('customer_id', $customer->id)->get();
// Handle transactions
$transactions = Transaction::where('contact_id', $customer->id)->type('income')->get();
$counts['revenues'] = $revenues->count();
$counts['transactions'] = $transactions->count();
// Prepare data
$items = collect($revenues)->each(function ($item) use (&$amounts) {
$amounts['paid'] += $item->getConvertedAmount();
$transactions->each(function ($item) use (&$amounts) {
$amounts['paid'] += $item->getAmountConvertedToDefault();
});
$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);
$limit = request('limit', setting('default.list_limit', '25'));
$transactions = $this->paginate($transactions->sortByDesc('paid_at'), $limit);
$invoices = $this->paginate($invoices->sortByDesc('invoiced_at'), $limit);
return view('incomes.customers.show', compact('customer', 'counts', 'amounts', 'transactions', 'invoices', 'revenues'));
return view('incomes.customers.show', compact('customer', 'counts', 'amounts', 'transactions', 'invoices'));
}
/**
@ -127,50 +119,33 @@ class Customers extends Controller
*/
public function store(Request $request)
{
if (empty($request->input('create_user'))) {
Customer::create($request->all());
$response = $this->ajaxDispatch(new CreateContact($request));
if ($response['success']) {
$response['redirect'] = route('customers.index');
$message = trans('messages.success.added', ['type' => trans_choice('general.customers', 1)]);
flash($message)->success();
} else {
// Check if user exist
$user = User::where('email', $request['email'])->first();
if (!empty($user)) {
$message = trans('messages.error.customer', ['name' => $user->name]);
$response['redirect'] = route('customers.create');
flash($message)->error();
$message = $response['message'];
return redirect()->back()->withInput($request->except('create_user'))->withErrors(
['email' => trans('customers.error.email')]
);
}
// Create user first
$data = $request->all();
$data['locale'] = setting('general.default_locale', 'en-GB');
$user = User::create($data);
$user->roles()->attach(['3']);
$user->companies()->attach([session('company_id')]);
// Finally create customer
$request['user_id'] = $user->id;
Customer::create($request->all());
flash($message)->error();
}
$message = trans('messages.success.added', ['type' => trans_choice('general.customers', 1)]);
flash($message)->success();
return redirect('incomes/customers');
return response()->json($response);
}
/**
* Duplicate the specified resource.
*
* @param Customer $customer
* @param Contact $customer
*
* @return Response
*/
public function duplicate(Customer $customer)
public function duplicate(Contact $customer)
{
$clone = $customer->duplicate();
@ -178,37 +153,35 @@ class Customers extends Controller
flash($message)->success();
return redirect('incomes/customers/' . $clone->id . '/edit');
return redirect()->route('customers.edit', $clone->id);
}
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
if (!Import::createFromFile($import, 'Income\Customer')) {
return redirect('common/import/incomes/customers');
}
\Excel::import(new Import(), $request->file('import'));
$message = trans('messages.success.imported', ['type' => trans_choice('general.customers', 2)]);
flash($message)->success();
return redirect('incomes/customers');
return redirect()->route('customers.index');
}
/**
* Show the form for editing the specified resource.
*
* @param Customer $customer
* @param Contact $customer
*
* @return Response
*/
public function edit(Customer $customer)
public function edit(Contact $customer)
{
$currencies = Currency::enabled()->pluck('name', 'code');
@ -218,110 +191,92 @@ class Customers extends Controller
/**
* Update the specified resource in storage.
*
* @param Customer $customer
* @param Request $request
* @param Contact $customer
* @param Request $request
*
* @return Response
*/
public function update(Customer $customer, Request $request)
public function update(Contact $customer, Request $request)
{
if (empty($request->input('create_user'))) {
$customer->update($request->all());
$response = $this->ajaxDispatch(new UpdateContact($customer, $request));
if ($response['success']) {
$response['redirect'] = route('customers.index');
$message = trans('messages.success.updated', ['type' => $customer->name]);
flash($message)->success();
} else {
// Check if user exist
$user = User::where('email', $request['email'])->first();
if (!empty($user)) {
$message = trans('messages.error.customer', ['name' => $user->name]);
$response['redirect'] = route('customers.edit', $customer->id);
flash($message)->error();
$message = $response['message'];
return redirect()->back()->withInput($request->except('create_user'))->withErrors(
['email' => trans('customers.error.email')]
);
}
// Create user first
$user = User::create($request->all());
$user->roles()->attach(['3']);
$user->companies()->attach([session('company_id')]);
$request['user_id'] = $user->id;
$customer->update($request->all());
flash($message)->error();
}
$message = trans('messages.success.updated', ['type' => trans_choice('general.customers', 1)]);
flash($message)->success();
return redirect('incomes/customers');
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Customer $customer
* @param Contact $customer
*
* @return Response
*/
public function enable(Customer $customer)
public function enable(Contact $customer)
{
$customer->enabled = 1;
$customer->save();
$response = $this->ajaxDispatch(new UpdateContact($customer, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.customers', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $customer->name]);
}
flash($message)->success();
return redirect()->route('customers.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Customer $customer
* @param Contact $customer
*
* @return Response
*/
public function disable(Customer $customer)
public function disable(Contact $customer)
{
$customer->enabled = 0;
$customer->save();
$response = $this->ajaxDispatch(new UpdateContact($customer, request()->merge(['enabled' => 0])));
$message = trans('messages.success.disabled', ['type' => trans_choice('general.customers', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $customer->name]);
}
flash($message)->success();
return redirect()->route('customers.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Customer $customer
* @param Contact $customer
*
* @return Response
*/
public function destroy(Customer $customer)
public function destroy(Contact $customer)
{
$relationships = $this->countRelationships($customer, [
'invoices' => 'invoices',
'revenues' => 'revenues',
]);
$response = $this->ajaxDispatch(new DeleteContact($customer));
if (empty($relationships)) {
$customer->delete();
$response['redirect'] = route('customers.index');
$message = trans('messages.success.deleted', ['type' => trans_choice('general.customers', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $customer->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $customer->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect('incomes/customers');
return response()->json($response);
}
/**
@ -331,30 +286,16 @@ class Customers extends Controller
*/
public function export()
{
\Excel::create('customers', function($excel) {
$excel->sheet('customers', function($sheet) {
$sheet->fromModel(Customer::filter(request()->input())->get()->makeHidden([
'id', 'company_id', 'created_at', 'updated_at', 'deleted_at'
]));
});
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.customers', 2) . '.xlsx');
}
public function currency()
public function currency(Contact $customer)
{
$customer_id = (int) request('customer_id');
if (empty($customer_id)) {
return response()->json([]);
}
$customer = Customer::find($customer_id);
if (empty($customer)) {
return response()->json([]);
}
$currency_code = setting('general.default_currency');
$currency_code = setting('default.currency');
if (isset($customer->currency_code)) {
$currencies = Currency::enabled()->pluck('name', 'code')->toArray();
@ -380,14 +321,7 @@ class Customers extends Controller
return response()->json($customer);
}
public function customer(Request $request)
{
$customer = Customer::create($request->all());
return response()->json($customer);
}
public function field(FRequest $request)
public function field(BaseRequest $request)
{
$html = '';
@ -395,10 +329,10 @@ class Customers extends Controller
foreach ($request['fields'] as $field) {
switch ($field) {
case 'password':
$html .= \Form::passwordGroup('password', trans('auth.password.current'), 'key', [], null, 'col-md-6 password');
$html .= \Form::passwordGroup('password', trans('auth.password.current'), 'key', [], 'col-md-6 password');
break;
case 'password_confirmation':
$html .= \Form::passwordGroup('password_confirmation', trans('auth.password.current_confirm'), 'key', [], null, 'col-md-6 password');
$html .= \Form::passwordGroup('password_confirmation', trans('auth.password.current_confirm'), 'key', [], 'col-md-6 password');
break;
}
}
@ -410,23 +344,4 @@ class Customers extends Controller
return response()->json($json);
}
/**
* Generate a pagination collection.
*
* @param array|Collection $items
* @param int $perPage
* @param int $page
* @param array $options
*
* @return LengthAwarePaginator
*/
public function paginate($items, $perPage = 15, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
}

View File

@ -2,49 +2,36 @@
namespace App\Http\Controllers\Incomes;
use App\Events\InvoiceCreated;
use App\Events\InvoicePrinting;
use App\Events\InvoiceUpdated;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Exports\Incomes\Invoices as Export;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Http\Requests\Income\Invoice as Request;
use App\Http\Requests\Income\InvoiceAddItem as ItemRequest;
use App\Http\Requests\Income\InvoicePayment as PaymentRequest;
use App\Imports\Incomes\Invoices as Import;
use App\Jobs\Income\CreateInvoice;
use App\Jobs\Income\DeleteInvoice;
use App\Jobs\Income\DuplicateInvoice;
use App\Jobs\Income\UpdateInvoice;
use App\Jobs\Income\CreateInvoicePayment;
use App\Models\Banking\Account;
use App\Models\Common\Contact;
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\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\Contacts;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Incomes;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use App\Utilities\Modules;
use Date;
use File;
use Image;
use Storage;
use SignedUrl;
use Illuminate\Support\Facades\URL;
class Invoices extends Controller
{
use DateTime, Currencies, Incomes, Uploads;
use Contacts, Currencies, DateTime, Incomes;
/**
* Display a listing of the resource.
@ -53,13 +40,13 @@ class Invoices extends Controller
*/
public function index()
{
$invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories'])->collect(['invoice_number'=> 'desc']);
$invoices = Invoice::with(['contact', 'items', 'histories', 'status', 'transactions'])->collect(['invoice_number'=> 'desc']);
$customers = collect(Customer::enabled()->orderBy('name')->pluck('name', 'id'));
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = collect(Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id'));
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$statuses = collect(InvoiceStatus::get()->each(function($item) {
$statuses = collect(InvoiceStatus::get()->each(function ($item) {
$item->name = trans('invoices.status.' . $item->code);
return $item;
})->pluck('name', 'code'));
@ -80,17 +67,21 @@ class Invoices extends Controller
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
$currency = Currency::where('code', $invoice->currency_code)->first();
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
$customer_share = SignedUrl::sign(route('signed.invoices', $invoice->id));
$signed_url = URL::signedRoute('signed.invoices.show', [$invoice->id, 'company_id' => session('company_id')]);
return view('incomes.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'customer_share'));
$date_format = $this->getCompanyDateFormat();
return view('incomes.invoices.show', compact('invoice', 'accounts', 'currencies', 'currency', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'signed_url', 'date_format'));
}
/**
@ -100,17 +91,17 @@ class Invoices extends Controller
*/
public function create()
{
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', '=', setting('general.default_currency'))->first();
$currency = Currency::where('code', setting('default.currency'))->first();
$items = Item::enabled()->orderBy('name')->pluck('name', 'id');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$number = $this->getNextInvoiceNumber();
@ -126,13 +117,23 @@ class Invoices extends Controller
*/
public function store(Request $request)
{
$invoice = dispatch(new CreateInvoice($request));
$response = $this->ajaxDispatch(new CreateInvoice($request));
$message = trans('messages.success.added', ['type' => trans_choice('general.invoices', 1)]);
if ($response['success']) {
$response['redirect'] = route('invoices.show', $response['data']->id);
flash($message)->success();
$message = trans('messages.success.added', ['type' => trans_choice('general.invoices', 1)]);
return redirect('incomes/invoices/' . $invoice->id);
flash($message)->success();
} else {
$response['redirect'] = route('invoices.create');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
@ -144,58 +145,27 @@ class Invoices extends Controller
*/
public function duplicate(Invoice $invoice)
{
$clone = $invoice->duplicate();
// Add invoice history
InvoiceHistory::create([
'company_id' => session('company_id'),
'invoice_id' => $clone->id,
'status_code' => 'draft',
'notify' => 0,
'description' => trans('messages.success.added', ['type' => $clone->invoice_number]),
]);
// Update next invoice number
$this->increaseNextInvoiceNumber();
$clone = $this->dispatch(new DuplicateInvoice($invoice));
$message = trans('messages.success.duplicated', ['type' => trans_choice('general.invoices', 1)]);
flash($message)->success();
return redirect('incomes/invoices/' . $clone->id . '/edit');
return redirect()->route('invoices.edit', $clone->id);
}
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
$success = true;
$allowed_sheets = ['invoices', 'invoice_items', 'invoice_item_taxes', 'invoice_histories', 'invoice_payments', 'invoice_totals'];
// Loop through all sheets
$import->each(function ($sheet) use (&$success, $allowed_sheets) {
$sheet_title = $sheet->getTitle();
if (!in_array($sheet_title, $allowed_sheets)) {
$message = trans('messages.error.import_sheet');
flash($message)->error()->important();
return false;
}
$slug = 'Income\\' . str_singular(studly_case($sheet_title));
if (!$success = Import::createFromSheet($sheet, $slug)) {
return false;
}
});
\Excel::import(new Import(), $request->file('import'));
if (!$success) {
return redirect('common/import/incomes/invoices');
@ -211,23 +181,23 @@ class Invoices extends Controller
/**
* Show the form for editing the specified resource.
*
* @param Invoice $invoice
* @param Invoice $invoice
*
* @return Response
*/
public function edit(Invoice $invoice)
{
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', '=', $invoice->currency_code)->first();
$currency = Currency::where('code', $invoice->currency_code)->first();
$items = Item::enabled()->orderBy('name')->pluck('name', 'id');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
return view('incomes.invoices.edit', compact('invoice', 'customers', 'currencies', 'currency', 'items', 'taxes', 'categories'));
}
@ -235,51 +205,56 @@ class Invoices extends Controller
/**
* Update the specified resource in storage.
*
* @param Invoice $invoice
* @param Request $request
* @param Invoice $invoice
* @param Request $request
*
* @return Response
*/
public function update(Invoice $invoice, Request $request)
{
$invoice = dispatch(new UpdateInvoice($invoice, $request));
$response = $this->ajaxDispatch(new UpdateInvoice($invoice, $request));
$message = trans('messages.success.updated', ['type' => trans_choice('general.invoices', 1)]);
if ($response['success']) {
$response['redirect'] = route('invoices.index');
flash($message)->success();
$message = trans('messages.success.updated', ['type' => trans_choice('general.invoices', 1)]);
return redirect('incomes/invoices/' . $invoice->id);
flash($message)->success();
} else {
$response['redirect'] = route('invoices.edit', $invoice->id);
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Invoice $invoice
* @param Invoice $invoice
*
* @return Response
*/
public function destroy(Invoice $invoice)
{
// Increase stock
$invoice->items()->each(function ($invoice_item) {
$item = Item::find($invoice_item->item_id);
$response = $this->ajaxDispatch(new DeleteInvoice($invoice));
if (empty($item)) {
return;
}
$response['redirect'] = route('invoices.index');
$item->quantity += (double) $invoice_item->quantity;
$item->save();
});
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.invoices', 1)]);
$this->deleteRelationships($invoice, ['items', 'item_taxes', 'histories', 'payments', 'recurring', 'totals']);
$invoice->delete();
flash($message)->success();
} else {
$message = $response['message'];
$message = trans('messages.success.deleted', ['type' => trans_choice('general.invoices', 1)]);
flash($message)->error();
}
flash($message)->success();
return redirect('incomes/invoices');
return response()->json($response);
}
/**
@ -289,37 +264,7 @@ class Invoices extends Controller
*/
public function export()
{
\Excel::create('invoices', function ($excel) {
$invoices = Invoice::with(['items', 'item_taxes', 'histories', 'payments', 'totals'])->filter(request()->input())->get();
$excel->sheet('invoices', function ($sheet) use ($invoices) {
$sheet->fromModel($invoices->makeHidden([
'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at', 'attachment', 'discount', 'items', 'item_taxes', 'histories', 'payments', 'totals', 'media', 'paid', 'amount_without_tax'
]));
});
$tables = ['items', 'item_taxes', 'histories', 'payments', 'totals'];
foreach ($tables as $table) {
$excel->sheet('invoice_' . $table, function ($sheet) use ($invoices, $table) {
$hidden_fields = ['id', 'company_id', 'created_at', 'updated_at', 'deleted_at', 'title'];
$i = 1;
foreach ($invoices as $invoice) {
$model = $invoice->$table->makeHidden($hidden_fields);
if ($i == 1) {
$sheet->fromModel($model, null, 'A1', false);
} else {
// Don't put multiple heading columns
$sheet->fromModel($model, null, 'A1', false, false);
}
$i++;
}
});
}
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.invoices', 2) . '.xlsx');
}
/**
@ -331,20 +276,11 @@ class Invoices extends Controller
*/
public function markSent(Invoice $invoice)
{
$invoice->invoice_status_code = 'sent';
event(new \App\Events\Income\InvoiceSent($invoice));
$invoice->save();
$message = trans('invoices.messages.marked_sent');
// Add invoice history
InvoiceHistory::create([
'company_id' => $invoice->company_id,
'invoice_id' => $invoice->id,
'status_code' => 'sent',
'notify' => 0,
'description' => trans('invoices.mark_sent'),
]);
flash(trans('invoices.messages.marked_sent'))->success();
flash($message)->success();
return redirect()->back();
}
@ -358,7 +294,7 @@ class Invoices extends Controller
*/
public function emailInvoice(Invoice $invoice)
{
if (empty($invoice->customer_email)) {
if (empty($invoice->contact_email)) {
return redirect()->back();
}
@ -367,7 +303,7 @@ class Invoices extends Controller
$view = view($invoice->template_path, compact('invoice'))->render();
$html = mb_convert_encoding($view, 'HTML-ENTITIES');
$pdf = \App::make('dompdf.wrapper');
$pdf = app('dompdf.wrapper');
$pdf->loadHTML($html);
$file = storage_path('app/temp/invoice_'.time().'.pdf');
@ -378,7 +314,7 @@ class Invoices extends Controller
$pdf->save($file);
// Notify the customer
$invoice->customer->notify(new Notification($invoice));
$invoice->contact->notify(new Notification($invoice, 'invoice_new_customer'));
// Delete temp file
File::delete($file);
@ -388,21 +324,7 @@ class Invoices extends Controller
unset($invoice->pdf_path);
unset($invoice->reconciled);
// Mark invoice as sent
if ($invoice->invoice_status_code != 'partial') {
$invoice->invoice_status_code = 'sent';
$invoice->save();
}
// Add invoice history
InvoiceHistory::create([
'company_id' => $invoice->company_id,
'invoice_id' => $invoice->id,
'status_code' => 'sent',
'notify' => 1,
'description' => trans('invoices.send_mail'),
]);
event(new \App\Events\Income\InvoiceSent($invoice));
flash(trans('invoices.messages.email_sent'))->success();
@ -458,199 +380,18 @@ class Invoices extends Controller
*/
public function markPaid(Invoice $invoice)
{
$paid = 0;
try {
event(new \App\Events\Income\PaymentReceived($invoice, []));
foreach ($invoice->payments as $item) {
$amount = $item->amount;
$message = trans('invoices.messages.marked_paid');
if ($invoice->currency_code != $item->currency_code) {
$item->default_currency_code = $invoice->currency_code;
flash($message)->success();
} catch(\Exception $e) {
$message = $e->getMessage();
$amount = $item->getDynamicConvertedAmount();
}
$paid += $amount;
flash($message)->error();
}
$amount = $invoice->amount - $paid;
if (!empty($amount)) {
$request = new PaymentRequest();
$request['company_id'] = $invoice->company_id;
$request['invoice_id'] = $invoice->id;
$request['account_id'] = setting('general.default_account');
$request['payment_method'] = setting('general.default_payment_method', 'offlinepayment.cash.1');
$request['currency_code'] = $invoice->currency_code;
$request['amount'] = $amount;
$request['paid_at'] = Date::now()->format('Y-m-d');
$request['_token'] = csrf_token();
$this->payment($request);
} else {
$invoice->invoice_status_code = 'paid';
$invoice->save();
}
return redirect()->back();
}
/**
* Add payment to the invoice.
*
* @param PaymentRequest $request
*
* @return Response
*/
public function payment(PaymentRequest $request)
{
// Get currency object
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$currency = Currency::where('code', $request['currency_code'])->first();
$request['currency_code'] = $currency->code;
$request['currency_rate'] = $currency->rate;
$invoice = Invoice::find($request['invoice_id']);
$total_amount = $invoice->amount;
$default_amount = (double) $request['amount'];
if ($invoice->currency_code == $request['currency_code']) {
$amount = $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 = $request['currency_code'];
$default_amount_model->currency_rate = $currencies[$request['currency_code']];
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
$convert_amount = new InvoicePayment();
$convert_amount->default_currency_code = $request['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();
}
if ($invoice->payments()->count()) {
$total_amount -= $invoice->payments()->paid();
}
// For amount cover integer
$multiplier = 1;
for ($i = 0; $i < $currency->precision; $i++) {
$multiplier *= 10;
}
$amount_check = (int) ($amount * $multiplier);
$total_amount_check = (int) (round($total_amount, $currency->precision) * $multiplier);
if ($amount_check > $total_amount_check) {
$error_amount = $total_amount;
if ($invoice->currency_code != $request['currency_code']) {
$error_amount_model = new InvoicePayment();
$error_amount_model->default_currency_code = $request['currency_code'];
$error_amount_model->amount = $error_amount;
$error_amount_model->currency_code = $invoice->currency_code;
$error_amount_model->currency_rate = $currencies[$invoice->currency_code];
$error_amount = (double) $error_amount_model->getDivideConvertedAmount();
$convert_amount = new InvoicePayment();
$convert_amount->default_currency_code = $invoice->currency_code;
$convert_amount->amount = $error_amount;
$convert_amount->currency_code = $request['currency_code'];
$convert_amount->currency_rate = $currencies[$request['currency_code']];
$error_amount = (double) $convert_amount->getDynamicConvertedAmount();
}
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $request['currency_code'], true)]);
return response()->json([
'success' => false,
'error' => true,
'data' => [
'amount' => $error_amount
],
'message' => $message,
'html' => 'null',
]);
} elseif ($amount_check == $total_amount_check) {
$invoice->invoice_status_code = 'paid';
} else {
$invoice->invoice_status_code = 'partial';
}
$invoice->save();
$invoice_payment = dispatch(new CreateInvoicePayment($request, $invoice));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'invoices');
$invoice_payment->attachMedia($media, 'attachment');
}
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
]);
}
/**
* Remove the specified resource from storage.
*
* @param InvoicePayment $payment
*
* @return Response
*/
public function paymentDestroy(InvoicePayment $payment)
{
$invoice = Invoice::find($payment->invoice_id);
if ($invoice->payments()->count() > 1) {
$invoice->invoice_status_code = 'partial';
} else {
$invoice->invoice_status_code = 'sent';
}
$invoice->save();
$desc_amount = money((float) $payment->amount, (string) $payment->currency_code, true)->format();
$description = $desc_amount . ' ' . trans_choice('general.payments', 1);
// Add invoice history
InvoiceHistory::create([
'company_id' => $invoice->company_id,
'invoice_id' => $invoice->id,
'status_code' => $invoice->invoice_status_code,
'notify' => 0,
'description' => trans('messages.success.deleted', ['type' => $description]),
]);
$payment->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.invoices', 1)]);
flash($message)->success();
return redirect()->back();
}
@ -659,12 +400,12 @@ class Invoices extends Controller
$item_row = $request['item_row'];
$currency_code = $request['currency_code'];
$taxes = Tax::enabled()->orderBy('rate')->get()->pluck('title', 'id');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$currency = Currency::where('code', '=', $currency_code)->first();
$currency = Currency::where('code', $currency_code)->first();
if (empty($currency)) {
$currency = Currency::where('code', '=', setting('general.default_currency'))->first();
$currency = Currency::where('code', setting('default.currency', 'USD'))->first();
}
if ($currency) {
@ -695,7 +436,7 @@ class Invoices extends Controller
if ($invoice->currency_code != $item->currency_code) {
$item->default_currency_code = $invoice->currency_code;
$amount = $item->getDynamicConvertedAmount();
$amount = $item->getAmountConvertedFromCustomDefault();
}
$paid += $amount;
@ -705,7 +446,7 @@ class Invoices extends Controller
$invoice->template_path = 'incomes.invoices.invoice';
event(new InvoicePrinting($invoice));
event(new \App\Events\Income\InvoicePrinting($invoice));
return $invoice;
}

View File

@ -2,23 +2,27 @@
namespace App\Http\Controllers\Incomes;
use App\Http\Controllers\Controller;
use App\Http\Requests\Income\Revenue as Request;
use App\Abstracts\Http\Controller;
use App\Exports\Incomes\Revenues as Export;
use App\Http\Requests\Banking\Transaction as Request;
use App\Http\Requests\Common\Import as ImportRequest;
use App\Imports\Common\Items as Import;
use App\Jobs\Banking\CreateTransaction;
use App\Jobs\Banking\DeleteTransaction;
use App\Jobs\Banking\UpdateTransaction;
use App\Models\Banking\Account;
use App\Models\Income\Customer;
use App\Models\Income\Revenue;
use App\Models\Banking\Transaction;
use App\Models\Common\Contact;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Traits\Contacts;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use App\Utilities\Modules;
class Revenues extends Controller
{
use DateTime, Currencies, Uploads;
use Contacts, Currencies, DateTime;
/**
* Display a listing of the resource.
@ -27,13 +31,13 @@ class Revenues extends Controller
*/
public function index()
{
$revenues = Revenue::with(['account', 'category', 'customer'])->isNotTransfer()->collect(['paid_at'=> 'desc']);
$revenues = Transaction::type('income')->with(['account', 'category', 'contact'])->isNotTransfer()->collect(['paid_at'=> 'desc']);
$customers = collect(Customer::enabled()->orderBy('name')->pluck('name', 'id'));
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = collect(Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id'));
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$accounts = collect(Account::enabled()->orderBy('name')->pluck('name', 'id'));
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$transfer_cat_id = Category::transfer();
@ -47,7 +51,7 @@ class Revenues extends Controller
*/
public function show()
{
return redirect('incomes/revenues');
return redirect()->route('revenues.index');
}
/**
@ -61,13 +65,13 @@ class Revenues extends Controller
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$currency = Currency::where('code', $account_currency_code)->first();
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
@ -83,33 +87,33 @@ class Revenues extends Controller
*/
public function store(Request $request)
{
$revenue = Revenue::create($request->input());
$response = $this->ajaxDispatch(new CreateTransaction($request));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'revenues');
if ($response['success']) {
$response['redirect'] = route('revenues.index');
$revenue->attachMedia($media, 'attachment');
$message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('revenues.create');
$message = $response['message'];
flash($message)->error();
}
// Recurring
$revenue->createRecurring();
$message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]);
flash($message)->success();
return redirect('incomes/revenues');
return response()->json($response);
}
/**
* Duplicate the specified resource.
*
* @param Revenue $revenue
* @param Transaction $revenue
*
* @return Response
*/
public function duplicate(Revenue $revenue)
public function duplicate(Transaction $revenue)
{
$clone = $revenue->duplicate();
@ -117,37 +121,35 @@ class Revenues extends Controller
flash($message)->success();
return redirect('incomes/revenues/' . $clone->id . '/edit');
return redirect()->route('revenues.edit', $clone->id);
}
/**
* Import the specified resource.
*
* @param ImportFile $import
* @param ImportRequest $request
*
* @return Response
*/
public function import(ImportFile $import)
public function import(ImportRequest $request)
{
if (!Import::createFromFile($import, 'Income\Revenue')) {
return redirect('common/import/incomes/revenues');
}
\Excel::import(new Import(), $request->file('import'));
$message = trans('messages.success.imported', ['type' => trans_choice('general.revenues', 2)]);
flash($message)->success();
return redirect('incomes/revenues');
return redirect()->route('revenues.index');
}
/**
* Show the form for editing the specified resource.
*
* @param Revenue $revenue
* @param Transaction $revenue
*
* @return Response
*/
public function edit(Revenue $revenue)
public function edit(Transaction $revenue)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
@ -155,66 +157,70 @@ class Revenues extends Controller
$currency = Currency::where('code', $revenue->currency_code)->first();
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
$customers = Contact::type($this->getCustomerTypes())->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
return view('incomes.revenues.edit', compact('revenue', 'accounts', 'currencies', 'currency', 'customers', 'categories', 'payment_methods'));
$date_format = $this->getCompanyDateFormat();
return view('incomes.revenues.edit', compact('revenue', 'accounts', 'currencies', 'currency', 'customers', 'categories', 'payment_methods', 'date_format'));
}
/**
* Update the specified resource in storage.
*
* @param Revenue $revenue
* @param Request $request
* @param Transaction $revenue
* @param Request $request
*
* @return Response
*/
public function update(Revenue $revenue, Request $request)
public function update(Transaction $revenue, Request $request)
{
$revenue->update($request->input());
$response = $this->ajaxDispatch(new UpdateTransaction($revenue, $request));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'revenues');
if ($response['success']) {
$response['redirect'] = route('revenues.index');
$revenue->attachMedia($media, 'attachment');
$message = trans('messages.success.updated', ['type' => trans_choice('general.revenues', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('revenues.edit', $revenue->id);
$message = $response['message'];
flash($message)->error();
}
// Recurring
$revenue->updateRecurring();
$message = trans('messages.success.updated', ['type' => trans_choice('general.revenues', 1)]);
flash($message)->success();
return redirect('incomes/revenues');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Revenue $revenue
* @param Transaction $revenue
*
* @return Response
*/
public function destroy(Revenue $revenue)
public function destroy(Transaction $revenue)
{
// Can't delete transfer revenue
if ($revenue->category->id == Category::transfer()) {
return redirect('incomes/revenues');
$response = $this->ajaxDispatch(new DeleteTransaction($revenue));
$response['redirect'] = route('revenues.index');
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => trans_choice('general.revenues', 1)]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
$revenue->recurring()->delete();
$revenue->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.revenues', 1)]);
flash($message)->success();
return redirect('incomes/revenues');
return response()->json($response);
}
/**
@ -224,12 +230,6 @@ class Revenues extends Controller
*/
public function export()
{
\Excel::create('revenues', function($excel) {
$excel->sheet('revenues', function($sheet) {
$sheet->fromModel(Revenue::filter(request()->input())->get()->makeHidden([
'id', 'company_id', 'parent_id', 'created_at', 'updated_at', 'deleted_at'
]));
});
})->download('xlsx');
return \Excel::download(new Export(), trans_choice('general.revenues', 2) . '.xlsx');
}
}

View File

@ -28,7 +28,7 @@ class Database extends Controller
*/
public function store(Request $request)
{
$host = $request['hostname'];
$host = $request['hostname'];
$port = env('DB_PORT', '3306');
$database = $request['database'];
$username = $request['username'];
@ -36,13 +36,20 @@ class Database extends Controller
// Check database connection
if (!Installer::createDbTables($host, $port, $database, $username, $password)) {
$message = trans('install.error.connection');
flash($message)->error()->important();
return redirect('install/database')->withInput();
$response = [
'status' => null,
'success' => false,
'error' => true,
'message' => trans('install.error.connection'),
'data' => null,
'redirect' => null,
];
}
return redirect('install/settings');
if (empty($response)) {
$response['redirect'] = route('install.settings');
}
return response()->json($response);
}
}

View File

@ -30,6 +30,22 @@ class Language extends Controller
// Set locale
Session::put('locale', $request['lang']);
return redirect('install/database');
$response['redirect'] = route('install.database');
return response()->json($response);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function getLanguages()
{
$response = [
'languages' => $languages = language()->allowed(),
];
return response()->json($response);
}
}

View File

@ -37,6 +37,8 @@ class Settings extends Controller
Installer::finalTouches();
// Redirect to dashboard
return redirect('auth/login');
$response['redirect'] = route('login');
return response()->json($response);
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Install;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Utilities\Updater;
use App\Utilities\Versions;
use Illuminate\Http\Request;
@ -28,7 +28,7 @@ class Updates extends Controller
$core = $updates['core'];
}
$rows = Module::all();
$rows = module()->all();
if ($rows) {
foreach ($rows as $row) {
@ -39,7 +39,7 @@ class Updates extends Controller
}
$m = new \stdClass();
$m->name = $row->get('name');
$m->name = $row->getName();
$m->alias = $row->get('alias');
$m->category = $row->get('category');
$m->installed = $row->get('version');
@ -85,9 +85,9 @@ class Updates extends Controller
$installed = version('short');
} else {
// Get module instance
$module = Module::findByAlias($alias);
$module = module($alias);
$name = $module->get('name');
$name = $module->getName();
$installed = $module->get('version');
}
@ -128,23 +128,23 @@ class Updates extends Controller
'url' => url('install/updates/file-copy')
];
// Migrate DB and trigger event UpdateFinish event
// Finish installation
$json['step'][] = [
'text' => trans('modules.installation.migrate', ['module' => $name]),
'url' => url('install/updates/migrate')
'text' => trans('modules.installation.finish', ['module' => $name]),
'url' => url('install/updates/finish')
];
// redirect update page
// Redirect
$json['step'][] = [
'text' => trans('modules.installation.finish'),
'url' => url('install/updates/finish')
'text' => trans('modules.installation.redirect', ['module' => $name]),
'url' => url('install/updates/redirect')
];
return response()->json($json);
}
/**
* Show the form for viewing the specified resource.
* Download the file
*
* @param $request
*
@ -154,17 +154,13 @@ class Updates extends Controller
{
set_time_limit(600); // 10 minutes
if ($request['alias'] != 'core') {
$this->checkApiToken();
}
$json = Updater::download($request['name'], $request['alias'], $request['version']);
$json = Updater::download($request['alias'], $request['version'], $request['installed']);
return response()->json($json);
}
/**
* Show the form for viewing the specified resource.
* Unzip the downloaded file
*
* @param $request
*
@ -174,17 +170,13 @@ class Updates extends Controller
{
set_time_limit(600); // 10 minutes
if ($request['alias'] != 'core') {
$this->checkApiToken();
}
$json = Updater::unzip($request['name'], $request['path']);
$json = Updater::unzip($request['path'], $request['alias'], $request['version'], $request['installed']);
return response()->json($json);
}
/**
* Show the form for viewing the specified resource.
* Copy files
*
* @param $request
*
@ -194,42 +186,38 @@ class Updates extends Controller
{
set_time_limit(600); // 10 minutes
if ($request['alias'] != 'core') {
$this->checkApiToken();
}
$json = Updater::fileCopy($request['name'], $request['alias'], $request['path'], $request['version']);
$json = Updater::fileCopy($request['path'], $request['alias'], $request['version'], $request['installed']);
return response()->json($json);
}
/**
* Show the form for viewing the specified resource.
*
* @param $request
*
* @return Response
*/
public function migrate(Request $request)
{
$json = Updater::migrate($request['name'], $request['alias'], $request['version'], $request['installed']);
return response()->json($json);
}
/**
* Show the form for viewing the specified resource.
* Finish the update
*
* @param $request
*
* @return Response
*/
public function finish(Request $request)
{
$json = Updater::finish($request['alias'], $request['version'], $request['installed']);
return response()->json($json);
}
/**
* Redirect back
*
* @param $request
*
* @return Response
*/
public function redirect(Request $request)
{
return response()->json([
'success' => true,
'errors' => false,
'redirect' => url("install/updates"),
'redirect' => route('updates.index'),
'data' => [],
]);
}

View File

@ -1,231 +0,0 @@
<?php
namespace App\Http\Controllers\Modals;
use App\Http\Controllers\Controller;
use App\Http\Requests\Expense\BillPayment as Request;
use App\Models\Expense\Bill;
use App\Models\Banking\Account;
use App\Models\Expense\BillPayment;
use App\Models\Expense\BillHistory;
use App\Models\Setting\Currency;
use App\Utilities\Modules;
use App\Traits\Uploads;
use App\Jobs\Expense\CreateBillPayment;
class BillPayments extends Controller
{
use Uploads;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:create-expenses-bills')->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-expenses-bills')->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-expenses-bills')->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-expenses-bills')->only('destroy');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create(Bill $bill)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', $bill->currency_code)->first();
$payment_methods = Modules::getPaymentMethods();
$paid = $this->getPaid($bill);
// Get Bill Totals
foreach ($bill->totals as $bill_total) {
$bill->{$bill_total->code} = $bill_total->amount;
}
$total = money($bill->total, $currency->code, true)->format();
$bill->grand_total = money($total, $currency->code)->getAmount();
if (!empty($paid)) {
$bill->grand_total = round($bill->total - $paid, $currency->precision) ;
}
$rand = rand();
$html = view('modals.bills.payment', compact('bill', 'accounts', 'currencies', 'currency', 'payment_methods', 'rand'))->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(Bill $bill, Request $request)
{
// Get currency object
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$currency = Currency::where('code', $request['currency_code'])->first();
$request['currency_code'] = $currency->code;
$request['currency_rate'] = $currency->rate;
$total_amount = $bill->amount;
$default_amount = (double) $request['amount'];
if ($bill->currency_code == $request['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 = $request['currency_code'];
$default_amount_model->currency_rate = $currencies[$request['currency_code']];
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
$convert_amount = new BillPayment();
$convert_amount->default_currency_code = $request['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();
}
if ($bill->payments()->count()) {
$total_amount -= $this->getPaid($bill);
}
// For amount cover integer
$multiplier = 1;
for ($i = 0; $i < $currency->precision; $i++) {
$multiplier *= 10;
}
$amount_check = (int) ($amount * $multiplier);
$total_amount_check = (int) (round($total_amount, $currency->precision) * $multiplier);
if ($amount_check > $total_amount_check) {
$error_amount = $total_amount;
if ($bill->currency_code != $request['currency_code']) {
$error_amount_model = new BillPayment();
$error_amount_model->default_currency_code = $request['currency_code'];
$error_amount_model->amount = $error_amount;
$error_amount_model->currency_code = $bill->currency_code;
$error_amount_model->currency_rate = $currencies[$bill->currency_code];
$error_amount = (double) $error_amount_model->getDivideConvertedAmount();
$convert_amount = new BillPayment();
$convert_amount->default_currency_code = $bill->currency_code;
$convert_amount->amount = $error_amount;
$convert_amount->currency_code = $request['currency_code'];
$convert_amount->currency_rate = $currencies[$request['currency_code']];
$error_amount = (double) $convert_amount->getDynamicConvertedAmount();
}
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $request['currency_code'], true)]);
return response()->json([
'success' => false,
'error' => true,
'data' => [
'amount' => $error_amount
],
'message' => $message,
'html' => 'null',
]);
} elseif ($amount_check == $total_amount_check) {
$bill->bill_status_code = 'paid';
} else {
$bill->bill_status_code = 'partial';
}
$bill->save();
$bill_payment = dispatch(new CreateBillPayment($request, $bill));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'bills');
$bill_payment->attachMedia($media, 'attachment');
}
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
return response()->json([
'success' => true,
'error' => false,
'data' => $bill_payment,
'message' => $message,
'html' => 'null',
]);
}
protected function getPaid($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;
}
}
return $paid;
}
}

View File

@ -0,0 +1,147 @@
<?php
namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Banking\Transaction as Request;
use App\Jobs\Banking\CreateDocumentTransaction;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Expense\Bill;
use App\Models\Setting\Currency;
use App\Utilities\Modules;
use App\Traits\Uploads;
class BillTransactions extends Controller
{
use Uploads;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:create-expenses-bills')->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-expenses-bills')->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-expenses-bills')->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-expenses-bills')->only('destroy');
}
/**
* Show the form for creating a new resource.
*
* @param Bill $bill
*
* @return Response
*/
public function create(Bill $bill)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', $bill->currency_code)->first();
$payment_methods = Modules::getPaymentMethods();
$paid = $this->getPaidAmount($bill);
// Get Bill Totals
foreach ($bill->totals as $bill_total) {
$bill->{$bill_total->code} = $bill_total->amount;
}
$total = money($bill->total, $currency->code, true)->format();
$bill->grand_total = money($total, $currency->code)->getAmount();
if (!empty($paid)) {
$bill->grand_total = round($bill->total - $paid, $currency->precision) ;
}
$rand = rand();
$html = view('modals.bills.payment', compact('bill', 'accounts', 'currencies', 'currency', 'payment_methods', 'rand'))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
/**
* Store a newly created resource in storage.
*
* @param Bill $bill
* @param Request $request
*
* @return Response
*/
public function store(Bill $bill, Request $request)
{
try {
$transaction = $this->dispatch(new CreateDocumentTransaction($bill, $request));
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
$response = [
'success' => true,
'error' => false,
'message' => $message,
'data' => $transaction,
];
} catch(\Exception $e) {
$response = [
'success' => false,
'error' => true,
'message' => $e->getMessage(),
'data' => 'null',
];
}
return response()->json($response);
}
protected function getPaidAmount($bill)
{
$paid = 0;
// Get Bill Payments
if (!$bill->payments->count()) {
return $paid;
}
$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 Transaction();
$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_model = new Transaction();
$convert_amount_model->default_currency_code = $item->currency_code;
$convert_amount_model->amount = $default_amount;
$convert_amount_model->currency_code = $bill->currency_code;
$convert_amount_model->currency_rate = $currencies[$bill->currency_code];
$amount = (double) $convert_amount_model->getAmountConvertedFromCustomDefault();
}
$paid += $amount;
}
return $paid;
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Modals;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Category as Request;
use Illuminate\Http\Request as CRequest;
use App\Models\Setting\Category;

View File

@ -2,20 +2,10 @@
namespace App\Http\Controllers\Modals;
use App\Http\Controllers\Controller;
use App\Http\Requests\Income\Customer as Request;
use App\Models\Auth\User;
use App\Models\Income\Customer;
use App\Models\Income\Invoice;
use App\Models\Income\Revenue;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\Contact as Request;
use App\Models\Common\Contact;
use App\Models\Setting\Currency;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use Date;
use Illuminate\Http\Request as FRequest;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
class Customers extends Controller
{
@ -38,17 +28,17 @@ class Customers extends Controller
*/
public function create()
{
$currencies = Currency::enabled()->pluck('name', 'code');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$customer_selector = false;
$contact_selector = false;
if (request()->has('customer_selector')) {
$customer_selector = request()->get('customer_selector');
if (request()->has('contact_selector')) {
$contact_selector = request()->get('contact_selector');
}
$rand = rand();
$html = view('modals.customers.create', compact('currencies', 'customer_selector', 'rand'))->render();
$html = view('modals.customers.create', compact('currencies', 'contact_selector', 'rand'))->render();
return response()->json([
'success' => true,
@ -69,7 +59,7 @@ class Customers extends Controller
{
$request['enabled'] = 1;
$customer = Customer::create($request->all());
$customer = Contact::create($request->all());
$message = trans('messages.success.added', ['type' => trans_choice('general.customers', 1)]);

View File

@ -1,231 +0,0 @@
<?php
namespace App\Http\Controllers\Modals;
use App\Http\Controllers\Controller;
use App\Http\Requests\Income\InvoicePayment as Request;
use App\Models\Income\Invoice;
use App\Models\Banking\Account;
use App\Models\Income\InvoicePayment;
use App\Models\Income\InvoiceHistory;
use App\Models\Setting\Currency;
use App\Utilities\Modules;
use App\Traits\Uploads;
use App\Jobs\Income\CreateInvoicePayment;
class InvoicePayments extends Controller
{
use Uploads;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:create-incomes-invoices')->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-incomes-invoices')->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-incomes-invoices')->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-incomes-invoices')->only('destroy');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create(Invoice $invoice)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', $invoice->currency_code)->first();
$payment_methods = Modules::getPaymentMethods();
$paid = $this->getPaid($invoice);
// Get Invoice Totals
foreach ($invoice->totals as $invoice_total) {
$invoice->{$invoice_total->code} = $invoice_total->amount;
}
$total = money($invoice->total, $currency->code, true)->format();
$invoice->grand_total = money($total, $currency->code)->getAmount();
if (!empty($paid)) {
$invoice->grand_total = round($invoice->total - $paid, $currency->precision) ;
}
$rand = rand();
$html = view('modals.invoices.payment', compact('invoice', 'accounts', 'currencies', 'currency', 'payment_methods', 'rand'))->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(Invoice $invoice, Request $request)
{
// Get currency object
$currencies = Currency::enabled()->pluck('rate', 'code')->toArray();
$currency = Currency::where('code', $request['currency_code'])->first();
$request['currency_code'] = $currency->code;
$request['currency_rate'] = $currency->rate;
$total_amount = $invoice->amount;
$default_amount = (double) $request['amount'];
if ($invoice->currency_code == $request['currency_code']) {
$amount = $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 = $request['currency_code'];
$default_amount_model->currency_rate = $currencies[$request['currency_code']];
$default_amount = (double) $default_amount_model->getDivideConvertedAmount();
$convert_amount = new InvoicePayment();
$convert_amount->default_currency_code = $request['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();
}
if ($invoice->payments()->count()) {
$total_amount -= $this->getPaid($invoice);
}
// For amount cover integer
$multiplier = 1;
for ($i = 0; $i < $currency->precision; $i++) {
$multiplier *= 10;
}
$amount_check = (int) ($amount * $multiplier);
$total_amount_check = (int) (round($total_amount, $currency->precision) * $multiplier);
if ($amount_check > $total_amount_check) {
$error_amount = $total_amount;
if ($invoice->currency_code != $request['currency_code']) {
$error_amount_model = new InvoicePayment();
$error_amount_model->default_currency_code = $request['currency_code'];
$error_amount_model->amount = $error_amount;
$error_amount_model->currency_code = $invoice->currency_code;
$error_amount_model->currency_rate = $currencies[$invoice->currency_code];
$error_amount = (double) $error_amount_model->getDivideConvertedAmount();
$convert_amount = new InvoicePayment();
$convert_amount->default_currency_code = $invoice->currency_code;
$convert_amount->amount = $error_amount;
$convert_amount->currency_code = $request['currency_code'];
$convert_amount->currency_rate = $currencies[$request['currency_code']];
$error_amount = (double) $convert_amount->getDynamicConvertedAmount();
}
$message = trans('messages.error.over_payment', ['amount' => money($error_amount, $request['currency_code'], true)]);
return response()->json([
'success' => false,
'error' => true,
'data' => [
'amount' => $error_amount
],
'message' => $message,
'html' => 'null',
]);
} elseif ($amount_check == $total_amount_check) {
$invoice->invoice_status_code = 'paid';
} else {
$invoice->invoice_status_code = 'partial';
}
$invoice->save();
$invoice_payment = dispatch(new CreateInvoicePayment($request, $invoice));
// Upload attachment
if ($request->file('attachment')) {
$media = $this->getMedia($request->file('attachment'), 'invoices');
$invoice_payment->attachMedia($media, 'attachment');
}
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
return response()->json([
'success' => true,
'error' => false,
'data' => $invoice_payment,
'message' => $message,
'html' => 'null',
]);
}
protected function getPaid($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;
}
}
return $paid;
}
}

View File

@ -0,0 +1,154 @@
<?php
namespace App\Http\Controllers\Modals;
use App\Abstracts\Http\Controller;
use App\Events\Income\PaymentReceived;
use App\Http\Requests\Banking\Transaction as Request;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Income\Invoice;
use App\Models\Setting\Currency;
use App\Utilities\Modules;
use App\Traits\Uploads;
class InvoiceTransactions extends Controller
{
use Uploads;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:create-incomes-invoices')->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-incomes-invoices')->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-incomes-invoices')->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-incomes-invoices')->only('destroy');
}
/**
* Show the form for creating a new resource.
*
* @param Invoice $invoice
*
* @return Response
*/
public function create(Invoice $invoice)
{
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$currency = Currency::where('code', $invoice->currency_code)->first();
$payment_methods = Modules::getPaymentMethods();
$paid = $this->getPaidAmount($invoice);
// Get Invoice Totals
foreach ($invoice->totals as $invoice_total) {
$invoice->{$invoice_total->code} = $invoice_total->amount;
}
$total = money($invoice->total, $currency->code, true)->format();
//$total = money(0, $currency->code, true)->format();
$invoice->grand_total = money($total, $currency->code)->getAmount();
if (!empty($paid)) {
$invoice->grand_total = round($invoice->total - $paid, $currency->precision) ;
}
$rand = rand();
$html = view('modals.invoices.payment', compact('invoice', 'accounts', 'currencies', 'currency', 'payment_methods', 'rand'))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
/**
* Store a newly created resource in storage.
*
* @param Invoice $invoice
* @param Request $request
*
* @return Response
*/
public function store(Invoice $invoice, Request $request)
{
try {
event(new PaymentReceived($invoice, $request));
$message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]);
flash($message)->success();
$response = [
'success' => true,
'error' => false,
'message' => $message,
'redirect' => route('invoices.show', $invoice->id),
];
} catch(\Exception $e) {
$message = $e->getMessage();
//flash($message)->error();
$response = [
'success' => false,
'error' => true,
'message' => $message,
'redirect' => null,
];
}
return response()->json($response);
}
protected function getPaidAmount($invoice)
{
$paid = 0;
// Get Invoice Payments
if (!$invoice->payments->count()) {
return $paid;
}
$_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 Transaction();
$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_model = new Transaction();
$convert_amount_model->default_currency_code = $item->currency_code;
$convert_amount_model->amount = $default_amount;
$convert_amount_model->currency_code = $invoice->currency_code;
$convert_amount_model->currency_rate = $_currencies[$invoice->currency_code];
$amount = (double) $convert_amount_model->getAmountConvertedFromCustomDefault();
}
$paid += $amount;
}
return $paid;
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Modals;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Tax as Request;
use App\Models\Setting\Tax;

View File

@ -2,24 +2,13 @@
namespace App\Http\Controllers\Modals;
use App\Http\Controllers\Controller;
use App\Http\Requests\Expense\Vendor as Request;
use App\Models\Expense\Bill;
use App\Models\Expense\Payment;
use App\Models\Expense\Vendor;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Common\Contact as Request;
use App\Models\Common\Contact;
use App\Models\Setting\Currency;
use App\Traits\Uploads;
use App\Utilities\Import;
use App\Utilities\ImportFile;
use Date;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
class Vendors extends Controller
{
use Uploads;
/**
* Instantiate a new controller instance.
*/
@ -39,17 +28,17 @@ class Vendors extends Controller
*/
public function create()
{
$currencies = Currency::enabled()->pluck('name', 'code');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$vendor_selector = false;
$contact_selector = false;
if (request()->has('vendor_selector')) {
$vendor_selector = request()->get('vendor_selector');
if (request()->has('contact_selector')) {
$contact_selector = request()->get('contact_selector');
}
$rand = rand();
$html = view('modals.vendors.create', compact('currencies', 'vendor_selector', 'rand'))->render();
$html = view('modals.vendors.create', compact('currencies', 'contact_selector', 'rand'))->render();
return response()->json([
'success' => true,
@ -70,21 +59,14 @@ class Vendors extends Controller
{
$request['enabled'] = 1;
$vendor = Vendor::create($request->all());
// Upload logo
if ($request->file('logo')) {
$media = $this->getMedia($request->file('logo'), 'vendors');
$vendor->attachMedia($media, 'logo');
}
$contact = Contact::create($request->all());
$message = trans('messages.success.added', ['type' => trans_choice('general.vendors', 1)]);
return response()->json([
'success' => true,
'error' => false,
'data' => $vendor,
'data' => $contact,
'message' => $message,
'html' => 'null',
]);

View File

@ -2,10 +2,10 @@
namespace App\Http\Controllers\Modules;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Module\Module as Request;
class Token extends Controller
class ApiKey extends Controller
{
/**
@ -15,7 +15,7 @@ class Token extends Controller
*/
public function create()
{
return view('modules.token.create');
return view('modules.api_key.create');
}
/**
@ -27,11 +27,11 @@ class Token extends Controller
*/
public function store(Request $request)
{
// Set Api Token
setting()->set('general.api_token', $request['api_token']);
// Set Api Key
setting()->set('apps.api_key', $request['api_key']);
setting()->save();
return redirect('apps/home');
return redirect()->route('apps.home.index');
}
}

View File

@ -2,10 +2,9 @@
namespace App\Http\Controllers\Modules;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Traits\Modules;
use App\Models\Module\Module;
use Illuminate\Routing\Route;
class Home extends Controller
{
@ -18,8 +17,6 @@ class Home extends Controller
*/
public function index()
{
$this->checkApiToken();
$data = [
'query' => [
'limit' => 4
@ -30,7 +27,7 @@ class Home extends Controller
$paid = $this->getPaidModules($data);
$new = $this->getNewModules($data);
$free = $this->getFreeModules($data);
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.home.index', compact('pre_sale', 'paid', 'new', 'free', 'installed'));
}

View File

@ -2,12 +2,11 @@
namespace App\Http\Controllers\Modules;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Models\Module\Module;
use App\Models\Module\ModuleHistory;
use App\Traits\Modules;
use Artisan;
use Module as LModule;
use Illuminate\Http\Request;
class Item extends Controller
@ -34,8 +33,6 @@ class Item extends Controller
*/
public function show($alias)
{
$this->checkApiToken();
$enable = false;
$installed = false;
@ -48,7 +45,7 @@ class Item extends Controller
if ($this->moduleExists($alias) && ($model = Module::alias($alias)->first())) {
$installed = true;
if ($model->status) {
if ($model->enabled) {
$enable = true;
}
}
@ -81,8 +78,6 @@ class Item extends Controller
*/
public function steps(Request $request)
{
$this->checkApiToken();
$json = [];
$json['step'] = [];
@ -119,13 +114,11 @@ class Item extends Controller
*/
public function download(Request $request)
{
$this->checkApiToken();
$path = $request['path'];
$version = $request['version'];
$path .= '/' . $version . '/' . version('short') . '/' . setting('general.api_token');
$path .= '/' . $version . '/' . version('short') . '/' . setting('apps.api_key');
$json = $this->downloadModule($path);
@ -141,8 +134,6 @@ class Item extends Controller
*/
public function unzip(Request $request)
{
$this->checkApiToken();
$path = $request['path'];
$json = $this->unzipModule($path);
@ -159,8 +150,6 @@ class Item extends Controller
*/
public function install(Request $request)
{
$this->checkApiToken();
$path = $request['path'];
$json = $this->installModule($path);
@ -176,8 +165,6 @@ class Item extends Controller
public function uninstall($alias)
{
$this->checkApiToken();
$json = $this->uninstallModule($alias);
$module = Module::alias($alias)->first();
@ -203,8 +190,6 @@ class Item extends Controller
public function update($alias)
{
$this->checkApiToken();
$json = $this->updateModule($alias);
$module = Module::alias($alias)->first();
@ -228,8 +213,6 @@ class Item extends Controller
public function enable($alias)
{
$this->checkApiToken();
$json = $this->enableModule($alias);
$module = Module::alias($alias)->first();
@ -242,7 +225,7 @@ class Item extends Controller
'description' => trans('modules.enabled', ['module' => $json['data']['name']]),
];
$module->status = 1;
$module->enabled = 1;
$module->save();
@ -257,8 +240,6 @@ class Item extends Controller
public function disable($alias)
{
$this->checkApiToken();
$json = $this->disableModule($alias);
$module = Module::alias($alias)->first();
@ -271,7 +252,7 @@ class Item extends Controller
'description' => trans('modules.disabled', ['module' => $json['data']['name']]),
];
$module->status = 0;
$module->enabled = 0;
$module->save();
@ -294,9 +275,9 @@ class Item extends Controller
{
Artisan::call('module:install', ['alias' => $alias, 'company_id' => session('company_id')]);
$module = LModule::findByAlias($alias);
$module = module($alias);
$message = trans('modules.installed', ['module' => $module->get('name')]);
$message = trans('modules.installed', ['module' => $module->getName()]);
flash($message)->success();
@ -328,8 +309,6 @@ class Item extends Controller
public function documentation($alias)
{
$this->checkApiToken();
$documentation = $this->getDocumentation($alias);
if (empty($documentation)) {

View File

@ -2,10 +2,9 @@
namespace App\Http\Controllers\Modules;
use App\Http\Controllers\Controller;
use App\Traits\Modules;
use App\Abstracts\Http\Controller;
use App\Models\Module\Module;
use Illuminate\Routing\Route;
use App\Traits\Modules;
class My extends Controller
{
@ -18,11 +17,9 @@ class My extends Controller
*/
public function index()
{
$this->checkApiToken();
$purchased = $this->getMyModules();
$modules = $this->getInstalledModules();
$installed = Module::where('company_id', '=', session('company_id'))->pluck('status', 'alias')->toArray();
$installed = Module::where('company_id', '=', session('company_id'))->pluck('enabled', 'alias')->toArray();
return view('modules.my.index', compact('purchased', 'modules', 'installed'));
}

View File

@ -2,10 +2,9 @@
namespace App\Http\Controllers\Modules;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Traits\Modules;
use App\Models\Module\Module;
use Illuminate\Routing\Route;
use Illuminate\Http\Request;
class Tiles extends Controller
@ -21,8 +20,6 @@ class Tiles extends Controller
*/
public function categoryModules($alias)
{
$this->checkApiToken();
$page = request('page', 1);
$request = [
@ -35,7 +32,7 @@ class Tiles extends Controller
$title = $data->category->name;
$modules = $data->modules;
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
}
@ -49,8 +46,6 @@ class Tiles extends Controller
*/
public function vendorModules($alias)
{
$this->checkApiToken();
$page = request('page', 1);
$request = [
@ -63,7 +58,7 @@ class Tiles extends Controller
$title = $data->vendor->name;
$modules = $data->modules;
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
}
@ -75,8 +70,6 @@ class Tiles extends Controller
*/
public function paidModules()
{
$this->checkApiToken();
$page = request('page', 1);
$data = [
@ -87,7 +80,7 @@ class Tiles extends Controller
$title = trans('modules.top_paid');
$modules = $this->getPaidModules($data);
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
}
@ -99,8 +92,6 @@ class Tiles extends Controller
*/
public function newModules()
{
$this->checkApiToken();
$page = request('page', 1);
$data = [
@ -111,7 +102,7 @@ class Tiles extends Controller
$title = trans('modules.new');
$modules = $this->getNewModules($data);
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
}
@ -123,8 +114,6 @@ class Tiles extends Controller
*/
public function freeModules()
{
$this->checkApiToken();
$page = request('page', 1);
$data = [
@ -135,7 +124,7 @@ class Tiles extends Controller
$title = trans('modules.top_free');
$modules = $this->getFreeModules($data);
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.tiles.index', compact('title', 'modules', 'installed'));
}
@ -147,8 +136,6 @@ class Tiles extends Controller
*/
public function searchModules(Request $request)
{
$this->checkApiToken();
$keyword = $request['keyword'];
$page = request('page', 1);
@ -161,7 +148,7 @@ class Tiles extends Controller
$title = trans('modules.search');
$modules = $this->getSearchModules($data);
$installed = Module::all()->pluck('status', 'alias')->toArray();
$installed = Module::all()->pluck('enabled', 'alias')->toArray();
return view('modules.tiles.index', compact('title', 'modules', 'keyword', 'installed'));
}

View File

@ -0,0 +1,209 @@
<?php
namespace App\Http\Controllers\Portal;
use App\Abstracts\Http\Controller;
use App\Models\Income\Invoice;
use App\Utilities\Chartjs;
use Date;
class Dashboard extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$contact = user()->contact;
$invoices = Invoice::with('status')->accrued()->where('contact_id', $contact->id)->get();
$start = Date::parse(request('start', Date::today()->startOfYear()->format('Y-m-d')));
$end = Date::parse(request('end', Date::today()->endOfYear()->format('Y-m-d')));
$start_month = $start->month;
$end_month = $end->month;
// Monthly
$labels = [];
$s = clone $start;
for ($j = $end_month; $j >= $start_month; $j--) {
$labels[$end_month - $j] = $s->format('M Y');
$s->addMonth();
}
$unpaid = $paid = $overdue = $partial_paid = [];
foreach ($invoices as $invoice) {
switch ($invoice->invoice_status_code) {
case 'paid':
$paid[] = $invoice;
break;
case 'partial':
$partial_paid[] = $invoice;
break;
case 'sent':
default:
if (Date::today()->format('Y-m-d') > $invoice->due_at->format('Y-m-d')) {
$overdue[] = $invoice;
} else {
$unpaid[] = $invoice;
}
}
}
$total = count($unpaid) + count($paid) + count($partial_paid) + count($overdue);
$progress = [
'unpaid' => count($unpaid),
'paid' => count($paid),
'overdue' => count($overdue),
'partially_paid' => count($partial_paid),
'total' => $total,
];
$unpaid = $this->calculateTotals($unpaid, $start, $end, 'unpaid');
$paid = $this->calculateTotals($paid, $start, $end, 'paid');
$partial_paid = $this->calculateTotals($partial_paid, $start, $end, 'partial');
$overdue = $this->calculateTotals($overdue, $start, $end, 'overdue');
$options = [
'tooltips' => [
'backgroundColor' => '#f5f5f5',
'titleFontColor' => '#333',
'bodyFontColor' => '#666',
'bodySpacing' => 4,
'YrPadding' => 12,
'mode' => 'nearest',
'intersect' => 0,
'position' => 'nearest'
],
'responsive' => true,
'scales' => [
'yAxes' => [
[
'barPercentage' => 1.6,
'gridLines' => [
'drawBorder' => false,
'color' => 'rgba(29,140,248,0.1)',
'zeroLineColor' => 'transparent',
'borderDash' => [2],
'borderDashOffset' => [2],
],
'ticks' => [
'padding' => 10,
'fontColor' => '#9e9e9e'
]
]
],
'xAxes' => [
[
'barPercentage' => 1.6,
'gridLines' => [
'drawBorder' => false,
'color' => 'rgba(29,140,248,0.0)',
'zeroLineColor' => 'transparent'
],
'ticks' => [
'suggestedMin' => 60,
'suggestedMax' => 125,
'padding' => 20,
'fontColor' => '#9e9e9e'
]
]
]
]
];
$chart = new Chartjs();
$chart->type('line')
->width(0)
->height(300)
->options($options)
->labels($labels);
$chart->dataset(trans('general.unpaid'), 'line', array_values($unpaid))
->backgroundColor('#ef3232')
->color('#ef3232')
->options([
'borderWidth' => 4,
'pointStyle' => 'line',
])
->fill(false);
$chart->dataset(trans('general.paid'), 'line', array_values($paid))
->backgroundColor('#6da252')
->color('#6da252')
->options([
'borderWidth' => 4,
'pointStyle' => 'line',
])
->fill(false);
$chart->dataset(trans('general.overdue'), 'line', array_values($overdue))
->backgroundColor('#efad32')
->color('#efad32')
->options([
'borderWidth' => 4,
'pointStyle' => 'line',
])
->fill(false);
$chart->dataset(trans('general.partially_paid'), 'line', array_values($partial_paid))
->backgroundColor('#328aef')
->color('#328aef')
->options([
'borderWidth' => 4,
'pointStyle' => 'line',
])
->fill(false);
return view('portal.dashboard.index', compact('contact', 'invoices', 'progress', 'chart'));
}
private function calculateTotals($items, $start, $end, $type)
{
$totals = [];
$date_format = 'Y-m';
$n = 1;
$start_date = $start->format($date_format);
$end_date = $end->format($date_format);
$next_date = $start_date;
$s = clone $start;
while ($next_date <= $end_date) {
$totals[$next_date] = 0;
$next_date = $s->addMonths($n)->format($date_format);
}
$this->setTotals($totals, $items, $date_format, $type);
return $totals;
}
private function setTotals(&$totals, $items, $date_format, $type)
{
foreach ($items as $item) {
if ($type == 'partial') {
$item->amount = $item->payments()->paid();
}
$i = Date::parse($item->paid_at)->format($date_format);
$totals[$i] += $item->getAmountConvertedToDefault();
}
}
}

View File

@ -1,25 +1,19 @@
<?php
namespace App\Http\Controllers\Customers;
namespace App\Http\Controllers\Portal;
use App\Http\Controllers\Controller;
use App\Events\InvoicePrinting;
use App\Abstracts\Http\Controller;
use App\Models\Banking\Account;
use App\Models\Income\Customer;
use App\Models\Common\Contact;
use App\Models\Income\Invoice;
use App\Models\Income\InvoiceStatus;
use App\Models\Setting\Category;
use App\Models\Setting\Currency;
use App\Models\Common\Media;
use App\Traits\Currencies;
use App\Traits\DateTime;
use App\Traits\Uploads;
use App\Utilities\Modules;
use File;
use Illuminate\Http\Request;
use Image;
use Storage;
use SignedUrl;
use Illuminate\Support\Facades\URL;
class Invoices extends Controller
{
@ -32,18 +26,18 @@ class Invoices extends Controller
*/
public function index()
{
$invoices = Invoice::with(['customer', 'status', 'items', 'payments', 'histories'])
->accrued()->where('customer_id', auth()->user()->customer->id)
$invoices = Invoice::with(['contact', 'status', 'items', 'payments', 'histories'])
->accrued()->where('contact_id', user()->contact->id)
->collect(['invoice_number'=> 'desc']);
$categories = collect(Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id'));
$categories = collect(Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id'));
$statuses = collect(InvoiceStatus::get()->each(function ($item) {
$item->name = trans('invoices.status.' . $item->code);
return $item;
})->pluck('name', 'code'));
return view('customers.invoices.index', compact('invoices', 'categories', 'statuses'));
return view('portal.invoices.index', compact('invoices', 'categories', 'statuses'));
}
/**
@ -59,15 +53,17 @@ class Invoices extends Controller
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code')->toArray();
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$customers = Customer::enabled()->orderBy('name')->pluck('name', 'id');
$customers = Contact::type('customer')->enabled()->orderBy('name')->pluck('name', 'id');
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->orderBy('name')->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
return view('customers.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods'));
event(new \App\Events\Income\InvoiceViewed($invoice));
return view('portal.invoices.show', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods'));
}
/**
@ -120,7 +116,7 @@ class Invoices extends Controller
if ($invoice->currency_code != $item->currency_code) {
$item->default_currency_code = $invoice->currency_code;
$amount = $item->getDynamicConvertedAmount();
$amount = $item->getAmountConvertedFromCustomDefault();
}
$paid += $amount;
@ -130,12 +126,12 @@ class Invoices extends Controller
$invoice->template_path = 'incomes.invoices.invoice';
event(new InvoicePrinting($invoice));
event(new \App\Events\Income\InvoicePrinting($invoice));
return $invoice;
}
public function link(Invoice $invoice, Request $request)
public function signed(Invoice $invoice)
{
if (empty($invoice)) {
redirect()->route('login');
@ -149,7 +145,7 @@ class Invoices extends Controller
if ($invoice->currency_code != $item->currency_code) {
$item->default_currency_code = $invoice->currency_code;
$amount = $item->getDynamicConvertedAmount();
$amount = $item->getAmountConvertedFromCustomDefault();
}
$paid += $amount;
@ -161,11 +157,11 @@ class Invoices extends Controller
$currencies = Currency::enabled()->pluck('name', 'code')->toArray();
$account_currency_code = Account::where('id', setting('general.default_account'))->pluck('currency_code')->first();
$account_currency_code = Account::where('id', setting('default.account'))->pluck('currency_code')->first();
$customers = Customer::enabled()->pluck('name', 'id');
$customers = Contact::type('customer')->enabled()->pluck('name', 'id');
$categories = Category::enabled()->type('income')->pluck('name', 'id');
$categories = Category::type('income')->enabled()->pluck('name', 'id');
$payment_methods = Modules::getPaymentMethods();
@ -175,13 +171,15 @@ class Invoices extends Controller
$codes = explode('.', $payment_method_key);
if (!isset($payment_actions[$codes[0]])) {
$payment_actions[$codes[0]] = SignedUrl::sign(url('signed/invoices/' . $invoice->id . '/' . $codes[0]), 1);
$payment_actions[$codes[0]] = URL::signedRoute('signed.invoices.' . $codes[0] . '.show', [$invoice->id, 'company_id' => session('company_id')]);
}
}
$print_action = SignedUrl::sign(route('signed.invoices.print', $invoice->id), 1);
$pdf_action = SignedUrl::sign(route('signed.invoices.pdf', $invoice->id), 1);
$print_action = URL::signedRoute('signed.invoices.print', [$invoice->id, 'company_id' => session('company_id')]);
$pdf_action = URL::signedRoute('signed.invoices.pdf', [$invoice->id, 'company_id' => session('company_id')]);
return view('customers.invoices.link', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'payment_actions', 'print_action', 'pdf_action'));
event(new \App\Events\Income\InvoiceViewed($invoice));
return view('portal.invoices.signed', compact('invoice', 'accounts', 'currencies', 'account_currency_code', 'customers', 'categories', 'payment_methods', 'payment_actions', 'print_action', 'pdf_action'));
}
}

View File

@ -1,16 +1,13 @@
<?php
namespace App\Http\Controllers\Customers;
namespace App\Http\Controllers\portal;
use App\Http\Controllers\Controller;
use App\Models\Income\Revenue as Payment;
use App\Models\Setting\Category;
use App\Abstracts\Http\Controller;
use App\Models\Banking\Account;
use App\Models\Banking\Transaction;
use App\Models\Setting\Category;
use App\Utilities\Modules;
use Auth;
class Payments extends Controller
{
@ -21,30 +18,30 @@ class Payments extends Controller
*/
public function index()
{
$payments = Payment::with(['account', 'category'])->where('customer_id', '=', Auth::user()->customer->id)->paginate();
$payments = Transaction::type('income')->with(['account', 'category'])->where('contact_id', '=', user()->contact->id)->paginate();
$payment_methods = Modules::getPaymentMethods('all');
$categories = collect(Category::enabled()->type('income')->pluck('name', 'id'))
$categories = collect(Category::type('income')->enabled()->pluck('name', 'id'))
->prepend(trans('general.all_type', ['type' => trans_choice('general.categories', 2)]), '');
$accounts = collect(Account::enabled()->pluck('name', 'id'))
->prepend(trans('general.all_type', ['type' => trans_choice('general.accounts', 2)]), '');
return view('customers.payments.index', compact('payments', 'payment_methods', 'categories', 'accounts'));
return view('portal.payments.index', compact('payments', 'payment_methods', 'categories', 'accounts'));
}
/**
* Show the form for viewing the specified resource.
*
* @param Payment $payment
* @param Transaction $payment
*
* @return Response
*/
public function show(Payment $payment)
public function show(Transaction $payment)
{
$payment_methods = Modules::getPaymentMethods();
$payment_methods = Modules::getPaymentMethods('all');
return view('customers.payments.show', compact('payment', 'payment_methods'));
return view('portal.payments.show', compact('payment', 'payment_methods'));
}
}

View File

@ -1,9 +1,9 @@
<?php
namespace App\Http\Controllers\Customers;
namespace App\Http\Controllers\Portal;
use App\Http\Controllers\Controller;
use App\Http\Requests\Customer\Profile as Request;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Portal\Profile as Request;
use App\Models\Auth\User;
use App\Traits\Uploads;
@ -28,9 +28,9 @@ class Profile extends Controller
*/
public function edit()
{
$user = auth()->user();
$user = user();
return view('customers.profile.edit', compact('user'));
return view('portal.profile.edit', compact('user'));
}
/**
@ -42,7 +42,7 @@ class Profile extends Controller
*/
public function update(Request $request)
{
$user = auth()->user();
$user = user();
// Do not reset password if not entered/changed
if (empty($request['password'])) {
@ -67,7 +67,7 @@ class Profile extends Controller
flash($message)->success();
return redirect('customers/profile/edit');
return redirect()->route('portal.profile.edit');
}
/**
@ -77,7 +77,7 @@ class Profile extends Controller
*/
public function readOverdueInvoices()
{
$user = auth()->user();
$user = user();
// Mark invoice notifications as read
foreach ($user->unreadNotifications as $notification) {
@ -90,6 +90,6 @@ class Profile extends Controller
}
// Redirect to invoices
return redirect('customers/invoices');
return redirect()->route('portal.invoices.index');
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers\Portal;
use App\Abstracts\Http\Controller;
use App\Models\Banking\Transaction;
use Auth;
class Transactions extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$transactions = Transaction::type('income')->where('contact_id', user()->contact->id)->get();
return view('portal.transactions.index', compact('transactions'));
}
}

View File

@ -1,228 +0,0 @@
<?php
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 App\Traits\DateTime;
use Charts;
use Date;
class ExpenseSummary extends Controller
{
use DateTime;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$dates = $totals = $expenses = $expenses_graph = $categories = [];
$status = request('status');
$year = request('year', Date::now()->year);
// check and assign year start
$financial_start = $this->getFinancialStart();
if ($financial_start->month != 1) {
// check if a specific year is requested
if (!is_null(request('year'))) {
$financial_start->year = $year;
}
$year = [$financial_start->format('Y'), $financial_start->addYear()->format('Y')];
$financial_start->subYear()->subMonth();
}
$categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id')->toArray();
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
for ($j = 1; $j <= 12; $j++) {
$ym_string = is_array($year) ? $financial_start->addMonth()->format('Y-m') : $year . '-' . $j;
$dates[$j] = Date::parse($ym_string)->format('F');
$expenses_graph[Date::parse($ym_string)->format('F-Y')] = 0;
// Totals
$totals[$dates[$j]] = array(
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
foreach ($cats as $category_id => $category_name) {
$expenses[$category_id][$dates[$j]] = array(
'category_id' => $category_id,
'name' => $category_name,
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
}
}
$payments = Payment::monthsOfYear('paid_at')->account(request('accounts'))->vendor(request('vendors'))->isNotTransfer()->get();
switch ($status) {
case 'paid':
// 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
$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
$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;
}
$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')) {
$chart_template = 'vendor.consoletvs.charts.chartjs.multi.line_print';
$view_template = 'reports.expense_summary.print';
} else {
$chart_template = 'vendor.consoletvs.charts.chartjs.multi.line';
$view_template = 'reports.expense_summary.index';
}
$print_url = $this->getPrintUrl(is_array($year) ? $year[0] : $year);
// Expenses chart
$chart = Charts::multi('line', 'chartjs')
->dimensions(0, 300)
->colors(['#F56954'])
->dataset(trans_choice('general.expenses', 1), $expenses_graph)
->labels($dates)
->credits(false)
->view($chart_template);
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->getTable() == 'bill_payments') {
$bill = $item->bill;
if ($vendors = request('vendors')) {
if (!in_array($bill->vendor_id, $vendors)) {
continue;
}
}
$item->category_id = $bill->category_id;
}
if ($item->getTable() == 'bills') {
if ($accounts = request('accounts')) {
foreach ($item->payments as $payment) {
if (!in_array($payment->account_id, $accounts)) {
continue 2;
}
}
}
}
$month = Date::parse($item->$date_field)->format('F');
$month_year = Date::parse($item->$date_field)->format('F-Y');
if (!isset($expenses[$item->category_id]) || !isset($expenses[$item->category_id][$month]) || !isset($graph[$month_year])) {
continue;
}
$amount = $item->getConvertedAmount();
// Forecasting
if (($type == 'bill') && ($date_field == 'due_at')) {
foreach ($item->payments as $payment) {
$amount -= $payment->getConvertedAmount();
}
}
$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[$month_year] += $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;
}
}

View File

@ -1,303 +0,0 @@
<?php
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 App\Traits\DateTime;
use Charts;
use Date;
class IncomeExpenseSummary extends Controller
{
use DateTime;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$dates = $totals = $compares = $profit_graph = $categories = [];
$status = request('status');
$year = request('year', Date::now()->year);
// check and assign year start
$financial_start = $this->getFinancialStart();
if ($financial_start->month != 1) {
// check if a specific year is requested
if (!is_null(request('year'))) {
$financial_start->year = $year;
}
$year = [$financial_start->format('Y'), $financial_start->addYear()->format('Y')];
$financial_start->subYear()->subMonth();
}
$categories_filter = request('categories');
$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')->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++) {
$ym_string = is_array($year) ? $financial_start->addMonth()->format('Y-m') : $year . '-' . $j;
$dates[$j] = Date::parse($ym_string)->format('F');
$profit_graph[Date::parse($ym_string)->format('F-Y')] = 0;
// Totals
$totals[$dates[$j]] = array(
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
foreach ($income_categories as $category_id => $category_name) {
$compares['income'][$category_id][$dates[$j]] = array(
'category_id' => $category_id,
'name' => $category_name,
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
}
foreach ($expense_categories as $category_id => $category_name) {
$compares['expense'][$category_id][$dates[$j]] = array(
'category_id' => $category_id,
'name' => $category_name,
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
}
}
$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
$invoices = InvoicePayment::monthsOfYear('paid_at')->account(request('accounts'))->get();
$this->setAmount($profit_graph, $totals, $compares, $invoices, 'invoice', 'paid_at');
// Revenues
$this->setAmount($profit_graph, $totals, $compares, $revenues, 'revenue', 'paid_at');
// 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':
// 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:
// 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;
}
$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')) {
$chart_template = 'vendor.consoletvs.charts.chartjs.multi.line_print';
$view_template = 'reports.income_expense_summary.print';
} else {
$chart_template = 'vendor.consoletvs.charts.chartjs.multi.line';
$view_template = 'reports.income_expense_summary.index';
}
$print_url = $this->getPrintUrl(is_array($year) ? $year[0] : $year);
// Profit chart
$chart = Charts::multi('line', 'chartjs')
->dimensions(0, 300)
->colors(['#6da252'])
->dataset(trans_choice('general.profits', 1), $profit_graph)
->labels($dates)
->credits(false)
->view($chart_template);
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->getTable() == 'bill_payments') || ($item->getTable() == 'invoice_payments')) {
$type_item = $item->$type;
$item->category_id = $type_item->category_id;
}
if ($item->getTable() == 'invoice_payments') {
$invoice = $item->invoice;
if ($customers = request('customers')) {
if (!in_array($invoice->customer_id, $customers)) {
continue;
}
}
$item->category_id = $invoice->category_id;
}
if ($item->getTable() == 'bill_payments') {
$bill = $item->bill;
if ($vendors = request('vendors')) {
if (!in_array($bill->vendor_id, $vendors)) {
continue;
}
}
$item->category_id = $bill->category_id;
}
if (($item->getTable() == 'invoices') || ($item->getTable() == 'bills')) {
if ($accounts = request('accounts')) {
foreach ($item->payments as $payment) {
if (!in_array($payment->account_id, $accounts)) {
continue 2;
}
}
}
}
$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]) || !isset($compares[$group][$item->category_id][$month]) || !isset($graph[$month_year])) {
continue;
}
$amount = $item->getConvertedAmount();
// Forecasting
if ((($type == 'invoice') || ($type == 'bill')) && ($date_field == 'due_at')) {
foreach ($item->payments as $payment) {
$amount -= $payment->getConvertedAmount();
}
}
$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[$month_year] += $amount;
$totals[$month]['amount'] += $amount;
} else {
$graph[$month_year] -= $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;
}
}

View File

@ -1,228 +0,0 @@
<?php
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 App\Traits\DateTime;
use Charts;
use Date;
class IncomeSummary extends Controller
{
use DateTime;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$dates = $totals = $incomes = $incomes_graph = $categories = [];
$status = request('status');
$year = request('year', Date::now()->year);
// check and assign year start
$financial_start = $this->getFinancialStart();
if ($financial_start->month != 1) {
// check if a specific year is requested
if (!is_null(request('year'))) {
$financial_start->year = $year;
}
$year = [$financial_start->format('Y'), $financial_start->addYear()->format('Y')];
$financial_start->subYear()->subMonth();
}
$categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id')->toArray();
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
for ($j = 1; $j <= 12; $j++) {
$ym_string = is_array($year) ? $financial_start->addMonth()->format('Y-m') : $year . '-' . $j;
$dates[$j] = Date::parse($ym_string)->format('F');
$incomes_graph[Date::parse($ym_string)->format('F-Y')] = 0;
// Totals
$totals[$dates[$j]] = array(
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
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
];
}
}
$revenues = Revenue::monthsOfYear('paid_at')->account(request('accounts'))->customer(request('customers'))->isNotTransfer()->get();
switch ($status) {
case 'paid':
// 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
$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
$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;
}
$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')) {
$chart_template = 'vendor.consoletvs.charts.chartjs.multi.line_print';
$view_template = 'reports.income_summary.print';
} else {
$chart_template = 'vendor.consoletvs.charts.chartjs.multi.line';
$view_template = 'reports.income_summary.index';
}
$print_url = $this->getPrintUrl(is_array($year) ? $year[0] : $year);
// Incomes chart
$chart = Charts::multi('line', 'chartjs')
->dimensions(0, 300)
->colors(['#00c0ef'])
->dataset(trans_choice('general.incomes', 1), $incomes_graph)
->labels($dates)
->credits(false)
->view($chart_template);
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->getTable() == 'invoice_payments') {
$invoice = $item->invoice;
if ($customers = request('customers')) {
if (!in_array($invoice->customer_id, $customers)) {
continue;
}
}
$item->category_id = $invoice->category_id;
}
if ($item->getTable() == 'invoices') {
if ($accounts = request('accounts')) {
foreach ($item->payments as $payment) {
if (!in_array($payment->account_id, $accounts)) {
continue 2;
}
}
}
}
$month = Date::parse($item->$date_field)->format('F');
$month_year = Date::parse($item->$date_field)->format('F-Y');
if (!isset($incomes[$item->category_id]) || !isset($incomes[$item->category_id][$month]) || !isset($graph[$month_year])) {
continue;
}
$amount = $item->getConvertedAmount();
// Forecasting
if (($type == 'invoice') && ($date_field == 'due_at')) {
foreach ($item->payments as $payment) {
$amount -= $payment->getConvertedAmount();
}
}
$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[$month_year] += $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;
}
}

View File

@ -1,220 +0,0 @@
<?php
namespace App\Http\Controllers\Reports;
use App\Http\Controllers\Controller;
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\Setting\Category;
use App\Traits\DateTime;
use Charts;
use Date;
class ProfitLoss extends Controller
{
use DateTime;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$dates = $totals = $compares = $categories = [];
$status = request('status');
$year = request('year', Date::now()->year);
// check and assign year start
$financial_start = $this->getFinancialStart();
if ($financial_start->month != 1) {
// check if a specific year is requested
if (!is_null(request('year'))) {
$financial_start->year = $year;
}
$year = [$financial_start->format('Y'), $financial_start->addYear()->format('Y')];
$financial_start->subYear()->subQuarter();
}
$income_categories = Category::enabled()->type('income')->orderBy('name')->pluck('name', 'id')->toArray();
$expense_categories = Category::enabled()->type('expense')->orderBy('name')->pluck('name', 'id')->toArray();
// Dates
for ($j = 1; $j <= 12; $j++) {
$ym_string = is_array($year) ? $financial_start->addQuarter()->format('Y-m') : $year . '-' . $j;
$dates[$j] = Date::parse($ym_string)->quarter;
// Totals
$totals[$dates[$j]] = array(
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
);
foreach ($income_categories as $category_id => $category_name) {
$compares['income'][$category_id][$dates[$j]] = [
'category_id' => $category_id,
'name' => $category_name,
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
];
}
foreach ($expense_categories as $category_id => $category_name) {
$compares['expense'][$category_id][$dates[$j]] = [
'category_id' => $category_id,
'name' => $category_name,
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
];
}
$j += 2;
}
$totals['total'] = [
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
];
foreach ($dates as $date) {
$gross['income'][$date] = 0;
$gross['expense'][$date] = 0;
}
$gross['income']['total'] = 0;
$gross['expense']['total'] = 0;
foreach ($income_categories as $category_id => $category_name) {
$compares['income'][$category_id]['total'] = [
'category_id' => $category_id,
'name' => trans_choice('general.totals', 1),
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
];
}
foreach ($expense_categories as $category_id => $category_name) {
$compares['expense'][$category_id]['total'] = [
'category_id' => $category_id,
'name' => trans_choice('general.totals', 1),
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1
];
}
// Invoices
switch ($status) {
case 'paid':
$invoices = InvoicePayment::monthsOfYear('paid_at')->get();
$this->setAmount($totals, $compares, $invoices, 'invoice', 'paid_at');
break;
case 'upcoming':
$invoices = Invoice::accrued()->monthsOfYear('due_at')->get();
$this->setAmount($totals, $compares, $invoices, 'invoice', 'due_at');
break;
default:
$invoices = Invoice::accrued()->monthsOfYear('invoiced_at')->get();
$this->setAmount($totals, $compares, $invoices, 'invoice', 'invoiced_at');
break;
}
// Revenues
if ($status != 'upcoming') {
$revenues = Revenue::monthsOfYear('paid_at')->isNotTransfer()->get();
$this->setAmount($totals, $compares, $revenues, 'revenue', 'paid_at');
}
// Bills
switch ($status) {
case 'paid':
$bills = BillPayment::monthsOfYear('paid_at')->get();
$this->setAmount($totals, $compares, $bills, 'bill', 'paid_at');
break;
case 'upcoming':
$bills = Bill::accrued()->monthsOfYear('due_at')->get();
$this->setAmount($totals, $compares, $bills, 'bill', 'due_at');
break;
default:
$bills = Bill::accrued()->monthsOfYear('billed_at')->get();
$this->setAmount($totals, $compares, $bills, 'bill', 'billed_at');
break;
}
// Payments
if ($status != 'upcoming') {
$payments = Payment::monthsOfYear('paid_at')->isNotTransfer()->get();
$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';
} else {
$view_template = 'reports.profit_loss.index';
}
return view($view_template, compact('dates', 'income_categories', 'expense_categories', 'compares', 'totals', 'gross', 'statuses'));
}
private function setAmount(&$totals, &$compares, $items, $type, $date_field)
{
foreach ($items as $item) {
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)->quarter;
$group = (($type == 'invoice') || ($type == 'revenue')) ? 'income' : 'expense';
if (!isset($compares[$group][$item->category_id])) {
continue;
}
$amount = $item->getConvertedAmount(false, false);
// Forecasting
if ((($type == 'invoice') || ($type == 'bill')) && ($date_field == 'due_at')) {
foreach ($item->payments as $payment) {
$amount -= $payment->getConvertedAmount();
}
}
$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]['total']['amount'] += $amount;
if ($group == 'income') {
$totals[$date]['amount'] += $amount;
$totals['total']['amount'] += $amount;
} else {
$totals[$date]['amount'] -= $amount;
$totals['total']['amount'] -= $amount;
}
}
}
}

View File

@ -1,165 +0,0 @@
<?php
namespace App\Http\Controllers\Reports;
use App\Http\Controllers\Controller;
use App\Models\Expense\Bill;
use App\Models\Expense\BillPayment;
use App\Models\Expense\BillTotal;
use App\Models\Income\Invoice;
use App\Models\Income\InvoicePayment;
use App\Models\Income\InvoiceTotal;
use App\Models\Setting\Tax;
use App\Traits\Currencies;
use App\Traits\DateTime;
use Date;
class TaxSummary extends Controller
{
use Currencies, DateTime;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$dates = $incomes = $expenses = $totals = [];
$status = request('status');
$year = request('year', Date::now()->year);
// check and assign year start
$financial_start = $this->getFinancialStart();
if ($financial_start->month != 1) {
// check if a specific year is requested
if (!is_null(request('year'))) {
$financial_start->year = $year;
}
$year = [$financial_start->format('Y'), $financial_start->addYear()->format('Y')];
$financial_start->subYear()->subMonth();
}
$t = Tax::enabled()->where('rate', '<>', '0')->pluck('name')->toArray();
$taxes = array_combine($t, $t);
// Dates
for ($j = 1; $j <= 12; $j++) {
$ym_string = is_array($year) ? $financial_start->addMonth()->format('Y-m') : $year . '-' . $j;
$dates[$j] = Date::parse($ym_string)->format('M');
foreach ($taxes as $tax_name) {
$incomes[$tax_name][$dates[$j]] = [
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1,
];
$expenses[$tax_name][$dates[$j]] = [
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1,
];
$totals[$tax_name][$dates[$j]] = [
'amount' => 0,
'currency_code' => setting('general.default_currency'),
'currency_rate' => 1,
];
}
}
switch ($status) {
case 'paid':
// Invoices
$invoices = InvoicePayment::with(['invoice', 'invoice.totals'])->monthsOfYear('paid_at')->get();
$this->setAmount($incomes, $totals, $invoices, 'invoice', 'paid_at');
// Bills
$bills = BillPayment::with(['bill', 'bill.totals'])->monthsOfYear('paid_at')->get();
$this->setAmount($expenses, $totals, $bills, 'bill', 'paid_at');
break;
case 'upcoming':
// Invoices
$invoices = Invoice::with(['totals'])->accrued()->monthsOfYear('due_at')->get();
$this->setAmount($incomes, $totals, $invoices, 'invoice', 'due_at');
// Bills
$bills = Bill::with(['totals'])->accrued()->monthsOfYear('due_at')->get();
$this->setAmount($expenses, $totals, $bills, 'bill', 'due_at');
break;
default:
// Invoices
$invoices = Invoice::with(['totals'])->accrued()->monthsOfYear('invoiced_at')->get();
$this->setAmount($incomes, $totals, $invoices, 'invoice', 'invoiced_at');
// Bills
$bills = Bill::with(['totals'])->accrued()->monthsOfYear('billed_at')->get();
$this->setAmount($expenses, $totals, $bills, 'bill', 'billed_at');
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';
} else {
$view_template = 'reports.tax_summary.index';
}
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->getTable() == 'bill_payments') || ($row->getTable() == 'invoice_payments')) {
$type_row = $row->$type;
$row->category_id = $type_row->category_id;
}
$date = Date::parse($row->$date_field)->format('M');
if ($date_field == 'paid_at') {
$row_totals = $row->$type->totals;
} else {
$row_totals = $row->totals;
}
foreach ($row_totals as $row_total) {
if ($row_total->code != 'tax') {
continue;
}
if (!isset($items[$row_total->name])) {
continue;
}
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;
if ($type == 'invoice') {
$totals[$row_total->name][$date]['amount'] += $amount;
} else {
$totals[$row_total->name][$date]['amount'] -= $amount;
}
}
}
}
}

View File

@ -2,8 +2,11 @@
namespace App\Http\Controllers\Settings;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Category as Request;
use App\Jobs\Setting\CreateCategory;
use App\Jobs\Setting\DeleteCategory;
use App\Jobs\Setting\UpdateCategory;
use App\Models\Setting\Category;
class Categories extends Controller
@ -37,7 +40,7 @@ class Categories extends Controller
*/
public function show()
{
return redirect('settings/categories');
return redirect()->route('categories.index');
}
/**
@ -66,13 +69,23 @@ class Categories extends Controller
*/
public function store(Request $request)
{
Category::create($request->all());
$response = $this->ajaxDispatch(new CreateCategory($request));
$message = trans('messages.success.added', ['type' => trans_choice('general.categories', 1)]);
if ($response['success']) {
$response['redirect'] = route('categories.index');
flash($message)->success();
$message = trans('messages.success.added', ['type' => trans_choice('general.categories', 1)]);
return redirect('settings/categories');
flash($message)->success();
} else {
$response['redirect'] = route('categories.create');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
@ -99,134 +112,97 @@ class Categories extends Controller
/**
* Update the specified resource in storage.
*
* @param Category $category
* @param Request $request
* @param Category $category
* @param Request $request
*
* @return Response
*/
public function update(Category $category, Request $request)
{
$relationships = $this->countRelationships($category, [
'items' => 'items',
'invoices' => 'invoices',
'revenues' => 'revenues',
'bills' => 'bills',
'payments' => 'payments',
]);
$response = $this->ajaxDispatch(new UpdateCategory($category, $request));
if (empty($relationships) || $request['enabled']) {
$category->update($request->all());
if ($response['success']) {
$response['redirect'] = route('categories.index');
$message = trans('messages.success.updated', ['type' => trans_choice('general.categories', 1)]);
$message = trans('messages.success.updated', ['type' => $category->name]);
flash($message)->success();
return redirect('settings/categories');
} else {
$message = trans('messages.warning.disabled', ['name' => $category->name, 'text' => implode(', ', $relationships)]);
$response['redirect'] = route('categories.edit', $category->id);
flash($message)->warning();
$message = $response['message'];
return redirect('settings/categories/' . $category->id . '/edit');
flash($message)->error();
}
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Category $category
* @param Category $category
*
* @return Response
*/
public function enable(Category $category)
{
$category->enabled = 1;
$category->save();
$response = $this->ajaxDispatch(new UpdateCategory($category, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.categories', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $category->name]);
}
flash($message)->success();
return redirect()->route('categories.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Category $category
* @param Category $category
*
* @return Response
*/
public function disable(Category $category)
{
$relationships = $this->countRelationships($category, [
'items' => 'items',
'invoices' => 'invoices',
'revenues' => 'revenues',
'bills' => 'bills',
'payments' => 'payments',
]);
$response = $this->ajaxDispatch(new UpdateCategory($category, request()->merge(['enabled' => 0])));
if (empty($relationships)) {
$category->enabled = 0;
$category->save();
$message = trans('messages.success.disabled', ['type' => trans_choice('general.categories', 1)]);
flash($message)->success();
} else {
$message = trans('messages.warning.disabled', ['name' => $category->name, 'text' => implode(', ', $relationships)]);
flash($message)->warning();
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $category->name]);
}
return redirect()->route('categories.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Category $category
* @param Category $category
*
* @return Response
*/
public function destroy(Category $category)
{
// Can not delete the last category by type
if (Category::where('type', $category->type)->count() == 1) {
$message = trans('messages.error.last_category', ['type' => strtolower(trans_choice('general.' . $category->type . 's', 1))]);
$response = $this->ajaxDispatch(new DeleteCategory($category));
flash($message)->warning();
$response['redirect'] = route('categories.index');
return redirect('settings/categories');
}
$relationships = $this->countRelationships($category, [
'items' => 'items',
'invoices' => 'invoices',
'revenues' => 'revenues',
'bills' => 'bills',
'payments' => 'payments',
]);
if (empty($relationships)) {
$category->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.categories', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $category->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $category->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect('settings/categories');
return response()->json($response);
}
public function category(Request $request)
{
$category = Category::create($request->all());
$category = $this->dispatch(new CreateCategory($request));
return response()->json($category);
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Abstracts\Http\Controller;
use App\Models\Setting\Setting;
class Company extends Controller
{
public function edit()
{
$setting = Setting::all('company')->map(function ($s) {
$s->key = str_replace('company.', '', $s->key);
return $s;
})->pluck('value', 'key');
return view('settings.company.edit', compact(
'setting'
));
}
}

View File

@ -3,9 +3,11 @@
namespace App\Http\Controllers\Settings;
use Akaunting\Money\Currency as MoneyCurrency;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Currency as Request;
use App\Models\Banking\Account;
use App\Jobs\Setting\CreateCurrency;
use App\Jobs\Setting\DeleteCurrency;
use App\Jobs\Setting\UpdateCurrency;
use App\Models\Setting\Currency;
class Currencies extends Controller
@ -29,7 +31,7 @@ class Currencies extends Controller
*/
public function show()
{
return redirect('settings/currencies');
return redirect()->route('currencies.index');
}
/**
@ -66,24 +68,23 @@ class Currencies extends Controller
*/
public function store(Request $request)
{
// Force the rate to be 1 for default currency
if ($request['default_currency']) {
$request['rate'] = '1';
$response = $this->ajaxDispatch(new CreateCurrency($request));
if ($response['success']) {
$response['redirect'] = route('currencies.index');
$message = trans('messages.success.added', ['type' => trans_choice('general.currencies', 1)]);
flash($message)->success();
} else {
$response['redirect'] = route('currencies.create');
$message = $response['message'];
flash($message)->error();
}
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)]);
flash($message)->success();
return redirect('settings/currencies');
return response()->json($response);
}
/**
@ -111,7 +112,7 @@ class Currencies extends Controller
}
// Set default currency
$currency->default_currency = ($currency->code == setting('general.default_currency')) ? 1 : 0;
$currency->default_currency = ($currency->code == setting('default.currency')) ? 1 : 0;
return view('settings.currencies.edit', compact('currency', 'codes'));
}
@ -119,149 +120,92 @@ class Currencies extends Controller
/**
* Update the specified resource in storage.
*
* @param Currency $currency
* @param Request $request
* @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',
]);
$response = $this->ajaxDispatch(new UpdateCurrency($currency, $request));
if ($currency->code == setting('general.default_currency')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
}
if ($response['success']) {
$response['redirect'] = route('currencies.index');
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)]);
$message = trans('messages.success.updated', ['type' => $currency->name]);
flash($message)->success();
return redirect('settings/currencies');
} else {
$message = trans('messages.warning.disable_code', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
$response['redirect'] = route('currencies.edit', $currency->id);
flash($message)->warning();
$message = $response['message'];
return redirect('settings/currencies/' . $currency->id . '/edit');
flash($message)->error();
}
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Currency $currency
* @param Currency $currency
*
* @return Response
*/
public function enable(Currency $currency)
{
$currency->enabled = 1;
$currency->save();
$response = $this->ajaxDispatch(new UpdateCurrency($currency, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.currencies', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $currency->name]);
}
flash($message)->success();
return redirect()->route('currencies.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Currency $currency
* @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',
]);
$response = $this->ajaxDispatch(new UpdateCurrency($currency, request()->merge(['enabled' => 0])));
if ($currency->code == setting('general.default_currency')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $currency->name]);
}
if (empty($relationships)) {
$currency->enabled = 0;
$currency->save();
$message = trans('messages.success.disabled', ['type' => trans_choice('general.currencies', 1)]);
flash($message)->success();
} else {
$message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
flash($message)->warning();
}
return redirect()->route('currencies.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Currency $currency
* @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',
]);
$response = $this->ajaxDispatch(new DeleteCurrency($currency));
if ($currency->code == setting('general.default_currency')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
$response['redirect'] = route('currencies.index');
if (empty($relationships)) {
$currency->delete();
$message = trans('messages.success.deleted', ['type' => trans_choice('general.currencies', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $currency->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect('settings/currencies');
return response()->json($response);
}
public function currency()
@ -270,13 +214,17 @@ class Currencies extends Controller
$code = request('code');
// Get currency object
$currency = Currency::where('code', $code)->first();
if ($code) {
// Get currency object
$currency = Currency::where('code', $code)->first();
// it should be integer for amount mask
$currency->precision = (int) $currency->precision;
// it should be integer for amount mask
$currency->precision = (int) $currency->precision;
return response()->json($currency);
$json = (object) $currency;
}
return response()->json($json);
}
public function config()
@ -287,7 +235,7 @@ class Currencies extends Controller
if ($code) {
$currency = config('money.' . $code);
$currency['rate'] = isset($currency['rate']) ? $currency['rate'] : null;
$currency['symbol_first'] = $currency['symbol_first'] ? 1 : 0;

View File

@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Abstracts\Http\Controller;
use App\Models\Banking\Account;
use App\Models\Setting\Currency;
use App\Models\Setting\Setting;
use App\Models\Setting\Tax;
use App\Utilities\Modules;
class Defaults extends Controller
{
public function edit()
{
$setting = Setting::all('default')->map(function ($s) {
$s->key = str_replace('default.', '', $s->key);
return $s;
})->pluck('value', 'key');
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$payment_methods = Modules::getPaymentMethods();
return view('settings.default.edit', compact(
'setting',
'accounts',
'currencies',
'taxes',
'payment_methods'
));
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Setting as Request;
use App\Models\Common\EmailTemplate;
use App\Models\Setting\Setting;
use Illuminate\Support\Str;
class Email extends Controller
{
public $skip_keys = ['company_id', '_method', '_token', '_prefix'];
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// No need to check for permission in console
if (app()->runningInConsole()) {
return;
}
// Add CRUD permission check
$this->middleware('permission:create-settings-settings')->only(['create', 'store', 'duplicate', 'import']);
$this->middleware('permission:read-settings-email')->only(['index', 'show', 'edit', 'export']);
$this->middleware('permission:update-settings-settings')->only(['update', 'enable', 'disable']);
$this->middleware('permission:delete-settings-settings')->only('destroy');
}
public function edit()
{
$setting = Setting::all('email')->map(function ($s) {
$s->key = str_replace('email.', '', $s->key);
return $s;
})->pluck('value', 'key');
EmailTemplate::all()->each(function ($template) use ($setting) {
$setting->put('template_' . $template->alias . '_subject', $template->subject);
$setting->put('template_' . $template->alias . '_body', $template->body);
$setting->put('template_' . $template->alias . '_params', $template->params);
});
$email_protocols = [
'mail' => trans('settings.email.php'),
'smtp' => trans('settings.email.smtp.name'),
'sendmail' => trans('settings.email.sendmail'),
'log' => trans('settings.email.log'),
];
$invoice_tags = implode(', ', app('App\Notifications\Income\Invoice')->getTags());
$payment_tags = implode(', ', app('App\Notifications\Portal\PaymentReceived')->getTags());
$bill_tags = implode(', ', app('App\Notifications\Expense\Bill')->getTags());
return view('settings.email.edit', compact(
'setting',
'email_protocols',
'invoice_tags',
'payment_tags',
'bill_tags'
));
}
public function update(Request $request)
{
$fields = $request->all();
$prefix = $request->get('_prefix', 'email');
foreach ($fields as $key => $value) {
$real_key = $prefix . '.' . $key;
// Don't process unwanted keys
if (in_array($key, $this->skip_keys)) {
continue;
}
if (Str::startsWith($key, 'template_')) {
$this->updateEmailTemplate($key, $fields);
continue;
}
setting()->set($real_key, $value);
}
// Save all settings
setting()->save();
$message = trans('messages.success.updated', ['type' => trans_choice('general.settings', 2)]);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => route('settings.index'),
];
flash($message)->success();
return response()->json($response);
}
public function updateEmailTemplate($key, &$fields)
{
$alias = str_replace(['template_', '_subject', '_body'], '', $key);
$subject_key = 'template_' . $alias . '_subject';
$body_key = 'template_' . $alias . '_body';
if (empty($fields[$subject_key]) || empty($fields[$body_key])) {
return;
}
$template = EmailTemplate::alias($alias)->first();
$template->update([
'company_id' => $template->company_id,
'alias' => $template->alias,
'subject' => $fields[$subject_key],
'body' => $fields[$body_key],
]);
unset($fields[$subject_key]);
unset($fields[$body_key]);
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Abstracts\Http\Controller;
use App\Models\Setting\Setting;
class Invoice extends Controller
{
public function edit()
{
$setting = Setting::all('invoice')->map(function ($s) {
$s->key = str_replace('invoice.', '', $s->key);
return $s;
})->pluck('value', 'key');
$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'),
];
$payment_terms = [
'0' => trans('settings.invoice.due_receipt'),
'15' => trans('settings.invoice.due_days', ['days' => 15]),
'30' => trans('settings.invoice.due_days', ['days' => 30]),
'45' => trans('settings.invoice.due_days', ['days' => 45]),
'60' => trans('settings.invoice.due_days', ['days' => 60]),
'90' => trans('settings.invoice.due_days', ['days' => 90]),
];
return view('settings.invoice.edit', compact(
'setting',
'item_names',
'price_names',
'quantity_names',
'payment_terms'
));
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Abstracts\Http\Controller;
use App\Models\Setting\Setting;
use App\Traits\DateTime;
class Localisation extends Controller
{
use DateTime;
public function edit()
{
$setting = Setting::all('localisation')->map(function ($s) {
$s->key = str_replace('localisation.', '', $s->key);
return $s;
})->pluck('value', 'key');
$timezones = $this->getTimezones();
$date_formats = [
'd M Y' => '31 Dec 2017',
'd F Y' => '31 December 2017',
'd m Y' => '31 12 2017',
'm d Y' => '12 31 2017',
'Y m d' => '2017 12 31',
];
$date_separators = [
'dash' => trans('settings.localisation.date.dash'),
'slash' => trans('settings.localisation.date.slash'),
'dot' => trans('settings.localisation.date.dot'),
'comma' => trans('settings.localisation.date.comma'),
'space' => trans('settings.localisation.date.space'),
];
$percent_positions = [
'before' => trans('settings.localisation.percent.before'),
'after' => trans('settings.localisation.percent.after'),
];
return view('settings.localisation.edit', compact(
'setting',
'timezones',
'date_formats',
'date_separators',
'percent_positions'
));
}
}

View File

@ -2,10 +2,9 @@
namespace App\Http\Controllers\Settings;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Models\Setting\Setting;
use File;
use Module;
use App\Http\Requests\Setting\Module as Request;
class Modules extends Controller
{
@ -16,13 +15,12 @@ class Modules extends Controller
*/
public function edit($alias)
{
/*$setting = Setting::all($alias)->pluck('value', 'key');*/
$setting = Setting::all($alias)->map(function($s) use($alias) {
$setting = Setting::all($alias)->map(function ($s) use ($alias) {
$s->key = str_replace($alias . '.', '', $s->key);
return $s;
})->pluck('value', 'key');
$module = Module::findByAlias($alias);
$module = module($alias);
return view('settings.modules.edit', compact('setting', 'module'));
}
@ -34,18 +32,11 @@ class Modules extends Controller
*
* @return Response
*/
public function update($alias)
public function update($alias, Request $request)
{
$fields = request()->all();
$skip_keys = ['company_id', '_method', '_token'];
foreach ($fields as $key => $value) {
// Don't process unwanted keys
if (in_array($key, $skip_keys)) {
continue;
}
$fields = $request->except(['company_id', '_method', '_token', 'module_alias']);
foreach ($fields as $key => $value) {
setting()->set($alias . '.' . $key, $value);
}
@ -54,8 +45,17 @@ class Modules extends Controller
$message = trans('messages.success.updated', ['type' => trans_choice('general.settings', 2)]);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => route('settings.index')//('settings/apps/' . $alias),
];
flash($message)->success();
return redirect('settings/apps/' . $alias);
return response()->json($response);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Settings;
use App\Abstracts\Http\Controller;
use App\Models\Setting\Setting;
class Schedule extends Controller
{
public function edit()
{
$setting = Setting::all('schedule')->map(function ($s) {
$s->key = str_replace('schedule.', '', $s->key);
return $s;
})->pluck('value', 'key');
return view('settings.schedule.edit', compact(
'setting'
));
}
}

View File

@ -2,123 +2,68 @@
namespace App\Http\Controllers\Settings;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Setting as Request;
use App\Models\Banking\Account;
use App\Models\Common\Company;
use App\Models\Setting\Currency;
use App\Models\Setting\Setting;
use App\Models\Common\Media;
use App\Models\Setting\Tax;
use App\Models\Module\Module;
use App\Traits\DateTime;
use App\Traits\Uploads;
use App\Utilities\Installer;
use App\Utilities\Modules;
use Date;
use Illuminate\Support\Str;
class Settings extends Controller
{
use DateTime, Uploads;
public $skip_keys = ['company_id', '_method', '_token', '_prefix'];
public $file_keys = ['company.logo', 'invoice.logo'];
/**
* Show the form for editing the specified resource.
*
* @return Response
*/
public function edit()
public function index()
{
$setting = Setting::all()->map(function ($s) {
$s->key = str_replace('general.', '', $s->key);
$modules = new \stdClass();
$modules->settings = [];
return $s;
})->pluck('value', 'key');
// Get enabled modules
$enabled_modules = Module::enabled()->get();
$setting->put('company_logo', Media::find($setting->pull('company_logo')));
$setting->put('invoice_logo', Media::find($setting->pull('invoice_logo')));
foreach ($enabled_modules as $module) {
$m = module($module->alias);
$timezones = $this->getTimezones();
// Check if the module exists and has settings
if (!$m || empty($m->get('settings'))) {
continue;
}
$accounts = Account::enabled()->orderBy('name')->pluck('name', 'id');
$modules->settings[$m->getAlias()] = [
'name' => $m->getName(),
'description' => $m->getDescription(),
'url' => 'settings/' . $m->getAlias(),
'icon' => $m->get('icon', 'fa fa-cog'),
];
}
$currencies = Currency::enabled()->orderBy('name')->pluck('name', 'code');
event(new \App\Events\Module\SettingShowing($modules));
$taxes = Tax::enabled()->orderBy('name')->get()->pluck('title', 'id');
$payment_methods = Modules::getPaymentMethods();
$date_formats = [
'd M Y' => '31 Dec 2017',
'd F Y' => '31 December 2017',
'd m Y' => '31 12 2017',
'm d Y' => '12 31 2017',
'Y m d' => '2017 12 31',
];
$date_separators = [
'dash' => trans('settings.localisation.date.dash'),
'slash' => trans('settings.localisation.date.slash'),
'dot' => trans('settings.localisation.date.dot'),
'comma' => trans('settings.localisation.date.comma'),
'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'),
'sendmail' => trans('settings.email.sendmail'),
'log' => trans('settings.email.log'),
];
$percent_positions = [
'before' => trans('settings.localisation.percent.before'),
'after' => trans('settings.localisation.percent.after'),
];
return view('settings.settings.edit', compact(
'setting',
'timezones',
'accounts',
'currencies',
'taxes',
'payment_methods',
'date_formats',
'date_separators',
'item_names',
'price_names',
'quantity_names',
'email_protocols',
'percent_positions'
));
return view('settings.settings.index', ['modules' => $modules->settings]);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @param Request $request
*
* @return Response
*/
public function update(Request $request)
{
$fields = $request->all();
$prefix = $request->get('_prefix', 'general');
$company_id = $request->get('company_id');
if (empty($company_id)) {
@ -127,24 +72,23 @@ class Settings extends Controller
$company = Company::find($company_id);
$skip_keys = ['company_id', '_method', '_token'];
$file_keys = ['company_logo', 'invoice_logo'];
$companies = Company::all()->count();
foreach ($fields as $key => $value) {
$real_key = $prefix . '.' . $key;
// Don't process unwanted keys
if (in_array($key, $skip_keys)) {
if (in_array($key, $this->skip_keys)) {
continue;
}
// Process file uploads
if (in_array($key, $file_keys)) {
if (in_array($real_key, $this->file_keys)) {
// Upload attachment
if ($request->file($key)) {
$media = $this->getMedia($request->file($key), 'settings');
$company->attachMedia($media, $key);
$company->attachMedia($media, Str::snake($real_key));
$value = $media->id;
}
@ -155,12 +99,16 @@ class Settings extends Controller
}
}
// If only 1 company
if ($companies == 1) {
$this->oneCompany($key, $value);
if ($real_key == 'default.locale') {
user()->setAttribute('locale', $value)->save();
}
setting()->set('general.' . $key, $value);
// If only 1 company
if ($companies == 1) {
$this->oneCompany($real_key, $value);
}
setting()->set($real_key, $value);
}
// Save all settings
@ -168,27 +116,33 @@ class Settings extends Controller
$message = trans('messages.success.updated', ['type' => trans_choice('general.settings', 2)]);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => route('settings.index'),
];
flash($message)->success();
return redirect('settings/settings');
return response()->json($response);
}
protected function oneCompany($key, $value)
protected function oneCompany($real_key, $value)
{
switch ($key) {
case 'company_name':
switch ($real_key) {
case 'company.name':
Installer::updateEnv(['MAIL_FROM_NAME' => '"' . $value . '"']);
break;
case 'company_email':
case 'company.email':
Installer::updateEnv(['MAIL_FROM_ADDRESS' => $value]);
break;
case 'default_locale':
case 'default.locale':
Installer::updateEnv(['APP_LOCALE' => $value]);
break;
case 'session_handler':
Installer::updateEnv(['SESSION_DRIVER' => $value]);
break;
case 'schedule_time':
case 'schedule.time':
Installer::updateEnv(['APP_SCHEDULE_TIME' => '"' . $value . '"']);
break;
}

View File

@ -2,8 +2,11 @@
namespace App\Http\Controllers\Settings;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Tax as Request;
use App\Jobs\Setting\CreateTax;
use App\Jobs\Setting\DeleteTax;
use App\Jobs\Setting\UpdateTax;
use App\Models\Setting\Tax;
class Taxes extends Controller
@ -19,6 +22,7 @@ class Taxes extends Controller
$taxes = Tax::collect();
$types = [
'fixed' => trans('taxes.fixed'),
'normal' => trans('taxes.normal'),
'inclusive' => trans('taxes.inclusive'),
'compound' => trans('taxes.compound'),
@ -34,7 +38,7 @@ class Taxes extends Controller
*/
public function show()
{
return redirect('settings/taxes');
return redirect()->route('taxes.index');
}
/**
@ -45,6 +49,7 @@ class Taxes extends Controller
public function create()
{
$types = [
'fixed' => trans('taxes.fixed'),
'normal' => trans('taxes.normal'),
'inclusive' => trans('taxes.inclusive'),
'compound' => trans('taxes.compound'),
@ -62,13 +67,23 @@ class Taxes extends Controller
*/
public function store(Request $request)
{
Tax::create($request->all());
$response = $this->ajaxDispatch(new CreateTax($request));
$message = trans('messages.success.added', ['type' => trans_choice('general.tax_rates', 1)]);
if ($response['success']) {
$response['redirect'] = route('taxes.index');
flash($message)->success();
$message = trans('messages.success.added', ['type' => trans_choice('general.taxes', 1)]);
return redirect('settings/taxes');
flash($message)->success();
} else {
$response['redirect'] = route('taxes.create');
$message = $response['message'];
flash($message)->error();
}
return response()->json($response);
}
/**
@ -81,6 +96,7 @@ class Taxes extends Controller
public function edit(Tax $tax)
{
$types = [
'fixed' => trans('taxes.fixed'),
'normal' => trans('taxes.normal'),
'inclusive' => trans('taxes.inclusive'),
'compound' => trans('taxes.compound'),
@ -92,113 +108,91 @@ class Taxes extends Controller
/**
* Update the specified resource in storage.
*
* @param Tax $tax
* @param Request $request
* @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',
]);
$response = $this->ajaxDispatch(new UpdateTax($tax, $request));
if (empty($relationships) || $request['enabled']) {
$tax->update($request->all());
if ($response['success']) {
$response['redirect'] = route('taxes.index');
$message = trans('messages.success.updated', ['type' => trans_choice('general.tax_rates', 1)]);
$message = trans('messages.success.updated', ['type' => $tax->name]);
flash($message)->success();
return redirect('settings/taxes');
} else {
$message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
$response['redirect'] = route('taxes.edit', $tax->id);
flash($message)->warning();
$message = $response['message'];
return redirect('settings/taxes/' . $tax->id . '/edit');
flash($message)->error();
}
return response()->json($response);
}
/**
* Enable the specified resource.
*
* @param Tax $tax
* @param Tax $tax
*
* @return Response
*/
public function enable(Tax $tax)
{
$tax->enabled = 1;
$tax->save();
$response = $this->ajaxDispatch(new UpdateTax($tax, request()->merge(['enabled' => 1])));
$message = trans('messages.success.enabled', ['type' => trans_choice('general.tax_rates', 1)]);
if ($response['success']) {
$response['message'] = trans('messages.success.enabled', ['type' => $tax->name]);
}
flash($message)->success();
return redirect()->route('taxes.index');
return response()->json($response);
}
/**
* Disable the specified resource.
*
* @param Tax $tax
* @param Tax $tax
*
* @return Response
*/
public function disable(Tax $tax)
{
$relationships = $this->countRelationships($tax, [
'items' => 'items',
'invoice_items' => 'invoices',
'bill_items' => 'bills',
]);
$response = $this->ajaxDispatch(new UpdateTax($tax, request()->merge(['enabled' => 0])));
if (empty($relationships)) {
$tax->enabled = 0;
$tax->save();
$message = trans('messages.success.disabled', ['type' => trans_choice('general.tax_rates', 1)]);
flash($message)->success();
} else {
$message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
flash($message)->warning();
if ($response['success']) {
$response['message'] = trans('messages.success.disabled', ['type' => $tax->name]);
}
return redirect()->route('taxes.index');
return response()->json($response);
}
/**
* Remove the specified resource from storage.
*
* @param Tax $tax
* @param Tax $tax
*
* @return Response
*/
public function destroy(Tax $tax)
{
$relationships = $this->countRelationships($tax, [
'items' => 'items',
'invoice_items' => 'invoices',
'bill_items' => 'bills',
]);
$response = $this->ajaxDispatch(new DeleteTax($tax));
if (empty($relationships)) {
$tax->delete();
$response['redirect'] = route('taxes.index');
$message = trans('messages.success.deleted', ['type' => trans_choice('general.taxes', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $tax->name]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
flash($message)->warning();
flash($message)->error();
}
return redirect('settings/taxes');
return response()->json($response);
}
}

View File

@ -2,11 +2,11 @@
namespace App\Http\Controllers\Wizard;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Wizard\Company as Request;
use App\Models\Common\Company;
use App\Traits\Uploads;
use Date;
use Illuminate\Support\Str;
class Companies extends Controller
{
@ -21,8 +21,6 @@ class Companies extends Controller
{
$company = Company::find(session('company_id'));
$company->setSettings();
return view('wizard.companies.edit', compact('company'));
}
@ -41,7 +39,7 @@ class Companies extends Controller
$fields = $request->all();
$skip_keys = ['company_id', '_method', '_token'];
$file_keys = ['company_logo', 'invoice_logo'];
$file_keys = ['company.logo'];
foreach ($fields as $key => $value) {
// Don't process unwanted keys
@ -49,13 +47,24 @@ class Companies extends Controller
continue;
}
switch ($key) {
case 'api_key':
$real_key = 'apps.' . $key;
break;
case 'financial_start':
$real_key = 'localisation.' . $key;
break;
default:
$real_key = 'company.' . $key;
}
// Process file uploads
if (in_array($key, $file_keys)) {
if (in_array($real_key, $file_keys)) {
// Upload attachment
if ($request->file($key)) {
$media = $this->getMedia($request->file($key), 'settings');
$company->attachMedia($media, $key);
$company->attachMedia($media, Str::snake($key));
$value = $media->id;
}
@ -66,12 +75,25 @@ class Companies extends Controller
}
}
setting()->set('general.' . $key, $value);
setting()->set($real_key, $value);
}
// Save all settings
setting()->save();
return redirect('wizard/currencies');
$message = trans('messages.success.updated', ['type' => trans_choice('general.companies', 2)]);
$response = [
'status' => null,
'success' => true,
'error' => false,
'message' => $message,
'data' => null,
'redirect' => route('wizard.currencies.index'),
];
flash($message)->success();
return response()->json($response);
}
}

View File

@ -3,9 +3,11 @@
namespace App\Http\Controllers\Wizard;
use Akaunting\Money\Currency as MoneyCurrency;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Currency as Request;
use App\Models\Banking\Account;
use App\Jobs\Setting\CreateCurrency;
use App\Jobs\Setting\DeleteCurrency;
use App\Jobs\Setting\UpdateCurrency;
use App\Models\Setting\Currency;
class Currencies extends Controller
@ -17,41 +19,19 @@ class Currencies extends Controller
*/
public function index()
{
$currencies = Currency::all();
$currencies = Currency::collect();
return view('wizard.currencies.index', compact('currencies'));
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
// Get current currencies
$current = Currency::pluck('code')->toArray();
$current = Currency::orderBy('code')->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;
}
$money_currencies = MoneyCurrency::getCurrencies();
foreach ($money_currencies as $key => $item) {
$codes[$key] = $key;
}
$html = view('wizard.currencies.create', compact('codes'))->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
return view('wizard.currencies.index', compact('currencies', 'codes'));
}
/**
@ -63,63 +43,22 @@ class Currencies extends Controller
*/
public function store(Request $request)
{
// Force the rate to be 1 for default currency
if ($request['default_currency']) {
$request['rate'] = '1';
$response = $this->ajaxDispatch(new CreateCurrency($request));
$response['redirect'] = route('wizard.currencies.index');
if ($response['success']) {
$message = trans('messages.success.added', ['type' => trans_choice('general.currencies', 1)]);
flash($message)->success();
} else {
$message = $response['message'];
flash($message)->error();
}
$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)
{
// 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,
]);
return response()->json($response);
}
/**
@ -132,122 +71,21 @@ class Currencies extends Controller
*/
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',
]);
$response = $this->ajaxDispatch(new UpdateCurrency($currency, $request));
if ($currency->code == setting('general.default_currency')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
}
$response['redirect'] = route('wizard.currencies.index');
if (empty($relationships)) {
// Force the rate to be 1 for default currency
if ($request['default_currency']) {
$request['rate'] = '1';
}
if ($response['success']) {
$message = trans('messages.success.updated', ['type' => $currency->name]);
$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,
]);
flash($message)->success();
} else {
$message = trans('messages.warning.disabled', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
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));
flash($message)->error();
}
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,
]);
}
return response()->json($response);
}
/**
@ -259,39 +97,20 @@ class Currencies extends Controller
*/
public function destroy(Currency $currency)
{
$relationships = $this->countRelationships($currency, [
'accounts' => 'accounts',
'customers' => 'customers',
'invoices' => 'invoices',
'revenues' => 'revenues',
'bills' => 'bills',
'payments' => 'payments',
]);
$response = $this->ajaxDispatch(new DeleteCurrency($currency));
if ($currency->code == setting('general.default_currency')) {
$relationships[] = strtolower(trans_choice('general.companies', 1));
}
$response['redirect'] = route('wizard.currencies.index');
if (empty($relationships)) {
$currency->delete();
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $currency->name]);
$message = trans('messages.success.deleted', ['type' => trans_choice('general.currencies', 1)]);
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
'data' => $currency,
]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $currency->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
return response()->json([
'success' => false,
'error' => true,
'message' => $message,
'data' => $currency,
]);
flash($message)->error();
}
return response()->json($response);
}
}

View File

@ -17,7 +17,7 @@ class Finish extends Controller
*/
public function index()
{
setting()->set('general.wizard', true);
setting()->set('wizard.completed', 1);
// Save all settings
setting()->save();

View File

@ -2,8 +2,11 @@
namespace App\Http\Controllers\Wizard;
use App\Http\Controllers\Controller;
use App\Abstracts\Http\Controller;
use App\Http\Requests\Setting\Tax as Request;
use App\Jobs\Setting\CreateTax;
use App\Jobs\Setting\DeleteTax;
use App\Jobs\Setting\UpdateTax;
use App\Models\Setting\Tax;
class Taxes extends Controller
@ -15,28 +18,11 @@ class Taxes extends Controller
*/
public function index()
{
$taxes = Tax::all();
$taxes = Tax::collect();
return view('wizard.taxes.index', compact('taxes'));
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
$html = view('wizard.taxes.create')->render();
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
}
/**
* Store a newly created resource in storage.
*
@ -46,37 +32,21 @@ class Taxes extends Controller
*/
public function store(Request $request)
{
$tax = Tax::create($request->all());
$response = $this->ajaxDispatch(new CreateTax($request));
$message = trans('messages.success.added', ['type' => trans_choice('general.tax_rates', 1)]);
$response['redirect'] = route('wizard.taxes.index');
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
'data' => $tax,
]);
}
if ($response['success']) {
$message = trans('messages.success.added', ['type' => trans_choice('general.taxes', 1)]);
/**
* Show the form for editing the specified resource.
*
* @param Tax $tax
*
* @return Response
*/
public function edit(Tax $tax)
{
$item = $tax;
flash($message)->success();
} else {
$message = $response['message'];
$html = view('wizard.taxes.edit', compact('item'))->render();
flash($message)->error();
}
return response()->json([
'success' => true,
'error' => false,
'message' => 'null',
'html' => $html,
]);
return response()->json($response);
}
/**
@ -89,94 +59,21 @@ class Taxes extends Controller
*/
public function update(Tax $tax, Request $request)
{
$relationships = $this->countRelationships($tax, [
'items' => 'items',
'invoice_items' => 'invoices',
'bill_items' => 'bills',
]);
$response = $this->ajaxDispatch(new UpdateTax($tax, $request));
if (empty($relationships) || $request['enabled']) {
$tax->update($request->all());
$response['redirect'] = route('wizard.taxes.index');
$message = trans('messages.success.updated', ['type' => trans_choice('general.tax_rates', 1)]);
if ($response['success']) {
$message = trans('messages.success.updated', ['type' => $tax->name]);
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
'data' => $tax,
]);
flash($message)->success();
} else {
$message = trans('messages.warning.disabled', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
'data' => $tax,
]);
flash($message)->error();
}
}
/**
* 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,
]);
}
return response()->json($response);
}
/**
@ -188,32 +85,20 @@ class Taxes extends Controller
*/
public function destroy(Tax $tax)
{
$relationships = $this->countRelationships($tax, [
'items' => 'items',
'invoice_items' => 'invoices',
'bill_items' => 'bills',
]);
$response = $this->ajaxDispatch(new DeleteTax($tax));
if (empty($relationships)) {
$tax->delete();
$response['redirect'] = route('wizard.taxes.index');
$message = trans('messages.success.deleted', ['type' => trans_choice('general.taxes', 1)]);
if ($response['success']) {
$message = trans('messages.success.deleted', ['type' => $tax->name]);
return response()->json([
'success' => true,
'error' => false,
'message' => $message,
'data' => $tax,
]);
flash($message)->success();
} else {
$message = trans('messages.warning.deleted', ['name' => $tax->name, 'text' => implode(', ', $relationships)]);
$message = $response['message'];
return response()->json([
'success' => false,
'error' => true,
'message' => $message,
'data' => $tax,
]);
flash($message)->error();
}
return response()->json($response);
}
}