mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 12:42:36 +01:00
Working on proposals
This commit is contained in:
parent
7c3cbc3a7e
commit
ea06b60294
123
app/Http/Controllers/ProposalCategoryController.php
Normal file
123
app/Http/Controllers/ProposalCategoryController.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\CreateProposalCategoryRequest;
|
||||
use App\Http\Requests\ProposalCategoryRequest;
|
||||
use App\Http\Requests\UpdateProposalCategoryRequest;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\ProposalCategory;
|
||||
use App\Ninja\Datatables\ProposalCategoryDatatable;
|
||||
use App\Ninja\Repositories\ProposalCategoryRepository;
|
||||
use App\Services\ProposalCategoryService;
|
||||
use Auth;
|
||||
use Input;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
class ProposalCategoryController extends BaseController
|
||||
{
|
||||
protected $proposalCategoryRepo;
|
||||
protected $proposalCategoryService;
|
||||
protected $entityType = ENTITY_PROPOSAL_CATEGORY;
|
||||
|
||||
public function __construct(ProposalCategoryRepository $proposalCategoryRepo, ProposalCategoryService $proposalCategoryService)
|
||||
{
|
||||
$this->proposalCategoryRepo = $proposalCategoryRepo;
|
||||
$this->proposalCategoryService = $proposalCategoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('list_wrapper', [
|
||||
'entityType' => ENTITY_PROPOSAL_CATEGORY,
|
||||
'datatable' => new ProposalCategoryDatatable(),
|
||||
'title' => trans('texts.proposal_categories'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getDatatable($expensePublicId = null)
|
||||
{
|
||||
$search = Input::get('sSearch');
|
||||
$userId = Auth::user()->filterId();
|
||||
|
||||
return $this->proposalCategoryService->getDatatable($search, $userId);
|
||||
}
|
||||
|
||||
public function create(ProposalCategoryRequest $request)
|
||||
{
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposalCategory' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'proposal_categories',
|
||||
'title' => trans('texts.new_proposal_category'),
|
||||
'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
||||
'templates' => ProposalCategory::scope()->orderBy('name')->get(),
|
||||
'quotePublicId' => $request->quote_id,
|
||||
];
|
||||
|
||||
return View::make('proposal_categories.edit', $data);
|
||||
}
|
||||
|
||||
public function edit(ProposalCategoryRequest $request)
|
||||
{
|
||||
$proposalCategory = $request->entity();
|
||||
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposalCategory' => $proposalCategory,
|
||||
'method' => 'PUT',
|
||||
'url' => 'proposal_categories/' . $proposalCategory->public_id,
|
||||
'title' => trans('texts.edit_proposal_category'),
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => $proposalCategory->client ? $proposalCategory->client->public_id : null,
|
||||
];
|
||||
|
||||
return View::make('proposal_categories.edit', $data);
|
||||
}
|
||||
|
||||
public function store(CreateProposalCategoryRequest $request)
|
||||
{
|
||||
$proposalCategory = $this->proposalCategoryService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_proposal_category'));
|
||||
|
||||
return redirect()->to($proposalCategory->getRoute());
|
||||
}
|
||||
|
||||
public function update(UpdateProposalCategoryRequest $request)
|
||||
{
|
||||
$proposalCategory = $this->proposalCategoryService->save($request->input(), $request->entity());
|
||||
|
||||
Session::flash('message', trans('texts.updated_proposal_category'));
|
||||
|
||||
$action = Input::get('action');
|
||||
if (in_array($action, ['archive', 'delete', 'restore'])) {
|
||||
return self::bulk();
|
||||
}
|
||||
|
||||
return redirect()->to($proposalCategory->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
|
||||
$count = $this->proposalCategoryService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$field = $count == 1 ? "{$action}d_proposal_category" : "{$action}d_proposal_categories";
|
||||
$message = trans("texts.$field", ['count' => $count]);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
|
||||
return redirect()->to('/proposal_categories');
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\GenerateProposalChartData;
|
||||
use App\Http\Requests\CreateProposalRequest;
|
||||
use App\Http\Requests\ProposalRequest;
|
||||
use App\Http\Requests\UpdateProposalRequest;
|
||||
@ -23,13 +22,11 @@ class ProposalController extends BaseController
|
||||
protected $proposalService;
|
||||
protected $entityType = ENTITY_PROPOSAL;
|
||||
|
||||
/*
|
||||
public function __construct(ProposalRepository $proposalRepo, ProposalService $proposalService)
|
||||
{
|
||||
$this->proposalRepo = $proposalRepo;
|
||||
$this->proposalService = $proposalService;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
@ -53,23 +50,6 @@ class ProposalController extends BaseController
|
||||
return $this->proposalService->getDatatable($search, $userId);
|
||||
}
|
||||
|
||||
/*
|
||||
public function show(ProposalRequest $request)
|
||||
{
|
||||
$account = auth()->user()->account;
|
||||
$proposal = $request->entity();
|
||||
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposal' => $proposal,
|
||||
'title' => trans('texts.view_proposal'),
|
||||
'showBreadcrumbs' => false,
|
||||
];
|
||||
|
||||
return View::make('proposals.show', $data);
|
||||
}
|
||||
*/
|
||||
|
||||
public function create(ProposalRequest $request)
|
||||
{
|
||||
$data = [
|
||||
|
124
app/Http/Controllers/ProposalSnippetController.php
Normal file
124
app/Http/Controllers/ProposalSnippetController.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\CreateProposalSnippetRequest;
|
||||
use App\Http\Requests\ProposalSnippetRequest;
|
||||
use App\Http\Requests\UpdateProposalSnippetRequest;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\ProposalSnippet;
|
||||
use App\Models\ProposalSnippetTemplate;
|
||||
use App\Ninja\Datatables\ProposalSnippetDatatable;
|
||||
use App\Ninja\Repositories\ProposalSnippetRepository;
|
||||
use App\Services\ProposalSnippetService;
|
||||
use Auth;
|
||||
use Input;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
class ProposalSnippetController extends BaseController
|
||||
{
|
||||
protected $proposalSnippetRepo;
|
||||
protected $proposalSnippetService;
|
||||
protected $entityType = ENTITY_PROPOSAL_SNIPPET;
|
||||
|
||||
public function __construct(ProposalSnippetRepository $proposalSnippetRepo, ProposalSnippetService $proposalSnippetService)
|
||||
{
|
||||
$this->proposalSnippetRepo = $proposalSnippetRepo;
|
||||
$this->proposalSnippetService = $proposalSnippetService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('list_wrapper', [
|
||||
'entityType' => ENTITY_PROPOSAL_SNIPPET,
|
||||
'datatable' => new ProposalSnippetDatatable(),
|
||||
'title' => trans('texts.proposal_snippets'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getDatatable($expensePublicId = null)
|
||||
{
|
||||
$search = Input::get('sSearch');
|
||||
$userId = Auth::user()->filterId();
|
||||
|
||||
return $this->proposalSnippetService->getDatatable($search, $userId);
|
||||
}
|
||||
|
||||
public function create(ProposalSnippetRequest $request)
|
||||
{
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposalSnippet' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'proposal_snippets',
|
||||
'title' => trans('texts.new_proposal_snippet'),
|
||||
'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
||||
'templates' => ProposalSnippetTemplate::scope()->orderBy('name')->get(),
|
||||
'quotePublicId' => $request->quote_id,
|
||||
];
|
||||
|
||||
return View::make('proposal_snippets.edit', $data);
|
||||
}
|
||||
|
||||
public function edit(ProposalSnippetRequest $request)
|
||||
{
|
||||
$proposalSnippet = $request->entity();
|
||||
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposalSnippet' => $proposalSnippet,
|
||||
'method' => 'PUT',
|
||||
'url' => 'proposal_snippets/' . $proposalSnippet->public_id,
|
||||
'title' => trans('texts.edit_proposal_snippet'),
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => $proposalSnippet->client ? $proposalSnippet->client->public_id : null,
|
||||
];
|
||||
|
||||
return View::make('proposal_snippets.edit', $data);
|
||||
}
|
||||
|
||||
public function store(CreateProposalSnippetRequest $request)
|
||||
{
|
||||
$proposalSnippet = $this->proposalSnippetService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_proposal_snippet'));
|
||||
|
||||
return redirect()->to($proposalSnippet->getRoute());
|
||||
}
|
||||
|
||||
public function update(UpdateProposalSnippetRequest $request)
|
||||
{
|
||||
$proposalSnippet = $this->proposalSnippetService->save($request->input(), $request->entity());
|
||||
|
||||
Session::flash('message', trans('texts.updated_proposal_snippet'));
|
||||
|
||||
$action = Input::get('action');
|
||||
if (in_array($action, ['archive', 'delete', 'restore'])) {
|
||||
return self::bulk();
|
||||
}
|
||||
|
||||
return redirect()->to($proposalSnippet->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
|
||||
$count = $this->proposalSnippetService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$field = $count == 1 ? "{$action}d_proposal_snippet" : "{$action}d_proposal_snippets";
|
||||
$message = trans("texts.$field", ['count' => $count]);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
|
||||
return redirect()->to('/proposal_snippets');
|
||||
}
|
||||
}
|
124
app/Http/Controllers/ProposalTemplateController.php
Normal file
124
app/Http/Controllers/ProposalTemplateController.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\CreateProposalTemplateRequest;
|
||||
use App\Http\Requests\ProposalTemplateRequest;
|
||||
use App\Http\Requests\UpdateProposalTemplateRequest;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\ProposalTemplate;
|
||||
use App\Models\ProposalTemplateTemplate;
|
||||
use App\Ninja\Datatables\ProposalTemplateDatatable;
|
||||
use App\Ninja\Repositories\ProposalTemplateRepository;
|
||||
use App\Services\ProposalTemplateService;
|
||||
use Auth;
|
||||
use Input;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
class ProposalTemplateController extends BaseController
|
||||
{
|
||||
protected $proposalTemplateRepo;
|
||||
protected $proposalTemplateService;
|
||||
protected $entityType = ENTITY_PROPOSAL_TEMPLATE;
|
||||
|
||||
public function __construct(ProposalTemplateRepository $proposalTemplateRepo, ProposalTemplateService $proposalTemplateService)
|
||||
{
|
||||
$this->proposalTemplateRepo = $proposalTemplateRepo;
|
||||
$this->proposalTemplateService = $proposalTemplateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('list_wrapper', [
|
||||
'entityType' => ENTITY_PROPOSAL_TEMPLATE,
|
||||
'datatable' => new ProposalTemplateDatatable(),
|
||||
'title' => trans('texts.proposal_templates'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getDatatable($expensePublicId = null)
|
||||
{
|
||||
$search = Input::get('sSearch');
|
||||
$userId = Auth::user()->filterId();
|
||||
|
||||
return $this->proposalTemplateService->getDatatable($search, $userId);
|
||||
}
|
||||
|
||||
public function create(ProposalTemplateRequest $request)
|
||||
{
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposalTemplate' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'proposal_templates',
|
||||
'title' => trans('texts.new_proposal_template'),
|
||||
'quotes' => Invoice::scope()->with('client.contacts')->quotes()->orderBy('id')->get(),
|
||||
'templates' => ProposalTemplateTemplate::scope()->orderBy('name')->get(),
|
||||
'quotePublicId' => $request->quote_id,
|
||||
];
|
||||
|
||||
return View::make('proposal_templates.edit', $data);
|
||||
}
|
||||
|
||||
public function edit(ProposalTemplateRequest $request)
|
||||
{
|
||||
$proposalTemplate = $request->entity();
|
||||
|
||||
$data = [
|
||||
'account' => auth()->user()->account,
|
||||
'proposalTemplate' => $proposalTemplate,
|
||||
'method' => 'PUT',
|
||||
'url' => 'proposal_templates/' . $proposalTemplate->public_id,
|
||||
'title' => trans('texts.edit_proposal_template'),
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => $proposalTemplate->client ? $proposalTemplate->client->public_id : null,
|
||||
];
|
||||
|
||||
return View::make('proposal_templates.edit', $data);
|
||||
}
|
||||
|
||||
public function store(CreateProposalTemplateRequest $request)
|
||||
{
|
||||
$proposalTemplate = $this->proposalTemplateService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_proposal_template'));
|
||||
|
||||
return redirect()->to($proposalTemplate->getRoute());
|
||||
}
|
||||
|
||||
public function update(UpdateProposalTemplateRequest $request)
|
||||
{
|
||||
$proposalTemplate = $this->proposalTemplateService->save($request->input(), $request->entity());
|
||||
|
||||
Session::flash('message', trans('texts.updated_proposal_template'));
|
||||
|
||||
$action = Input::get('action');
|
||||
if (in_array($action, ['archive', 'delete', 'restore'])) {
|
||||
return self::bulk();
|
||||
}
|
||||
|
||||
return redirect()->to($proposalTemplate->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
|
||||
$count = $this->proposalTemplateService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$field = $count == 1 ? "{$action}d_proposal_template" : "{$action}d_proposal_templates";
|
||||
$message = trans("texts.$field", ['count' => $count]);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
|
||||
return redirect()->to('/proposal_templates');
|
||||
}
|
||||
}
|
8
app/Http/Requests/ProposalCategoryRequest.php
Normal file
8
app/Http/Requests/ProposalCategoryRequest.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
class ProposalCategoryRequest extends EntityRequest
|
||||
{
|
||||
protected $entityType = ENTITY_PROPOSAL_CATEGORY;
|
||||
}
|
@ -564,6 +564,8 @@ class Utils
|
||||
|
||||
if ($type === ENTITY_EXPENSE_CATEGORY) {
|
||||
return 'expense_categories';
|
||||
} elseif ($type === ENTITY_PROPOSAL_CATEGORY) {
|
||||
return 'proposal_categories';
|
||||
} else {
|
||||
return $type . 's';
|
||||
}
|
||||
|
76
app/Ninja/Repositories/ProposalCategoryRepository.php
Normal file
76
app/Ninja/Repositories/ProposalCategoryRepository.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ninja\Repositories;
|
||||
|
||||
use App\Models\ProposalCategory;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Utils;
|
||||
|
||||
class ProposalCategoryRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\ProposalCategory';
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return ProposalCategory::scope()->get();
|
||||
}
|
||||
|
||||
public function find($filter = null, $userId = false)
|
||||
{
|
||||
$query = DB::table('proposal_categories')
|
||||
->where('proposal_categories.account_id', '=', Auth::user()->account_id)
|
||||
->leftjoin('invoices', 'invoices.id', '=', 'proposal_categories.quote_id')
|
||||
->leftjoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||
->where('clients.deleted_at', '=', null)
|
||||
->where('contacts.deleted_at', '=', null)
|
||||
->where('contacts.is_primary', '=', true)
|
||||
->select(
|
||||
'proposal_categories.name as proposal',
|
||||
'proposal_categories.public_id',
|
||||
'proposal_categories.user_id',
|
||||
'proposal_categories.deleted_at',
|
||||
'proposal_categories.is_deleted',
|
||||
'proposal_categories.private_notes',
|
||||
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
|
||||
'clients.user_id as client_user_id',
|
||||
'clients.public_id as client_public_id'
|
||||
);
|
||||
|
||||
$this->applyFilters($query, ENTITY_PROPOSAL_CATEGORY);
|
||||
|
||||
if ($filter) {
|
||||
$query->where(function ($query) use ($filter) {
|
||||
$query->where('clients.name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.first_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.last_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.email', 'like', '%'.$filter.'%')
|
||||
->orWhere('proposal_categories.name', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
$query->where('proposal_categories.user_id', '=', $userId);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($input, $proposal = false)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if (! $proposal) {
|
||||
$proposal = ProposalCategory::createNew();
|
||||
}
|
||||
|
||||
$proposal->fill($input);
|
||||
$proposal->save();
|
||||
|
||||
return $proposal;
|
||||
}
|
||||
}
|
76
app/Ninja/Repositories/ProposalRepository.php
Normal file
76
app/Ninja/Repositories/ProposalRepository.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ninja\Repositories;
|
||||
|
||||
use App\Models\Proposal;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Utils;
|
||||
|
||||
class ProposalRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Proposal';
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return Proposal::scope()->get();
|
||||
}
|
||||
|
||||
public function find($filter = null, $userId = false)
|
||||
{
|
||||
$query = DB::table('proposals')
|
||||
->where('proposals.account_id', '=', Auth::user()->account_id)
|
||||
->leftjoin('invoices', 'invoices.id', '=', 'proposals.quote_id')
|
||||
->leftjoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||
->where('clients.deleted_at', '=', null)
|
||||
->where('contacts.deleted_at', '=', null)
|
||||
->where('contacts.is_primary', '=', true)
|
||||
->select(
|
||||
'proposals.public_id',
|
||||
'proposals.user_id',
|
||||
'proposals.deleted_at',
|
||||
'proposals.is_deleted',
|
||||
'proposals.private_notes',
|
||||
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
|
||||
'clients.user_id as client_user_id',
|
||||
'clients.public_id as client_public_id',
|
||||
'invoices.invoice_number as quote'
|
||||
);
|
||||
|
||||
$this->applyFilters($query, ENTITY_PROPOSAL);
|
||||
|
||||
if ($filter) {
|
||||
$query->where(function ($query) use ($filter) {
|
||||
$query->where('clients.name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.first_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.last_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.email', 'like', '%'.$filter.'%')
|
||||
->orWhere('invoices.invoice_number', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
$query->where('proposals.user_id', '=', $userId);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($input, $proposal = false)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if (! $proposal) {
|
||||
$proposal = Proposal::createNew();
|
||||
}
|
||||
|
||||
$proposal->fill($input);
|
||||
$proposal->save();
|
||||
|
||||
return $proposal;
|
||||
}
|
||||
}
|
76
app/Ninja/Repositories/ProposalSnippetRepository.php
Normal file
76
app/Ninja/Repositories/ProposalSnippetRepository.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ninja\Repositories;
|
||||
|
||||
use App\Models\ProposalSnippet;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Utils;
|
||||
|
||||
class ProposalSnippetRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\ProposalSnippet';
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return ProposalSnippet::scope()->get();
|
||||
}
|
||||
|
||||
public function find($filter = null, $userId = false)
|
||||
{
|
||||
$query = DB::table('proposal_snippets')
|
||||
->where('proposal_snippets.account_id', '=', Auth::user()->account_id)
|
||||
->leftjoin('invoices', 'invoices.id', '=', 'proposal_snippets.quote_id')
|
||||
->leftjoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||
->where('clients.deleted_at', '=', null)
|
||||
->where('contacts.deleted_at', '=', null)
|
||||
->where('contacts.is_primary', '=', true)
|
||||
->select(
|
||||
'proposal_snippets.name as proposal',
|
||||
'proposal_snippets.public_id',
|
||||
'proposal_snippets.user_id',
|
||||
'proposal_snippets.deleted_at',
|
||||
'proposal_snippets.is_deleted',
|
||||
'proposal_snippets.private_notes',
|
||||
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
|
||||
'clients.user_id as client_user_id',
|
||||
'clients.public_id as client_public_id'
|
||||
);
|
||||
|
||||
$this->applyFilters($query, ENTITY_PROPOSAL_SNIPPET);
|
||||
|
||||
if ($filter) {
|
||||
$query->where(function ($query) use ($filter) {
|
||||
$query->where('clients.name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.first_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.last_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.email', 'like', '%'.$filter.'%')
|
||||
->orWhere('proposal_snippets.name', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
$query->where('proposal_snippets.user_id', '=', $userId);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($input, $proposal = false)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if (! $proposal) {
|
||||
$proposal = ProposalSnippet::createNew();
|
||||
}
|
||||
|
||||
$proposal->fill($input);
|
||||
$proposal->save();
|
||||
|
||||
return $proposal;
|
||||
}
|
||||
}
|
76
app/Ninja/Repositories/ProposalTemplateRepository.php
Normal file
76
app/Ninja/Repositories/ProposalTemplateRepository.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ninja\Repositories;
|
||||
|
||||
use App\Models\ProposalTemplate;
|
||||
use Auth;
|
||||
use DB;
|
||||
use Utils;
|
||||
|
||||
class ProposalTemplateRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\ProposalTemplate';
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return ProposalTemplate::scope()->get();
|
||||
}
|
||||
|
||||
public function find($filter = null, $userId = false)
|
||||
{
|
||||
$query = DB::table('proposal_templates')
|
||||
->where('proposal_templates.account_id', '=', Auth::user()->account_id)
|
||||
->leftjoin('invoices', 'invoices.id', '=', 'proposal_templates.quote_id')
|
||||
->leftjoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||
->where('clients.deleted_at', '=', null)
|
||||
->where('contacts.deleted_at', '=', null)
|
||||
->where('contacts.is_primary', '=', true)
|
||||
->select(
|
||||
'proposal_templates.name as proposal',
|
||||
'proposal_templates.public_id',
|
||||
'proposal_templates.user_id',
|
||||
'proposal_templates.deleted_at',
|
||||
'proposal_templates.is_deleted',
|
||||
'proposal_templates.private_notes',
|
||||
DB::raw("COALESCE(NULLIF(clients.name,''), NULLIF(CONCAT(contacts.first_name, ' ', contacts.last_name),''), NULLIF(contacts.email,'')) client_name"),
|
||||
'clients.user_id as client_user_id',
|
||||
'clients.public_id as client_public_id'
|
||||
);
|
||||
|
||||
$this->applyFilters($query, ENTITY_PROPOSAL_TEMPLATE);
|
||||
|
||||
if ($filter) {
|
||||
$query->where(function ($query) use ($filter) {
|
||||
$query->where('clients.name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.first_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.last_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('contacts.email', 'like', '%'.$filter.'%')
|
||||
->orWhere('proposal_templates.name', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
$query->where('proposal_templates.user_id', '=', $userId);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($input, $proposal = false)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if (! $proposal) {
|
||||
$proposal = ProposalTemplate::createNew();
|
||||
}
|
||||
|
||||
$proposal->fill($input);
|
||||
$proposal->save();
|
||||
|
||||
return $proposal;
|
||||
}
|
||||
}
|
71
app/Services/ProposalCategoryService.php
Normal file
71
app/Services/ProposalCategoryService.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Ninja\Datatables\ProposalCategoryDatatable;
|
||||
use App\Ninja\Repositories\ProposalCategoryRepository;
|
||||
|
||||
/**
|
||||
* Class ProposalCategoryService.
|
||||
*/
|
||||
class ProposalCategoryService extends BaseService
|
||||
{
|
||||
/**
|
||||
* @var ProposalCategoryRepository
|
||||
*/
|
||||
protected $proposalCategoryRepo;
|
||||
|
||||
/**
|
||||
* @var DatatableService
|
||||
*/
|
||||
protected $datatableService;
|
||||
|
||||
/**
|
||||
* CreditService constructor.
|
||||
*
|
||||
* @param ProposalCategoryRepository $creditRepo
|
||||
* @param DatatableService $datatableService
|
||||
*/
|
||||
public function __construct(ProposalCategoryRepository $proposalCategoryRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->proposalCategoryRepo = $proposalCategoryRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CreditRepository
|
||||
*/
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->proposalCategoryRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param mixed $proposalCategory
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function save($data, $proposalCategory = false)
|
||||
{
|
||||
return $this->proposalCategoryRepo->save($data, $proposalCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $clientPublicId
|
||||
* @param $search
|
||||
* @param mixed $userId
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getDatatable($search, $userId)
|
||||
{
|
||||
// we don't support bulk edit and hide the client on the individual client page
|
||||
$datatable = new ProposalCategoryDatatable();
|
||||
|
||||
$query = $this->proposalCategoryRepo->find($search, $userId);
|
||||
|
||||
return $this->datatableService->createDatatable($datatable, $query);
|
||||
}
|
||||
}
|
71
app/Services/ProposalService.php
Normal file
71
app/Services/ProposalService.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Ninja\Datatables\ProposalDatatable;
|
||||
use App\Ninja\Repositories\ProposalRepository;
|
||||
|
||||
/**
|
||||
* Class ProposalService.
|
||||
*/
|
||||
class ProposalService extends BaseService
|
||||
{
|
||||
/**
|
||||
* @var ProposalRepository
|
||||
*/
|
||||
protected $proposalRepo;
|
||||
|
||||
/**
|
||||
* @var DatatableService
|
||||
*/
|
||||
protected $datatableService;
|
||||
|
||||
/**
|
||||
* CreditService constructor.
|
||||
*
|
||||
* @param ProposalRepository $creditRepo
|
||||
* @param DatatableService $datatableService
|
||||
*/
|
||||
public function __construct(ProposalRepository $proposalRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->proposalRepo = $proposalRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CreditRepository
|
||||
*/
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->proposalRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param mixed $proposal
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function save($data, $proposal = false)
|
||||
{
|
||||
return $this->proposalRepo->save($data, $proposal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $clientPublicId
|
||||
* @param $search
|
||||
* @param mixed $userId
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getDatatable($search, $userId)
|
||||
{
|
||||
// we don't support bulk edit and hide the client on the individual client page
|
||||
$datatable = new ProposalDatatable();
|
||||
|
||||
$query = $this->proposalRepo->find($search, $userId);
|
||||
|
||||
return $this->datatableService->createDatatable($datatable, $query);
|
||||
}
|
||||
}
|
71
app/Services/ProposalSnippetService.php
Normal file
71
app/Services/ProposalSnippetService.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Ninja\Datatables\ProposalSnippetDatatable;
|
||||
use App\Ninja\Repositories\ProposalSnippetRepository;
|
||||
|
||||
/**
|
||||
* Class ProposalSnippetService.
|
||||
*/
|
||||
class ProposalSnippetService extends BaseService
|
||||
{
|
||||
/**
|
||||
* @var ProposalSnippetRepository
|
||||
*/
|
||||
protected $proposalSnippetRepo;
|
||||
|
||||
/**
|
||||
* @var DatatableService
|
||||
*/
|
||||
protected $datatableService;
|
||||
|
||||
/**
|
||||
* CreditService constructor.
|
||||
*
|
||||
* @param ProposalSnippetRepository $creditRepo
|
||||
* @param DatatableService $datatableService
|
||||
*/
|
||||
public function __construct(ProposalSnippetRepository $proposalSnippetRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->proposalSnippetRepo = $proposalSnippetRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CreditRepository
|
||||
*/
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->proposalSnippetRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param mixed $proposalSnippet
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function save($data, $proposalSnippet = false)
|
||||
{
|
||||
return $this->proposalSnippetRepo->save($data, $proposalSnippet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $clientPublicId
|
||||
* @param $search
|
||||
* @param mixed $userId
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getDatatable($search, $userId)
|
||||
{
|
||||
// we don't support bulk edit and hide the client on the individual client page
|
||||
$datatable = new ProposalSnippetDatatable();
|
||||
|
||||
$query = $this->proposalSnippetRepo->find($search, $userId);
|
||||
|
||||
return $this->datatableService->createDatatable($datatable, $query);
|
||||
}
|
||||
}
|
71
app/Services/ProposalTemplateService.php
Normal file
71
app/Services/ProposalTemplateService.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Ninja\Datatables\ProposalTemplateDatatable;
|
||||
use App\Ninja\Repositories\ProposalTemplateRepository;
|
||||
|
||||
/**
|
||||
* Class ProposalTemplateService.
|
||||
*/
|
||||
class ProposalTemplateService extends BaseService
|
||||
{
|
||||
/**
|
||||
* @var ProposalTemplateRepository
|
||||
*/
|
||||
protected $proposalTemplateRepo;
|
||||
|
||||
/**
|
||||
* @var DatatableService
|
||||
*/
|
||||
protected $datatableService;
|
||||
|
||||
/**
|
||||
* CreditService constructor.
|
||||
*
|
||||
* @param ProposalTemplateRepository $creditRepo
|
||||
* @param DatatableService $datatableService
|
||||
*/
|
||||
public function __construct(ProposalTemplateRepository $proposalTemplateRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->proposalTemplateRepo = $proposalTemplateRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CreditRepository
|
||||
*/
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->proposalTemplateRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param mixed $proposalTemplate
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function save($data, $proposalTemplate = false)
|
||||
{
|
||||
return $this->proposalTemplateRepo->save($data, $proposalTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $clientPublicId
|
||||
* @param $search
|
||||
* @param mixed $userId
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getDatatable($search, $userId)
|
||||
{
|
||||
// we don't support bulk edit and hide the client on the individual client page
|
||||
$datatable = new ProposalTemplateDatatable();
|
||||
|
||||
$query = $this->proposalTemplateRepo->find($search, $userId);
|
||||
|
||||
return $this->datatableService->createDatatable($datatable, $query);
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ class AddSubscriptionFormat extends Migration
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->boolean('is_deleted')->default(false);
|
||||
|
||||
$table->string('name');
|
||||
|
||||
@ -43,10 +44,12 @@ class AddSubscriptionFormat extends Migration
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->boolean('is_deleted')->default(false);
|
||||
|
||||
$table->unsignedInteger('proposal_category_id');
|
||||
$table->string('name');
|
||||
|
||||
$table->text('private_notes');
|
||||
|
||||
$table->mediumText('html');
|
||||
$table->mediumText('css');
|
||||
|
||||
@ -63,6 +66,8 @@ class AddSubscriptionFormat extends Migration
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->boolean('is_deleted')->default(false);
|
||||
$table->text('private_notes');
|
||||
|
||||
$table->string('name');
|
||||
$table->text('tags');
|
||||
@ -82,9 +87,11 @@ class AddSubscriptionFormat extends Migration
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->boolean('is_deleted')->default(false);
|
||||
|
||||
$table->unsignedInteger('quote_id')->index();
|
||||
$table->unsignedInteger('temlate_id')->index();
|
||||
$table->text('private_notes');
|
||||
$table->mediumText('html');
|
||||
$table->mediumText('css');
|
||||
|
||||
|
@ -2659,8 +2659,63 @@ $LANG = array(
|
||||
'tax_amount' => 'Tax Amount',
|
||||
'tax_paid' => 'Tax Paid',
|
||||
'none' => 'None',
|
||||
|
||||
'proposal' => 'Proposal',
|
||||
'proposals' => 'Proposals',
|
||||
'new_proposal' => 'New Proposal',
|
||||
'edit_proposal' => 'Edit Proposal',
|
||||
'archive_proposal' => 'Archive Proposal',
|
||||
'delete_proposal' => 'Delete Proposal',
|
||||
'restored_proposal' => 'Restore Proposal',
|
||||
'created_proposal' => 'Successfully created proposal',
|
||||
'updated_proposal' => 'Successfully updated proposal',
|
||||
'archived_proposal' => 'Successfully archived proposal',
|
||||
'deleted_proposal' => 'Successfully archived proposal',
|
||||
'archived_proposals' => 'Successfully archived :count proposals',
|
||||
'deleted_proposals' => 'Successfully archived :count proposals',
|
||||
'restored_proposal' => 'Successfully restored proposal',
|
||||
'proposal_snippet' => 'Snippet',
|
||||
'proposal_snippets' => 'Snippets',
|
||||
'new_proposal_snippet' => 'New Snippet',
|
||||
'edit_proposal_snippet' => 'Edit Snippet',
|
||||
'archive_proposal_snippet' => 'Archive Snippet',
|
||||
'delete_proposal_snippet' => 'Delete Snippet',
|
||||
'restored_proposal_snippet' => 'Restore Snippet',
|
||||
'created_proposal_snippet' => 'Successfully created snippet',
|
||||
'updated_proposal_snippet' => 'Successfully updated snippet',
|
||||
'archived_proposal_snippet' => 'Successfully archived snippet',
|
||||
'deleted_proposal_snippet' => 'Successfully archived snippet',
|
||||
'archived_proposal_snippets' => 'Successfully archived :count snippets',
|
||||
'deleted_proposal_snippets' => 'Successfully archived :count snippets',
|
||||
'restored_proposal_snippet' => 'Successfully restored snippet',
|
||||
'proposal_template' => 'Template',
|
||||
'proposal_templates' => 'Templates',
|
||||
'new_proposal_template' => 'New Template',
|
||||
'edit_proposal_template' => 'Edit Template',
|
||||
'archive_proposal_template' => 'Archive Template',
|
||||
'delete_proposal_template' => 'Delete Template',
|
||||
'restored_proposal_template' => 'Restore Template',
|
||||
'created_proposal_template' => 'Successfully created temlate',
|
||||
'updated_proposal_template' => 'Successfully updated temlate',
|
||||
'archived_proposal_template' => 'Successfully archived temlate',
|
||||
'deleted_proposal_template' => 'Successfully archived temlate',
|
||||
'archived_proposal_templates' => 'Successfully archived :count temlates',
|
||||
'deleted_proposal_templates' => 'Successfully archived :count temlates',
|
||||
'restored_proposal_template' => 'Successfully restored temlate',
|
||||
'proposal_category' => 'Proposal Category',
|
||||
'proposal_categories' => 'Proposal Categories',
|
||||
'new_proposal_category' => 'New Category',
|
||||
'edit_proposal_category' => 'Edit Category',
|
||||
'archive_proposal_category' => 'Archive Category',
|
||||
'delete_proposal_category' => 'Delete Category',
|
||||
'restored_proposal_category' => 'Restore Category',
|
||||
'created_proposal_category' => 'Successfully created category',
|
||||
'updated_proposal_category' => 'Successfully updated category',
|
||||
'archived_proposal_category' => 'Successfully archived category',
|
||||
'deleted_proposal_category' => 'Successfully archived category',
|
||||
'archived_proposal_categories' => 'Successfully archived :count categories',
|
||||
'deleted_proposal_categories' => 'Successfully archived :count categories',
|
||||
'restored_proposal_category' => 'Successfully restored category',
|
||||
|
||||
);
|
||||
|
||||
|
@ -46,17 +46,40 @@
|
||||
<input id="tableFilter_{{ $entityType }}" type="text" style="width:180px;margin-right:17px;background-color: white !important"
|
||||
class="form-control pull-left" placeholder="{{ trans('texts.filter') }}" value="{{ Input::get('filter') }}"/>
|
||||
|
||||
@if (false && $entityType == ENTITY_INVOICE && auth()->user()->account->isModuleEnabled(ENTITY_RECURRING_INVOICE))
|
||||
{!! DropdownButton::normal(trans('texts.recurring'))
|
||||
->withAttributes(['class'=>'recurringDropdown'])
|
||||
@if ($entityType == ENTITY_PROPOSAL)
|
||||
{!! DropdownButton::normal(trans('texts.templates'))
|
||||
->withAttributes(['class'=>'templatesDropdown'])
|
||||
->withContents([
|
||||
['label' => trans('texts.new_recurring_invoice'), 'url' => url('/recurring_invoices/create')],
|
||||
['label' => trans('texts.new_template'), 'url' => url('/proposal_templates/create')],
|
||||
]
|
||||
)->split() !!}
|
||||
{!! DropdownButton::normal(trans('texts.snippets'))
|
||||
->withAttributes(['class'=>'snippetsDropdown'])
|
||||
->withContents([
|
||||
['label' => trans('texts.new_snippet'), 'url' => url('/proposal_snippets/create')],
|
||||
]
|
||||
)->split() !!}
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$('.templatesDropdown:not(.dropdown-toggle)').click(function(event) {
|
||||
openUrlOnClick('{{ url('/proposal_templates') }}', event);
|
||||
});
|
||||
$('.snippetsDropdown:not(.dropdown-toggle)').click(function(event) {
|
||||
openUrlOnClick('{{ url('/proposal_snippets') }}', event);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@elseif ($entityType == ENTITY_PROPOSAL_SNIPPET)
|
||||
{!! DropdownButton::normal(trans('texts.categories'))
|
||||
->withAttributes(['class'=>'categoriesDropdown'])
|
||||
->withContents([
|
||||
['label' => trans('texts.new_category'), 'url' => url('/proposal_categories/create')],
|
||||
]
|
||||
)->split() !!}
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$('.recurringDropdown:not(.dropdown-toggle)').click(function(event) {
|
||||
openUrlOnClick('{{ url('/recurring_invoices') }}', event);
|
||||
$('.categoriesDropdown:not(.dropdown-toggle)').click(function(event) {
|
||||
openUrlOnClick('{{ url('/proposal_categories') }}', event);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -207,15 +207,19 @@ Route::group(['middleware' => ['lookup:user', 'auth:user']], function () {
|
||||
|
||||
Route::get('proposals/create/{quote_id?}', 'ProposalController@create');
|
||||
Route::resource('proposals', 'ProposalController');
|
||||
Route::get('api/proposals', 'ProposalController@getDatatable');
|
||||
|
||||
Route::get('proposal_templates/create', 'ProposalTemplateController@create');
|
||||
Route::resource('proposal_templates', 'ProposalTemplateController');
|
||||
Route::get('api/proposal_templates', 'ProposalTemplateController@getDatatable');
|
||||
|
||||
Route::get('proposal_snippets/create', 'ProposalSnippetController@create');
|
||||
Route::resource('proposal_snippets', 'ProposalSnippetController');
|
||||
Route::get('api/proposal_snippets', 'ProposalSnippetController@getDatatable');
|
||||
|
||||
Route::get('proposal_categories/create', 'ProposalCategoryController@create');
|
||||
Route::resource('proposal_categories', 'ProposalController');
|
||||
Route::resource('proposal_categories', 'ProposalCategoryController');
|
||||
Route::get('api/proposal_categories', 'ProposalCategoryController@getDatatable');
|
||||
|
||||
Route::resource('payments', 'PaymentController');
|
||||
Route::get('payments/create/{client_id?}/{invoice_id?}', 'PaymentController@create');
|
||||
|
Loading…
Reference in New Issue
Block a user